@tonytomo/gosocket-client 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +98 -0
- package/LICENSE.md +21 -0
- package/README.md +630 -2
- package/dist/index.d.ts +880 -0
- package/dist/index.js +3060 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the Browser WebSocket Client SDK (`@ws-server/ws-client`) will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.4.0] - 2026-10-29
|
|
9
|
+
|
|
10
|
+
### Added — JS SDK Phase J4 (Final Phase)
|
|
11
|
+
|
|
12
|
+
- **Error Classification & Recovery Policy (PROTOCOL.md §4.7)**:
|
|
13
|
+
- 18-row classification table mapping every protocol `ErrorCode` to SDK recovery actions (`fatal`, `drop_intent`, `app_prompt`, `retry_backoff`, `ignore`).
|
|
14
|
+
- Pure `classifyError(code, frame?, overrides?)` function supporting caller overrides via `ClientConfig.errorPolicy`.
|
|
15
|
+
- `errorClassified` event emitted immediately before raw `error` frames with code, action, retry delay, and optional raw frame.
|
|
16
|
+
- `AUTH_FAILED` ↔ `UNAUTHORIZED` unification: browser auth heuristic emits `errorClassified { code: 'UNAUTHORIZED', action: 'fatal' }` before emitting `fatal { code: 'AUTH_FAILED' }`.
|
|
17
|
+
- **Round-Trip Latency (RTT) Tracking & Ping API**:
|
|
18
|
+
- `client.ping(timeoutMs?)`: Explicit on-demand ping returning measured round-trip time in milliseconds, serialized to prevent interleaving.
|
|
19
|
+
- `client.rttStats()`: Latency summary (`last`, `min`, `max`, `mean` via exponential moving average $\alpha = 0.2$, `samples`), reset on every reconnect cycle and client close.
|
|
20
|
+
- Passive heartbeat RTT sampling enabled by default (opt-out via `heartbeat: { trackRtt: false }`).
|
|
21
|
+
- `rtt` event emitted with `{ sample, source: 'heartbeat' | 'on_demand', stats }`.
|
|
22
|
+
- **Local Pre-Send Validation (PROTOCOL.md §§3.1, 3.6)**:
|
|
23
|
+
- Strict validation of room names (`^[a-zA-Z0-9_-]{1,64}$`) and channel names (`^[a-zA-Z0-9_-]{1,32}$`).
|
|
24
|
+
- Rejection of reserved `'presence'` channel name for outbound message publishing.
|
|
25
|
+
- Maximum text payload limit (`maxTextPayloadBytes: 65024`, reserving 512 bytes for message envelope).
|
|
26
|
+
- Maximum binary payload limit (`maxBinaryPayloadBytes: 65535`).
|
|
27
|
+
- Client-side validation throwing `ValidationError` with field, rule, limit, and truncated value.
|
|
28
|
+
- Escape hatches: `validation: { enabled: false }` or direct `client.send(frame)` bypassing local validation to test raw wire frames.
|
|
29
|
+
- **Capability-Driven Pre-Flight Checks (PROTOCOL.md §8)**:
|
|
30
|
+
- Synchronous pre-flight checks in `createRoom()` against advertised `welcome.capabilities.limits`:
|
|
31
|
+
- `max_metadata_bytes`: JSON-encoded byte size check.
|
|
32
|
+
- `max_channels_per_room`: effective channel count check including `'presence'`, room preset channels, and custom channels.
|
|
33
|
+
- `max_rooms_per_key`: tracks owned rooms created on current connection, rejecting creation exceeding server limits before sending frames.
|
|
34
|
+
- Rejections throw `CapabilityLimitError` locally without sending wire frames or emitting `errorClassified`.
|
|
35
|
+
- **Live Conformance Suite & CI Runner**:
|
|
36
|
+
- Live conformance suite running in Vitest against real server binaries in `test/live/` with `ws` Node polyfill.
|
|
37
|
+
- Conformance test runner `scripts/live-conformance-js.sh` orchestrating primary (18080), binary-disabled (18081), and policy-violation (18082) server instances.
|
|
38
|
+
- GitHub Actions CI workflow running JS unit tests and live conformance suite.
|
|
39
|
+
|
|
40
|
+
## [0.3.0] - 2026-10-29
|
|
41
|
+
|
|
42
|
+
### Added — JS SDK Phase J3
|
|
43
|
+
|
|
44
|
+
- **Binary Channels (PROTOCOL.md §7)**:
|
|
45
|
+
- `BinaryMapBuilder` and `validateBinaryMap` ensuring channel IDs are integers in $[1, 254]$, rejecting reserved names (`""`, `"presence"`) and duplicate IDs/channels with construction-time validation.
|
|
46
|
+
- Global binary-ID uniqueness across rooms on a single connection (`binaryOwner` registry) with proactive pre-wire collision checks and `binaryIdCollision` event dispatch.
|
|
47
|
+
- Transactional reservation rollback when server join requests fail or reject.
|
|
48
|
+
- Inbound binary frame parsing using `ws.binaryType = 'arraybuffer'`, decoding 1-byte channel prefix and dispatching `binaryMessage` or `binaryUnknownChannel`.
|
|
49
|
+
- Binary publishing via `publishBinary` routing through reliable/unreliable lanes, shared token-bucket rate limiting, server backoff, and frame-type-distinct coalescing slots (`${room}:${channel}:binary`).
|
|
50
|
+
- **Presence Cache (PROTOCOL.md §6)**:
|
|
51
|
+
- Local cached roster tracking with typed events: `presenceJoin`, `presenceLeave`, `presenceInvalidated`, `roomDeleted`.
|
|
52
|
+
- Self-exclusion filtering in `knownMembers(room)` and `selfLabel` connection tracking from welcome frames.
|
|
53
|
+
- Server count tracking in `lastServerMemberCount(room)`.
|
|
54
|
+
- Protocol violation detection (`self presence event`, `unknown presence event`, `presence event missing who`, `malformed presence payload`, `empty binary frame`, `binary frame on presence channel`).
|
|
55
|
+
- Automatic reconnection invalidation marking presence caches stale (`invalidReason: 'reconnected'`) and requiring explicit `resetPresence(room)` to clear.
|
|
56
|
+
- **Sequence-Gap Detection (PROTOCOL.md §5.6)**:
|
|
57
|
+
- Per-`(room, channel)` monotonic sequence number tracking across text message frames.
|
|
58
|
+
- Forward sequence gap detection emitting `sequenceGap` with `prev`, `current`, `missed`, and `reliable` lane flag.
|
|
59
|
+
- Silent re-baselining on reconnection, backward sequences (e.g. room re-creation), duplicate sequences, and sequence 0.
|
|
60
|
+
- Optional `autoInvalidateOnReliableGap` configuration invalidating room presence caches when a sequence gap occurs on the reliable `presence` channel.
|
|
61
|
+
- **Delete Room Ackless Semantics**:
|
|
62
|
+
- `deleteRoom` resolves cleanly on incoming `room_deleted` presence frames with caller identification, removing room intents and executing complete state cleanup via `clearRoomState(room)`.
|
|
63
|
+
- **Comprehensive Cleanup Hooks (`clearRoomState`)**:
|
|
64
|
+
- Centralized eviction of binary owners, presence states, sequence states, rate limiters, coalescing slots, and applied policies upon room leave, delete, or session restore drop.
|
|
65
|
+
- **New Events & Errors**:
|
|
66
|
+
- Events: `binaryMessage`, `binaryUnknownChannel`, `binaryIdCollision`, `binaryMappingChanged`, `presenceJoin`, `presenceLeave`, `presenceInvalidated`, `roomDeleted`, `sequenceGap`, `protocolViolation`.
|
|
67
|
+
- Errors: `BinaryMapValidationError`, `BinaryMapExhaustedError`, `BinaryIdCollisionError`, `BinaryChannelUnmappedError`, `BinaryPayloadTooLargeError`.
|
|
68
|
+
|
|
69
|
+
## [0.2.0] - 2026-10-29
|
|
70
|
+
|
|
71
|
+
### Added — JS SDK Phase J2
|
|
72
|
+
|
|
73
|
+
- **Two-Lane Outbound Pipeline**: Reliable lane (bounded FIFO, drop-newest or close on overflow) and Unreliable lane (bounded FIFO, drop-oldest) matching server delivery semantics in PROTOCOL.md §5.4.
|
|
74
|
+
- **Channel Policy System**: `ChannelPolicy`, `PolicyProvider`, and `presetsFor(kind, overrides)` reproducing PROTOCOL.md §5.2 room presets for `chat`, `game`, and `custom` room templates.
|
|
75
|
+
- **Client-Side Token Bucket Rate Limiting**: Per `(room, channel)` limiters enforcing `rate = maxRate` and `burst = max(2, maxRate * 2)` to cooperatively preempt server rate violations.
|
|
76
|
+
- **Inbound RATE_LIMITED Backoff Correlation**: Reader pauses local publishing on channels receiving server `RATE_LIMITED` frames, inferring target rooms from recent publish tracking.
|
|
77
|
+
- **Message Coalescing**: Outbound state coalescing on unreliable channels with `'timer'` and browser-native `'raf'` (`requestAnimationFrame`) drivers and customizable `merge` functions.
|
|
78
|
+
- **Writer Loop Scheduler**: Single async event loop writer pump with burst draining (reliable 32, unreliable 8) and microtask yields (`await Promise.resolve()`) per frame to avoid blocking UI rendering.
|
|
79
|
+
- **Transport Backpressure Management**: Cooperative monitoring of `WebSocket.bufferedAmount` with high ($1 \text{ MiB}$) and low ($512 \text{ KiB}$) watermarks and hysteresis, pausing unreliable flushes under saturation.
|
|
80
|
+
- **Generation-Scoped Queues**: Outbound queues discard pending frames on reconnect to prevent stale message delivery contradicting restored room states, emitting `queuesDiscarded` before session restore begins.
|
|
81
|
+
- **Public API Additions**: Added `publish(req)`, `setChannelPolicy(room, channel, policy)`, `queueDepth()`, `bufferedAmount()`, and test seam `__flushNow()`.
|
|
82
|
+
- **New Events & Errors**: Added events (`rateLimited`, `reliableOverflow`, `unreliableDropped`, `coalesced`, `queuesDiscarded`, `backpressure`, `policyApplied`) and errors (`NotReadyError`, `ChannelNotReliableError`, `RateLimitedError`).
|
|
83
|
+
|
|
84
|
+
## [0.1.0] - 2026-10-29
|
|
85
|
+
|
|
86
|
+
### Added — JS SDK Phase J1
|
|
87
|
+
|
|
88
|
+
- **Connection Lifecycle State Machine**: Full lifecycle management covering `idle`, `connecting`, `awaiting_welcome`, `ready`, `reconnecting`, and `closed` states with typed event notifications.
|
|
89
|
+
- **Browser-Native Authentication**: Query parameter authentication (`?key=...`) with mandatory key redaction in logs and error frames.
|
|
90
|
+
- **401 Detection Heuristic**: Intelligent classification of browser-masked abnormal close (`1006`) errors into `AUTH_FAILED` fatal halts versus retryable network failures, supporting `'heuristic'`, `'never-fatal'`, and `'always-fatal'` modes alongside an `onAmbiguousAuth` callback.
|
|
91
|
+
- **Exponential Reconnection**: Full-jitter, equal-jitter, and non-jitter exponential backoff with configurable base delays, maximum ceilings, retry ceilings, and `shouldReconnect` overrides.
|
|
92
|
+
- **Serialized Session Restore**: Automatic rejoining of active room memberships upon reconnection in alphabetical room order, handling `ROOM_NOT_FOUND`, `FORBIDDEN_SCOPE`, `INVALID_PASSCODE`, `ROOM_FULL` (with `'drop'` and `'retry'` policies), and per-room deadlines.
|
|
93
|
+
- **Heartbeat Management**: Application-level ping/pong liveness verification with configurable intervals and timeouts, forcing connection resets on missed deadlines.
|
|
94
|
+
- **Capabilities Discovery**: Caching of server `welcome.capabilities` preserving S2 `null`-means-disabled semantics and emitting `capabilitiesChanged` on server version or capacity upgrades.
|
|
95
|
+
- **Core Protocol API**: Async convenience wrappers for `createRoom`, `joinRoom`, `leaveRoom`, `deleteRoom`, `listRooms`, and low-level `send`.
|
|
96
|
+
- **Error Hierarchy**: ES2022 error taxonomy rooted at `SdkError`, including `AuthError`, `ConnectError`, `PolicyViolationError`, `RequestTimeoutError`, `ConcurrentRequestError`, and `ServerError`.
|
|
97
|
+
- **Transport & Clock Abstractions**: Dependency-injected `Transport` and `Clock` interfaces powering deterministic zero-wall-clock test suites with 100% fake-timer execution.
|
|
98
|
+
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tony Tomo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|