Fixes 4 issues surfaced in a design review of the codebase.
Fixes#
- Reconnect off-by-one —
scheduleReconnectchecked>= maxAttemptsafter incrementing, somaxAttempts: Nproduced only N-1 real reconnects. Now checks before incrementing;maxAttempts: 3yields 3 attempts per service, matching the documented contract. - New
exhaustedevent — emitted when reconnection gives up after all attempts/cycles ({ services, attempts, cycles }); previously the give-up branch only logged, so consumers had no signal. Wired throughWebSocketClient, documented in README + JSDoc. - Router throughput (demo) —
test-jetstream.tsrewritten to a singlez.discriminatedUnion+ one handler (O(1) dispatch onkind) instead of registering 3 overlapping schemas that ran a fullsafeParseper schema per message. The router code is unchanged; the canonical example now is also the fastest pattern. - Param method merge —
setParamsfolded intoupdateParams(params, { immediate }).setParamskept as a deprecated alias forupdateParams(params, { immediate: false }).
Tests#
Added regression guards in tests/client.test.ts: off-by-one attempt count (3 reconnecting + 1 exhausted), deferred params, setParams alias. Full suite: 55 passing. Typecheck, lint, build all green.
Behavior changes (review carefully)#
maxAttemptsnow does one more attempt per service than before — anyone relying on the old N-1 behavior gets N.exhaustedis a new public event on both the connection and client.