# @suaveplan/api-ws-bun - Bun.serve-backed WebSocket engine for @suaveplan/api-ws. Implements the abstract WsEngine contract using Bun's native WebSocket primitives: handshake pipeline freezing the principal, per-tenant ConnectionRegistry, SubscriptionBus integration, backpressure eviction (default 256 msg queue), heartbeat (30s ping / 2 missed-pong drop), per-tenant caps (1000), HMAC-signed reconnect tokens (5-min TTL) with auto/memory/broker event-buffer strategies, and the OTel surface from design §11.7. Passes runWsEngineConformance. Bun.serve-backed WebSocket engine for the `@suaveplan/api-ws` Stage-1 abstract contract. The engine composes the per-connection handshake pipeline, registry, subscription bus, backpressure guard, heartbeat controller, principal-expiry watcher, reconnect-token issuer, reconnect-event buffer, and OTel surface into one `createBunWsEngine(opts)` factory call. Passes `runWsEngineConformance` and ships a real `Bun.serve` integration smoke under `tests/integration/`. ## Documentation tree - [backpressure](./src/backpressure/backpressure.md) — Enforces the per-connection send-queue cap described in design §11.4. Each connection owns one `BackpressureGuard` inst… - [backpressure](./src/backpressure/backpressure.md) — Enforces the per-connection send-queue cap described in design §11.4. Each connection owns one `BackpressureGuard` inst… - [engine](./src/engine/bun-ws-engine.md) — `createBunWsEngine` is the package's headline factory. It composes every other module in the package — registry, bus, i… - [bun-ws-engine](./src/engine/bun-ws-engine.md) — `createBunWsEngine` is the package's headline factory. It composes every other module in the package — registry, bus, i… - [error-codes](./src/error-codes/error-codes.md) — Provides the stable error-code registry and the typed `WsBunError` subclass for `@suaveplan/api-ws-bun`. Every producti… - [error-codes](./src/error-codes/error-codes.md) — Provides the stable error-code registry and the typed `WsBunError` subclass for `@suaveplan/api-ws-bun`. Every producti… - [handshake](./src/handshake/handshake.md) — Freezes the per-request pipeline result onto a per-connection `HandshakeOutcome`. The host runs the standard pipeline s… - [handshake](./src/handshake/handshake.md) — Freezes the per-request pipeline result onto a per-connection `HandshakeOutcome`. The host runs the standard pipeline s… - [subprotocol](./src/handshake/subprotocol.md) — Implements RFC 6455 §4.1 subprotocol negotiation as a tiny pure function. The server is supplied the client's requested… - [heartbeat](./src/heartbeat/heartbeat.md) — Implements the per-connection ping/pong state machine described in design §11.4. The engine instantiates one `Heartbeat… - [heartbeat](./src/heartbeat/heartbeat.md) — Implements the per-connection ping/pong state machine described in design §11.4. The engine instantiates one `Heartbeat… - [instruments](./src/instruments/instruments.md) — Builds the OTel instrument registry the engine emits to. The names, units, and attribute keys all match design doc §11.… - [instruments](./src/instruments/instruments.md) — Builds the OTel instrument registry the engine emits to. The names, units, and attribute keys all match design doc §11.… - [limits](./src/limits/tenant-cap.md) — Provides the per-tenant connection-count enforcement function that the handshake pipeline calls before admitting a new… - [tenant-cap](./src/limits/tenant-cap.md) — Provides the per-tenant connection-count enforcement function that the handshake pipeline calls before admitting a new… - [options](./src/options/options.md) — Defines the Zod-validated options surface accepted by `createBunWsEngine`. Every field has a documented default sourced… - [options](./src/options/options.md) — Defines the Zod-validated options surface accepted by `createBunWsEngine`. Every field has a documented default sourced… - [principal](./src/principal/principal-expiry.md) — Tracks the underlying token expiry for a frozen principal so the engine can drop the connection at the right moment. Th… - [principal-expiry](./src/principal/principal-expiry.md) — Tracks the underlying token expiry for a frozen principal so the engine can drop the connection at the right moment. Th… - [event-buffer](./src/reconnect/event-buffer.md) — Provides the per-`(tenant, topic)` reconnect-event buffer used to replay events to a reconnecting client whose `lastEve… - [reconnect-token](./src/reconnect/reconnect-token.md) — Wraps the api-ws contract's `signReconnectToken` / `verifyReconnectToken` HMAC token helpers so the engine has a statef… - [registry](./src/registry/connection-registry.md) — Wraps the api-ws contract's `InMemoryConnectionRegistry` to give the Bun engine a typed registry surface that the confo… - [connection-registry](./src/registry/connection-registry.md) — Wraps the api-ws contract's `InMemoryConnectionRegistry` to give the Bun engine a typed registry surface that the confo… - [subscription](./src/subscription/subscription-bus.md) — Builds the per-engine subscription bus instance and binds it to the engine's connection registry. The bus implementatio… - [subscription-bus](./src/subscription/subscription-bus.md) — Builds the per-engine subscription bus instance and binds it to the engine's connection registry. The bus implementatio… - [testing](./src/testing/conformance-binding.md) — Binds the abstract `runWsEngineConformance` harness from `@suaveplan/api-ws/testing` to a default `createBunWsEngine`-b… - [conformance-binding](./src/testing/conformance-binding.md) — Binds the abstract `runWsEngineConformance` harness from `@suaveplan/api-ws/testing` to a default `createBunWsEngine`-b… ## Defaults | Option | Default | Source | |---|---|---| | `maxQueuedMessages` | `256` | §11.4 | | `heartbeatMs` | `30_000` (min 5_000) | §11.4 | | `missedPongLimit` | `2` | §11.4 | | `maxConnectionsPerTenant` | `1_000` | §11.4 | | `reconnectTokenTtlMs` | `300_000` | §11.5 | | `reconnectEventBufferStrategy` | `"auto"` | §11.5 + §14 | | `reconnectEventBufferLimit` | `256` | engine | | `subprotocols` | `[]` | engine | | `pluginId` | `"api-ws-bun"` | engine | ## Modules - `engine` — `createBunWsEngine`, `ManagedConnection`, `BunWsSocketSink`. - `options` — `BunWsEngineOptions`, `bunWsEngineOptionsSchema`, `resolveBunWsEngineOptions`. - `handshake` — `runHandshake`, `resolveSubprotocol`. - `registry` — `BunConnectionRegistry`. - `subscription` — `createBunSubscriptionBus`. - `backpressure` — `BackpressureGuard`. - `heartbeat` — `HeartbeatController`. - `limits` — `enforceTenantCap`. - `principal` — `PrincipalExpiryWatcher`. - `reconnect` — `ReconnectTokenIssuer`, `MemoryReconnectEventBuffer`, `BrokerReconnectEventBuffer`, `resolveReconnectEventBuffer`. - `instruments` — `createBunWsInstruments` (every §11.7 instrument). - `error-codes` — `WS_BUN_CODES`, `WsBunError`, ten `raise*` helpers. - `testing` (subpath `@suaveplan/api-ws-bun/testing`) — `runBunWsConformance`, `bunEngineFactory`, `adaptEngineToFactory`. ## Example ```ts import { createBunWsEngine } from "@suaveplan/api-ws-bun"; import { createInMemoryWsBroker } from "@suaveplan/api-ws-broker-in-memory"; const broker = createInMemoryWsBroker(); const engine = createBunWsEngine({ reconnectTokenSecret: new Uint8Array(32).fill(7), broker, }); Bun.serve({ port: 8787, fetch(req, srv) { if (new URL(req.url).pathname === "/ws") { return srv.upgrade(req, { data: { id: crypto.randomUUID() } }) ? undefined : new Response("upgrade failed", { status: 400 }); } return new Response("ok"); }, websocket: { open(ws) { engine.attach({ id: ws.data.id, principal, tenantId, capabilities: new Set(), tokenExpiresAt: Date.now() + 3_600_000, sink: { send: (s) => ws.send(s), close: (c, r) => ws.close(c, r), ping: () => ws.ping?.(), }, }); }, message() {}, close() {}, }, }); ``` ## Tests ```bash bunx turbo lint typecheck test:coverage --filter=@suaveplan/api-ws-bun ```