UNPKG

@tapsioss/client-socket-manager

Version:
351 lines (345 loc) 11.7 kB
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 };