19 tasks covering core testing, Redis hardening, WebSocket client/server adapters, Worker adapter, and final review gates. Iroh adapters are tracked as a deferred placeholder blocked on the @alkdev/iroh fork. Phases: core validation → Redis hardening → review gate → WebSocket adapters → review gate → Worker adapter → review gate → final validation.
56 lines
2.6 KiB
Markdown
56 lines
2.6 KiB
Markdown
---
|
|
id: websocket-client-adapter
|
|
name: Implement WebSocket client event target adapter
|
|
status: pending
|
|
depends_on: [review-core-and-redis]
|
|
scope: moderate
|
|
risk: medium
|
|
impact: component
|
|
level: implementation
|
|
---
|
|
|
|
## Description
|
|
|
|
Implement the `createWebSocketClientEventTarget` adapter as specified in `docs/architecture/event-targets/websocket-client.md`.
|
|
|
|
This is a symmetric (single-connection) adapter that wraps a `WebSocket` connection for the spoke/client side. It's bidirectional — can both send and receive events. It must implement subscription forwarding using `__subscribe`/`__unsubscribe` control events per ADR-003.
|
|
|
|
Key requirements from the architecture:
|
|
- Takes an already-connected `WebSocket` (caller handles connection lifecycle)
|
|
- `dispatchEvent` → `ws.send(JSON.stringify(event.detail))`
|
|
- `addEventListener` → register local listener + send `__subscribe` control event on first listener for topic
|
|
- `removeEventListener` → remove local listener + send `__unsubscribe` when no listeners remain
|
|
- Subscription reference counting: `__subscribe` sent only on first `addEventListener` per topic
|
|
- Malformed JSON from server → silently ignored, log warning
|
|
- Control events (`__subscribe`, `__unsubscribe`) received from server → silently ignored
|
|
- `ws.send()` failure → error propagates to caller, no retry
|
|
|
|
## Acceptance Criteria
|
|
|
|
- [ ] `src/event-target-websocket-client.ts` exists
|
|
- [ ] Implements `createWebSocketClientEventTarget(ws: WebSocket): TypedEventTarget<TEvent>`
|
|
- [ ] `dispatchEvent` serializes envelope and calls `ws.send()`
|
|
- [ ] `addEventListener` registers local listener and sends `__subscribe` on first listener for topic
|
|
- [ ] Subscription reference counting: only one `__subscribe` per topic regardless of listener count
|
|
- [ ] `removeEventListener` removes local listener and sends `__unsubscribe` when no listeners remain
|
|
- [ ] Malformed JSON messages from server are silently ignored (logged)
|
|
- [ ] Control events received from server are silently ignored
|
|
- [ ] `ws.onmessage` parses envelope, creates `CustomEvent` with `type:id` topic, dispatches to listeners
|
|
- [ ] `ws.send()` failure propagates to caller
|
|
- [ ] No comments in source code (project convention)
|
|
- [ ] Sub-path export added to `package.json` and `tsup.config.ts`
|
|
- [ ] Barrel re-export added to `src/index.ts`
|
|
|
|
## References
|
|
|
|
- docs/architecture/event-targets/websocket-client.md
|
|
- docs/architecture/decisions/003-subscription-control-protocol.md
|
|
- src/types.ts (TypedEventTarget, TypedEvent, EventEnvelope)
|
|
|
|
## Notes
|
|
|
|
> To be filled by implementation agent
|
|
|
|
## Summary
|
|
|
|
> To be filled on completion |