5.1 KiB
OpenSpec Change: enterprise-websocket-gateway
- Change ID: enterprise-websocket-gateway
- Package:
@suaveplan/websocket-gateway - Category: api/framework
- Target path:
api/framework/websocket-gateway - Status: SUPERSEDED-BY-GENESIS-WAVE
- Date: 2026-04-24
Summary
Deliver @suaveplan/websocket-gateway on the genesis branch from scratch at enterprise quality. The package provides a WebSocket gateway layer for the Suaveplan API tier: connection lifecycle management (connect / disconnect / reconnect), message routing (topic-based publish/subscribe + RPC-style request/reply), authentication via JWT (injected @suaveplan/jwt-tenant verifier), per-connection rate limiting, backpressure via bounded send queues, heartbeat/ping-pong with configurable intervals, and a Hono WebSocket upgrade adapter. Backed by @suaveplan/events for internal message fan-out. Genesis adds structured errors, Zod message schemas, OTel instrumentation, and a benchmark suite.
Current-state audit (genesis)
Package does not exist on genesis — fresh build. No reference enterprise spec file found; design based on @suaveplan/api-gateway pattern and the Hono WebSocket API.
Available workspace deps on genesis
| Package | Role |
|---|---|
@suaveplan/error (workspace:^) |
WebSocketGatewayError hierarchy |
@suaveplan/types (workspace:^) |
LoggerLike, EventBusLike |
@suaveplan/logger (workspace:^) |
Per-connection structured logging |
@suaveplan/events (workspace:^) |
Internal topic fan-out |
@suaveplan/rate-limiter (workspace:^) |
Per-connection message rate limiting |
@suaveplan/api (workspace:^) |
Hono app type |
hono (catalog:server) |
upgradeWebSocket helper |
zod (catalog:forms) |
Message schema validation |
@opentelemetry/api (catalog:observability) |
Spans + metrics |
tslib (catalog:build) |
Runtime helpers |
Public API surface
Core
function createWebSocketGateway(options: WebSocketGatewayOptions): WebSocketGateway
interface WebSocketGateway {
handleUpgrade(app: HonoApp, path: string): void
publish(topic: string, message: unknown): void
broadcast(message: unknown): void
getConnection(id: string): WsConnection | undefined
connectionCount(): number
close(): Promise<void>
}
interface WsConnection {
id: string
userId?: string
tenantId?: string
subscribe(topic: string): void
unsubscribe(topic: string): void
send(message: unknown): void
close(): void
}
Types
interface WebSocketGatewayOptions {
maxConnections?: number
sendQueueSize?: number
heartbeatIntervalMs?: number
pingTimeoutMs?: number
rateLimiter?: RateLimiterLike
authenticate?: (token: string) => Promise<WsAuthResult>
logger?: LoggerLike
eventBus?: EventBusLike
}
interface WsAuthResult { userId: string; tenantId: string; claims: Record<string, unknown> }
type WsMessageHandler = (conn: WsConnection, message: unknown) => void | Promise<void>
Error codes
type WsGatewayErrorCode =
| "WS_MAX_CONNECTIONS"
| "WS_AUTH_FAILED"
| "WS_RATE_LIMITED"
| "WS_QUEUE_FULL"
| "WS_INVALID_MESSAGE"
| "WS_CONNECTION_NOT_FOUND"
Genesis additions
- Zod message envelope schema —
{ type: string, topic?: string, payload: unknown, id?: string }validated on every inbound message. - OTel —
ws.connections_activegauge,ws.messages_received_total/ws.messages_sent_totalcounters,ws.message_processing_duration_mshistogram. - Heartbeat — ping frame sent every
heartbeatIntervalMs(default 30 s); connection closed if pong not received withinpingTimeoutMs(default 10 s). - Backpressure — outbound send queue per connection; drops oldest messages when full (with counter
ws.queue_drops_total). - Topic-based pub/sub —
connection.subscribe(topic)/gateway.publish(topic, msg)fan-out. - Benchmark suite — measure message throughput and concurrent connection overhead.
File layout
api/framework/websocket-gateway/
package.json
tsconfig.json
vitest.config.ts
src/
index.ts
constants/index.ts
types/
common.ts
common.md
errors/
ws-errors.ts
ws-errors.md
ws-errors.test.ts
index.ts
core/
gateway/
gateway.ts
gateway.md
gateway.types.ts
gateway.test.ts
index.ts
connection/
connection.ts
connection.md
connection.test.ts
index.ts
router/
ws-router.ts
ws-router.md
ws-router.test.ts
index.ts
heartbeat/
heartbeat.ts
heartbeat.md
heartbeat.test.ts
index.ts
adapters/
hono-ws-adapter/
hono-ws-adapter.ts
hono-ws-adapter.md
hono-ws-adapter.test.ts
index.ts
__benchmarks__/
ws-gateway.bench.ts
tests/
integration.test.ts
Impact
Downstream: any real-time feature (notifications, live collaboration, chat). Prerequisites: @suaveplan/error, @suaveplan/types, @suaveplan/logger, @suaveplan/events, @suaveplan/rate-limiter, @suaveplan/api.