fix: add close() lifecycle methods to all adapters, fix WS client handler preservation, add Worker thread context guard
- Add close() to Redis, WS Client, WS Server, Worker Host, Worker Thread adapters for graceful teardown (cleanup subscriptions, restore handlers, clear maps) - WS Client now saves/restores original onmessage (consistent with WS Server) - WS Client dispatchEvent/addEventListener/removeEventListener are no-ops after close() - WS Server close() removes all connections and clears local listeners - Redis close() unsubscribes all channels and removes message listener - Worker Host/Thread close() restore original onmessage and clear callbacks - Worker Thread throws clear error if globalThis.postMessage is unavailable - Add double-call guard to WS Server removeConnection - Export new adapter interface types (RedisEventTarget, WebSocketClientEventTarget, etc.) - Add sideEffects: false to package.json for tree-shaking - Update architecture docs: lifecycle section, close() contract, adapter status updates - 22 new tests covering close(), handler restoration, idempotency, and context guard
This commit is contained in:
@@ -90,7 +90,7 @@ The `Repeater` automatically cleans up its `addEventListener` when the consumer
|
||||
|--------|--------|-------------|
|
||||
| `EventEnvelope<TType, TPayload>` | `types.ts` | Cross-platform envelope: `{ type, id, payload }`. JSON-serializable. |
|
||||
| `TypedEvent<TType, TDetail>` | `types.ts` | Event with typed `type` and `detail`. Omits `CustomEvent`'s untyped fields. |
|
||||
| `TypedEventTarget<TEvent>` | `types.ts` | Extends `EventTarget` with typed `addEventListener`, `dispatchEvent`, `removeEventListener`. |
|
||||
| `TypedEventTarget<TEvent>` | `types.ts` | Extends `EventTarget` with typed `addEventListener`, `dispatchEvent`, `removeEventListener`. All adapters' `dispatchEvent` returns `true` (events are non-cancelable). |
|
||||
| `TypedEventListener<TEvent>` | `types.ts` | `(evt: TEvent) => void` |
|
||||
| `TypedEventListenerObject<TEvent>` | `types.ts` | `{ handleEvent(object: TEvent): void }` |
|
||||
| `TypedEventListenerOrEventListenerObject<TEvent>` | `types.ts` | Union of the above |
|
||||
@@ -99,6 +99,27 @@ The `Repeater` automatically cleans up its `addEventListener` when the consumer
|
||||
| `PubSubEvent<TEventMap, TType>` | `create_pubsub.ts` | Derived `TypedEvent` for a specific event type, with `detail` as `EventEnvelope<TType, TPayload>` |
|
||||
| `PubSubEventTarget<TEventMap>` | `create_pubsub.ts` | `TypedEventTarget<PubSubEvent<...>>` |
|
||||
|
||||
## Adapter Lifecycle
|
||||
|
||||
All transport adapters provide a `close()` method for graceful teardown. After `close()`:
|
||||
|
||||
- The adapter is unusable (no-op for `addEventListener`, `removeEventListener`, `dispatchEvent`)
|
||||
- All subscriptions are cleaned up (Redis channels unsubscribed, `__unsubscribe` sent for WebSocket topics, callbacks cleared)
|
||||
- Intercepted handlers are restored to their originals
|
||||
- The underlying transport (Redis connection, WebSocket, Worker) is **not** destroyed — the caller owns it
|
||||
|
||||
`close()` is idempotent. Calling it multiple times is safe.
|
||||
|
||||
Adapter return types reflect this:
|
||||
|
||||
| Adapter | Return type |
|
||||
|---------|-------------|
|
||||
| Redis | `RedisEventTarget<TEvent>` (extends `TypedEventTarget<TEvent>`, adds `close()`) |
|
||||
| WebSocket Client | `WebSocketClientEventTarget<TEvent>` (extends `TypedEventTarget<TEvent>`, adds `close()`) |
|
||||
| WebSocket Server | `WebSocketServerEventTarget<TEvent>` (extends `TypedEventTarget<TEvent>`, adds `addConnection`, `removeConnection`, `close()`) |
|
||||
| Worker Host | `WorkerHostEventTarget<TEvent>` (extends `TypedEventTarget<TEvent>`, adds `close()`) |
|
||||
| Worker Thread | `WorkerThreadEventTarget<TEvent>` (extends `TypedEventTarget<TEvent>`, adds `close()`) |
|
||||
|
||||
## Operators
|
||||
|
||||
All operators work with any `AsyncIterable`. Operators that return `Repeater` provide backpressure-aware push semantics.
|
||||
|
||||
Reference in New Issue
Block a user