Files
suaveplan/openspec/archive/2026-05-12-enterprise-network-websockets/tasks.md
2026-05-27 23:29:53 +01:00

4.0 KiB

Tasks: enterprise-network-websockets

Change ID: enterprise-network-websockets Package: @suaveplan/network-websockets Target path: universal/network/network-websockets Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/events, @suaveplan/logger, @suaveplan/retry, @suaveplan/serialize


1. Scaffold

  • Create universal/network/network-websockets/ with src/, tests/, and all feature subdirectories.
  • Write package.json at version 0.1.0: "sideEffects": false, exports map, deps per proposal.md.
  • Write tsconfig.json extending @suaveplan/typescript-config/library.json.
  • Write vitest.config.ts using createTestConfig().
  • Add lint, typecheck, test, test:coverage, build, docs:check scripts.

2. Types and error codes

  • Define all public types in src/types/common.ts: WebSocketClientOptions, WebSocketMessage, MessageMeta, ReconnectOptions, HeartbeatOptions, ConnectionState, ConnectionEvent, MessageHandler, WebSocketAdapter, WebSocketHandle.
  • Write src/types/common.md (≥200 words, simple + advanced examples).
  • Define error codes in src/error-codes.ts: NetworkWebsocketsErrorCode union, metadata, registerNetworkWebsocketsErrorCodes().
  • Write Zod schemas in src/types/schemas.ts + src/types/schemas.md.

3. Message queue (src/core/queue/)

  • Implement bounded MessageQueue (ring buffer, maxQueueSize).
  • enqueue(message) — returns false and throws NetworkWebsocketsError(WS_QUEUE_FULL) when full.
  • dequeue() / drain() — returns next message or all queued.
  • Write queue.test.ts + queue.md.

4. Heartbeat (src/core/heartbeat/)

  • Implement HeartbeatManager:
    • On start(), send a ping frame on every intervalMs interval (injectable Clock).
    • On pong received, reset timer.
    • On timeoutMs exceeded without pong, emit timeout event.
  • Write heartbeat.test.ts + heartbeat.md.

5. Native WebSocket adapter (src/adapters/)

  • Implement createNativeWebSocketAdapter() — wraps globalThis.WebSocket (browser) or Bun.WebSocket (Bun server).
  • Guard with platform check; throw WS_CONNECTION_FAILED if WebSocket not available.
  • Write native-adapter.test.ts (uses fake adapter from @suaveplan/network-testing if available, else skipped) + native-adapter.md.

6. WebSocket client (src/core/client/)

  • Implement createWebSocketClient(options):
    • Validates options with Zod.
    • Uses options.adapter ?? createNativeWebSocketAdapter().
    • State machine: disconnected → connecting → connected; reconnect loop via @suaveplan/retry.
  • Implement client.connect(signal?) — starts connection, heartbeat.
  • Implement client.disconnect(code?, reason?) — graceful close.
  • Implement client.send(message, signal?) — enqueues if not connected; drains queue on connect; serializes via @suaveplan/serialize.
  • Implement client.subscribe(channel, handler) — routes incoming messages by message.channel; returns unsubscribe.
  • Implement client.on(event, handler) — connection lifecycle events.
  • OTel: span ws.connect, counters ws.messages_sent_total, ws.messages_received_total.
  • Write client.test.ts (≤500 lines) using injectable fake adapter.
  • Write client.md (≥200 words).

7. Property-based tests (tests/property.test.ts)

  • Message queue invariants: enqueue count - dequeue count = current queue depth.
  • Channel routing: messages with channel: 'X' are always routed to channel: 'X' subscribers only.

8. Docs and verify

  • All per-file .md files per layout in proposal.md.
  • universal/network/network-websockets/README.md.
  • bunx turbo lint typecheck test test:coverage --filter=@suaveplan/network-websockets — all green, 100% coverage.
  • bun scripts/publish.ts --package @suaveplan/network-websockets.
  • Update CLAUDE.md. Archive change folder.