@tapsioss/client-socket-manager
Version:
<div align="center">
351 lines (345 loc) • 11.7 kB
TypeScript
import { ManagerOptions, SocketOptions, Socket } from 'socket.io-client';
type SubscribeCallback = (...args: any[]) => void;
type DisconnectDescription = Error | {
description: string;
context?: unknown;
};
type EventsMap = Record<string, any>;
type DefaultEventsMap = Record<string, SubscribeCallback>;
type EventNames<Map extends EventsMap> = keyof Map & string;
type EventParams<Map extends EventsMap, Ev extends EventNames<Map>> = Parameters<Map[Ev]>;
type OverrideMembers<Origin extends Record<PropertyKey, any>, Destination extends Record<PropertyKey, any>> = Omit<Origin, keyof Destination> & Destination;
type ClientSocketManagerListenerOptions = {
/**
* Fired upon instantiation.
*/
onInit?: (this: ClientSocketManager) => void;
/**
* Fired upon disposal.
*/
onDispose?: (this: ClientSocketManager) => void;
/**
* Fired upon a connection error.
*
* @param err - The connection error instance.
*/
onConnectionError?: (this: ClientSocketManager, err: Error) => void;
/**
* Fired when a ping packet is received from the server.
*/
onServerPing?: (this: ClientSocketManager) => void;
/**
* Fired upon an attempt to reconnect.
*
* @param attempt - The number of reconnection attempts.
*/
onReconnecting?: (this: ClientSocketManager, attempt: number) => void;
/**
* Fired upon a reconnection attempt error.
*
* @param err - The reconnection attempt error instance.
*/
onReconnectingError?: (this: ClientSocketManager, err: Error) => void;
/**
* Fired when couldn't reconnect within `reconnectionAttempts`.
*/
onReconnectionFailure?: (this: ClientSocketManager) => void;
/**
* Fired upon a successful reconnection.
*
* @param attempt - The number of reconnection attempts.
*/
onSuccessfulReconnection?: (this: ClientSocketManager, attempt: number) => void;
/**
* This event is fired by the Socket instance upon connection and reconnection.
*/
onSocketConnection?: (this: ClientSocketManager) => void;
/**
* This event is fired upon connection failure.
*
* @param err - The connection error instance.
*/
onSocketConnectionError?: (this: ClientSocketManager, err: Error) => void;
/**
* This event is fired upon disconnection.
*
* @param reason - The reason of disconnection.
* @param details - The details of the disconnection.
*/
onSocketDisconnection?: (this: ClientSocketManager, reason: Socket.DisconnectReason, details?: DisconnectDescription) => void;
/**
* The callback is fired when page's `visibilityState` changes to `visible`.
*
* The page content may be at least partially visible.
* In practice this means that the page is the foreground tab of a non-minimized window.
*/
onVisiblePage?: (this: ClientSocketManager) => void;
/**
* This callback is fired when page's `visibilityState` changes to `hidden`.
*
* The page's content is not visible to the user, either due to
* the document's tab being in the background or part of a window that is
* minimized, or because the device's screen is off.
*/
onHiddenPage?: (this: ClientSocketManager) => void;
/**
* The callback is fired when any message is received from a subscribed channel.
*
* @param channel - The name of the channel from which the message is received.
* @param received - The data received from the channel.
*/
onAnySubscribedMessageReceived?: (this: ClientSocketManager, channel: string, received: any[]) => void;
};
type ClientSocketManagerOptions = OverrideMembers<Partial<ManagerOptions> & SocketOptions, {
/**
* The time delay in milliseconds between reconnection attempts.
*
* @default 500
*/
reconnectionDelay?: number;
/**
* The max time delay in milliseconds between reconnection attempts.
*
* @default 2000
*/
reconnectionDelayMax?: number;
}> & {
/**
* Handlers for various events.
*/
eventHandlers?: ClientSocketManagerListenerOptions;
/**
* Client Socket Devtool options.
*
* This is useful for development and debugging purposes.
* In production environments, it's recommended to leave this section empty.
*/
devtool?: {
/**
* Enables the in-browser DevTool panel for socket debugging.
*
* When set to `true`, a floating DevTool UI will appear in the browser that displays:
* - The current socket connection status (`connected`, `disconnected`, `reconnecting`)
* - A list of currently subscribed channels
* - A log panel showing socket events and debugging messages.
*
* @default false
*/
enabled: boolean;
/**
* The `z-index` of the devtool.
*
* @default 9999
*/
zIndex?: number;
};
};
declare class ClientSocketManager<ListenEvents extends EventsMap = DefaultEventsMap, EmitEvents extends EventsMap = ListenEvents> {
private _disposed;
private _socket;
private _inputListeners;
constructor(uri: string, options?: ClientSocketManagerOptions);
private _attachPageEvents;
private _attachSocketEvents;
private _attachManagerEvents;
private _detachPageEvents;
private _detachSocketEvents;
private _detachManagerEvents;
private _handleVisibilityChange;
/**
* Whether the client is disposed.
*/
get disposed(): boolean;
/**
* Emits an event to the socket identified by the channel name.
*/
emit<Ev extends EventNames<EmitEvents>>(channel: Ev, ...args: EventParams<EmitEvents, Ev>): void;
/**
* A unique identifier for the session.
*
* `null` when the socket is not connected.
*/
get id(): string | null;
/**
* Whether the socket is currently connected to the server.
*/
get connected(): boolean;
/**
* Whether the connection state was recovered after a temporary disconnection.
* In that case, any missed packets will be transmitted by the server.
*/
get recovered(): boolean;
/**
* Whether the Socket will try to reconnect when its Manager connects
* or reconnects.
*/
get autoReconnectable(): boolean;
/**
* Subscribes to a specified channel with a callback function.
*/
subscribe<Ev extends EventNames<ListenEvents>>(
/**
* The name of the channel to subscribe to.
*/
channel: Ev,
/**
* The callback function to invoke when a message is received on the channel.
*/
cb: ListenEvents[Ev], options?: {
/**
* The callback function to invoke when the subscription is complete.
*/
onSubscriptionComplete?: (this: ClientSocketManager, channel: string) => void;
/**
* The `AbortSignal` to unsubscribe the listener upon abortion.
*/
signal?: AbortSignal;
}): void;
/**
* Removes the listener for the specified channel.
* If no callback is provided, it removes all listeners for that channel.
*/
unsubscribe<Ev extends EventNames<ListenEvents>>(
/**
* The name of the channel whose listener should be deleted.
*/
channel: Ev,
/**
* The subscriber callback function to remove.
*/
cb?: ListenEvents[Ev]): void;
/**
* Manually connects/reconnects the socket.
*/
connect(): void;
/**
* Manually disconnects the socket.
* In that case, the socket will not try to reconnect.
*
* If this is the last active Socket instance of the Manager,
* the low-level connection will be closed.
*/
disconnect(): void;
/**
* Disposes of the socket, manager, and engine, ensuring all connections are
* closed and cleaned up.
*/
dispose(): void;
/**
* Show devtool in the browser programmatically.
*/
showDevtool(): void;
/**
* Hide devtool in the browser programmatically.
*/
hideDevtool(): void;
}
/**
* A stub implementation of `ClientSocketManager` intended for use in
* test environments or server-side rendering (SSR), where actual socket
* connections are unnecessary or undesired.
*
* Provides no-op methods and tracks basic connection/disposal state.
*/
declare class ClientSocketManagerStub {
private _inputListeners;
private _connected;
private _disposed;
/**
* Indicates this is a mock/stub implementation.
*/
static __mock__: boolean;
/**
* Creates a new stubbed ClientSocketManager.
*
* @param _uri - Optional URI string, ignored in stub.
* @param options - Optional configuration object containing event handlers.
*/
constructor(_uri?: string, options?: Partial<ClientSocketManagerOptions>);
/**
* A static session identifier.
* Returns a mock ID if connected, otherwise null.
*/
get id(): string | null;
/**
* Whether the stub is considered connected.
*/
get connected(): boolean;
/**
* Whether the connection has been recovered after interruption.
* Always returns false in the stub.
*/
get recovered(): boolean;
/**
* Whether the client attempts reconnection automatically.
* Always returns false in the stub.
*/
get autoReconnectable(): boolean;
/**
* Whether this instance has been disposed.
*/
get disposed(): boolean;
/**
* Emits a message to the server.
* No-op in stub.
*
* @param _args - Event name and payload, ignored in stub.
*/
emit(): void;
/**
* Subscribes to a socket channel.
* No-op in stub.
*
* @param _channel - Channel name.
* @param _cb - Callback function.
* @param _options - Optional configuration for signal and subscription completion.
*/
subscribe(_channel: string, _cb: () => void, _options?: {
onSubscriptionComplete?: (channel: string) => void;
signal?: AbortSignal;
}): void;
/**
* Unsubscribes from a socket channel.
* No-op in stub.
*
* @param _channel - Channel name.
* @param _cb - Callback function to remove.
*/
unsubscribe(_channel: string, _cb: () => void): void;
/**
* Simulates connecting to a socket.
* Triggers the `onSocketConnection` event handler if defined.
*/
connect(): void;
/**
* Simulates disconnecting the socket.
* Triggers the `onSocketDisconnection` event handler if defined.
*/
disconnect(): void;
/**
* Cleans up the instance by disconnecting and clearing handlers.
*/
dispose(): void;
/**
* Show devtool in the browser programmatically.
*/
showDevtool(): void;
/**
* Show devtool in the browser programmatically.
*/
hideDevtool(): void;
}
declare const SocketReservedEvents: {
readonly CONNECTION: "connect";
readonly CONNECTION_ERROR: "connect_error";
readonly DISCONNECTION: "disconnect";
};
declare const ManagerReservedEvents: {
readonly SERVER_PING: "ping";
readonly CONNECTION_ERROR: "error";
readonly RECONNECTING: "reconnect_attempt";
readonly RECONNECTING_ERROR: "reconnect_error";
readonly RECONNECTION_FAILURE: "reconnect_failed";
readonly SUCCESSFUL_RECONNECTION: "reconnect";
};
export { ClientSocketManager, type ClientSocketManagerListenerOptions, type ClientSocketManagerOptions, ClientSocketManagerStub, ManagerReservedEvents, SocketReservedEvents };