Skip to content

LiveConnection WS Client

src/lib/offline/live.ts is the client end of event push (ADR-011). It holds the live WebSocket to the user’s SyncInbox and, on each signal, triggers the existing delta-read reconcilers — the socket replaces the polling timer, not the data path.

  • createLiveConnection(deps) — opens/closes the socket on lifecycle (foreground + online + signed-in), runs a catch-up ?since read on connect, and reconnects with backoff.
  • reconnectDelayMs(...) — backoff with jitter, capped at RECONNECT_CAP_MS (30 s).
  • createSignalCoalescer(...) — debounces bursts per surface (~500 ms) so many signals collapse into one refresh.
  • mapSurfaceTags(tags, active) — maps signal surface tags to the surfaces the client should refresh.
  • Self-mutation suppressionnoteLocalMutation(tags) records the surfaces a local write just touched; takeUnsuppressedTags(tags) filters those out of an incoming signal so a client does not redundantly re-read its own change. SYNC_STREAM_PATH is /api/v1/sync/stream.
  • StategetLiveState() / subscribeLiveState(listener) expose transport state (live / reconnecting-fallback / offline) for the status UI.

While the socket is down, a slow polling fallback (PollController, src/lib/offline/poll.ts) drives refreshes, and every reconnect performs a catch-up read — so convergence and offline-first are preserved regardless of socket health (ADR-006 → ADR-011).

Related: SyncInbox Durable Object (the server end), Sync-Core Reconcilers (what a signal triggers), Poll Controller (the fallback).