typed-websocket-client
v1.0.0
Published
[](https://npm.im/typed-websocket-client) [](https://npm.im/typed-websocket-client) [.
- Custom heartbeat payload and reply detection.
- Custom reconnection timing.
- Pluggable logger for easy debugging.
- 🌐 Isomorphic: Works seamlessly in both browsers and Node.js environments (by providing a
wsconstructor). - modern Modern API:
- Familiar
on/offevent listener interface. - Supports
AbortSignalfor automatic listener cleanup.
Installation
npm install typed-websocket-clientUsage
Basic Usage
Here's a simple example of connecting to a WebSocket echo server.
import { WebSocketClient } from 'typed-websocket-client';
// Create a new client instance
const client = new WebSocketClient('wss://echo.websocket.org/');
// Listen for the 'open' event
client.on('open', () => {
console.log('Connection established!');
client.push('Hello, WebSocket!');
});
// Listen for incoming messages
client.on('message', (data) => {
console.log('Received:', data); // Received: Hello, WebSocket!
});
// Listen for the 'close' event
client.on('close', (event) => {
console.log(`Connection closed: ${event.reason} (Code: ${event.code})`);
});
// Listen for errors
client.on('error', (error) => {
console.error('WebSocket Error:', error);
});
// Start the connection
client.connect();Type-Safe Usage
The real power comes from defining types for your messages.
import { WebSocketClient } from 'typed-websocket-client';
// 1. Define your message types
interface UserMessage {
type: 'message';
payload: {
text: string;
timestamp: number;
};
}
interface ServerEvent {
type: 'event';
payload: {
name: 'user_joined' | 'user_left';
userId: string;
};
}
type SendType = UserMessage;
type ReceiveType = UserMessage | ServerEvent;
// 2. Create a typed client instance
const client = new WebSocketClient<SendType, ReceiveType>('ws://localhost:8080/socket');
client.on('open', () => {
// `push` is now strongly typed. This is valid:
client.push({
type: 'message',
payload: { text: 'Hello from a typed client!', timestamp: Date.now() },
});
// This would cause a TypeScript error:
// client.push({ type: 'invalid_type' });
});
// 3. The `data` in the message handler is also strongly typed
client.on('message', (data) => {
// `data` is of type `UserMessage | ServerEvent`
switch (data.type) {
case 'message':
console.log(`Received message: "${data.payload.text}"`);
break;
case 'event':
console.log(`Server event: ${data.payload.name}`);
break;
}
});
client.connect();Advanced Configuration
You can customize almost every aspect of the client's behavior.
import { WebSocketClient } from 'typed-websocket-client';
// For Node.js, you need to install and provide a WebSocket implementation
import WebSocket from 'ws';
const controller = new AbortController();
const client = new WebSocketClient('ws://localhost:8080/socket', {
// Use the 'ws' library in Node.js
WebSocketCtor: WebSocket,
// Custom reconnection strategy (e.g., every 3 seconds)
reconnectAfterMs: (tries) => 3000,
// Custom heartbeat interval and timeout
heartbeatIntervalMs: 25000,
timeout: 5000,
// Add dynamic query parameters for authentication
params: () => ({
token: getAuthToken(), // Your function to get a fresh token
}),
// Enable logging for debugging
logger: (kind, msg, data) => {
console.log(`[${new Date().toISOString()}] ${kind.toUpperCase()}: ${msg}`, data || '');
},
});
// Add a listener that can be removed via an AbortSignal
client.on(
'message',
(data) => {
console.log('This listener will only fire once.', data);
controller.abort(); // Abort the signal to remove the listener
},
{ signal: controller.signal },
);
client.connect();
function getAuthToken() {
return 'some-secret-jwt-token';
}API
new WebSocketClient(endPoint, options?)
Creates a new client instance.
endPoint(string): The WebSocket URL.options(WebSocketClientOptions): Configuration options.
Options
| Option | Type | Default | Description |
| --------------------- | --------------------------------------- | ---------------------------------- | ---------------------------------------------------------------------------- |
| WebSocketCtor | new (...) => WebSocket | window.WebSocket | A WebSocket constructor, required for Node.js environments. |
| timeout | number | 10000 | Timeout in ms for connection and heartbeat events. |
| heartbeatIntervalMs | number | 30000 | Interval in ms for sending heartbeat messages. |
| reconnectAfterMs | (tries: number) => number | Exponential backoff | A function returning the reconnection delay in ms. |
| logger | (kind, msg, data?) => void | undefined | A function for logging internal events. |
| params | Record<string, any> \| (() => Record) | {} | Query parameters to append to the URL. Can be a function for dynamic values. |
| protocols | string \| string[] | undefined | WebSocket sub-protocols. |
| binaryType | BinaryType | 'arraybuffer' | The binary data type to use. |
| encode | (data, callback) => void | JSON.stringify | Custom function to encode outgoing messages. |
| decode | (data, callback) => void | JSON.parse | Custom function to decode incoming messages. |
| heartbeatPayload | () => SendType | { event: 'heartbeat', ref: ... } | A function that returns the payload for a heartbeat message. |
| isHeartbeatReply | (data: ReceiveType) => boolean | Checks for matching ref | A function to identify if an incoming message is a reply to a heartbeat. |
Methods
connect(): Establishes the connection.disconnect(callback?, code?, reason?): Closes the connection cleanly.push(data: SendType): Sends a message. Buffers if offline.on(event, callback, options?): Adds an event listener.off(event, callback): Removes an event listener.connectionState(): Returns'connecting' | 'open' | 'closing' | 'closed'.isConnected(): Returnstrueif the connection is open.
