@drift-labs/common 1.0.52 → 1.0.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"swiftClient.js","sourceRoot":"","sources":["../../src/clients/swiftClient.ts"],"names":[],"mappings":"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","sourcesContent":["import { AccountInfo, Connection, PublicKey } from '@solana/web3.js';\nimport {\n\tDriftClient,\n\tMarketType,\n\tOrderType,\n\tSignedMsgOrderParamsDelegateMessage,\n\tSignedMsgOrderParamsMessage,\n\tSignedMsgUserOrdersAccount,\n\tdigestSignature,\n\tisVariant,\n} from '@drift-labs/sdk';\n\n// Cache for URL construction to prevent repeated string concatenation\nconst swiftUrlCache = new Map<string, string>();\nconst MAX_SWIFT_URL_CACHE_SIZE = 200;\n\nfunction getCachedUrl(baseUrl: string, endpoint: string): string {\n\tconst cacheKey = `${baseUrl}:${endpoint}`;\n\n\tif (swiftUrlCache.has(cacheKey)) {\n\t\treturn swiftUrlCache.get(cacheKey)!;\n\t}\n\n\tconst result = `${baseUrl}${endpoint}`;\n\n\tif (swiftUrlCache.size < MAX_SWIFT_URL_CACHE_SIZE) {\n\t\tswiftUrlCache.set(cacheKey, result);\n\t}\n\n\treturn result;\n}\nimport { Observable, Subscriber } from 'rxjs';\nimport { allEnvDlog } from '../utils/logger';\nexport type SwiftServerOrderProcessResponse = {\n\terror?: string;\n\tmessage: string;\n};\n\ntype ClientResponse<T = void> = Promise<{\n\tsuccess: boolean;\n\tbody?: T;\n\tmessage?: string;\n\tstatus?: number;\n}>;\n\ntype BaseSwiftOrderEvent = {\n\thash: string;\n};\n\nexport interface SwiftOrderSentEvent extends BaseSwiftOrderEvent {\n\ttype: 'sent';\n}\n\nexport interface SwiftOrderErroredEvent extends BaseSwiftOrderEvent {\n\ttype: 'errored' | 'expired';\n\tmessage?: string;\n\tstatus?: number;\n}\n\nexport interface SwiftOrderConfirmedEvent extends BaseSwiftOrderEvent {\n\ttype: 'confirmed';\n\torderId: string;\n}\n\nexport type SwiftOrderEvent =\n\t| SwiftOrderErroredEvent\n\t| SwiftOrderConfirmedEvent\n\t| SwiftOrderSentEvent;\n\nexport type SwiftOrderEventWithParams<T extends SwiftOrderEvent> = T & {\n\tswiftOrderUuid: Uint8Array;\n\torderParamsMessage:\n\t\t| SignedMsgOrderParamsMessage\n\t\t| SignedMsgOrderParamsDelegateMessage;\n};\n\nexport class SwiftClient {\n\tprivate static baseUrl = '';\n\tprivate static swiftClientConsumer?: string;\n\n\tstatic supportedOrderTypes: OrderType[] = [OrderType.MARKET, OrderType.LIMIT];\n\n\tpublic static init(baseUrl: string, swiftClientConsumer?: string) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.swiftClientConsumer = swiftClientConsumer;\n\t}\n\n\tprivate static get(url: string) {\n\t\tif (!this.baseUrl) {\n\t\t\tthrow new Error('SwiftClient not initialized');\n\t\t}\n\n\t\treturn new Promise<{ success: boolean; body: string; status: number }>(\n\t\t\t(res) => {\n\t\t\t\tconst headers = new Headers({\n\t\t\t\t\t...this.getSwiftHeaders(),\n\t\t\t\t});\n\n\t\t\t\tfetch(getCachedUrl(this.baseUrl, url), {\n\t\t\t\t\theaders,\n\t\t\t\t})\n\t\t\t\t\t.then(async (response) => {\n\t\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\t\tres({\n\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\tbody: await response.text(),\n\t\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tres({\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\tbody: await response.text(),\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t});\n\t\t\t\t\t})\n\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\tres({ success: false, body: err, status: 0 });\n\t\t\t\t\t});\n\t\t\t}\n\t\t);\n\t}\n\n\tprivate static post(url: string, bodyObject: any) {\n\t\tif (!this.baseUrl) {\n\t\t\tthrow new Error('SwiftClient not initialized');\n\t\t}\n\n\t\tconst requestOptions = {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { ...this.getSwiftHeaders() },\n\t\t\tbody: JSON.stringify(bodyObject),\n\t\t};\n\n\t\treturn new Promise<{\n\t\t\tsuccess: boolean;\n\t\t\tbody: SwiftServerOrderProcessResponse;\n\t\t\tstatus: number;\n\t\t}>((res) => {\n\t\t\tconst postRequest = new Request(\n\t\t\t\tgetCachedUrl(this.baseUrl, url),\n\t\t\t\trequestOptions\n\t\t\t);\n\n\t\t\tfetch(postRequest)\n\t\t\t\t.then(async (response) => {\n\t\t\t\t\tlet resBody: SwiftServerOrderProcessResponse | null = null;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresBody =\n\t\t\t\t\t\t\t(await response.json()) as SwiftServerOrderProcessResponse;\n\n\t\t\t\t\t\tres({\n\t\t\t\t\t\t\tsuccess: response.ok,\n\t\t\t\t\t\t\tbody: resBody,\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tallEnvDlog('swiftClient', 'Error reading response body', err);\n\n\t\t\t\t\t\tres({\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\tbody: err as any,\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tres({ success: false, body: err, status: 0 });\n\t\t\t\t});\n\t\t});\n\t}\n\n\tstatic async sendSwiftOrder(\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tsigningAuthority?: PublicKey\n\t): ClientResponse<{\n\t\thash: string;\n\t}> {\n\t\tconst requestPayload = {\n\t\t\tmarket_index: marketIndex,\n\t\t\tmarket_type: isVariant(marketType, 'perp') ? 'perp' : 'spot',\n\t\t\tmessage,\n\t\t\tsignature: signature.toString('base64'),\n\t\t\tsigning_authority: signingAuthority?.toBase58() ?? '',\n\t\t\ttaker_authority: takerPubkey.toBase58(),\n\t\t};\n\n\t\tconst response = await this.post('/orders', requestPayload);\n\n\t\tif (response.status !== 200) {\n\t\t\tconsole.error(\n\t\t\t\t`Non-200 status code received for sent Swift order: ${response.status}`\n\t\t\t);\n\t\t\tallEnvDlog('swiftClient', 'full non-200 response body', response.body);\n\t\t\treturn {\n\t\t\t\tmessage:\n\t\t\t\t\tresponse.body?.error ||\n\t\t\t\t\tresponse.body?.message ||\n\t\t\t\t\t`HTTP ${response.status}: Error from Swift server`,\n\t\t\t\tstatus: response.status,\n\t\t\t\tsuccess: false,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tmessage: `Successfully sent Swift order`,\n\t\t\tbody: {\n\t\t\t\thash: digestSignature(Uint8Array.from(signature)),\n\t\t\t},\n\t\t\tsuccess: true,\n\t\t\tstatus: 200,\n\t\t};\n\t}\n\n\tstatic async confirmSwiftOrderWS(\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tsignedMsgUserOrdersAccount: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array,\n\t\tconfirmDuration: number\n\t): Promise<number | undefined> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tlet settled = false;\n\t\t\tlet subId: number | undefined = undefined;\n\t\t\tlet pollInterval: NodeJS.Timeout | undefined = undefined;\n\n\t\t\tconst finalizeResolve = (orderId: number) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tif (subId !== undefined) {\n\t\t\t\t\tconnection.removeAccountChangeListener(subId).catch(() => {});\n\t\t\t\t}\n\t\t\t\tclearTimeout(timeout);\n\n\t\t\t\tif (pollInterval) {\n\t\t\t\t\tclearInterval(pollInterval);\n\t\t\t\t}\n\n\t\t\t\tresolve(orderId);\n\t\t\t};\n\n\t\t\tconst finalizeReject = (error: Error) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tif (subId !== undefined) {\n\t\t\t\t\tconnection.removeAccountChangeListener(subId).catch(() => {});\n\t\t\t\t}\n\t\t\t\tclearTimeout(timeout);\n\n\t\t\t\tif (pollInterval) {\n\t\t\t\t\tclearInterval(pollInterval);\n\t\t\t\t}\n\n\t\t\t\treject(error);\n\t\t\t};\n\n\t\t\tconst checkOrder = async (\n\t\t\t\tconfirmType: 'initial' | 'poll' | 'timeout'\n\t\t\t) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst lastOrderId = await this.confirmSwiftOrderRPCFetch(\n\t\t\t\t\t\tconnection,\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tsignedMsgUserOrdersAccount,\n\t\t\t\t\t\tsignedMsgOrderUuid\n\t\t\t\t\t);\n\t\t\t\t\tif (lastOrderId !== undefined) {\n\t\t\t\t\t\tallEnvDlog(\n\t\t\t\t\t\t\t'swiftClient',\n\t\t\t\t\t\t\t`confirmed in ${confirmType} RPC fetch orderID\\n`,\n\t\t\t\t\t\t\tlastOrderId\n\t\t\t\t\t\t);\n\t\t\t\t\t\tfinalizeResolve(lastOrderId);\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tallEnvDlog('swiftClient', `${confirmType} RPC fetch error`, err);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst timeout = setTimeout(async () => {\n\t\t\t\tawait checkOrder('timeout');\n\n\t\t\t\tif (!settled) {\n\t\t\t\t\tfinalizeReject(new Error('Order not found'));\n\t\t\t\t}\n\t\t\t}, confirmDuration);\n\n\t\t\t// Perform an initial check.\n\t\t\tcheckOrder('initial');\n\n\t\t\t// Poll every 2 seconds as backup for unreliable websocket.\n\t\t\tpollInterval = setInterval(() => checkOrder('poll'), 2000);\n\n\t\t\t// Subscribe for account change confirmations via WS.\n\t\t\tsubId = connection.onAccountChange(\n\t\t\t\tsignedMsgUserOrdersAccount,\n\t\t\t\t(accountInfo) => {\n\t\t\t\t\tconst order = this.findOrderInSignedMsgUserOrdersAccount(\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\taccountInfo,\n\t\t\t\t\t\tsignedMsgOrderUuid\n\t\t\t\t\t);\n\t\t\t\t\tif (order) {\n\t\t\t\t\t\tallEnvDlog(\n\t\t\t\t\t\t\t'swiftClient',\n\t\t\t\t\t\t\t'confirmed in onAccountChange orderID\\n',\n\t\t\t\t\t\t\torder.orderId\n\t\t\t\t\t\t);\n\t\t\t\t\t\tfinalizeResolve(order.orderId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate static async confirmSwiftOrderRPCFetch(\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tsignedMsgUserOrdersAccount: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array\n\t): Promise<number | undefined> {\n\t\tconst accountInfo = await connection.getAccountInfo(\n\t\t\tsignedMsgUserOrdersAccount\n\t\t);\n\t\tif (!accountInfo) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst order = this.findOrderInSignedMsgUserOrdersAccount(\n\t\t\tclient,\n\t\t\taccountInfo,\n\t\t\tsignedMsgOrderUuid\n\t\t);\n\t\treturn order?.orderId;\n\t}\n\n\tstatic findOrderInSignedMsgUserOrdersAccount(\n\t\tclient: DriftClient,\n\t\tordersAccount: AccountInfo<Buffer>,\n\t\tsignedMsgOrderUuid: Uint8Array\n\t) {\n\t\tconst accountDecoder =\n\t\t\tclient.program.account.signedMsgUserOrders.coder.accounts.decodeUnchecked.bind(\n\t\t\t\tclient.program.account.signedMsgUserOrders.coder.accounts\n\t\t\t);\n\t\tconst decodedAccount = accountDecoder(\n\t\t\t'SignedMsgUserOrders',\n\t\t\tordersAccount.data\n\t\t) as SignedMsgUserOrdersAccount;\n\t\tallEnvDlog(\n\t\t\t'swiftClient findOrder',\n\t\t\t'decodedAccount\\n',\n\t\t\tdecodedAccount,\n\t\t\tsignedMsgOrderUuid.toString()\n\t\t);\n\t\tconst order = decodedAccount.signedMsgOrderData.find(\n\t\t\t(order) => order.uuid.toString() === signedMsgOrderUuid.toString()\n\t\t);\n\t\tallEnvDlog('swiftClient findOrder', 'order\\n', order);\n\t\treturn order;\n\t}\n\n\tstatic async confirmSwiftOrder(\n\t\thash: string,\n\t\tconfirmDuration: number\n\t): Promise<\n\t\tClientResponse<\n\t\t\t| {\n\t\t\t\t\torderId: string;\n\t\t\t\t\tstatus: 'confirmed';\n\t\t\t }\n\t\t\t| {\n\t\t\t\t\tstatus: 'expired';\n\t\t\t }\n\t\t>\n\t> {\n\t\tconst expireTime = Date.now() + confirmDuration;\n\n\t\twhile (Date.now() < expireTime) {\n\t\t\tconst confirmResponse = await this.get(\n\t\t\t\t`/confirmation/hash-status?hash=${encodeURIComponent(hash)}`\n\t\t\t);\n\n\t\t\tif (confirmResponse.status === 200) {\n\t\t\t\tconsole.log('Confirmed hash: ', hash);\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tstatus: 200,\n\t\t\t\t\tmessage: `Confirmed hash: ${hash}`,\n\t\t\t\t\tbody: {\n\t\t\t\t\t\torderId: confirmResponse.body,\n\t\t\t\t\t\tstatus: 'confirmed',\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t} else if (\n\t\t\t\tconfirmResponse.status >= 500 ||\n\t\t\t\tconfirmResponse.status < 200\n\t\t\t) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\t}\n\n\t\tconsole.error('Failed to confirm hash: ', hash);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tstatus: 408,\n\t\t\tmessage: `Failed to confirm hash: ${hash}`,\n\t\t\tbody: {\n\t\t\t\tstatus: 'expired',\n\t\t\t},\n\t\t};\n\t}\n\n\tstatic async handleSwiftOrderSubscriber(\n\t\tsubscriber: Subscriber<SwiftOrderEvent>,\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority?: PublicKey\n\t) {\n\t\t// First send the order\n\t\tconst sendResponse = await this.sendSwiftOrder(\n\t\t\tmarketIndex,\n\t\t\tmarketType,\n\t\t\tmessage,\n\t\t\tsignature,\n\t\t\ttakerPubkey,\n\t\t\tsigningAuthority\n\t\t);\n\n\t\tif (!sendResponse.success) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'errored',\n\t\t\t\thash: '',\n\t\t\t\tmessage: sendResponse.message,\n\t\t\t\tstatus: sendResponse.status,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t\treturn;\n\t\t} else {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'sent',\n\t\t\t\thash: sendResponse.body.hash,\n\t\t\t});\n\t\t}\n\n\t\tconst hash = sendResponse.body.hash;\n\n\t\t// Then confirm it\n\t\tconst confirmResponse = await this.confirmSwiftOrder(hash, confirmDuration);\n\n\t\tif (!confirmResponse.success) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: confirmResponse.body.status as 'expired',\n\t\t\t\thash,\n\t\t\t\tmessage: confirmResponse.message,\n\t\t\t\tstatus: confirmResponse.status,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t}\n\t\tif (confirmResponse.body.status === 'confirmed') {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'confirmed',\n\t\t\t\torderId: confirmResponse.body.orderId,\n\t\t\t\thash,\n\t\t\t});\n\t\t\tsubscriber.complete();\n\t\t}\n\t}\n\tstatic async handleSwiftOrderSubscriberWS(\n\t\tsubscriber: Subscriber<SwiftOrderEvent>,\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tsignedMsgUserOrdersAccountPubkey: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority?: PublicKey\n\t) {\n\t\t// First send the order\n\t\tconst sendResponse = await this.sendSwiftOrder(\n\t\t\tmarketIndex,\n\t\t\tmarketType,\n\t\t\tmessage,\n\t\t\tsignature,\n\t\t\ttakerPubkey,\n\t\t\tsigningAuthority\n\t\t);\n\t\tallEnvDlog('swiftClient', 'sendResponse\\n', sendResponse);\n\n\t\tif (!sendResponse.success) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'errored',\n\t\t\t\thash: '',\n\t\t\t\tmessage: `Error from swift node: ${sendResponse.message}`,\n\t\t\t\tstatus: sendResponse.status,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t\treturn;\n\t\t} else {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'sent',\n\t\t\t\thash: sendResponse.body.hash,\n\t\t\t});\n\t\t}\n\n\t\tconst hash = sendResponse.body.hash;\n\n\t\t// Then confirm it\n\t\tconst orderID = await this.confirmSwiftOrderWS(\n\t\t\tconnection,\n\t\t\tclient,\n\t\t\tsignedMsgUserOrdersAccountPubkey,\n\t\t\tsignedMsgOrderUuid,\n\t\t\tconfirmDuration\n\t\t).catch((err) => {\n\t\t\tallEnvDlog('swiftClient', 'confirmSwiftOrderWS error', err);\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'expired',\n\t\t\t\thash,\n\t\t\t\tmessage: 'Order failed to confirm',\n\t\t\t\tstatus: 408,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t});\n\n\t\tif (!orderID) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'expired',\n\t\t\t\thash,\n\t\t\t\tmessage: 'Order failed to confirm',\n\t\t\t\tstatus: 408,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t} else {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'confirmed',\n\t\t\t\torderId: orderID.toString(),\n\t\t\t\thash,\n\t\t\t});\n\t\t\tsubscriber.complete();\n\t\t}\n\t}\n\n\tpublic static sendAndConfirmSwiftOrder(\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority: PublicKey\n\t): Observable<SwiftOrderEvent> {\n\t\treturn new Observable<SwiftOrderEvent>((subscriber) => {\n\t\t\tthis.handleSwiftOrderSubscriber(\n\t\t\t\tsubscriber,\n\t\t\t\tmarketIndex,\n\t\t\t\tmarketType,\n\t\t\t\tmessage,\n\t\t\t\tsignature,\n\t\t\t\ttakerPubkey,\n\t\t\t\tconfirmDuration,\n\t\t\t\tsigningAuthority\n\t\t\t);\n\t\t});\n\t}\n\n\tpublic static sendAndConfirmSwiftOrderWS(\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tsignedMsgUserOrdersAccountPubkey: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority: PublicKey\n\t): Observable<SwiftOrderEvent> {\n\t\treturn new Observable<SwiftOrderEvent>((subscriber) => {\n\t\t\tthis.handleSwiftOrderSubscriberWS(\n\t\t\t\tsubscriber,\n\t\t\t\tconnection,\n\t\t\t\tclient,\n\t\t\t\tmarketIndex,\n\t\t\t\tmarketType,\n\t\t\t\tmessage,\n\t\t\t\tsignature,\n\t\t\t\ttakerPubkey,\n\t\t\t\tsignedMsgUserOrdersAccountPubkey,\n\t\t\t\tsignedMsgOrderUuid,\n\t\t\t\tconfirmDuration,\n\t\t\t\tsigningAuthority\n\t\t\t);\n\t\t});\n\t}\n\n\tpublic static async isSwiftServerHealthy(): Promise<boolean> {\n\t\tconst response = await this.get('/health');\n\t\treturn response.status === 200;\n\t}\n\n\tprivate static getSwiftHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t\t'X-Swift-Client-Consumer': this.swiftClientConsumer ?? 'default',\n\t\t};\n\t}\n\n\tpublic static isSupportedOrderType(orderType: OrderType) {\n\t\treturn this.supportedOrderTypes.includes(orderType);\n\t}\n}\n"]}
1
+ {"version":3,"file":"swiftClient.js","sourceRoot":"","sources":["../../src/clients/swiftClient.ts"],"names":[],"mappings":"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","sourcesContent":["import { AccountInfo, Connection, PublicKey } from '@solana/web3.js';\nimport {\n\tDriftClient,\n\tMarketType,\n\tOrderType,\n\tSignedMsgOrderParamsDelegateMessage,\n\tSignedMsgOrderParamsMessage,\n\tSignedMsgUserOrdersAccount,\n\tdigestSignature,\n\tisVariant,\n} from '@drift-labs/sdk';\n\n// Cache for URL construction to prevent repeated string concatenation\nconst swiftUrlCache = new Map<string, string>();\nconst MAX_SWIFT_URL_CACHE_SIZE = 200;\n\nfunction getCachedUrl(baseUrl: string, endpoint: string): string {\n\tconst cacheKey = `${baseUrl}:${endpoint}`;\n\n\tif (swiftUrlCache.has(cacheKey)) {\n\t\treturn swiftUrlCache.get(cacheKey)!;\n\t}\n\n\tconst result = `${baseUrl}${endpoint}`;\n\n\tif (swiftUrlCache.size < MAX_SWIFT_URL_CACHE_SIZE) {\n\t\tswiftUrlCache.set(cacheKey, result);\n\t}\n\n\treturn result;\n}\nimport { Observable, Subscriber } from 'rxjs';\nimport { allEnvDlog } from '../utils/logger';\nexport type SwiftServerOrderProcessResponse = {\n\terror?: string;\n\tmessage: string;\n};\n\ntype ClientResponse<T = void> = Promise<{\n\tsuccess: boolean;\n\tbody?: T;\n\tmessage?: string;\n\tstatus?: number;\n}>;\n\ntype BaseSwiftOrderEvent = {\n\thash: string;\n};\n\nexport interface SwiftOrderSentEvent extends BaseSwiftOrderEvent {\n\ttype: 'sent';\n}\n\nexport interface SwiftOrderErroredEvent extends BaseSwiftOrderEvent {\n\ttype: 'errored' | 'expired';\n\tmessage?: string;\n\tstatus?: number;\n}\n\nexport interface SwiftOrderConfirmedEvent extends BaseSwiftOrderEvent {\n\ttype: 'confirmed';\n\torderId: string;\n}\n\nexport type SwiftOrderEvent =\n\t| SwiftOrderErroredEvent\n\t| SwiftOrderConfirmedEvent\n\t| SwiftOrderSentEvent;\n\nexport type SwiftOrderEventWithParams<T extends SwiftOrderEvent> = T & {\n\tswiftOrderUuid: Uint8Array;\n\torderParamsMessage:\n\t\t| SignedMsgOrderParamsMessage\n\t\t| SignedMsgOrderParamsDelegateMessage;\n};\n\nexport class SwiftClient {\n\tprivate static baseUrl = '';\n\tprivate static swiftClientConsumer?: string;\n\n\tstatic supportedOrderTypes: OrderType[] = [OrderType.MARKET, OrderType.LIMIT];\n\n\tpublic static init(baseUrl: string, swiftClientConsumer?: string) {\n\t\tthis.baseUrl = baseUrl;\n\t\tthis.swiftClientConsumer = swiftClientConsumer;\n\t}\n\n\tprivate static get(url: string) {\n\t\tif (!this.baseUrl) {\n\t\t\tthrow new Error('SwiftClient not initialized');\n\t\t}\n\n\t\treturn new Promise<{ success: boolean; body: string; status: number }>(\n\t\t\t(res) => {\n\t\t\t\tconst headers = new Headers({\n\t\t\t\t\t...this.getSwiftHeaders(),\n\t\t\t\t});\n\n\t\t\t\tfetch(getCachedUrl(this.baseUrl, url), {\n\t\t\t\t\theaders,\n\t\t\t\t})\n\t\t\t\t\t.then(async (response) => {\n\t\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\t\tres({\n\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\tbody: await response.text(),\n\t\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tres({\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\tbody: await response.text(),\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t});\n\t\t\t\t\t})\n\t\t\t\t\t.catch((err) => {\n\t\t\t\t\t\tres({ success: false, body: err, status: 0 });\n\t\t\t\t\t});\n\t\t\t}\n\t\t);\n\t}\n\n\tprivate static post(url: string, bodyObject: any) {\n\t\tif (!this.baseUrl) {\n\t\t\tthrow new Error('SwiftClient not initialized');\n\t\t}\n\n\t\tconst requestOptions = {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { ...this.getSwiftHeaders() },\n\t\t\tbody: JSON.stringify(bodyObject),\n\t\t};\n\n\t\treturn new Promise<{\n\t\t\tsuccess: boolean;\n\t\t\tbody: SwiftServerOrderProcessResponse;\n\t\t\tstatus: number;\n\t\t}>((res) => {\n\t\t\tconst postRequest = new Request(\n\t\t\t\tgetCachedUrl(this.baseUrl, url),\n\t\t\t\trequestOptions\n\t\t\t);\n\n\t\t\tfetch(postRequest)\n\t\t\t\t.then(async (response) => {\n\t\t\t\t\tlet resBody: SwiftServerOrderProcessResponse | null = null;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresBody =\n\t\t\t\t\t\t\t(await response.json()) as SwiftServerOrderProcessResponse;\n\n\t\t\t\t\t\tres({\n\t\t\t\t\t\t\tsuccess: response.ok,\n\t\t\t\t\t\t\tbody: resBody,\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tallEnvDlog('swiftClient', 'Error reading response body', err);\n\n\t\t\t\t\t\tres({\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\tbody: err as any,\n\t\t\t\t\t\t\tstatus: response.status,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tres({ success: false, body: err, status: 0 });\n\t\t\t\t});\n\t\t});\n\t}\n\n\tstatic async sendSwiftOrder(\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tsigningAuthority?: PublicKey\n\t): ClientResponse<{\n\t\thash: string;\n\t}> {\n\t\tconst requestPayload = {\n\t\t\tmarket_index: marketIndex,\n\t\t\tmarket_type: isVariant(marketType, 'perp') ? 'perp' : 'spot',\n\t\t\tmessage,\n\t\t\tsignature: signature.toString('base64'),\n\t\t\tsigning_authority: signingAuthority?.toBase58() ?? '',\n\t\t\ttaker_authority: takerPubkey.toBase58(),\n\t\t};\n\n\t\tconst response = await this.post('/orders', requestPayload);\n\n\t\tif (response.status !== 200) {\n\t\t\tconsole.error(\n\t\t\t\t`Non-200 status code received for sent Swift order: ${response.status}`\n\t\t\t);\n\t\t\tallEnvDlog('swiftClient', 'full non-200 response body', response.body);\n\t\t\treturn {\n\t\t\t\tmessage:\n\t\t\t\t\tresponse.body?.error ||\n\t\t\t\t\tresponse.body?.message ||\n\t\t\t\t\t`HTTP ${response.status}: Error from Swift server`,\n\t\t\t\tstatus: response.status,\n\t\t\t\tsuccess: false,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tmessage: `Successfully sent Swift order`,\n\t\t\tbody: {\n\t\t\t\thash: digestSignature(Uint8Array.from(signature)),\n\t\t\t},\n\t\t\tsuccess: true,\n\t\t\tstatus: 200,\n\t\t};\n\t}\n\n\tstatic async confirmSwiftOrderWS(\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tsignedMsgUserOrdersAccount: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array,\n\t\tconfirmDuration: number\n\t): Promise<number | undefined> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tlet settled = false;\n\t\t\tlet subId: number | undefined = undefined;\n\t\t\tlet pollInterval: ReturnType<typeof setInterval> | undefined = undefined;\n\n\t\t\tconst finalizeResolve = (orderId: number) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tif (subId !== undefined) {\n\t\t\t\t\tconnection.removeAccountChangeListener(subId).catch(() => {});\n\t\t\t\t}\n\t\t\t\tclearTimeout(timeout);\n\n\t\t\t\tif (pollInterval) {\n\t\t\t\t\tclearInterval(pollInterval);\n\t\t\t\t}\n\n\t\t\t\tresolve(orderId);\n\t\t\t};\n\n\t\t\tconst finalizeReject = (error: Error) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tif (subId !== undefined) {\n\t\t\t\t\tconnection.removeAccountChangeListener(subId).catch(() => {});\n\t\t\t\t}\n\t\t\t\tclearTimeout(timeout);\n\n\t\t\t\tif (pollInterval) {\n\t\t\t\t\tclearInterval(pollInterval);\n\t\t\t\t}\n\n\t\t\t\treject(error);\n\t\t\t};\n\n\t\t\tconst checkOrder = async (\n\t\t\t\tconfirmType: 'initial' | 'poll' | 'timeout'\n\t\t\t) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst lastOrderId = await this.confirmSwiftOrderRPCFetch(\n\t\t\t\t\t\tconnection,\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tsignedMsgUserOrdersAccount,\n\t\t\t\t\t\tsignedMsgOrderUuid\n\t\t\t\t\t);\n\t\t\t\t\tif (lastOrderId !== undefined) {\n\t\t\t\t\t\tallEnvDlog(\n\t\t\t\t\t\t\t'swiftClient',\n\t\t\t\t\t\t\t`confirmed in ${confirmType} RPC fetch orderID\\n`,\n\t\t\t\t\t\t\tlastOrderId\n\t\t\t\t\t\t);\n\t\t\t\t\t\tfinalizeResolve(lastOrderId);\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tallEnvDlog('swiftClient', `${confirmType} RPC fetch error`, err);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst timeout = setTimeout(async () => {\n\t\t\t\tawait checkOrder('timeout');\n\n\t\t\t\tif (!settled) {\n\t\t\t\t\tfinalizeReject(new Error('Order not found'));\n\t\t\t\t}\n\t\t\t}, confirmDuration);\n\n\t\t\t// Perform an initial check.\n\t\t\tcheckOrder('initial');\n\n\t\t\t// Poll every 2 seconds as backup for unreliable websocket.\n\t\t\tpollInterval = setInterval(() => checkOrder('poll'), 2000);\n\n\t\t\t// Subscribe for account change confirmations via WS.\n\t\t\tsubId = connection.onAccountChange(\n\t\t\t\tsignedMsgUserOrdersAccount,\n\t\t\t\t(accountInfo) => {\n\t\t\t\t\tconst order = this.findOrderInSignedMsgUserOrdersAccount(\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\taccountInfo,\n\t\t\t\t\t\tsignedMsgOrderUuid\n\t\t\t\t\t);\n\t\t\t\t\tif (order) {\n\t\t\t\t\t\tallEnvDlog(\n\t\t\t\t\t\t\t'swiftClient',\n\t\t\t\t\t\t\t'confirmed in onAccountChange orderID\\n',\n\t\t\t\t\t\t\torder.orderId\n\t\t\t\t\t\t);\n\t\t\t\t\t\tfinalizeResolve(order.orderId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate static async confirmSwiftOrderRPCFetch(\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tsignedMsgUserOrdersAccount: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array\n\t): Promise<number | undefined> {\n\t\tconst accountInfo = await connection.getAccountInfo(\n\t\t\tsignedMsgUserOrdersAccount\n\t\t);\n\t\tif (!accountInfo) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst order = this.findOrderInSignedMsgUserOrdersAccount(\n\t\t\tclient,\n\t\t\taccountInfo,\n\t\t\tsignedMsgOrderUuid\n\t\t);\n\t\treturn order?.orderId;\n\t}\n\n\tstatic findOrderInSignedMsgUserOrdersAccount(\n\t\tclient: DriftClient,\n\t\tordersAccount: AccountInfo<Buffer>,\n\t\tsignedMsgOrderUuid: Uint8Array\n\t) {\n\t\tconst accountDecoder =\n\t\t\tclient.program.account.signedMsgUserOrders.coder.accounts.decodeUnchecked.bind(\n\t\t\t\tclient.program.account.signedMsgUserOrders.coder.accounts\n\t\t\t);\n\t\tconst decodedAccount = accountDecoder(\n\t\t\t'SignedMsgUserOrders',\n\t\t\tordersAccount.data\n\t\t) as SignedMsgUserOrdersAccount;\n\t\tallEnvDlog(\n\t\t\t'swiftClient findOrder',\n\t\t\t'decodedAccount\\n',\n\t\t\tdecodedAccount,\n\t\t\tsignedMsgOrderUuid.toString()\n\t\t);\n\t\tconst order = decodedAccount.signedMsgOrderData.find(\n\t\t\t(order) => order.uuid.toString() === signedMsgOrderUuid.toString()\n\t\t);\n\t\tallEnvDlog('swiftClient findOrder', 'order\\n', order);\n\t\treturn order;\n\t}\n\n\tstatic async confirmSwiftOrder(\n\t\thash: string,\n\t\tconfirmDuration: number\n\t): Promise<\n\t\tClientResponse<\n\t\t\t| {\n\t\t\t\t\torderId: string;\n\t\t\t\t\tstatus: 'confirmed';\n\t\t\t }\n\t\t\t| {\n\t\t\t\t\tstatus: 'expired';\n\t\t\t }\n\t\t>\n\t> {\n\t\tconst expireTime = Date.now() + confirmDuration;\n\n\t\twhile (Date.now() < expireTime) {\n\t\t\tconst confirmResponse = await this.get(\n\t\t\t\t`/confirmation/hash-status?hash=${encodeURIComponent(hash)}`\n\t\t\t);\n\n\t\t\tif (confirmResponse.status === 200) {\n\t\t\t\tconsole.log('Confirmed hash: ', hash);\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tstatus: 200,\n\t\t\t\t\tmessage: `Confirmed hash: ${hash}`,\n\t\t\t\t\tbody: {\n\t\t\t\t\t\torderId: confirmResponse.body,\n\t\t\t\t\t\tstatus: 'confirmed',\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t} else if (\n\t\t\t\tconfirmResponse.status >= 500 ||\n\t\t\t\tconfirmResponse.status < 200\n\t\t\t) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\t}\n\n\t\tconsole.error('Failed to confirm hash: ', hash);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tstatus: 408,\n\t\t\tmessage: `Failed to confirm hash: ${hash}`,\n\t\t\tbody: {\n\t\t\t\tstatus: 'expired',\n\t\t\t},\n\t\t};\n\t}\n\n\tstatic async handleSwiftOrderSubscriber(\n\t\tsubscriber: Subscriber<SwiftOrderEvent>,\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority?: PublicKey\n\t) {\n\t\t// First send the order\n\t\tconst sendResponse = await this.sendSwiftOrder(\n\t\t\tmarketIndex,\n\t\t\tmarketType,\n\t\t\tmessage,\n\t\t\tsignature,\n\t\t\ttakerPubkey,\n\t\t\tsigningAuthority\n\t\t);\n\n\t\tif (!sendResponse.success) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'errored',\n\t\t\t\thash: '',\n\t\t\t\tmessage: sendResponse.message,\n\t\t\t\tstatus: sendResponse.status,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t\treturn;\n\t\t} else {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'sent',\n\t\t\t\thash: sendResponse.body.hash,\n\t\t\t});\n\t\t}\n\n\t\tconst hash = sendResponse.body.hash;\n\n\t\t// Then confirm it\n\t\tconst confirmResponse = await this.confirmSwiftOrder(hash, confirmDuration);\n\n\t\tif (!confirmResponse.success) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: confirmResponse.body.status as 'expired',\n\t\t\t\thash,\n\t\t\t\tmessage: confirmResponse.message,\n\t\t\t\tstatus: confirmResponse.status,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t}\n\t\tif (confirmResponse.body.status === 'confirmed') {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'confirmed',\n\t\t\t\torderId: confirmResponse.body.orderId,\n\t\t\t\thash,\n\t\t\t});\n\t\t\tsubscriber.complete();\n\t\t}\n\t}\n\tstatic async handleSwiftOrderSubscriberWS(\n\t\tsubscriber: Subscriber<SwiftOrderEvent>,\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tsignedMsgUserOrdersAccountPubkey: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority?: PublicKey\n\t) {\n\t\t// First send the order\n\t\tconst sendResponse = await this.sendSwiftOrder(\n\t\t\tmarketIndex,\n\t\t\tmarketType,\n\t\t\tmessage,\n\t\t\tsignature,\n\t\t\ttakerPubkey,\n\t\t\tsigningAuthority\n\t\t);\n\t\tallEnvDlog('swiftClient', 'sendResponse\\n', sendResponse);\n\n\t\tif (!sendResponse.success) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'errored',\n\t\t\t\thash: '',\n\t\t\t\tmessage: `Error from swift node: ${sendResponse.message}`,\n\t\t\t\tstatus: sendResponse.status,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t\treturn;\n\t\t} else {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'sent',\n\t\t\t\thash: sendResponse.body.hash,\n\t\t\t});\n\t\t}\n\n\t\tconst hash = sendResponse.body.hash;\n\n\t\t// Then confirm it\n\t\tconst orderID = await this.confirmSwiftOrderWS(\n\t\t\tconnection,\n\t\t\tclient,\n\t\t\tsignedMsgUserOrdersAccountPubkey,\n\t\t\tsignedMsgOrderUuid,\n\t\t\tconfirmDuration\n\t\t).catch((err) => {\n\t\t\tallEnvDlog('swiftClient', 'confirmSwiftOrderWS error', err);\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'expired',\n\t\t\t\thash,\n\t\t\t\tmessage: 'Order failed to confirm',\n\t\t\t\tstatus: 408,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t});\n\n\t\tif (!orderID) {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'expired',\n\t\t\t\thash,\n\t\t\t\tmessage: 'Order failed to confirm',\n\t\t\t\tstatus: 408,\n\t\t\t});\n\t\t\tsubscriber.error();\n\t\t} else {\n\t\t\tsubscriber.next({\n\t\t\t\ttype: 'confirmed',\n\t\t\t\torderId: orderID.toString(),\n\t\t\t\thash,\n\t\t\t});\n\t\t\tsubscriber.complete();\n\t\t}\n\t}\n\n\tpublic static sendAndConfirmSwiftOrder(\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority: PublicKey\n\t): Observable<SwiftOrderEvent> {\n\t\treturn new Observable<SwiftOrderEvent>((subscriber) => {\n\t\t\tthis.handleSwiftOrderSubscriber(\n\t\t\t\tsubscriber,\n\t\t\t\tmarketIndex,\n\t\t\t\tmarketType,\n\t\t\t\tmessage,\n\t\t\t\tsignature,\n\t\t\t\ttakerPubkey,\n\t\t\t\tconfirmDuration,\n\t\t\t\tsigningAuthority\n\t\t\t);\n\t\t});\n\t}\n\n\tpublic static sendAndConfirmSwiftOrderWS(\n\t\tconnection: Connection,\n\t\tclient: DriftClient,\n\t\tmarketIndex: number,\n\t\tmarketType: MarketType,\n\t\tmessage: string,\n\t\tsignature: Buffer,\n\t\ttakerPubkey: PublicKey,\n\t\tsignedMsgUserOrdersAccountPubkey: PublicKey,\n\t\tsignedMsgOrderUuid: Uint8Array,\n\t\tconfirmDuration: number,\n\t\tsigningAuthority: PublicKey\n\t): Observable<SwiftOrderEvent> {\n\t\treturn new Observable<SwiftOrderEvent>((subscriber) => {\n\t\t\tthis.handleSwiftOrderSubscriberWS(\n\t\t\t\tsubscriber,\n\t\t\t\tconnection,\n\t\t\t\tclient,\n\t\t\t\tmarketIndex,\n\t\t\t\tmarketType,\n\t\t\t\tmessage,\n\t\t\t\tsignature,\n\t\t\t\ttakerPubkey,\n\t\t\t\tsignedMsgUserOrdersAccountPubkey,\n\t\t\t\tsignedMsgOrderUuid,\n\t\t\t\tconfirmDuration,\n\t\t\t\tsigningAuthority\n\t\t\t);\n\t\t});\n\t}\n\n\tpublic static async isSwiftServerHealthy(): Promise<boolean> {\n\t\tconst response = await this.get('/health');\n\t\treturn response.status === 200;\n\t}\n\n\tprivate static getSwiftHeaders(): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t\t'X-Swift-Client-Consumer': this.swiftClientConsumer ?? 'default',\n\t\t};\n\t}\n\n\tpublic static isSupportedOrderType(orderType: OrderType) {\n\t\treturn this.supportedOrderTypes.includes(orderType);\n\t}\n}\n"]}
@@ -21,16 +21,10 @@ exports.HIDDEN_PERP_MARKET_INDEXES = new Map([
21
21
  [14, 1772625600], // HNT — 4 Mar 2026, 12:00 UTC
22
22
  [19, 1772625600], // TIA — 4 Mar 2026, 12:00 UTC
23
23
  [21, 1772625600], // SEI — 4 Mar 2026, 12:00 UTC
24
- [27, 1772625600], // W — 4 Mar 2026, 12:00 UTC
25
- [31, 1772625600], // CLOUD — 4 Mar 2026, 12:00 UTC
26
24
  [34, 1772625600], // POPCAT — 4 Mar 2026, 12:00 UTC
27
25
  [42, 1772625600], // TON — 4 Mar 2026, 12:00 UTC
28
- [61, 1772625600], // ME — 4 Mar 2026, 12:00 UTC
29
26
  [62, 1772625600], // PENGU — 4 Mar 2026, 12:00 UTC
30
27
  [64, 1772625600], // TRUMP — 4 Mar 2026, 12:00 UTC
31
- [66, 1772625600], // BERA — 4 Mar 2026, 12:00 UTC
32
- [69, 1772625600], // KAITO — 4 Mar 2026, 12:00 UTC
33
- [70, 1772625600], // IP — 4 Mar 2026, 12:00 UTC
34
28
  [72, 1772625600], // ADA — 4 Mar 2026, 12:00 UTC
35
29
  [77, 1772625600], // XPL — 4 Mar 2026, 12:00 UTC
36
30
  [78, 1772625600], // 2Z — 4 Mar 2026, 12:00 UTC
@@ -1 +1 @@
1
- {"version":3,"file":"markets.js","sourceRoot":"","sources":["../../src/constants/markets.ts"],"names":[],"mappings":";;;AAAa,QAAA,sBAAsB,GAAG,CAAC,CAAC;AAC3B,QAAA,qBAAqB,GAAG,CAAC,CAAC;AAC1B,QAAA,sBAAsB,GAAG,CAAC,CAAC;AAC3B,QAAA,sBAAsB,GAAG,CAAC,CAAC;AAC3B,QAAA,uBAAuB,GAAG,EAAE,CAAC;AAE7B,QAAA,2BAA2B,GAAG,EAAE,CAAC;AAE9C;;;;;;GAMG;AACU,QAAA,0BAA0B,GAAgC,IAAI,GAAG,CAAC;IAC9E,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAC/C,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,iCAAiC;IACnD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,6BAA6B;IAC/C,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,4BAA4B;IAC9C,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,gCAAgC;IAClD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,iCAAiC;IACnD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,6BAA6B;IAC/C,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,gCAAgC;IAClD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,gCAAgC;IAClD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,+BAA+B;IACjD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,gCAAgC;IAClD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,6BAA6B;IAC/C,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,6BAA6B;IAC/C,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;CAChD,CAAC,CAAC","sourcesContent":["export const USDC_SPOT_MARKET_INDEX = 0;\nexport const SOL_SPOT_MARKET_INDEX = 1;\nexport const WBTC_SPOT_MARKET_INDEX = 3;\nexport const WETH_SPOT_MARKET_INDEX = 4;\nexport const CBBTC_SPOT_MARKET_INDEX = 27;\n\nexport const DEFAULT_MAX_MARKET_LEVERAGE = 10;\n\n/**\n * Low-activity perp markets to hide from the UI.\n * Key = perp market index, Value = Unix timestamp (seconds) after which the market is hidden.\n * Before the timestamp: market is visible but a warning banner is shown.\n * After the timestamp: market is hidden from dropdowns (unless user has positions/orders/unsettled PnL).\n * Direct URL navigation (e.g. /TIA-PERP) is unaffected.\n */\nexport const HIDDEN_PERP_MARKET_INDEXES: ReadonlyMap<number, number> = new Map([\n\t[5, 1772625600], // POL — 4 Mar 2026, 12:00 UTC\n\t[10, 1772625600], // 1MPEPE — 4 Mar 2026, 12:00 UTC\n\t[11, 1772625600], // OP — 4 Mar 2026, 12:00 UTC\n\t[14, 1772625600], // HNT — 4 Mar 2026, 12:00 UTC\n\t[19, 1772625600], // TIA — 4 Mar 2026, 12:00 UTC\n\t[21, 1772625600], // SEI — 4 Mar 2026, 12:00 UTC\n\t[27, 1772625600], // W — 4 Mar 2026, 12:00 UTC\n\t[31, 1772625600], // CLOUD — 4 Mar 2026, 12:00 UTC\n\t[34, 1772625600], // POPCAT — 4 Mar 2026, 12:00 UTC\n\t[42, 1772625600], // TON — 4 Mar 2026, 12:00 UTC\n\t[61, 1772625600], // ME — 4 Mar 2026, 12:00 UTC\n\t[62, 1772625600], // PENGU — 4 Mar 2026, 12:00 UTC\n\t[64, 1772625600], // TRUMP — 4 Mar 2026, 12:00 UTC\n\t[66, 1772625600], // BERA — 4 Mar 2026, 12:00 UTC\n\t[69, 1772625600], // KAITO — 4 Mar 2026, 12:00 UTC\n\t[70, 1772625600], // IP — 4 Mar 2026, 12:00 UTC\n\t[72, 1772625600], // ADA — 4 Mar 2026, 12:00 UTC\n\t[77, 1772625600], // XPL — 4 Mar 2026, 12:00 UTC\n\t[78, 1772625600], // 2Z — 4 Mar 2026, 12:00 UTC\n\t[80, 1772625600], // MNT — 4 Mar 2026, 12:00 UTC\n\t[82, 1772625600], // MET — 4 Mar 2026, 12:00 UTC\n]);\n"]}
1
+ {"version":3,"file":"markets.js","sourceRoot":"","sources":["../../src/constants/markets.ts"],"names":[],"mappings":";;;AAAa,QAAA,sBAAsB,GAAG,CAAC,CAAC;AAC3B,QAAA,qBAAqB,GAAG,CAAC,CAAC;AAC1B,QAAA,sBAAsB,GAAG,CAAC,CAAC;AAC3B,QAAA,sBAAsB,GAAG,CAAC,CAAC;AAC3B,QAAA,uBAAuB,GAAG,EAAE,CAAC;AAE7B,QAAA,2BAA2B,GAAG,EAAE,CAAC;AAE9C;;;;;;GAMG;AACU,QAAA,0BAA0B,GAAgC,IAAI,GAAG,CAAC;IAC9E,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAC/C,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,iCAAiC;IACnD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,6BAA6B;IAC/C,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,iCAAiC;IACnD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,gCAAgC;IAClD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,gCAAgC;IAClD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,6BAA6B;IAC/C,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;IAChD,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,8BAA8B;CAChD,CAAC,CAAC","sourcesContent":["export const USDC_SPOT_MARKET_INDEX = 0;\nexport const SOL_SPOT_MARKET_INDEX = 1;\nexport const WBTC_SPOT_MARKET_INDEX = 3;\nexport const WETH_SPOT_MARKET_INDEX = 4;\nexport const CBBTC_SPOT_MARKET_INDEX = 27;\n\nexport const DEFAULT_MAX_MARKET_LEVERAGE = 10;\n\n/**\n * Low-activity perp markets to hide from the UI.\n * Key = perp market index, Value = Unix timestamp (seconds) after which the market is hidden.\n * Before the timestamp: market is visible but a warning banner is shown.\n * After the timestamp: market is hidden from dropdowns (unless user has positions/orders/unsettled PnL).\n * Direct URL navigation (e.g. /TIA-PERP) is unaffected.\n */\nexport const HIDDEN_PERP_MARKET_INDEXES: ReadonlyMap<number, number> = new Map([\n\t[5, 1772625600], // POL — 4 Mar 2026, 12:00 UTC\n\t[10, 1772625600], // 1MPEPE — 4 Mar 2026, 12:00 UTC\n\t[11, 1772625600], // OP — 4 Mar 2026, 12:00 UTC\n\t[14, 1772625600], // HNT — 4 Mar 2026, 12:00 UTC\n\t[19, 1772625600], // TIA — 4 Mar 2026, 12:00 UTC\n\t[21, 1772625600], // SEI — 4 Mar 2026, 12:00 UTC\n\t[34, 1772625600], // POPCAT — 4 Mar 2026, 12:00 UTC\n\t[42, 1772625600], // TON — 4 Mar 2026, 12:00 UTC\n\t[62, 1772625600], // PENGU — 4 Mar 2026, 12:00 UTC\n\t[64, 1772625600], // TRUMP — 4 Mar 2026, 12:00 UTC\n\t[72, 1772625600], // ADA — 4 Mar 2026, 12:00 UTC\n\t[77, 1772625600], // XPL — 4 Mar 2026, 12:00 UTC\n\t[78, 1772625600], // 2Z — 4 Mar 2026, 12:00 UTC\n\t[80, 1772625600], // MNT — 4 Mar 2026, 12:00 UTC\n\t[82, 1772625600], // MET — 4 Mar 2026, 12:00 UTC\n]);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"PollingDlob.js","sourceRoot":"","sources":["../../../../src/drift/Drift/data/PollingDlob.ts"],"names":[],"mappings":"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","sourcesContent":["import { Subject, Observable } from 'rxjs';\nimport { MarketId, MarketKey } from '../../../types/MarketId';\nimport { L2WithOracleAndMarketData } from '../../../utils/orderbook/types';\nimport { PollingCategory } from '../constants/blockchain';\nimport { fetchBulkMarketsDlobL2Data } from '../../base/actions/trade/openPerpOrder/dlobServer';\n\nexport interface PollingConfig {\n\tdriftDlobServerHttpUrl: string;\n\tindicativeLiquidityEnabled?: boolean;\n\tgroupingSize?: number;\n}\n\nexport interface PollingInterval {\n\tid: string;\n\tintervalMultiplier: number;\n\tdepth: number;\n\tmarkets: Set<MarketKey>;\n\t/**\n\t * Used to track markets that were added to an interval in the current tick, so that they get polled on the next tick regardless of interval multiplier.\n\t * Otherwise, they would only get polled on the next interval, which could be a long time if the interval multiplier is high.\n\t */\n\tnewlyAddedMarkets: Set<MarketKey>;\n}\n\nexport interface MarketPollingData {\n\tmarketId: MarketId;\n\tdata: L2WithOracleAndMarketData;\n}\n\n// Predefined interval multipliers from the original React hook\nexport const POLLING_INTERVALS = {\n\tLIVE_MARKET: 1,\n\tBACKGROUND_DEEP: 3, // Can be configured to 2 for interim usage\n\tBACKGROUND_SHALLOW: 30,\n\tIDLE_1: 30,\n\tIDLE_2: 60,\n} as const;\n\nexport const POLLING_DEPTHS = {\n\tSHALLOW: 1,\n\tDEEP: 1,\n\tORDERBOOK: 100,\n} as const;\n\n/**\n * PollingDlob - A configurable market data polling system.\n * The Drift DLOB (decentralized limit orderbook) server stores the current live state of the orderbook\n * across all Drift markets. This class is used to poll the DLOB server for the markets' current mark price,\n * while oracle price data is also provided alongside.\n *\n * Example usage:\n * ```typescript\n * import { PollingDlob, MarketId } from '@drift/common';\n *\n * const pollingDlob = new PollingDlob({\n * dlobServerHttpUrl: 'https://dlob.drift.trade',\n * indicativeLiquidityEnabled: true\n * });\n *\n * // Add different polling intervals\n * pollingDlob.addInterval('live', 1, 100); // Every 1s with depth 100\n * pollingDlob.addInterval('background', 3, 1); // Every 3s with depth 1\n * pollingDlob.addInterval('idle', 30, 1); // Every 30s with depth 1\n *\n * // Add markets to intervals\n * const perpMarket = MarketId.createPerpMarket(0);\n * const spotMarket = MarketId.createSpotMarket(0);\n *\n * pollingDlob.addMarketToInterval('live', perpMarket);\n * pollingDlob.addMarketToInterval('background', spotMarket);\n *\n * // Subscribe to data updates\n * pollingDlob.onData().subscribe(marketData => {\n * marketData.forEach(({ marketId, data, intervalId }) => {\n * console.log(`Market ${marketId.key} data from ${intervalId}:`, data);\n * });\n * });\n *\n * // Subscribe to errors\n * pollingDlob.onError().subscribe(error => {\n * console.error('Polling error:', error);\n * });\n *\n * // Start polling\n * pollingDlob.start();\n *\n * // Stop when done\n * // pollingDlob.stop();\n * ```\n */\n\nexport class PollingDlob {\n\tprivate config: PollingConfig;\n\tprivate baseTickIntervalMs = 1000;\n\tprivate intervals: Map<string, PollingInterval> = new Map();\n\tprivate _marketToIntervalMap: Map<MarketKey, string> = new Map();\n\tprivate dataSubject: Subject<MarketPollingData[]> = new Subject();\n\tprivate errorSubject: Subject<Error> = new Subject();\n\tprivate isStarted = false;\n\tprivate intervalHandle: NodeJS.Timeout | null = null;\n\tprivate tickCounter = 0;\n\tprivate consecutiveEmptyResponseCount = 0;\n\tprivate consecutiveErrorCount = 0;\n\tprivate readonly maxConsecutiveEmptyResponses = 3;\n\tprivate readonly maxConsecutiveErrors = 5;\n\n\tconstructor(config: PollingConfig) {\n\t\tthis.config = {\n\t\t\tindicativeLiquidityEnabled: true,\n\t\t\t...config,\n\t\t};\n\t}\n\n\tpublic getPollingIntervalForMarket(\n\t\tmarketKey: MarketKey\n\t): PollingInterval | undefined {\n\t\tconst intervalId = this._marketToIntervalMap.get(marketKey);\n\t\tif (!intervalId) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn this.intervals.get(intervalId);\n\t}\n\n\tpublic addInterval(\n\t\tid: string,\n\t\tintervalMultiplier: number,\n\t\tdepth: number\n\t): void {\n\t\tif (this.intervals.has(id)) {\n\t\t\tthrow new Error(`Interval with id '${id}' already exists`);\n\t\t}\n\n\t\tthis.intervals.set(id, {\n\t\t\tid,\n\t\t\tintervalMultiplier,\n\t\t\tdepth,\n\t\t\tmarkets: new Set(),\n\t\t\tnewlyAddedMarkets: new Set(),\n\t\t});\n\t}\n\n\tpublic removeInterval(id: string): void {\n\t\tconst interval = this.intervals.get(id);\n\t\tif (!interval) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove all markets from this interval\n\t\tinterval.markets.forEach((market) => {\n\t\t\tthis._marketToIntervalMap.delete(market);\n\t\t});\n\n\t\tthis.intervals.delete(id);\n\t}\n\n\t/**\n\t * Add a market to an interval.\n\t * If the market is already in an interval, it will be removed from the existing interval.\n\t * Newly added markets will be polled on the next tick regardless of interval multiplier.\n\t */\n\tpublic addMarketToInterval(intervalId: string, marketKey: MarketKey): void {\n\t\tconst interval = this.intervals.get(intervalId);\n\t\tif (!interval) {\n\t\t\tthrow new Error(`Interval with id '${intervalId}' does not exist`);\n\t\t}\n\n\t\t// Remove market from any existing interval first\n\t\tconst existingIntervalId = this._marketToIntervalMap.get(marketKey);\n\n\t\tif (existingIntervalId === intervalId) {\n\t\t\t// market is already in the interval\n\t\t\treturn;\n\t\t}\n\n\t\tif (existingIntervalId) {\n\t\t\tthis.removeMarketFromInterval(existingIntervalId, marketKey);\n\t\t}\n\n\t\tinterval.markets.add(marketKey);\n\t\t// Mark as newly added so it gets polled on the next tick\n\t\tinterval.newlyAddedMarkets.add(marketKey);\n\t\tthis._marketToIntervalMap.set(marketKey, intervalId);\n\t}\n\n\tpublic addMarketsToInterval(\n\t\tintervalId: string,\n\t\tmarketKeys: MarketKey[]\n\t): void {\n\t\tfor (const marketKey of marketKeys) {\n\t\t\tthis.addMarketToInterval(intervalId, marketKey);\n\t\t}\n\t}\n\n\tpublic removeMarketFromInterval(\n\t\tintervalId: string,\n\t\tmarketKey: MarketKey\n\t): void {\n\t\tconst interval = this.intervals.get(intervalId);\n\t\tif (!interval) {\n\t\t\treturn;\n\t\t}\n\n\t\tinterval.markets.delete(marketKey);\n\t\tinterval.newlyAddedMarkets.delete(marketKey);\n\t\tthis._marketToIntervalMap.delete(marketKey);\n\t}\n\n\tpublic getMarketInterval(marketKey: MarketKey): string | undefined {\n\t\treturn this._marketToIntervalMap.get(marketKey);\n\t}\n\n\tpublic onData(): Observable<MarketPollingData[]> {\n\t\treturn this.dataSubject.asObservable();\n\t}\n\n\tpublic onError(): Observable<Error> {\n\t\treturn this.errorSubject.asObservable();\n\t}\n\n\tpublic start(): Promise<void> {\n\t\tif (this.isStarted) {\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tthis.isStarted = true;\n\t\tthis.tickCounter = 0;\n\n\t\tconst firstTickPromise = this.tick();\n\n\t\tthis.intervalHandle = setInterval(() => {\n\t\t\tthis.tick();\n\t\t}, this.baseTickIntervalMs);\n\n\t\treturn firstTickPromise;\n\t}\n\n\tpublic stop(): void {\n\t\tif (!this.isStarted) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.isStarted = false;\n\n\t\tif (this.intervalHandle) {\n\t\t\tclearInterval(this.intervalHandle);\n\t\t\tthis.intervalHandle = null;\n\t\t}\n\t}\n\n\tpublic isRunning(): boolean {\n\t\treturn this.isStarted;\n\t}\n\n\tpublic getConfig(): PollingConfig {\n\t\treturn { ...this.config };\n\t}\n\n\tpublic updateConfig(newConfig: Partial<PollingConfig>): void {\n\t\tthis.config = { ...this.config, ...newConfig };\n\t}\n\n\tpublic getMarketCount(): number {\n\t\treturn this._marketToIntervalMap.size;\n\t}\n\n\tpublic getIntervalCount(): number {\n\t\treturn this.intervals.size;\n\t}\n\n\tpublic getAllMarkets(): MarketKey[] {\n\t\tconst allMarkets: MarketKey[] = [];\n\t\tthis.intervals.forEach((interval) => {\n\t\t\tallMarkets.push(...Array.from(interval.markets));\n\t\t});\n\t\treturn allMarkets;\n\t}\n\n\tpublic getMarketsForInterval(intervalId: string): MarketKey[] {\n\t\tconst interval = this.intervals.get(intervalId);\n\t\treturn interval ? Array.from(interval.markets) : [];\n\t}\n\n\tpublic getStats(): {\n\t\tisRunning: boolean;\n\t\ttickCounter: number;\n\t\tintervalCount: number;\n\t\tmarketCount: number;\n\t\tconsecutiveEmptyResponses: number;\n\t\tconsecutiveErrors: number;\n\t} {\n\t\treturn {\n\t\t\tisRunning: this.isStarted,\n\t\t\ttickCounter: this.tickCounter,\n\t\t\tintervalCount: this.intervals.size,\n\t\t\tmarketCount: this._marketToIntervalMap.size,\n\t\t\tconsecutiveEmptyResponses: this.consecutiveEmptyResponseCount,\n\t\t\tconsecutiveErrors: this.consecutiveErrorCount,\n\t\t};\n\t}\n\n\tpublic resetErrorCounters(): void {\n\t\tthis.consecutiveEmptyResponseCount = 0;\n\t\tthis.consecutiveErrorCount = 0;\n\t}\n\n\t/**\n\t * Factory method to create a PollingDlob with common interval configurations\n\t */\n\tpublic static createWithCommonIntervals(config: PollingConfig): PollingDlob {\n\t\tconst pollingDlob = new PollingDlob(config);\n\n\t\t// Add common intervals based on the original React hook\n\t\tpollingDlob.addInterval(\n\t\t\tPollingCategory.SELECTED_MARKET,\n\t\t\tPOLLING_INTERVALS.LIVE_MARKET,\n\t\t\tPOLLING_DEPTHS.ORDERBOOK\n\t\t);\n\t\tpollingDlob.addInterval(\n\t\t\tPollingCategory.USER_INVOLVED,\n\t\t\tPOLLING_INTERVALS.BACKGROUND_DEEP,\n\t\t\tPOLLING_DEPTHS.DEEP\n\t\t);\n\t\tpollingDlob.addInterval(\n\t\t\tPollingCategory.USER_NOT_INVOLVED,\n\t\t\tPOLLING_INTERVALS.BACKGROUND_SHALLOW,\n\t\t\tPOLLING_DEPTHS.SHALLOW\n\t\t);\n\n\t\treturn pollingDlob;\n\t}\n\n\tprivate async tick(): Promise<void> {\n\t\tthis.tickCounter++;\n\n\t\t// Find intervals that should be polled this tick\n\t\tconst intervalsToPoll = Array.from(this.intervals.values()).filter(\n\t\t\t(interval) => {\n\t\t\t\tconst hasMarkets = interval.markets.size > 0;\n\t\t\t\tconst hasNewlyAddedMarkets = interval.newlyAddedMarkets.size > 0;\n\t\t\t\tconst isFirstTick = this.tickCounter === 1;\n\t\t\t\tconst isRegularInterval =\n\t\t\t\t\tthis.tickCounter % interval.intervalMultiplier === 0;\n\n\t\t\t\treturn (\n\t\t\t\t\thasMarkets &&\n\t\t\t\t\t(isFirstTick || isRegularInterval || hasNewlyAddedMarkets)\n\t\t\t\t);\n\t\t\t}\n\t\t);\n\n\t\tif (intervalsToPoll.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst allMarketPollingData: MarketPollingData[] = [];\n\n\t\t\t// Combine all markets from different intervals into a single request\n\t\t\tconst combinedMarketRequests: {\n\t\t\t\tmarketId: MarketId;\n\t\t\t\tdepth: number;\n\t\t\t\tintervalMultiplier: number;\n\t\t\t}[] = [];\n\n\t\t\tfor (const interval of intervalsToPoll) {\n\t\t\t\tconst marketsArray = Array.from(interval.markets);\n\t\t\t\tif (marketsArray.length === 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tfor (const marketKey of marketsArray) {\n\t\t\t\t\tcombinedMarketRequests.push({\n\t\t\t\t\t\tmarketId: MarketId.getMarketIdFromKey(marketKey),\n\t\t\t\t\t\tdepth: interval.depth,\n\t\t\t\t\t\tintervalMultiplier: interval.intervalMultiplier,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (combinedMarketRequests.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Make a single bulk fetch for all markets\n\t\t\tconst l2Data = await fetchBulkMarketsDlobL2Data(\n\t\t\t\tthis.config.driftDlobServerHttpUrl,\n\t\t\t\tcombinedMarketRequests.map((req) => ({\n\t\t\t\t\tmarketId: req.marketId,\n\t\t\t\t\tdepth: req.depth,\n\t\t\t\t}))\n\t\t\t);\n\n\t\t\t// Map the results back to MarketPollingData with correct interval IDs\n\t\t\tconst intervalData: MarketPollingData[] = l2Data.map((data, index) => ({\n\t\t\t\tmarketId: combinedMarketRequests[index].marketId,\n\t\t\t\tdata,\n\t\t\t}));\n\n\t\t\tallMarketPollingData.push(...intervalData);\n\n\t\t\tif (allMarketPollingData.length > 0) {\n\t\t\t\tthis.consecutiveEmptyResponseCount = 0;\n\t\t\t\tthis.consecutiveErrorCount = 0;\n\t\t\t\tthis.dataSubject.next(allMarketPollingData);\n\n\t\t\t\t// Clear newly added markets flags for intervals that were polled\n\t\t\t\tintervalsToPoll.forEach((interval) => {\n\t\t\t\t\tinterval.newlyAddedMarkets.clear();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.consecutiveEmptyResponseCount++;\n\t\t\t\tif (\n\t\t\t\t\tthis.consecutiveEmptyResponseCount >=\n\t\t\t\t\tthis.maxConsecutiveEmptyResponses\n\t\t\t\t) {\n\t\t\t\t\tthis.errorSubject.next(\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`Received ${this.maxConsecutiveEmptyResponses} consecutive empty responses`\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.consecutiveErrorCount++;\n\t\t\tconst errorInstance =\n\t\t\t\terror instanceof Error ? error : new Error(String(error));\n\n\t\t\tif (this.consecutiveErrorCount >= this.maxConsecutiveErrors) {\n\t\t\t\tthis.errorSubject.next(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`Received ${this.maxConsecutiveErrors} consecutive errors. Latest: ${errorInstance.message}`\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.errorSubject.next(errorInstance);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"PollingDlob.js","sourceRoot":"","sources":["../../../../src/drift/Drift/data/PollingDlob.ts"],"names":[],"mappings":"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","sourcesContent":["import { Subject, Observable } from 'rxjs';\nimport { MarketId, MarketKey } from '../../../types/MarketId';\nimport { L2WithOracleAndMarketData } from '../../../utils/orderbook/types';\nimport { PollingCategory } from '../constants/blockchain';\nimport { fetchBulkMarketsDlobL2Data } from '../../base/actions/trade/openPerpOrder/dlobServer';\n\nexport interface PollingConfig {\n\tdriftDlobServerHttpUrl: string;\n\tindicativeLiquidityEnabled?: boolean;\n\tgroupingSize?: number;\n}\n\nexport interface PollingInterval {\n\tid: string;\n\tintervalMultiplier: number;\n\tdepth: number;\n\tmarkets: Set<MarketKey>;\n\t/**\n\t * Used to track markets that were added to an interval in the current tick, so that they get polled on the next tick regardless of interval multiplier.\n\t * Otherwise, they would only get polled on the next interval, which could be a long time if the interval multiplier is high.\n\t */\n\tnewlyAddedMarkets: Set<MarketKey>;\n}\n\nexport interface MarketPollingData {\n\tmarketId: MarketId;\n\tdata: L2WithOracleAndMarketData;\n}\n\n// Predefined interval multipliers from the original React hook\nexport const POLLING_INTERVALS = {\n\tLIVE_MARKET: 1,\n\tBACKGROUND_DEEP: 3, // Can be configured to 2 for interim usage\n\tBACKGROUND_SHALLOW: 30,\n\tIDLE_1: 30,\n\tIDLE_2: 60,\n} as const;\n\nexport const POLLING_DEPTHS = {\n\tSHALLOW: 1,\n\tDEEP: 1,\n\tORDERBOOK: 100,\n} as const;\n\n/**\n * PollingDlob - A configurable market data polling system.\n * The Drift DLOB (decentralized limit orderbook) server stores the current live state of the orderbook\n * across all Drift markets. This class is used to poll the DLOB server for the markets' current mark price,\n * while oracle price data is also provided alongside.\n *\n * Example usage:\n * ```typescript\n * import { PollingDlob, MarketId } from '@drift/common';\n *\n * const pollingDlob = new PollingDlob({\n * dlobServerHttpUrl: 'https://dlob.drift.trade',\n * indicativeLiquidityEnabled: true\n * });\n *\n * // Add different polling intervals\n * pollingDlob.addInterval('live', 1, 100); // Every 1s with depth 100\n * pollingDlob.addInterval('background', 3, 1); // Every 3s with depth 1\n * pollingDlob.addInterval('idle', 30, 1); // Every 30s with depth 1\n *\n * // Add markets to intervals\n * const perpMarket = MarketId.createPerpMarket(0);\n * const spotMarket = MarketId.createSpotMarket(0);\n *\n * pollingDlob.addMarketToInterval('live', perpMarket);\n * pollingDlob.addMarketToInterval('background', spotMarket);\n *\n * // Subscribe to data updates\n * pollingDlob.onData().subscribe(marketData => {\n * marketData.forEach(({ marketId, data, intervalId }) => {\n * console.log(`Market ${marketId.key} data from ${intervalId}:`, data);\n * });\n * });\n *\n * // Subscribe to errors\n * pollingDlob.onError().subscribe(error => {\n * console.error('Polling error:', error);\n * });\n *\n * // Start polling\n * pollingDlob.start();\n *\n * // Stop when done\n * // pollingDlob.stop();\n * ```\n */\n\nexport class PollingDlob {\n\tprivate config: PollingConfig;\n\tprivate baseTickIntervalMs = 1000;\n\tprivate intervals: Map<string, PollingInterval> = new Map();\n\tprivate _marketToIntervalMap: Map<MarketKey, string> = new Map();\n\tprivate dataSubject: Subject<MarketPollingData[]> = new Subject();\n\tprivate errorSubject: Subject<Error> = new Subject();\n\tprivate isStarted = false;\n\tprivate intervalHandle: ReturnType<typeof setInterval> | null = null;\n\tprivate tickCounter = 0;\n\tprivate consecutiveEmptyResponseCount = 0;\n\tprivate consecutiveErrorCount = 0;\n\tprivate readonly maxConsecutiveEmptyResponses = 3;\n\tprivate readonly maxConsecutiveErrors = 5;\n\n\tconstructor(config: PollingConfig) {\n\t\tthis.config = {\n\t\t\tindicativeLiquidityEnabled: true,\n\t\t\t...config,\n\t\t};\n\t}\n\n\tpublic getPollingIntervalForMarket(\n\t\tmarketKey: MarketKey\n\t): PollingInterval | undefined {\n\t\tconst intervalId = this._marketToIntervalMap.get(marketKey);\n\t\tif (!intervalId) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn this.intervals.get(intervalId);\n\t}\n\n\tpublic addInterval(\n\t\tid: string,\n\t\tintervalMultiplier: number,\n\t\tdepth: number\n\t): void {\n\t\tif (this.intervals.has(id)) {\n\t\t\tthrow new Error(`Interval with id '${id}' already exists`);\n\t\t}\n\n\t\tthis.intervals.set(id, {\n\t\t\tid,\n\t\t\tintervalMultiplier,\n\t\t\tdepth,\n\t\t\tmarkets: new Set(),\n\t\t\tnewlyAddedMarkets: new Set(),\n\t\t});\n\t}\n\n\tpublic removeInterval(id: string): void {\n\t\tconst interval = this.intervals.get(id);\n\t\tif (!interval) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove all markets from this interval\n\t\tinterval.markets.forEach((market) => {\n\t\t\tthis._marketToIntervalMap.delete(market);\n\t\t});\n\n\t\tthis.intervals.delete(id);\n\t}\n\n\t/**\n\t * Add a market to an interval.\n\t * If the market is already in an interval, it will be removed from the existing interval.\n\t * Newly added markets will be polled on the next tick regardless of interval multiplier.\n\t */\n\tpublic addMarketToInterval(intervalId: string, marketKey: MarketKey): void {\n\t\tconst interval = this.intervals.get(intervalId);\n\t\tif (!interval) {\n\t\t\tthrow new Error(`Interval with id '${intervalId}' does not exist`);\n\t\t}\n\n\t\t// Remove market from any existing interval first\n\t\tconst existingIntervalId = this._marketToIntervalMap.get(marketKey);\n\n\t\tif (existingIntervalId === intervalId) {\n\t\t\t// market is already in the interval\n\t\t\treturn;\n\t\t}\n\n\t\tif (existingIntervalId) {\n\t\t\tthis.removeMarketFromInterval(existingIntervalId, marketKey);\n\t\t}\n\n\t\tinterval.markets.add(marketKey);\n\t\t// Mark as newly added so it gets polled on the next tick\n\t\tinterval.newlyAddedMarkets.add(marketKey);\n\t\tthis._marketToIntervalMap.set(marketKey, intervalId);\n\t}\n\n\tpublic addMarketsToInterval(\n\t\tintervalId: string,\n\t\tmarketKeys: MarketKey[]\n\t): void {\n\t\tfor (const marketKey of marketKeys) {\n\t\t\tthis.addMarketToInterval(intervalId, marketKey);\n\t\t}\n\t}\n\n\tpublic removeMarketFromInterval(\n\t\tintervalId: string,\n\t\tmarketKey: MarketKey\n\t): void {\n\t\tconst interval = this.intervals.get(intervalId);\n\t\tif (!interval) {\n\t\t\treturn;\n\t\t}\n\n\t\tinterval.markets.delete(marketKey);\n\t\tinterval.newlyAddedMarkets.delete(marketKey);\n\t\tthis._marketToIntervalMap.delete(marketKey);\n\t}\n\n\tpublic getMarketInterval(marketKey: MarketKey): string | undefined {\n\t\treturn this._marketToIntervalMap.get(marketKey);\n\t}\n\n\tpublic onData(): Observable<MarketPollingData[]> {\n\t\treturn this.dataSubject.asObservable();\n\t}\n\n\tpublic onError(): Observable<Error> {\n\t\treturn this.errorSubject.asObservable();\n\t}\n\n\tpublic start(): Promise<void> {\n\t\tif (this.isStarted) {\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tthis.isStarted = true;\n\t\tthis.tickCounter = 0;\n\n\t\tconst firstTickPromise = this.tick();\n\n\t\tthis.intervalHandle = setInterval(() => {\n\t\t\tthis.tick();\n\t\t}, this.baseTickIntervalMs);\n\n\t\treturn firstTickPromise;\n\t}\n\n\tpublic stop(): void {\n\t\tif (!this.isStarted) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.isStarted = false;\n\n\t\tif (this.intervalHandle) {\n\t\t\tclearInterval(this.intervalHandle);\n\t\t\tthis.intervalHandle = null;\n\t\t}\n\t}\n\n\tpublic isRunning(): boolean {\n\t\treturn this.isStarted;\n\t}\n\n\tpublic getConfig(): PollingConfig {\n\t\treturn { ...this.config };\n\t}\n\n\tpublic updateConfig(newConfig: Partial<PollingConfig>): void {\n\t\tthis.config = { ...this.config, ...newConfig };\n\t}\n\n\tpublic getMarketCount(): number {\n\t\treturn this._marketToIntervalMap.size;\n\t}\n\n\tpublic getIntervalCount(): number {\n\t\treturn this.intervals.size;\n\t}\n\n\tpublic getAllMarkets(): MarketKey[] {\n\t\tconst allMarkets: MarketKey[] = [];\n\t\tthis.intervals.forEach((interval) => {\n\t\t\tallMarkets.push(...Array.from(interval.markets));\n\t\t});\n\t\treturn allMarkets;\n\t}\n\n\tpublic getMarketsForInterval(intervalId: string): MarketKey[] {\n\t\tconst interval = this.intervals.get(intervalId);\n\t\treturn interval ? Array.from(interval.markets) : [];\n\t}\n\n\tpublic getStats(): {\n\t\tisRunning: boolean;\n\t\ttickCounter: number;\n\t\tintervalCount: number;\n\t\tmarketCount: number;\n\t\tconsecutiveEmptyResponses: number;\n\t\tconsecutiveErrors: number;\n\t} {\n\t\treturn {\n\t\t\tisRunning: this.isStarted,\n\t\t\ttickCounter: this.tickCounter,\n\t\t\tintervalCount: this.intervals.size,\n\t\t\tmarketCount: this._marketToIntervalMap.size,\n\t\t\tconsecutiveEmptyResponses: this.consecutiveEmptyResponseCount,\n\t\t\tconsecutiveErrors: this.consecutiveErrorCount,\n\t\t};\n\t}\n\n\tpublic resetErrorCounters(): void {\n\t\tthis.consecutiveEmptyResponseCount = 0;\n\t\tthis.consecutiveErrorCount = 0;\n\t}\n\n\t/**\n\t * Factory method to create a PollingDlob with common interval configurations\n\t */\n\tpublic static createWithCommonIntervals(config: PollingConfig): PollingDlob {\n\t\tconst pollingDlob = new PollingDlob(config);\n\n\t\t// Add common intervals based on the original React hook\n\t\tpollingDlob.addInterval(\n\t\t\tPollingCategory.SELECTED_MARKET,\n\t\t\tPOLLING_INTERVALS.LIVE_MARKET,\n\t\t\tPOLLING_DEPTHS.ORDERBOOK\n\t\t);\n\t\tpollingDlob.addInterval(\n\t\t\tPollingCategory.USER_INVOLVED,\n\t\t\tPOLLING_INTERVALS.BACKGROUND_DEEP,\n\t\t\tPOLLING_DEPTHS.DEEP\n\t\t);\n\t\tpollingDlob.addInterval(\n\t\t\tPollingCategory.USER_NOT_INVOLVED,\n\t\t\tPOLLING_INTERVALS.BACKGROUND_SHALLOW,\n\t\t\tPOLLING_DEPTHS.SHALLOW\n\t\t);\n\n\t\treturn pollingDlob;\n\t}\n\n\tprivate async tick(): Promise<void> {\n\t\tthis.tickCounter++;\n\n\t\t// Find intervals that should be polled this tick\n\t\tconst intervalsToPoll = Array.from(this.intervals.values()).filter(\n\t\t\t(interval) => {\n\t\t\t\tconst hasMarkets = interval.markets.size > 0;\n\t\t\t\tconst hasNewlyAddedMarkets = interval.newlyAddedMarkets.size > 0;\n\t\t\t\tconst isFirstTick = this.tickCounter === 1;\n\t\t\t\tconst isRegularInterval =\n\t\t\t\t\tthis.tickCounter % interval.intervalMultiplier === 0;\n\n\t\t\t\treturn (\n\t\t\t\t\thasMarkets &&\n\t\t\t\t\t(isFirstTick || isRegularInterval || hasNewlyAddedMarkets)\n\t\t\t\t);\n\t\t\t}\n\t\t);\n\n\t\tif (intervalsToPoll.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst allMarketPollingData: MarketPollingData[] = [];\n\n\t\t\t// Combine all markets from different intervals into a single request\n\t\t\tconst combinedMarketRequests: {\n\t\t\t\tmarketId: MarketId;\n\t\t\t\tdepth: number;\n\t\t\t\tintervalMultiplier: number;\n\t\t\t}[] = [];\n\n\t\t\tfor (const interval of intervalsToPoll) {\n\t\t\t\tconst marketsArray = Array.from(interval.markets);\n\t\t\t\tif (marketsArray.length === 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tfor (const marketKey of marketsArray) {\n\t\t\t\t\tcombinedMarketRequests.push({\n\t\t\t\t\t\tmarketId: MarketId.getMarketIdFromKey(marketKey),\n\t\t\t\t\t\tdepth: interval.depth,\n\t\t\t\t\t\tintervalMultiplier: interval.intervalMultiplier,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (combinedMarketRequests.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Make a single bulk fetch for all markets\n\t\t\tconst l2Data = await fetchBulkMarketsDlobL2Data(\n\t\t\t\tthis.config.driftDlobServerHttpUrl,\n\t\t\t\tcombinedMarketRequests.map((req) => ({\n\t\t\t\t\tmarketId: req.marketId,\n\t\t\t\t\tdepth: req.depth,\n\t\t\t\t}))\n\t\t\t);\n\n\t\t\t// Map the results back to MarketPollingData with correct interval IDs\n\t\t\tconst intervalData: MarketPollingData[] = l2Data.map((data, index) => ({\n\t\t\t\tmarketId: combinedMarketRequests[index].marketId,\n\t\t\t\tdata,\n\t\t\t}));\n\n\t\t\tallMarketPollingData.push(...intervalData);\n\n\t\t\tif (allMarketPollingData.length > 0) {\n\t\t\t\tthis.consecutiveEmptyResponseCount = 0;\n\t\t\t\tthis.consecutiveErrorCount = 0;\n\t\t\t\tthis.dataSubject.next(allMarketPollingData);\n\n\t\t\t\t// Clear newly added markets flags for intervals that were polled\n\t\t\t\tintervalsToPoll.forEach((interval) => {\n\t\t\t\t\tinterval.newlyAddedMarkets.clear();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.consecutiveEmptyResponseCount++;\n\t\t\t\tif (\n\t\t\t\t\tthis.consecutiveEmptyResponseCount >=\n\t\t\t\t\tthis.maxConsecutiveEmptyResponses\n\t\t\t\t) {\n\t\t\t\t\tthis.errorSubject.next(\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`Received ${this.maxConsecutiveEmptyResponses} consecutive empty responses`\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.consecutiveErrorCount++;\n\t\t\tconst errorInstance =\n\t\t\t\terror instanceof Error ? error : new Error(String(error));\n\n\t\t\tif (this.consecutiveErrorCount >= this.maxConsecutiveErrors) {\n\t\t\t\tthis.errorSubject.next(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`Received ${this.maxConsecutiveErrors} consecutive errors. Latest: ${errorInstance.message}`\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.errorSubject.next(errorInstance);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"MultiplexWebSocket.js","sourceRoot":"","sources":["../../src/utils/MultiplexWebSocket.ts"],"names":[],"mappings":"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","sourcesContent":["import { Subject, Subscription, catchError } from 'rxjs';\nimport WebSocket, { MessageEvent } from 'isomorphic-ws';\n\ntype WebSocketMessage<T = Record<string, unknown>> = T;\n\ntype WebSocketSubscriptionProps<T = Record<string, unknown>> = {\n\twsUrl: string;\n\tsubscriptionId: string;\n\tsubscribeMessage: string;\n\tunsubscribeMessage: string;\n\tonError: (err?: any) => void;\n\tonMessage: (message: WebSocketMessage<T>) => void;\n\tmessageFilter?: (message: WebSocketMessage<T>) => boolean;\n\terrorMessageFilter?: (message: WebSocketMessage<T>) => boolean;\n\tonClose?: () => void;\n\tenableHeartbeatMonitoring?: boolean;\n\theartbeatTimeoutMs?: number;\n};\n\ntype WebSocketSubscriptionState<T = Record<string, unknown>> =\n\tWebSocketSubscriptionProps<T> & {\n\t\thasSentSubscribeMessage?: boolean;\n\t\tsubjectSubscription?: Subscription;\n\t};\n\ntype WebSocketUrl = string;\ntype SubscriptionId = string;\n\nconst DEFAULT_MAX_RECONNECT_ATTEMPTS = 5;\nconst DEFAULT_MAX_RECONNECT_WINDOW_MS = 60 * 1000;\nconst DEFAULT_CONNECTION_CLOSE_DELAY_MS = 2 * 1000; // 2 seconds delay before closing connection\nconst DEFAULT_HEARTBEAT_TIMEOUT_MS = 11 * 1000; // Consider connection dead if no heartbeat within 11 seconds (a little more than twice of 5 seconds, the interval Drift servers use)\n\n/**\n * Manages reconnection logic for WebSocket connections with exponential backoff and rate limiting.\n *\n * Features:\n * - Tracks reconnection attempts within a time window\n * - Implements exponential backoff (1s, 2s, 4s, 8s max)\n * - Resets attempt counter after configurable time window\n * - Throws error when max attempts exceeded\n * - Provides configurable limits for attempts and time window\n *\n * @example\n * ```ts\n * const manager = new ReconnectionManager(5, 60000); // 5 attempts in 60s\n * const { shouldReconnect, delay } = manager.attemptReconnection('ws://example.com');\n * if (shouldReconnect) {\n * setTimeout(() => reconnect(), delay);\n * }\n * ```\n */\nclass ReconnectionManager {\n\tprivate reconnectAttempts: number = 0;\n\tprivate lastReconnectWindow: number = Date.now();\n\tprivate maxAttemptsCount: number;\n\tprivate maxAttemptsWindowMs: number;\n\n\tconstructor(\n\t\tmaxAttemptsCount = DEFAULT_MAX_RECONNECT_ATTEMPTS,\n\t\tmaxAttemptsWindowMs = DEFAULT_MAX_RECONNECT_WINDOW_MS\n\t) {\n\t\tthis.maxAttemptsCount = maxAttemptsCount;\n\t\tthis.maxAttemptsWindowMs = maxAttemptsWindowMs;\n\t}\n\n\tpublic attemptReconnection(wsUrl: string): {\n\t\tshouldReconnect: boolean;\n\t\tdelay: number;\n\t} {\n\t\tconst now = Date.now();\n\n\t\t// Reset reconnect attempts if more than a minute has passed\n\t\tif (now - this.lastReconnectWindow > this.maxAttemptsWindowMs) {\n\t\t\tthis.reconnectAttempts = 0;\n\t\t\tthis.lastReconnectWindow = now;\n\t\t}\n\n\t\t// Check if we've exceeded the maximum reconnect attempts\n\t\tif (this.reconnectAttempts >= this.maxAttemptsCount) {\n\t\t\tthrow new Error(\n\t\t\t\t`WebSocket reconnection failed: Maximum reconnect attempts (${this.maxAttemptsCount}) exceeded within ${this.maxAttemptsWindowMs}ms for ${wsUrl}`\n\t\t\t);\n\t\t}\n\n\t\tthis.reconnectAttempts++;\n\n\t\t// Calculate exponential backoff delay: 1s, 2s, 4s, 8s, etc. (capped at 8s)\n\t\tconst backoffDelay = Math.min(\n\t\t\t1000 * Math.pow(2, this.reconnectAttempts - 1),\n\t\t\t8000\n\t\t);\n\n\t\treturn {\n\t\t\tshouldReconnect: true,\n\t\t\tdelay: backoffDelay,\n\t\t};\n\t}\n\n\tpublic reset(): void {\n\t\tthis.reconnectAttempts = 0;\n\t\tthis.lastReconnectWindow = Date.now();\n\t}\n}\n\nenum WebSocketConnectionState {\n\tCONNECTING,\n\tCONNECTED,\n\tDISCONNECTING,\n\tDISCONNECTED,\n}\n\ntype IMultiplexWebSocket<T = Record<string, unknown>> = {\n\twsUrl: WebSocketUrl;\n\twebSocket: WebSocket;\n\tcustomConnectionState: WebSocketConnectionState;\n\tsubject: Subject<WebSocketMessage<T>>;\n\tsubscriptions: Map<\n\t\tSubscriptionId,\n\t\tOmit<WebSocketSubscriptionProps<T>, 'wsUrl' | 'subscriptionId'>\n\t>;\n};\n\n/**\n * MultiplexWebSocket allows for multiple subscriptions to a single websocket of the same URL, improving efficiency and reducing the number of open connections.\n *\n * This implementation assumes the following:\n * - All websocket streams are treated equally - reconnection attempts are performed at the same standards\n * - All messages returned are in the `WebSocketMessage` format\n * - 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\n *\n * Internal implementation details:\n * - The websocket is closed when the number of subscriptions is 0\n * - The websocket will be refreshed (new instance) when it disconnects unexpectedly or errors, until it reaches the maximum number of reconnect attempts\n */\nexport class MultiplexWebSocket<T = Record<string, unknown>>\n\timplements IMultiplexWebSocket<T>\n{\n\t/**\n\t * A lookup of all websockets by their URL.\n\t */\n\tprivate static URL_TO_WEBSOCKETS_LOOKUP = new Map<\n\t\tWebSocketUrl,\n\t\tMultiplexWebSocket<any>\n\t>();\n\n\t/**\n\t * A lookup from websocket URL to all subscription IDs for that URL.\n\t */\n\tprivate static URL_TO_SUBSCRIPTION_IDS_LOOKUP = new Map<\n\t\tWebSocketUrl,\n\t\tSet<SubscriptionId>\n\t>();\n\n\twsUrl: WebSocketUrl;\n\t#webSocket: WebSocket;\n\tcustomConnectionState: WebSocketConnectionState;\n\tsubject: Subject<WebSocketMessage<T>>;\n\tsubscriptions: Map<\n\t\tSubscriptionId,\n\t\tOmit<WebSocketSubscriptionState<T>, 'wsUrl' | 'subscriptionId'>\n\t>;\n\tprivate reconnectionManager: ReconnectionManager;\n\tprivate closeTimeout: NodeJS.Timeout | null = null;\n\tprivate heartbeatTimeout: NodeJS.Timeout | null = null;\n\tprivate heartbeatMonitoringEnabled: boolean = false;\n\tprivate heartbeatTimeoutMs: number = DEFAULT_HEARTBEAT_TIMEOUT_MS;\n\n\tprivate constructor(\n\t\twsUrl: WebSocketUrl,\n\t\tenableHeartbeatMonitoring: boolean = false,\n\t\theartbeatTimeoutMs: number = DEFAULT_HEARTBEAT_TIMEOUT_MS\n\t) {\n\t\tif (MultiplexWebSocket.URL_TO_WEBSOCKETS_LOOKUP.has(wsUrl)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Attempting to create a new websocket for ${wsUrl}, but it already exists`\n\t\t\t);\n\t\t}\n\n\t\tthis.wsUrl = wsUrl;\n\t\tthis.customConnectionState = WebSocketConnectionState.CONNECTING;\n\t\tthis.subject = new Subject<WebSocketMessage<T>>();\n\t\tthis.subscriptions = new Map<\n\t\t\tSubscriptionId,\n\t\t\tOmit<WebSocketSubscriptionProps<T>, 'wsUrl' | 'subscriptionId'>\n\t\t>();\n\n\t\tthis.reconnectionManager = new ReconnectionManager();\n\t\tthis.heartbeatMonitoringEnabled = enableHeartbeatMonitoring;\n\t\tthis.heartbeatTimeoutMs = heartbeatTimeoutMs;\n\n\t\tthis.webSocket = new WebSocket(wsUrl);\n\n\t\tMultiplexWebSocket.URL_TO_WEBSOCKETS_LOOKUP.set(wsUrl, this);\n\t}\n\n\t/**\n\t * Creates a new virtual websocket subscription. If an existing websocket for the given URL exists, the subscription will be added to the existing websocket.\n\t * Returns a function that can be called to unsubscribe from the subscription.\n\t */\n\tpublic static createWebSocketSubscription<T = Record<string, unknown>>(\n\t\tprops: WebSocketSubscriptionProps<T>\n\t): { unsubscribe: () => void } {\n\t\tconst { wsUrl } = props;\n\n\t\tconst doesWebSocketForWsUrlExist =\n\t\t\tMultiplexWebSocket.URL_TO_WEBSOCKETS_LOOKUP.has(wsUrl);\n\n\t\tif (doesWebSocketForWsUrlExist) {\n\t\t\treturn this.handleNewSubForExistingWsUrl<T>(props);\n\t\t} else {\n\t\t\t// Create new websocket for new URL or reopen previously closed websocket\n\t\t\treturn this.handleNewSubForNewWsUrl<T>(props);\n\t\t}\n\t}\n\n\tprivate static handleNewSubForNewWsUrl<T = Record<string, unknown>>(\n\t\tnewSubscriptionProps: WebSocketSubscriptionProps<T>\n\t) {\n\t\tconst newMWS = new MultiplexWebSocket<T>(\n\t\t\tnewSubscriptionProps.wsUrl,\n\t\t\tnewSubscriptionProps.enableHeartbeatMonitoring ?? false,\n\t\t\tnewSubscriptionProps.heartbeatTimeoutMs ?? DEFAULT_HEARTBEAT_TIMEOUT_MS\n\t\t);\n\n\t\tnewMWS.subscribe(newSubscriptionProps);\n\n\t\treturn {\n\t\t\tunsubscribe: () => {\n\t\t\t\tnewMWS.unsubscribe(newSubscriptionProps.subscriptionId);\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate static handleNewSubForExistingWsUrl<T = Record<string, unknown>>(\n\t\tnewSubscriptionProps: WebSocketSubscriptionProps<T>\n\t) {\n\t\tconst { wsUrl, subscriptionId } = newSubscriptionProps;\n\n\t\tif (!MultiplexWebSocket.URL_TO_WEBSOCKETS_LOOKUP.has(wsUrl)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Attempting to subscribe to ${subscriptionId} on websocket ${wsUrl}, but websocket does not exist yet`\n\t\t\t);\n\t\t}\n\n\t\tconst existingMWS = MultiplexWebSocket.URL_TO_WEBSOCKETS_LOOKUP.get(\n\t\t\twsUrl\n\t\t) as MultiplexWebSocket<T>;\n\n\t\t// Check if heartbeat monitoring settings match\n\t\tconst requestedHeartbeat =\n\t\t\tnewSubscriptionProps.enableHeartbeatMonitoring ?? false;\n\t\tif (existingMWS.heartbeatMonitoringEnabled !== requestedHeartbeat) {\n\t\t\tconsole.warn(\n\t\t\t\t`WebSocket for ${wsUrl} already exists with heartbeat monitoring ${\n\t\t\t\t\texistingMWS.heartbeatMonitoringEnabled ? 'enabled' : 'disabled'\n\t\t\t\t}, ` +\n\t\t\t\t\t`but new subscription requests ${\n\t\t\t\t\t\trequestedHeartbeat ? 'enabled' : 'disabled'\n\t\t\t\t\t}. Using existing setting.`\n\t\t\t);\n\t\t}\n\n\t\t// Check if heartbeat timeout settings match for the same websocket URL (note that this assumes that all types of subscriptions from the same websocket URL are expected to have the same heartbeat interval)\n\t\tconst requestedTimeout =\n\t\t\tnewSubscriptionProps.heartbeatTimeoutMs ?? DEFAULT_HEARTBEAT_TIMEOUT_MS;\n\t\tif (existingMWS.heartbeatTimeoutMs !== requestedTimeout) {\n\t\t\tconsole.warn(\n\t\t\t\t`WebSocket for ${wsUrl} already exists with heartbeat timeout ${existingMWS.heartbeatTimeoutMs}ms, ` +\n\t\t\t\t\t`but new subscription requests ${requestedTimeout}ms. Using existing setting.`\n\t\t\t);\n\t\t}\n\n\t\t// Track new subscription for existing websocket\n\t\texistingMWS.subscribe(newSubscriptionProps);\n\n\t\treturn {\n\t\t\tunsubscribe: () => {\n\t\t\t\texistingMWS.unsubscribe(newSubscriptionProps.subscriptionId);\n\t\t\t},\n\t\t};\n\t}\n\n\tget webSocket() {\n\t\treturn this.#webSocket;\n\t}\n\n\t/**\n\t * Setting the WebSocket instance will automatically add event handlers to the WebSocket instance.\n\t * When the WebSocket is connected, all existing subscriptions will be subscribed to.\n\t */\n\tset webSocket(webSocket: WebSocket) {\n\t\twebSocket.onopen = () => {\n\t\t\tthis.customConnectionState = WebSocketConnectionState.CONNECTED;\n\t\t\tthis.reconnectionManager.reset(); // Reset reconnection attempts on successful connection\n\n\t\t\t// Start heartbeat monitoring if enabled\n\t\t\tif (this.heartbeatMonitoringEnabled) {\n\t\t\t\tthis.startHeartbeatMonitoring();\n\t\t\t}\n\n\t\t\t// sends subscription message for each subscription for those that are added before the websocket is connected\n\t\t\tfor (const [subscriptionId] of this.subscriptions.entries()) {\n\t\t\t\tthis.subscribeToWebSocket(subscriptionId);\n\t\t\t}\n\t\t};\n\n\t\twebSocket.onmessage = (messageEvent: MessageEvent) => {\n\t\t\tconst message = JSON.parse(\n\t\t\t\tmessageEvent.data as string\n\t\t\t) as WebSocketMessage<T>;\n\n\t\t\t// Check for heartbeat message from server (only if heartbeat monitoring is enabled)\n\t\t\tif (this.heartbeatMonitoringEnabled && this.isHeartbeatMessage(message)) {\n\t\t\t\tthis.handleHeartbeat(message);\n\t\t\t\treturn; // Don't forward heartbeat messages to subscriptions\n\t\t\t}\n\n\t\t\tthis.subject.next(message);\n\t\t};\n\n\t\twebSocket.onclose = (event) => {\n\t\t\tthis.customConnectionState = WebSocketConnectionState.DISCONNECTED;\n\n\t\t\t// Stop heartbeat monitoring when connection closes (if enabled)\n\t\t\tif (this.heartbeatMonitoringEnabled) {\n\t\t\t\tthis.stopHeartbeatMonitoring();\n\t\t\t}\n\n\t\t\t// Restart websocket if it was closed unexpectedly (not by us)\n\t\t\tif (!event.wasClean && this.subscriptions.size > 0) {\n\t\t\t\tconsole.log('WebSocket closed unexpectedly, restarting...', event);\n\t\t\t\tthis.refreshWebSocket();\n\t\t\t}\n\t\t};\n\n\t\twebSocket.onerror = (error) => {\n\t\t\tconsole.error('MultiplexWebSocket Error', { error, webSocket });\n\n\t\t\t// Forward error to all subscriptions for this websocket URL\n\t\t\tconst subscriptionIds =\n\t\t\t\tMultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.get(this.wsUrl);\n\t\t\tif (subscriptionIds) {\n\t\t\t\tfor (const subscriptionId of subscriptionIds) {\n\t\t\t\t\tconst subscription = this.subscriptions.get(subscriptionId);\n\t\t\t\t\tif (subscription) {\n\t\t\t\t\t\tsubscription.onError(error);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Note: onclose always fires after onerror, so reconnection is handled there\n\t\t\t// to avoid double-counting reconnection attempts.\n\t\t};\n\n\t\tthis.#webSocket = webSocket;\n\t}\n\n\tprivate subscribeToWebSocket(subscriptionId: SubscriptionId) {\n\t\tconst subscriptionState = this.subscriptions.get(subscriptionId);\n\n\t\tconst {\n\t\t\tsubscribeMessage,\n\t\t\tonError,\n\t\t\tonMessage,\n\t\t\tmessageFilter,\n\t\t\terrorMessageFilter,\n\t\t\tonClose,\n\t\t} = subscriptionState;\n\n\t\tthis.webSocket.send(subscribeMessage);\n\t\tif (subscriptionState) {\n\t\t\tsubscriptionState.hasSentSubscribeMessage = true;\n\t\t}\n\n\t\t// Create internal subscription for message handling\n\t\tconst subjectSubscription = this.subject\n\t\t\t.pipe(\n\t\t\t\tcatchError((err) => {\n\t\t\t\t\tconsole.error('Caught websocket error', err);\n\t\t\t\t\tonError();\n\t\t\t\t\treturn [];\n\t\t\t\t})\n\t\t\t)\n\t\t\t.subscribe({\n\t\t\t\tnext: (message: WebSocketMessage<T>) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (messageFilter && !messageFilter(message)) return;\n\n\t\t\t\t\t\tif (errorMessageFilter && errorMessageFilter(message)) {\n\t\t\t\t\t\t\tonError();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tonMessage(message);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.error('Error parsing websocket message', err);\n\t\t\t\t\t\tonError();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\terror: (err) => {\n\t\t\t\t\tconsole.error('Error subscribing to websocket', err);\n\t\t\t\t\tonError();\n\t\t\t\t},\n\t\t\t\tcomplete: () => {\n\t\t\t\t\tif (onClose) {\n\t\t\t\t\t\tonClose();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\tsubscriptionState.subjectSubscription = subjectSubscription;\n\t}\n\n\tprivate subscribe(props: WebSocketSubscriptionProps<T>) {\n\t\tconst {\n\t\t\tsubscriptionId,\n\t\t\tsubscribeMessage,\n\t\t\tunsubscribeMessage,\n\t\t\tonError,\n\t\t\tonMessage,\n\t\t\tmessageFilter,\n\t\t\terrorMessageFilter,\n\t\t\tonClose,\n\t\t} = props;\n\n\t\tif (this.subscriptions.get(subscriptionId)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Attempting to subscribe to ${subscriptionId} on websocket ${this.wsUrl}, but subscription already exists`\n\t\t\t);\n\t\t}\n\n\t\t// Cancel any pending delayed close since we're adding a new subscription\n\t\tthis.cancelDelayedClose();\n\n\t\tthis.subscriptions.set(subscriptionId, {\n\t\t\tsubscribeMessage,\n\t\t\tunsubscribeMessage,\n\t\t\tonError,\n\t\t\tonMessage,\n\t\t\tmessageFilter,\n\t\t\terrorMessageFilter,\n\t\t\tonClose,\n\t\t\thasSentSubscribeMessage: false,\n\t\t});\n\n\t\t// Update URL to subscription IDs lookup\n\t\tif (!MultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.has(this.wsUrl)) {\n\t\t\tMultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.set(\n\t\t\t\tthis.wsUrl,\n\t\t\t\tnew Set()\n\t\t\t);\n\t\t}\n\t\tMultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.get(this.wsUrl)!.add(\n\t\t\tsubscriptionId\n\t\t);\n\n\t\tif (this.customConnectionState === WebSocketConnectionState.CONNECTED) {\n\t\t\tthis.subscribeToWebSocket(subscriptionId);\n\t\t} else if (\n\t\t\tthis.customConnectionState === WebSocketConnectionState.CONNECTING\n\t\t) {\n\t\t\t// do nothing, subscription will automatically start when websocket is connected\n\t\t} else {\n\t\t\t// handle case where websocket is disconnecting/disconnected\n\t\t\tthis.refreshWebSocket();\n\t\t}\n\t}\n\n\tprivate unsubscribe(subscriptionId: SubscriptionId) {\n\t\tconst subscriptionState = this.subscriptions.get(subscriptionId);\n\t\tif (subscriptionState) {\n\t\t\tsubscriptionState.subjectSubscription?.unsubscribe();\n\n\t\t\t// Only send unsubscribe message if websocket is connected and ready to send.\n\t\t\t//// Otherwise, when the websocket DOES connect we don't have to worry about this subscription because we are deleting it from the subscriptions map. (Which only trigger their connections once the websocket becomes connected)\n\t\t\tif (\n\t\t\t\tthis.customConnectionState === WebSocketConnectionState.CONNECTED &&\n\t\t\t\tthis.webSocket.readyState === WebSocket.OPEN\n\t\t\t) {\n\t\t\t\tthis.webSocket.send(subscriptionState.unsubscribeMessage);\n\t\t\t}\n\n\t\t\tthis.subscriptions.delete(subscriptionId);\n\n\t\t\t// Update URL to subscription IDs lookup\n\t\t\tconst subscriptionIds =\n\t\t\t\tMultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.get(this.wsUrl);\n\t\t\tif (subscriptionIds) {\n\t\t\t\tsubscriptionIds.delete(subscriptionId);\n\t\t\t\tif (subscriptionIds.size === 0) {\n\t\t\t\t\tMultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.delete(this.wsUrl);\n\t\t\t\t\t// Schedule delayed close when last subscriber unsubscribes\n\t\t\t\t\tthis.scheduleDelayedClose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate scheduleDelayedClose() {\n\t\t// Cancel any existing delayed close timeout\n\t\tthis.cancelDelayedClose();\n\n\t\t// Schedule new delayed close\n\t\tthis.closeTimeout = setTimeout(() => {\n\t\t\tthis.close();\n\t\t}, DEFAULT_CONNECTION_CLOSE_DELAY_MS);\n\t}\n\n\tprivate cancelDelayedClose() {\n\t\tif (this.closeTimeout) {\n\t\t\tclearTimeout(this.closeTimeout);\n\t\t\tthis.closeTimeout = null;\n\t\t}\n\t}\n\n\tprivate close() {\n\t\t// Cancel any pending delayed close\n\t\tthis.cancelDelayedClose();\n\n\t\t// Stop heartbeat monitoring (if enabled)\n\t\tif (this.heartbeatMonitoringEnabled) {\n\t\t\tthis.stopHeartbeatMonitoring();\n\t\t}\n\n\t\tfor (const [subscriptionId] of this.subscriptions.entries()) {\n\t\t\tthis.unsubscribe(subscriptionId);\n\t\t}\n\n\t\tthis.subscriptions.clear();\n\t\tthis.webSocket.close();\n\t\tMultiplexWebSocket.URL_TO_WEBSOCKETS_LOOKUP.delete(this.wsUrl);\n\t\tMultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.delete(this.wsUrl);\n\t\tthis.reconnectionManager.reset();\n\t}\n\n\tprivate startHeartbeatMonitoring() {\n\t\t// Start the heartbeat timeout - if we don't receive a heartbeat message within the timeout, refresh connection\n\t\tthis.resetHeartbeatTimeout();\n\t}\n\n\tprivate stopHeartbeatMonitoring() {\n\t\tif (this.heartbeatTimeout) {\n\t\t\tclearTimeout(this.heartbeatTimeout);\n\t\t\tthis.heartbeatTimeout = null;\n\t\t}\n\t}\n\n\tprivate resetHeartbeatTimeout() {\n\t\t// Clear existing timeout\n\t\tif (this.heartbeatTimeout) {\n\t\t\tclearTimeout(this.heartbeatTimeout);\n\t\t}\n\n\t\t// Set new timeout\n\t\tthis.heartbeatTimeout = setTimeout(() => {\n\t\t\tconsole.warn(\n\t\t\t\t`No heartbeat received within ${this.heartbeatTimeoutMs}ms - connection appears dead`\n\t\t\t);\n\t\t\tthis.refreshWebSocket();\n\t\t}, this.heartbeatTimeoutMs);\n\t}\n\n\tprivate isHeartbeatMessage(message: WebSocketMessage<T>): boolean {\n\t\t// Check if message is a heartbeat message from server\n\t\treturn (message as any)?.channel === 'heartbeat';\n\t}\n\n\tprivate handleHeartbeat(_message: WebSocketMessage<T>) {\n\t\t// Reset the heartbeat timeout\n\t\tthis.resetHeartbeatTimeout();\n\t}\n\n\tprivate refreshWebSocket() {\n\t\t// Cancel any pending delayed close since we're refreshing\n\t\tthis.cancelDelayedClose();\n\n\t\t// Reset heartbeat monitoring during refresh (if enabled) - it will restart when the new connection opens\n\t\tif (this.heartbeatMonitoringEnabled) {\n\t\t\tthis.stopHeartbeatMonitoring();\n\t\t}\n\n\t\tlet shouldReconnect: boolean;\n\t\tlet delay: number;\n\n\t\ttry {\n\t\t\t({ shouldReconnect, delay } =\n\t\t\t\tthis.reconnectionManager.attemptReconnection(this.wsUrl));\n\t\t} catch (error) {\n\t\t\t// Max reconnect attempts exceeded — close gracefully and notify all subscribers\n\t\t\tconsole.error('WebSocket reconnection failed', error);\n\n\t\t\t// Forward error to all subscriptions before closing\n\t\t\tfor (const [, subscription] of this.subscriptions.entries()) {\n\t\t\t\tsubscription.onError(error);\n\t\t\t}\n\n\t\t\tthis.close();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!shouldReconnect) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clean up current websocket\n\t\tconst currentWebSocket = this.webSocket;\n\t\tif (currentWebSocket) {\n\t\t\tcurrentWebSocket.onerror = () => {};\n\t\t\tcurrentWebSocket.onclose = () => {};\n\t\t\tcurrentWebSocket.onmessage = () => {};\n\t\t\tcurrentWebSocket.onopen = () => {\n\t\t\t\t// in the event where the websocket has yet to connect, we close the connection after it is connected\n\t\t\t\tcurrentWebSocket.close();\n\t\t\t};\n\t\t\tcurrentWebSocket.close();\n\t\t}\n\n\t\t// Reset subscription states\n\t\tthis.subscriptions.forEach((subscription) => {\n\t\t\tsubscription.hasSentSubscribeMessage = false;\n\t\t});\n\n\t\t// Use exponential backoff before attempting to reconnect\n\t\tsetTimeout(() => {\n\t\t\tthis.webSocket = new WebSocket(this.wsUrl);\n\t\t}, delay);\n\t}\n}\n"]}
1
+ {"version":3,"file":"MultiplexWebSocket.js","sourceRoot":"","sources":["../../src/utils/MultiplexWebSocket.ts"],"names":[],"mappings":"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","sourcesContent":["import { Subject, Subscription, catchError } from 'rxjs';\nimport WebSocket, { MessageEvent } from 'isomorphic-ws';\n\ntype WebSocketMessage<T = Record<string, unknown>> = T;\n\ntype WebSocketSubscriptionProps<T = Record<string, unknown>> = {\n\twsUrl: string;\n\tsubscriptionId: string;\n\tsubscribeMessage: string;\n\tunsubscribeMessage: string;\n\tonError: (err?: any) => void;\n\tonMessage: (message: WebSocketMessage<T>) => void;\n\tmessageFilter?: (message: WebSocketMessage<T>) => boolean;\n\terrorMessageFilter?: (message: WebSocketMessage<T>) => boolean;\n\tonClose?: () => void;\n\tenableHeartbeatMonitoring?: boolean;\n\theartbeatTimeoutMs?: number;\n};\n\ntype WebSocketSubscriptionState<T = Record<string, unknown>> =\n\tWebSocketSubscriptionProps<T> & {\n\t\thasSentSubscribeMessage?: boolean;\n\t\tsubjectSubscription?: Subscription;\n\t};\n\ntype WebSocketUrl = string;\ntype SubscriptionId = string;\n\nconst DEFAULT_MAX_RECONNECT_ATTEMPTS = 5;\nconst DEFAULT_MAX_RECONNECT_WINDOW_MS = 60 * 1000;\nconst DEFAULT_CONNECTION_CLOSE_DELAY_MS = 2 * 1000; // 2 seconds delay before closing connection\nconst DEFAULT_HEARTBEAT_TIMEOUT_MS = 11 * 1000; // Consider connection dead if no heartbeat within 11 seconds (a little more than twice of 5 seconds, the interval Drift servers use)\n\n/**\n * Manages reconnection logic for WebSocket connections with exponential backoff and rate limiting.\n *\n * Features:\n * - Tracks reconnection attempts within a time window\n * - Implements exponential backoff (1s, 2s, 4s, 8s max)\n * - Resets attempt counter after configurable time window\n * - Throws error when max attempts exceeded\n * - Provides configurable limits for attempts and time window\n *\n * @example\n * ```ts\n * const manager = new ReconnectionManager(5, 60000); // 5 attempts in 60s\n * const { shouldReconnect, delay } = manager.attemptReconnection('ws://example.com');\n * if (shouldReconnect) {\n * setTimeout(() => reconnect(), delay);\n * }\n * ```\n */\nclass ReconnectionManager {\n\tprivate reconnectAttempts: number = 0;\n\tprivate lastReconnectWindow: number = Date.now();\n\tprivate maxAttemptsCount: number;\n\tprivate maxAttemptsWindowMs: number;\n\n\tconstructor(\n\t\tmaxAttemptsCount = DEFAULT_MAX_RECONNECT_ATTEMPTS,\n\t\tmaxAttemptsWindowMs = DEFAULT_MAX_RECONNECT_WINDOW_MS\n\t) {\n\t\tthis.maxAttemptsCount = maxAttemptsCount;\n\t\tthis.maxAttemptsWindowMs = maxAttemptsWindowMs;\n\t}\n\n\tpublic attemptReconnection(wsUrl: string): {\n\t\tshouldReconnect: boolean;\n\t\tdelay: number;\n\t} {\n\t\tconst now = Date.now();\n\n\t\t// Reset reconnect attempts if more than a minute has passed\n\t\tif (now - this.lastReconnectWindow > this.maxAttemptsWindowMs) {\n\t\t\tthis.reconnectAttempts = 0;\n\t\t\tthis.lastReconnectWindow = now;\n\t\t}\n\n\t\t// Check if we've exceeded the maximum reconnect attempts\n\t\tif (this.reconnectAttempts >= this.maxAttemptsCount) {\n\t\t\tthrow new Error(\n\t\t\t\t`WebSocket reconnection failed: Maximum reconnect attempts (${this.maxAttemptsCount}) exceeded within ${this.maxAttemptsWindowMs}ms for ${wsUrl}`\n\t\t\t);\n\t\t}\n\n\t\tthis.reconnectAttempts++;\n\n\t\t// Calculate exponential backoff delay: 1s, 2s, 4s, 8s, etc. (capped at 8s)\n\t\tconst backoffDelay = Math.min(\n\t\t\t1000 * Math.pow(2, this.reconnectAttempts - 1),\n\t\t\t8000\n\t\t);\n\n\t\treturn {\n\t\t\tshouldReconnect: true,\n\t\t\tdelay: backoffDelay,\n\t\t};\n\t}\n\n\tpublic reset(): void {\n\t\tthis.reconnectAttempts = 0;\n\t\tthis.lastReconnectWindow = Date.now();\n\t}\n}\n\nenum WebSocketConnectionState {\n\tCONNECTING,\n\tCONNECTED,\n\tDISCONNECTING,\n\tDISCONNECTED,\n}\n\ntype IMultiplexWebSocket<T = Record<string, unknown>> = {\n\twsUrl: WebSocketUrl;\n\twebSocket: WebSocket;\n\tcustomConnectionState: WebSocketConnectionState;\n\tsubject: Subject<WebSocketMessage<T>>;\n\tsubscriptions: Map<\n\t\tSubscriptionId,\n\t\tOmit<WebSocketSubscriptionProps<T>, 'wsUrl' | 'subscriptionId'>\n\t>;\n};\n\n/**\n * MultiplexWebSocket allows for multiple subscriptions to a single websocket of the same URL, improving efficiency and reducing the number of open connections.\n *\n * This implementation assumes the following:\n * - All websocket streams are treated equally - reconnection attempts are performed at the same standards\n * - All messages returned are in the `WebSocketMessage` format\n * - 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\n *\n * Internal implementation details:\n * - The websocket is closed when the number of subscriptions is 0\n * - The websocket will be refreshed (new instance) when it disconnects unexpectedly or errors, until it reaches the maximum number of reconnect attempts\n */\nexport class MultiplexWebSocket<T = Record<string, unknown>>\n\timplements IMultiplexWebSocket<T>\n{\n\t/**\n\t * A lookup of all websockets by their URL.\n\t */\n\tprivate static URL_TO_WEBSOCKETS_LOOKUP = new Map<\n\t\tWebSocketUrl,\n\t\tMultiplexWebSocket<any>\n\t>();\n\n\t/**\n\t * A lookup from websocket URL to all subscription IDs for that URL.\n\t */\n\tprivate static URL_TO_SUBSCRIPTION_IDS_LOOKUP = new Map<\n\t\tWebSocketUrl,\n\t\tSet<SubscriptionId>\n\t>();\n\n\twsUrl: WebSocketUrl;\n\t#webSocket: WebSocket;\n\tcustomConnectionState: WebSocketConnectionState;\n\tsubject: Subject<WebSocketMessage<T>>;\n\tsubscriptions: Map<\n\t\tSubscriptionId,\n\t\tOmit<WebSocketSubscriptionState<T>, 'wsUrl' | 'subscriptionId'>\n\t>;\n\tprivate reconnectionManager: ReconnectionManager;\n\tprivate closeTimeout: ReturnType<typeof setTimeout> | null = null;\n\tprivate heartbeatTimeout: ReturnType<typeof setTimeout> | null = null;\n\tprivate heartbeatMonitoringEnabled: boolean = false;\n\tprivate heartbeatTimeoutMs: number = DEFAULT_HEARTBEAT_TIMEOUT_MS;\n\n\tprivate constructor(\n\t\twsUrl: WebSocketUrl,\n\t\tenableHeartbeatMonitoring: boolean = false,\n\t\theartbeatTimeoutMs: number = DEFAULT_HEARTBEAT_TIMEOUT_MS\n\t) {\n\t\tif (MultiplexWebSocket.URL_TO_WEBSOCKETS_LOOKUP.has(wsUrl)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Attempting to create a new websocket for ${wsUrl}, but it already exists`\n\t\t\t);\n\t\t}\n\n\t\tthis.wsUrl = wsUrl;\n\t\tthis.customConnectionState = WebSocketConnectionState.CONNECTING;\n\t\tthis.subject = new Subject<WebSocketMessage<T>>();\n\t\tthis.subscriptions = new Map<\n\t\t\tSubscriptionId,\n\t\t\tOmit<WebSocketSubscriptionProps<T>, 'wsUrl' | 'subscriptionId'>\n\t\t>();\n\n\t\tthis.reconnectionManager = new ReconnectionManager();\n\t\tthis.heartbeatMonitoringEnabled = enableHeartbeatMonitoring;\n\t\tthis.heartbeatTimeoutMs = heartbeatTimeoutMs;\n\n\t\tthis.webSocket = new WebSocket(wsUrl);\n\n\t\tMultiplexWebSocket.URL_TO_WEBSOCKETS_LOOKUP.set(wsUrl, this);\n\t}\n\n\t/**\n\t * Creates a new virtual websocket subscription. If an existing websocket for the given URL exists, the subscription will be added to the existing websocket.\n\t * Returns a function that can be called to unsubscribe from the subscription.\n\t */\n\tpublic static createWebSocketSubscription<T = Record<string, unknown>>(\n\t\tprops: WebSocketSubscriptionProps<T>\n\t): { unsubscribe: () => void } {\n\t\tconst { wsUrl } = props;\n\n\t\tconst doesWebSocketForWsUrlExist =\n\t\t\tMultiplexWebSocket.URL_TO_WEBSOCKETS_LOOKUP.has(wsUrl);\n\n\t\tif (doesWebSocketForWsUrlExist) {\n\t\t\treturn this.handleNewSubForExistingWsUrl<T>(props);\n\t\t} else {\n\t\t\t// Create new websocket for new URL or reopen previously closed websocket\n\t\t\treturn this.handleNewSubForNewWsUrl<T>(props);\n\t\t}\n\t}\n\n\tprivate static handleNewSubForNewWsUrl<T = Record<string, unknown>>(\n\t\tnewSubscriptionProps: WebSocketSubscriptionProps<T>\n\t) {\n\t\tconst newMWS = new MultiplexWebSocket<T>(\n\t\t\tnewSubscriptionProps.wsUrl,\n\t\t\tnewSubscriptionProps.enableHeartbeatMonitoring ?? false,\n\t\t\tnewSubscriptionProps.heartbeatTimeoutMs ?? DEFAULT_HEARTBEAT_TIMEOUT_MS\n\t\t);\n\n\t\tnewMWS.subscribe(newSubscriptionProps);\n\n\t\treturn {\n\t\t\tunsubscribe: () => {\n\t\t\t\tnewMWS.unsubscribe(newSubscriptionProps.subscriptionId);\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate static handleNewSubForExistingWsUrl<T = Record<string, unknown>>(\n\t\tnewSubscriptionProps: WebSocketSubscriptionProps<T>\n\t) {\n\t\tconst { wsUrl, subscriptionId } = newSubscriptionProps;\n\n\t\tif (!MultiplexWebSocket.URL_TO_WEBSOCKETS_LOOKUP.has(wsUrl)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Attempting to subscribe to ${subscriptionId} on websocket ${wsUrl}, but websocket does not exist yet`\n\t\t\t);\n\t\t}\n\n\t\tconst existingMWS = MultiplexWebSocket.URL_TO_WEBSOCKETS_LOOKUP.get(\n\t\t\twsUrl\n\t\t) as MultiplexWebSocket<T>;\n\n\t\t// Check if heartbeat monitoring settings match\n\t\tconst requestedHeartbeat =\n\t\t\tnewSubscriptionProps.enableHeartbeatMonitoring ?? false;\n\t\tif (existingMWS.heartbeatMonitoringEnabled !== requestedHeartbeat) {\n\t\t\tconsole.warn(\n\t\t\t\t`WebSocket for ${wsUrl} already exists with heartbeat monitoring ${\n\t\t\t\t\texistingMWS.heartbeatMonitoringEnabled ? 'enabled' : 'disabled'\n\t\t\t\t}, ` +\n\t\t\t\t\t`but new subscription requests ${\n\t\t\t\t\t\trequestedHeartbeat ? 'enabled' : 'disabled'\n\t\t\t\t\t}. Using existing setting.`\n\t\t\t);\n\t\t}\n\n\t\t// Check if heartbeat timeout settings match for the same websocket URL (note that this assumes that all types of subscriptions from the same websocket URL are expected to have the same heartbeat interval)\n\t\tconst requestedTimeout =\n\t\t\tnewSubscriptionProps.heartbeatTimeoutMs ?? DEFAULT_HEARTBEAT_TIMEOUT_MS;\n\t\tif (existingMWS.heartbeatTimeoutMs !== requestedTimeout) {\n\t\t\tconsole.warn(\n\t\t\t\t`WebSocket for ${wsUrl} already exists with heartbeat timeout ${existingMWS.heartbeatTimeoutMs}ms, ` +\n\t\t\t\t\t`but new subscription requests ${requestedTimeout}ms. Using existing setting.`\n\t\t\t);\n\t\t}\n\n\t\t// Track new subscription for existing websocket\n\t\texistingMWS.subscribe(newSubscriptionProps);\n\n\t\treturn {\n\t\t\tunsubscribe: () => {\n\t\t\t\texistingMWS.unsubscribe(newSubscriptionProps.subscriptionId);\n\t\t\t},\n\t\t};\n\t}\n\n\tget webSocket() {\n\t\treturn this.#webSocket;\n\t}\n\n\t/**\n\t * Setting the WebSocket instance will automatically add event handlers to the WebSocket instance.\n\t * When the WebSocket is connected, all existing subscriptions will be subscribed to.\n\t */\n\tset webSocket(webSocket: WebSocket) {\n\t\twebSocket.onopen = () => {\n\t\t\tthis.customConnectionState = WebSocketConnectionState.CONNECTED;\n\t\t\tthis.reconnectionManager.reset(); // Reset reconnection attempts on successful connection\n\n\t\t\t// Start heartbeat monitoring if enabled\n\t\t\tif (this.heartbeatMonitoringEnabled) {\n\t\t\t\tthis.startHeartbeatMonitoring();\n\t\t\t}\n\n\t\t\t// sends subscription message for each subscription for those that are added before the websocket is connected\n\t\t\tfor (const [subscriptionId] of this.subscriptions.entries()) {\n\t\t\t\tthis.subscribeToWebSocket(subscriptionId);\n\t\t\t}\n\t\t};\n\n\t\twebSocket.onmessage = (messageEvent: MessageEvent) => {\n\t\t\tconst message = JSON.parse(\n\t\t\t\tmessageEvent.data as string\n\t\t\t) as WebSocketMessage<T>;\n\n\t\t\t// Check for heartbeat message from server (only if heartbeat monitoring is enabled)\n\t\t\tif (this.heartbeatMonitoringEnabled && this.isHeartbeatMessage(message)) {\n\t\t\t\tthis.handleHeartbeat(message);\n\t\t\t\treturn; // Don't forward heartbeat messages to subscriptions\n\t\t\t}\n\n\t\t\tthis.subject.next(message);\n\t\t};\n\n\t\twebSocket.onclose = (event) => {\n\t\t\tthis.customConnectionState = WebSocketConnectionState.DISCONNECTED;\n\n\t\t\t// Stop heartbeat monitoring when connection closes (if enabled)\n\t\t\tif (this.heartbeatMonitoringEnabled) {\n\t\t\t\tthis.stopHeartbeatMonitoring();\n\t\t\t}\n\n\t\t\t// Restart websocket if it was closed unexpectedly (not by us)\n\t\t\tif (!event.wasClean && this.subscriptions.size > 0) {\n\t\t\t\tconsole.log('WebSocket closed unexpectedly, restarting...', event);\n\t\t\t\tthis.refreshWebSocket();\n\t\t\t}\n\t\t};\n\n\t\twebSocket.onerror = (error) => {\n\t\t\tconsole.error('MultiplexWebSocket Error', { error, webSocket });\n\n\t\t\t// Forward error to all subscriptions for this websocket URL\n\t\t\tconst subscriptionIds =\n\t\t\t\tMultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.get(this.wsUrl);\n\t\t\tif (subscriptionIds) {\n\t\t\t\tfor (const subscriptionId of subscriptionIds) {\n\t\t\t\t\tconst subscription = this.subscriptions.get(subscriptionId);\n\t\t\t\t\tif (subscription) {\n\t\t\t\t\t\tsubscription.onError(error);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Note: onclose always fires after onerror, so reconnection is handled there\n\t\t\t// to avoid double-counting reconnection attempts.\n\t\t};\n\n\t\tthis.#webSocket = webSocket;\n\t}\n\n\tprivate subscribeToWebSocket(subscriptionId: SubscriptionId) {\n\t\tconst subscriptionState = this.subscriptions.get(subscriptionId);\n\n\t\tconst {\n\t\t\tsubscribeMessage,\n\t\t\tonError,\n\t\t\tonMessage,\n\t\t\tmessageFilter,\n\t\t\terrorMessageFilter,\n\t\t\tonClose,\n\t\t} = subscriptionState;\n\n\t\tthis.webSocket.send(subscribeMessage);\n\t\tif (subscriptionState) {\n\t\t\tsubscriptionState.hasSentSubscribeMessage = true;\n\t\t}\n\n\t\t// Create internal subscription for message handling\n\t\tconst subjectSubscription = this.subject\n\t\t\t.pipe(\n\t\t\t\tcatchError((err) => {\n\t\t\t\t\tconsole.error('Caught websocket error', err);\n\t\t\t\t\tonError();\n\t\t\t\t\treturn [];\n\t\t\t\t})\n\t\t\t)\n\t\t\t.subscribe({\n\t\t\t\tnext: (message: WebSocketMessage<T>) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (messageFilter && !messageFilter(message)) return;\n\n\t\t\t\t\t\tif (errorMessageFilter && errorMessageFilter(message)) {\n\t\t\t\t\t\t\tonError();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tonMessage(message);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.error('Error parsing websocket message', err);\n\t\t\t\t\t\tonError();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\terror: (err) => {\n\t\t\t\t\tconsole.error('Error subscribing to websocket', err);\n\t\t\t\t\tonError();\n\t\t\t\t},\n\t\t\t\tcomplete: () => {\n\t\t\t\t\tif (onClose) {\n\t\t\t\t\t\tonClose();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\tsubscriptionState.subjectSubscription = subjectSubscription;\n\t}\n\n\tprivate subscribe(props: WebSocketSubscriptionProps<T>) {\n\t\tconst {\n\t\t\tsubscriptionId,\n\t\t\tsubscribeMessage,\n\t\t\tunsubscribeMessage,\n\t\t\tonError,\n\t\t\tonMessage,\n\t\t\tmessageFilter,\n\t\t\terrorMessageFilter,\n\t\t\tonClose,\n\t\t} = props;\n\n\t\tif (this.subscriptions.get(subscriptionId)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Attempting to subscribe to ${subscriptionId} on websocket ${this.wsUrl}, but subscription already exists`\n\t\t\t);\n\t\t}\n\n\t\t// Cancel any pending delayed close since we're adding a new subscription\n\t\tthis.cancelDelayedClose();\n\n\t\tthis.subscriptions.set(subscriptionId, {\n\t\t\tsubscribeMessage,\n\t\t\tunsubscribeMessage,\n\t\t\tonError,\n\t\t\tonMessage,\n\t\t\tmessageFilter,\n\t\t\terrorMessageFilter,\n\t\t\tonClose,\n\t\t\thasSentSubscribeMessage: false,\n\t\t});\n\n\t\t// Update URL to subscription IDs lookup\n\t\tif (!MultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.has(this.wsUrl)) {\n\t\t\tMultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.set(\n\t\t\t\tthis.wsUrl,\n\t\t\t\tnew Set()\n\t\t\t);\n\t\t}\n\t\tMultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.get(this.wsUrl)!.add(\n\t\t\tsubscriptionId\n\t\t);\n\n\t\tif (this.customConnectionState === WebSocketConnectionState.CONNECTED) {\n\t\t\tthis.subscribeToWebSocket(subscriptionId);\n\t\t} else if (\n\t\t\tthis.customConnectionState === WebSocketConnectionState.CONNECTING\n\t\t) {\n\t\t\t// do nothing, subscription will automatically start when websocket is connected\n\t\t} else {\n\t\t\t// handle case where websocket is disconnecting/disconnected\n\t\t\tthis.refreshWebSocket();\n\t\t}\n\t}\n\n\tprivate unsubscribe(subscriptionId: SubscriptionId) {\n\t\tconst subscriptionState = this.subscriptions.get(subscriptionId);\n\t\tif (subscriptionState) {\n\t\t\tsubscriptionState.subjectSubscription?.unsubscribe();\n\n\t\t\t// Only send unsubscribe message if websocket is connected and ready to send.\n\t\t\t//// Otherwise, when the websocket DOES connect we don't have to worry about this subscription because we are deleting it from the subscriptions map. (Which only trigger their connections once the websocket becomes connected)\n\t\t\tif (\n\t\t\t\tthis.customConnectionState === WebSocketConnectionState.CONNECTED &&\n\t\t\t\tthis.webSocket.readyState === WebSocket.OPEN\n\t\t\t) {\n\t\t\t\tthis.webSocket.send(subscriptionState.unsubscribeMessage);\n\t\t\t}\n\n\t\t\tthis.subscriptions.delete(subscriptionId);\n\n\t\t\t// Update URL to subscription IDs lookup\n\t\t\tconst subscriptionIds =\n\t\t\t\tMultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.get(this.wsUrl);\n\t\t\tif (subscriptionIds) {\n\t\t\t\tsubscriptionIds.delete(subscriptionId);\n\t\t\t\tif (subscriptionIds.size === 0) {\n\t\t\t\t\tMultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.delete(this.wsUrl);\n\t\t\t\t\t// Schedule delayed close when last subscriber unsubscribes\n\t\t\t\t\tthis.scheduleDelayedClose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate scheduleDelayedClose() {\n\t\t// Cancel any existing delayed close timeout\n\t\tthis.cancelDelayedClose();\n\n\t\t// Schedule new delayed close\n\t\tthis.closeTimeout = setTimeout(() => {\n\t\t\tthis.close();\n\t\t}, DEFAULT_CONNECTION_CLOSE_DELAY_MS);\n\t}\n\n\tprivate cancelDelayedClose() {\n\t\tif (this.closeTimeout) {\n\t\t\tclearTimeout(this.closeTimeout);\n\t\t\tthis.closeTimeout = null;\n\t\t}\n\t}\n\n\tprivate close() {\n\t\t// Cancel any pending delayed close\n\t\tthis.cancelDelayedClose();\n\n\t\t// Stop heartbeat monitoring (if enabled)\n\t\tif (this.heartbeatMonitoringEnabled) {\n\t\t\tthis.stopHeartbeatMonitoring();\n\t\t}\n\n\t\tfor (const [subscriptionId] of this.subscriptions.entries()) {\n\t\t\tthis.unsubscribe(subscriptionId);\n\t\t}\n\n\t\tthis.subscriptions.clear();\n\t\tthis.webSocket.close();\n\t\tMultiplexWebSocket.URL_TO_WEBSOCKETS_LOOKUP.delete(this.wsUrl);\n\t\tMultiplexWebSocket.URL_TO_SUBSCRIPTION_IDS_LOOKUP.delete(this.wsUrl);\n\t\tthis.reconnectionManager.reset();\n\t}\n\n\tprivate startHeartbeatMonitoring() {\n\t\t// Start the heartbeat timeout - if we don't receive a heartbeat message within the timeout, refresh connection\n\t\tthis.resetHeartbeatTimeout();\n\t}\n\n\tprivate stopHeartbeatMonitoring() {\n\t\tif (this.heartbeatTimeout) {\n\t\t\tclearTimeout(this.heartbeatTimeout);\n\t\t\tthis.heartbeatTimeout = null;\n\t\t}\n\t}\n\n\tprivate resetHeartbeatTimeout() {\n\t\t// Clear existing timeout\n\t\tif (this.heartbeatTimeout) {\n\t\t\tclearTimeout(this.heartbeatTimeout);\n\t\t}\n\n\t\t// Set new timeout\n\t\tthis.heartbeatTimeout = setTimeout(() => {\n\t\t\tconsole.warn(\n\t\t\t\t`No heartbeat received within ${this.heartbeatTimeoutMs}ms - connection appears dead`\n\t\t\t);\n\t\t\tthis.refreshWebSocket();\n\t\t}, this.heartbeatTimeoutMs);\n\t}\n\n\tprivate isHeartbeatMessage(message: WebSocketMessage<T>): boolean {\n\t\t// Check if message is a heartbeat message from server\n\t\treturn (message as any)?.channel === 'heartbeat';\n\t}\n\n\tprivate handleHeartbeat(_message: WebSocketMessage<T>) {\n\t\t// Reset the heartbeat timeout\n\t\tthis.resetHeartbeatTimeout();\n\t}\n\n\tprivate refreshWebSocket() {\n\t\t// Cancel any pending delayed close since we're refreshing\n\t\tthis.cancelDelayedClose();\n\n\t\t// Reset heartbeat monitoring during refresh (if enabled) - it will restart when the new connection opens\n\t\tif (this.heartbeatMonitoringEnabled) {\n\t\t\tthis.stopHeartbeatMonitoring();\n\t\t}\n\n\t\tlet shouldReconnect: boolean;\n\t\tlet delay: number;\n\n\t\ttry {\n\t\t\t({ shouldReconnect, delay } =\n\t\t\t\tthis.reconnectionManager.attemptReconnection(this.wsUrl));\n\t\t} catch (error) {\n\t\t\t// Max reconnect attempts exceeded — close gracefully and notify all subscribers\n\t\t\tconsole.error('WebSocket reconnection failed', error);\n\n\t\t\t// Forward error to all subscriptions before closing\n\t\t\tfor (const [, subscription] of this.subscriptions.entries()) {\n\t\t\t\tsubscription.onError(error);\n\t\t\t}\n\n\t\t\tthis.close();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!shouldReconnect) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clean up current websocket\n\t\tconst currentWebSocket = this.webSocket;\n\t\tif (currentWebSocket) {\n\t\t\tcurrentWebSocket.onerror = () => {};\n\t\t\tcurrentWebSocket.onclose = () => {};\n\t\t\tcurrentWebSocket.onmessage = () => {};\n\t\t\tcurrentWebSocket.onopen = () => {\n\t\t\t\t// in the event where the websocket has yet to connect, we close the connection after it is connected\n\t\t\t\tcurrentWebSocket.close();\n\t\t\t};\n\t\t\tcurrentWebSocket.close();\n\t\t}\n\n\t\t// Reset subscription states\n\t\tthis.subscriptions.forEach((subscription) => {\n\t\t\tsubscription.hasSentSubscribeMessage = false;\n\t\t});\n\n\t\t// Use exponential backoff before attempting to reconnect\n\t\tsetTimeout(() => {\n\t\t\tthis.webSocket = new WebSocket(this.wsUrl);\n\t\t}, delay);\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/common",
3
- "version": "1.0.52",
3
+ "version": "1.0.54",
4
4
  "description": "Common functions for Drift",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",