Files
2026-05-27 23:29:53 +01:00

72 lines
7.1 KiB
Markdown

# @suaveplan/api-ws - Abstract WebSocket engine contract for the Suaveplan API foundation — Connection, ConnectionRegistry, SubscriptionBus, WsBroker, reconnect-token envelope, backpressure + heartbeat policies, cross-tenant capability gate, and a runWsEngineConformance harness. contracts only; concrete engines (api-ws-bun) and brokers (api-ws-broker-redis / -in-memory) plug behind these interfaces.
> Stage-1 abstract WebSocket contract for the Suaveplan API plugin system.
Universal contract package. Defines the canonical interfaces every concrete
WebSocket engine (`api-ws-bun`, future browser shims) and broker
(`api-ws-broker-in-memory`, `api-ws-broker-redis`) plugs behind. Ships a
single-host in-memory `ConnectionRegistry` + `SubscriptionBus` so the
conformance harness has an executable reference, plus the cross-tenant
capability gate documented in design doc §11.2.
<!-- begin:auto-docs -->
## Documentation tree
- [backpressure](./src/backpressure/backpressure.md) — Per design doc §11.4, every WebSocket connection MUST have a bounded outbound queue. This module owns the abstract poli…
- [backpressure](./src/backpressure/backpressure.md) — Per design doc §11.4, every WebSocket connection MUST have a bounded outbound queue. This module owns the abstract poli…
- [broker](./src/broker/broker.md) — A single-host deployment never needs a broker — the `SubscriptionBus` inside that process already sees every connection…
- [broker](./src/broker/broker.md) — A single-host deployment never needs a broker — the `SubscriptionBus` inside that process already sees every connection…
- [capability-id](./src/capability-id/capability-id.md) — `@suaveplan/api-types/capabilities` owns the closed `CapabilityId` union for the whole API foundation. `@suaveplan/api-…
- [capability-id](./src/capability-id/capability-id.md) — `@suaveplan/api-types/capabilities` owns the closed `CapabilityId` union for the whole API foundation. `@suaveplan/api-…
- [connection](./src/connection/connection.md) — `@suaveplan/api-ws/connection` declares the abstract `WsConnection` interface every concrete engine (`api-ws-bun`, futu…
- [connection](./src/connection/connection.md) — `@suaveplan/api-ws/connection` declares the abstract `WsConnection` interface every concrete engine (`api-ws-bun`, futu…
- [connection-registry](./src/connection-registry/connection-registry.md) — Every plugin endpoint that opens a WebSocket connection registers it with a host-owned `ConnectionRegistry`. The regist…
- [connection-registry](./src/connection-registry/connection-registry.md) — Every plugin endpoint that opens a WebSocket connection registers it with a host-owned `ConnectionRegistry`. The regist…
- [envelope](./src/envelope/envelope.md) — `@suaveplan/api-ws/envelope` owns the canonical Zod schema for every WebSocket frame that flows between the host and a…
- [envelope](./src/envelope/envelope.md) — `@suaveplan/api-ws/envelope` owns the canonical Zod schema for every WebSocket frame that flows between the host and a…
- [error-codes](./src/error-codes/error-codes.md) — `@suaveplan/api-ws` owns the abstract WebSocket contract. Every public failure path raises a `WsError` carrying a stabl…
- [error-codes](./src/error-codes/error-codes.md) — `@suaveplan/api-ws` owns the abstract WebSocket contract. Every public failure path raises a `WsError` carrying a stabl…
- [heartbeat](./src/heartbeat/heartbeat.md) — Every WebSocket connection that the Suaveplan API host accepts is policed by a heartbeat: the engine pings at a fixed c…
- [heartbeat](./src/heartbeat/heartbeat.md) — Every WebSocket connection that the Suaveplan API host accepts is policed by a heartbeat: the engine pings at a fixed c…
- [reconnect-token](./src/reconnect-token/reconnect-token.md) — When the host closes a WebSocket connection cleanly (heartbeat failure, deploy, transient network issue), it issues a r…
- [reconnect-token](./src/reconnect-token/reconnect-token.md) — When the host closes a WebSocket connection cleanly (heartbeat failure, deploy, transient network issue), it issues a r…
- [subscription-bus](./src/subscription-bus/subscription-bus.md) — `SubscriptionBus` is the broadcast surface every plugin uses to fan a payload out to every subscribed connection on the…
- [subscription-bus](./src/subscription-bus/subscription-bus.md) — `SubscriptionBus` is the broadcast surface every plugin uses to fan a payload out to every subscribed connection on the…
- [testing](./src/testing/conformance.md) — Every concrete WebSocket engine and broker the foundation publishes (`api-ws-bun`, `api-ws-broker-in-memory`, `api-ws-b…
- [conformance](./src/testing/conformance.md) — Every concrete WebSocket engine and broker the foundation publishes (`api-ws-bun`, `api-ws-broker-in-memory`, `api-ws-b…
<!-- end:auto-docs -->
## Modules
| Subpath | Purpose |
|---|---|
| `./connection` | `WsConnection` interface, `WsConnectionState`, `SubscriptionFilter`, `SubscribeOptions`. [docs](./src/connection/connection.md) |
| `./connection-registry` | `ConnectionRegistry` interface + `InMemoryConnectionRegistry` with `(tenantId)` and `(topic, tenantId)` indices. [docs](./src/connection-registry/connection-registry.md) |
| `./subscription-bus` | `SubscriptionBus<Payload>` + `InMemorySubscriptionBus`; cross-tenant capability gate. [docs](./src/subscription-bus/subscription-bus.md) |
| `./broker` | `WsBroker` multi-host fan-out contract — `publish`, `subscribe`, `dispose`. [docs](./src/broker/broker.md) |
| `./envelope` | `WsEnvelope` Zod schema for wire frames; strict mode rejects unknown keys. [docs](./src/envelope/envelope.md) |
| `./backpressure` | `BackpressurePolicy` + `evaluateBackpressure` (default `maxQueuedMessages = 256`). [docs](./src/backpressure/backpressure.md) |
| `./heartbeat` | `HeartbeatPolicy` + `evaluateHeartbeat` (default `heartbeatMs = 30000`, two missed pongs to abort). [docs](./src/heartbeat/heartbeat.md) |
| `./reconnect-token` | HMAC-SHA-256 reconnect-token envelope with 5-minute TTL; Web Crypto. [docs](./src/reconnect-token/reconnect-token.md) |
| `./capability-id` | `WS_CAPABILITY_IDS` re-exports for `"ws"` and `"ws.broadcast-cross-tenant"`. [docs](./src/capability-id/capability-id.md) |
| `./error-codes` | `WS_CODES` registry (8 codes) + `WsError` + engine throw helpers. [docs](./src/error-codes/error-codes.md) |
| `./testing` | `runWsEngineConformance` harness + `inMemoryFactory` reference. [docs](./src/testing/conformance.md) |
## Out of scope (this package)
- Concrete engines (`api-ws-bun`, browser shims) — .
- Concrete brokers (`api-ws-broker-redis`, `api-ws-broker-in-memory`) — Stages 5 / 7.
- The `graphql-ws` protocol wiring — that lives in `api-graphql` engine adapters,
which read this package's `SubscriptionBus`.
## Dependencies
- `@suaveplan/api-types workspace:^` — `Principal`, `TenantId`, `CapabilityId`.
- `@suaveplan/error workspace:^` — `defineCodes` + `SuaveplanError`.
- `@suaveplan/types workspace:^` — shared option bundles + clock contract.
- `zod catalog:forms` — wire-envelope schema (default-import form `import z from "zod"`).
- `tslib catalog:build`.
No transport dependencies — engines own that.