feat(realtime): declarative live-update subscription module (LC-156 phase 1) #192
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/lc-156-live-subscribe-foundation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Phase 1 of LC-156 (live updates by default): the foundational shared subscribe mechanism. Design:
docs/superpowers/specs/2026-05-22-live-updates-by-default-design.md.The room, DM, and voice pages each hand-rolled an identical
htmx:wsOpensubscribe +htmx:beforeCleanupElementteardown IIFE (100% duplication). This replaces all three with one sharedassets/live.jsloaded once from base.html.How
data-lc-live-room="<id>"on any element.live.jssends{type:"subscribe",room_id}on socket open (scanning the whole document, using the wrapper from the event detail so it does not depend on layout.html's ownwsOpenlistener ordering) and onhtmx:loadfor any live element in a freshly-loaded subtree (usingwindow.__lcWS).No server or protocol change: keeps the existing
room_idsubscribe frame. This is a behavior-preserving deduplication that establishes the mechanism.Deferred to follow-up sub-issues (filed)
enclave:/user:/admin:) on the hub + subscribe-time authorization.Test
just check(Askama templates compile),just test,just test-saasgreen - the route tests that render the room/DM/voice pages confirm the templates still render with the new attribute. (just verifywas blocked locally by a port already in use, unrelated to the change; the release build itself succeeded.) JS runtime behavior is not unit-tested in this repo (the replaced IIFEs were not either); the change is a faithful consolidation of identical logic.Part of the LC-159 post-audit story.
🤖 Generated with Claude Code
Foundation for "live updates by default" (LC-156). The room, DM, and voice pages each hand-rolled an identical htmx:wsOpen subscribe + htmx:beforeCleanupElement teardown IIFE (100% duplication). Replace all three with one shared assets/live.js loaded once from base.html: a page opts into WS room updates by putting data-lc-live-room="<id>" on any element, and the module sends the {type:"subscribe",room_id} frame on socket open and when such an element loads into the DOM. Because the module is loaded once and registers document-level listeners, it cannot accumulate duplicate listeners across reconnect soft-refreshes (the reason the per-page IIFEs needed explicit teardown), so the teardown dance is gone. On wsOpen it subscribes every live element in the document using the wrapper from the event detail (so it does not depend on layout.html's own wsOpen listener having set window.__lcWS first); on htmx:load it subscribes any live elements in the freshly-loaded subtree using window.__lcWS. Re-subscribing an already-subscribed room is harmless (the server's subscriber set is a HashSet); no unsubscribe is sent, matching prior behavior. No server or protocol change: this keeps the existing room_id subscribe frame. Typed topics (enclave/user/admin + subscribe-time authorization) and the per-surface stale-page fills are deliberately deferred to follow-up sub-issues; see docs/superpowers/specs/2026-05-22-live-updates-by-default-design.md. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>