@metamask-previews/core-backend 2.1.0-preview-8e6c5423 → 3.0.0-preview-5cda4487
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/CHANGELOG.md +35 -1
- package/dist/AccountActivityService.cjs +23 -10
- package/dist/AccountActivityService.cjs.map +1 -1
- package/dist/AccountActivityService.d.cts +3 -1
- package/dist/AccountActivityService.d.cts.map +1 -1
- package/dist/AccountActivityService.d.mts +3 -1
- package/dist/AccountActivityService.d.mts.map +1 -1
- package/dist/AccountActivityService.mjs +22 -9
- package/dist/AccountActivityService.mjs.map +1 -1
- package/dist/BackendWebSocketService-method-action-types.cjs.map +1 -1
- package/dist/BackendWebSocketService-method-action-types.d.cts +21 -1
- package/dist/BackendWebSocketService-method-action-types.d.cts.map +1 -1
- package/dist/BackendWebSocketService-method-action-types.d.mts +21 -1
- package/dist/BackendWebSocketService-method-action-types.d.mts.map +1 -1
- package/dist/BackendWebSocketService-method-action-types.mjs.map +1 -1
- package/dist/BackendWebSocketService.cjs +94 -22
- package/dist/BackendWebSocketService.cjs.map +1 -1
- package/dist/BackendWebSocketService.d.cts +17 -2
- package/dist/BackendWebSocketService.d.cts.map +1 -1
- package/dist/BackendWebSocketService.d.mts +17 -2
- package/dist/BackendWebSocketService.d.mts.map +1 -1
- package/dist/BackendWebSocketService.mjs +94 -22
- package/dist/BackendWebSocketService.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -21,6 +21,26 @@ export type BackendWebSocketServiceDisconnectAction = {
|
|
|
21
21
|
type: `BackendWebSocketService:disconnect`;
|
|
22
22
|
handler: BackendWebSocketService['disconnect'];
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Forces a WebSocket reconnection to clean up subscription state
|
|
26
|
+
*
|
|
27
|
+
* This method is useful when subscription state may be out of sync and needs to be reset.
|
|
28
|
+
* It performs a controlled disconnect-then-reconnect sequence:
|
|
29
|
+
* - Disconnects cleanly to trigger subscription cleanup
|
|
30
|
+
* - Schedules reconnection with exponential backoff to prevent rapid loops
|
|
31
|
+
* - All subscriptions will be cleaned up automatically on disconnect
|
|
32
|
+
*
|
|
33
|
+
* Use cases:
|
|
34
|
+
* - Recovering from subscription/unsubscription issues
|
|
35
|
+
* - Cleaning up orphaned subscriptions
|
|
36
|
+
* - Forcing a fresh subscription state
|
|
37
|
+
*
|
|
38
|
+
* @returns Promise that resolves when disconnection is complete (reconnection is scheduled)
|
|
39
|
+
*/
|
|
40
|
+
export type BackendWebSocketServiceForceReconnectionAction = {
|
|
41
|
+
type: `BackendWebSocketService:forceReconnection`;
|
|
42
|
+
handler: BackendWebSocketService['forceReconnection'];
|
|
43
|
+
};
|
|
24
44
|
/**
|
|
25
45
|
* Sends a message through the WebSocket
|
|
26
46
|
*
|
|
@@ -142,5 +162,5 @@ export type BackendWebSocketServiceSubscribeAction = {
|
|
|
142
162
|
/**
|
|
143
163
|
* Union of all BackendWebSocketService action types.
|
|
144
164
|
*/
|
|
145
|
-
export type BackendWebSocketServiceMethodActions = BackendWebSocketServiceConnectAction | BackendWebSocketServiceDisconnectAction | BackendWebSocketServiceSendMessageAction | BackendWebSocketServiceSendRequestAction | BackendWebSocketServiceGetConnectionInfoAction | BackendWebSocketServiceGetSubscriptionsByChannelAction | BackendWebSocketServiceChannelHasSubscriptionAction | BackendWebSocketServiceFindSubscriptionsByChannelPrefixAction | BackendWebSocketServiceAddChannelCallbackAction | BackendWebSocketServiceRemoveChannelCallbackAction | BackendWebSocketServiceGetChannelCallbacksAction | BackendWebSocketServiceSubscribeAction;
|
|
165
|
+
export type BackendWebSocketServiceMethodActions = BackendWebSocketServiceConnectAction | BackendWebSocketServiceDisconnectAction | BackendWebSocketServiceForceReconnectionAction | BackendWebSocketServiceSendMessageAction | BackendWebSocketServiceSendRequestAction | BackendWebSocketServiceGetConnectionInfoAction | BackendWebSocketServiceGetSubscriptionsByChannelAction | BackendWebSocketServiceChannelHasSubscriptionAction | BackendWebSocketServiceFindSubscriptionsByChannelPrefixAction | BackendWebSocketServiceAddChannelCallbackAction | BackendWebSocketServiceRemoveChannelCallbackAction | BackendWebSocketServiceGetChannelCallbacksAction | BackendWebSocketServiceSubscribeAction;
|
|
146
166
|
//# sourceMappingURL=BackendWebSocketService-method-action-types.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackendWebSocketService-method-action-types.d.mts","sourceRoot":"","sources":["../src/BackendWebSocketService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,sCAAkC;AAEzE;;;;GAIG;AACH,MAAM,MAAM,oCAAoC,GAAG;IACjD,IAAI,EAAE,iCAAiC,CAAC;IACxC,OAAO,EAAE,uBAAuB,CAAC,SAAS,CAAC,CAAC;CAC7C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,uCAAuC,GAAG;IACpD,IAAI,EAAE,oCAAoC,CAAC;IAC3C,OAAO,EAAE,uBAAuB,CAAC,YAAY,CAAC,CAAC;CAChD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,wCAAwC,GAAG;IACrD,IAAI,EAAE,qCAAqC,CAAC;IAC5C,OAAO,EAAE,uBAAuB,CAAC,aAAa,CAAC,CAAC;CACjD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,wCAAwC,GAAG;IACrD,IAAI,EAAE,qCAAqC,CAAC;IAC5C,OAAO,EAAE,uBAAuB,CAAC,aAAa,CAAC,CAAC;CACjD,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,8CAA8C,GAAG;IAC3D,IAAI,EAAE,2CAA2C,CAAC;IAClD,OAAO,EAAE,uBAAuB,CAAC,mBAAmB,CAAC,CAAC;CACvD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,sDAAsD,GAAG;IACnE,IAAI,EAAE,mDAAmD,CAAC;IAC1D,OAAO,EAAE,uBAAuB,CAAC,2BAA2B,CAAC,CAAC;CAC/D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,mDAAmD,GAAG;IAChE,IAAI,EAAE,gDAAgD,CAAC;IACvD,OAAO,EAAE,uBAAuB,CAAC,wBAAwB,CAAC,CAAC;CAC5D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,6DAA6D,GAAG;IAC1E,IAAI,EAAE,0DAA0D,CAAC;IACjE,OAAO,EAAE,uBAAuB,CAAC,kCAAkC,CAAC,CAAC;CACtE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,MAAM,+CAA+C,GAAG;IAC5D,IAAI,EAAE,4CAA4C,CAAC;IACnD,OAAO,EAAE,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;CACxD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,kDAAkD,GAAG;IAC/D,IAAI,EAAE,+CAA+C,CAAC;IACtD,OAAO,EAAE,uBAAuB,CAAC,uBAAuB,CAAC,CAAC;CAC3D,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gDAAgD,GAAG;IAC7D,IAAI,EAAE,6CAA6C,CAAC;IACpD,OAAO,EAAE,uBAAuB,CAAC,qBAAqB,CAAC,CAAC;CACzD,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,sCAAsC,GAAG;IACnD,IAAI,EAAE,mCAAmC,CAAC;IAC1C,OAAO,EAAE,uBAAuB,CAAC,WAAW,CAAC,CAAC;CAC/C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oCAAoC,GAC5C,oCAAoC,GACpC,uCAAuC,GACvC,wCAAwC,GACxC,wCAAwC,GACxC,8CAA8C,GAC9C,sDAAsD,GACtD,mDAAmD,GACnD,6DAA6D,GAC7D,+CAA+C,GAC/C,kDAAkD,GAClD,gDAAgD,GAChD,sCAAsC,CAAC"}
|
|
1
|
+
{"version":3,"file":"BackendWebSocketService-method-action-types.d.mts","sourceRoot":"","sources":["../src/BackendWebSocketService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,sCAAkC;AAEzE;;;;GAIG;AACH,MAAM,MAAM,oCAAoC,GAAG;IACjD,IAAI,EAAE,iCAAiC,CAAC;IACxC,OAAO,EAAE,uBAAuB,CAAC,SAAS,CAAC,CAAC;CAC7C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,uCAAuC,GAAG;IACpD,IAAI,EAAE,oCAAoC,CAAC;IAC3C,OAAO,EAAE,uBAAuB,CAAC,YAAY,CAAC,CAAC;CAChD,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,8CAA8C,GAAG;IAC3D,IAAI,EAAE,2CAA2C,CAAC;IAClD,OAAO,EAAE,uBAAuB,CAAC,mBAAmB,CAAC,CAAC;CACvD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,wCAAwC,GAAG;IACrD,IAAI,EAAE,qCAAqC,CAAC;IAC5C,OAAO,EAAE,uBAAuB,CAAC,aAAa,CAAC,CAAC;CACjD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,wCAAwC,GAAG;IACrD,IAAI,EAAE,qCAAqC,CAAC;IAC5C,OAAO,EAAE,uBAAuB,CAAC,aAAa,CAAC,CAAC;CACjD,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,8CAA8C,GAAG;IAC3D,IAAI,EAAE,2CAA2C,CAAC;IAClD,OAAO,EAAE,uBAAuB,CAAC,mBAAmB,CAAC,CAAC;CACvD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,sDAAsD,GAAG;IACnE,IAAI,EAAE,mDAAmD,CAAC;IAC1D,OAAO,EAAE,uBAAuB,CAAC,2BAA2B,CAAC,CAAC;CAC/D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,mDAAmD,GAAG;IAChE,IAAI,EAAE,gDAAgD,CAAC;IACvD,OAAO,EAAE,uBAAuB,CAAC,wBAAwB,CAAC,CAAC;CAC5D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,6DAA6D,GAAG;IAC1E,IAAI,EAAE,0DAA0D,CAAC;IACjE,OAAO,EAAE,uBAAuB,CAAC,kCAAkC,CAAC,CAAC;CACtE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,MAAM,+CAA+C,GAAG;IAC5D,IAAI,EAAE,4CAA4C,CAAC;IACnD,OAAO,EAAE,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;CACxD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,kDAAkD,GAAG;IAC/D,IAAI,EAAE,+CAA+C,CAAC;IACtD,OAAO,EAAE,uBAAuB,CAAC,uBAAuB,CAAC,CAAC;CAC3D,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gDAAgD,GAAG;IAC7D,IAAI,EAAE,6CAA6C,CAAC;IACpD,OAAO,EAAE,uBAAuB,CAAC,qBAAqB,CAAC,CAAC;CACzD,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,sCAAsC,GAAG;IACnD,IAAI,EAAE,mCAAmC,CAAC;IAC1C,OAAO,EAAE,uBAAuB,CAAC,WAAW,CAAC,CAAC;CAC/C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oCAAoC,GAC5C,oCAAoC,GACpC,uCAAuC,GACvC,8CAA8C,GAC9C,wCAAwC,GACxC,wCAAwC,GACxC,8CAA8C,GAC9C,sDAAsD,GACtD,mDAAmD,GACnD,6DAA6D,GAC7D,+CAA+C,GAC/C,kDAAkD,GAClD,gDAAgD,GAChD,sCAAsC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackendWebSocketService-method-action-types.mjs","sourceRoot":"","sources":["../src/BackendWebSocketService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated by `scripts/generate-method-action-types.ts`.\n * Do not edit manually.\n */\n\nimport type { BackendWebSocketService } from './BackendWebSocketService';\n\n/**\n * Establishes WebSocket connection\n *\n * @returns Promise that resolves when connection is established\n */\nexport type BackendWebSocketServiceConnectAction = {\n type: `BackendWebSocketService:connect`;\n handler: BackendWebSocketService['connect'];\n};\n\n/**\n * Closes WebSocket connection\n *\n * @returns Promise that resolves when disconnection is complete\n */\nexport type BackendWebSocketServiceDisconnectAction = {\n type: `BackendWebSocketService:disconnect`;\n handler: BackendWebSocketService['disconnect'];\n};\n\n/**\n * Sends a message through the WebSocket\n *\n * @param message - The message to send\n * @returns Promise that resolves when message is sent\n */\nexport type BackendWebSocketServiceSendMessageAction = {\n type: `BackendWebSocketService:sendMessage`;\n handler: BackendWebSocketService['sendMessage'];\n};\n\n/**\n * Sends a request and waits for a correlated response\n *\n * @param message - The request message\n * @returns Promise that resolves with the response data\n */\nexport type BackendWebSocketServiceSendRequestAction = {\n type: `BackendWebSocketService:sendRequest`;\n handler: BackendWebSocketService['sendRequest'];\n};\n\n/**\n * Gets current connection information\n *\n * @returns Current connection status and details\n */\nexport type BackendWebSocketServiceGetConnectionInfoAction = {\n type: `BackendWebSocketService:getConnectionInfo`;\n handler: BackendWebSocketService['getConnectionInfo'];\n};\n\n/**\n * Gets all subscription information for a specific channel\n *\n * @param channel - The channel name to look up\n * @returns Array of subscription details for all subscriptions containing the channel\n */\nexport type BackendWebSocketServiceGetSubscriptionsByChannelAction = {\n type: `BackendWebSocketService:getSubscriptionsByChannel`;\n handler: BackendWebSocketService['getSubscriptionsByChannel'];\n};\n\n/**\n * Checks if a channel has a subscription\n *\n * @param channel - The channel name to check\n * @returns True if the channel has a subscription, false otherwise\n */\nexport type BackendWebSocketServiceChannelHasSubscriptionAction = {\n type: `BackendWebSocketService:channelHasSubscription`;\n handler: BackendWebSocketService['channelHasSubscription'];\n};\n\n/**\n * Finds all subscriptions that have channels starting with the specified prefix\n *\n * @param channelPrefix - The channel prefix to search for (e.g., \"account-activity.v1\")\n * @returns Array of subscription info for matching subscriptions\n */\nexport type BackendWebSocketServiceFindSubscriptionsByChannelPrefixAction = {\n type: `BackendWebSocketService:findSubscriptionsByChannelPrefix`;\n handler: BackendWebSocketService['findSubscriptionsByChannelPrefix'];\n};\n\n/**\n * Register a callback for specific channels\n *\n * @param options - Channel callback configuration\n * @param options.channelName - Channel name to match exactly\n * @param options.callback - Function to call when channel matches\n *\n * @example\n * ```typescript\n * // Listen to specific account activity channel\n * webSocketService.addChannelCallback({\n * channelName: 'account-activity.v1.eip155:0:0x1234...',\n * callback: (notification) => {\n * console.log('Account activity:', notification.data);\n * }\n * });\n *\n * // Listen to system notifications channel\n * webSocketService.addChannelCallback({\n * channelName: 'system-notifications.v1',\n * callback: (notification) => {\n * console.log('System notification:', notification.data);\n * }\n * });\n * ```\n */\nexport type BackendWebSocketServiceAddChannelCallbackAction = {\n type: `BackendWebSocketService:addChannelCallback`;\n handler: BackendWebSocketService['addChannelCallback'];\n};\n\n/**\n * Remove a channel callback\n *\n * @param channelName - The channel name to remove callback for\n * @returns True if callback was found and removed, false otherwise\n */\nexport type BackendWebSocketServiceRemoveChannelCallbackAction = {\n type: `BackendWebSocketService:removeChannelCallback`;\n handler: BackendWebSocketService['removeChannelCallback'];\n};\n\n/**\n * Get all registered channel callbacks (for debugging)\n */\nexport type BackendWebSocketServiceGetChannelCallbacksAction = {\n type: `BackendWebSocketService:getChannelCallbacks`;\n handler: BackendWebSocketService['getChannelCallbacks'];\n};\n\n/**\n * Create and manage a subscription with direct callback routing\n *\n * @param options - Subscription configuration\n * @param options.channels - Array of channel names to subscribe to\n * @param options.callback - Callback function for handling notifications\n * @returns Promise that resolves with subscription object containing unsubscribe method\n */\nexport type BackendWebSocketServiceSubscribeAction = {\n type: `BackendWebSocketService:subscribe`;\n handler: BackendWebSocketService['subscribe'];\n};\n\n/**\n * Union of all BackendWebSocketService action types.\n */\nexport type BackendWebSocketServiceMethodActions =\n | BackendWebSocketServiceConnectAction\n | BackendWebSocketServiceDisconnectAction\n | BackendWebSocketServiceSendMessageAction\n | BackendWebSocketServiceSendRequestAction\n | BackendWebSocketServiceGetConnectionInfoAction\n | BackendWebSocketServiceGetSubscriptionsByChannelAction\n | BackendWebSocketServiceChannelHasSubscriptionAction\n | BackendWebSocketServiceFindSubscriptionsByChannelPrefixAction\n | BackendWebSocketServiceAddChannelCallbackAction\n | BackendWebSocketServiceRemoveChannelCallbackAction\n | BackendWebSocketServiceGetChannelCallbacksAction\n | BackendWebSocketServiceSubscribeAction;\n"]}
|
|
1
|
+
{"version":3,"file":"BackendWebSocketService-method-action-types.mjs","sourceRoot":"","sources":["../src/BackendWebSocketService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated by `scripts/generate-method-action-types.ts`.\n * Do not edit manually.\n */\n\nimport type { BackendWebSocketService } from './BackendWebSocketService';\n\n/**\n * Establishes WebSocket connection\n *\n * @returns Promise that resolves when connection is established\n */\nexport type BackendWebSocketServiceConnectAction = {\n type: `BackendWebSocketService:connect`;\n handler: BackendWebSocketService['connect'];\n};\n\n/**\n * Closes WebSocket connection\n *\n * @returns Promise that resolves when disconnection is complete\n */\nexport type BackendWebSocketServiceDisconnectAction = {\n type: `BackendWebSocketService:disconnect`;\n handler: BackendWebSocketService['disconnect'];\n};\n\n/**\n * Forces a WebSocket reconnection to clean up subscription state\n *\n * This method is useful when subscription state may be out of sync and needs to be reset.\n * It performs a controlled disconnect-then-reconnect sequence:\n * - Disconnects cleanly to trigger subscription cleanup\n * - Schedules reconnection with exponential backoff to prevent rapid loops\n * - All subscriptions will be cleaned up automatically on disconnect\n *\n * Use cases:\n * - Recovering from subscription/unsubscription issues\n * - Cleaning up orphaned subscriptions\n * - Forcing a fresh subscription state\n *\n * @returns Promise that resolves when disconnection is complete (reconnection is scheduled)\n */\nexport type BackendWebSocketServiceForceReconnectionAction = {\n type: `BackendWebSocketService:forceReconnection`;\n handler: BackendWebSocketService['forceReconnection'];\n};\n\n/**\n * Sends a message through the WebSocket\n *\n * @param message - The message to send\n * @returns Promise that resolves when message is sent\n */\nexport type BackendWebSocketServiceSendMessageAction = {\n type: `BackendWebSocketService:sendMessage`;\n handler: BackendWebSocketService['sendMessage'];\n};\n\n/**\n * Sends a request and waits for a correlated response\n *\n * @param message - The request message\n * @returns Promise that resolves with the response data\n */\nexport type BackendWebSocketServiceSendRequestAction = {\n type: `BackendWebSocketService:sendRequest`;\n handler: BackendWebSocketService['sendRequest'];\n};\n\n/**\n * Gets current connection information\n *\n * @returns Current connection status and details\n */\nexport type BackendWebSocketServiceGetConnectionInfoAction = {\n type: `BackendWebSocketService:getConnectionInfo`;\n handler: BackendWebSocketService['getConnectionInfo'];\n};\n\n/**\n * Gets all subscription information for a specific channel\n *\n * @param channel - The channel name to look up\n * @returns Array of subscription details for all subscriptions containing the channel\n */\nexport type BackendWebSocketServiceGetSubscriptionsByChannelAction = {\n type: `BackendWebSocketService:getSubscriptionsByChannel`;\n handler: BackendWebSocketService['getSubscriptionsByChannel'];\n};\n\n/**\n * Checks if a channel has a subscription\n *\n * @param channel - The channel name to check\n * @returns True if the channel has a subscription, false otherwise\n */\nexport type BackendWebSocketServiceChannelHasSubscriptionAction = {\n type: `BackendWebSocketService:channelHasSubscription`;\n handler: BackendWebSocketService['channelHasSubscription'];\n};\n\n/**\n * Finds all subscriptions that have channels starting with the specified prefix\n *\n * @param channelPrefix - The channel prefix to search for (e.g., \"account-activity.v1\")\n * @returns Array of subscription info for matching subscriptions\n */\nexport type BackendWebSocketServiceFindSubscriptionsByChannelPrefixAction = {\n type: `BackendWebSocketService:findSubscriptionsByChannelPrefix`;\n handler: BackendWebSocketService['findSubscriptionsByChannelPrefix'];\n};\n\n/**\n * Register a callback for specific channels\n *\n * @param options - Channel callback configuration\n * @param options.channelName - Channel name to match exactly\n * @param options.callback - Function to call when channel matches\n *\n * @example\n * ```typescript\n * // Listen to specific account activity channel\n * webSocketService.addChannelCallback({\n * channelName: 'account-activity.v1.eip155:0:0x1234...',\n * callback: (notification) => {\n * console.log('Account activity:', notification.data);\n * }\n * });\n *\n * // Listen to system notifications channel\n * webSocketService.addChannelCallback({\n * channelName: 'system-notifications.v1',\n * callback: (notification) => {\n * console.log('System notification:', notification.data);\n * }\n * });\n * ```\n */\nexport type BackendWebSocketServiceAddChannelCallbackAction = {\n type: `BackendWebSocketService:addChannelCallback`;\n handler: BackendWebSocketService['addChannelCallback'];\n};\n\n/**\n * Remove a channel callback\n *\n * @param channelName - The channel name to remove callback for\n * @returns True if callback was found and removed, false otherwise\n */\nexport type BackendWebSocketServiceRemoveChannelCallbackAction = {\n type: `BackendWebSocketService:removeChannelCallback`;\n handler: BackendWebSocketService['removeChannelCallback'];\n};\n\n/**\n * Get all registered channel callbacks (for debugging)\n */\nexport type BackendWebSocketServiceGetChannelCallbacksAction = {\n type: `BackendWebSocketService:getChannelCallbacks`;\n handler: BackendWebSocketService['getChannelCallbacks'];\n};\n\n/**\n * Create and manage a subscription with direct callback routing\n *\n * @param options - Subscription configuration\n * @param options.channels - Array of channel names to subscribe to\n * @param options.callback - Callback function for handling notifications\n * @returns Promise that resolves with subscription object containing unsubscribe method\n */\nexport type BackendWebSocketServiceSubscribeAction = {\n type: `BackendWebSocketService:subscribe`;\n handler: BackendWebSocketService['subscribe'];\n};\n\n/**\n * Union of all BackendWebSocketService action types.\n */\nexport type BackendWebSocketServiceMethodActions =\n | BackendWebSocketServiceConnectAction\n | BackendWebSocketServiceDisconnectAction\n | BackendWebSocketServiceForceReconnectionAction\n | BackendWebSocketServiceSendMessageAction\n | BackendWebSocketServiceSendRequestAction\n | BackendWebSocketServiceGetConnectionInfoAction\n | BackendWebSocketServiceGetSubscriptionsByChannelAction\n | BackendWebSocketServiceChannelHasSubscriptionAction\n | BackendWebSocketServiceFindSubscriptionsByChannelPrefixAction\n | BackendWebSocketServiceAddChannelCallbackAction\n | BackendWebSocketServiceRemoveChannelCallbackAction\n | BackendWebSocketServiceGetChannelCallbacksAction\n | BackendWebSocketServiceSubscribeAction;\n"]}
|
|
@@ -10,9 +10,10 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _BackendWebSocketService_instances, _BackendWebSocketService_messenger, _BackendWebSocketService_options, _BackendWebSocketService_isEnabled, _BackendWebSocketService_trace, _BackendWebSocketService_ws, _BackendWebSocketService_state, _BackendWebSocketService_reconnectAttempts, _BackendWebSocketService_reconnectTimer, _BackendWebSocketService_connectionTimeout, _BackendWebSocketService_connectionPromise, _BackendWebSocketService_pendingRequests, _BackendWebSocketService_connectedAt, _BackendWebSocketService_manualDisconnect, _BackendWebSocketService_subscriptions, _BackendWebSocketService_channelCallbacks, _BackendWebSocketService_subscribeEvents, _BackendWebSocketService_buildAuthenticatedUrl, _BackendWebSocketService_establishConnection, _BackendWebSocketService_handleMessage, _BackendWebSocketService_isServerResponse, _BackendWebSocketService_isSubscriptionNotification, _BackendWebSocketService_isChannelMessage, _BackendWebSocketService_handleServerResponse, _BackendWebSocketService_handleChannelMessage, _BackendWebSocketService_handleSubscriptionNotification, _BackendWebSocketService_parseMessage, _BackendWebSocketService_handleClose, _BackendWebSocketService_handleError, _BackendWebSocketService_scheduleReconnect, _BackendWebSocketService_clearTimers, _BackendWebSocketService_clearPendingRequests, _BackendWebSocketService_clearSubscriptions, _BackendWebSocketService_setState;
|
|
13
|
+
var _BackendWebSocketService_instances, _BackendWebSocketService_messenger, _BackendWebSocketService_options, _BackendWebSocketService_isEnabled, _BackendWebSocketService_trace, _BackendWebSocketService_ws, _BackendWebSocketService_state, _BackendWebSocketService_reconnectAttempts, _BackendWebSocketService_reconnectTimer, _BackendWebSocketService_connectionTimeout, _BackendWebSocketService_stableConnectionTimer, _BackendWebSocketService_connectionPromise, _BackendWebSocketService_pendingRequests, _BackendWebSocketService_connectedAt, _BackendWebSocketService_manualDisconnect, _BackendWebSocketService_subscriptions, _BackendWebSocketService_channelCallbacks, _BackendWebSocketService_backoff, _BackendWebSocketService_subscribeEvents, _BackendWebSocketService_buildAuthenticatedUrl, _BackendWebSocketService_establishConnection, _BackendWebSocketService_handleMessage, _BackendWebSocketService_isServerResponse, _BackendWebSocketService_isSubscriptionNotification, _BackendWebSocketService_isChannelMessage, _BackendWebSocketService_handleServerResponse, _BackendWebSocketService_handleChannelMessage, _BackendWebSocketService_handleSubscriptionNotification, _BackendWebSocketService_parseMessage, _BackendWebSocketService_handleClose, _BackendWebSocketService_handleError, _BackendWebSocketService_scheduleReconnect, _BackendWebSocketService_newBackoff, _BackendWebSocketService_clearTimers, _BackendWebSocketService_clearPendingRequests, _BackendWebSocketService_clearSubscriptions, _BackendWebSocketService_setState;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.BackendWebSocketService = exports.WebSocketEventType = exports.WebSocketState = exports.getCloseReason = void 0;
|
|
16
|
+
const controller_utils_1 = require("@metamask/controller-utils");
|
|
16
17
|
const utils_1 = require("@metamask/utils");
|
|
17
18
|
const uuid_1 = require("uuid");
|
|
18
19
|
const logger_1 = require("./logger.cjs");
|
|
@@ -21,6 +22,7 @@ const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, SERVICE_NAM
|
|
|
21
22
|
const MESSENGER_EXPOSED_METHODS = [
|
|
22
23
|
'connect',
|
|
23
24
|
'disconnect',
|
|
25
|
+
'forceReconnection',
|
|
24
26
|
'sendMessage',
|
|
25
27
|
'sendRequest',
|
|
26
28
|
'subscribe',
|
|
@@ -152,6 +154,7 @@ class BackendWebSocketService {
|
|
|
152
154
|
_BackendWebSocketService_reconnectAttempts.set(this, 0);
|
|
153
155
|
_BackendWebSocketService_reconnectTimer.set(this, null);
|
|
154
156
|
_BackendWebSocketService_connectionTimeout.set(this, null);
|
|
157
|
+
_BackendWebSocketService_stableConnectionTimer.set(this, null);
|
|
155
158
|
// Track the current connection promise to handle concurrent connection attempts
|
|
156
159
|
_BackendWebSocketService_connectionPromise.set(this, null);
|
|
157
160
|
_BackendWebSocketService_pendingRequests.set(this, new Map());
|
|
@@ -166,6 +169,8 @@ class BackendWebSocketService {
|
|
|
166
169
|
// Key: channel name (serves as unique identifier)
|
|
167
170
|
// Value: ChannelCallback configuration
|
|
168
171
|
_BackendWebSocketService_channelCallbacks.set(this, new Map());
|
|
172
|
+
// Backoff instance for reconnection delays (reset on stable connection)
|
|
173
|
+
_BackendWebSocketService_backoff.set(this, void 0);
|
|
169
174
|
__classPrivateFieldSet(this, _BackendWebSocketService_messenger, options.messenger, "f");
|
|
170
175
|
__classPrivateFieldSet(this, _BackendWebSocketService_isEnabled, options.isEnabled, "f");
|
|
171
176
|
// Default to no-op trace function to keep core platform-agnostic
|
|
@@ -179,6 +184,8 @@ class BackendWebSocketService {
|
|
|
179
184
|
maxReconnectDelay: options.maxReconnectDelay ?? 5000,
|
|
180
185
|
requestTimeout: options.requestTimeout ?? 30000,
|
|
181
186
|
}, "f");
|
|
187
|
+
// Initialize backoff for reconnection delays
|
|
188
|
+
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_newBackoff).call(this);
|
|
182
189
|
// Subscribe to authentication and keyring controller events
|
|
183
190
|
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_subscribeEvents).call(this);
|
|
184
191
|
// Register action handlers using the method actions pattern
|
|
@@ -220,6 +227,11 @@ class BackendWebSocketService {
|
|
|
220
227
|
await __classPrivateFieldGet(this, _BackendWebSocketService_connectionPromise, "f");
|
|
221
228
|
return;
|
|
222
229
|
}
|
|
230
|
+
// If a reconnect is already scheduled, defer to it to avoid bypassing exponential backoff
|
|
231
|
+
// This prevents rapid loops when server accepts then immediately closes connections
|
|
232
|
+
if (__classPrivateFieldGet(this, _BackendWebSocketService_reconnectTimer, "f")) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
223
235
|
// Create and store the connection promise IMMEDIATELY (before any async operations)
|
|
224
236
|
// This ensures subsequent connect() calls will wait for this promise instead of creating new connections
|
|
225
237
|
__classPrivateFieldSet(this, _BackendWebSocketService_connectionPromise, (async () => {
|
|
@@ -228,15 +240,12 @@ class BackendWebSocketService {
|
|
|
228
240
|
try {
|
|
229
241
|
const token = await __classPrivateFieldGet(this, _BackendWebSocketService_messenger, "f").call('AuthenticationController:getBearerToken');
|
|
230
242
|
if (!token) {
|
|
231
|
-
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_scheduleReconnect).call(this);
|
|
232
243
|
throw new Error('Authentication required: user not signed in');
|
|
233
244
|
}
|
|
234
245
|
bearerToken = token;
|
|
235
246
|
}
|
|
236
247
|
catch (error) {
|
|
237
248
|
log('Failed to check authentication requirements', { error });
|
|
238
|
-
// Can't connect - schedule retry
|
|
239
|
-
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_scheduleReconnect).call(this);
|
|
240
249
|
throw error;
|
|
241
250
|
}
|
|
242
251
|
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_setState).call(this, WebSocketState.CONNECTING);
|
|
@@ -248,13 +257,17 @@ class BackendWebSocketService {
|
|
|
248
257
|
const errorMessage = (0, utils_1.getErrorMessage)(error);
|
|
249
258
|
log('Connection attempt failed', { errorMessage, error });
|
|
250
259
|
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_setState).call(this, WebSocketState.ERROR);
|
|
251
|
-
// Rethrow to propagate error to caller
|
|
252
260
|
throw error;
|
|
253
261
|
}
|
|
254
262
|
})(), "f");
|
|
255
263
|
try {
|
|
256
264
|
await __classPrivateFieldGet(this, _BackendWebSocketService_connectionPromise, "f");
|
|
257
265
|
}
|
|
266
|
+
catch {
|
|
267
|
+
// Always schedule reconnect on any failure
|
|
268
|
+
// Exponential backoff will prevent aggressive retries
|
|
269
|
+
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_scheduleReconnect).call(this);
|
|
270
|
+
}
|
|
258
271
|
finally {
|
|
259
272
|
// Clear the connection promise when done (success or failure)
|
|
260
273
|
__classPrivateFieldSet(this, _BackendWebSocketService_connectionPromise, null, "f");
|
|
@@ -262,10 +275,8 @@ class BackendWebSocketService {
|
|
|
262
275
|
}
|
|
263
276
|
/**
|
|
264
277
|
* Closes WebSocket connection
|
|
265
|
-
*
|
|
266
|
-
* @returns Promise that resolves when disconnection is complete
|
|
267
278
|
*/
|
|
268
|
-
|
|
279
|
+
disconnect() {
|
|
269
280
|
if (__classPrivateFieldGet(this, _BackendWebSocketService_state, "f") === WebSocketState.DISCONNECTED ||
|
|
270
281
|
__classPrivateFieldGet(this, _BackendWebSocketService_state, "f") === WebSocketState.DISCONNECTING) {
|
|
271
282
|
return;
|
|
@@ -277,11 +288,41 @@ class BackendWebSocketService {
|
|
|
277
288
|
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_clearPendingRequests).call(this, new Error('WebSocket disconnected'));
|
|
278
289
|
// Clear any pending connection promise
|
|
279
290
|
__classPrivateFieldSet(this, _BackendWebSocketService_connectionPromise, null, "f");
|
|
291
|
+
// Reset reconnect attempts on manual disconnect
|
|
292
|
+
__classPrivateFieldSet(this, _BackendWebSocketService_reconnectAttempts, 0, "f");
|
|
280
293
|
if (__classPrivateFieldGet(this, _BackendWebSocketService_ws, "f")) {
|
|
281
294
|
__classPrivateFieldGet(this, _BackendWebSocketService_ws, "f").close(1000, 'Normal closure');
|
|
282
295
|
}
|
|
283
296
|
log('WebSocket manually disconnected');
|
|
284
297
|
}
|
|
298
|
+
/**
|
|
299
|
+
* Forces a WebSocket reconnection to clean up subscription state
|
|
300
|
+
*
|
|
301
|
+
* This method is useful when subscription state may be out of sync and needs to be reset.
|
|
302
|
+
* It performs a controlled disconnect-then-reconnect sequence:
|
|
303
|
+
* - Disconnects cleanly to trigger subscription cleanup
|
|
304
|
+
* - Schedules reconnection with exponential backoff to prevent rapid loops
|
|
305
|
+
* - All subscriptions will be cleaned up automatically on disconnect
|
|
306
|
+
*
|
|
307
|
+
* Use cases:
|
|
308
|
+
* - Recovering from subscription/unsubscription issues
|
|
309
|
+
* - Cleaning up orphaned subscriptions
|
|
310
|
+
* - Forcing a fresh subscription state
|
|
311
|
+
*
|
|
312
|
+
* @returns Promise that resolves when disconnection is complete (reconnection is scheduled)
|
|
313
|
+
*/
|
|
314
|
+
async forceReconnection() {
|
|
315
|
+
// If a reconnect is already scheduled, don't force another one
|
|
316
|
+
if (__classPrivateFieldGet(this, _BackendWebSocketService_reconnectTimer, "f")) {
|
|
317
|
+
log('Reconnect already scheduled, skipping force reconnection');
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
log('Forcing WebSocket reconnection to clean up subscription state');
|
|
321
|
+
// Perform controlled disconnect
|
|
322
|
+
this.disconnect();
|
|
323
|
+
// Schedule reconnection with exponential backoff
|
|
324
|
+
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_scheduleReconnect).call(this);
|
|
325
|
+
}
|
|
285
326
|
/**
|
|
286
327
|
* Sends a message through the WebSocket (fire-and-forget, no response expected)
|
|
287
328
|
*
|
|
@@ -626,7 +667,7 @@ class BackendWebSocketService {
|
|
|
626
667
|
}
|
|
627
668
|
}
|
|
628
669
|
exports.BackendWebSocketService = BackendWebSocketService;
|
|
629
|
-
_BackendWebSocketService_messenger = new WeakMap(), _BackendWebSocketService_options = new WeakMap(), _BackendWebSocketService_isEnabled = new WeakMap(), _BackendWebSocketService_trace = new WeakMap(), _BackendWebSocketService_ws = new WeakMap(), _BackendWebSocketService_state = new WeakMap(), _BackendWebSocketService_reconnectAttempts = new WeakMap(), _BackendWebSocketService_reconnectTimer = new WeakMap(), _BackendWebSocketService_connectionTimeout = new WeakMap(), _BackendWebSocketService_connectionPromise = new WeakMap(), _BackendWebSocketService_pendingRequests = new WeakMap(), _BackendWebSocketService_connectedAt = new WeakMap(), _BackendWebSocketService_manualDisconnect = new WeakMap(), _BackendWebSocketService_subscriptions = new WeakMap(), _BackendWebSocketService_channelCallbacks = new WeakMap(), _BackendWebSocketService_instances = new WeakSet(), _BackendWebSocketService_subscribeEvents = function _BackendWebSocketService_subscribeEvents() {
|
|
670
|
+
_BackendWebSocketService_messenger = new WeakMap(), _BackendWebSocketService_options = new WeakMap(), _BackendWebSocketService_isEnabled = new WeakMap(), _BackendWebSocketService_trace = new WeakMap(), _BackendWebSocketService_ws = new WeakMap(), _BackendWebSocketService_state = new WeakMap(), _BackendWebSocketService_reconnectAttempts = new WeakMap(), _BackendWebSocketService_reconnectTimer = new WeakMap(), _BackendWebSocketService_connectionTimeout = new WeakMap(), _BackendWebSocketService_stableConnectionTimer = new WeakMap(), _BackendWebSocketService_connectionPromise = new WeakMap(), _BackendWebSocketService_pendingRequests = new WeakMap(), _BackendWebSocketService_connectedAt = new WeakMap(), _BackendWebSocketService_manualDisconnect = new WeakMap(), _BackendWebSocketService_subscriptions = new WeakMap(), _BackendWebSocketService_channelCallbacks = new WeakMap(), _BackendWebSocketService_backoff = new WeakMap(), _BackendWebSocketService_instances = new WeakSet(), _BackendWebSocketService_subscribeEvents = function _BackendWebSocketService_subscribeEvents() {
|
|
630
671
|
// Subscribe to authentication state changes (sign in/out)
|
|
631
672
|
__classPrivateFieldGet(this, _BackendWebSocketService_messenger, "f").subscribe('AuthenticationController:stateChange', (state) => {
|
|
632
673
|
if (state.isSignedIn) {
|
|
@@ -634,7 +675,6 @@ _BackendWebSocketService_messenger = new WeakMap(), _BackendWebSocketService_opt
|
|
|
634
675
|
this.connect();
|
|
635
676
|
}
|
|
636
677
|
else {
|
|
637
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
638
678
|
this.disconnect();
|
|
639
679
|
}
|
|
640
680
|
}, (state) => ({ isSignedIn: state.isSignedIn }));
|
|
@@ -645,7 +685,6 @@ _BackendWebSocketService_messenger = new WeakMap(), _BackendWebSocketService_opt
|
|
|
645
685
|
});
|
|
646
686
|
// Subscribe to wallet lock event
|
|
647
687
|
__classPrivateFieldGet(this, _BackendWebSocketService_messenger, "f").subscribe('KeyringController:lock', () => {
|
|
648
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
649
688
|
this.disconnect();
|
|
650
689
|
});
|
|
651
690
|
}, _BackendWebSocketService_buildAuthenticatedUrl = function _BackendWebSocketService_buildAuthenticatedUrl(bearerToken) {
|
|
@@ -694,8 +733,15 @@ async function _BackendWebSocketService_establishConnection(bearerToken) {
|
|
|
694
733
|
__classPrivateFieldSet(this, _BackendWebSocketService_ws, ws, "f");
|
|
695
734
|
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_setState).call(this, WebSocketState.CONNECTED);
|
|
696
735
|
__classPrivateFieldSet(this, _BackendWebSocketService_connectedAt, Date.now(), "f");
|
|
697
|
-
//
|
|
698
|
-
|
|
736
|
+
// Only reset after connection stays stable for a period (10 seconds)
|
|
737
|
+
// This prevents rapid reconnect loops when server accepts then immediately closes
|
|
738
|
+
__classPrivateFieldSet(this, _BackendWebSocketService_stableConnectionTimer, setTimeout(() => {
|
|
739
|
+
__classPrivateFieldSet(this, _BackendWebSocketService_stableConnectionTimer, null, "f");
|
|
740
|
+
__classPrivateFieldSet(this, _BackendWebSocketService_reconnectAttempts, 0, "f");
|
|
741
|
+
// Create new backoff sequence for fresh start on next disconnect
|
|
742
|
+
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_newBackoff).call(this);
|
|
743
|
+
log('Connection stable - reset reconnect attempts and backoff');
|
|
744
|
+
}, 10000), "f");
|
|
699
745
|
resolve();
|
|
700
746
|
});
|
|
701
747
|
};
|
|
@@ -837,7 +883,14 @@ async function _BackendWebSocketService_establishConnection(bearerToken) {
|
|
|
837
883
|
}, _BackendWebSocketService_handleClose = function _BackendWebSocketService_handleClose(event) {
|
|
838
884
|
// Calculate connection duration before we clear state
|
|
839
885
|
const connectionDuration = Date.now() - __classPrivateFieldGet(this, _BackendWebSocketService_connectedAt, "f");
|
|
840
|
-
__classPrivateFieldGet(this,
|
|
886
|
+
if (__classPrivateFieldGet(this, _BackendWebSocketService_connectionTimeout, "f")) {
|
|
887
|
+
clearTimeout(__classPrivateFieldGet(this, _BackendWebSocketService_connectionTimeout, "f"));
|
|
888
|
+
__classPrivateFieldSet(this, _BackendWebSocketService_connectionTimeout, null, "f");
|
|
889
|
+
}
|
|
890
|
+
if (__classPrivateFieldGet(this, _BackendWebSocketService_stableConnectionTimer, "f")) {
|
|
891
|
+
clearTimeout(__classPrivateFieldGet(this, _BackendWebSocketService_stableConnectionTimer, "f"));
|
|
892
|
+
__classPrivateFieldSet(this, _BackendWebSocketService_stableConnectionTimer, null, "f");
|
|
893
|
+
}
|
|
841
894
|
__classPrivateFieldSet(this, _BackendWebSocketService_connectedAt, 0, "f");
|
|
842
895
|
// Clear any pending connection promise
|
|
843
896
|
__classPrivateFieldSet(this, _BackendWebSocketService_connectionPromise, null, "f");
|
|
@@ -867,28 +920,43 @@ async function _BackendWebSocketService_establishConnection(bearerToken) {
|
|
|
867
920
|
}, () => {
|
|
868
921
|
// Empty trace callback - just measuring the event
|
|
869
922
|
});
|
|
870
|
-
// For any unexpected disconnects, attempt reconnection
|
|
871
|
-
// The manualDisconnect flag is the only gate - if it's false, we reconnect
|
|
872
923
|
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_scheduleReconnect).call(this);
|
|
873
924
|
}, _BackendWebSocketService_handleError = function _BackendWebSocketService_handleError(_error) {
|
|
874
925
|
// Placeholder for future error handling logic
|
|
875
926
|
}, _BackendWebSocketService_scheduleReconnect = function _BackendWebSocketService_scheduleReconnect() {
|
|
927
|
+
// If a reconnect is already scheduled, don't schedule another one
|
|
928
|
+
if (__classPrivateFieldGet(this, _BackendWebSocketService_reconnectTimer, "f")) {
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
931
|
+
// Increment attempts BEFORE calculating delay so backoff grows properly
|
|
876
932
|
__classPrivateFieldSet(this, _BackendWebSocketService_reconnectAttempts, __classPrivateFieldGet(this, _BackendWebSocketService_reconnectAttempts, "f") + 1, "f");
|
|
877
|
-
|
|
878
|
-
const delay =
|
|
933
|
+
// Use Cockatiel's exponential backoff to get delay with jitter
|
|
934
|
+
const delay = __classPrivateFieldGet(this, _BackendWebSocketService_backoff, "f").duration;
|
|
935
|
+
// Progress to next backoff state for future reconnect attempts
|
|
936
|
+
// Pass attempt number as context (though ExponentialBackoff doesn't use it)
|
|
937
|
+
__classPrivateFieldSet(this, _BackendWebSocketService_backoff, __classPrivateFieldGet(this, _BackendWebSocketService_backoff, "f").next({ attempt: __classPrivateFieldGet(this, _BackendWebSocketService_reconnectAttempts, "f") }), "f");
|
|
938
|
+
log('Scheduling reconnect', {
|
|
939
|
+
attempt: __classPrivateFieldGet(this, _BackendWebSocketService_reconnectAttempts, "f"),
|
|
940
|
+
delay_ms: delay,
|
|
941
|
+
});
|
|
879
942
|
__classPrivateFieldSet(this, _BackendWebSocketService_reconnectTimer, setTimeout(() => {
|
|
880
943
|
// Clear timer reference first
|
|
881
944
|
__classPrivateFieldSet(this, _BackendWebSocketService_reconnectTimer, null, "f");
|
|
882
945
|
// Check if connection is still enabled before reconnecting
|
|
883
946
|
if (__classPrivateFieldGet(this, _BackendWebSocketService_isEnabled, "f") && !__classPrivateFieldGet(this, _BackendWebSocketService_isEnabled, "f").call(this)) {
|
|
884
947
|
__classPrivateFieldSet(this, _BackendWebSocketService_reconnectAttempts, 0, "f");
|
|
948
|
+
// Create new backoff sequence when disabled
|
|
949
|
+
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_newBackoff).call(this);
|
|
885
950
|
return;
|
|
886
951
|
}
|
|
887
|
-
//
|
|
888
|
-
this.connect()
|
|
889
|
-
__classPrivateFieldGet(this, _BackendWebSocketService_instances, "m", _BackendWebSocketService_scheduleReconnect).call(this);
|
|
890
|
-
});
|
|
952
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
953
|
+
this.connect();
|
|
891
954
|
}, delay), "f");
|
|
955
|
+
}, _BackendWebSocketService_newBackoff = function _BackendWebSocketService_newBackoff() {
|
|
956
|
+
__classPrivateFieldSet(this, _BackendWebSocketService_backoff, new controller_utils_1.ExponentialBackoff({
|
|
957
|
+
initialDelay: __classPrivateFieldGet(this, _BackendWebSocketService_options, "f").reconnectDelay,
|
|
958
|
+
maxDelay: __classPrivateFieldGet(this, _BackendWebSocketService_options, "f").maxReconnectDelay,
|
|
959
|
+
}).next(), "f");
|
|
892
960
|
}, _BackendWebSocketService_clearTimers = function _BackendWebSocketService_clearTimers() {
|
|
893
961
|
if (__classPrivateFieldGet(this, _BackendWebSocketService_reconnectTimer, "f")) {
|
|
894
962
|
clearTimeout(__classPrivateFieldGet(this, _BackendWebSocketService_reconnectTimer, "f"));
|
|
@@ -898,6 +966,10 @@ async function _BackendWebSocketService_establishConnection(bearerToken) {
|
|
|
898
966
|
clearTimeout(__classPrivateFieldGet(this, _BackendWebSocketService_connectionTimeout, "f"));
|
|
899
967
|
__classPrivateFieldSet(this, _BackendWebSocketService_connectionTimeout, null, "f");
|
|
900
968
|
}
|
|
969
|
+
if (__classPrivateFieldGet(this, _BackendWebSocketService_stableConnectionTimer, "f")) {
|
|
970
|
+
clearTimeout(__classPrivateFieldGet(this, _BackendWebSocketService_stableConnectionTimer, "f"));
|
|
971
|
+
__classPrivateFieldSet(this, _BackendWebSocketService_stableConnectionTimer, null, "f");
|
|
972
|
+
}
|
|
901
973
|
}, _BackendWebSocketService_clearPendingRequests = function _BackendWebSocketService_clearPendingRequests(error) {
|
|
902
974
|
for (const [, request] of __classPrivateFieldGet(this, _BackendWebSocketService_pendingRequests, "f")) {
|
|
903
975
|
clearTimeout(request.timeout);
|