sigildocs

(sigil web live)

(sigil web live) - Live streams and collections

A live-stream is a server-push channel a page subscribes to over SSE: you live-push! ui-* updates and every connected client applies them. It owns a broadcast hub, an SSE route, and a lazily-started heartbeat. No store, no render — the general case (a chat feed, a room log, notifications).

A live-collection is a live-stream plus an id-keyed store and a per-item render function. Mutating it (live-add! / live-update! / live-remove!) pushes the right DOM patch automatically: a new row appends, an updated row morphs in place by id, a removed row is deleted by id. An optional on-change: derives extra UI (e.g. a count) from the item list after every mutation.

Mutations do NOT return the HTTP response — they return the affected item (or #f). Under ui-routes a handler can just end with the mutation. Mental model: the mutation/push is what everyone sees; the handler's return is what you see.

Example:

(define todos
  (live-collection render: item-row container: "#todo-list" path: "/events"
    on-change: (lambda (items)
                 (ui-update target: "#count" mode: "inner"
                            content: (count-label (length items))))))

(define log (live-stream path: "/log"))                 ; a plain feed

(define (create-handler req)
  (live-add! todos (dict text: (form-text req) done?: #f))
  (live-push! log (ui-update target: "#log" mode: "append"
                             content: (log-line "Added" (form-text req)))))

Exports

Construct a live-stream-rec struct.

Test if a value is a live-stream-rec struct.

Get the path field of a live-stream-rec struct.

Get the hub field of a live-stream-rec struct.

Get the on-connect field of a live-stream-rec struct.

Get the heartbeat-latch field of a live-stream-rec struct.

live-streamprocedure

Create a live stream: a broadcast hub + an SSE route (registered via live-routes) + a lazily-started heartbeat. Push ui-* updates to it with live-push!; put its subscription element on the page with live-subscribe.

Parameters: path: the SSE path the page subscribes to (default "/events"). on-connect: optional thunk returning an initial ui-update string (or #f) sent to each new subscriber. Collections use this for the current-state snapshot; a plain feed usually omits it.

live-stream?procedure

#t if x is a live stream.

live-push!procedure

Push a UI update (or a list of them) to every client subscribed to the stream. x is a stream or a collection. Returns update.

(live-push! log (ui-update target: "#log" mode: "append" content: row))

The hidden element that subscribes a page to a stream's live updates. x is a stream or a collection. Drop it into a page body.

live-routesprocedure

Return a handler that serves the SSE endpoint for a stream or a collection. Combine with your app's routes: (routes (router …) (live-routes todos) (live-routes log)).

Return a handler that serves the SSE endpoint for a stream or a collection. Combine with your app's routes: (routes (router …) (live-routes todos) (live-routes log)).

mem-storeprocedure

Construct a mem-store struct.

mem-store?procedure

Test if a value is a mem-store struct.

Get the items field of a mem-store struct.

Get the next-id field of a mem-store struct.

Set the items field of a mem-store struct.

Set the next-id field of a mem-store struct.

Construct a live-collection-rec struct.

Test if a value is a live-collection-rec struct.

Get the stream field of a live-collection-rec struct.

Get the store field of a live-collection-rec struct.

Get the render field of a live-collection-rec struct.

Get the container field of a live-collection-rec struct.

Get the on-change field of a live-collection-rec struct.

Create a live collection: a stream whose subscribers see a list of rendered rows kept in sync as you mutate it.

Parameters: render: (item -> SXML) rendering one row. The rendered element MUST carry an id attribute; the collection targets that id when it morphs or removes the row. container: CSS id-selector of the list element rows live in (e.g. "#todo-list"). path: the SSE path the page subscribes to (default "/events"). on-change: optional (items -> ui-update or list of them), broadcast after every mutation. For UI derived from the whole list (a count, a summary). Receives ONLY the item list.

#t if x is a live collection.

live-snapshotprocedure

The current-state snapshot for a collection (the same update sent on connect). Exposed for callers who want to re-seed a target.

live-getprocedure

Read one item by id (or #f). For read-only handlers such as an inline edit form that needs the item's current state; mutations go through live-update! / live-remove!.

live-allprocedure

All items in insertion order. Read-only.

live-add!procedure

Add item: assign an id, store it, broadcast an append of its rendered row (then any on-change update) to every client. Returns the stored item. Does NOT return an HTTP response.

live-update!procedure

Update item id in place with (f item): store it, broadcast a morph of its rendered row (then any on-change). Returns the new item, or #f if no such id. Does NOT return a response.

live-remove!procedure

Remove item id: delete it, broadcast a remove of its row (then any on-change). Returns the removed item, or #f if no such id. Does NOT return a response.

Render the collection's list view: the list container holding the current rows, plus the hidden element subscribing the page to the live stream. Drop this into a page body.