2.8 KiB
2.8 KiB
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\nautomatically. - Non-string payloads passed through
JSON.stringifyso the wire format is always plain text. formatHeartbeatFrame()emits a:-prefixed comment frame that EventSource ignores but proxies see as activity.
Usage: Basic
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
import {
formatHeartbeatFrame,
formatSseFrame,
} from "@suaveplan/api-plugin-sse/formatter/format";
// Manual stream construction that bypasses the bundled handler.
const stream = new ReadableStream<Uint8Array>({
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.datais JSON-stringified when not already a string; multi-line strings are split into onedata: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, notid: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.