# format ## Purpose Serialises `SseEvent` objects into the `text/event-stream` wire format defined by the WHATWG HTML Standard so the SSE handler can write framed bytes directly to the response body. Also exposes a small helper for the heartbeat comment frame that keeps idle connections alive through proxies. Pure functions — no I/O, no state, suitable for use anywhere in the runtime. ## Features - Canonical SSE framing: `id:`, `event:`, `retry:`, `data:` lines followed by the blank-line frame terminator. - Multi-line string payloads expanded to one `data:` line per source line per the spec, so browser-side parsers join them with `\n` automatically. - Non-string payloads passed through `JSON.stringify` so the wire format is always plain text. - `formatHeartbeatFrame()` emits a `:`-prefixed comment frame that EventSource ignores but proxies see as activity. ## Usage: Basic ```ts import { formatSseFrame } from "@suaveplan/api-plugin-sse/formatter/format"; const frame = formatSseFrame({ id: "42", event: "ping", data: { n: 1 } }); // "id: 42\nevent: ping\ndata: {\"n\":1}\n\n" controller.enqueue(new TextEncoder().encode(frame)); ``` ## Usage: Advanced ```ts import { formatHeartbeatFrame, formatSseFrame, } from "@suaveplan/api-plugin-sse/formatter/format"; // Manual stream construction that bypasses the bundled handler. const stream = new ReadableStream({ start(controller) { const encoder = new TextEncoder(); const interval = setInterval(() => { controller.enqueue(encoder.encode(formatHeartbeatFrame())); }, 30_000); // ... wire up your own subscriber loop return () => clearInterval(interval); }, }); // retry: hint for client reconnect-after value const reconnectHint = formatSseFrame({ id: "0", retry: 5_000, data: "" }); ``` ## API Reference - `formatSseFrame(event: SseEvent): string` — returns the canonical wire-format string. `event.data` is JSON-stringified when not already a string; multi-line strings are split into one `data:` line per source line. - `formatHeartbeatFrame(): string` — returns `": heartbeat\n\n"`. EventSource ignores comment frames; HTTP intermediaries observe activity and keep the connection open. ## Implementation Notes - The serialiser inserts a single space after the colon (`id: 42`, not `id:42`). The space is per spec recommendation and is stripped by the browser parser. - Binary payloads are not supported — the wire format is line-oriented text. Base64-encode binary data into a string field if you need to transmit blobs. - Field ordering (`id`, `event`, `retry`, `data`) is consistent across every call so dashboards relying on byte-level matching see stable output. The spec does not mandate ordering, but consistency simplifies snapshot tests downstream.