(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
live-stream-recprocedureConstruct a live-stream-rec struct.
live-stream-rec?procedureTest if a value is a live-stream-rec struct.
live-stream-rec-pathprocedureGet the path field of a live-stream-rec struct.
live-stream-rec-hubprocedureGet the hub field of a live-stream-rec struct.
live-stream-rec-on-connectprocedureGet the on-connect field of a live-stream-rec struct.
live-stream-rec-heartbeat-latchprocedureGet the heartbeat-latch field of a live-stream-rec struct.
live-streamprocedureCreate 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!procedurePush 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))live-subscribeprocedureThe 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-routesprocedureReturn 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-store--typevariableReturn 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-storeprocedureConstruct a mem-store struct.
mem-store?procedureTest if a value is a mem-store struct.
mem-store-itemsprocedureGet the items field of a mem-store struct.
mem-store-next-idprocedureGet the next-id field of a mem-store struct.
set-mem-store-items!procedureSet the items field of a mem-store struct.
set-mem-store-next-id!procedureSet the next-id field of a mem-store struct.
live-collection-recprocedureConstruct a live-collection-rec struct.
live-collection-rec?procedureTest if a value is a live-collection-rec struct.
live-collection-rec-streamprocedureGet the stream field of a live-collection-rec struct.
live-collection-rec-storeprocedureGet the store field of a live-collection-rec struct.
live-collection-rec-renderprocedureGet the render field of a live-collection-rec struct.
live-collection-rec-containerprocedureGet the container field of a live-collection-rec struct.
live-collection-rec-on-changeprocedureGet the on-change field of a live-collection-rec struct.
live-collectionprocedureCreate 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.
live-collection?procedure#t if x is a live collection.
live-snapshotprocedureThe current-state snapshot for a collection (the same update sent on connect). Exposed for callers who want to re-seed a target.
live-getprocedureRead 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-allprocedureAll items in insertion order. Read-only.
live-add!procedureAdd 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!procedureUpdate 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!procedureRemove 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.
live-list-viewprocedureRender 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.