UNPKG

@drift-labs/common

Version:

Common functions for Drift

96 lines (95 loc) 4.05 kB
/// <reference types="ws" /> import { Subject, Subscription } from 'rxjs'; import WebSocket from 'isomorphic-ws'; type WebSocketMessage<T = Record<string, unknown>> = T; type WebSocketSubscriptionProps<T = Record<string, unknown>> = { wsUrl: string; subscriptionId: string; subscribeMessage: string; unsubscribeMessage: string; onError: (err?: any) => void; onMessage: (message: WebSocketMessage<T>) => void; messageFilter: (message: WebSocketMessage<T>) => boolean; errorMessageFilter: (message: WebSocketMessage<T>) => boolean; onClose?: () => void; enableHeartbeatMonitoring?: boolean; }; type WebSocketSubscriptionState<T = Record<string, unknown>> = WebSocketSubscriptionProps<T> & { hasSentSubscribeMessage?: boolean; subjectSubscription?: Subscription; }; type WebSocketUrl = string; type SubscriptionId = string; declare enum WebSocketConnectionState { CONNECTING = 0, CONNECTED = 1, DISCONNECTING = 2, DISCONNECTED = 3 } type IMultiplexWebSocket<T = Record<string, unknown>> = { wsUrl: WebSocketUrl; webSocket: WebSocket; customConnectionState: WebSocketConnectionState; subject: Subject<WebSocketMessage<T>>; subscriptions: Map<SubscriptionId, Omit<WebSocketSubscriptionProps<T>, 'wsUrl' | 'subscriptionId'>>; }; /** * MultiplexWebSocket allows for multiple subscriptions to a single websocket of the same URL, improving efficiency and reducing the number of open connections. * * This implementation assumes the following: * - All websocket streams are treated equally - reconnection attempts are performed at the same standards * - All messages returned are in the `WebSocketMessage` format * - A single instance of the websocket manager is created for each websocket URL - this means all subscriptions to the same websocket URL will share the same websocket instance * * Internal implementation details: * - The websocket is closed when the number of subscriptions is 0 * - The websocket will be refreshed (new instance) when it disconnects unexpectedly or errors, until it reaches the maximum number of reconnect attempts */ export declare class MultiplexWebSocket<T = Record<string, unknown>> implements IMultiplexWebSocket<T> { #private; /** * A lookup of all websockets by their URL. */ private static URL_TO_WEBSOCKETS_LOOKUP; /** * A lookup from websocket URL to all subscription IDs for that URL. */ private static URL_TO_SUBSCRIPTION_IDS_LOOKUP; wsUrl: WebSocketUrl; customConnectionState: WebSocketConnectionState; subject: Subject<WebSocketMessage<T>>; subscriptions: Map<SubscriptionId, Omit<WebSocketSubscriptionState<T>, 'wsUrl' | 'subscriptionId'>>; private reconnectionManager; private closeTimeout; private heartbeatTimeout; private heartbeatMonitoringEnabled; private constructor(); /** * Creates a new virtual websocket subscription. If an existing websocket for the given URL exists, the subscription will be added to the existing websocket. * Returns a function that can be called to unsubscribe from the subscription. */ static createWebSocketSubscription<T = Record<string, unknown>>(props: WebSocketSubscriptionProps<T>): { unsubscribe: () => void; }; private static handleNewSubForNewWsUrl; private static handleNewSubForExistingWsUrl; get webSocket(): WebSocket; /** * Setting the WebSocket instance will automatically add event handlers to the WebSocket instance. * When the WebSocket is connected, all existing subscriptions will be subscribed to. */ set webSocket(webSocket: WebSocket); private subscribeToWebSocket; private subscribe; private unsubscribe; private scheduleDelayedClose; private cancelDelayedClose; private close; private startHeartbeatMonitoring; private stopHeartbeatMonitoring; private resetHeartbeatTimeout; private isHeartbeatMessage; private handleHeartbeat; private refreshWebSocket; } export {};