first commit
This commit is contained in:
57
docs/api-stack/api/api-plugin-sse/src/formatter/format.md
Normal file
57
docs/api-stack/api/api-plugin-sse/src/formatter/format.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# 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<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.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.
|
||||
Reference in New Issue
Block a user