Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
# `@suaveplan/api-ws-broker-in-memory` — In-memory WebSocket broker for tests
**Package**: `@suaveplan/api-ws-broker-in-memory`
**Status**: PROPOSED
**Type**: new-package
**Stage**: 5 (Testing kit + conformance suites) — see umbrella `openspec/changes/api-plugin-foundation/`
## Why
Per design doc §11, `api-ws` defines a `WsBroker` abstraction for subscription fan-out. Multi-host deployments wire this to Redis via `api-ws-broker-redis` (Stage 7). For tests AND single-host development, an in-memory broker is sufficient — it pumps published messages directly to every interested connection without crossing a network.
The package is a load-bearing piece of `createTestHost`: any plugin manifesting WebSocket endpoints can be tested end-to-end (connect → subscribe → publish → assert received) without spinning up Redis. The broker is production-grade for single-host topologies; "in-memory" describes implementation, not test-double status.
## What changes
Net-new package depending on `@suaveplan/api-ws` (contract + `./testing` conformance), `@suaveplan/api-types`, `@suaveplan/error`, `zod`.
- ADDED: `createInMemoryWsBroker(opts)` — factory returning a `WsBroker` (per `@suaveplan/api-types`) that maintains a per-subscription-topic set of connection ids and a `publish(topic, message)` method that delivers to every subscriber in O(subscribers).
- ADDED: `InMemoryWsBrokerOptions` — Zod schema (`maxSubscribersPerTopic?: number` (default unlimited), `deliveryMode: "fire-and-forget" | "await-all"` (default `"fire-and-forget"`)).
- ADDED: `subscribe(connectionId, topic)`, `unsubscribe(connectionId, topic)`, `publish(topic, message)`, `subscribersOf(topic)`, `cleanupConnection(connectionId)`.
- ADDED: `WS_BROKER_IN_MEMORY_*` error codes (`WS_BROKER_IN_MEMORY_MAX_SUBSCRIBERS_EXCEEDED`, `WS_BROKER_IN_MEMORY_INVALID_OPTIONS`).
- ADDED: Registered in `@suaveplan/api-host/testing`'s adapter table as `ws.broker: "in-memory"` (default for `createTestHost`).
## Out of scope
- Network distribution — by design.
- Reconnect token persistence — that lives in the WebSocket engine (`api-ws-bun` Stage 7), not the broker.
- Message persistence — broker is fan-out only; tests assert via `host.ws.connectionsOf(topic)` and direct connection observation.
## Source mapping
Genesis-original. Source of design intent: `docs/superpowers/specs/2026-05-13-api-plugin-foundation-design.md`.
| Requirement | Design doc section |
|---|---|
| Subscription bus + broker abstraction | §11.2, §11.3 |
| Single-host + test broker | §11.3 (final sentence) |
| Registered in `api-host/testing` adapter table | §15 Stage 5 |
## Verification approach
- `src/factory/create-in-memory-ws-broker.test.ts` — subscribe, publish, fan-out count; unsubscribe; cleanupConnection on disconnect.
- `src/factory/create-in-memory-ws-broker.spec-conformance.test.ts` — `runWsBrokerConformance("in-memory-direct", ...)`.
- `src/delivery/delivery-mode.test.ts` — `"await-all"` waits for every subscriber's handler to settle; `"fire-and-forget"` returns synchronously.
- `tests/integration/integration.test.ts` — via `createTestHost`; full subscribe-then-publish flow against a plugin manifesting a WS endpoint.
## Migration impact
None — additive only.