Subscriptions for Lustre!
5

Configure Feed

Select the types of activity you want to include in your feed.

Gleam 75.6%
JavaScript 17.6%
CSS 6.6%
Erlang 0.2%
30 1 3

Clone this repository

https://tangled.org/becca.monster/off_topic https://tangled.org/did:plc:vdxvzqf7pvn3vhdmy7hoz5cc
git@tangled.org:becca.monster/off_topic git@tangled.org:did:plc:vdxvzqf7pvn3vhdmy7hoz5cc

For self-hosted knots, clone URLs may differ based on your setup.



README.md

off_topic#

Package Version Hex Docs

This is an experimental (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_topic

Usage#

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.