🚨 Active Supply Chain Attack:node-ipc Package Compromised.Learn More
Socket
Book a DemoSign in
Socket

@bytesocket/client

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bytesocket/client - npm Package Compare versions

Comparing version
0.2.2
to
0.3.0
+501
-349
dist/index.d.cts

@@ -1,16 +0,10 @@

import { MsgpackrOptions, AnyCallback, LifecycleTypes, SocketEvents, ErrorContext, StringNumberKeys, EventsForRooms, LifecycleMessage, UserMessage, StringKeys } from '@bytesocket/types';
import { SocketEvents, ErrorContext, StringNumberKeys, EventsForRooms, StringKeys, UserMessage, LifecycleMessage, MsgpackrOptions, AnyCallback, LifecycleTypes } from '@bytesocket/types';
export * from '@bytesocket/types';
export { FLOAT32_OPTIONS } from 'msgpackr';
/** The data types actually accepted by the browser WebSocket.send() method.
* (Excluding Blob to keep queue handling simple.) */
type ClientSendData = string | BufferSource;
/** Signature of a callback that receives event data. */
type EventCallback<D> = (data: D) => void;
/** Internal state tracking for a single room. */
interface RoomState {
/** Current pending operation (join/leave) or null. */
pending: "join" | "leave" | null;
/** Whether the application intends to be in this room. */
wanted: boolean;
/** Whether the server has confirmed membership. */
joined: boolean;
}
/**

@@ -21,5 +15,5 @@ * Authentication configuration.

* @example
* // Static auth object
* // Static auth object (must wrap payload with `data`)
* const socket = new ByteSocket('ws://localhost:8080', {
* auth: { token: 'my-secret' }
* auth: { data: { token: 'my-secret' } }
* });

@@ -85,122 +79,180 @@ *

};
/**
* Abstract base class providing common callback management for lifecycle and user events.
* Used internally by `ByteSocket` and `RoomManager`.
*
* @internal
*/
declare abstract class SocketBase {
/** Whether debug logging is enabled. */
protected abstract readonly debug: boolean;
/** Stores permanent callbacks for lifecycle events. */
protected lifecycleCallbacksMap: Map<string | number, Set<AnyCallback>>;
/** Stores `once` wrappers for lifecycle events. */
protected onceLifecycleCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>;
/** Adds a callback to a given event in the provided map. */
protected addCallback<E extends string | number, D>(callbacksMap: Map<string | number, Set<AnyCallback>>, event: E, callback: EventCallback<D>): void;
/** Registers a one-time callback by storing the wrapper in a separate map. */
protected addOnceCallback<E extends string | number, D>(onceCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>, event: E, callback: EventCallback<D>, callbackWrapper: EventCallback<D>): void;
/** Removes a callback from an event map. */
protected deleteCallback<E extends string | number, D>(callbacksMap: Map<string | number, Set<AnyCallback>>, event: E, callbackWrapper: EventCallback<D>): void;
/** Removes a one-time callback and its associated wrapper. */
protected deleteOnceCallback<E extends string | number, D>(onceCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>, event: E, callback: EventCallback<D>, callbackWrapper: EventCallback<D>): void;
/** Registers a permanent listener for a lifecycle event. */
protected onLifecycle<T extends LifecycleTypes>(type: T, callback: AnyCallback): void;
interface RoomLifecycleApi {
/**
* Removes a listener for a lifecycle event.
* If no callback is provided, all listeners for that event are removed.
* Emitted when a single room join succeeds.
* @param callback - Function that receives the room name.
*/
protected offLifecycle<T extends LifecycleTypes>(type: T, callback?: AnyCallback): void;
onJoinSuccess: (callback: (room: string) => void) => void;
/**
* Registers a one-time listener for a lifecycle event.
* The callback is automatically removed after the first invocation.
* Removes a join-success listener.
* @param callback - The listener to remove.
*/
protected onceLifecycle<T extends LifecycleTypes>(type: T, callback: AnyCallback): void;
/** Safely invokes a set of callbacks, catching and logging errors if debug is enabled. */
protected triggerCallback<Args extends Array<unknown>>(callbackWrappers?: Set<AnyCallback>, ...args: Args): void;
offJoinSuccess: (callback?: (room: string) => void) => void;
/**
* One‑time listener for a single room join success.
* @param callback - Function that receives the room name.
*/
onceJoinSuccess: (callback: (room: string) => void) => void;
/**
* Emitted when a single room join fails.
* @param callback - Function that receives the room and error context.
*/
onJoinError: (callback: (room: string, ctx: ErrorContext) => void) => void;
/**
* Removes a join‑error listener.
* @param callback - The listener to remove.
*/
offJoinError: (callback?: (room: string, ctx: ErrorContext) => void) => void;
/**
* One‑time listener for a single room join error.
* @param callback - Function that receives the room and error context.
*/
onceJoinError: (callback: (room: string, ctx: ErrorContext) => void) => void;
/**
* Emitted when a single room leave succeeds.
* @param callback - Function that receives the room name.
*/
onLeaveSuccess: (callback: (room: string) => void) => void;
/**
* Removes a leave‑success listener.
* @param callback - The listener to remove.
*/
offLeaveSuccess: (callback?: (room: string) => void) => void;
/**
* One‑time listener for a single room leave success.
* @param callback - Function that receives the room name.
*/
onceLeaveSuccess: (callback: (room: string) => void) => void;
/**
* Emitted when a single room leave fails.
* @param callback - Function that receives the room and error context.
*/
onLeaveError: (callback: (room: string, ctx: ErrorContext) => void) => void;
/**
* Removes a leave‑error listener.
* @param callback - The listener to remove.
*/
offLeaveError: (callback?: (room: string, ctx: ErrorContext) => void) => void;
/**
* One‑time listener for a single room leave error.
* @param callback - Function that receives the room and error context.
*/
onceLeaveError: (callback: (room: string, ctx: ErrorContext) => void) => void;
}
/**
* Manages room membership and room-scoped event listeners.
*
* You should not instantiate this class directly; it is accessible via
* `socket.rooms` on a ByteSocket instance.
*
* @typeParam TEvents - The event map type (from SocketEvents) defining allowed room events.
*/
declare class RoomManager<TEvents extends SocketEvents> extends SocketBase {
#private;
protected readonly debug: boolean;
interface RoomBulkApi<TEvents extends SocketEvents> {
/**
* Lifecycle event listeners for single-room operations.
* Emit an event to multiple rooms at once.
*
* @typeParam Rs -- The array of room names.
* @typeParam E -- The event name.
* @typeParam D -- The event data type.
* @param rooms - Array of room names.
* @param event - Name of the event to emit.
* @param data - Event payload.
*
* @example
* socket.rooms.lifecycle.onJoinSuccess((room) => {
* console.log(`Joined room ${room}`);
* });
* // Assuming emitRooms: { rooms: ['roomA','roomB']; event: { message: string } }
* socket.rooms.bulk.emit(['roomA', 'roomB'], 'message', { text: 'Hello both!' });
*/
emit<Rs extends NonNullable<TEvents["emitRooms"]>["rooms"], E extends StringNumberKeys<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>, D extends NonNullable<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>[E]>(rooms: Rs, event: E, data: D): void;
/**
* Request to join multiple rooms.
* Only rooms not already joined or pending will be sent.
*
* @param rooms - Array of room names to join.
*
* @example
* socket.rooms.bulk.join(['lobby', 'notifications']);
*/
join(rooms: string[]): void;
/**
* Request to leave multiple rooms.
* Only rooms currently joined will be sent.
*
* @param rooms - Array of room names to leave.
*
* @example
* socket.rooms.bulk.leave(['lobby', 'notifications']);
*/
leave(rooms: string[]): void;
/** Bulk lifecycle hooks. */
readonly lifecycle: {
/**
* Register a listener for successful single-room join.
* @param callback - Function invoked with the room name.
* Emitted when a bulk join succeeds.
* @param callback - Function that receives the list of rooms.
*/
onJoinSuccess: (callback: (room: string) => void) => void;
onJoinSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Remove a listener for successful single-room join.
* @param callback - Optional; if omitted, all listeners are removed.
* Removes a bulk join‑success listener.
* @param callback - The listener to remove.
*/
offJoinSuccess: (callback?: (room: string) => void) => void;
offJoinSuccess: (callback?: (rooms: string[]) => void) => void;
/**
* Register a one-time listener for successful single-room join.
* @param callback - Function invoked once with the room name.
* One‑time listener for a bulk join success.
* @param callback - Function that receives the list of rooms.
*/
onceJoinSuccess: (callback: (room: string) => void) => void;
onceJoinSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Register a listener for single-room join errors.
* @param callback - Function invoked with the room name and error data.
* Emitted when a bulk join fails.
* @param callback - Function that receives the list of rooms and error context.
*/
onJoinError: (callback: (room: string, ctx: ErrorContext) => void) => void;
onJoinError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Remove a listener for single-room join errors.
* @param callback - Optional; if omitted, all listeners are removed.
* Removes a bulk join‑error listener.
* @param callback - The listener to remove.
*/
offJoinError: (callback?: (room: string, ctx: ErrorContext) => void) => void;
offJoinError: (callback?: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Register a one-time listener for single-room join errors.
* @param callback - Function invoked once with the room name and error data.
* One‑time listener for a bulk join error.
* @param callback - Function that receives the list of rooms and error context.
*/
onceJoinError: (callback: (room: string, ctx: ErrorContext) => void) => void;
onceJoinError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Register a listener for successful single-room leave.
* @param callback - Function invoked with the room name.
* Emitted when a bulk leave succeeds.
* @param callback - Function that receives the list of rooms.
*/
onLeaveSuccess: (callback: (room: string) => void) => void;
onLeaveSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Remove a listener for successful single-room leave.
* @param callback - Optional; if omitted, all listeners are removed.
* Removes a bulk leave‑success listener.
* @param callback - The listener to remove.
*/
offLeaveSuccess: (callback?: (room: string) => void) => void;
offLeaveSuccess: (callback?: (rooms: string[]) => void) => void;
/**
* Register a one-time listener for successful single-room leave.
* @param callback - Function invoked once with the room name.
* One‑time listener for a bulk leave success.
* @param callback - Function that receives the list of rooms.
*/
onceLeaveSuccess: (callback: (room: string) => void) => void;
onceLeaveSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Register a listener for single-room leave errors.
* @param callback - Function invoked with the room name and error data.
* Emitted when a bulk leave fails.
* @param callback - Function that receives the list of rooms and error context.
*/
onLeaveError: (callback: (room: string, ctx: ErrorContext) => void) => void;
onLeaveError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Remove a listener for single-room leave errors.
* @param callback - Optional; if omitted, all listeners are removed.
* Removes a bulk leave‑error listener.
* @param callback - The listener to remove.
*/
offLeaveError: (callback?: (room: string, ctx: ErrorContext) => void) => void;
offLeaveError: (callback?: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Register a one-time listener for single-room leave errors.
* @param callback - Function invoked once with the room name and error data.
* One‑time listener for a bulk leave error.
* @param callback - Function that receives the list of rooms and error context.
*/
onceLeaveError: (callback: (room: string, ctx: ErrorContext) => void) => void;
onceLeaveError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
};
}
/**
* Public API for room management on a ByteSocket client.
*
* @typeParam TEvents -- The event map type (from `SocketEvents`) that defines allowed room event names and payloads.
*/
interface IRoomManager<TEvents extends SocketEvents> {
/**
* Lifecycle event listeners for single-room join/leave operations.
*
* @example
* socket.rooms.lifecycle.onJoinSuccess((room) => {
* console.log(`Joined room ${room}`);
* });
*/
readonly lifecycle: RoomLifecycleApi;
/**
* Bulk operations (join/leave/emit multiple rooms) and their lifecycle listeners.

@@ -212,98 +264,4 @@ *

*/
readonly bulk: {
/**
* Emit an event to multiple rooms at once.
*
* @typeParam Rs - The array of room names.
* @typeParam E - The event name.
* @typeParam D - The event data type.
*
* @example
* socket.rooms.bulk.emit(['roomA', 'roomB'], 'message', { text: 'Hello both!' });
*/
emit: <Rs extends NonNullable<TEvents["emitRooms"]>["rooms"], E extends StringNumberKeys<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>, D extends NonNullable<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>[E]>(rooms: Rs, event: E, data: D) => void;
/**
* Request to join multiple rooms.
* Only rooms not already joined or pending will be sent.
*
* @example
* socket.rooms.bulk.join(['lobby', 'notifications']);
*/
join: (rooms: string[]) => void;
/**
* Request to leave multiple rooms.
* Only rooms currently joined will be sent.
*
* @example
* socket.rooms.bulk.leave(['lobby', 'notifications']);
*/
leave: (rooms: string[]) => void;
lifecycle: {
/**
* Register a listener for successful bulk join.
* @param callback - Function invoked with the array of room names.
*/
onJoinSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Remove a listener for successful bulk join.
* @param callback - Optional; if omitted, all listeners are removed.
*/
offJoinSuccess: (callback?: (rooms: string[]) => void) => void;
/**
* Register a one-time listener for successful bulk join.
* @param callback - Function invoked once with the array of room names.
*/
onceJoinSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Register a listener for bulk join errors.
* @param callback - Function invoked with the array of room names and error data.
*/
onJoinError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Remove a listener for bulk join errors.
* @param callback - Optional; if omitted, all listeners are removed.
*/
offJoinError: (callback?: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Register a one-time listener for bulk join errors.
* @param callback - Function invoked once with the array of room names and error data.
*/
onceJoinError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Register a listener for successful bulk leave.
* @param callback - Function invoked with the array of room names.
*/
onLeaveSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Remove a listener for successful bulk leave.
* @param callback - Optional; if omitted, all listeners are removed.
*/
offLeaveSuccess: (callback?: (rooms: string[]) => void) => void;
/**
* Register a one-time listener for successful bulk leave.
* @param callback - Function invoked once with the array of room names.
*/
onceLeaveSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Register a listener for bulk leave errors.
* @param callback - Function invoked with the array of room names and error data.
*/
onLeaveError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Remove a listener for bulk leave errors.
* @param callback - Optional; if omitted, all listeners are removed.
*/
offLeaveError: (callback?: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Register a one-time listener for bulk leave errors.
* @param callback - Function invoked once with the array of room names and error data.
*/
onceLeaveError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
};
};
readonly bulk: RoomBulkApi<TEvents>;
/**
* @internal
*/
constructor(debug: boolean, send: <R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>, bypassAuthPending?: boolean) => void, onOpen: (callback: () => void) => void, onClose: (callback: (event: CloseEvent) => void) => void);
/**
* Emit an event to a specific room.

@@ -314,2 +272,5 @@ *

* @typeParam D - The event data type.
* @param room - Room to emit the event to.
* @param event - Name of the event to emit.
* @param data - Event payload.
*

@@ -325,2 +286,4 @@ * @example

*
* @param room - Name of the room to join.
*
* @example

@@ -333,2 +296,4 @@ * socket.rooms.join('chat');

*
* @param room - Name of the room to leave.
*
* @example

@@ -353,2 +318,5 @@ * socket.rooms.leave('chat');

* @typeParam E - Event name.
* @param room - Name of the room.
* @param event - Name of the event to listen for.
* @param callback - Function to call when the event is received.
*

@@ -367,2 +335,6 @@ * @example

*
* @param room - Name of the room.
* @param event - (optional) Name of the event.
* @param callback - (optional) The specific listener to remove.
*
* @example

@@ -381,2 +353,6 @@ * // Remove specific callback

*
* @param room - Name of the room.
* @param event - Name of the event to listen for.
* @param callback - Function to call once when the event is received.
*
* @example

@@ -400,77 +376,131 @@ * socket.rooms.once('chat', 'message', (data) => {

}
interface LifecycleApi {
/**
* Register a listener for the socket opens (after successful authentication).
* @param callback - Function to call when the socket opens.
*/
onOpen: (callback: () => void) => void;
/**
* Remove a listener for socket open.
* @param callback - The listener to remove.
*/
offOpen: (callback?: () => void) => void;
/**
* Register a one-time listener for socket open.
* @param callback - Function to call once when the socket opens.
*/
onceOpen: (callback: () => void) => void;
/**
* Listen for raw incoming WebSocket messages **after** internal heartbeat filtering.
* Receive `string` (JSON) or `ArrayBuffer` (binary).
* @param callback - Function that receives the raw message data.
*/
onMessage: (callback: (data: string | ArrayBuffer) => void) => void;
/**
* Remove a listener for raw messages.
* @param callback - The listener to remove.
*/
offMessage: (callback?: (data: string | ArrayBuffer) => void) => void;
/**
* Register a one-time listener for raw incoming WebSocket messages.
* @param callback - Function to call once with the raw data.
*/
onceMessage: (callback: (data: string | ArrayBuffer) => void) => void;
/**
* Register a listener for the socket closes.
* @param callback - Function that receives the `CloseEvent`.
*/
onClose: (callback: (event: CloseEvent) => void) => void;
/**
* Remove a listener for socket close.
* @param callback - The listener to remove.
*/
offClose: (callback?: (event: CloseEvent) => void) => void;
/**
* Register a one-time listener for socket close.
* @param callback - Function to call once when the socket closes.
*/
onceClose: (callback: (event: CloseEvent) => void) => void;
/**
* Emitted on WebSocket errors.
* @param callback - Function that receives the error context.
*/
onError: (callback: (ctx: ErrorContext) => void) => void;
/**
* Remove a listener for WebSocket errors.
* @param callback - The listener to remove.
*/
offError: (callback?: (ctx: ErrorContext) => void) => void;
/**
* Register a one-time listener for WebSocket errors.
* @param callback - Function to call once on error.
*/
onceError: (callback: (ctx: ErrorContext) => void) => void;
/**
* Emitted after successful authentication.
* @param callback - Function to call when authentication succeeds.
*/
onAuthSuccess: (callback: () => void) => void;
/**
* Remove a listener for authentication success.
* @param callback - The listener to remove.
*/
offAuthSuccess: (callback?: () => void) => void;
/**
* Register a one-time listener for authentication success.
* @param callback - Function to call once on auth success.
*/
onceAuthSuccess: (callback: () => void) => void;
/**
* Register a listener for authentication fails.
* @param callback - Function that receives the error context.
*/
onAuthError: (callback: (ctx: ErrorContext) => void) => void;
/**
* Remove a listener for authentication errors.
* @param callback - The listener to remove.
*/
offAuthError: (callback?: (ctx: ErrorContext) => void) => void;
/**
* Register a one-time listener for authentication errors.
* @param callback - Function to call once on auth error.
*/
onceAuthError: (callback: (ctx: ErrorContext) => void) => void;
/**
* Register a listener for the outgoing message queue is full and a message is dropped.
* @param callback - Function to call when the queue overflows.
*/
onQueueFull: (callback: () => void) => void;
/**
* Remove a listener for queue-full events.
* @param callback - The listener to remove.
*/
offQueueFull: (callback?: () => void) => void;
/**
* Register a one-time listener for queue-full events.
* @param callback - Function to call once when the queue is full.
*/
onceQueueFull: (callback: () => void) => void;
/**
* Register a listener for when reconnection fails after all attempts.
* @param callback - Function to call when reconnection is exhausted.
*/
onReconnectFailed: (callback: () => void) => void;
/**
* Remove a listener for reconnect-failed events.
* @param callback - The listener to remove.
*/
offReconnectFailed: (callback?: () => void) => void;
/**
* Register a one-time listener for reconnect-failed events.
* @param callback - Function to call once when reconnection fails.
*/
onceReconnectFailed: (callback: () => void) => void;
}
/**
* ByteSocket is a WebSocket client with automatic reconnection, room management,
* authentication, heartbeat, and pluggable serialization (JSON or MessagePack).
* Public API of the ByteSocket WebSocket client.
*
* It provides a fully typed event system via a user-supplied event map (`TEvents`).
*
* @typeParam TEvents - A type extending `SocketEvents` that defines the shape of
* all emit/listen events (global and room-scoped).
*
* @example Symmetric events (most common)
* ```ts
* // Define your event map
* type MyEvents = SocketEvents<{
* "chat:message": { text: string };
* "user:joined": { userId: string };
* }>;
*
* // Create a typed socket instance
* const socket = new ByteSocket<MyEvents>('wss://example.com/socket', {
* debug: true,
* auth: { token: 'abc123' }
* });
*
* // Use typed methods (emit and listen share the same event map)
* socket.emit('chat:message', { text: 'Hello!' });
* socket.on('user:joined', (data) => console.log(data.userId));
*
* socket.rooms.join('lobby');
* socket.rooms.emit('lobby', 'chat:message', { text: 'Hi everyone' });
* socket.rooms.on('lobby', 'chat:message', (data) => {
* console.log(`Message: ${data.text}`);
* });
* ```
*
* @example Asymmetric events (full control via interface extension)
* ```ts
* // Extend SocketEvents to differentiate emit/listen/room maps
* interface MyEvents extends SocketEvents {
* emit: {
* "message:send": { text: string };
* "ping": void;
* };
* listen: {
* "message:receive": { text: string; sender: string };
* "pong": number;
* };
* emitRoom: {
* chat: { "message": { text: string } };
* dm: { "message": { text: string; recipient: string } };
* };
* listenRoom: {
* chat: { "message": { text: string; sender: string } };
* };
* }
*
* const socket = new ByteSocket<MyEvents>('wss://example.com/socket', {
* debug: true,
* auth: { token: 'abc123' }
* });
*
* // Global emits/listens
* socket.emit('ping', undefined);
* socket.on('message:receive', (data) => console.log(`${data.sender}: ${data.text}`));
*
* // Room-specific emits/listens
* socket.rooms.join('chat');
* socket.rooms.emit('chat', 'message', { text: 'Hello!' });
* socket.rooms.on('chat', 'message', (data) => {
* console.log(`${data.sender}: ${data.text}`);
* });
* ```
* @typeParam TEvents -- The event map type (from `SocketEvents`) that defines allowed event names and payloads.
*/
declare class ByteSocket<TEvents extends SocketEvents = SocketEvents> extends SocketBase {
#private;
interface IByteSocket<TEvents extends SocketEvents = SocketEvents> {
/**

@@ -484,57 +514,3 @@ * Lifecycle event listeners for connection, authentication, and errors.

*/
readonly lifecycle: {
/** Register a listener for socket open. */
onOpen: (callback: () => void) => void;
/** Remove a listener for socket open. */
offOpen: (callback?: () => void) => void;
/** Register a one-time listener for socket open. */
onceOpen: (callback: () => void) => void;
/**
* Register a listener for raw incoming WebSocket messages.
* Called immediately when a message is received, before any internal processing.
*
* @param callback - Receives the raw data and a boolean indicating if it's binary.
*/
onMessage: (callback: (data: string | ArrayBuffer) => void) => void;
/** Remove a listener for raw messages. */
offMessage: (callback?: (data: string | ArrayBuffer) => void) => void;
/** Register a one-time listener for raw incoming WebSocket messages. */
onceMessage: (callback: (data: string | ArrayBuffer) => void) => void;
/** Register a listener for socket close. */
onClose: (callback: (event: CloseEvent) => void) => void;
/** Remove a listener for socket close. */
offClose: (callback?: (event: CloseEvent) => void) => void;
/** Register a one-time listener for socket close. */
onceClose: (callback: (event: CloseEvent) => void) => void;
/** Register a listener for WebSocket errors. */
onError: (callback: (event: ErrorContext) => void) => void;
/** Remove a listener for WebSocket errors. */
offError: (callback?: (event: ErrorContext) => void) => void;
/** Register a one-time listener for WebSocket errors. */
onceError: (callback: (event: ErrorContext) => void) => void;
/** Register a listener for authentication success. */
onAuthSuccess: (callback: () => void) => void;
/** Remove a listener for authentication success. */
offAuthSuccess: (callback?: () => void) => void;
/** Register a one-time listener for authentication success. */
onceAuthSuccess: (callback: () => void) => void;
/** Register a listener for authentication errors. */
onAuthError: (callback: (ctx: ErrorContext) => void) => void;
/** Remove a listener for authentication errors. */
offAuthError: (callback?: (ctx: ErrorContext) => void) => void;
/** Register a one-time listener for authentication errors. */
onceAuthError: (callback: (ctx: ErrorContext) => void) => void;
/** Register a listener for when the message queue becomes full and a message is dropped. */
onQueueFull: (callback: () => void) => void;
/** Remove a listener for queue-full events. */
offQueueFull: (callback?: () => void) => void;
/** Register a one-time listener for queue-full events. */
onceQueueFull: (callback: () => void) => void;
/** Register a listener for when reconnection fails after all attempts. */
onReconnectFailed: (callback: () => void) => void;
/** Remove a listener for reconnect-failed events. */
offReconnectFailed: (callback?: () => void) => void;
/** Register a one-time listener for reconnect-failed events. */
onceReconnectFailed: (callback: () => void) => void;
};
readonly lifecycle: LifecycleApi;
/**

@@ -547,17 +523,11 @@ * Room management and room-scoped events.

*/
readonly rooms: RoomManager<TEvents>;
protected readonly debug: boolean;
readonly rooms: IRoomManager<TEvents>;
/**
* Creates a new ByteSocket instance.
* Current WebSocket `readyState` (CONNECTING, OPEN, CLOSING, CLOSED).
* Returns `WebSocket.CLOSED` if no socket exists.
*
* @param baseUrl - WebSocket URL (e.g., `wss://example.com/socket` or relative `"/socket"`).
* @param options - Configuration options.
* @returns The current readyState constant.
*/
constructor(baseUrl: string, options?: ByteSocketOptions);
readonly readyState: number;
/**
* Current WebSocket readyState (CONNECTING, OPEN, CLOSING, CLOSED).
* Returns `WebSocket.CLOSED` if no socket exists.
*/
get readyState(): number;
/**
* Whether the socket is currently able to send messages.

@@ -568,2 +538,4 @@ * Returns `true` if the WebSocket is open and authentication (if configured) has succeeded.

*
* @returns `true` if ready to send, otherwise `false`.
*
* @example

@@ -574,12 +546,16 @@ * if (socket.canSend) {

*/
get canSend(): boolean;
readonly canSend: boolean;
/**
* Whether the socket has been manually closed or permanently destroyed.
* Returns `true` after `close()` or `destroy()` has been called.
*
* @returns `true` if closed/destroyed, otherwise `false`.
*/
get isClosed(): boolean;
readonly isClosed: boolean;
/**
* Whether the underlying WebSocket connection is currently open.
*
* @returns `true` if the connection is open, otherwise `false`.
*/
get isConnected(): boolean;
readonly isConnected: boolean;
/**

@@ -610,5 +586,5 @@ * Encode a structured payload into a format suitable for sending over the WebSocket.

*/
decode(message: string | ArrayBuffer, isBinary?: boolean): any;
decode(message: string | ArrayBuffer, isBinary?: boolean): unknown;
/**
* Send a pre-serialized payload (LifecycleMessage or UserMessage) over the WebSocket.
* Send a payload (LifecycleMessage or UserMessage) to be serialized and sent over the WebSocket.
* If the socket is not ready, the payload is queued and sent when the connection

@@ -629,9 +605,9 @@ * becomes operational and authentication (if required) has succeeded.

/**
* Send a raw message (string or Uint8Array<ArrayBuffer>) directly over the WebSocket.
* Bypasses serialization and auth checks. If the socket is not open, the message
* is queued and sent when possible (auth state is ignored).
* Send a raw message (string or binary) directly over the WebSocket.
* Bypasses serialisation and auth checks. If the socket is not open, the message
* is queued and sent when possible.
*
* @param message - The raw data to send.
* @param message -- The raw data to send (`string`, `ArrayBuffer`, or any typed array).
*/
sendRaw(message: string | Uint8Array<ArrayBuffer>): void;
sendRaw(message: ClientSendData): void;
/**

@@ -642,2 +618,4 @@ * Emit a global event.

* @typeParam D - Event data type.
* @param event - Name of the event to emit.
* @param data - Event payload.
*

@@ -653,2 +631,4 @@ * @example

* @typeParam E - Event name (must be a key in `TEvents['listen']`).
* @param event - Name of the event to listen for.
* @param callback - Function to call when the event is received.
*

@@ -666,2 +646,5 @@ * @example

*
* @param event - Name of the event.
* @param callback - (optional) The specific listener to remove.
*
* @example

@@ -678,2 +661,5 @@ * // Remove specific callback

*
* @param event - Name of the event.
* @param callback - Function to call once when the event occurs.
*
* @example

@@ -686,11 +672,2 @@ * socket.once('user:joined', (data) => {

/**
* Update the authentication configuration before connecting.
* Must be called before `connect()` (or auto-connect).
*
* @param config - New auth config (static object or async callback).
*
* @throws {Error} If called after `destroy()` or after the socket is already connecting/open.
*/
setAuth<D>(config: AuthConfig<D> | undefined): void;
/**
* Opens the WebSocket connection. Called automatically if `autoConnect` is `true`.

@@ -718,4 +695,179 @@ * Can be called manually after a previous `close()`.

destroy(): void;
/**
* Update the authentication configuration before connecting.
* Must be called before `connect()` (or auto-connect).
*
* @param config - New auth config (static object or async callback).
*
* @throws {Error} If called after `destroy()` or after the socket is already connecting/open.
*/
setAuth<D>(config: AuthConfig<D> | undefined): void;
}
export { type AuthConfig, ByteSocket, type ByteSocketOptions, type EventCallback, RoomManager, type RoomState, SocketBase };
/**
* Abstract base class providing common callback management for lifecycle and user events.
* Used internally by `ByteSocket` and `RoomManager`.
*
* @internal
*/
declare abstract class SocketBase {
/** Whether debug logging is enabled. */
protected abstract readonly debug: boolean;
/** Stores permanent callbacks for lifecycle events. */
protected lifecycleCallbacksMap: Map<string | number, Set<AnyCallback>>;
/** Stores `once` wrappers for lifecycle events. */
protected onceLifecycleCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>;
/** Adds a callback to a given event in the provided map. */
protected addCallback<E extends string | number, D>(callbacksMap: Map<string | number, Set<AnyCallback>>, event: E, callback: EventCallback<D>): void;
/** Registers a one-time callback by storing the wrapper in a separate map. */
protected addOnceCallback<E extends string | number, D>(onceCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>, event: E, callback: EventCallback<D>, callbackWrapper: EventCallback<D>): void;
/** Removes a callback from an event map. */
protected deleteCallback<E extends string | number, D>(callbacksMap: Map<string | number, Set<AnyCallback>>, event: E, callbackWrapper: EventCallback<D>): void;
/** Removes a one-time callback and its associated wrapper. */
protected deleteOnceCallback<E extends string | number, D>(onceCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>, event: E, callback: EventCallback<D>, callbackWrapper: EventCallback<D>): void;
/** Registers a permanent listener for a lifecycle event. */
protected onLifecycle<T extends LifecycleTypes>(type: T, callback: AnyCallback): void;
/**
* Removes a listener for a lifecycle event.
* If no callback is provided, all listeners for that event are removed.
*/
protected offLifecycle<T extends LifecycleTypes>(type: T, callback?: AnyCallback): void;
/**
* Registers a one-time listener for a lifecycle event.
* The callback is automatically removed after the first invocation.
*/
protected onceLifecycle<T extends LifecycleTypes>(type: T, callback: AnyCallback): void;
/** Safely invokes a set of callbacks, catching and logging errors if debug is enabled. */
protected triggerCallback<Args extends Array<unknown>>(callbackWrappers?: Set<AnyCallback>, ...args: Args): void;
}
/**
* Manages room membership and room-scoped event listeners.
*
* You should not instantiate this class directly; it is accessible via
* `socket.rooms` on a ByteSocket instance.
*
* @typeParam TEvents - The event map type (from SocketEvents) defining allowed room events.
*/
declare class RoomManager<TEvents extends SocketEvents> extends SocketBase implements IRoomManager<TEvents> {
#private;
protected readonly debug: boolean;
readonly lifecycle: RoomLifecycleApi;
readonly bulk: RoomBulkApi<TEvents>;
/** @internal */
constructor(debug: boolean, send: <R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>, bypassAuthPending?: boolean) => void, onOpen: (callback: () => void) => void, onClose: (callback: (event: CloseEvent) => void) => void);
emit<R extends StringKeys<TEvents["emitRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["emitRoom"]>[R]>, D extends NonNullable<TEvents["emitRoom"]>[R][E]>(room: R, event: E, data: D): void;
join(room: string): void;
leave(room: string): void;
list(): string[];
on<R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event: E, callback: EventCallback<D>): void;
off<R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event?: E, callback?: EventCallback<D>): void;
once<R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event: E, callback: EventCallback<D>): void;
_handleMessage(payload: UserMessage): boolean;
_clear(): void;
}
/**
* ByteSocket is a WebSocket client with automatic reconnection, room management,
* authentication, heartbeat, and pluggable serialization (JSON or MessagePack).
*
* It provides a fully typed event system via a user-supplied event map (`TEvents`).
*
* @typeParam TEvents - A type extending `SocketEvents` that defines the shape of
* all emit/listen events (global and room-scoped).
*
* @example Symmetric events (most common)
* ```ts
* // Define your event map
* type MyEvents = SocketEvents<{
* "chat:message": { text: string };
* "user:joined": { userId: string };
* }>;
*
* // Create a typed socket instance
* const socket = new ByteSocket<MyEvents>('wss://example.com/socket', {
* debug: true,
* auth: { data: { token: 'abc123' } }
* });
*
* // Use typed methods (emit and listen share the same event map)
* socket.emit('chat:message', { text: 'Hello!' });
* socket.on('user:joined', (data) => console.log(data.userId));
*
* socket.rooms.join('lobby');
* socket.rooms.emit('lobby', 'chat:message', { text: 'Hi everyone' });
* socket.rooms.on('lobby', 'chat:message', (data) => {
* console.log(`Message: ${data.text}`);
* });
* ```
*
* @example Asymmetric events (full control via interface extension)
* ```ts
* // Extend SocketEvents to differentiate emit/listen/room maps
* interface MyEvents extends SocketEvents {
* emit: {
* "message:send": { text: string };
* "ping": void;
* };
* listen: {
* "message:receive": { text: string; sender: string };
* "pong": number;
* };
* emitRoom: {
* chat: { "message": { text: string } };
* dm: { "message": { text: string; recipient: string } };
* };
* listenRoom: {
* chat: { "message": { text: string; sender: string } };
* };
* }
*
* const socket = new ByteSocket<MyEvents>('wss://example.com/socket', {
* debug: true,
* auth: { data: { token: 'abc123' } }
* });
*
* // Global emits/listens
* socket.emit('ping', undefined);
* socket.on('message:receive', (data) => console.log(`${data.sender}: ${data.text}`));
*
* // Room-specific emits/listens
* socket.rooms.join('chat');
* socket.rooms.emit('chat', 'message', { text: 'Hello!' });
* socket.rooms.on('chat', 'message', (data) => {
* console.log(`${data.sender}: ${data.text}`);
* });
* ```
*/
declare class ByteSocket<TEvents extends SocketEvents = SocketEvents> extends SocketBase implements IByteSocket<TEvents> {
#private;
readonly lifecycle: LifecycleApi;
readonly rooms: RoomManager<TEvents>;
protected readonly debug: boolean;
/**
* Creates a new ByteSocket instance.
*
* @param baseUrl - WebSocket URL (e.g., `wss://example.com/socket` or relative `"/socket"`).
* @param options - Configuration options.
*/
constructor(baseUrl: string, options?: ByteSocketOptions);
get readyState(): number;
get canSend(): boolean;
get isClosed(): boolean;
get isConnected(): boolean;
encode<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>, serialization?: "json" | "binary"): string | Uint8Array<ArrayBuffer>;
decode(message: string | ArrayBuffer, isBinary?: boolean): any;
send<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): void;
sendRaw(message: ClientSendData): void;
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): void;
on<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<D>): void;
off<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback?: EventCallback<D>): void;
once<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<D>): void;
setAuth<D>(config: AuthConfig<D> | undefined): void;
connect(): void;
reconnect(): void;
close(code?: number, reason?: string): void;
destroy(): void;
}
export { type AuthConfig, ByteSocket, type ByteSocketOptions, type EventCallback, type IByteSocket, type IRoomManager, type LifecycleApi, type RoomBulkApi, type RoomLifecycleApi };

