@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 — Enforces the per-connection send-queue cap described in design §11.4. Each connection owns one
BackpressureGuardinst…- backpressure — Enforces the per-connection send-queue cap described in design §11.4. Each connection owns one
BackpressureGuardinst…
- backpressure — Enforces the per-connection send-queue cap described in design §11.4. Each connection owns one
- engine —
createBunWsEngineis the package's headline factory. It composes every other module in the package — registry, bus, i…- bun-ws-engine —
createBunWsEngineis the package's headline factory. It composes every other module in the package — registry, bus, i…
- bun-ws-engine —
- error-codes — Provides the stable error-code registry and the typed
WsBunErrorsubclass for@suaveplan/api-ws-bun. Every producti…- error-codes — Provides the stable error-code registry and the typed
WsBunErrorsubclass for@suaveplan/api-ws-bun. Every producti…
- error-codes — Provides the stable error-code registry and the typed
- handshake — Freezes the per-request pipeline result onto a per-connection
HandshakeOutcome. The host runs the standard pipeline s…- handshake — Freezes the per-request pipeline result onto a per-connection
HandshakeOutcome. The host runs the standard pipeline s… - subprotocol — Implements RFC 6455 §4.1 subprotocol negotiation as a tiny pure function. The server is supplied the client's requested…
- handshake — Freezes the per-request pipeline result onto a per-connection
- heartbeat — Implements the per-connection ping/pong state machine described in design §11.4. The engine instantiates one `Heartbeat…
- heartbeat — Implements the per-connection ping/pong state machine described in design §11.4. The engine instantiates one `Heartbeat…
- instruments — Builds the OTel instrument registry the engine emits to. The names, units, and attribute keys all match design doc §11.…
- instruments — Builds the OTel instrument registry the engine emits to. The names, units, and attribute keys all match design doc §11.…
- limits — Provides the per-tenant connection-count enforcement function that the handshake pipeline calls before admitting a new…
- tenant-cap — Provides the per-tenant connection-count enforcement function that the handshake pipeline calls before admitting a new…
- options — Defines the Zod-validated options surface accepted by
createBunWsEngine. Every field has a documented default sourced…- options — Defines the Zod-validated options surface accepted by
createBunWsEngine. Every field has a documented default sourced…
- options — Defines the Zod-validated options surface accepted by
- principal — Tracks the underlying token expiry for a frozen principal so the engine can drop the connection at the right moment. Th…
- principal-expiry — Tracks the underlying token expiry for a frozen principal so the engine can drop the connection at the right moment. Th…
- event-buffer — Provides the per-
(tenant, topic)reconnect-event buffer used to replay events to a reconnecting client whose `lastEve… - reconnect-token — Wraps the api-ws contract's
signReconnectToken/verifyReconnectTokenHMAC token helpers so the engine has a statef… - registry — Wraps the api-ws contract's
InMemoryConnectionRegistryto give the Bun engine a typed registry surface that the confo…- connection-registry — Wraps the api-ws contract's
InMemoryConnectionRegistryto give the Bun engine a typed registry surface that the confo…
- connection-registry — Wraps the api-ws contract's
- subscription — Builds the per-engine subscription bus instance and binds it to the engine's connection registry. The bus implementatio…
- subscription-bus — Builds the per-engine subscription bus instance and binds it to the engine's connection registry. The bus implementatio…
- testing — Binds the abstract
runWsEngineConformanceharness from@suaveplan/api-ws/testingto a defaultcreateBunWsEngine-b…- conformance-binding — Binds the abstract
runWsEngineConformanceharness from@suaveplan/api-ws/testingto a defaultcreateBunWsEngine-b…
- conformance-binding — Binds the abstract
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, tenraise*helpers.testing(subpath@suaveplan/api-ws-bun/testing) —runBunWsConformance,bunEngineFactory,adaptEngineToFactory.
Example
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
bunx turbo lint typecheck test:coverage --filter=@suaveplan/api-ws-bun