off_topic
This is an experimtal (in design not implementation) Lustre runtime extension,
adding so-called subscriptions. Subscriptions are at their core effects with a
cleanup function. If you know React, Vue, or Svelte, you can think of them as
useEffect or watch calls. off_topic lets you define your active subscriptions
in a declarative way, using a familiar diffing mechanism to figure out which effects
to start, and which cleanup functions to run.
It also comes with a comprehensive library of built-in effects and subscriptions and a vast collection of little demo apps showing how to work with them. Built-in subscriptions range from simple timers to browser events to SSE and WebSockets.
Almost all subscriptions and effects in off_topic work both with client and server-
components using a small (~3kb min+gzip), extensible runtime custom-element
in the browser.
gleam add off_topicUsage
off_topic.application is a drop-in for lustre.application that adds a
subscriptions callback. off_topic calls it after every update, starting new
subscriptions and stopping removed ones automatically.
import lustre
import off_topic.{type Subscription}
pub fn main() {
let app = off_topic.application(init:, update:, subscriptions:, view:)
let assert Ok(_) = lustre.start(app, "#app", Nil)
Nil
}
fn subscriptions(model: Model) -> Subscription(Msg) {
off_topic.batch([
// always listen for the page state / visibility
off_topic.page_state(PageStateChanged),
case model.page_state {
// while the page is focused, run a 1 second interval
off_topic.Active ->
off_topic.every(every: duration.seconds(1), immediate: False, on_elapsed: Tick)
// when the page is no longer active, returning off_topic.none()
// causes the runtime to clean up the interval automatically.
_ -> off_topic.none()
},
])
}The module documentation contains many more examples and their source code for you to play with!
There's also some guides on the left that go into more detail.
Documentation
Full API reference and guides at https://hexdocs.pm/off_topic.