Live collections
Every tab keeps its own filter. PubSub sends a tiny nudge, then each browser reloads the collection with the signals it actually holds.
Demo
Changes arrive through the open PubSub stream.
This tab's filtered query
Switch another tab to a different status, then mutate either one.
Bjfh
activework item 5
Segsg
activework item 4
Ship collection nudge
donework item 3
Verify signal contract
activework item 2
Review edge deployment
activework item 1
How it works
- The stream knows that data changed, but never guesses what a tab is showing.
- nudge/2 changes nudges.work_items; on_nudge/2 posts the tab's current signals.
- reload queries Postgres with that tab's statusFilter and patches one panel.
- Only the separate unfiltered arrival feed uses append_elements/3.
The filtered collection deliberately does not receive row mutations. An item can leave one filter and enter another, so every open tab re-runs its own query. The arrival lane is the contrast: it contains immutable creation facts in append order, making a direct append correct rather than merely faster.
def handle_connect(conn, _params) do
:ok = LiveCollections.subscribe()
nudge(conn, "work_items")
end
# ...
def handle_info({:live_collection_changed, :created, item}, conn) do
conn
|> nudge("work_items")
|> append_elements(arrival_row(%{item: item}), "#arrival-feed")
end
def handle_info({:live_collection_changed, :updated, _item}, conn) do
nudge(conn, "work_items")
end