# `bun-sse-engine` _(no submodules)_ ## Purpose The `bun-sse-engine` module exports `createBunSseEngine`, the factory the host calls to mount Server-Sent Events on top of `Bun.serve`. The factory wires the seven collaborators (options, subscription bus, tenant cap, event buffer, instruments, handshake pipeline, active connection registry) into one cohesive engine value. Plugin authors never touch the internals — they hand the engine to the host's router which calls `engine.acceptRequest(...)` on every matching GET request. ## Features - Single factory: validated options, broker- or in-memory event buffer selected automatically, shared subscription bus exposed for the WS engine to plug into. - `acceptRequest({ request, path, topic })` runs the full handshake pipeline and returns the 200 streaming `Response`. - `publish(envelope)` shortcut: append to the buffer + broadcast on the bus in one call — used by plugins that publish in-process. - `activeConnections` map for observability dashboards (size, tenant distribution, oldest open). - `buildReplayBuffer` exposed for the conformance harness so the engine's ring-buffer semantics are pinned by the same test path every other engine uses. ## Usage: Basic ```ts import { createBunSseEngine } from "@suaveplan/api-sse-bun"; const engine = createBunSseEngine({ authenticate: async () => ({ tenantId: "acme" as never, principal: null, }), }); // ...wire engine.acceptRequest into a Bun.serve handler... engine.dispose(); ``` ## Usage: Advanced ```ts import { createBunSseEngine } from "@suaveplan/api-sse-bun"; import Bun from "bun"; const engine = createBunSseEngine({ eventBufferSize: 512, eventBufferMs: 600_000, keepAliveCommentMs: 30_000, maxConnectionsPerTenant: 5_000, compressionEnabled: true, retryMs: 4_000, authenticate: async (req) => { const tenant = req.headers.get("x-tenant"); if (tenant === null) return { tenantId: null, principal: null }; return { tenantId: tenant as never, principal: null }; }, }); Bun.serve({ port: 0, async fetch(request) { const url = new URL(request.url); if (url.pathname === "/sse/audit") { return engine.acceptRequest({ request: { headers: request.headers, url: request.url, method: request.method, }, path: url.pathname, topic: "audit", }); } return new Response("not found", { status: 404 }); }, }); ``` ## API Reference - `interface SseAcceptInputs` — `{ request, path, topic }`. - `interface BunSseEngine` — `bus`, `cap`, `buffer`, `instruments`, `options`, `activeConnections`, `acceptRequest(inputs)`, `publish(envelope)`, `dispose()`, `buildReplayBuffer(opts?)`. - `function createBunSseEngine(options: BunSseEngineOptions): BunSseEngine`. - `function aggregateConnectionSnapshot(active, plugin): readonly { plugin, path, tenant, value }[]` — exported so OTel snapshots can be exercised in tests independent of the global meter provider. ## Implementation Notes The factory does not start any background timers — every long-lived resource (keep-alive scheduler, gzip stream) is owned by the handshake pipeline and bound to a single connection. `dispose()` is a synchronous best-effort: it cancels the bus and clears the active map but does not eagerly close every open stream (the HTTP transport handles that when the underlying socket closes). The `connectionSnapshot` for the OTel gauge aggregates active connections per `(path, tenantId)` so dashboards can plot capacity per route per tenant without re-walking the connection set inside the SDK callback.