# Tasks: enterprise-browser-network-webrtc **Change ID**: enterprise-browser-network-webrtc **Package**: `@suaveplan/network-webrtc` **Target path**: `browser/network/network-webrtc` **Prerequisite packages on Verdaccio**: `@suaveplan/network`, `@suaveplan/serialize`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events` --- ## 1. Scaffold - [x] Create `browser/network/network-webrtc/` directory tree per layout in `proposal.md`. - [x] Write `package.json` at version `0.1.0`: - `"sideEffects": false`; no `react` runtime dep - `exports`: `"."`, `"./webrtc"`, `"./dual-channel"`, `"./channel-router"`, `"./signaling"`, `"./config/ice-servers"` - `dependencies`: `@suaveplan/network workspace:^`, `@suaveplan/serialize workspace:^`, `@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`, `@suaveplan/events workspace:^`, `zod catalog:forms`, `@opentelemetry/api catalog:observability`, `tslib catalog:build` - `devDependencies`: `vitest catalog:testing`, `@vitest/coverage-istanbul catalog:testing`, `@playwright/test catalog:testing`, `@suaveplan/testing workspace:^` - `files`: `["dist", "src", "README.md"]` — `examples/` intentionally excluded - [x] Write `tsconfig.json` and `vitest.config.ts` (pool: forks). --- ## 2. Error codes (`src/error-codes.ts`) - [x] Define `WebRTCErrorCode`: `WEBRTC_DIAL_FAILED`, `WEBRTC_ICE_FAILED`, `WEBRTC_CHANNEL_CLOSED`, `WEBRTC_SIGNALING_TIMEOUT`, `WEBRTC_INVALID_STATE`. - [x] Export `registerWebRTCErrorCodes()` and call eagerly. --- ## 3. Signalling (`src/signaling/`) ### 3a. `signaling-channel/signaling-channel.ts` - [x] Define `SignalingChannel` interface with offer/answer/ICE methods. - [x] Implement `MemorySignalingChannel` for in-process testing (two paired instances). - [x] Add Zod schemas `OfferMessageSchema`, `AnswerMessageSchema`, `IceCandidateMessageSchema`; validate on receive. - [x] Write `signaling-channel.test.ts`, `signaling-channel.md`. ### 3b. `websocket-signaling/websocket-signaling.ts` - [x] Implement `WebSocketSignalingChannel` with reconnect on error. - [x] Write `websocket-signaling.test.ts`, `websocket-signaling.md`. --- ## 4. Peer connection (`src/webrtc/peer-connection/`) - [x] Implement `PeerConnection` wrapping `RTCPeerConnection`: - Perfect-negotiation pattern (`onnegotiationneeded` with polite-peer collision handling). - ICE-restart policy: detect `iceConnectionState === 'failed'`, call `restartIce()`, emit `'ice:restart'`. - Typed event emitter for `'state:change'`, `'ice:state:change'`, `'ice:restart'`, `'error'`. - [x] Write `peer-connection.test.ts`, `peer-connection.md`. --- ## 5. Data channel (`src/webrtc/data-channel/`) - [x] Implement `DataChannel` wrapping `RTCDataChannel` with `onMessage`, `send`, `close`, back-pressure watermark. - [x] Write `data-channel.test.ts`, `data-channel.md`. --- ## 6. Signalling handlers (`src/webrtc/signaling-handlers/`) - [x] Implement `SignalingHandlers`: route offer/answer/ICE-candidate events from `SignalingChannel` to `PeerConnection`. - [x] Write `signaling-handlers.test.ts`, `signaling-handlers.md`. --- ## 7. WebRTC transport (`src/webrtc/webrtc-transport/`) - [x] Implement `WebRTCTransport` composing `PeerConnection`, `DataChannel`, `SignalingHandlers`. - [x] Wire OTel counters + histograms from `src/error-codes.ts` metrics. - [x] Write `webrtc-transport.test.ts` (vitest, no describe.skip), `webrtc-transport.md`, `webrtc-transport.types.ts`. --- ## 8. Dual channel (`src/dual-channel/dual-channel/`) - [x] Implement `DualChannel` with reliable (ordered, maxRetransmits=10) and unreliable (unordered, maxRetransmits=0) channels. - [x] Back-pressure: track `bufferedAmount`; queue sends when > watermark. - [x] Write `dual-channel.test.ts`, `dual-channel.md`. --- ## 9. Channel router (`src/channel-router/channel-router/`) - [x] Implement `ChannelRouter` with register/unregister/route/send. - [x] Write `channel-router.test.ts`, `channel-router.md`. --- ## 10. ICE server config (`src/config/ice-servers/`) - [x] Export `STUN_SERVERS` (public Cloudflare STUN), `validateIceServers(servers)` (Zod), and builder helper. - [x] Write `ice-servers.md`. --- ## 11. Integration test (`tests/integration.test.ts`) - [x] Two in-process `WebRTCTransport` instances connected via `MemorySignalingChannel`: dial → send reliable + unreliable → receive → close. - [x] ICE-restart: simulate `iceConnectionState = 'failed'`; verify restart event fires and connection recovers. - [x] Flow-control: send above watermark; verify queuing without data loss. --- ## 12. Playwright E2E (`e2e/webrtc.spec.ts`) - [x] Two Chromium browser contexts; each runs a Vite-bundled test page. - [x] Signal via in-page `BroadcastChannel` acting as the `MemorySignalingChannel` equivalent. - [x] Assert: offer/answer/ICE/dial/send/close lifecycle; message received in both directions. --- ## 13. Docs - [x] Write `.md` per module (≥200 words, API reference, examples). - [x] Write `README.md` with subpath table, signalling matrix, ICE/TURN ops guidance, metrics table. --- ## 14. Verify and publish - [x] `bunx turbo lint typecheck test --filter=@suaveplan/network-webrtc` — green. - [x] `bunx turbo test:coverage --filter=@suaveplan/network-webrtc` — 100% on touched modules. - [x] `bun run docs:check --filter=@suaveplan/network-webrtc` — zero errors. - [x] No `describe.skip`, `vi.mock`, `vi.stubGlobal`, `any`, `ts-ignore` in `src/`. - [x] `react` not in runtime deps. - [x] Playwright E2E proves offer/answer/ICE/dial/send/close. - [x] `bun scripts/publish.ts --package @suaveplan/network-webrtc`. - [x] Archive to `openspec/archive/2026-04-24-enterprise-browser-network-webrtc/`.