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

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

  1. Zod message envelope schema — { type: string, topic?: string, payload: unknown, id?: string } validated on every inbound message.
  2. OTel — ws.connections_active gauge, ws.messages_received_total / ws.messages_sent_total counters, ws.message_processing_duration_ms histogram.
  3. Heartbeat — ping frame sent every heartbeatIntervalMs (default 30 s); connection closed if pong not received within pingTimeoutMs (default 10 s).
  4. Backpressure — outbound send queue per connection; drops oldest messages when full (with counter ws.queue_drops_total).
  5. Topic-based pub/sub — connection.subscribe(topic) / gateway.publish(topic, msg) fan-out.
  6. 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.