realtime

5 modules

  • realtime/outbound_budget.ts

    The byte budget of the frames waiting to be written to one connection — a WebSocket or an SSE stream.

    A producer never waits on a recipient: a broadcast is synchronous and called from anywhere, so a client that stopped reading makes the server hold what it has not taken. OutboundBudget is the bound on that, and it is accounting only — its owner holds the frames and decides what "waiting" means for its connection (WsOutboundWriter for a WebSocket, create_sse_response for an SSE stream).

    • The charge. Each waiting frame is charged its payload bytes — the UTF-8 length of its text — plus OUTBOUND_FRAME_OVERHEAD_BYTES.
    • The rule. A frame is admitted when the charges already waiting plus its own stay within the budget — and, whatever its size, when nothing is waiting, so a single message larger than the whole budget is deliverable.

    Nothing counts frames: any number may wait while their charges fit. The twin of the Rust spine's fuz_realtime outbound queue, with the same charge and the same rule.

  • realtime/sse_auth_guard.ts

    SSE auth guard, connection closer, and convenience factory for audit log SSE.

    An SSE stream is authorized once, at open, and then only emits — nothing re-reads its credential or its role. Two things close it when its access is revoked:

    create_audit_log_sse is a convenience factory that combines the registry, guard, closer, and broadcaster — making the secure path the easy path for consumers.

  • realtime/sse_constants.ts

    Hono-free SSE wire constants.

    Split from sse.ts (which pulls hono/streaming via streamSSE) so the stream-framing constants are importable by cross-process test suites asserting on the wire without dragging in the in-process Hono SSE implementation.

  • realtime/sse.ts

    SSE (Server-Sent Events) streaming utilities for Hono.

    Provides generic helpers for creating SSE response streams and a notification type aligned with JSON-RPC 2.0.

    Outbound bound

    SseStream.send never waits on its client: each frame is written to the response stream, which holds it until the client reads. What a stream holds unread is kept within SSE_OUTBOUND_QUEUE_BYTES — each frame charged its bytes as written (data: prefix and terminator included) plus OUTBOUND_FRAME_OVERHEAD_BYTES, and a frame always accepted when nothing is unread, so a single frame larger than the budget is still deliverable. A frame that does not fit ends the stream: it is not written, what was unread is dropped, the body ends with no final frame, and the stream's on_close listeners run. One warn line names the stream's account (when the caller passed it) and what was unread; no audit row is written, since each would itself be fanned to every stream. A client that is reading reconnects and misses the frames in between. The twin of the Rust spine's fuz_realtime SSE bound — the same budget and charge.

  • realtime/subscriber_registry.ts

    Generic subscriber registry for broadcasting to SSE clients.

    Supports channel-based filtering — subscribers connect with optional channel filters, and broadcasts reach only matching subscribers.

    Two identity slots enable both targeted disconnection and per-scope cap enforcement:

    • scope — a single capped identity (e.g., session hash). Subject to the per-scope cap and matched by close_by_identity. Use for the narrowest identity the subscriber belongs to.
    • groups — any number of uncapped identities (e.g., account id). Matched by close_by_identity but not subject to any cap. Use for coarser scopes a stream should be reachable by.

    The split keeps "tabs-per-session" cap semantics sane when a stream also carries a broader identity for coarse close — the broader identity doesn't cap across sessions.

    Registration can run in two phases (subscribe_pending then admit) so a revocation reaches a stream that is still opening — see the class doc.