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_realtimeoutbound 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_sse_connection_closer adapts a SubscriberRegistry to ConnectionCloser, so the revocation handlers close streams directly after their transaction commits (queue_connection_close), whatever happens to the audit write.
- create_sse_auth_guard is the audit-event listener: it repeats those closes when the row is announced, and it is the only closer for a role revocation.
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 pullshono/streamingviastreamSSE) 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.sendnever 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'son_closelisteners run. Onewarnline 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'sfuz_realtimeSSE 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 byclose_by_identity. Use for the narrowest identity the subscriber belongs to.groups— any number of uncapped identities (e.g., account id). Matched byclose_by_identitybut 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_pendingthenadmit) so a revocation reaches a stream that is still opening — see the class doc.