87 lines
4.0 KiB
Markdown
87 lines
4.0 KiB
Markdown
# 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
|
|
|
|
- [x] Create `universal/network/network-websockets/` with `src/`, `tests/`, and all feature subdirectories.
|
|
- [x] Write `package.json` at version `0.1.0`: `"sideEffects": false`, exports map, deps per `proposal.md`.
|
|
- [x] Write `tsconfig.json` extending `@suaveplan/typescript-config/library.json`.
|
|
- [x] Write `vitest.config.ts` using `createTestConfig()`.
|
|
- [x] Add `lint`, `typecheck`, `test`, `test:coverage`, `build`, `docs:check` scripts.
|
|
|
|
---
|
|
|
|
## 2. Types and error codes
|
|
|
|
- [x] Define all public types in `src/types/common.ts`: `WebSocketClientOptions`, `WebSocketMessage`, `MessageMeta`, `ReconnectOptions`, `HeartbeatOptions`, `ConnectionState`, `ConnectionEvent`, `MessageHandler`, `WebSocketAdapter`, `WebSocketHandle`.
|
|
- [x] Write `src/types/common.md` (≥200 words, simple + advanced examples).
|
|
- [x] Define error codes in `src/error-codes.ts`: `NetworkWebsocketsErrorCode` union, metadata, `registerNetworkWebsocketsErrorCodes()`.
|
|
- [x] Write Zod schemas in `src/types/schemas.ts` + `src/types/schemas.md`.
|
|
|
|
---
|
|
|
|
## 3. Message queue (`src/core/queue/`)
|
|
|
|
- [x] Implement bounded `MessageQueue` (ring buffer, `maxQueueSize`).
|
|
- [x] `enqueue(message)` — returns `false` and throws `NetworkWebsocketsError(WS_QUEUE_FULL)` when full.
|
|
- [x] `dequeue()` / `drain()` — returns next message or all queued.
|
|
- [x] Write `queue.test.ts` + `queue.md`.
|
|
|
|
---
|
|
|
|
## 4. Heartbeat (`src/core/heartbeat/`)
|
|
|
|
- [x] 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.
|
|
- [x] Write `heartbeat.test.ts` + `heartbeat.md`.
|
|
|
|
---
|
|
|
|
## 5. Native WebSocket adapter (`src/adapters/`)
|
|
|
|
- [x] Implement `createNativeWebSocketAdapter()` — wraps `globalThis.WebSocket` (browser) or `Bun.WebSocket` (Bun server).
|
|
- [x] Guard with platform check; throw `WS_CONNECTION_FAILED` if WebSocket not available.
|
|
- [x] 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/`)
|
|
|
|
- [x] Implement `createWebSocketClient(options)`:
|
|
- Validates options with Zod.
|
|
- Uses `options.adapter ?? createNativeWebSocketAdapter()`.
|
|
- State machine: `disconnected → connecting → connected`; reconnect loop via `@suaveplan/retry`.
|
|
- [x] Implement `client.connect(signal?)` — starts connection, heartbeat.
|
|
- [x] Implement `client.disconnect(code?, reason?)` — graceful close.
|
|
- [x] Implement `client.send(message, signal?)` — enqueues if not connected; drains queue on connect; serializes via `@suaveplan/serialize`.
|
|
- [x] Implement `client.subscribe(channel, handler)` — routes incoming messages by `message.channel`; returns unsubscribe.
|
|
- [x] Implement `client.on(event, handler)` — connection lifecycle events.
|
|
- [x] OTel: span `ws.connect`, counters `ws.messages_sent_total`, `ws.messages_received_total`.
|
|
- [x] Write `client.test.ts` (≤500 lines) using injectable fake adapter.
|
|
- [x] Write `client.md` (≥200 words).
|
|
|
|
---
|
|
|
|
## 7. Property-based tests (`tests/property.test.ts`)
|
|
|
|
- [x] Message queue invariants: `enqueue` count - `dequeue` count = current queue depth.
|
|
- [x] Channel routing: messages with `channel: 'X'` are always routed to `channel: 'X'` subscribers only.
|
|
|
|
---
|
|
|
|
## 8. Docs and verify
|
|
|
|
- [x] All per-file `.md` files per layout in `proposal.md`.
|
|
- [x] `universal/network/network-websockets/README.md`.
|
|
- [x] `bunx turbo lint typecheck test test:coverage --filter=@suaveplan/network-websockets` — all green, 100% coverage.
|
|
- [x] `bun scripts/publish.ts --package @suaveplan/network-websockets`.
|
|
- [x] Update `CLAUDE.md`. Archive change folder.
|