Extract the shared bus-drain and control-dispatch machinery (LC-616) #575

Merged
longjacksonle merged 1 commit from refactor/lc616-rtc-machinery into main 2026-07-21 03:39:27 +02:00

Closes LC-616. The mechanical follow-up deferred from LC-613 (#574).

What was duplicated

call.js and voice.js each open a WebSocket "bus" the server pushes OOB fragments into, and each binds one delegated click listener for its control bar. Two idioms were duplicated:

  • The drain loop, byte-for-byte across three copies: call.js's call bus and control bus, and voice.js's voice bus. All three are the same MutationObserver differing only in the bus id, the event attribute, and the handler.
  • The control-click dispatch: one delegated click listener with a t.closest(sel) -> handler; return chain, same idiom in both files.

What this adds

A new server/assets/rtc_common.js exposing window.LetsChatRtc:

  • watchBus(busId, eventAttr, handler) - the drain, parameterized by exactly the three tokens that differed.
  • bindControls(map) - one delegated listener from a selector -> fn(el, event) map, matching the first selector the target is inside and short-circuiting, as the old if/else chains did. The handler gets (el, event), which is what lets call.js's start-button case keep its preventDefault + room/peer context extraction; every other case is a nullary handler.

Loaded before both consumers; base.html is the only place these scripts load.

Still surface-specific, on purpose

Per LC-613, the media operations (mute/camera/screen) and the signaling frames stay per-file - they are genuinely different between one RTCPeerConnection, a mesh, and the SFU. This PR is machinery only.

No behaviour change (no JS harness, so verified by)

  • all three files parse (node --check)
  • the old inline MutationObserver idiom is gone from both consumers (0 occurrences), and the handler functions (handleSignal/handleControl/handleEvent) and the watchBus()/watchControlBus() registration sites are intact
  • the LC-614 server tests stay green - this touches no WS frame
  • load order is guaranteed: three ordered defer scripts, rtc_common.js first, so window.LetsChatRtc is defined before the consumers execute their IIFEs
  • an adversarial review confirmed each helper is behaviour-preserving against the originals: selector construction, observer config, the first-match short-circuit, the start-case (el, e) signature and its isFinite guard, and insertion-order dispatch (start checked first)

just check clean.

Net

~90 lines of duplication removed across two files for ~70 in one shared module - single source of truth. One new global namespace (LetsChatRtc), offset by the room global LC-613 already removed, so the overall global count is flat.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FhDVMViNHqUbwmfe2aXTv5

Closes LC-616. The mechanical follow-up deferred from LC-613 (#574). ## What was duplicated `call.js` and `voice.js` each open a WebSocket "bus" the server pushes OOB fragments into, and each binds one delegated click listener for its control bar. Two idioms were duplicated: - **The drain loop**, byte-for-byte across three copies: `call.js`'s call bus and control bus, and `voice.js`'s voice bus. All three are the same MutationObserver differing only in the bus id, the event attribute, and the handler. - **The control-click dispatch**: one delegated `click` listener with a `t.closest(sel) -> handler; return` chain, same idiom in both files. ## What this adds A new `server/assets/rtc_common.js` exposing `window.LetsChatRtc`: - `watchBus(busId, eventAttr, handler)` - the drain, parameterized by exactly the three tokens that differed. - `bindControls(map)` - one delegated listener from a `selector -> fn(el, event)` map, matching the first selector the target is inside and short-circuiting, as the old if/else chains did. The handler gets `(el, event)`, which is what lets `call.js`'s start-button case keep its `preventDefault` + room/peer context extraction; every other case is a nullary handler. Loaded before both consumers; base.html is the only place these scripts load. ## Still surface-specific, on purpose Per LC-613, the media operations (mute/camera/screen) and the signaling frames stay per-file - they are genuinely different between one `RTCPeerConnection`, a mesh, and the SFU. This PR is machinery only. ## No behaviour change (no JS harness, so verified by) - all three files parse (`node --check`) - the old inline MutationObserver idiom is gone from both consumers (0 occurrences), and the handler functions (`handleSignal`/`handleControl`/`handleEvent`) and the `watchBus()`/`watchControlBus()` registration sites are intact - the LC-614 server tests stay green - this touches no WS frame - load order is guaranteed: three ordered `defer` scripts, `rtc_common.js` first, so `window.LetsChatRtc` is defined before the consumers execute their IIFEs - an adversarial review confirmed each helper is behaviour-preserving against the originals: selector construction, observer config, the first-match short-circuit, the start-case `(el, e)` signature and its `isFinite` guard, and insertion-order dispatch (start checked first) `just check` clean. ## Net ~90 lines of duplication removed across two files for ~70 in one shared module - single source of truth. One new global namespace (`LetsChatRtc`), offset by the room global LC-613 already removed, so the overall global count is flat. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01FhDVMViNHqUbwmfe2aXTv5
refactor(rtc): extract the shared bus-drain and control-dispatch machinery (LC-616)
All checks were successful
check-secrets / Nosey parker (push) Successful in 5s
check-secrets / Kingfisher (push) Successful in 5s
check-secrets / TruffleHog (push) Successful in 9s
check-secrets / Nosey parker (pull_request) Successful in 6s
check-secrets / Kingfisher (pull_request) Successful in 6s
check-secrets / TruffleHog (pull_request) Successful in 12s
Check / clippy + fmt + tests (pull_request) Successful in 13m30s
Create release / Create release from merged PR (pull_request) Has been skipped
5dfa68faab
The mechanical follow-up deferred from LC-613. call.js and voice.js each opened a WebSocket "bus" that the server pushes OOB fragments into, and each bound one delegated click listener for its control bar. The drain loop was byte-for-byte identical across three copies (call.js has two buses: the call bus and the control bus; voice.js has the voice bus), and the click-dispatch idiom was the same in both files. They now live once in a new `rtc_common.js` (`window.LetsChatRtc.watchBus` + `.bindControls`), loaded before both consumers.

`watchBus(busId, eventAttr, handler)` is the MutationObserver drain, parameterized by the three tokens that were all that differed between the copies. `bindControls(map)` binds one delegated click listener from a `selector -> fn(el, event)` map, matching the first selector the target is inside and short-circuiting, exactly as the old if/else chains did. The handler receives the matched element and the event, which is what lets call.js's special start-button case keep its preventDefault + context extraction; every other case is a nullary handler.

Deliberately still surface-specific, per LC-613: the media operations (mute/camera/screen) and the signaling frames, which are genuinely different between one RTCPeerConnection, a mesh, and the SFU.

No behaviour change. There is no JS test harness, so: all three files parse, the old inline MutationObserver idiom is gone from both consumers (0 occurrences), the handler functions and registration sites are intact, the LC-614 server tests stay green (this touches no WS frame), load order is guaranteed by three ordered `defer` scripts with base.html the sole loader, and an adversarial review confirmed each helper is behaviour-preserving against the originals - selector construction, observer config, first-match short-circuit, the start-case (el, e) signature, and insertion-order dispatch.

Net: ~90 lines of duplication removed across two files for ~70 in one shared module, single source of truth. One new global namespace (`LetsChatRtc`), offset by the room global LC-613 already removed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhDVMViNHqUbwmfe2aXTv5
longjacksonle scheduled this pull request to auto merge when all checks succeed 2026-07-21 03:37:56 +02:00
longjacksonle deleted branch refactor/lc616-rtc-machinery 2026-07-21 03:39:27 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!575
No description provided.