@@ -1,16 +0,10 @@

import { MsgpackrOptions, AnyCallback, LifecycleTypes, SocketEvents, ErrorContext, StringNumberKeys, EventsForRooms, LifecycleMessage, UserMessage, StringKeys } from '@bytesocket/types';
import { SocketEvents, ErrorContext, StringNumberKeys, EventsForRooms, StringKeys, UserMessage, LifecycleMessage, MsgpackrOptions, AnyCallback, LifecycleTypes } from '@bytesocket/types';
export * from '@bytesocket/types';
export { FLOAT32_OPTIONS } from 'msgpackr';
/** The data types actually accepted by the browser WebSocket.send() method.
* (Excluding Blob to keep queue handling simple.) */
type ClientSendData = string | BufferSource;
/** Signature of a callback that receives event data. */
type EventCallback<D> = (data: D) => void;
/** Internal state tracking for a single room. */
interface RoomState {
/** Current pending operation (join/leave) or null. */
pending: "join" | "leave" | null;
/** Whether the application intends to be in this room. */
wanted: boolean;
/** Whether the server has confirmed membership. */
joined: boolean;
}
/**

@@ -21,5 +15,5 @@ * Authentication configuration.

* @example
* // Static auth object
* // Static auth object (must wrap payload with `data`)
* const socket = new ByteSocket('ws://localhost:8080', {
* auth: { token: 'my-secret' }
* auth: { data: { token: 'my-secret' } }
* });

@@ -85,122 +79,180 @@ *

};
/**
* Abstract base class providing common callback management for lifecycle and user events.
* Used internally by `ByteSocket` and `RoomManager`.
*
* @internal
*/
declare abstract class SocketBase {
/** Whether debug logging is enabled. */
protected abstract readonly debug: boolean;
/** Stores permanent callbacks for lifecycle events. */
protected lifecycleCallbacksMap: Map<string | number, Set<AnyCallback>>;
/** Stores `once` wrappers for lifecycle events. */
protected onceLifecycleCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>;
/** Adds a callback to a given event in the provided map. */
protected addCallback<E extends string | number, D>(callbacksMap: Map<string | number, Set<AnyCallback>>, event: E, callback: EventCallback<D>): void;
/** Registers a one-time callback by storing the wrapper in a separate map. */
protected addOnceCallback<E extends string | number, D>(onceCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>, event: E, callback: EventCallback<D>, callbackWrapper: EventCallback<D>): void;
/** Removes a callback from an event map. */
protected deleteCallback<E extends string | number, D>(callbacksMap: Map<string | number, Set<AnyCallback>>, event: E, callbackWrapper: EventCallback<D>): void;
/** Removes a one-time callback and its associated wrapper. */
protected deleteOnceCallback<E extends string | number, D>(onceCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>, event: E, callback: EventCallback<D>, callbackWrapper: EventCallback<D>): void;
/** Registers a permanent listener for a lifecycle event. */
protected onLifecycle<T extends LifecycleTypes>(type: T, callback: AnyCallback): void;
interface RoomLifecycleApi {
/**
* Removes a listener for a lifecycle event.
* If no callback is provided, all listeners for that event are removed.
* Emitted when a single room join succeeds.
* @param callback - Function that receives the room name.
*/
protected offLifecycle<T extends LifecycleTypes>(type: T, callback?: AnyCallback): void;
onJoinSuccess: (callback: (room: string) => void) => void;
/**
* Registers a one-time listener for a lifecycle event.
* The callback is automatically removed after the first invocation.
* Removes a join-success listener.
* @param callback - The listener to remove.
*/
protected onceLifecycle<T extends LifecycleTypes>(type: T, callback: AnyCallback): void;
/** Safely invokes a set of callbacks, catching and logging errors if debug is enabled. */
protected triggerCallback<Args extends Array<unknown>>(callbackWrappers?: Set<AnyCallback>, ...args: Args): void;
offJoinSuccess: (callback?: (room: string) => void) => void;
/**
* One‑time listener for a single room join success.
* @param callback - Function that receives the room name.
*/
onceJoinSuccess: (callback: (room: string) => void) => void;
/**
* Emitted when a single room join fails.
* @param callback - Function that receives the room and error context.
*/
onJoinError: (callback: (room: string, ctx: ErrorContext) => void) => void;
/**
* Removes a join‑error listener.
* @param callback - The listener to remove.
*/
offJoinError: (callback?: (room: string, ctx: ErrorContext) => void) => void;
/**
* One‑time listener for a single room join error.
* @param callback - Function that receives the room and error context.
*/
onceJoinError: (callback: (room: string, ctx: ErrorContext) => void) => void;
/**
* Emitted when a single room leave succeeds.
* @param callback - Function that receives the room name.
*/
onLeaveSuccess: (callback: (room: string) => void) => void;
/**
* Removes a leave‑success listener.
* @param callback - The listener to remove.
*/
offLeaveSuccess: (callback?: (room: string) => void) => void;
/**
* One‑time listener for a single room leave success.
* @param callback - Function that receives the room name.
*/
onceLeaveSuccess: (callback: (room: string) => void) => void;
/**
* Emitted when a single room leave fails.
* @param callback - Function that receives the room and error context.
*/
onLeaveError: (callback: (room: string, ctx: ErrorContext) => void) => void;
/**
* Removes a leave‑error listener.
* @param callback - The listener to remove.
*/
offLeaveError: (callback?: (room: string, ctx: ErrorContext) => void) => void;
/**
* One‑time listener for a single room leave error.
* @param callback - Function that receives the room and error context.
*/
onceLeaveError: (callback: (room: string, ctx: ErrorContext) => void) => void;
}
/**
* Manages room membership and room-scoped event listeners.
*
* You should not instantiate this class directly; it is accessible via
* `socket.rooms` on a ByteSocket instance.
*
* @typeParam TEvents - The event map type (from SocketEvents) defining allowed room events.
*/
declare class RoomManager<TEvents extends SocketEvents> extends SocketBase {
#private;
protected readonly debug: boolean;
interface RoomBulkApi<TEvents extends SocketEvents> {
/**
* Lifecycle event listeners for single-room operations.
* Emit an event to multiple rooms at once.
*
* @typeParam Rs -- The array of room names.
* @typeParam E -- The event name.
* @typeParam D -- The event data type.
* @param rooms - Array of room names.
* @param event - Name of the event to emit.
* @param data - Event payload.
*
* @example
* socket.rooms.lifecycle.onJoinSuccess((room) => {
* console.log(`Joined room ${room}`);
* });
* // Assuming emitRooms: { rooms: ['roomA','roomB']; event: { message: string } }
* socket.rooms.bulk.emit(['roomA', 'roomB'], 'message', { text: 'Hello both!' });
*/
emit<Rs extends NonNullable<TEvents["emitRooms"]>["rooms"], E extends StringNumberKeys<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>, D extends NonNullable<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>[E]>(rooms: Rs, event: E, data: D): void;
/**
* Request to join multiple rooms.
* Only rooms not already joined or pending will be sent.
*
* @param rooms - Array of room names to join.
*
* @example
* socket.rooms.bulk.join(['lobby', 'notifications']);
*/
join(rooms: string[]): void;
/**
* Request to leave multiple rooms.
* Only rooms currently joined will be sent.
*
* @param rooms - Array of room names to leave.
*
* @example
* socket.rooms.bulk.leave(['lobby', 'notifications']);
*/
leave(rooms: string[]): void;
/** Bulk lifecycle hooks. */
readonly lifecycle: {
/**
* Register a listener for successful single-room join.
* @param callback - Function invoked with the room name.
* Emitted when a bulk join succeeds.
* @param callback - Function that receives the list of rooms.
*/
onJoinSuccess: (callback: (room: string) => void) => void;
onJoinSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Remove a listener for successful single-room join.
* @param callback - Optional; if omitted, all listeners are removed.
* Removes a bulk join‑success listener.
* @param callback - The listener to remove.
*/
offJoinSuccess: (callback?: (room: string) => void) => void;
offJoinSuccess: (callback?: (rooms: string[]) => void) => void;
/**
* Register a one-time listener for successful single-room join.
* @param callback - Function invoked once with the room name.
* One‑time listener for a bulk join success.
* @param callback - Function that receives the list of rooms.
*/
onceJoinSuccess: (callback: (room: string) => void) => void;
onceJoinSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Register a listener for single-room join errors.
* @param callback - Function invoked with the room name and error data.
* Emitted when a bulk join fails.
* @param callback - Function that receives the list of rooms and error context.
*/
onJoinError: (callback: (room: string, ctx: ErrorContext) => void) => void;
onJoinError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Remove a listener for single-room join errors.
* @param callback - Optional; if omitted, all listeners are removed.
* Removes a bulk join‑error listener.
* @param callback - The listener to remove.
*/
offJoinError: (callback?: (room: string, ctx: ErrorContext) => void) => void;
offJoinError: (callback?: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Register a one-time listener for single-room join errors.
* @param callback - Function invoked once with the room name and error data.
* One‑time listener for a bulk join error.
* @param callback - Function that receives the list of rooms and error context.
*/
onceJoinError: (callback: (room: string, ctx: ErrorContext) => void) => void;
onceJoinError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Register a listener for successful single-room leave.
* @param callback - Function invoked with the room name.
* Emitted when a bulk leave succeeds.
* @param callback - Function that receives the list of rooms.
*/
onLeaveSuccess: (callback: (room: string) => void) => void;
onLeaveSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Remove a listener for successful single-room leave.
* @param callback - Optional; if omitted, all listeners are removed.
* Removes a bulk leave‑success listener.
* @param callback - The listener to remove.
*/
offLeaveSuccess: (callback?: (room: string) => void) => void;
offLeaveSuccess: (callback?: (rooms: string[]) => void) => void;
/**
* Register a one-time listener for successful single-room leave.
* @param callback - Function invoked once with the room name.
* One‑time listener for a bulk leave success.
* @param callback - Function that receives the list of rooms.
*/
onceLeaveSuccess: (callback: (room: string) => void) => void;
onceLeaveSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Register a listener for single-room leave errors.
* @param callback - Function invoked with the room name and error data.
* Emitted when a bulk leave fails.
* @param callback - Function that receives the list of rooms and error context.
*/
onLeaveError: (callback: (room: string, ctx: ErrorContext) => void) => void;
onLeaveError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Remove a listener for single-room leave errors.
* @param callback - Optional; if omitted, all listeners are removed.
* Removes a bulk leave‑error listener.
* @param callback - The listener to remove.
*/
offLeaveError: (callback?: (room: string, ctx: ErrorContext) => void) => void;
offLeaveError: (callback?: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Register a one-time listener for single-room leave errors.
* @param callback - Function invoked once with the room name and error data.
* One‑time listener for a bulk leave error.
* @param callback - Function that receives the list of rooms and error context.
*/
onceLeaveError: (callback: (room: string, ctx: ErrorContext) => void) => void;
onceLeaveError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
};
}
/**
* Public API for room management on a ByteSocket client.
*
* @typeParam TEvents -- The event map type (from `SocketEvents`) that defines allowed room event names and payloads.
*/
interface IRoomManager<TEvents extends SocketEvents> {
/**
* Lifecycle event listeners for single-room join/leave operations.
*
* @example
* socket.rooms.lifecycle.onJoinSuccess((room) => {
* console.log(`Joined room ${room}`);
* });
*/
readonly lifecycle: RoomLifecycleApi;
/**
* Bulk operations (join/leave/emit multiple rooms) and their lifecycle listeners.

@@ -212,98 +264,4 @@ *

*/
readonly bulk: {
/**
* Emit an event to multiple rooms at once.
*
* @typeParam Rs - The array of room names.
* @typeParam E - The event name.
* @typeParam D - The event data type.
*
* @example
* socket.rooms.bulk.emit(['roomA', 'roomB'], 'message', { text: 'Hello both!' });
*/
emit: <Rs extends NonNullable<TEvents["emitRooms"]>["rooms"], E extends StringNumberKeys<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>, D extends NonNullable<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>[E]>(rooms: Rs, event: E, data: D) => void;
/**
* Request to join multiple rooms.
* Only rooms not already joined or pending will be sent.
*
* @example
* socket.rooms.bulk.join(['lobby', 'notifications']);
*/
join: (rooms: string[]) => void;
/**
* Request to leave multiple rooms.
* Only rooms currently joined will be sent.
*
* @example
* socket.rooms.bulk.leave(['lobby', 'notifications']);
*/
leave: (rooms: string[]) => void;
lifecycle: {
/**
* Register a listener for successful bulk join.
* @param callback - Function invoked with the array of room names.
*/
onJoinSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Remove a listener for successful bulk join.
* @param callback - Optional; if omitted, all listeners are removed.
*/
offJoinSuccess: (callback?: (rooms: string[]) => void) => void;
/**
* Register a one-time listener for successful bulk join.
* @param callback - Function invoked once with the array of room names.
*/
onceJoinSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Register a listener for bulk join errors.
* @param callback - Function invoked with the array of room names and error data.
*/
onJoinError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Remove a listener for bulk join errors.
* @param callback - Optional; if omitted, all listeners are removed.
*/
offJoinError: (callback?: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Register a one-time listener for bulk join errors.
* @param callback - Function invoked once with the array of room names and error data.
*/
onceJoinError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Register a listener for successful bulk leave.
* @param callback - Function invoked with the array of room names.
*/
onLeaveSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Remove a listener for successful bulk leave.
* @param callback - Optional; if omitted, all listeners are removed.
*/
offLeaveSuccess: (callback?: (rooms: string[]) => void) => void;
/**
* Register a one-time listener for successful bulk leave.
* @param callback - Function invoked once with the array of room names.
*/
onceLeaveSuccess: (callback: (rooms: string[]) => void) => void;
/**
* Register a listener for bulk leave errors.
* @param callback - Function invoked with the array of room names and error data.
*/
onLeaveError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Remove a listener for bulk leave errors.
* @param callback - Optional; if omitted, all listeners are removed.
*/
offLeaveError: (callback?: (rooms: string[], ctx: ErrorContext) => void) => void;
/**
* Register a one-time listener for bulk leave errors.
* @param callback - Function invoked once with the array of room names and error data.
*/
onceLeaveError: (callback: (rooms: string[], ctx: ErrorContext) => void) => void;
};
};
readonly bulk: RoomBulkApi<TEvents>;
/**
* @internal
*/
constructor(debug: boolean, send: <R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>, bypassAuthPending?: boolean) => void, onOpen: (callback: () => void) => void, onClose: (callback: (event: CloseEvent) => void) => void);
/**
* Emit an event to a specific room.

@@ -314,2 +272,5 @@ *

* @typeParam D - The event data type.
* @param room - Room to emit the event to.
* @param event - Name of the event to emit.
* @param data - Event payload.
*

@@ -325,2 +286,4 @@ * @example

*
* @param room - Name of the room to join.
*
* @example

@@ -333,2 +296,4 @@ * socket.rooms.join('chat');

*
* @param room - Name of the room to leave.
*
* @example

@@ -353,2 +318,5 @@ * socket.rooms.leave('chat');

* @typeParam E - Event name.
* @param room - Name of the room.
* @param event - Name of the event to listen for.
* @param callback - Function to call when the event is received.
*

@@ -367,2 +335,6 @@ * @example

*
* @param room - Name of the room.
* @param event - (optional) Name of the event.
* @param callback - (optional) The specific listener to remove.
*
* @example

@@ -381,2 +353,6 @@ * // Remove specific callback

*
* @param room - Name of the room.
* @param event - Name of the event to listen for.
* @param callback - Function to call once when the event is received.
*
* @example

@@ -400,77 +376,131 @@ * socket.rooms.once('chat', 'message', (data) => {

}
interface LifecycleApi {
/**
* Register a listener for the socket opens (after successful authentication).
* @param callback - Function to call when the socket opens.
*/
onOpen: (callback: () => void) => void;
/**
* Remove a listener for socket open.
* @param callback - The listener to remove.
*/
offOpen: (callback?: () => void) => void;
/**
* Register a one-time listener for socket open.
* @param callback - Function to call once when the socket opens.
*/
onceOpen: (callback: () => void) => void;
/**
* Listen for raw incoming WebSocket messages **after** internal heartbeat filtering.
* Receive `string` (JSON) or `ArrayBuffer` (binary).
* @param callback - Function that receives the raw message data.
*/
onMessage: (callback: (data: string | ArrayBuffer) => void) => void;
/**
* Remove a listener for raw messages.
* @param callback - The listener to remove.
*/
offMessage: (callback?: (data: string | ArrayBuffer) => void) => void;
/**
* Register a one-time listener for raw incoming WebSocket messages.
* @param callback - Function to call once with the raw data.
*/
onceMessage: (callback: (data: string | ArrayBuffer) => void) => void;
/**
* Register a listener for the socket closes.
* @param callback - Function that receives the `CloseEvent`.
*/
onClose: (callback: (event: CloseEvent) => void) => void;
/**
* Remove a listener for socket close.
* @param callback - The listener to remove.
*/
offClose: (callback?: (event: CloseEvent) => void) => void;
/**
* Register a one-time listener for socket close.
* @param callback - Function to call once when the socket closes.
*/
onceClose: (callback: (event: CloseEvent) => void) => void;
/**
* Emitted on WebSocket errors.
* @param callback - Function that receives the error context.
*/
onError: (callback: (ctx: ErrorContext) => void) => void;
/**
* Remove a listener for WebSocket errors.
* @param callback - The listener to remove.
*/
offError: (callback?: (ctx: ErrorContext) => void) => void;
/**
* Register a one-time listener for WebSocket errors.
* @param callback - Function to call once on error.
*/
onceError: (callback: (ctx: ErrorContext) => void) => void;
/**
* Emitted after successful authentication.
* @param callback - Function to call when authentication succeeds.
*/
onAuthSuccess: (callback: () => void) => void;
/**
* Remove a listener for authentication success.
* @param callback - The listener to remove.
*/
offAuthSuccess: (callback?: () => void) => void;
/**
* Register a one-time listener for authentication success.
* @param callback - Function to call once on auth success.
*/
onceAuthSuccess: (callback: () => void) => void;
/**
* Register a listener for authentication fails.
* @param callback - Function that receives the error context.
*/
onAuthError: (callback: (ctx: ErrorContext) => void) => void;
/**
* Remove a listener for authentication errors.
* @param callback - The listener to remove.
*/
offAuthError: (callback?: (ctx: ErrorContext) => void) => void;
/**
* Register a one-time listener for authentication errors.
* @param callback - Function to call once on auth error.
*/
onceAuthError: (callback: (ctx: ErrorContext) => void) => void;
/**
* Register a listener for the outgoing message queue is full and a message is dropped.
* @param callback - Function to call when the queue overflows.
*/
onQueueFull: (callback: () => void) => void;
/**
* Remove a listener for queue-full events.
* @param callback - The listener to remove.
*/
offQueueFull: (callback?: () => void) => void;
/**
* Register a one-time listener for queue-full events.
* @param callback - Function to call once when the queue is full.
*/
onceQueueFull: (callback: () => void) => void;
/**
* Register a listener for when reconnection fails after all attempts.
* @param callback - Function to call when reconnection is exhausted.
*/
onReconnectFailed: (callback: () => void) => void;
/**
* Remove a listener for reconnect-failed events.
* @param callback - The listener to remove.
*/
offReconnectFailed: (callback?: () => void) => void;
/**
* Register a one-time listener for reconnect-failed events.
* @param callback - Function to call once when reconnection fails.
*/
onceReconnectFailed: (callback: () => void) => void;
}
/**
* ByteSocket is a WebSocket client with automatic reconnection, room management,
* authentication, heartbeat, and pluggable serialization (JSON or MessagePack).
* Public API of the ByteSocket WebSocket client.
*
* It provides a fully typed event system via a user-supplied event map (`TEvents`).
*
* @typeParam TEvents - A type extending `SocketEvents` that defines the shape of
* all emit/listen events (global and room-scoped).
*
* @example Symmetric events (most common)
* ```ts
* // Define your event map
* type MyEvents = SocketEvents<{
* "chat:message": { text: string };
* "user:joined": { userId: string };
* }>;
*
* // Create a typed socket instance
* const socket = new ByteSocket<MyEvents>('wss://example.com/socket', {
* debug: true,
* auth: { token: 'abc123' }
* });
*
* // Use typed methods (emit and listen share the same event map)
* socket.emit('chat:message', { text: 'Hello!' });
* socket.on('user:joined', (data) => console.log(data.userId));
*
* socket.rooms.join('lobby');
* socket.rooms.emit('lobby', 'chat:message', { text: 'Hi everyone' });
* socket.rooms.on('lobby', 'chat:message', (data) => {
* console.log(`Message: ${data.text}`);
* });
* ```
*
* @example Asymmetric events (full control via interface extension)
* ```ts
* // Extend SocketEvents to differentiate emit/listen/room maps
* interface MyEvents extends SocketEvents {
* emit: {
* "message:send": { text: string };
* "ping": void;
* };
* listen: {
* "message:receive": { text: string; sender: string };
* "pong": number;
* };
* emitRoom: {
* chat: { "message": { text: string } };
* dm: { "message": { text: string; recipient: string } };
* };
* listenRoom: {
* chat: { "message": { text: string; sender: string } };
* };
* }
*
* const socket = new ByteSocket<MyEvents>('wss://example.com/socket', {
* debug: true,
* auth: { token: 'abc123' }
* });
*
* // Global emits/listens
* socket.emit('ping', undefined);
* socket.on('message:receive', (data) => console.log(`${data.sender}: ${data.text}`));
*
* // Room-specific emits/listens
* socket.rooms.join('chat');
* socket.rooms.emit('chat', 'message', { text: 'Hello!' });
* socket.rooms.on('chat', 'message', (data) => {
* console.log(`${data.sender}: ${data.text}`);
* });
* ```
* @typeParam TEvents -- The event map type (from `SocketEvents`) that defines allowed event names and payloads.
*/
declare class ByteSocket<TEvents extends SocketEvents = SocketEvents> extends SocketBase {
#private;
interface IByteSocket<TEvents extends SocketEvents = SocketEvents> {
/**

@@ -484,57 +514,3 @@ * Lifecycle event listeners for connection, authentication, and errors.

*/
readonly lifecycle: {
/** Register a listener for socket open. */
onOpen: (callback: () => void) => void;
/** Remove a listener for socket open. */
offOpen: (callback?: () => void) => void;
/** Register a one-time listener for socket open. */
onceOpen: (callback: () => void) => void;
/**
* Register a listener for raw incoming WebSocket messages.
* Called immediately when a message is received, before any internal processing.
*
* @param callback - Receives the raw data and a boolean indicating if it's binary.
*/
onMessage: (callback: (data: string | ArrayBuffer) => void) => void;
/** Remove a listener for raw messages. */
offMessage: (callback?: (data: string | ArrayBuffer) => void) => void;
/** Register a one-time listener for raw incoming WebSocket messages. */
onceMessage: (callback: (data: string | ArrayBuffer) => void) => void;
/** Register a listener for socket close. */
onClose: (callback: (event: CloseEvent) => void) => void;
/** Remove a listener for socket close. */
offClose: (callback?: (event: CloseEvent) => void) => void;
/** Register a one-time listener for socket close. */
onceClose: (callback: (event: CloseEvent) => void) => void;
/** Register a listener for WebSocket errors. */
onError: (callback: (event: ErrorContext) => void) => void;
/** Remove a listener for WebSocket errors. */
offError: (callback?: (event: ErrorContext) => void) => void;
/** Register a one-time listener for WebSocket errors. */
onceError: (callback: (event: ErrorContext) => void) => void;
/** Register a listener for authentication success. */
onAuthSuccess: (callback: () => void) => void;
/** Remove a listener for authentication success. */
offAuthSuccess: (callback?: () => void) => void;
/** Register a one-time listener for authentication success. */
onceAuthSuccess: (callback: () => void) => void;
/** Register a listener for authentication errors. */
onAuthError: (callback: (ctx: ErrorContext) => void) => void;
/** Remove a listener for authentication errors. */
offAuthError: (callback?: (ctx: ErrorContext) => void) => void;
/** Register a one-time listener for authentication errors. */
onceAuthError: (callback: (ctx: ErrorContext) => void) => void;
/** Register a listener for when the message queue becomes full and a message is dropped. */
onQueueFull: (callback: () => void) => void;
/** Remove a listener for queue-full events. */
offQueueFull: (callback?: () => void) => void;
/** Register a one-time listener for queue-full events. */
onceQueueFull: (callback: () => void) => void;
/** Register a listener for when reconnection fails after all attempts. */
onReconnectFailed: (callback: () => void) => void;
/** Remove a listener for reconnect-failed events. */
offReconnectFailed: (callback?: () => void) => void;
/** Register a one-time listener for reconnect-failed events. */
onceReconnectFailed: (callback: () => void) => void;
};
readonly lifecycle: LifecycleApi;
/**

@@ -547,17 +523,11 @@ * Room management and room-scoped events.

*/
readonly rooms: RoomManager<TEvents>;
protected readonly debug: boolean;
readonly rooms: IRoomManager<TEvents>;
/**
* Creates a new ByteSocket instance.
* Current WebSocket `readyState` (CONNECTING, OPEN, CLOSING, CLOSED).
* Returns `WebSocket.CLOSED` if no socket exists.
*
* @param baseUrl - WebSocket URL (e.g., `wss://example.com/socket` or relative `"/socket"`).
* @param options - Configuration options.
* @returns The current readyState constant.
*/
constructor(baseUrl: string, options?: ByteSocketOptions);
readonly readyState: number;
/**
* Current WebSocket readyState (CONNECTING, OPEN, CLOSING, CLOSED).
* Returns `WebSocket.CLOSED` if no socket exists.
*/
get readyState(): number;
/**
* Whether the socket is currently able to send messages.

@@ -568,2 +538,4 @@ * Returns `true` if the WebSocket is open and authentication (if configured) has succeeded.

*
* @returns `true` if ready to send, otherwise `false`.
*
* @example

@@ -574,12 +546,16 @@ * if (socket.canSend) {

*/
get canSend(): boolean;
readonly canSend: boolean;
/**
* Whether the socket has been manually closed or permanently destroyed.
* Returns `true` after `close()` or `destroy()` has been called.
*
* @returns `true` if closed/destroyed, otherwise `false`.
*/
get isClosed(): boolean;
readonly isClosed: boolean;
/**
* Whether the underlying WebSocket connection is currently open.
*
* @returns `true` if the connection is open, otherwise `false`.
*/
get isConnected(): boolean;
readonly isConnected: boolean;
/**

@@ -610,5 +586,5 @@ * Encode a structured payload into a format suitable for sending over the WebSocket.

*/
decode(message: string | ArrayBuffer, isBinary?: boolean): any;
decode(message: string | ArrayBuffer, isBinary?: boolean): unknown;
/**
* Send a pre-serialized payload (LifecycleMessage or UserMessage) over the WebSocket.
* Send a payload (LifecycleMessage or UserMessage) to be serialized and sent over the WebSocket.
* If the socket is not ready, the payload is queued and sent when the connection

@@ -629,9 +605,9 @@ * becomes operational and authentication (if required) has succeeded.

/**
* Send a raw message (string or Uint8Array<ArrayBuffer>) directly over the WebSocket.
* Bypasses serialization and auth checks. If the socket is not open, the message
* is queued and sent when possible (auth state is ignored).
* Send a raw message (string or binary) directly over the WebSocket.
* Bypasses serialisation and auth checks. If the socket is not open, the message
* is queued and sent when possible.
*
* @param message - The raw data to send.
* @param message -- The raw data to send (`string`, `ArrayBuffer`, or any typed array).
*/
sendRaw(message: string | Uint8Array<ArrayBuffer>): void;
sendRaw(message: ClientSendData): void;
/**

@@ -642,2 +618,4 @@ * Emit a global event.

* @typeParam D - Event data type.
* @param event - Name of the event to emit.
* @param data - Event payload.
*

@@ -653,2 +631,4 @@ * @example

* @typeParam E - Event name (must be a key in `TEvents['listen']`).
* @param event - Name of the event to listen for.
* @param callback - Function to call when the event is received.
*

@@ -666,2 +646,5 @@ * @example

*
* @param event - Name of the event.
* @param callback - (optional) The specific listener to remove.
*
* @example

@@ -678,2 +661,5 @@ * // Remove specific callback

*
* @param event - Name of the event.
* @param callback - Function to call once when the event occurs.
*
* @example

@@ -686,11 +672,2 @@ * socket.once('user:joined', (data) => {

/**
* Update the authentication configuration before connecting.
* Must be called before `connect()` (or auto-connect).
*
* @param config - New auth config (static object or async callback).
*
* @throws {Error} If called after `destroy()` or after the socket is already connecting/open.
*/
setAuth<D>(config: AuthConfig<D> | undefined): void;
/**
* Opens the WebSocket connection. Called automatically if `autoConnect` is `true`.

@@ -718,4 +695,179 @@ * Can be called manually after a previous `close()`.

destroy(): void;
/**
* Update the authentication configuration before connecting.
* Must be called before `connect()` (or auto-connect).
*
* @param config - New auth config (static object or async callback).
*
* @throws {Error} If called after `destroy()` or after the socket is already connecting/open.
*/
setAuth<D>(config: AuthConfig<D> | undefined): void;
}
export { type AuthConfig, ByteSocket, type ByteSocketOptions, type EventCallback, RoomManager, type RoomState, SocketBase };
/**
* Abstract base class providing common callback management for lifecycle and user events.
* Used internally by `ByteSocket` and `RoomManager`.
*
* @internal
*/
declare abstract class SocketBase {
/** Whether debug logging is enabled. */
protected abstract readonly debug: boolean;
/** Stores permanent callbacks for lifecycle events. */
protected lifecycleCallbacksMap: Map<string | number, Set<AnyCallback>>;
/** Stores `once` wrappers for lifecycle events. */
protected onceLifecycleCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>;
/** Adds a callback to a given event in the provided map. */
protected addCallback<E extends string | number, D>(callbacksMap: Map<string | number, Set<AnyCallback>>, event: E, callback: EventCallback<D>): void;
/** Registers a one-time callback by storing the wrapper in a separate map. */
protected addOnceCallback<E extends string | number, D>(onceCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>, event: E, callback: EventCallback<D>, callbackWrapper: EventCallback<D>): void;
/** Removes a callback from an event map. */
protected deleteCallback<E extends string | number, D>(callbacksMap: Map<string | number, Set<AnyCallback>>, event: E, callbackWrapper: EventCallback<D>): void;
/** Removes a one-time callback and its associated wrapper. */
protected deleteOnceCallback<E extends string | number, D>(onceCallbacksMap: Map<string | number, Map<AnyCallback, Set<AnyCallback>>>, event: E, callback: EventCallback<D>, callbackWrapper: EventCallback<D>): void;
/** Registers a permanent listener for a lifecycle event. */
protected onLifecycle<T extends LifecycleTypes>(type: T, callback: AnyCallback): void;
/**
* Removes a listener for a lifecycle event.
* If no callback is provided, all listeners for that event are removed.
*/
protected offLifecycle<T extends LifecycleTypes>(type: T, callback?: AnyCallback): void;
/**
* Registers a one-time listener for a lifecycle event.
* The callback is automatically removed after the first invocation.
*/
protected onceLifecycle<T extends LifecycleTypes>(type: T, callback: AnyCallback): void;
/** Safely invokes a set of callbacks, catching and logging errors if debug is enabled. */
protected triggerCallback<Args extends Array<unknown>>(callbackWrappers?: Set<AnyCallback>, ...args: Args): void;
}
/**
* Manages room membership and room-scoped event listeners.
*
* You should not instantiate this class directly; it is accessible via
* `socket.rooms` on a ByteSocket instance.
*
* @typeParam TEvents - The event map type (from SocketEvents) defining allowed room events.
*/
declare class RoomManager<TEvents extends SocketEvents> extends SocketBase implements IRoomManager<TEvents> {
#private;
protected readonly debug: boolean;
readonly lifecycle: RoomLifecycleApi;
readonly bulk: RoomBulkApi<TEvents>;
/** @internal */
constructor(debug: boolean, send: <R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>, bypassAuthPending?: boolean) => void, onOpen: (callback: () => void) => void, onClose: (callback: (event: CloseEvent) => void) => void);
emit<R extends StringKeys<TEvents["emitRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["emitRoom"]>[R]>, D extends NonNullable<TEvents["emitRoom"]>[R][E]>(room: R, event: E, data: D): void;
join(room: string): void;
leave(room: string): void;
list(): string[];
on<R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event: E, callback: EventCallback<D>): void;
off<R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event?: E, callback?: EventCallback<D>): void;
once<R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event: E, callback: EventCallback<D>): void;
_handleMessage(payload: UserMessage): boolean;
_clear(): void;
}
/**
* ByteSocket is a WebSocket client with automatic reconnection, room management,
* authentication, heartbeat, and pluggable serialization (JSON or MessagePack).
*
* It provides a fully typed event system via a user-supplied event map (`TEvents`).
*
* @typeParam TEvents - A type extending `SocketEvents` that defines the shape of
* all emit/listen events (global and room-scoped).
*
* @example Symmetric events (most common)
* ```ts
* // Define your event map
* type MyEvents = SocketEvents<{
* "chat:message": { text: string };
* "user:joined": { userId: string };
* }>;
*
* // Create a typed socket instance
* const socket = new ByteSocket<MyEvents>('wss://example.com/socket', {
* debug: true,
* auth: { data: { token: 'abc123' } }
* });
*
* // Use typed methods (emit and listen share the same event map)
* socket.emit('chat:message', { text: 'Hello!' });
* socket.on('user:joined', (data) => console.log(data.userId));
*
* socket.rooms.join('lobby');
* socket.rooms.emit('lobby', 'chat:message', { text: 'Hi everyone' });
* socket.rooms.on('lobby', 'chat:message', (data) => {
* console.log(`Message: ${data.text}`);
* });
* ```
*
* @example Asymmetric events (full control via interface extension)
* ```ts
* // Extend SocketEvents to differentiate emit/listen/room maps
* interface MyEvents extends SocketEvents {
* emit: {
* "message:send": { text: string };
* "ping": void;
* };
* listen: {
* "message:receive": { text: string; sender: string };
* "pong": number;
* };
* emitRoom: {
* chat: { "message": { text: string } };
* dm: { "message": { text: string; recipient: string } };
* };
* listenRoom: {
* chat: { "message": { text: string; sender: string } };
* };
* }
*
* const socket = new ByteSocket<MyEvents>('wss://example.com/socket', {
* debug: true,
* auth: { data: { token: 'abc123' } }
* });
*
* // Global emits/listens
* socket.emit('ping', undefined);
* socket.on('message:receive', (data) => console.log(`${data.sender}: ${data.text}`));
*
* // Room-specific emits/listens
* socket.rooms.join('chat');
* socket.rooms.emit('chat', 'message', { text: 'Hello!' });
* socket.rooms.on('chat', 'message', (data) => {
* console.log(`${data.sender}: ${data.text}`);
* });
* ```
*/
declare class ByteSocket<TEvents extends SocketEvents = SocketEvents> extends SocketBase implements IByteSocket<TEvents> {
#private;
readonly lifecycle: LifecycleApi;
readonly rooms: RoomManager<TEvents>;
protected readonly debug: boolean;
/**
* Creates a new ByteSocket instance.
*
* @param baseUrl - WebSocket URL (e.g., `wss://example.com/socket` or relative `"/socket"`).
* @param options - Configuration options.
*/
constructor(baseUrl: string, options?: ByteSocketOptions);
get readyState(): number;
get canSend(): boolean;
get isClosed(): boolean;
get isConnected(): boolean;
encode<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>, serialization?: "json" | "binary"): string | Uint8Array<ArrayBuffer>;
decode(message: string | ArrayBuffer, isBinary?: boolean): any;
send<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): void;
sendRaw(message: ClientSendData): void;
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): void;
on<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<D>): void;
off<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback?: EventCallback<D>): void;
once<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<D>): void;
setAuth<D>(config: AuthConfig<D> | undefined): void;
connect(): void;
reconnect(): void;
close(code?: number, reason?: string): void;
destroy(): void;
}
export { type AuthConfig, ByteSocket, type ByteSocketOptions, type EventCallback, type IByteSocket, type IRoomManager, type LifecycleApi, type RoomBulkApi, type RoomLifecycleApi };
{
"name": "@bytesocket/client",
"version": "0.2.2",
"version": "0.3.0",
"description": "High-performance WebSocket client for browsers",

@@ -45,3 +45,3 @@ "keywords": [

"msgpackr": "^1.11.10",
"@bytesocket/types": "0.2.2"
"@bytesocket/types": "0.3.0"
},

@@ -48,0 +48,0 @@ "engines": {

@@ -38,6 +38,6 @@ # ByteSocket

| Package | Backend | Status |
| ------------------------------------------------------------------ | --------------------------------------------------------------- | -------------- |
| [`@bytesocket/uws`](https://www.npmjs.com/package/@bytesocket/uws) | [uWebSockets.js](https://github.com/uNetworking/uWebSockets.js) | ✅ Available |
| `@bytesocket/node` | node:http server using [ws](https://www.npmjs.com/package/ws) | 🚧 Coming soon |
| Package | Backend | Status |
| -------------------------------------------------------------------- | --------------------------------------------------------------- | ------------ |
| [`@bytesocket/uws`](https://www.npmjs.com/package/@bytesocket/uws) | [uWebSockets.js](https://github.com/uNetworking/uWebSockets.js) | ✅ Available |
| [`@bytesocket/node`](https://www.npmjs.com/package/@bytesocket/node) | node:http server using [ws](https://www.npmjs.com/package/ws) | ✅ Available |

@@ -143,3 +143,3 @@ ---

const socket = new ByteSocket("wss://example.com/socket", {
auth: { token: "my-secret-token" },
auth: { data: { token: "my-secret-token" } },
});

@@ -449,3 +449,3 @@

// Set auth before the first connect
socket.setAuth({ token: getToken() });
socket.setAuth({ data: { token: getToken() } });
socket.connect();

@@ -455,3 +455,3 @@

socket.close();
socket.setAuth({ token: await refreshToken() });
socket.setAuth({ data: { token: await refreshToken() } });
socket.connect();

@@ -494,3 +494,3 @@ ```

// Auth
auth: { token: "abc" }, // or async (callback) => callback(data)
auth: { data: { token: "abc" } }, // or async (callback) => callback(data)
authTimeout: 5000,

@@ -497,0 +497,0 @@

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display