Files
2026-05-27 23:47:53 +01:00

12 KiB

@suaveplan/network-transport-websockets - WebSocket client utilities: typed message framing, connection lifecycle, heartbeat, backpressure queue, and injectable transport adapters

Summary

WebSocket client utilities with typed message framing, connection lifecycle management, heartbeat, backpressure queue, and injectable transport adapters.

Documentation tree

- [native-adapter](./src/adapters/native-adapter.md) — _(no submodules)_- [client](./src/core/client/client.md) — _(no submodules)_- [client](./src/core/client/client.md) — _(no submodules)_- [heartbeat](./src/core/heartbeat/heartbeat.md) — _(no submodules)_- [heartbeat](./src/core/heartbeat/heartbeat.md) — _(no submodules)_- [queue](./src/core/queue/queue.md) — _(no submodules)_- [queue](./src/core/queue/queue.md) — _(no submodules)_- [otel](./src/otel/otel.md) — _(no submodules)_- [otel](./src/otel/otel.md) — _(no submodules)_- [plugin](./src/plugin/plugin.md) — _(no submodules)_- [plugin](./src/plugin/plugin.md) — _(no submodules)_- [transport](./src/transport/transport.md) — _(no submodules)_- [transport](./src/transport/transport.md) — _(no submodules)_- [types](./src/types/common.md) — _(no submodules)_- [common](./src/types/common.md) — _(no submodules)_- [error-codes](./src/error-codes.md) — Frozen error-code registry for the `@suaveplan/network-transport-websockets` package. Centralises every failure classif…
  • native-adapter — (no submodules)- client — (no submodules)- client — (no submodules)- heartbeat — (no submodules)- heartbeat — (no submodules)- queue — (no submodules)- queue — (no submodules)- otel — (no submodules)- otel — (no submodules)- plugin — (no submodules)- plugin — (no submodules)- transport — (no submodules)- transport — (no submodules)- types — (no submodules)- common — (no submodules)- error-codes — Frozen error-code registry for the @suaveplan/network-transport-websockets package. Centralises every failure classif…
  • native-adapter — (no submodules)- client — (no submodules)- client — (no submodules)- heartbeat — (no submodules)- heartbeat — (no submodules)- queue — (no submodules)- queue — (no submodules)- otel — (no submodules)- otel — (no submodules)- plugin — (no submodules)- plugin — (no submodules)- transport — (no submodules)- transport — (no submodules)- types — (no submodules)- common — (no submodules)- error-codes — Frozen error-code registry for the @suaveplan/network-transport-websockets package. Centralises every failure classif…
  • native-adapter — (no submodules)- client — (no submodules) - client — (no submodules)- heartbeat — (no submodules) - heartbeat — (no submodules)- queue — (no submodules) - queue — (no submodules)- otel — (no submodules) - otel — (no submodules)- plugin — (no submodules) - plugin — (no submodules)- transport — (no submodules) - transport — (no submodules)- types — (no submodules) - common — (no submodules)- error-codes — Frozen error-code registry for the @suaveplan/network-transport-websockets package. Centralises every failure classif…

Purpose

@suaveplan/network-transport-websockets provides a robust, enterprise-grade WebSocket client for browser and Node.js environments. It handles connection establishment, automatic reconnection with exponential backoff, heartbeat/ping-pong keepalive, a bounded message queue for backpressure, and channel-based message multiplexing over a single WebSocket connection. All timing is injectable via a Clock interface for deterministic testing.

Features

  • Connection lifecycle — connect, disconnect, and state tracking (disconnected | connecting | connected | reconnecting | closed)
  • Automatic reconnect — configurable exponential backoff with max attempts and capped delay
  • Heartbeat — configurable ping interval and pong timeout; disconnects on missed pong
  • Message queue — bounded queue that drops oldest messages when full, with rejections for dropped items
  • Channel multiplexing — subscribe to named channels and receive typed messages
  • Injectable adapter — swap the native WebSocket transport for custom implementations (tests, mocks, alternate runtimes)
  • Injectable clock — drive timers deterministically in tests using FakeClock
  • Event bus integration — emits websocket:connected and websocket:disconnected events
  • AbortSignal support — cancel connect() and send() via AbortSignal
  • Structured errors — all errors use @suaveplan/error with stable WS.* error codes

Usage

Basic Example

import { createWebSocketClient } from "@suaveplan/network-transport-websockets";

const client = createWebSocketClient({
    url: "wss://example.com/socket",
    heartbeat: { enabled: true, intervalMs: 30000, timeoutMs: 10000 },
    reconnect: { enabled: true, maxAttempts: 5, initialDelayMs: 1000, maxDelayMs: 30000 },
});

await client.connect();

client.subscribe("chat", (msg, meta) => {
    console.log(`[${meta.channel}] ${msg}`);
});

await client.send({ type: "chat", channel: "chat", payload: { text: "hello" } });

client.disconnect();

Advanced Example

import { createWebSocketClient } from "@suaveplan/network-transport-websockets";

const client = createWebSocketClient({
    url: "wss://example.com/socket",
    clock: fakeClock,           // injectable for tests
    adapter: customAdapter,     // custom WebSocket transport
    eventBus: appEventBus,      // emit connection events
    maxQueueSize: 100,
    serialization: "json",
});

client.on("connect", () => console.log("connected"));
client.on("disconnect", ({ code, reason }) => console.log("disconnected", code, reason));
client.on("reconnect", ({ attempt }) => console.log("reconnecting, attempt", attempt));

const ctrl = new AbortController();
await client.connect(ctrl.signal);

// Send with abort support
await client.send({ type: "ping", payload: null }, ctrl.signal);

API Reference

See the per-module documentation in src/:

  • src/core/client/ — createWebSocketClient, WebSocketClient, connection lifecycle
  • src/core/heartbeat/ — createHeartbeat, HeartbeatController
  • src/core/queue/ — MessageQueue, bounded message queue
  • src/adapters/ — nativeWebSocketAdapter, WebSocketAdapter contract
  • src/types/ — WebSocketClientOptions, WebSocketMessage, MessageMeta, Clock
  • src/error-codes.ts — WS_CODES and WsError

Implementation Notes

The client uses private fields for all internal state and exposes a minimal public API. The native adapter wraps the global WebSocket with safe close() handling for reserved close codes. The heartbeat controller is fully decoupled from the client and can be tested in isolation. All timer-based behavior uses an injectable Clock so tests can advance time deterministically without real waits.