@drift-labs/common 1.0.12 → 1.0.14
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.
- package/lib/clients/DlobWebsocketClient.d.ts +81 -0
- package/lib/clients/DlobWebsocketClient.js +226 -0
- package/lib/clients/DlobWebsocketClient.js.map +1 -0
- package/lib/clients/swiftClient.js +1 -0
- package/lib/clients/swiftClient.js.map +1 -1
- package/lib/common-ui-utils/commonUiUtils.d.ts +1 -1
- package/lib/common-ui-utils/trading.d.ts +1 -1
- package/lib/common-ui-utils/trading.js +2 -1
- package/lib/common-ui-utils/trading.js.map +1 -1
- package/lib/common-ui-utils/user.js +4 -3
- package/lib/common-ui-utils/user.js.map +1 -1
- package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/index.d.ts +20 -2
- package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/index.js +32 -0
- package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/index.js.map +1 -1
- package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/types.d.ts +31 -1
- package/lib/drift/Drift/clients/AuthorityDrift/DriftOperations/types.js.map +1 -1
- package/lib/drift/Drift/clients/AuthorityDrift/index.d.ts +10 -2
- package/lib/drift/Drift/clients/AuthorityDrift/index.js +12 -0
- package/lib/drift/Drift/clients/AuthorityDrift/index.js.map +1 -1
- package/lib/drift/base/actions/builder/createRevenueShareAccount.d.ts +62 -0
- package/lib/drift/base/actions/builder/createRevenueShareAccount.js +59 -0
- package/lib/drift/base/actions/builder/createRevenueShareAccount.js.map +1 -0
- package/lib/drift/base/actions/builder/createRevenueShareEscrow.d.ts +126 -0
- package/lib/drift/base/actions/builder/createRevenueShareEscrow.js +114 -0
- package/lib/drift/base/actions/builder/createRevenueShareEscrow.js.map +1 -0
- package/lib/drift/base/actions/builder/index.d.ts +3 -0
- package/lib/drift/base/actions/builder/index.js +20 -0
- package/lib/drift/base/actions/builder/index.js.map +1 -0
- package/lib/drift/base/actions/builder/manageBuilder.d.ts +157 -0
- package/lib/drift/base/actions/builder/manageBuilder.js +139 -0
- package/lib/drift/base/actions/builder/manageBuilder.js.map +1 -0
- package/lib/drift/base/actions/index.d.ts +1 -0
- package/lib/drift/base/actions/index.js +1 -0
- package/lib/drift/base/actions/index.js.map +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/dlobServer/index.d.ts +0 -5
- package/lib/drift/base/actions/trade/openPerpOrder/dlobServer/index.js.map +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/openPerpMarketOrder/index.d.ts +29 -1
- package/lib/drift/base/actions/trade/openPerpOrder/openPerpMarketOrder/index.js +2 -1
- package/lib/drift/base/actions/trade/openPerpOrder/openPerpMarketOrder/index.js.map +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/openPerpNonMarketOrder/index.d.ts +8 -0
- package/lib/drift/base/actions/trade/openPerpOrder/openPerpNonMarketOrder/index.js +1 -0
- package/lib/drift/base/actions/trade/openPerpOrder/openPerpNonMarketOrder/index.js.map +1 -1
- package/lib/drift/base/actions/trade/openPerpOrder/openSwiftOrder/index.d.ts +56 -2
- package/lib/drift/base/actions/trade/openPerpOrder/openSwiftOrder/index.js +9 -3
- package/lib/drift/base/actions/trade/openPerpOrder/openSwiftOrder/index.js.map +1 -1
- package/lib/drift/base/constants/index.d.ts +2 -0
- package/lib/drift/base/constants/index.js +19 -0
- package/lib/drift/base/constants/index.js.map +1 -0
- package/lib/drift/index.d.ts +1 -0
- package/lib/drift/index.js +1 -0
- package/lib/drift/index.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/utils/MultiplexWebSocket.d.ts +4 -2
- package/lib/utils/MultiplexWebSocket.js +18 -9
- package/lib/utils/MultiplexWebSocket.js.map +1 -1
- package/lib/utils/ResultSlotIncrementer.d.ts +31 -0
- package/lib/utils/ResultSlotIncrementer.js +83 -0
- package/lib/utils/ResultSlotIncrementer.js.map +1 -0
- package/lib/utils/index.d.ts +3 -1
- package/lib/utils/index.js +7 -1
- package/lib/utils/index.js.map +1 -1
- package/lib/utils/math.js +1 -1
- package/lib/utils/math.js.map +1 -1
- package/lib/utils/signedMsgs.d.ts +1 -0
- package/lib/utils/signedMsgs.js +10 -0
- package/lib/utils/signedMsgs.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiplexWebSocket.js","sourceRoot":"","sources":["../../src/utils/MultiplexWebSocket.ts"],"names":[],"mappings":"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","sourcesContent":["import { Subject, catchError, Subscription } 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};\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 = 60 * 1000; // Consider connection dead if no heartbeat within 60 seconds\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\n\tprivate constructor(\n\t\twsUrl: WebSocketUrl,\n\t\tenableHeartbeatMonitoring: boolean = false\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\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);\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// 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// Restart the websocket connection on error\n\t\t\tthis.refreshWebSocket();\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\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(message)) return;\n\n\t\t\t\t\t\tif (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 ${DEFAULT_HEARTBEAT_TIMEOUT_MS}ms - connection appears dead`\n\t\t\t);\n\t\t\tthis.refreshWebSocket();\n\t\t}, DEFAULT_HEARTBEAT_TIMEOUT_MS);\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\tconst { shouldReconnect, delay } =\n\t\t\tthis.reconnectionManager.attemptReconnection(this.wsUrl);\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: 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// Restart the websocket connection on error\n\t\t\tthis.refreshWebSocket();\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\tconst { shouldReconnect, delay } =\n\t\t\tthis.reconnectionManager.attemptReconnection(this.wsUrl);\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"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility class which makes sure that all results with a slot are only accepted if the slot is higher than the previous result
|
|
3
|
+
* Enhanced to handle tab return scenarios and prevent "speed run" through queued messages
|
|
4
|
+
*/
|
|
5
|
+
export declare class ResultSlotIncrementer {
|
|
6
|
+
private resultIncrements;
|
|
7
|
+
private tabReturnTimestamp;
|
|
8
|
+
private isInTabReturnMode;
|
|
9
|
+
private tabReturnDebounceMs;
|
|
10
|
+
private maxSlotJumpThreshold;
|
|
11
|
+
/**
|
|
12
|
+
* Call this when the tab returns from being inactive to enable enhanced filtering
|
|
13
|
+
*/
|
|
14
|
+
handleTabReturn(): void;
|
|
15
|
+
/**
|
|
16
|
+
* Check if we should reset state due to a large slot jump (indicating queued messages)
|
|
17
|
+
*/
|
|
18
|
+
private shouldResetDueToSlotJump;
|
|
19
|
+
/**
|
|
20
|
+
* Enhanced result handler that deals with tab return scenarios
|
|
21
|
+
*/
|
|
22
|
+
handleResult(key: string | symbol, slot: number, messageTimestamp?: number): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Reset slot tracking for a specific key (useful when reestablishing connections)
|
|
25
|
+
*/
|
|
26
|
+
resetKey(key: string | symbol): void;
|
|
27
|
+
/**
|
|
28
|
+
* Configure the tab return behavior
|
|
29
|
+
*/
|
|
30
|
+
configureTabReturn(debounceMs: number, slotJumpThreshold: number): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ResultSlotIncrementer = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Utility class which makes sure that all results with a slot are only accepted if the slot is higher than the previous result
|
|
6
|
+
* Enhanced to handle tab return scenarios and prevent "speed run" through queued messages
|
|
7
|
+
*/
|
|
8
|
+
class ResultSlotIncrementer {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.resultIncrements = new Map();
|
|
11
|
+
this.tabReturnTimestamp = null;
|
|
12
|
+
this.isInTabReturnMode = false;
|
|
13
|
+
this.tabReturnDebounceMs = 2000; // 2 seconds to filter old messages after tab return
|
|
14
|
+
this.maxSlotJumpThreshold = 100; // If slot jumps by more than this, consider it a "speed run" scenario
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Call this when the tab returns from being inactive to enable enhanced filtering
|
|
18
|
+
*/
|
|
19
|
+
handleTabReturn() {
|
|
20
|
+
this.tabReturnTimestamp = Date.now();
|
|
21
|
+
this.isInTabReturnMode = true;
|
|
22
|
+
// Auto-disable tab return mode after debounce period
|
|
23
|
+
setTimeout(() => {
|
|
24
|
+
this.isInTabReturnMode = false;
|
|
25
|
+
this.tabReturnTimestamp = null;
|
|
26
|
+
}, this.tabReturnDebounceMs);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if we should reset state due to a large slot jump (indicating queued messages)
|
|
30
|
+
*/
|
|
31
|
+
shouldResetDueToSlotJump(key, slot) {
|
|
32
|
+
const previous = this.resultIncrements.get(key);
|
|
33
|
+
if (!previous)
|
|
34
|
+
return false;
|
|
35
|
+
const slotJump = slot - previous;
|
|
36
|
+
return slotJump > this.maxSlotJumpThreshold;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Enhanced result handler that deals with tab return scenarios
|
|
40
|
+
*/
|
|
41
|
+
handleResult(key, slot, messageTimestamp) {
|
|
42
|
+
if (slot === undefined) {
|
|
43
|
+
console.warn('Caught undefined slot in ResultSlotIncrementer');
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
// If we're in tab return mode, be more aggressive about filtering
|
|
47
|
+
if (this.isInTabReturnMode && this.tabReturnTimestamp) {
|
|
48
|
+
// If message timestamp is available and it's older than when tab returned, skip it
|
|
49
|
+
if (messageTimestamp && messageTimestamp < this.tabReturnTimestamp) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
// Check for large slot jumps that indicate queued messages
|
|
53
|
+
if (this.shouldResetDueToSlotJump(key, slot)) {
|
|
54
|
+
// Reset the previous slot to current - 1 so this message passes
|
|
55
|
+
// This effectively "jumps" to the latest state
|
|
56
|
+
this.resultIncrements.set(key, slot - 1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const previous = this.resultIncrements.get(key);
|
|
60
|
+
if (!previous || slot >= previous) {
|
|
61
|
+
this.resultIncrements.set(key, slot);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Reset slot tracking for a specific key (useful when reestablishing connections)
|
|
70
|
+
*/
|
|
71
|
+
resetKey(key) {
|
|
72
|
+
this.resultIncrements.delete(key);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Configure the tab return behavior
|
|
76
|
+
*/
|
|
77
|
+
configureTabReturn(debounceMs, slotJumpThreshold) {
|
|
78
|
+
this.tabReturnDebounceMs = debounceMs;
|
|
79
|
+
this.maxSlotJumpThreshold = slotJumpThreshold;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.ResultSlotIncrementer = ResultSlotIncrementer;
|
|
83
|
+
//# sourceMappingURL=ResultSlotIncrementer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResultSlotIncrementer.js","sourceRoot":"","sources":["../../src/utils/ResultSlotIncrementer.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,MAAa,qBAAqB;IAAlC;QACS,qBAAgB,GAAG,IAAI,GAAG,EAA2B,CAAC;QACtD,uBAAkB,GAAkB,IAAI,CAAC;QACzC,sBAAiB,GAAG,KAAK,CAAC;QAC1B,wBAAmB,GAAG,IAAI,CAAC,CAAC,oDAAoD;QAChF,yBAAoB,GAAG,GAAG,CAAC,CAAC,sEAAsE;IA8E3G,CAAC;IA5EA;;OAEG;IACH,eAAe;QACd,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACrC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAE9B,qDAAqD;QACrD,UAAU,CAAC,GAAG,EAAE;YACf,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;YAC/B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAChC,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACK,wBAAwB,CAC/B,GAAoB,EACpB,IAAY;QAEZ,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChD,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAE5B,MAAM,QAAQ,GAAG,IAAI,GAAG,QAAQ,CAAC;QACjC,OAAO,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,GAAoB,EAAE,IAAY,EAAE,gBAAyB;QACzE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC;QACb,CAAC;QAED,kEAAkE;QAClE,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACvD,mFAAmF;YACnF,IAAI,gBAAgB,IAAI,gBAAgB,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACpE,OAAO,KAAK,CAAC;YACd,CAAC;YAED,2DAA2D;YAC3D,IAAI,IAAI,CAAC,wBAAwB,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;gBAC9C,gEAAgE;gBAChE,+CAA+C;gBAC/C,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;YAC1C,CAAC;QACF,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEhD,IAAI,CAAC,QAAQ,IAAI,IAAI,IAAI,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACrC,OAAO,IAAI,CAAC;QACb,CAAC;aAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,GAAoB;QAC5B,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,UAAkB,EAAE,iBAAyB;QAC/D,IAAI,CAAC,mBAAmB,GAAG,UAAU,CAAC;QACtC,IAAI,CAAC,oBAAoB,GAAG,iBAAiB,CAAC;IAC/C,CAAC;CACD;AAnFD,sDAmFC","sourcesContent":["/**\n * Utility class which makes sure that all results with a slot are only accepted if the slot is higher than the previous result\n * Enhanced to handle tab return scenarios and prevent \"speed run\" through queued messages\n */\nexport class ResultSlotIncrementer {\n\tprivate resultIncrements = new Map<string | symbol, number>();\n\tprivate tabReturnTimestamp: number | null = null;\n\tprivate isInTabReturnMode = false;\n\tprivate tabReturnDebounceMs = 2000; // 2 seconds to filter old messages after tab return\n\tprivate maxSlotJumpThreshold = 100; // If slot jumps by more than this, consider it a \"speed run\" scenario\n\n\t/**\n\t * Call this when the tab returns from being inactive to enable enhanced filtering\n\t */\n\thandleTabReturn() {\n\t\tthis.tabReturnTimestamp = Date.now();\n\t\tthis.isInTabReturnMode = true;\n\n\t\t// Auto-disable tab return mode after debounce period\n\t\tsetTimeout(() => {\n\t\t\tthis.isInTabReturnMode = false;\n\t\t\tthis.tabReturnTimestamp = null;\n\t\t}, this.tabReturnDebounceMs);\n\t}\n\n\t/**\n\t * Check if we should reset state due to a large slot jump (indicating queued messages)\n\t */\n\tprivate shouldResetDueToSlotJump(\n\t\tkey: string | symbol,\n\t\tslot: number\n\t): boolean {\n\t\tconst previous = this.resultIncrements.get(key);\n\t\tif (!previous) return false;\n\n\t\tconst slotJump = slot - previous;\n\t\treturn slotJump > this.maxSlotJumpThreshold;\n\t}\n\n\t/**\n\t * Enhanced result handler that deals with tab return scenarios\n\t */\n\thandleResult(key: string | symbol, slot: number, messageTimestamp?: number) {\n\t\tif (slot === undefined) {\n\t\t\tconsole.warn('Caught undefined slot in ResultSlotIncrementer');\n\t\t\treturn true;\n\t\t}\n\n\t\t// If we're in tab return mode, be more aggressive about filtering\n\t\tif (this.isInTabReturnMode && this.tabReturnTimestamp) {\n\t\t\t// If message timestamp is available and it's older than when tab returned, skip it\n\t\t\tif (messageTimestamp && messageTimestamp < this.tabReturnTimestamp) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Check for large slot jumps that indicate queued messages\n\t\t\tif (this.shouldResetDueToSlotJump(key, slot)) {\n\t\t\t\t// Reset the previous slot to current - 1 so this message passes\n\t\t\t\t// This effectively \"jumps\" to the latest state\n\t\t\t\tthis.resultIncrements.set(key, slot - 1);\n\t\t\t}\n\t\t}\n\n\t\tconst previous = this.resultIncrements.get(key);\n\n\t\tif (!previous || slot >= previous) {\n\t\t\tthis.resultIncrements.set(key, slot);\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Reset slot tracking for a specific key (useful when reestablishing connections)\n\t */\n\tresetKey(key: string | symbol) {\n\t\tthis.resultIncrements.delete(key);\n\t}\n\n\t/**\n\t * Configure the tab return behavior\n\t */\n\tconfigureTabReturn(debounceMs: number, slotJumpThreshold: number) {\n\t\tthis.tabReturnDebounceMs = debounceMs;\n\t\tthis.maxSlotJumpThreshold = slotJumpThreshold;\n\t}\n}\n"]}
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -178,4 +178,6 @@ export declare const COMMON_UTILS: {
|
|
|
178
178
|
};
|
|
179
179
|
};
|
|
180
180
|
};
|
|
181
|
-
export {};
|
|
181
|
+
export { getSwiftConfirmationTimeoutMs } from './signedMsgs';
|
|
182
|
+
export { ResultSlotIncrementer } from './ResultSlotIncrementer';
|
|
183
|
+
export { MultiplexWebSocket } from './MultiplexWebSocket';
|
package/lib/utils/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.COMMON_UTILS = exports.getTieredSortScore = exports.aprFromApy = exports.MultiSwitch = exports.Counter = exports.Ref = exports.getAnchorEnumString = exports.orderIsNull = exports.getPriceForUIOrderRecord = exports.getPriceForOrderRecord = exports.getPriceForBaseAndQuoteAmount = exports.filterTradeRecordsFromUIOrderRecords = exports.filterTradeRecordsFromOrderActionRecords = exports.uiOrderActionRecordIsTrade = exports.orderActionRecordIsTrade = exports.getUIOrderRecordsLaterThanTarget = exports.getLatestOfTwoOrderRecords = exports.getLatestOfTwoUIOrderRecords = exports.sortOrderRecords = exports.sortUIOrderRecords = exports.sortUIOrderActionRecords = exports.sortUIMatchedOrderRecordAndAction = exports.getSortScoreForOrderActionRecords = exports.getTradeInfoFromActionRecord = exports.getSortScoreForOrderRecords = exports.decodeStringifiableObject = exports.encodeStringifiableObject = exports.sleep = exports.ENUM_UTILS = exports.matchEnum = void 0;
|
|
3
|
+
exports.MultiplexWebSocket = exports.ResultSlotIncrementer = exports.getSwiftConfirmationTimeoutMs = exports.COMMON_UTILS = exports.getTieredSortScore = exports.aprFromApy = exports.MultiSwitch = exports.Counter = exports.Ref = exports.getAnchorEnumString = exports.orderIsNull = exports.getPriceForUIOrderRecord = exports.getPriceForOrderRecord = exports.getPriceForBaseAndQuoteAmount = exports.filterTradeRecordsFromUIOrderRecords = exports.filterTradeRecordsFromOrderActionRecords = exports.uiOrderActionRecordIsTrade = exports.orderActionRecordIsTrade = exports.getUIOrderRecordsLaterThanTarget = exports.getLatestOfTwoOrderRecords = exports.getLatestOfTwoUIOrderRecords = exports.sortOrderRecords = exports.sortUIOrderRecords = exports.sortUIOrderActionRecords = exports.sortUIMatchedOrderRecordAndAction = exports.getSortScoreForOrderActionRecords = exports.getTradeInfoFromActionRecord = exports.getSortScoreForOrderRecords = exports.decodeStringifiableObject = exports.encodeStringifiableObject = exports.sleep = exports.ENUM_UTILS = exports.matchEnum = void 0;
|
|
4
4
|
const sdk_1 = require("@drift-labs/sdk");
|
|
5
5
|
const insuranceFund_1 = require("./insuranceFund");
|
|
6
6
|
const matchEnum = (enum1, enum2) => {
|
|
@@ -605,4 +605,10 @@ exports.COMMON_UTILS = {
|
|
|
605
605
|
},
|
|
606
606
|
},
|
|
607
607
|
};
|
|
608
|
+
var signedMsgs_1 = require("./signedMsgs");
|
|
609
|
+
Object.defineProperty(exports, "getSwiftConfirmationTimeoutMs", { enumerable: true, get: function () { return signedMsgs_1.getSwiftConfirmationTimeoutMs; } });
|
|
610
|
+
var ResultSlotIncrementer_1 = require("./ResultSlotIncrementer");
|
|
611
|
+
Object.defineProperty(exports, "ResultSlotIncrementer", { enumerable: true, get: function () { return ResultSlotIncrementer_1.ResultSlotIncrementer; } });
|
|
612
|
+
var MultiplexWebSocket_1 = require("./MultiplexWebSocket");
|
|
613
|
+
Object.defineProperty(exports, "MultiplexWebSocket", { enumerable: true, get: function () { return MultiplexWebSocket_1.MultiplexWebSocket; } });
|
|
608
614
|
//# sourceMappingURL=index.js.map
|
package/lib/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tAMM_RESERVE_PRECISION_EXP,\n\tBASE_PRECISION,\n\tBN,\n\tEvent,\n\tPRICE_PRECISION,\n\tOrderAction,\n\tOrderActionRecord,\n\tOrderRecord,\n\tPublicKey,\n\tQUOTE_PRECISION,\n\tZERO,\n\tPRICE_PRECISION_EXP,\n\tBASE_PRECISION_EXP,\n\tBigNum,\n\tMarketType,\n\tDriftClient,\n\tSPOT_MARKET_RATE_PRECISION_EXP,\n\tcalculateDepositRate,\n\tcalculateBorrowRate,\n\tgetTokenAmount,\n\tSpotBalanceType,\n\tSpotMarketConfig,\n} from '@drift-labs/sdk';\nimport {\n\tUIMatchedOrderRecordAndAction,\n\tUISerializableOrderActionRecord,\n} from '../serializableTypes';\nimport { getIfStakingVaultApr, getIfVaultBalance } from './insuranceFund';\nimport { AccountInfo, Connection } from '@solana/web3.js';\n\nexport const matchEnum = (enum1: any, enum2) => {\n\treturn JSON.stringify(enum1) === JSON.stringify(enum2);\n};\n\nfunction enumToObj(enumStr: string) {\n\tif (!enumStr) return undefined;\n\n\treturn {\n\t\t[enumStr ?? '']: {},\n\t};\n}\n\nfunction enumToStr(enumStr: Record<string, any>) {\n\treturn Object.keys(enumStr ?? {})?.[0];\n}\n\nexport const ENUM_UTILS = {\n\tmatch: matchEnum,\n\ttoObj: enumToObj,\n\ttoStr: enumToStr,\n};\n\nexport async function sleep(ms) {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\nconst getStringifiableObjectEntry = (value: any): [any, string] => {\n\t// If BN\n\t// if (value instanceof BN) { /* This method would be much safer but don't think it's possible to ensure that instances of classes match when they're in different npm packages */\n\tif (Object.keys(value).sort().join(',') === 'length,negative,red,words') {\n\t\treturn [value.toString(), '_bgnm_'];\n\t}\n\n\t// If PublicKey\n\t// if (value instanceof PublicKey) { { /* This method would be much safer but don't think it's possible to ensure that instances of classes match when they're in different npm packages */\n\tif (Object.keys(value).sort().join(',') === '_bn') {\n\t\treturn [value.toString(), '_pbky_'];\n\t}\n\n\tif (typeof value === 'object') {\n\t\treturn [encodeStringifiableObject(value), ''];\n\t}\n\n\treturn [value, ''];\n};\n\n/**\n * Converts an objects with potential Pubkeys and BNs in it into a form that can be JSON stringified. When pubkeys get converted a _pbky_ suffix will be added to their key, and _bgnm_ for BNs.\n *\n * e.g.\n * input : {\n * QuoteAmount: BN\n * }\n *\n * output: {\n * _bgnm_QuoteAmount: string\n * }\n * @param value\n * @returns\n */\nexport const encodeStringifiableObject = (value: any) => {\n\tif (typeof value !== 'object') return value;\n\n\tif (Array.isArray(value)) {\n\t\treturn value.map((entry) => encodeStringifiableObject(entry));\n\t}\n\n\tconst buildJsonObject = {};\n\n\tif (!value) return value;\n\n\tObject.entries(value).forEach(([key, val]) => {\n\t\tconst [convertedVal, keyTag] = getStringifiableObjectEntry(val);\n\t\tbuildJsonObject[`${keyTag}${key}`] = convertedVal;\n\t});\n\n\treturn buildJsonObject;\n};\n\n/**\n * Converts a parsed object with potential Pubkeys and BNs in it (in string form) to their proper form. Pubkey values must have a key starting in _pbky_ and BN values must have a key starting in _bnnm_\n *\n * * e.g.\n * input : {\n * _bgnm_QuoteAmount: string\n * }\n *\n * output: {\n * QuoteAmount: BN\n * }\n * @param value\n * @returns\n */\nexport const decodeStringifiableObject = (value: any) => {\n\tif (typeof value !== 'object') return value;\n\n\tif (Array.isArray(value)) {\n\t\treturn value.map((entry) => decodeStringifiableObject(entry));\n\t}\n\n\tconst buildJsonObject = {};\n\n\tObject.entries(value)\n\t\t.filter((val) => val != undefined && val != null)\n\t\t.forEach(([key, val]) => {\n\t\t\tif (key.match(/^_pbky_/)) {\n\t\t\t\tbuildJsonObject[key.replace('_pbky_', '')] = new PublicKey(val);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (key.match(/^_bgnm_/)) {\n\t\t\t\tbuildJsonObject[key.replace('_bgnm_', '')] = new BN(val as string);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (typeof val === 'object' && val != undefined && val != null) {\n\t\t\t\tbuildJsonObject[key] = decodeStringifiableObject(val);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tbuildJsonObject[key] = val;\n\t\t});\n\n\treturn buildJsonObject;\n};\n\nconst getChronologicalValueForOrderAction = (action: OrderAction) => {\n\treturn matchEnum(action, OrderAction.PLACE)\n\t\t? 0\n\t\t: matchEnum(action, OrderAction.FILL)\n\t\t? 1\n\t\t: 2;\n};\n\n/**\n * Returns 1 if the first Order is chronologically later than the second Order, -1 if before, 0 if equal\n * @param orderA\n * @param orderB\n * @returns\n */\nexport const getSortScoreForOrderRecords = (\n\torderA: { slot: number },\n\torderB: { slot: number }\n) => {\n\tif (orderA.slot !== orderB.slot) {\n\t\treturn orderA.slot > orderB.slot ? 1 : -1;\n\t}\n\n\treturn 0;\n};\n\nexport const getTradeInfoFromActionRecord = (\n\tactionRecord: PartialUISerializableOrderActionRecord\n) => {\n\treturn {\n\t\tts: actionRecord.ts,\n\t\tbaseAssetAmount: actionRecord.taker\n\t\t\t? actionRecord.takerOrderBaseAssetAmount\n\t\t\t: actionRecord.makerOrderBaseAssetAmount,\n\t\tbaseAssetAmountFilled: actionRecord.taker\n\t\t\t? actionRecord.takerOrderCumulativeBaseAssetAmountFilled\n\t\t\t: actionRecord.makerOrderCumulativeBaseAssetAmountFilled,\n\t\tquoteAssetAmountFilled: actionRecord.taker\n\t\t\t? actionRecord.takerOrderCumulativeQuoteAssetAmountFilled\n\t\t\t: actionRecord.makerOrderCumulativeQuoteAssetAmountFilled,\n\t};\n};\n\nexport type PartialOrderActionRecord =\n\t| PartialUISerializableOrderActionRecord\n\t| PartialOrderActionEventRecord;\n\nexport type PartialUISerializableOrderActionRecord = Pick<\n\tUISerializableOrderActionRecord,\n\t| 'quoteAssetAmountFilled'\n\t| 'baseAssetAmountFilled'\n\t| 'ts'\n\t| 'slot'\n\t| 'action'\n\t| 'fillRecordId'\n\t| 'taker'\n\t| 'takerOrderBaseAssetAmount'\n\t| 'makerOrderBaseAssetAmount'\n\t| 'takerOrderCumulativeBaseAssetAmountFilled'\n\t| 'makerOrderCumulativeBaseAssetAmountFilled'\n\t| 'takerOrderCumulativeQuoteAssetAmountFilled'\n\t| 'makerOrderCumulativeQuoteAssetAmountFilled'\n\t| 'oraclePrice'\n>;\n\nexport type PartialOrderActionEventRecord = Pick<\n\tEvent<OrderActionRecord>,\n\t| 'quoteAssetAmountFilled'\n\t| 'baseAssetAmountFilled'\n\t| 'ts'\n\t| 'slot'\n\t| 'action'\n\t| 'fillRecordId'\n\t| 'taker'\n\t| 'takerOrderBaseAssetAmount'\n\t| 'makerOrderBaseAssetAmount'\n\t| 'takerOrderCumulativeBaseAssetAmountFilled'\n\t| 'makerOrderCumulativeBaseAssetAmountFilled'\n\t| 'takerOrderCumulativeQuoteAssetAmountFilled'\n\t| 'makerOrderCumulativeQuoteAssetAmountFilled'\n>;\n\n/**\n * Returns 1 if the first Order is chronologically later than the second Order, -1 if before, 0 if equal\n * @param orderA\n * @param orderB\n * @returns\n */\nexport const getSortScoreForOrderActionRecords = (\n\torderA: PartialOrderActionRecord,\n\torderB: PartialOrderActionRecord\n) => {\n\tif (orderA.slot !== orderB.slot) {\n\t\treturn orderA.slot > orderB.slot ? 1 : -1;\n\t}\n\n\tif (!matchEnum(orderA.action, orderB.action)) {\n\t\t// @ts-ignore\n\t\tconst orderAActionVal = getChronologicalValueForOrderAction(orderA.action);\n\t\t// @ts-ignore\n\t\tconst orderBActionVal = getChronologicalValueForOrderAction(orderB.action);\n\n\t\treturn orderAActionVal > orderBActionVal ? 1 : -1;\n\t}\n\t// @ts-ignore\n\tif (orderA.fillRecordId && orderB.fillRecordId) {\n\t\tif (!orderA.fillRecordId.eq(orderB.fillRecordId)) {\n\t\t\t// @ts-ignore\n\t\t\treturn orderA.fillRecordId.gt(orderB.fillRecordId) ? 1 : -1;\n\t\t}\n\t}\n\n\treturn 0;\n};\n\nexport const sortUIMatchedOrderRecordAndAction = (\n\trecords: UIMatchedOrderRecordAndAction[],\n\tdirection: 'asc' | 'desc' = 'desc'\n) => {\n\tconst ascSortedRecords = records.sort((a, b) =>\n\t\tgetSortScoreForOrderActionRecords(a.actionRecord, b.actionRecord)\n\t);\n\n\treturn direction === 'desc' ? ascSortedRecords.reverse() : ascSortedRecords;\n};\n\nexport const sortUIOrderActionRecords = (\n\trecords: PartialUISerializableOrderActionRecord[],\n\tdirection: 'asc' | 'desc' = 'desc'\n) => {\n\tconst ascSortedRecords = records.sort(getSortScoreForOrderActionRecords);\n\n\treturn direction === 'desc' ? ascSortedRecords.reverse() : ascSortedRecords;\n};\n\nexport const sortUIOrderRecords = <T extends { slot: number }>(\n\trecords: T[],\n\tdirection: 'asc' | 'desc' = 'desc'\n) => {\n\tconst ascSortedRecords = records.sort(getSortScoreForOrderRecords);\n\n\treturn direction === 'desc' ? ascSortedRecords.reverse() : ascSortedRecords;\n};\n\nexport const sortOrderRecords = (\n\trecords: Event<OrderRecord>[],\n\tdirection: 'asc' | 'desc' = 'desc'\n) => {\n\tconst ascSortedRecords = records.sort(getSortScoreForOrderRecords);\n\n\treturn direction === 'desc' ? ascSortedRecords.reverse() : ascSortedRecords;\n};\n\nexport const getLatestOfTwoUIOrderRecords = <T extends { slot: number }>(\n\torderA: T,\n\torderB: T\n) => {\n\treturn getSortScoreForOrderRecords(orderA, orderB) === 1 ? orderA : orderB;\n};\n\nexport const getLatestOfTwoOrderRecords = <T extends { slot: number }>(\n\torderA: T,\n\torderB: T\n) => {\n\treturn getSortScoreForOrderRecords(orderA, orderB) === 1 ? orderA : orderB;\n};\n\nexport const getUIOrderRecordsLaterThanTarget = <T extends { slot: number }>(\n\ttarget: T,\n\trecords: T[]\n) =>\n\trecords.filter(\n\t\t(record) => getLatestOfTwoUIOrderRecords(record, target) === record\n\t);\n\n// Trade records are order records which have been filled\nexport const orderActionRecordIsTrade = (orderRecord: OrderActionRecord) =>\n\torderRecord.baseAssetAmountFilled.gt(ZERO) &&\n\t// @ts-ignore\n\tmatchEnum(orderRecord.action, OrderAction.FILL) &&\n\ttrue;\n\nexport const uiOrderActionRecordIsTrade = (\n\torderRecord: UISerializableOrderActionRecord\n) =>\n\torderRecord.baseAssetAmountFilled.gtZero() &&\n\tmatchEnum(orderRecord.action, OrderAction.FILL) &&\n\ttrue;\n\n// Trade records are order records which have been filled\nexport const filterTradeRecordsFromOrderActionRecords = (\n\torderRecords: OrderActionRecord[]\n): OrderActionRecord[] => orderRecords.filter(orderActionRecordIsTrade);\n\n// Trade records are order records which have been filled\nexport const filterTradeRecordsFromUIOrderRecords = (\n\torderRecords: UISerializableOrderActionRecord[]\n): UISerializableOrderActionRecord[] =>\n\torderRecords.filter(uiOrderActionRecordIsTrade);\n\n/**\n * Returns the average price for a given base amount and quote amount.\n * @param quoteAmount\n * @param baseAmount\n * @returns PRICE_PRECISION\n */\nexport const getPriceForBaseAndQuoteAmount = (\n\tquoteAmount: BN,\n\tbaseAmount: BN\n) => {\n\treturn quoteAmount\n\t\t.mul(PRICE_PRECISION)\n\t\t.mul(BASE_PRECISION)\n\t\t.div(QUOTE_PRECISION)\n\t\t.div(BigNum.from(baseAmount, BASE_PRECISION_EXP).val);\n};\n\nexport const getPriceForOrderRecord = (\n\torderRecord: Pick<\n\t\tOrderActionRecord,\n\t\t'quoteAssetAmountFilled' | 'baseAssetAmountFilled'\n\t>\n) => {\n\treturn getPriceForBaseAndQuoteAmount(\n\t\t// @ts-ignore\n\t\torderRecord.quoteAssetAmountFilled,\n\t\t// @ts-ignore\n\t\torderRecord.baseAssetAmountFilled\n\t);\n};\n\nexport const getPriceForUIOrderRecord = (\n\torderRecord: Pick<\n\t\tUISerializableOrderActionRecord,\n\t\t'quoteAssetAmountFilled' | 'baseAssetAmountFilled'\n\t>\n) => {\n\treturn orderRecord.quoteAssetAmountFilled\n\t\t.shiftTo(AMM_RESERVE_PRECISION_EXP)\n\t\t.shift(PRICE_PRECISION_EXP)\n\t\t.div(orderRecord.baseAssetAmountFilled.shiftTo(BASE_PRECISION_EXP))\n\t\t.shiftTo(PRICE_PRECISION_EXP);\n};\n\nexport const orderIsNull = (\n\torder: UISerializableOrderActionRecord | Event<OrderActionRecord>,\n\tside: 'taker' | 'maker'\n) => {\n\treturn side === 'taker' ? !order.taker : !order.maker;\n};\n\nexport const getAnchorEnumString = (enumVal: Record<string, unknown>) => {\n\treturn Object.keys(enumVal)[0];\n};\nexport class Ref<T> {\n\tpublic val: T;\n\n\tconstructor(val: T) {\n\t\tthis.val = val;\n\t}\n\n\tset(val: T) {\n\t\tthis.val = val;\n\t}\n\n\tget() {\n\t\treturn this.val;\n\t}\n}\n\nexport class Counter {\n\tprivate val = 0;\n\n\tget() {\n\t\treturn this.val;\n\t}\n\n\tincrement(value = 1) {\n\t\tthis.val += value;\n\t}\n\n\treset() {\n\t\tthis.val = 0;\n\t}\n}\n\n/**\n * A class which allows a group of switches to seperately turn a multiswitch on or off. The base state is the state of the \"multiswitch\" when all of the constituent switches are off. When any of the switches are \"on\" then the multiswitch flips to the opposite state\n *\n * If baseState is on => any switch being \"on\" will turn the multiswitch off.\n * If baseState is off => any switch being \"off\" will turn the multiswitch off.\n */\nexport class MultiSwitch {\n\tprivate switches: string[] = [];\n\tprivate switchValue = 0;\n\n\tconstructor(private baseState: 'on' | 'off' = 'off') {}\n\n\tprivate getSwitchKey(key: string) {\n\t\t// If first time using switch, add to list of switches\n\t\tif (!this.switches.includes(key)) {\n\t\t\tthis.switches.push(key);\n\t\t}\n\n\t\tconst switchIndex = this.switches.indexOf(key);\n\n\t\treturn 2 ** switchIndex;\n\t}\n\n\tpublic switchOn(key: string) {\n\t\tif (this.baseState === 'on') {\n\t\t\tthis._switchOff(key);\n\t\t\treturn;\n\t\t}\n\t\tthis._switchOn(key);\n\t}\n\n\tpublic switchOff(key: string) {\n\t\tif (this.baseState === 'on') {\n\t\t\tthis._switchOn(key);\n\t\t\treturn;\n\t\t}\n\t\tthis._switchOff(key);\n\t}\n\n\tprivate _switchOff(key: string) {\n\t\tconst switchKey = this.getSwitchKey(key);\n\n\t\tthis.switchValue &= ~switchKey;\n\t}\n\n\tprivate _switchOn(key: string) {\n\t\tconst switchKey = this.getSwitchKey(key);\n\n\t\tthis.switchValue |= switchKey;\n\t}\n\n\tpublic get isOn() {\n\t\t// When the base state is on, then if any switch is on the multi-switch is off\n\t\tif (this.baseState === 'on') {\n\t\t\treturn this.switchValue === 0;\n\t\t}\n\n\t\tif (this.baseState === 'off') {\n\t\t\treturn this.switchValue > 0;\n\t\t}\n\t}\n}\n\n/**\n * Returns the quote amount of the current open interest for a market, using the current oracle price\n * @param marketIndex\n * @param marketType\n * @param driftClient\n * @returns\n */\nconst getCurrentOpenInterestForMarket = (\n\tmarketIndex: number,\n\tmarketType: MarketType,\n\tdriftClient: DriftClient\n) => {\n\tif (ENUM_UTILS.match(marketType, MarketType.PERP)) {\n\t\tconst market = driftClient.getPerpMarketAccount(marketIndex);\n\t\tconst OI = BigNum.from(\n\t\t\tmarket.amm.baseAssetAmountLong.add(market.amm.baseAssetAmountShort.abs()),\n\t\t\tBASE_PRECISION_EXP\n\t\t);\n\n\t\tconst priceData = driftClient.getOraclePriceDataAndSlot(\n\t\t\tmarket.amm.oracle,\n\t\t\tmarket.amm.oracleSource\n\t\t);\n\n\t\tconst price = BigNum.from(priceData.data.price, PRICE_PRECISION_EXP);\n\n\t\tconst quoteOIforMarket = price.toNum() * OI.toNum();\n\n\t\treturn quoteOIforMarket;\n\t} else {\n\t\tthrow new Error('Invalid market type for Open Interest calculation');\n\t}\n};\n\n/**\n * Gets the deposit APR for a spot market, in percent\n * @param marketIndex\n * @param marketType\n * @param driftClient\n * @returns\n */\nconst getDepositAprForMarket = (\n\tmarketIndex: number,\n\tmarketType: MarketType,\n\tdriftClient: DriftClient\n) => {\n\tif (ENUM_UTILS.match(marketType, MarketType.SPOT)) {\n\t\tconst marketAccount = driftClient.getSpotMarketAccount(marketIndex);\n\n\t\tconst depositApr = BigNum.from(\n\t\t\tcalculateDepositRate(marketAccount),\n\t\t\tSPOT_MARKET_RATE_PRECISION_EXP\n\t\t);\n\n\t\tconst depositAprPct = depositApr.toNum() * 100;\n\n\t\treturn depositAprPct;\n\t} else {\n\t\tthrow new Error('Invalid market type for Deposit APR calculation');\n\t}\n};\n\n/**\n * Get's the borrow APR for a spot market, in percent\n * @param marketIndex\n * @param marketType\n * @param driftClient\n * @returns\n */\nconst getBorrowAprForMarket = (\n\tmarketIndex: number,\n\tmarketType: MarketType,\n\tdriftClient: DriftClient\n) => {\n\tif (ENUM_UTILS.match(marketType, MarketType.SPOT)) {\n\t\tconst marketAccount = driftClient.getSpotMarketAccount(marketIndex);\n\n\t\tconst depositApr = BigNum.from(\n\t\t\tcalculateBorrowRate(marketAccount),\n\t\t\tSPOT_MARKET_RATE_PRECISION_EXP\n\t\t);\n\n\t\tconst depositAprPct = depositApr.toNum() * 100;\n\n\t\treturn depositAprPct;\n\t} else {\n\t\tthrow new Error('Invalid market type for Borrow APR calculation');\n\t}\n};\n\nconst getTotalBorrowsForMarket = (\n\tmarket: SpotMarketConfig,\n\tdriftClient: DriftClient\n) => {\n\tconst marketAccount = driftClient.getSpotMarketAccount(market.marketIndex);\n\n\tconst totalBorrowsTokenAmount = getTokenAmount(\n\t\tmarketAccount.borrowBalance,\n\t\tdriftClient.getSpotMarketAccount(marketAccount.marketIndex),\n\t\tSpotBalanceType.BORROW\n\t);\n\n\tconst totalBorrowsAmountBigNum = BigNum.from(\n\t\ttotalBorrowsTokenAmount,\n\t\tmarket.precisionExp\n\t);\n\n\tconst priceData = driftClient.getOraclePriceDataAndSlot(\n\t\tmarketAccount.oracle,\n\t\tmarketAccount.oracleSource\n\t);\n\n\tconst price = BigNum.from(priceData.data.price, PRICE_PRECISION_EXP);\n\n\tconst totalBorrowsQuote = price.toNum() * totalBorrowsAmountBigNum.toNum();\n\n\treturn Number(totalBorrowsQuote.toFixed(2));\n};\n\nconst getTotalDepositsForMarket = (\n\tmarket: SpotMarketConfig,\n\tdriftClient: DriftClient\n) => {\n\tconst marketAccount = driftClient.getSpotMarketAccount(market.marketIndex);\n\n\tconst totalDepositsTokenAmount = getTokenAmount(\n\t\tmarketAccount.depositBalance,\n\t\tmarketAccount,\n\t\tSpotBalanceType.DEPOSIT\n\t);\n\n\tconst totalDepositsTokenAmountBigNum = BigNum.from(\n\t\ttotalDepositsTokenAmount,\n\t\tmarket.precisionExp\n\t);\n\n\tconst priceData = driftClient.getOraclePriceDataAndSlot(\n\t\tmarketAccount.oracle,\n\t\tmarketAccount.oracleSource\n\t);\n\n\tconst price = BigNum.from(priceData.data.price, PRICE_PRECISION_EXP);\n\n\tconst totalDepositsBase = totalDepositsTokenAmountBigNum.toNum();\n\tconst totalDepositsQuote =\n\t\tprice.toNum() * totalDepositsTokenAmountBigNum.toNum();\n\n\treturn {\n\t\ttotalDepositsBase,\n\t\ttotalDepositsQuote,\n\t};\n};\n\n/**\n * Check if numbers divide exactly, accounting for floating point division annoyingness\n * @param numerator\n * @param denominator\n * @returns\n */\nconst dividesExactly = (numerator: number, denominator: number) => {\n\tconst division = numerator / denominator;\n\tconst remainder = division % 1;\n\n\tif (remainder === 0) return true;\n\n\t// Because of floating point weirdness, we're just going to assume that if the remainder after dividing is less than 1/10^6 then the numbers do divide exactly\n\tif (Math.abs(remainder - 1) < 1 / 10 ** 6) return true;\n\n\treturn false;\n};\n\nconst toSnakeCase = (str: string): string =>\n\tstr.replace(/[^\\w]/g, '_').toLowerCase();\n\nconst toCamelCase = (str: string): string => {\n\tconst words = str.split(/[_\\-\\s]+/); // split on underscores, hyphens, and spaces\n\tconst firstWord = words[0].toLowerCase();\n\tconst restWords = words\n\t\t.slice(1)\n\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());\n\treturn [firstWord, ...restWords].join('');\n};\n\nexport const aprFromApy = (apy: number, compoundsPerYear: number) => {\n\tconst compoundedAmount = 1 + apy * 0.01;\n\tconst estimatedApr =\n\t\t(Math.pow(compoundedAmount, 1 / compoundsPerYear) - 1) * compoundsPerYear;\n\n\treturn estimatedApr * 100;\n};\n\n/**\n * Helper utility to get a sort score for \"tiered\" parameters.\n *\n * Example: Want to sort students by Grade, but fall back to using Age if they are equal. This method will accept an array for each student of [grade, age] and return the appropriate sort score for each.\n *\n * @param aScores\n * @param bScores\n * @returns\n */\nexport const getTieredSortScore = (aScores: number[], bScores: number[]) => {\n\tconst maxIndex = Math.max(aScores.length, bScores.length);\n\n\tfor (let i = 0; i < maxIndex; i++) {\n\t\tconst aScore = aScores[i] ?? Number.MIN_SAFE_INTEGER;\n\t\tconst bScore = bScores[i] ?? Number.MIN_SAFE_INTEGER;\n\n\t\tif (aScore !== bScore) return aScore - bScore;\n\t}\n\n\treturn 0;\n};\n\nconst normalizeBaseAssetSymbol = (symbol: string) => {\n\treturn symbol.replace(/^1M/, '');\n};\n\n/**\n * Returns the number of standard deviations between a target value and the history of values to compare it to.\n * @param target\n * @param previousValues\n * @returns\n */\nconst calculateZScore = (target: number, previousValues: number[]): number => {\n\tconst meanValue = calculateMean(previousValues);\n\tconst standardDeviationValue = calculateStandardDeviation(\n\t\tpreviousValues,\n\t\tmeanValue\n\t);\n\n\tconst zScore = (target - meanValue) / standardDeviationValue;\n\treturn zScore;\n};\n\nconst calculateMean = (numbers: number[]): number => {\n\tconst sum = numbers.reduce((total, num) => total + num, 0);\n\treturn sum / numbers.length;\n};\n\nconst calculateMedian = (numbers: number[]): number => {\n\tconst sortedNumbers = numbers.sort();\n\tconst middleIndex = Math.floor(sortedNumbers.length / 2);\n\tif (sortedNumbers.length % 2 === 0) {\n\t\treturn (sortedNumbers[middleIndex - 1] + sortedNumbers[middleIndex]) / 2;\n\t} else {\n\t\treturn sortedNumbers[middleIndex];\n\t}\n};\n\nconst calculateStandardDeviation = (\n\tnumbers: number[],\n\tmean: number\n): number => {\n\tconst squaredDifferences = numbers.map((num) => Math.pow(num - mean, 2));\n\tconst sumSquaredDifferences = squaredDifferences.reduce(\n\t\t(total, diff) => total + diff,\n\t\t0\n\t);\n\tconst variance = sumSquaredDifferences / numbers.length;\n\treturn Math.sqrt(variance);\n};\n\nconst glueArray = <T>(size: number, elements: T[]): T[][] => {\n\tconst gluedElements: T[][] = [];\n\n\telements.forEach((element, index) => {\n\t\tconst gluedIndex = Math.floor(index / size);\n\t\tif (gluedElements[gluedIndex]) {\n\t\t\tgluedElements[gluedIndex].push(element);\n\t\t} else {\n\t\t\tgluedElements[gluedIndex] = [element];\n\t\t}\n\t});\n\n\treturn gluedElements;\n};\n\nconst bnMin = (numbers: BN[]): BN => {\n\tlet min = numbers[0];\n\tfor (let i = 1; i < numbers.length; i++) {\n\t\tif (numbers[i].lt(min)) {\n\t\t\tmin = numbers[i];\n\t\t}\n\t}\n\treturn min;\n};\n\nconst bnMax = (numbers: BN[]): BN => {\n\tlet max = numbers[0];\n\tfor (let i = 1; i < numbers.length; i++) {\n\t\tif (numbers[i].gt(max)) {\n\t\t\tmax = numbers[i];\n\t\t}\n\t}\n\treturn max;\n};\n\nconst bnMedian = (numbers: BN[]): BN => {\n\tconst sortedNumbers = numbers.sort((a, b) => a.cmp(b));\n\tconst middleIndex = Math.floor(sortedNumbers.length / 2);\n\tif (sortedNumbers.length % 2 === 0) {\n\t\treturn sortedNumbers[middleIndex - 1]\n\t\t\t.add(sortedNumbers[middleIndex])\n\t\t\t.div(new BN(2));\n\t} else {\n\t\treturn sortedNumbers[middleIndex];\n\t}\n};\n\nconst bnMean = (numbers: BN[]): BN => {\n\tlet sum = new BN(0);\n\tfor (let i = 0; i < numbers.length; i++) {\n\t\tsum = sum.add(numbers[i]);\n\t}\n\treturn sum.div(new BN(numbers.length));\n};\n\nconst timedPromise = async <T>(promise: T) => {\n\tconst start = Date.now();\n\tconst promiseResult = await promise;\n\n\treturn {\n\t\tpromiseTime: Date.now() - start,\n\t\tpromiseResult,\n\t};\n};\n\nconst chunks = <T>(array: readonly T[], size: number): T[][] => {\n\treturn new Array(Math.ceil(array.length / size))\n\t\t.fill(null)\n\t\t.map((_, index) => index * size)\n\t\t.map((begin) => array.slice(begin, begin + size));\n};\n\nconst getMultipleAccountsInfoChunked = async (\n\tconnection: Connection,\n\taccounts: PublicKey[]\n): Promise<(AccountInfo<Buffer> | null)[]> => {\n\tconst accountChunks = chunks(accounts, 100); // 100 is limit for getMultipleAccountsInfo\n\tconst responses = await Promise.all(\n\t\taccountChunks.map((chunk) => connection.getMultipleAccountsInfo(chunk))\n\t);\n\treturn responses.flat();\n};\n\nexport const COMMON_UTILS = {\n\tgetIfVaultBalance,\n\tgetIfStakingVaultApr,\n\tgetCurrentOpenInterestForMarket,\n\tgetDepositAprForMarket,\n\tgetBorrowAprForMarket,\n\tgetTotalBorrowsForMarket,\n\tgetTotalDepositsForMarket,\n\tdividesExactly,\n\ttoSnakeCase,\n\ttoCamelCase,\n\tgetTieredSortScore,\n\tnormalizeBaseAssetSymbol,\n\tcalculateZScore,\n\tglueArray,\n\ttimedPromise,\n\tchunks,\n\tgetMultipleAccountsInfoChunked,\n\tMATH: {\n\t\tNUM: {\n\t\t\tmean: calculateMean,\n\t\t\tmedian: calculateMedian,\n\t\t},\n\t\tBN: {\n\t\t\tbnMax,\n\t\t\tbnMin,\n\t\t\tbnMean,\n\t\t\tbnMedian,\n\t\t},\n\t},\n};\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;AAAA,yCAuByB;AAKzB,mDAA0E;AAGnE,MAAM,SAAS,GAAG,CAAC,KAAU,EAAE,KAAK,EAAE,EAAE;IAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC,CAAC;AAFW,QAAA,SAAS,aAEpB;AAEF,SAAS,SAAS,CAAC,OAAe;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAE/B,OAAO;QACN,CAAC,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,EAAE,CAAC,EAAE,EAAE;KACnB,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,OAA4B;;IAC9C,OAAO,MAAA,MAAM,CAAC,IAAI,CAAC,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,EAAE,CAAC,0CAAG,CAAC,CAAC,CAAC;AACxC,CAAC;AAEY,QAAA,UAAU,GAAG;IACzB,KAAK,EAAE,iBAAS;IAChB,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;CAChB,CAAC;AAEK,KAAK,UAAU,KAAK,CAAC,EAAE;IAC7B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC1D,CAAC;AAFD,sBAEC;AACD,MAAM,2BAA2B,GAAG,CAAC,KAAU,EAAiB,EAAE;IACjE,QAAQ;IACR,kLAAkL;IAClL,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,2BAA2B,EAAE,CAAC;QACzE,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,eAAe;IACf,2LAA2L;IAC3L,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAA,iCAAyB,EAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACpB,CAAC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACI,MAAM,yBAAyB,GAAG,CAAC,KAAU,EAAE,EAAE;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE5C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,iCAAyB,EAAC,KAAK,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,eAAe,GAAG,EAAE,CAAC;IAE3B,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE;QAC5C,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC;QAChE,eAAe,CAAC,GAAG,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,YAAY,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,OAAO,eAAe,CAAC;AACxB,CAAC,CAAC;AAjBW,QAAA,yBAAyB,6BAiBpC;AAEF;;;;;;;;;;;;;GAaG;AACI,MAAM,yBAAyB,GAAG,CAAC,KAAU,EAAE,EAAE;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE5C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,iCAAyB,EAAC,KAAK,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,eAAe,GAAG,EAAE,CAAC;IAE3B,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;SACnB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,SAAS,IAAI,GAAG,IAAI,IAAI,CAAC;SAChD,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE;QACvB,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,eAAS,CAAC,GAAG,CAAC,CAAC;YAChE,OAAO;QACR,CAAC;QAED,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,QAAE,CAAC,GAAa,CAAC,CAAC;YACnE,OAAO;QACR,CAAC;QAED,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YAChE,eAAe,CAAC,GAAG,CAAC,GAAG,IAAA,iCAAyB,EAAC,GAAG,CAAC,CAAC;YACtD,OAAO;QACR,CAAC;QAED,eAAe,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEJ,OAAO,eAAe,CAAC;AACxB,CAAC,CAAC;AA/BW,QAAA,yBAAyB,6BA+BpC;AAEF,MAAM,mCAAmC,GAAG,CAAC,MAAmB,EAAE,EAAE;IACnE,OAAO,IAAA,iBAAS,EAAC,MAAM,EAAE,iBAAW,CAAC,KAAK,CAAC;QAC1C,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,IAAA,iBAAS,EAAC,MAAM,EAAE,iBAAW,CAAC,IAAI,CAAC;YACrC,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,CAAC,CAAC;AACN,CAAC,CAAC;AAEF;;;;;GAKG;AACI,MAAM,2BAA2B,GAAG,CAC1C,MAAwB,EACxB,MAAwB,EACvB,EAAE;IACH,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC;QACjC,OAAO,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,CAAC,CAAC;AACV,CAAC,CAAC;AATW,QAAA,2BAA2B,+BAStC;AAEK,MAAM,4BAA4B,GAAG,CAC3C,YAAoD,EACnD,EAAE;IACH,OAAO;QACN,EAAE,EAAE,YAAY,CAAC,EAAE;QACnB,eAAe,EAAE,YAAY,CAAC,KAAK;YAClC,CAAC,CAAC,YAAY,CAAC,yBAAyB;YACxC,CAAC,CAAC,YAAY,CAAC,yBAAyB;QACzC,qBAAqB,EAAE,YAAY,CAAC,KAAK;YACxC,CAAC,CAAC,YAAY,CAAC,yCAAyC;YACxD,CAAC,CAAC,YAAY,CAAC,yCAAyC;QACzD,sBAAsB,EAAE,YAAY,CAAC,KAAK;YACzC,CAAC,CAAC,YAAY,CAAC,0CAA0C;YACzD,CAAC,CAAC,YAAY,CAAC,0CAA0C;KAC1D,CAAC;AACH,CAAC,CAAC;AAfW,QAAA,4BAA4B,gCAevC;AAyCF;;;;;GAKG;AACI,MAAM,iCAAiC,GAAG,CAChD,MAAgC,EAChC,MAAgC,EAC/B,EAAE;IACH,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC;QACjC,OAAO,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,IAAA,iBAAS,EAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9C,aAAa;QACb,MAAM,eAAe,GAAG,mCAAmC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3E,aAAa;QACb,MAAM,eAAe,GAAG,mCAAmC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAE3E,OAAO,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,aAAa;IACb,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;YAClD,aAAa;YACb,OAAO,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7D,CAAC;IACF,CAAC;IAED,OAAO,CAAC,CAAC;AACV,CAAC,CAAC;AAzBW,QAAA,iCAAiC,qCAyB5C;AAEK,MAAM,iCAAiC,GAAG,CAChD,OAAwC,EACxC,YAA4B,MAAM,EACjC,EAAE;IACH,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC9C,IAAA,yCAAiC,EAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,YAAY,CAAC,CACjE,CAAC;IAEF,OAAO,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC;AAC7E,CAAC,CAAC;AATW,QAAA,iCAAiC,qCAS5C;AAEK,MAAM,wBAAwB,GAAG,CACvC,OAAiD,EACjD,YAA4B,MAAM,EACjC,EAAE;IACH,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,yCAAiC,CAAC,CAAC;IAEzE,OAAO,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC;AAC7E,CAAC,CAAC;AAPW,QAAA,wBAAwB,4BAOnC;AAEK,MAAM,kBAAkB,GAAG,CACjC,OAAY,EACZ,YAA4B,MAAM,EACjC,EAAE;IACH,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,mCAA2B,CAAC,CAAC;IAEnE,OAAO,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC;AAC7E,CAAC,CAAC;AAPW,QAAA,kBAAkB,sBAO7B;AAEK,MAAM,gBAAgB,GAAG,CAC/B,OAA6B,EAC7B,YAA4B,MAAM,EACjC,EAAE;IACH,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,mCAA2B,CAAC,CAAC;IAEnE,OAAO,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC;AAC7E,CAAC,CAAC;AAPW,QAAA,gBAAgB,oBAO3B;AAEK,MAAM,4BAA4B,GAAG,CAC3C,MAAS,EACT,MAAS,EACR,EAAE;IACH,OAAO,IAAA,mCAA2B,EAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AAC5E,CAAC,CAAC;AALW,QAAA,4BAA4B,gCAKvC;AAEK,MAAM,0BAA0B,GAAG,CACzC,MAAS,EACT,MAAS,EACR,EAAE;IACH,OAAO,IAAA,mCAA2B,EAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AAC5E,CAAC,CAAC;AALW,QAAA,0BAA0B,8BAKrC;AAEK,MAAM,gCAAgC,GAAG,CAC/C,MAAS,EACT,OAAY,EACX,EAAE,CACH,OAAO,CAAC,MAAM,CACb,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,oCAA4B,EAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CACnE,CAAC;AANU,QAAA,gCAAgC,oCAM1C;AAEH,yDAAyD;AAClD,MAAM,wBAAwB,GAAG,CAAC,WAA8B,EAAE,EAAE,CAC1E,WAAW,CAAC,qBAAqB,CAAC,EAAE,CAAC,UAAI,CAAC;IAC1C,aAAa;IACb,IAAA,iBAAS,EAAC,WAAW,CAAC,MAAM,EAAE,iBAAW,CAAC,IAAI,CAAC;IAC/C,IAAI,CAAC;AAJO,QAAA,wBAAwB,4BAI/B;AAEC,MAAM,0BAA0B,GAAG,CACzC,WAA4C,EAC3C,EAAE,CACH,WAAW,CAAC,qBAAqB,CAAC,MAAM,EAAE;IAC1C,IAAA,iBAAS,EAAC,WAAW,CAAC,MAAM,EAAE,iBAAW,CAAC,IAAI,CAAC;IAC/C,IAAI,CAAC;AALO,QAAA,0BAA0B,8BAKjC;AAEN,yDAAyD;AAClD,MAAM,wCAAwC,GAAG,CACvD,YAAiC,EACX,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,gCAAwB,CAAC,CAAC;AAF3D,QAAA,wCAAwC,4CAEmB;AAExE,yDAAyD;AAClD,MAAM,oCAAoC,GAAG,CACnD,YAA+C,EACX,EAAE,CACtC,YAAY,CAAC,MAAM,CAAC,kCAA0B,CAAC,CAAC;AAHpC,QAAA,oCAAoC,wCAGA;AAEjD;;;;;GAKG;AACI,MAAM,6BAA6B,GAAG,CAC5C,WAAe,EACf,UAAc,EACb,EAAE;IACH,OAAO,WAAW;SAChB,GAAG,CAAC,qBAAe,CAAC;SACpB,GAAG,CAAC,oBAAc,CAAC;SACnB,GAAG,CAAC,qBAAe,CAAC;SACpB,GAAG,CAAC,YAAM,CAAC,IAAI,CAAC,UAAU,EAAE,wBAAkB,CAAC,CAAC,GAAG,CAAC,CAAC;AACxD,CAAC,CAAC;AATW,QAAA,6BAA6B,iCASxC;AAEK,MAAM,sBAAsB,GAAG,CACrC,WAGC,EACA,EAAE;IACH,OAAO,IAAA,qCAA6B;IACnC,aAAa;IACb,WAAW,CAAC,sBAAsB;IAClC,aAAa;IACb,WAAW,CAAC,qBAAqB,CACjC,CAAC;AACH,CAAC,CAAC;AAZW,QAAA,sBAAsB,0BAYjC;AAEK,MAAM,wBAAwB,GAAG,CACvC,WAGC,EACA,EAAE;IACH,OAAO,WAAW,CAAC,sBAAsB;SACvC,OAAO,CAAC,+BAAyB,CAAC;SAClC,KAAK,CAAC,yBAAmB,CAAC;SAC1B,GAAG,CAAC,WAAW,CAAC,qBAAqB,CAAC,OAAO,CAAC,wBAAkB,CAAC,CAAC;SAClE,OAAO,CAAC,yBAAmB,CAAC,CAAC;AAChC,CAAC,CAAC;AAXW,QAAA,wBAAwB,4BAWnC;AAEK,MAAM,WAAW,GAAG,CAC1B,KAAiE,EACjE,IAAuB,EACtB,EAAE;IACH,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;AACvD,CAAC,CAAC;AALW,QAAA,WAAW,eAKtB;AAEK,MAAM,mBAAmB,GAAG,CAAC,OAAgC,EAAE,EAAE;IACvE,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC,CAAC;AAFW,QAAA,mBAAmB,uBAE9B;AACF,MAAa,GAAG;IAGf,YAAY,GAAM;QACjB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IAChB,CAAC;IAED,GAAG,CAAC,GAAM;QACT,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IAChB,CAAC;IAED,GAAG;QACF,OAAO,IAAI,CAAC,GAAG,CAAC;IACjB,CAAC;CACD;AAdD,kBAcC;AAED,MAAa,OAAO;IAApB;QACS,QAAG,GAAG,CAAC,CAAC;IAajB,CAAC;IAXA,GAAG;QACF,OAAO,IAAI,CAAC,GAAG,CAAC;IACjB,CAAC;IAED,SAAS,CAAC,KAAK,GAAG,CAAC;QAClB,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC;IACnB,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACd,CAAC;CACD;AAdD,0BAcC;AAED;;;;;GAKG;AACH,MAAa,WAAW;IAIvB,YAAoB,YAA0B,KAAK;QAA/B,cAAS,GAAT,SAAS,CAAsB;QAH3C,aAAQ,GAAa,EAAE,CAAC;QACxB,gBAAW,GAAG,CAAC,CAAC;IAE8B,CAAC;IAE/C,YAAY,CAAC,GAAW;QAC/B,sDAAsD;QACtD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAE/C,OAAO,CAAC,IAAI,WAAW,CAAC;IACzB,CAAC;IAEM,QAAQ,CAAC,GAAW;QAC1B,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACrB,OAAO;QACR,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAEM,SAAS,CAAC,GAAW;QAC3B,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACpB,OAAO;QACR,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IAEO,UAAU,CAAC,GAAW;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAEzC,IAAI,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC;IAChC,CAAC;IAEO,SAAS,CAAC,GAAW;QAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAEzC,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC;IAC/B,CAAC;IAED,IAAW,IAAI;QACd,8EAA8E;QAC9E,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,WAAW,KAAK,CAAC,CAAC;QAC/B,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QAC7B,CAAC;IACF,CAAC;CACD;AAvDD,kCAuDC;AAED;;;;;;GAMG;AACH,MAAM,+BAA+B,GAAG,CACvC,WAAmB,EACnB,UAAsB,EACtB,WAAwB,EACvB,EAAE;IACH,IAAI,kBAAU,CAAC,KAAK,CAAC,UAAU,EAAE,gBAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,MAAM,MAAM,GAAG,WAAW,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAC7D,MAAM,EAAE,GAAG,YAAM,CAAC,IAAI,CACrB,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,GAAG,EAAE,CAAC,EACzE,wBAAkB,CAClB,CAAC;QAEF,MAAM,SAAS,GAAG,WAAW,CAAC,yBAAyB,CACtD,MAAM,CAAC,GAAG,CAAC,MAAM,EACjB,MAAM,CAAC,GAAG,CAAC,YAAY,CACvB,CAAC;QAEF,MAAM,KAAK,GAAG,YAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,yBAAmB,CAAC,CAAC;QAErE,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC;QAEpD,OAAO,gBAAgB,CAAC;IACzB,CAAC;SAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACtE,CAAC;AACF,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,sBAAsB,GAAG,CAC9B,WAAmB,EACnB,UAAsB,EACtB,WAAwB,EACvB,EAAE;IACH,IAAI,kBAAU,CAAC,KAAK,CAAC,UAAU,EAAE,gBAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,MAAM,aAAa,GAAG,WAAW,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAEpE,MAAM,UAAU,GAAG,YAAM,CAAC,IAAI,CAC7B,IAAA,0BAAoB,EAAC,aAAa,CAAC,EACnC,oCAA8B,CAC9B,CAAC;QAEF,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC;QAE/C,OAAO,aAAa,CAAC;IACtB,CAAC;SAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACpE,CAAC;AACF,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,qBAAqB,GAAG,CAC7B,WAAmB,EACnB,UAAsB,EACtB,WAAwB,EACvB,EAAE;IACH,IAAI,kBAAU,CAAC,KAAK,CAAC,UAAU,EAAE,gBAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,MAAM,aAAa,GAAG,WAAW,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAEpE,MAAM,UAAU,GAAG,YAAM,CAAC,IAAI,CAC7B,IAAA,yBAAmB,EAAC,aAAa,CAAC,EAClC,oCAA8B,CAC9B,CAAC;QAEF,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC;QAE/C,OAAO,aAAa,CAAC;IACtB,CAAC;SAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACnE,CAAC;AACF,CAAC,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAChC,MAAwB,EACxB,WAAwB,EACvB,EAAE;IACH,MAAM,aAAa,GAAG,WAAW,CAAC,oBAAoB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAE3E,MAAM,uBAAuB,GAAG,IAAA,oBAAc,EAC7C,aAAa,CAAC,aAAa,EAC3B,WAAW,CAAC,oBAAoB,CAAC,aAAa,CAAC,WAAW,CAAC,EAC3D,qBAAe,CAAC,MAAM,CACtB,CAAC;IAEF,MAAM,wBAAwB,GAAG,YAAM,CAAC,IAAI,CAC3C,uBAAuB,EACvB,MAAM,CAAC,YAAY,CACnB,CAAC;IAEF,MAAM,SAAS,GAAG,WAAW,CAAC,yBAAyB,CACtD,aAAa,CAAC,MAAM,EACpB,aAAa,CAAC,YAAY,CAC1B,CAAC;IAEF,MAAM,KAAK,GAAG,YAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,yBAAmB,CAAC,CAAC;IAErE,MAAM,iBAAiB,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,wBAAwB,CAAC,KAAK,EAAE,CAAC;IAE3E,OAAO,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CACjC,MAAwB,EACxB,WAAwB,EACvB,EAAE;IACH,MAAM,aAAa,GAAG,WAAW,CAAC,oBAAoB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAE3E,MAAM,wBAAwB,GAAG,IAAA,oBAAc,EAC9C,aAAa,CAAC,cAAc,EAC5B,aAAa,EACb,qBAAe,CAAC,OAAO,CACvB,CAAC;IAEF,MAAM,8BAA8B,GAAG,YAAM,CAAC,IAAI,CACjD,wBAAwB,EACxB,MAAM,CAAC,YAAY,CACnB,CAAC;IAEF,MAAM,SAAS,GAAG,WAAW,CAAC,yBAAyB,CACtD,aAAa,CAAC,MAAM,EACpB,aAAa,CAAC,YAAY,CAC1B,CAAC;IAEF,MAAM,KAAK,GAAG,YAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,yBAAmB,CAAC,CAAC;IAErE,MAAM,iBAAiB,GAAG,8BAA8B,CAAC,KAAK,EAAE,CAAC;IACjE,MAAM,kBAAkB,GACvB,KAAK,CAAC,KAAK,EAAE,GAAG,8BAA8B,CAAC,KAAK,EAAE,CAAC;IAExD,OAAO;QACN,iBAAiB;QACjB,kBAAkB;KAClB,CAAC;AACH,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,cAAc,GAAG,CAAC,SAAiB,EAAE,WAAmB,EAAE,EAAE;IACjE,MAAM,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IACzC,MAAM,SAAS,GAAG,QAAQ,GAAG,CAAC,CAAC;IAE/B,IAAI,SAAS,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEjC,8JAA8J;IAC9J,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvD,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,GAAW,EAAU,EAAE,CAC3C,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AAE1C,MAAM,WAAW,GAAG,CAAC,GAAW,EAAU,EAAE;IAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,4CAA4C;IACjF,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,KAAK;SACrB,KAAK,CAAC,CAAC,CAAC;SACR,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5E,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEK,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,gBAAwB,EAAE,EAAE;IACnE,MAAM,gBAAgB,GAAG,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC;IACxC,MAAM,YAAY,GACjB,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,gBAAgB,CAAC;IAE3E,OAAO,YAAY,GAAG,GAAG,CAAC;AAC3B,CAAC,CAAC;AANW,QAAA,UAAU,cAMrB;AAEF;;;;;;;;GAQG;AACI,MAAM,kBAAkB,GAAG,CAAC,OAAiB,EAAE,OAAiB,EAAE,EAAE;;IAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,MAAA,OAAO,CAAC,CAAC,CAAC,mCAAI,MAAM,CAAC,gBAAgB,CAAC;QACrD,MAAM,MAAM,GAAG,MAAA,OAAO,CAAC,CAAC,CAAC,mCAAI,MAAM,CAAC,gBAAgB,CAAC;QAErD,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO,MAAM,GAAG,MAAM,CAAC;IAC/C,CAAC;IAED,OAAO,CAAC,CAAC;AACV,CAAC,CAAC;AAXW,QAAA,kBAAkB,sBAW7B;AAEF,MAAM,wBAAwB,GAAG,CAAC,MAAc,EAAE,EAAE;IACnD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,eAAe,GAAG,CAAC,MAAc,EAAE,cAAwB,EAAU,EAAE;IAC5E,MAAM,SAAS,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;IAChD,MAAM,sBAAsB,GAAG,0BAA0B,CACxD,cAAc,EACd,SAAS,CACT,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,sBAAsB,CAAC;IAC7D,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,OAAiB,EAAU,EAAE;IACnD,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;IAC3D,OAAO,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,OAAiB,EAAU,EAAE;IACrD,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IACrC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,aAAa,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1E,CAAC;SAAM,CAAC;QACP,OAAO,aAAa,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;AACF,CAAC,CAAC;AAEF,MAAM,0BAA0B,GAAG,CAClC,OAAiB,EACjB,IAAY,EACH,EAAE;IACX,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACzE,MAAM,qBAAqB,GAAG,kBAAkB,CAAC,MAAM,CACtD,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,EAC7B,CAAC,CACD,CAAC;IACF,MAAM,QAAQ,GAAG,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;IACxD,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAI,IAAY,EAAE,QAAa,EAAS,EAAE;IAC3D,MAAM,aAAa,GAAU,EAAE,CAAC;IAEhC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;QACnC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;QAC5C,IAAI,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACP,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,OAAO,aAAa,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,KAAK,GAAG,CAAC,OAAa,EAAM,EAAE;IACnC,IAAI,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,KAAK,GAAG,CAAC,OAAa,EAAM,EAAE;IACnC,IAAI,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,OAAa,EAAM,EAAE;IACtC,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,aAAa,CAAC,WAAW,GAAG,CAAC,CAAC;aACnC,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;aAC/B,GAAG,CAAC,IAAI,QAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;SAAM,CAAC;QACP,OAAO,aAAa,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;AACF,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG,CAAC,OAAa,EAAM,EAAE;IACpC,IAAI,GAAG,GAAG,IAAI,QAAE,CAAC,CAAC,CAAC,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,QAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,KAAK,EAAK,OAAU,EAAE,EAAE;IAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC;IAEpC,OAAO;QACN,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;QAC/B,aAAa;KACb,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG,CAAI,KAAmB,EAAE,IAAY,EAAS,EAAE;IAC9D,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;SAC9C,IAAI,CAAC,IAAI,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC;SAC/B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF,MAAM,8BAA8B,GAAG,KAAK,EAC3C,UAAsB,EACtB,QAAqB,EACqB,EAAE;IAC5C,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,2CAA2C;IACxF,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC,CACvE,CAAC;IACF,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC,CAAC;AAEW,QAAA,YAAY,GAAG;IAC3B,iBAAiB,EAAjB,iCAAiB;IACjB,oBAAoB,EAApB,oCAAoB;IACpB,+BAA+B;IAC/B,sBAAsB;IACtB,qBAAqB;IACrB,wBAAwB;IACxB,yBAAyB;IACzB,cAAc;IACd,WAAW;IACX,WAAW;IACX,kBAAkB,EAAlB,0BAAkB;IAClB,wBAAwB;IACxB,eAAe;IACf,SAAS;IACT,YAAY;IACZ,MAAM;IACN,8BAA8B;IAC9B,IAAI,EAAE;QACL,GAAG,EAAE;YACJ,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,eAAe;SACvB;QACD,EAAE,EAAE;YACH,KAAK;YACL,KAAK;YACL,MAAM;YACN,QAAQ;SACR;KACD;CACD,CAAC;AACF,2CAA6D;AAApD,2HAAA,6BAA6B,OAAA;AACtC,iEAAgE;AAAvD,8HAAA,qBAAqB,OAAA;AAC9B,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA","sourcesContent":["import {\n\tAMM_RESERVE_PRECISION_EXP,\n\tBASE_PRECISION,\n\tBN,\n\tEvent,\n\tPRICE_PRECISION,\n\tOrderAction,\n\tOrderActionRecord,\n\tOrderRecord,\n\tPublicKey,\n\tQUOTE_PRECISION,\n\tZERO,\n\tPRICE_PRECISION_EXP,\n\tBASE_PRECISION_EXP,\n\tBigNum,\n\tMarketType,\n\tDriftClient,\n\tSPOT_MARKET_RATE_PRECISION_EXP,\n\tcalculateDepositRate,\n\tcalculateBorrowRate,\n\tgetTokenAmount,\n\tSpotBalanceType,\n\tSpotMarketConfig,\n} from '@drift-labs/sdk';\nimport {\n\tUIMatchedOrderRecordAndAction,\n\tUISerializableOrderActionRecord,\n} from '../serializableTypes';\nimport { getIfStakingVaultApr, getIfVaultBalance } from './insuranceFund';\nimport { AccountInfo, Connection } from '@solana/web3.js';\n\nexport const matchEnum = (enum1: any, enum2) => {\n\treturn JSON.stringify(enum1) === JSON.stringify(enum2);\n};\n\nfunction enumToObj(enumStr: string) {\n\tif (!enumStr) return undefined;\n\n\treturn {\n\t\t[enumStr ?? '']: {},\n\t};\n}\n\nfunction enumToStr(enumStr: Record<string, any>) {\n\treturn Object.keys(enumStr ?? {})?.[0];\n}\n\nexport const ENUM_UTILS = {\n\tmatch: matchEnum,\n\ttoObj: enumToObj,\n\ttoStr: enumToStr,\n};\n\nexport async function sleep(ms) {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\nconst getStringifiableObjectEntry = (value: any): [any, string] => {\n\t// If BN\n\t// if (value instanceof BN) { /* This method would be much safer but don't think it's possible to ensure that instances of classes match when they're in different npm packages */\n\tif (Object.keys(value).sort().join(',') === 'length,negative,red,words') {\n\t\treturn [value.toString(), '_bgnm_'];\n\t}\n\n\t// If PublicKey\n\t// if (value instanceof PublicKey) { { /* This method would be much safer but don't think it's possible to ensure that instances of classes match when they're in different npm packages */\n\tif (Object.keys(value).sort().join(',') === '_bn') {\n\t\treturn [value.toString(), '_pbky_'];\n\t}\n\n\tif (typeof value === 'object') {\n\t\treturn [encodeStringifiableObject(value), ''];\n\t}\n\n\treturn [value, ''];\n};\n\n/**\n * Converts an objects with potential Pubkeys and BNs in it into a form that can be JSON stringified. When pubkeys get converted a _pbky_ suffix will be added to their key, and _bgnm_ for BNs.\n *\n * e.g.\n * input : {\n * QuoteAmount: BN\n * }\n *\n * output: {\n * _bgnm_QuoteAmount: string\n * }\n * @param value\n * @returns\n */\nexport const encodeStringifiableObject = (value: any) => {\n\tif (typeof value !== 'object') return value;\n\n\tif (Array.isArray(value)) {\n\t\treturn value.map((entry) => encodeStringifiableObject(entry));\n\t}\n\n\tconst buildJsonObject = {};\n\n\tif (!value) return value;\n\n\tObject.entries(value).forEach(([key, val]) => {\n\t\tconst [convertedVal, keyTag] = getStringifiableObjectEntry(val);\n\t\tbuildJsonObject[`${keyTag}${key}`] = convertedVal;\n\t});\n\n\treturn buildJsonObject;\n};\n\n/**\n * Converts a parsed object with potential Pubkeys and BNs in it (in string form) to their proper form. Pubkey values must have a key starting in _pbky_ and BN values must have a key starting in _bnnm_\n *\n * * e.g.\n * input : {\n * _bgnm_QuoteAmount: string\n * }\n *\n * output: {\n * QuoteAmount: BN\n * }\n * @param value\n * @returns\n */\nexport const decodeStringifiableObject = (value: any) => {\n\tif (typeof value !== 'object') return value;\n\n\tif (Array.isArray(value)) {\n\t\treturn value.map((entry) => decodeStringifiableObject(entry));\n\t}\n\n\tconst buildJsonObject = {};\n\n\tObject.entries(value)\n\t\t.filter((val) => val != undefined && val != null)\n\t\t.forEach(([key, val]) => {\n\t\t\tif (key.match(/^_pbky_/)) {\n\t\t\t\tbuildJsonObject[key.replace('_pbky_', '')] = new PublicKey(val);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (key.match(/^_bgnm_/)) {\n\t\t\t\tbuildJsonObject[key.replace('_bgnm_', '')] = new BN(val as string);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (typeof val === 'object' && val != undefined && val != null) {\n\t\t\t\tbuildJsonObject[key] = decodeStringifiableObject(val);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tbuildJsonObject[key] = val;\n\t\t});\n\n\treturn buildJsonObject;\n};\n\nconst getChronologicalValueForOrderAction = (action: OrderAction) => {\n\treturn matchEnum(action, OrderAction.PLACE)\n\t\t? 0\n\t\t: matchEnum(action, OrderAction.FILL)\n\t\t? 1\n\t\t: 2;\n};\n\n/**\n * Returns 1 if the first Order is chronologically later than the second Order, -1 if before, 0 if equal\n * @param orderA\n * @param orderB\n * @returns\n */\nexport const getSortScoreForOrderRecords = (\n\torderA: { slot: number },\n\torderB: { slot: number }\n) => {\n\tif (orderA.slot !== orderB.slot) {\n\t\treturn orderA.slot > orderB.slot ? 1 : -1;\n\t}\n\n\treturn 0;\n};\n\nexport const getTradeInfoFromActionRecord = (\n\tactionRecord: PartialUISerializableOrderActionRecord\n) => {\n\treturn {\n\t\tts: actionRecord.ts,\n\t\tbaseAssetAmount: actionRecord.taker\n\t\t\t? actionRecord.takerOrderBaseAssetAmount\n\t\t\t: actionRecord.makerOrderBaseAssetAmount,\n\t\tbaseAssetAmountFilled: actionRecord.taker\n\t\t\t? actionRecord.takerOrderCumulativeBaseAssetAmountFilled\n\t\t\t: actionRecord.makerOrderCumulativeBaseAssetAmountFilled,\n\t\tquoteAssetAmountFilled: actionRecord.taker\n\t\t\t? actionRecord.takerOrderCumulativeQuoteAssetAmountFilled\n\t\t\t: actionRecord.makerOrderCumulativeQuoteAssetAmountFilled,\n\t};\n};\n\nexport type PartialOrderActionRecord =\n\t| PartialUISerializableOrderActionRecord\n\t| PartialOrderActionEventRecord;\n\nexport type PartialUISerializableOrderActionRecord = Pick<\n\tUISerializableOrderActionRecord,\n\t| 'quoteAssetAmountFilled'\n\t| 'baseAssetAmountFilled'\n\t| 'ts'\n\t| 'slot'\n\t| 'action'\n\t| 'fillRecordId'\n\t| 'taker'\n\t| 'takerOrderBaseAssetAmount'\n\t| 'makerOrderBaseAssetAmount'\n\t| 'takerOrderCumulativeBaseAssetAmountFilled'\n\t| 'makerOrderCumulativeBaseAssetAmountFilled'\n\t| 'takerOrderCumulativeQuoteAssetAmountFilled'\n\t| 'makerOrderCumulativeQuoteAssetAmountFilled'\n\t| 'oraclePrice'\n>;\n\nexport type PartialOrderActionEventRecord = Pick<\n\tEvent<OrderActionRecord>,\n\t| 'quoteAssetAmountFilled'\n\t| 'baseAssetAmountFilled'\n\t| 'ts'\n\t| 'slot'\n\t| 'action'\n\t| 'fillRecordId'\n\t| 'taker'\n\t| 'takerOrderBaseAssetAmount'\n\t| 'makerOrderBaseAssetAmount'\n\t| 'takerOrderCumulativeBaseAssetAmountFilled'\n\t| 'makerOrderCumulativeBaseAssetAmountFilled'\n\t| 'takerOrderCumulativeQuoteAssetAmountFilled'\n\t| 'makerOrderCumulativeQuoteAssetAmountFilled'\n>;\n\n/**\n * Returns 1 if the first Order is chronologically later than the second Order, -1 if before, 0 if equal\n * @param orderA\n * @param orderB\n * @returns\n */\nexport const getSortScoreForOrderActionRecords = (\n\torderA: PartialOrderActionRecord,\n\torderB: PartialOrderActionRecord\n) => {\n\tif (orderA.slot !== orderB.slot) {\n\t\treturn orderA.slot > orderB.slot ? 1 : -1;\n\t}\n\n\tif (!matchEnum(orderA.action, orderB.action)) {\n\t\t// @ts-ignore\n\t\tconst orderAActionVal = getChronologicalValueForOrderAction(orderA.action);\n\t\t// @ts-ignore\n\t\tconst orderBActionVal = getChronologicalValueForOrderAction(orderB.action);\n\n\t\treturn orderAActionVal > orderBActionVal ? 1 : -1;\n\t}\n\t// @ts-ignore\n\tif (orderA.fillRecordId && orderB.fillRecordId) {\n\t\tif (!orderA.fillRecordId.eq(orderB.fillRecordId)) {\n\t\t\t// @ts-ignore\n\t\t\treturn orderA.fillRecordId.gt(orderB.fillRecordId) ? 1 : -1;\n\t\t}\n\t}\n\n\treturn 0;\n};\n\nexport const sortUIMatchedOrderRecordAndAction = (\n\trecords: UIMatchedOrderRecordAndAction[],\n\tdirection: 'asc' | 'desc' = 'desc'\n) => {\n\tconst ascSortedRecords = records.sort((a, b) =>\n\t\tgetSortScoreForOrderActionRecords(a.actionRecord, b.actionRecord)\n\t);\n\n\treturn direction === 'desc' ? ascSortedRecords.reverse() : ascSortedRecords;\n};\n\nexport const sortUIOrderActionRecords = (\n\trecords: PartialUISerializableOrderActionRecord[],\n\tdirection: 'asc' | 'desc' = 'desc'\n) => {\n\tconst ascSortedRecords = records.sort(getSortScoreForOrderActionRecords);\n\n\treturn direction === 'desc' ? ascSortedRecords.reverse() : ascSortedRecords;\n};\n\nexport const sortUIOrderRecords = <T extends { slot: number }>(\n\trecords: T[],\n\tdirection: 'asc' | 'desc' = 'desc'\n) => {\n\tconst ascSortedRecords = records.sort(getSortScoreForOrderRecords);\n\n\treturn direction === 'desc' ? ascSortedRecords.reverse() : ascSortedRecords;\n};\n\nexport const sortOrderRecords = (\n\trecords: Event<OrderRecord>[],\n\tdirection: 'asc' | 'desc' = 'desc'\n) => {\n\tconst ascSortedRecords = records.sort(getSortScoreForOrderRecords);\n\n\treturn direction === 'desc' ? ascSortedRecords.reverse() : ascSortedRecords;\n};\n\nexport const getLatestOfTwoUIOrderRecords = <T extends { slot: number }>(\n\torderA: T,\n\torderB: T\n) => {\n\treturn getSortScoreForOrderRecords(orderA, orderB) === 1 ? orderA : orderB;\n};\n\nexport const getLatestOfTwoOrderRecords = <T extends { slot: number }>(\n\torderA: T,\n\torderB: T\n) => {\n\treturn getSortScoreForOrderRecords(orderA, orderB) === 1 ? orderA : orderB;\n};\n\nexport const getUIOrderRecordsLaterThanTarget = <T extends { slot: number }>(\n\ttarget: T,\n\trecords: T[]\n) =>\n\trecords.filter(\n\t\t(record) => getLatestOfTwoUIOrderRecords(record, target) === record\n\t);\n\n// Trade records are order records which have been filled\nexport const orderActionRecordIsTrade = (orderRecord: OrderActionRecord) =>\n\torderRecord.baseAssetAmountFilled.gt(ZERO) &&\n\t// @ts-ignore\n\tmatchEnum(orderRecord.action, OrderAction.FILL) &&\n\ttrue;\n\nexport const uiOrderActionRecordIsTrade = (\n\torderRecord: UISerializableOrderActionRecord\n) =>\n\torderRecord.baseAssetAmountFilled.gtZero() &&\n\tmatchEnum(orderRecord.action, OrderAction.FILL) &&\n\ttrue;\n\n// Trade records are order records which have been filled\nexport const filterTradeRecordsFromOrderActionRecords = (\n\torderRecords: OrderActionRecord[]\n): OrderActionRecord[] => orderRecords.filter(orderActionRecordIsTrade);\n\n// Trade records are order records which have been filled\nexport const filterTradeRecordsFromUIOrderRecords = (\n\torderRecords: UISerializableOrderActionRecord[]\n): UISerializableOrderActionRecord[] =>\n\torderRecords.filter(uiOrderActionRecordIsTrade);\n\n/**\n * Returns the average price for a given base amount and quote amount.\n * @param quoteAmount\n * @param baseAmount\n * @returns PRICE_PRECISION\n */\nexport const getPriceForBaseAndQuoteAmount = (\n\tquoteAmount: BN,\n\tbaseAmount: BN\n) => {\n\treturn quoteAmount\n\t\t.mul(PRICE_PRECISION)\n\t\t.mul(BASE_PRECISION)\n\t\t.div(QUOTE_PRECISION)\n\t\t.div(BigNum.from(baseAmount, BASE_PRECISION_EXP).val);\n};\n\nexport const getPriceForOrderRecord = (\n\torderRecord: Pick<\n\t\tOrderActionRecord,\n\t\t'quoteAssetAmountFilled' | 'baseAssetAmountFilled'\n\t>\n) => {\n\treturn getPriceForBaseAndQuoteAmount(\n\t\t// @ts-ignore\n\t\torderRecord.quoteAssetAmountFilled,\n\t\t// @ts-ignore\n\t\torderRecord.baseAssetAmountFilled\n\t);\n};\n\nexport const getPriceForUIOrderRecord = (\n\torderRecord: Pick<\n\t\tUISerializableOrderActionRecord,\n\t\t'quoteAssetAmountFilled' | 'baseAssetAmountFilled'\n\t>\n) => {\n\treturn orderRecord.quoteAssetAmountFilled\n\t\t.shiftTo(AMM_RESERVE_PRECISION_EXP)\n\t\t.shift(PRICE_PRECISION_EXP)\n\t\t.div(orderRecord.baseAssetAmountFilled.shiftTo(BASE_PRECISION_EXP))\n\t\t.shiftTo(PRICE_PRECISION_EXP);\n};\n\nexport const orderIsNull = (\n\torder: UISerializableOrderActionRecord | Event<OrderActionRecord>,\n\tside: 'taker' | 'maker'\n) => {\n\treturn side === 'taker' ? !order.taker : !order.maker;\n};\n\nexport const getAnchorEnumString = (enumVal: Record<string, unknown>) => {\n\treturn Object.keys(enumVal)[0];\n};\nexport class Ref<T> {\n\tpublic val: T;\n\n\tconstructor(val: T) {\n\t\tthis.val = val;\n\t}\n\n\tset(val: T) {\n\t\tthis.val = val;\n\t}\n\n\tget() {\n\t\treturn this.val;\n\t}\n}\n\nexport class Counter {\n\tprivate val = 0;\n\n\tget() {\n\t\treturn this.val;\n\t}\n\n\tincrement(value = 1) {\n\t\tthis.val += value;\n\t}\n\n\treset() {\n\t\tthis.val = 0;\n\t}\n}\n\n/**\n * A class which allows a group of switches to seperately turn a multiswitch on or off. The base state is the state of the \"multiswitch\" when all of the constituent switches are off. When any of the switches are \"on\" then the multiswitch flips to the opposite state\n *\n * If baseState is on => any switch being \"on\" will turn the multiswitch off.\n * If baseState is off => any switch being \"off\" will turn the multiswitch off.\n */\nexport class MultiSwitch {\n\tprivate switches: string[] = [];\n\tprivate switchValue = 0;\n\n\tconstructor(private baseState: 'on' | 'off' = 'off') {}\n\n\tprivate getSwitchKey(key: string) {\n\t\t// If first time using switch, add to list of switches\n\t\tif (!this.switches.includes(key)) {\n\t\t\tthis.switches.push(key);\n\t\t}\n\n\t\tconst switchIndex = this.switches.indexOf(key);\n\n\t\treturn 2 ** switchIndex;\n\t}\n\n\tpublic switchOn(key: string) {\n\t\tif (this.baseState === 'on') {\n\t\t\tthis._switchOff(key);\n\t\t\treturn;\n\t\t}\n\t\tthis._switchOn(key);\n\t}\n\n\tpublic switchOff(key: string) {\n\t\tif (this.baseState === 'on') {\n\t\t\tthis._switchOn(key);\n\t\t\treturn;\n\t\t}\n\t\tthis._switchOff(key);\n\t}\n\n\tprivate _switchOff(key: string) {\n\t\tconst switchKey = this.getSwitchKey(key);\n\n\t\tthis.switchValue &= ~switchKey;\n\t}\n\n\tprivate _switchOn(key: string) {\n\t\tconst switchKey = this.getSwitchKey(key);\n\n\t\tthis.switchValue |= switchKey;\n\t}\n\n\tpublic get isOn() {\n\t\t// When the base state is on, then if any switch is on the multi-switch is off\n\t\tif (this.baseState === 'on') {\n\t\t\treturn this.switchValue === 0;\n\t\t}\n\n\t\tif (this.baseState === 'off') {\n\t\t\treturn this.switchValue > 0;\n\t\t}\n\t}\n}\n\n/**\n * Returns the quote amount of the current open interest for a market, using the current oracle price\n * @param marketIndex\n * @param marketType\n * @param driftClient\n * @returns\n */\nconst getCurrentOpenInterestForMarket = (\n\tmarketIndex: number,\n\tmarketType: MarketType,\n\tdriftClient: DriftClient\n) => {\n\tif (ENUM_UTILS.match(marketType, MarketType.PERP)) {\n\t\tconst market = driftClient.getPerpMarketAccount(marketIndex);\n\t\tconst OI = BigNum.from(\n\t\t\tmarket.amm.baseAssetAmountLong.add(market.amm.baseAssetAmountShort.abs()),\n\t\t\tBASE_PRECISION_EXP\n\t\t);\n\n\t\tconst priceData = driftClient.getOraclePriceDataAndSlot(\n\t\t\tmarket.amm.oracle,\n\t\t\tmarket.amm.oracleSource\n\t\t);\n\n\t\tconst price = BigNum.from(priceData.data.price, PRICE_PRECISION_EXP);\n\n\t\tconst quoteOIforMarket = price.toNum() * OI.toNum();\n\n\t\treturn quoteOIforMarket;\n\t} else {\n\t\tthrow new Error('Invalid market type for Open Interest calculation');\n\t}\n};\n\n/**\n * Gets the deposit APR for a spot market, in percent\n * @param marketIndex\n * @param marketType\n * @param driftClient\n * @returns\n */\nconst getDepositAprForMarket = (\n\tmarketIndex: number,\n\tmarketType: MarketType,\n\tdriftClient: DriftClient\n) => {\n\tif (ENUM_UTILS.match(marketType, MarketType.SPOT)) {\n\t\tconst marketAccount = driftClient.getSpotMarketAccount(marketIndex);\n\n\t\tconst depositApr = BigNum.from(\n\t\t\tcalculateDepositRate(marketAccount),\n\t\t\tSPOT_MARKET_RATE_PRECISION_EXP\n\t\t);\n\n\t\tconst depositAprPct = depositApr.toNum() * 100;\n\n\t\treturn depositAprPct;\n\t} else {\n\t\tthrow new Error('Invalid market type for Deposit APR calculation');\n\t}\n};\n\n/**\n * Get's the borrow APR for a spot market, in percent\n * @param marketIndex\n * @param marketType\n * @param driftClient\n * @returns\n */\nconst getBorrowAprForMarket = (\n\tmarketIndex: number,\n\tmarketType: MarketType,\n\tdriftClient: DriftClient\n) => {\n\tif (ENUM_UTILS.match(marketType, MarketType.SPOT)) {\n\t\tconst marketAccount = driftClient.getSpotMarketAccount(marketIndex);\n\n\t\tconst depositApr = BigNum.from(\n\t\t\tcalculateBorrowRate(marketAccount),\n\t\t\tSPOT_MARKET_RATE_PRECISION_EXP\n\t\t);\n\n\t\tconst depositAprPct = depositApr.toNum() * 100;\n\n\t\treturn depositAprPct;\n\t} else {\n\t\tthrow new Error('Invalid market type for Borrow APR calculation');\n\t}\n};\n\nconst getTotalBorrowsForMarket = (\n\tmarket: SpotMarketConfig,\n\tdriftClient: DriftClient\n) => {\n\tconst marketAccount = driftClient.getSpotMarketAccount(market.marketIndex);\n\n\tconst totalBorrowsTokenAmount = getTokenAmount(\n\t\tmarketAccount.borrowBalance,\n\t\tdriftClient.getSpotMarketAccount(marketAccount.marketIndex),\n\t\tSpotBalanceType.BORROW\n\t);\n\n\tconst totalBorrowsAmountBigNum = BigNum.from(\n\t\ttotalBorrowsTokenAmount,\n\t\tmarket.precisionExp\n\t);\n\n\tconst priceData = driftClient.getOraclePriceDataAndSlot(\n\t\tmarketAccount.oracle,\n\t\tmarketAccount.oracleSource\n\t);\n\n\tconst price = BigNum.from(priceData.data.price, PRICE_PRECISION_EXP);\n\n\tconst totalBorrowsQuote = price.toNum() * totalBorrowsAmountBigNum.toNum();\n\n\treturn Number(totalBorrowsQuote.toFixed(2));\n};\n\nconst getTotalDepositsForMarket = (\n\tmarket: SpotMarketConfig,\n\tdriftClient: DriftClient\n) => {\n\tconst marketAccount = driftClient.getSpotMarketAccount(market.marketIndex);\n\n\tconst totalDepositsTokenAmount = getTokenAmount(\n\t\tmarketAccount.depositBalance,\n\t\tmarketAccount,\n\t\tSpotBalanceType.DEPOSIT\n\t);\n\n\tconst totalDepositsTokenAmountBigNum = BigNum.from(\n\t\ttotalDepositsTokenAmount,\n\t\tmarket.precisionExp\n\t);\n\n\tconst priceData = driftClient.getOraclePriceDataAndSlot(\n\t\tmarketAccount.oracle,\n\t\tmarketAccount.oracleSource\n\t);\n\n\tconst price = BigNum.from(priceData.data.price, PRICE_PRECISION_EXP);\n\n\tconst totalDepositsBase = totalDepositsTokenAmountBigNum.toNum();\n\tconst totalDepositsQuote =\n\t\tprice.toNum() * totalDepositsTokenAmountBigNum.toNum();\n\n\treturn {\n\t\ttotalDepositsBase,\n\t\ttotalDepositsQuote,\n\t};\n};\n\n/**\n * Check if numbers divide exactly, accounting for floating point division annoyingness\n * @param numerator\n * @param denominator\n * @returns\n */\nconst dividesExactly = (numerator: number, denominator: number) => {\n\tconst division = numerator / denominator;\n\tconst remainder = division % 1;\n\n\tif (remainder === 0) return true;\n\n\t// Because of floating point weirdness, we're just going to assume that if the remainder after dividing is less than 1/10^6 then the numbers do divide exactly\n\tif (Math.abs(remainder - 1) < 1 / 10 ** 6) return true;\n\n\treturn false;\n};\n\nconst toSnakeCase = (str: string): string =>\n\tstr.replace(/[^\\w]/g, '_').toLowerCase();\n\nconst toCamelCase = (str: string): string => {\n\tconst words = str.split(/[_\\-\\s]+/); // split on underscores, hyphens, and spaces\n\tconst firstWord = words[0].toLowerCase();\n\tconst restWords = words\n\t\t.slice(1)\n\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());\n\treturn [firstWord, ...restWords].join('');\n};\n\nexport const aprFromApy = (apy: number, compoundsPerYear: number) => {\n\tconst compoundedAmount = 1 + apy * 0.01;\n\tconst estimatedApr =\n\t\t(Math.pow(compoundedAmount, 1 / compoundsPerYear) - 1) * compoundsPerYear;\n\n\treturn estimatedApr * 100;\n};\n\n/**\n * Helper utility to get a sort score for \"tiered\" parameters.\n *\n * Example: Want to sort students by Grade, but fall back to using Age if they are equal. This method will accept an array for each student of [grade, age] and return the appropriate sort score for each.\n *\n * @param aScores\n * @param bScores\n * @returns\n */\nexport const getTieredSortScore = (aScores: number[], bScores: number[]) => {\n\tconst maxIndex = Math.max(aScores.length, bScores.length);\n\n\tfor (let i = 0; i < maxIndex; i++) {\n\t\tconst aScore = aScores[i] ?? Number.MIN_SAFE_INTEGER;\n\t\tconst bScore = bScores[i] ?? Number.MIN_SAFE_INTEGER;\n\n\t\tif (aScore !== bScore) return aScore - bScore;\n\t}\n\n\treturn 0;\n};\n\nconst normalizeBaseAssetSymbol = (symbol: string) => {\n\treturn symbol.replace(/^1M/, '');\n};\n\n/**\n * Returns the number of standard deviations between a target value and the history of values to compare it to.\n * @param target\n * @param previousValues\n * @returns\n */\nconst calculateZScore = (target: number, previousValues: number[]): number => {\n\tconst meanValue = calculateMean(previousValues);\n\tconst standardDeviationValue = calculateStandardDeviation(\n\t\tpreviousValues,\n\t\tmeanValue\n\t);\n\n\tconst zScore = (target - meanValue) / standardDeviationValue;\n\treturn zScore;\n};\n\nconst calculateMean = (numbers: number[]): number => {\n\tconst sum = numbers.reduce((total, num) => total + num, 0);\n\treturn sum / numbers.length;\n};\n\nconst calculateMedian = (numbers: number[]): number => {\n\tconst sortedNumbers = numbers.sort();\n\tconst middleIndex = Math.floor(sortedNumbers.length / 2);\n\tif (sortedNumbers.length % 2 === 0) {\n\t\treturn (sortedNumbers[middleIndex - 1] + sortedNumbers[middleIndex]) / 2;\n\t} else {\n\t\treturn sortedNumbers[middleIndex];\n\t}\n};\n\nconst calculateStandardDeviation = (\n\tnumbers: number[],\n\tmean: number\n): number => {\n\tconst squaredDifferences = numbers.map((num) => Math.pow(num - mean, 2));\n\tconst sumSquaredDifferences = squaredDifferences.reduce(\n\t\t(total, diff) => total + diff,\n\t\t0\n\t);\n\tconst variance = sumSquaredDifferences / numbers.length;\n\treturn Math.sqrt(variance);\n};\n\nconst glueArray = <T>(size: number, elements: T[]): T[][] => {\n\tconst gluedElements: T[][] = [];\n\n\telements.forEach((element, index) => {\n\t\tconst gluedIndex = Math.floor(index / size);\n\t\tif (gluedElements[gluedIndex]) {\n\t\t\tgluedElements[gluedIndex].push(element);\n\t\t} else {\n\t\t\tgluedElements[gluedIndex] = [element];\n\t\t}\n\t});\n\n\treturn gluedElements;\n};\n\nconst bnMin = (numbers: BN[]): BN => {\n\tlet min = numbers[0];\n\tfor (let i = 1; i < numbers.length; i++) {\n\t\tif (numbers[i].lt(min)) {\n\t\t\tmin = numbers[i];\n\t\t}\n\t}\n\treturn min;\n};\n\nconst bnMax = (numbers: BN[]): BN => {\n\tlet max = numbers[0];\n\tfor (let i = 1; i < numbers.length; i++) {\n\t\tif (numbers[i].gt(max)) {\n\t\t\tmax = numbers[i];\n\t\t}\n\t}\n\treturn max;\n};\n\nconst bnMedian = (numbers: BN[]): BN => {\n\tconst sortedNumbers = numbers.sort((a, b) => a.cmp(b));\n\tconst middleIndex = Math.floor(sortedNumbers.length / 2);\n\tif (sortedNumbers.length % 2 === 0) {\n\t\treturn sortedNumbers[middleIndex - 1]\n\t\t\t.add(sortedNumbers[middleIndex])\n\t\t\t.div(new BN(2));\n\t} else {\n\t\treturn sortedNumbers[middleIndex];\n\t}\n};\n\nconst bnMean = (numbers: BN[]): BN => {\n\tlet sum = new BN(0);\n\tfor (let i = 0; i < numbers.length; i++) {\n\t\tsum = sum.add(numbers[i]);\n\t}\n\treturn sum.div(new BN(numbers.length));\n};\n\nconst timedPromise = async <T>(promise: T) => {\n\tconst start = Date.now();\n\tconst promiseResult = await promise;\n\n\treturn {\n\t\tpromiseTime: Date.now() - start,\n\t\tpromiseResult,\n\t};\n};\n\nconst chunks = <T>(array: readonly T[], size: number): T[][] => {\n\treturn new Array(Math.ceil(array.length / size))\n\t\t.fill(null)\n\t\t.map((_, index) => index * size)\n\t\t.map((begin) => array.slice(begin, begin + size));\n};\n\nconst getMultipleAccountsInfoChunked = async (\n\tconnection: Connection,\n\taccounts: PublicKey[]\n): Promise<(AccountInfo<Buffer> | null)[]> => {\n\tconst accountChunks = chunks(accounts, 100); // 100 is limit for getMultipleAccountsInfo\n\tconst responses = await Promise.all(\n\t\taccountChunks.map((chunk) => connection.getMultipleAccountsInfo(chunk))\n\t);\n\treturn responses.flat();\n};\n\nexport const COMMON_UTILS = {\n\tgetIfVaultBalance,\n\tgetIfStakingVaultApr,\n\tgetCurrentOpenInterestForMarket,\n\tgetDepositAprForMarket,\n\tgetBorrowAprForMarket,\n\tgetTotalBorrowsForMarket,\n\tgetTotalDepositsForMarket,\n\tdividesExactly,\n\ttoSnakeCase,\n\ttoCamelCase,\n\tgetTieredSortScore,\n\tnormalizeBaseAssetSymbol,\n\tcalculateZScore,\n\tglueArray,\n\ttimedPromise,\n\tchunks,\n\tgetMultipleAccountsInfoChunked,\n\tMATH: {\n\t\tNUM: {\n\t\t\tmean: calculateMean,\n\t\t\tmedian: calculateMedian,\n\t\t},\n\t\tBN: {\n\t\t\tbnMax,\n\t\t\tbnMin,\n\t\t\tbnMean,\n\t\t\tbnMedian,\n\t\t},\n\t},\n};\nexport { getSwiftConfirmationTimeoutMs } from './signedMsgs';\nexport { ResultSlotIncrementer } from './ResultSlotIncrementer';\nexport { MultiplexWebSocket } from './MultiplexWebSocket';\n"]}
|
package/lib/utils/math.js
CHANGED
|
@@ -50,7 +50,7 @@ const calculateBidAskAndmarkPrice = (l2, oraclePrice) => {
|
|
|
50
50
|
};
|
|
51
51
|
};
|
|
52
52
|
const calculateSpreadQuote = (bestBidPrice, bestAskPrice) => {
|
|
53
|
-
return
|
|
53
|
+
return sdk_1.BN.max(bestAskPrice.sub(bestBidPrice), sdk_1.ZERO);
|
|
54
54
|
};
|
|
55
55
|
function calculateSpreadPct(markPricePrice, spreadQuote) {
|
|
56
56
|
return spreadQuote.muln(100).mul(sdk_1.PERCENTAGE_PRECISION).div(markPricePrice);
|
package/lib/utils/math.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"math.js","sourceRoot":"","sources":["../../src/utils/math.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"math.js","sourceRoot":"","sources":["../../src/utils/math.ts"],"names":[],"mappings":"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","sourcesContent":["import { BN, L2OrderBook, PERCENTAGE_PRECISION, ZERO } from '@drift-labs/sdk';\n\nconst calculateMarkPrice = (\n\tbestBidPrice?: BN,\n\tbestAskPrice?: BN,\n\toraclePrice?: BN\n) => {\n\tconst bid = bestBidPrice;\n\tconst ask = bestAskPrice;\n\n\tlet mid: BN;\n\n\t// if bid/ask cross, force it to be the one closer to oracle, if oracle is in the middle, use oracle price\n\tif (bid && ask && bid.gt(ask) && oraclePrice) {\n\t\tif (bid.gt(oraclePrice) && ask.gt(oraclePrice)) {\n\t\t\tmid = BN.min(bid, ask);\n\t\t} else if (bid.lt(oraclePrice) && ask.lt(oraclePrice)) {\n\t\t\tmid = BN.max(bid, ask);\n\t\t} else {\n\t\t\tmid = oraclePrice;\n\t\t}\n\t} else {\n\t\tif (bid && ask) {\n\t\t\tmid = bid.add(ask).divn(2);\n\t\t} else if (oraclePrice) {\n\t\t\tmid = oraclePrice;\n\t\t} else {\n\t\t\tmid = undefined;\n\t\t}\n\t}\n\n\treturn mid;\n};\n\nconst calculateBidAskAndmarkPrice = (l2: L2OrderBook, oraclePrice?: BN) => {\n\tconst bestBidPrice = l2.bids.reduce((previousMax, currentBid) => {\n\t\tif (!previousMax) return currentBid.price;\n\t\treturn BN.max(currentBid.price, previousMax);\n\t}, undefined as BN);\n\n\tconst bestAskPrice = l2.asks.reduce((previousMin, currentBid) => {\n\t\tif (!previousMin) return currentBid.price;\n\t\treturn BN.min(currentBid.price, previousMin);\n\t}, undefined as BN);\n\n\tconst markPrice = calculateMarkPrice(bestBidPrice, bestAskPrice, oraclePrice);\n\n\treturn {\n\t\tbestBidPrice,\n\t\tbestAskPrice,\n\t\tmarkPrice,\n\t};\n};\n\nconst calculateSpreadQuote = (bestBidPrice: BN, bestAskPrice: BN) => {\n\treturn BN.max(bestAskPrice.sub(bestBidPrice), ZERO);\n};\n\nfunction calculateSpreadPct(markPricePrice: BN, spreadQuote: BN) {\n\treturn spreadQuote.muln(100).mul(PERCENTAGE_PRECISION).div(markPricePrice);\n}\n\nconst calculateSpread = (bestBidPrice: BN, bestAskPrice: BN, markPrice: BN) => {\n\tconst spreadQuote = calculateSpreadQuote(bestBidPrice, bestAskPrice);\n\tconst spreadPct = calculateSpreadPct(markPrice, spreadQuote);\n\n\treturn {\n\t\tspreadPct,\n\t\tspreadQuote,\n\t};\n};\n\nconst calculateSpreadBidAskMark = (\n\tl2: Pick<L2OrderBook, 'bids' | 'asks'>,\n\toraclePrice?: BN\n) => {\n\tif (l2.asks.length === 0 || l2.bids.length === 0) {\n\t\treturn {\n\t\t\tspreadQuote: undefined,\n\t\t\tspreadPct: undefined,\n\t\t\tmarkPrice: undefined,\n\t\t\tbestBidPrice: undefined,\n\t\t\tbestAskPrice: undefined,\n\t\t};\n\t}\n\n\tconst { bestBidPrice, bestAskPrice, markPrice } = calculateBidAskAndmarkPrice(\n\t\tl2,\n\t\toraclePrice\n\t);\n\n\tconst { spreadPct, spreadQuote } = calculateSpread(\n\t\tbestBidPrice,\n\t\tbestAskPrice,\n\t\tmarkPrice\n\t);\n\treturn {\n\t\tbestBidPrice,\n\t\tbestAskPrice,\n\t\tmarkPrice,\n\t\tspreadPct,\n\t\tspreadQuote,\n\t};\n};\n\nexport const COMMON_MATH = {\n\tcalculateSpreadBidAskMark,\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getSwiftConfirmationTimeoutMs(auctionDurationSlots: number, multiplier?: number): number;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSwiftConfirmationTimeoutMs = void 0;
|
|
4
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
5
|
+
function getSwiftConfirmationTimeoutMs(auctionDurationSlots, multiplier) {
|
|
6
|
+
const baseMs = ((auctionDurationSlots !== null && auctionDurationSlots !== void 0 ? auctionDurationSlots : 0) + 15) * sdk_1.SLOT_TIME_ESTIMATE_MS;
|
|
7
|
+
return baseMs * (multiplier !== null && multiplier !== void 0 ? multiplier : 1);
|
|
8
|
+
}
|
|
9
|
+
exports.getSwiftConfirmationTimeoutMs = getSwiftConfirmationTimeoutMs;
|
|
10
|
+
//# sourceMappingURL=signedMsgs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signedMsgs.js","sourceRoot":"","sources":["../../src/utils/signedMsgs.ts"],"names":[],"mappings":";;;AAAA,yCAAwD;AAExD,SAAgB,6BAA6B,CAC5C,oBAA4B,EAC5B,UAAmB;IAEnB,MAAM,MAAM,GAAG,CAAC,CAAC,oBAAoB,aAApB,oBAAoB,cAApB,oBAAoB,GAAI,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,2BAAqB,CAAC;IAC1E,OAAO,MAAM,GAAG,CAAC,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,CAAC,CAAC,CAAC;AACnC,CAAC;AAND,sEAMC","sourcesContent":["import { SLOT_TIME_ESTIMATE_MS } from '@drift-labs/sdk';\n\nexport function getSwiftConfirmationTimeoutMs(\n\tauctionDurationSlots: number,\n\tmultiplier?: number\n): number {\n\tconst baseMs = ((auctionDurationSlots ?? 0) + 15) * SLOT_TIME_ESTIMATE_MS;\n\treturn baseMs * (multiplier ?? 1);\n}\n"]}
|