bitmart-api
Version:
Complete & robust Node.js SDK for BitMart's REST APIs and WebSockets, with TypeScript declarations.
157 lines (156 loc) • 7.38 kB
TypeScript
import EventEmitter from 'events';
import WebSocket from 'isomorphic-ws';
import { WebsocketClientOptions, WSClientConfigurableOptions } from '../types/websockets/client.js';
import { DefaultLogger } from './logger.js';
import { MessageEventLike } from './requestUtils.js';
import { WsStore } from './websocket/WsStore.js';
interface WSClientEventMap<WsKey extends string> {
/** Connection opened. If this connection was previously opened and reconnected, expect the reconnected event instead */
open: (evt: {
wsKey: WsKey;
event: any;
}) => void;
/** Reconnecting a dropped connection */
reconnect: (evt: {
wsKey: WsKey;
event: any;
}) => void;
/** Successfully reconnected a connection that dropped */
reconnected: (evt: {
wsKey: WsKey;
event: any;
}) => void;
/** Connection closed */
close: (evt: {
wsKey: WsKey;
event: any;
}) => void;
/** Received reply to websocket command (e.g. after subscribing to topics) */
response: (response: any & {
wsKey: WsKey;
}) => void;
/** Received data for topic */
update: (response: any & {
wsKey: WsKey;
}) => void;
/** Exception from ws client OR custom listeners (e.g. if you throw inside your event handler) */
exception: (response: any & {
wsKey: WsKey;
}) => void;
/** Confirmation that a connection successfully authenticated */
authenticated: (event: {
wsKey: WsKey;
event: any;
}) => void;
}
export interface EmittableEvent<TEvent = any> {
eventType: 'response' | 'update' | 'exception' | 'authenticated';
event: TEvent;
}
export interface BaseWebsocketClient<TWSMarket extends string, TWSKey extends string, TWSTopic = any> {
on<U extends keyof WSClientEventMap<TWSKey>>(event: U, listener: WSClientEventMap<TWSKey>[U]): this;
emit<U extends keyof WSClientEventMap<TWSKey>>(event: U, ...args: Parameters<WSClientEventMap<TWSKey>[U]>): boolean;
}
export declare abstract class BaseWebsocketClient<TWSMarket extends string, TWSKey extends string,
/**
* The "topic" being subscribed to, not the event sent to subscribe to one or more topics
*/
TWSTopic extends string | object> extends EventEmitter {
private wsStore;
protected logger: typeof DefaultLogger;
protected options: WebsocketClientOptions;
constructor(options?: WSClientConfigurableOptions, logger?: typeof DefaultLogger);
protected abstract getWsKeyForMarket(market: TWSMarket, isPrivate?: boolean): TWSKey;
protected abstract sendPingEvent(wsKey: TWSKey, ws: WebSocket): void;
protected abstract isWsPong(data: any): boolean;
protected abstract getWsAuthRequestEvent(wsKey: TWSKey): Promise<object>;
protected abstract getWsMarketForWsKey(key: TWSKey): TWSMarket;
protected abstract isPrivateChannel(subscribeEvent: TWSTopic): boolean;
protected abstract getPrivateWSKeys(): TWSKey[];
protected abstract getWsUrl(wsKey: TWSKey): string;
protected abstract getMaxTopicsPerSubscribeEvent(wsKey: TWSKey): number | null;
/**
* Returns a list of string events that can be individually sent upstream to complete subscribing to these topics
*/
protected abstract getWsSubscribeEventsForTopics(topics: TWSTopic[], wsKey: TWSKey): string[];
/**
* Returns a list of string events that can be individually sent upstream to complete unsubscribing to these topics
*/
protected abstract getWsUnsubscribeEventsForTopics(topics: TWSTopic[], wsKey: TWSKey): string[];
/**
* Abstraction called to sort ws events into emittable event types (response to a request, data update, etc)
*/
protected abstract resolveEmittableEvents(event: MessageEventLike): EmittableEvent[];
/**
* Request connection of all dependent (public & private) websockets, instead of waiting for automatic connection by library
*/
abstract connectAll(): Promise<WebSocket | undefined>[];
protected isPrivateWsKey(wsKey: TWSKey): boolean;
/**
* Subscribe to one or more topics on a WS connection (identified by WS Key).
*
* - Topics are automatically cached
* - Connections are automatically opened, if not yet connected
* - Authentication is automatically handled
* - Topics are automatically resubscribed to, if something happens to the connection, unless you call unsubsribeTopicsForWsKey(topics, key).
*
* @param wsTopics array of topics to subscribe to
* @param wsKey ws key referring to the ws connection these topics should be subscribed on
*/
subscribeTopicsForWsKey(wsTopics: TWSTopic[], wsKey: TWSKey): false | Promise<WebSocket | undefined> | undefined;
unsubscribeTopicsForWsKey(wsTopics: TWSTopic[], wsKey: TWSKey): void;
/**
* Subscribe to topics & track/persist them. They will be automatically resubscribed to if the connection drops/reconnects.
* @param wsTopics topic or list of topics
* @param isPrivate optional - the library will try to detect private topics, you can use this to mark a topic as private (if the topic isn't recognised yet)
*/
subscribe(wsTopics: TWSTopic[] | TWSTopic, market: TWSMarket, isPrivate?: boolean): void;
/**
* Unsubscribe from topics & remove them from memory. They won't be re-subscribed to if the connection reconnects.
* @param wsTopics topic or list of topics
* @param isPrivateTopic optional - the library will try to detect private topics, you can use this to mark a topic as private (if the topic isn't recognised yet)
*/
unsubscribe(wsTopics: TWSTopic[] | TWSTopic, market: TWSMarket, isPrivateTopic?: boolean): void;
/** Get the WsStore that tracks websockets & topics */
getWsStore(): WsStore<TWSKey, TWSTopic>;
close(wsKey: TWSKey, force?: boolean): void;
closeAll(force?: boolean): void;
isConnected(wsKey: TWSKey): boolean;
/**
* Request connection to a specific websocket, instead of waiting for automatic connection.
*/
protected connect(wsKey: TWSKey): Promise<WebSocket | undefined>;
private parseWsError;
/** Get a signature, build the auth request and send it */
private sendAuthRequest;
private reconnectWithDelay;
private ping;
private clearTimers;
private clearPingTimer;
private clearPongTimer;
/**
* Simply builds and sends subscribe events for a list of topics for a ws key
*
* @private Use the `subscribe(topics)` or `subscribeTopicsForWsKey(topics, wsKey)` method to subscribe to topics. Send WS message to subscribe to topics.
*/
private requestSubscribeTopics;
/**
* Simply builds and sends unsubscribe events for a list of topics for a ws key
*
* @private Use the `unsubscribe(topics)` method to unsubscribe from topics. Send WS message to unsubscribe from topics.
*/
private requestUnsubscribeTopics;
/**
* Try sending a string event on a WS connection (identified by the WS Key)
*/
tryWsSend(wsKey: TWSKey, wsMessage: string): void;
private connectToWsUrl;
private onWsOpen;
/** Handle subscription to private topics _after_ authentication successfully completes asynchronously */
private onWsAuthenticated;
private onWsMessage;
private onWsClose;
private getWs;
private setWsState;
}
export {};