The unmodified Speaker and Controller below run the real protocol peer-to-peer over an
RTCDataChannel — no WebSocket hub relaying frames. The hub logic (timer, registry,
the reducers in shared/protocol.js) runs on whichever peer wins the host lock; the other
connects to it directly. ● negotiating…
BroadcastChannel, and the two
peers connect over loopback ICE — no STUN/TURN. For real cross-device P2P you swap this one
signaling channel for a network one (a serverless endpoint, or the hub used only as a signaler) and
add STUN — plus a TURN relay when peers can't connect directly. See
the demo home and docs/DEPLOY.md.