stream-chat 9.50.3 → 10.0.0-rc.2

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.
Files changed (242) hide show
  1. package/dist/cjs/index.browser.js +19798 -14472
  2. package/dist/cjs/index.browser.js.map +4 -4
  3. package/dist/cjs/index.node.js +19817 -14482
  4. package/dist/cjs/index.node.js.map +4 -4
  5. package/dist/esm/index.mjs +19795 -14469
  6. package/dist/esm/index.mjs.map +4 -4
  7. package/dist/types/ChannelManager.d.ts +221 -0
  8. package/dist/types/EventHandlerPipeline.d.ts +104 -0
  9. package/dist/types/api-client.d.ts +26 -0
  10. package/dist/types/campaign.d.ts +0 -44
  11. package/dist/types/channel.d.ts +454 -479
  12. package/dist/types/channel_batch_updater.d.ts +0 -93
  13. package/dist/types/channel_state.d.ts +53 -201
  14. package/dist/types/client.d.ts +451 -1920
  15. package/dist/types/client_state.d.ts +4 -4
  16. package/dist/types/configuration/InstanceConfigurationService.d.ts +26 -0
  17. package/dist/types/configuration/index.d.ts +1 -0
  18. package/dist/types/configuration/types.d.ts +53 -0
  19. package/dist/types/connection.d.ts +49 -41
  20. package/dist/types/connection_fallback.d.ts +6 -4
  21. package/dist/types/constants.d.ts +0 -4
  22. package/dist/types/custom_types.d.ts +2 -0
  23. package/dist/types/entityStore/EntityStore.d.ts +111 -0
  24. package/dist/types/entityStore/StoreBackedItemIndex.d.ts +60 -0
  25. package/dist/types/entityStore/applyReactionLocally.d.ts +26 -0
  26. package/dist/types/entityStore/index.d.ts +2 -0
  27. package/dist/types/errors.d.ts +10 -2
  28. package/dist/types/gen/chat/ChannelApi.d.ts +45 -0
  29. package/dist/types/gen/chat/ChatApi.d.ts +334 -0
  30. package/dist/types/gen/model-decoders/decoders.d.ts +3 -0
  31. package/dist/types/gen/model-decoders/event-decoder-mapping.d.ts +6 -0
  32. package/dist/types/gen/models/index.d.ts +8836 -0
  33. package/dist/types/gen/moderation/ModerationApi.d.ts +50 -0
  34. package/dist/types/gen-imports.d.ts +3 -0
  35. package/dist/types/index.d.ts +8 -7
  36. package/dist/types/insights.d.ts +9 -8
  37. package/dist/types/logger.d.ts +9 -0
  38. package/dist/types/messageComposer/LocationComposer.d.ts +7 -4
  39. package/dist/types/messageComposer/attachmentIdentity.d.ts +2 -2
  40. package/dist/types/messageComposer/attachmentManager.d.ts +8 -4
  41. package/dist/types/messageComposer/configuration/types.d.ts +11 -11
  42. package/dist/types/messageComposer/linkPreviewsManager.d.ts +25 -13
  43. package/dist/types/messageComposer/messageComposer.d.ts +10 -10
  44. package/dist/types/messageComposer/middleware/messageComposer/types.d.ts +3 -3
  45. package/dist/types/messageComposer/middleware/pollComposer/types.d.ts +4 -7
  46. package/dist/types/messageComposer/middleware/textComposer/commandUtils.d.ts +3 -3
  47. package/dist/types/messageComposer/middleware/textComposer/commands.d.ts +7 -7
  48. package/dist/types/messageComposer/middleware/textComposer/mentions.d.ts +218 -4
  49. package/dist/types/messageComposer/middleware/textComposer/types.d.ts +9 -4
  50. package/dist/types/messageComposer/pollComposer.d.ts +5 -4
  51. package/dist/types/messageComposer/textComposer.d.ts +8 -3
  52. package/dist/types/messageComposer/types.d.ts +6 -28
  53. package/dist/types/messageDelivery/MessageDeliveryReporter.d.ts +40 -25
  54. package/dist/types/messageDelivery/MessageReceiptsTracker.d.ts +53 -12
  55. package/dist/types/messageOperations/MessageOperationStatePolicy.d.ts +19 -0
  56. package/dist/types/messageOperations/MessageOperations.d.ts +17 -0
  57. package/dist/types/messageOperations/index.d.ts +3 -0
  58. package/dist/types/messageOperations/types.d.ts +49 -0
  59. package/dist/types/moderation.d.ts +21 -203
  60. package/dist/types/notifications/types.d.ts +8 -7
  61. package/dist/types/offline-support/offline_support_api.d.ts +111 -87
  62. package/dist/types/offline-support/offline_sync_manager.d.ts +0 -7
  63. package/dist/types/offline-support/types.d.ts +19 -23
  64. package/dist/types/offline-support/util.d.ts +4 -2
  65. package/dist/types/pagination/FilterBuilder.d.ts +1 -1
  66. package/dist/types/pagination/ItemIndex.d.ts +25 -0
  67. package/dist/types/pagination/cursorDerivation/createdAtAroundPaginationFlags.d.ts +9 -0
  68. package/dist/types/pagination/cursorDerivation/idAroundPaginationFlags.d.ts +6 -0
  69. package/dist/types/pagination/cursorDerivation/index.d.ts +1 -0
  70. package/dist/types/pagination/cursorDerivation/linearPaginationFlags.d.ts +6 -0
  71. package/dist/types/pagination/filterCompiler.d.ts +7 -0
  72. package/dist/types/pagination/index.d.ts +1 -3
  73. package/dist/types/pagination/paginators/BasePaginator.d.ts +848 -0
  74. package/dist/types/pagination/paginators/ChannelPaginator.d.ts +212 -0
  75. package/dist/types/pagination/paginators/MessageIntervalPaginator.d.ts +282 -0
  76. package/dist/types/pagination/paginators/MessagePaginator.d.ts +208 -0
  77. package/dist/types/pagination/paginators/PinnedMessagePaginator.d.ts +39 -0
  78. package/dist/types/pagination/paginators/ReminderPaginator.d.ts +19 -0
  79. package/dist/types/pagination/paginators/UserGroupPaginator.d.ts +24 -0
  80. package/dist/types/pagination/paginators/index.d.ts +7 -0
  81. package/dist/types/pagination/paginators/stateThrottling.d.ts +2 -0
  82. package/dist/types/pagination/sortCompiler.d.ts +49 -0
  83. package/dist/types/pagination/types.normalization.d.ts +11 -0
  84. package/dist/types/pagination/utility.normalization.d.ts +18 -0
  85. package/dist/types/pagination/utility.queryChannel.d.ts +26 -0
  86. package/dist/types/pagination/utility.search.d.ts +13 -0
  87. package/dist/types/permissions.d.ts +1 -1
  88. package/dist/types/poll.d.ts +29 -32
  89. package/dist/types/poll_manager.d.ts +2 -2
  90. package/dist/types/reminders/Reminder.d.ts +2 -5
  91. package/dist/types/reminders/ReminderManager.d.ts +2 -9
  92. package/dist/types/search/MessageSearchSource.d.ts +4 -4
  93. package/dist/types/search/UserSearchSource.d.ts +1 -1
  94. package/dist/types/search/types.d.ts +3 -3
  95. package/dist/types/segment.d.ts +0 -34
  96. package/dist/types/signing.d.ts +105 -65
  97. package/dist/types/store.d.ts +1 -0
  98. package/dist/types/thread.d.ts +70 -34
  99. package/dist/types/thread_manager.d.ts +3 -3
  100. package/dist/types/token_manager.d.ts +15 -10
  101. package/dist/types/types.d.ts +197 -3404
  102. package/dist/types/utils/FixedSizeQueueCache.d.ts +12 -6
  103. package/dist/types/utils/WithSubscriptions.d.ts +2 -1
  104. package/dist/types/utils/concurrency.d.ts +4 -4
  105. package/dist/types/utils/mergeWith/mergeWith.d.ts +3 -3
  106. package/dist/types/utils/mergeWith/mergeWithCore.d.ts +8 -3
  107. package/dist/types/utils/retryable.d.ts +34 -0
  108. package/dist/types/utils/throttling/throttle.d.ts +36 -0
  109. package/dist/types/utils.d.ts +100 -194
  110. package/package.json +7 -3
  111. package/src/ChannelManager.ts +724 -0
  112. package/src/CooldownTimer.ts +2 -2
  113. package/src/EventHandlerPipeline.ts +228 -0
  114. package/src/LiveLocationManager.ts +12 -11
  115. package/src/api-client.ts +275 -0
  116. package/src/campaign.ts +1 -77
  117. package/src/channel.ts +1344 -1282
  118. package/src/channel_batch_updater.ts +1 -211
  119. package/src/channel_state.ts +144 -1013
  120. package/src/client.ts +936 -3995
  121. package/src/client_state.ts +4 -4
  122. package/src/configuration/InstanceConfigurationService.ts +73 -0
  123. package/src/configuration/index.ts +1 -0
  124. package/src/configuration/types.ts +81 -0
  125. package/src/connection.ts +145 -94
  126. package/src/connection_fallback.ts +29 -27
  127. package/src/constants.ts +1 -5
  128. package/src/custom_types.ts +4 -1
  129. package/src/entityStore/EntityStore.ts +208 -0
  130. package/src/entityStore/StoreBackedItemIndex.ts +115 -0
  131. package/src/entityStore/applyReactionLocally.ts +113 -0
  132. package/src/entityStore/index.ts +2 -0
  133. package/src/errors.ts +14 -2
  134. package/src/gen/chat/ChannelApi.ts +275 -0
  135. package/src/gen/chat/ChatApi.ts +2554 -0
  136. package/src/gen/model-decoders/decoders.ts +2680 -0
  137. package/src/gen/model-decoders/event-decoder-mapping.ts +198 -0
  138. package/src/gen/models/index.ts +12673 -0
  139. package/src/gen/moderation/ModerationApi.ts +607 -0
  140. package/src/gen-imports.ts +3 -0
  141. package/src/index.ts +11 -12
  142. package/src/insights.ts +6 -5
  143. package/src/logger.ts +28 -0
  144. package/src/messageComposer/LocationComposer.ts +9 -5
  145. package/src/messageComposer/MessageComposerEffectHandlers.ts +1 -0
  146. package/src/messageComposer/attachmentIdentity.ts +16 -9
  147. package/src/messageComposer/attachmentManager.ts +13 -8
  148. package/src/messageComposer/configuration/types.ts +11 -11
  149. package/src/messageComposer/linkPreviewsManager.ts +9 -10
  150. package/src/messageComposer/messageComposer.ts +57 -53
  151. package/src/messageComposer/middleware/messageComposer/attachments.ts +1 -2
  152. package/src/messageComposer/middleware/messageComposer/cleanData.ts +1 -1
  153. package/src/messageComposer/middleware/messageComposer/compositionValidation.ts +2 -2
  154. package/src/messageComposer/middleware/messageComposer/messageComposerState.ts +2 -2
  155. package/src/messageComposer/middleware/messageComposer/sharedLocation.ts +4 -3
  156. package/src/messageComposer/middleware/messageComposer/textComposer.ts +2 -2
  157. package/src/messageComposer/middleware/messageComposer/types.ts +3 -4
  158. package/src/messageComposer/middleware/messageComposer/userDataInjection.ts +9 -5
  159. package/src/messageComposer/middleware/pollComposer/state.ts +0 -2
  160. package/src/messageComposer/middleware/pollComposer/types.ts +4 -7
  161. package/src/messageComposer/middleware/textComposer/TextComposerMiddlewareExecutor.ts +10 -1
  162. package/src/messageComposer/middleware/textComposer/commandEffects.ts +4 -4
  163. package/src/messageComposer/middleware/textComposer/commandUtils.ts +3 -6
  164. package/src/messageComposer/middleware/textComposer/commands.ts +3 -3
  165. package/src/messageComposer/middleware/textComposer/mentionUtils.ts +1 -1
  166. package/src/messageComposer/middleware/textComposer/mentions.ts +31 -15
  167. package/src/messageComposer/middleware/textComposer/types.ts +9 -4
  168. package/src/messageComposer/pollComposer.ts +6 -8
  169. package/src/messageComposer/textComposer.ts +27 -2
  170. package/src/messageComposer/types.ts +6 -28
  171. package/src/messageDelivery/MessageDeliveryReporter.ts +101 -45
  172. package/src/messageDelivery/MessageReceiptsTracker.ts +294 -21
  173. package/src/messageOperations/MessageOperationStatePolicy.ts +77 -0
  174. package/src/messageOperations/MessageOperations.ts +212 -0
  175. package/src/messageOperations/index.ts +10 -0
  176. package/src/messageOperations/types.ts +64 -0
  177. package/src/moderation.ts +38 -431
  178. package/src/notifications/types.ts +8 -7
  179. package/src/offline-support/offline_support_api.ts +200 -133
  180. package/src/offline-support/offline_sync_manager.ts +23 -44
  181. package/src/offline-support/types.ts +23 -26
  182. package/src/offline-support/util.ts +5 -4
  183. package/src/pagination/FilterBuilder.ts +4 -1
  184. package/src/pagination/ItemIndex.ts +25 -0
  185. package/src/pagination/cursorDerivation/createdAtAroundPaginationFlags.ts +73 -0
  186. package/src/pagination/cursorDerivation/idAroundPaginationFlags.ts +53 -0
  187. package/src/pagination/cursorDerivation/index.ts +1 -0
  188. package/src/pagination/cursorDerivation/linearPaginationFlags.ts +86 -0
  189. package/src/pagination/filterCompiler.ts +196 -0
  190. package/src/pagination/index.ts +1 -3
  191. package/src/pagination/paginators/BasePaginator.ts +2859 -0
  192. package/src/pagination/paginators/ChannelPaginator.ts +729 -0
  193. package/src/pagination/paginators/MessageIntervalPaginator.ts +1116 -0
  194. package/src/pagination/paginators/MessagePaginator.ts +508 -0
  195. package/src/pagination/paginators/PinnedMessagePaginator.ts +108 -0
  196. package/src/pagination/paginators/ReminderPaginator.ts +107 -0
  197. package/src/pagination/paginators/UserGroupPaginator.ts +127 -0
  198. package/src/pagination/paginators/index.ts +7 -0
  199. package/src/pagination/paginators/stateThrottling.ts +31 -0
  200. package/src/pagination/sortCompiler.ts +193 -0
  201. package/src/pagination/types.normalization.ts +14 -0
  202. package/src/pagination/utility.normalization.ts +106 -0
  203. package/src/pagination/utility.queryChannel.ts +84 -0
  204. package/src/pagination/utility.search.ts +80 -0
  205. package/src/permissions.ts +7 -8
  206. package/src/poll.ts +101 -110
  207. package/src/poll_manager.ts +14 -8
  208. package/src/reminders/Reminder.ts +2 -5
  209. package/src/reminders/ReminderManager.ts +19 -21
  210. package/src/search/BaseSearchSource.ts +0 -3
  211. package/src/search/ChannelMemberSearchSource.ts +7 -1
  212. package/src/search/ChannelSearchSource.ts +10 -3
  213. package/src/search/MessageSearchSource.ts +29 -30
  214. package/src/search/UserSearchSource.ts +12 -8
  215. package/src/search/types.ts +3 -4
  216. package/src/segment.ts +1 -95
  217. package/src/signing.ts +107 -67
  218. package/src/store.ts +2 -1
  219. package/src/thread.ts +562 -238
  220. package/src/thread_manager.ts +37 -16
  221. package/src/token_manager.ts +21 -10
  222. package/src/types.ts +364 -4533
  223. package/src/uploadManager.ts +8 -0
  224. package/src/utils/FixedSizeQueueCache.ts +12 -6
  225. package/src/utils/WithSubscriptions.ts +2 -1
  226. package/src/utils/concurrency.ts +4 -4
  227. package/src/utils/mergeWith/mergeWith.ts +3 -3
  228. package/src/utils/mergeWith/mergeWithCore.ts +140 -164
  229. package/src/utils/mergeWith/mergeWithDiff.ts +3 -3
  230. package/src/utils/retryable.ts +117 -0
  231. package/src/utils/throttling/throttle.ts +130 -0
  232. package/src/utils.ts +208 -754
  233. package/dist/types/channel_manager.d.ts +0 -122
  234. package/dist/types/events.d.ts +0 -72
  235. package/dist/types/pagination/BasePaginator.d.ts +0 -69
  236. package/dist/types/pagination/ReminderPaginator.d.ts +0 -16
  237. package/dist/types/pagination/UserGroupPaginator.d.ts +0 -21
  238. package/src/channel_manager.ts +0 -830
  239. package/src/events.ts +0 -75
  240. package/src/pagination/BasePaginator.ts +0 -184
  241. package/src/pagination/ReminderPaginator.ts +0 -56
  242. package/src/pagination/UserGroupPaginator.ts +0 -93
package/src/connection.ts CHANGED
@@ -13,9 +13,14 @@ import {
13
13
  buildWsSuccessAfterFailureInsight,
14
14
  postInsights,
15
15
  } from './insights';
16
- import type { ConnectAPIResponse, ConnectionOpen, LogLevel, UR } from './types';
16
+ import { chatLoggerSystem } from './logger';
17
+ import type { ConnectAPIResponse, ConnectionOpen, EventPayload } from './types';
17
18
  import type { StreamChat } from './client';
18
19
  import type { APIError } from './errors';
20
+ import { decodeWSEvent } from './gen/model-decoders/event-decoder-mapping';
21
+ import type { WSEvent } from './gen/models';
22
+
23
+ const logger = chatLoggerSystem.getLogger('connection');
19
24
 
20
25
  // Type guards to check WebSocket error type
21
26
  const isCloseEvent = (
@@ -27,15 +32,16 @@ const isErrorEvent = (
27
32
  ): res is WebSocket.ErrorEvent => (res as WebSocket.ErrorEvent).error !== undefined;
28
33
 
29
34
  /**
30
- * StableWSConnection - A WS connection that reconnects upon failure.
35
+ * A WS connection that reconnects upon failure.
36
+ *
31
37
  * - the browser will sometimes report that you're online or offline
32
38
  * - the WS connection can break and fail (there is a 30s health check)
33
39
  * - sometimes your WS connection will seem to work while the user is in fact offline
34
- * - to speed up online/offline detection you can use the window.addEventListener('offline');
40
+ * - to speed up online/offline detection you can use the `window.addEventListener('offline')`
35
41
  *
36
42
  * There are 4 ways in which a connection can become unhealthy:
37
- * - websocket.onerror is called
38
- * - websocket.onclose is called
43
+ * - WebSocket.onerror is called
44
+ * - WebSocket.onclose is called
39
45
  * - the health check fails and no event is received for ~40 seconds
40
46
  * - the browser indicates the connection is now offline
41
47
  *
@@ -99,18 +105,15 @@ export class StableWSConnection {
99
105
  addConnectionEventListeners(this.onlineStatusChanged);
100
106
  }
101
107
 
102
- _log(msg: string, extra: UR = {}, level: LogLevel = 'info') {
103
- this.client.logger(level, 'connection:' + msg, { tags: ['connection'], ...extra });
104
- }
105
-
106
108
  setClient(client: StreamChat) {
107
109
  this.client = client;
108
110
  }
109
111
 
110
112
  /**
111
- * connect - Connect to the WS URL
112
- * the default 15s timeout allows between 2~3 tries
113
- * @return {ConnectAPIResponse<ChannelType, CommandType, UserType>} Promise that completes once the first health check message is received
113
+ * Connects to the WS URL. The default 15s timeout allows between 2 and 3 tries.
114
+ *
115
+ * @param timeout - Connect timeout in milliseconds (optional, defaults to `15000`).
116
+ * @returns A promise that resolves once the first health check message is received.
114
117
  */
115
118
  async connect(timeout = 15000) {
116
119
  if (this.isConnecting) {
@@ -125,8 +128,9 @@ export class StableWSConnection {
125
128
  const healthCheck = await this._connect();
126
129
  this.consecutiveFailures = 0;
127
130
 
128
- this._log(`connect() - Established ws connection with healthcheck: ${healthCheck}`);
129
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
131
+ logger
132
+ .withExtraTags('connect')
133
+ .info(`Established a WebSocket connection. Health check: ${healthCheck}.`);
130
134
  } catch (error: any) {
131
135
  this.isHealthy = false;
132
136
  this.consecutiveFailures += 1;
@@ -134,9 +138,11 @@ export class StableWSConnection {
134
138
  const e = error as APIError;
135
139
 
136
140
  if (e.code === chatCodes.TOKEN_EXPIRED && !this.client.tokenManager.isStatic()) {
137
- this._log(
138
- 'connect() - WS failure due to expired token, so going to try to reload token and reconnect',
139
- );
141
+ logger
142
+ .withExtraTags('connect')
143
+ .warn(
144
+ 'WebSocket connection failed due to an expired token. Reloading the token and reconnecting.',
145
+ );
140
146
  this._reconnect({ refreshToken: true });
141
147
  } else if (!e.isWSFailure) {
142
148
  // API rejected the connection and we should not retry
@@ -157,7 +163,8 @@ export class StableWSConnection {
157
163
  /**
158
164
  * _waitForHealthy polls the promise connection to see if its resolved until it times out
159
165
  * the default 15s timeout allows between 2~3 tries
160
- * @param timeout duration(ms)
166
+ *
167
+ * @param timeout - duration (ms)
161
168
  */
162
169
  _waitForHealthy(timeout = 15000) {
163
170
  return Promise.race([
@@ -166,7 +173,6 @@ export class StableWSConnection {
166
173
  for (let i = 0; i <= timeout; i += interval) {
167
174
  try {
168
175
  return await this.connectionOpen;
169
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
170
176
  } catch (error: any) {
171
177
  if (i === timeout) {
172
178
  throw new Error(
@@ -198,7 +204,8 @@ export class StableWSConnection {
198
204
  }
199
205
 
200
206
  /**
201
- * Builds and returns the url for websocket.
207
+ * Builds and returns the URL for the WebSocket connection.
208
+ *
202
209
  * @private
203
210
  * @returns url string
204
211
  */
@@ -220,11 +227,14 @@ export class StableWSConnection {
220
227
  };
221
228
 
222
229
  /**
223
- * disconnect - Disconnect the connection and doesn't recover...
230
+ * Disconnects the connection without attempting to recover.
224
231
  *
232
+ * @param timeout - Optional timeout in milliseconds to wait for the close frame from the server.
225
233
  */
226
234
  disconnect(timeout?: number) {
227
- this._log(`disconnect() - Closing the websocket connection for wsID ${this.wsID}`);
235
+ logger
236
+ .withExtraTags('disconnect')
237
+ .info(`Closing the WebSocket connection for wsID ${this.wsID}.`);
228
238
 
229
239
  this.wsID += 1;
230
240
  this.isConnecting = false;
@@ -255,29 +265,33 @@ export class StableWSConnection {
255
265
  if (ws && ws.close && ws.readyState === ws.OPEN) {
256
266
  isClosedPromise = new Promise((resolve) => {
257
267
  const onclose = (event: WebSocket.CloseEvent) => {
258
- this._log(
259
- `disconnect() - resolving isClosedPromise ${event ? 'with' : 'without'} close frame`,
260
- { event },
261
- );
268
+ logger
269
+ .withExtraTags('disconnect')
270
+ .debug(
271
+ `Resolving the close promise ${event ? 'with' : 'without'} a close frame.`,
272
+ { event },
273
+ );
262
274
  resolve();
263
275
  };
264
276
 
265
277
  ws.onclose = onclose;
266
- // In case we don't receive close frame websocket server in time,
278
+ // In case we don't receive a close frame from the WebSocket server in time,
267
279
  // lets not wait for more than 1 seconds.
268
280
  setTimeout(onclose, timeout != null ? timeout : 1000);
269
281
  });
270
282
 
271
- this._log(
272
- `disconnect() - Manually closed connection by calling client.disconnect()`,
273
- );
283
+ logger
284
+ .withExtraTags('disconnect')
285
+ .debug('Manually closing the connection via client.disconnect().');
274
286
 
275
287
  ws.close(
276
288
  chatCodes.WS_CLOSED_SUCCESS,
277
289
  'Manually closed connection by calling client.disconnect()',
278
290
  );
279
291
  } else {
280
- this._log(`disconnect() - ws connection doesn't exist or it is already closed.`);
292
+ logger
293
+ .withExtraTags('disconnect')
294
+ .debug('The WebSocket connection does not exist or is already closed.');
281
295
  isClosedPromise = Promise.resolve();
282
296
  }
283
297
 
@@ -287,9 +301,9 @@ export class StableWSConnection {
287
301
  }
288
302
 
289
303
  /**
290
- * _connect - Connect to the WS endpoint
304
+ * Connects to the WS endpoint.
291
305
  *
292
- * @return {ConnectAPIResponse<ChannelType, CommandType, UserType>} Promise that completes once the first health check message is received
306
+ * @returns A promise that resolves once the first health check message is received.
293
307
  */
294
308
  async _connect() {
295
309
  if (
@@ -302,7 +316,7 @@ export class StableWSConnection {
302
316
  this.client.insightMetrics.connectionStartTimestamp = new Date().getTime();
303
317
  let isTokenReady = false;
304
318
  try {
305
- this._log(`_connect() - waiting for token`);
319
+ logger.withExtraTags('_connect').debug('Waiting for the auth token.');
306
320
  await this.client.tokenManager.tokenReady();
307
321
  isTokenReady = true;
308
322
  } catch (e) {
@@ -311,13 +325,15 @@ export class StableWSConnection {
311
325
 
312
326
  try {
313
327
  if (!isTokenReady) {
314
- this._log(`_connect() - tokenProvider failed before, so going to retry`);
328
+ logger
329
+ .withExtraTags('_connect')
330
+ .warn('The token provider failed previously. Retrying.');
315
331
  await this.client.tokenManager.loadToken();
316
332
  }
317
333
 
318
334
  this._setupConnectionPromise();
319
335
  const wsURL = this._buildUrl();
320
- this._log(`_connect() - Connecting to ${wsURL}`, {
336
+ logger.withExtraTags('_connect').info(`Connecting to ${wsURL}.`, {
321
337
  wsURL,
322
338
  requestID: this.requestID,
323
339
  });
@@ -343,10 +359,11 @@ export class StableWSConnection {
343
359
  }
344
360
  return response;
345
361
  }
346
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
347
362
  } catch (error: any) {
348
363
  this.isConnecting = false;
349
- this._log(`_connect() - Error - `, error);
364
+ logger
365
+ .withExtraTags('_connect')
366
+ .warn('An error occurred while connecting.', { error });
350
367
  if (this.client.options.enableInsights) {
351
368
  this.client.insightMetrics.wsConsecutiveFailures++;
352
369
  this.client.insightMetrics.wsTotalFailures++;
@@ -362,21 +379,22 @@ export class StableWSConnection {
362
379
  }
363
380
 
364
381
  /**
365
- * _reconnect - Retry the connection to WS endpoint
366
- *
367
- * @param {{ interval?: number; refreshToken?: boolean }} options Following options are available
382
+ * Retries the connection to the WS endpoint.
368
383
  *
369
- * - `interval` {int} number of ms that function should wait before reconnecting
370
- * - `refreshToken` {boolean} reload/refresh user token be refreshed before attempting reconnection.
384
+ * @param options - Reconnect options.
385
+ * @param options.interval - Number of milliseconds to wait before reconnecting.
386
+ * @param options.refreshToken - Reload/refresh the user token before attempting to reconnect.
371
387
  */
372
388
  async _reconnect(
373
389
  options: { interval?: number; refreshToken?: boolean } = {},
374
390
  ): Promise<void> {
375
- this._log('_reconnect() - Initiating the reconnect');
391
+ logger.withExtraTags('_reconnect').info('Initiating a reconnect.');
376
392
 
377
393
  // only allow 1 connection at the time
378
394
  if (this.isConnecting || this.isHealthy) {
379
- this._log('_reconnect() - Abort (1) since already connecting or healthy');
395
+ logger
396
+ .withExtraTags('_reconnect')
397
+ .debug('Aborting reconnect: already connecting or healthy (check 1).');
380
398
  return;
381
399
  }
382
400
 
@@ -392,16 +410,22 @@ export class StableWSConnection {
392
410
  // Check once again if by some other call to _reconnect is active or connection is
393
411
  // already restored, then no need to proceed.
394
412
  if (this.isConnecting || this.isHealthy) {
395
- this._log('_reconnect() - Abort (2) since already connecting or healthy');
413
+ logger
414
+ .withExtraTags('_reconnect')
415
+ .debug('Aborting reconnect: already connecting or healthy (check 2).');
396
416
  return;
397
417
  }
398
418
 
399
419
  if (this.isDisconnected && this.client.options.enableWSFallback) {
400
- this._log('_reconnect() - Abort (3) since disconnect() is called');
420
+ logger
421
+ .withExtraTags('_reconnect')
422
+ .debug('Aborting reconnect: disconnect() was called.');
401
423
  return;
402
424
  }
403
425
 
404
- this._log('_reconnect() - Destroying current WS connection');
426
+ logger
427
+ .withExtraTags('_reconnect')
428
+ .info('Destroying the current WebSocket connection.');
405
429
 
406
430
  // cleanup the old connection
407
431
  this._destroyCurrentWSConnection();
@@ -412,12 +436,11 @@ export class StableWSConnection {
412
436
 
413
437
  try {
414
438
  await this._connect();
415
- this._log('_reconnect() - Waiting for recoverCallBack');
439
+ logger.withExtraTags('_reconnect').debug('Waiting for the recover callback.');
416
440
  await this.client.recoverState();
417
- this._log('_reconnect() - Finished recoverCallBack');
441
+ logger.withExtraTags('_reconnect').debug('Finished the recover callback.');
418
442
 
419
443
  this.consecutiveFailures = 0;
420
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
421
444
  } catch (error: any) {
422
445
  this.isHealthy = false;
423
446
  this.consecutiveFailures += 1;
@@ -425,60 +448,71 @@ export class StableWSConnection {
425
448
  error.code === chatCodes.TOKEN_EXPIRED &&
426
449
  !this.client.tokenManager.isStatic()
427
450
  ) {
428
- this._log(
429
- '_reconnect() - WS failure due to expired token, so going to try to reload token and reconnect',
430
- );
451
+ logger
452
+ .withExtraTags('_reconnect')
453
+ .warn(
454
+ 'WebSocket connection failed due to an expired token. Reloading the token and reconnecting.',
455
+ );
431
456
 
432
457
  return this._reconnect({ refreshToken: true });
433
458
  }
434
459
 
435
460
  // reconnect on WS failures, don't reconnect if there is a code bug
436
461
  if (error.isWSFailure) {
437
- this._log('_reconnect() - WS failure, so going to try to reconnect');
462
+ logger
463
+ .withExtraTags('_reconnect')
464
+ .warn('WebSocket connection failed. Retrying the reconnect.');
438
465
 
439
466
  this._reconnect();
440
467
  }
441
468
  }
442
- this._log('_reconnect() - == END ==');
469
+ logger.withExtraTags('_reconnect').debug('Reconnect attempt finished.');
443
470
  }
444
471
 
445
472
  /**
446
- * onlineStatusChanged - this function is called when the browser connects or disconnects from the internet.
447
- *
448
- * @param {Event} event Event with type online or offline
473
+ * Called when the browser connects or disconnects from the internet.
449
474
  *
475
+ * @param event - The DOM event whose `type` is `'online'` or `'offline'`.
450
476
  */
451
477
  onlineStatusChanged = (event: Event) => {
452
478
  if (event.type === 'offline') {
453
479
  // mark the connection as down
454
- this._log('onlineStatusChanged() - Status changing to offline');
480
+ logger
481
+ .withExtraTags('onlineStatusChanged')
482
+ .info('Network status changed to offline.');
455
483
  this._setHealth(false);
456
484
  } else if (event.type === 'online') {
457
485
  // retry right now...
458
486
  // We check this.isHealthy, not sure if it's always
459
487
  // smart to create a new WS connection if the old one is still up and running.
460
488
  // it's possible we didn't miss any messages, so this process is just expensive and not needed.
461
- this._log(
462
- `onlineStatusChanged() - Status changing to online. isHealthy: ${this.isHealthy}`,
463
- );
489
+ logger
490
+ .withExtraTags('onlineStatusChanged')
491
+ .info(`Network status changed to online. isHealthy: ${this.isHealthy}.`);
464
492
  if (!this.isHealthy) {
465
493
  this._reconnect({ interval: 10 });
466
494
  }
467
495
  }
468
496
  };
469
497
 
470
- onopen = (wsID: number) => {
471
- if (this.wsID !== wsID) return;
498
+ onopen = (wsId: number) => {
499
+ if (this.wsID !== wsId) return;
472
500
 
473
- this._log('onopen() - onopen callback', { wsID });
501
+ logger.withExtraTags('onopen').debug('WebSocket onopen callback fired.', {
502
+ wsID: wsId,
503
+ });
474
504
  };
475
505
 
476
- onmessage = (wsID: number, event: WebSocket.MessageEvent) => {
477
- if (this.wsID !== wsID) return;
506
+ onmessage = (wsId: number, event: WebSocket.MessageEvent) => {
507
+ if (this.wsID !== wsId) return;
478
508
 
479
- this._log('onmessage() - onmessage callback', { event, wsID });
509
+ logger.withExtraTags('onmessage').trace('WebSocket onmessage callback fired.', {
510
+ event,
511
+ wsID: wsId,
512
+ });
480
513
  if (typeof event.data !== 'string') return;
481
514
  const data = JSON.parse(event.data);
515
+ const decodedData = decodeWSEvent(data) as WSEvent;
482
516
 
483
517
  // we wait till the first message before we consider the connection open..
484
518
  // the reason for this is that auth errors and similar errors trigger a ws.onopen and immediately
@@ -490,7 +524,7 @@ export class StableWSConnection {
490
524
  return;
491
525
  }
492
526
 
493
- this.resolvePromise?.(data);
527
+ this.resolvePromise?.(decodedData as EventPayload<'health.check'>);
494
528
  this._setHealth(true);
495
529
  }
496
530
 
@@ -501,14 +535,19 @@ export class StableWSConnection {
501
535
  this.scheduleNextPing();
502
536
  }
503
537
 
504
- this.client.dispatchEvent(data);
538
+ this.client.dispatchEvent(decodedData);
505
539
  this.scheduleConnectionCheck();
506
540
  };
507
541
 
508
- onclose = (wsID: number, event: WebSocket.CloseEvent) => {
509
- if (this.wsID !== wsID) return;
542
+ onclose = (wsId: number, event: WebSocket.CloseEvent) => {
543
+ if (this.wsID !== wsId) return;
510
544
 
511
- this._log('onclose() - onclose callback - ' + event.code, { event, wsID });
545
+ logger
546
+ .withExtraTags('onclose')
547
+ .debug(`WebSocket onclose callback fired with code ${event.code}.`, {
548
+ event,
549
+ wsID: wsId,
550
+ });
512
551
 
513
552
  if (event.code === chatCodes.WS_CLOSED_SUCCESS) {
514
553
  // this is a permanent error raised by stream..
@@ -523,7 +562,9 @@ export class StableWSConnection {
523
562
  error.target = event.target;
524
563
 
525
564
  this.rejectPromise?.(error);
526
- this._log(`onclose() - WS connection reject with error ${event.reason}`, { event });
565
+ logger
566
+ .withExtraTags('onclose')
567
+ .warn(`The WebSocket connection was rejected: ${event.reason}.`, { event });
527
568
  } else {
528
569
  this.consecutiveFailures += 1;
529
570
  this.totalFailures += 1;
@@ -532,15 +573,19 @@ export class StableWSConnection {
532
573
 
533
574
  this.rejectPromise?.(this._errorFromWSEvent(event));
534
575
 
535
- this._log(`onclose() - WS connection closed. Calling reconnect ...`, { event });
576
+ logger
577
+ .withExtraTags('onclose')
578
+ .warn('The WebSocket connection was closed. Attempting to reconnect.', {
579
+ event,
580
+ });
536
581
 
537
582
  // reconnect if its an abnormal failure
538
583
  this._reconnect();
539
584
  }
540
585
  };
541
586
 
542
- onerror = (wsID: number, event: WebSocket.ErrorEvent) => {
543
- if (this.wsID !== wsID) return;
587
+ onerror = (wsId: number, event: WebSocket.ErrorEvent) => {
588
+ if (this.wsID !== wsId) return;
544
589
 
545
590
  this.consecutiveFailures += 1;
546
591
  this.totalFailures += 1;
@@ -548,17 +593,17 @@ export class StableWSConnection {
548
593
  this.isConnecting = false;
549
594
 
550
595
  this.rejectPromise?.(this._errorFromWSEvent(event));
551
- this._log(`onerror() - WS connection resulted into error`, { event });
596
+ logger
597
+ .withExtraTags('onerror')
598
+ .warn('The WebSocket connection raised an error.', { event });
552
599
 
553
600
  this._reconnect();
554
601
  };
555
602
 
556
603
  /**
557
- * _setHealth - Sets the connection to healthy or unhealthy.
558
- * Broadcasts an event in case the connection status changed.
559
- *
560
- * @param {boolean} healthy boolean indicating if the connection is healthy or not
604
+ * Sets the connection to healthy or unhealthy. Broadcasts an event if the connection status changed.
561
605
  *
606
+ * @param healthy - Whether the connection is healthy.
562
607
  */
563
608
  _setHealth = (healthy: boolean) => {
564
609
  if (healthy === this.isHealthy) return;
@@ -578,8 +623,11 @@ export class StableWSConnection {
578
623
  };
579
624
 
580
625
  /**
581
- * _errorFromWSEvent - Creates an error object for the WS event
626
+ * Creates an error object for the WS event.
582
627
  *
628
+ * @param event - The raw WebSocket close / data / error event.
629
+ * @param isWSFailure - Whether the underlying cause is a WebSocket failure (optional, defaults to `true`).
630
+ * @returns A normalized error describing the WS failure.
583
631
  */
584
632
  _errorFromWSEvent = (
585
633
  event: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent,
@@ -601,7 +649,9 @@ export class StableWSConnection {
601
649
  }
602
650
 
603
651
  // Keeping this `warn` level log, to avoid cluttering of error logs from ws failures.
604
- this._log(`_errorFromWSEvent() - WS failed with code ${code}`, { event }, 'warn');
652
+ logger
653
+ .withExtraTags('_errorFromWSEvent')
654
+ .warn(`The WebSocket failed with code ${code}.`, { event });
605
655
 
606
656
  const error = new Error(
607
657
  `WS failed with code ${code} and reason - ${message}`,
@@ -621,8 +671,7 @@ export class StableWSConnection {
621
671
  };
622
672
 
623
673
  /**
624
- * _destroyCurrentWSConnection - Removes the current WS connection
625
- *
674
+ * Removes the current WS connection.
626
675
  */
627
676
  _destroyCurrentWSConnection() {
628
677
  // increment the ID, meaning we will ignore all messages from the old
@@ -638,7 +687,7 @@ export class StableWSConnection {
638
687
  }
639
688
 
640
689
  /**
641
- * _setupPromise - sets up the this.connectOpen promise
690
+ * Sets up the `this.connectionOpen` promise.
642
691
  */
643
692
  _setupConnectionPromise = () => {
644
693
  this.isResolved = false;
@@ -650,7 +699,7 @@ export class StableWSConnection {
650
699
  };
651
700
 
652
701
  /**
653
- * Schedules a next health check ping for websocket.
702
+ * Schedules the next health check ping for the WebSocket connection.
654
703
  */
655
704
  scheduleNextPing = () => {
656
705
  if (this.healthCheckTimeoutRef) {
@@ -660,7 +709,7 @@ export class StableWSConnection {
660
709
  // 30 seconds is the recommended interval (messenger uses this)
661
710
  this.healthCheckTimeoutRef = setTimeout(() => {
662
711
  // send the healthcheck.., server replies with a health check event
663
- const data = [{ type: 'health.check', client_id: this.client.clientID }];
712
+ const data = [{ type: 'health.check', client_id: this.client.clientId }];
664
713
  // try to send on the connection
665
714
  try {
666
715
  this.ws?.send(JSON.stringify(data));
@@ -671,9 +720,9 @@ export class StableWSConnection {
671
720
  };
672
721
 
673
722
  /**
674
- * scheduleConnectionCheck - schedules a check for time difference between last received event and now.
675
- * If the difference is more than 35 seconds, it means our health check logic has failed and websocket needs
676
- * to be reconnected.
723
+ * Schedules a check for the time difference between the last received event and now. If the
724
+ * difference is more than 35 seconds, it means our health check logic has failed and the
725
+ * WebSocket needs to be reconnected.
677
726
  */
678
727
  scheduleConnectionCheck = () => {
679
728
  if (this.connectionCheckTimeoutRef) {
@@ -686,7 +735,9 @@ export class StableWSConnection {
686
735
  this.lastEvent &&
687
736
  now.getTime() - this.lastEvent.getTime() > this.connectionCheckTimeout
688
737
  ) {
689
- this._log('scheduleConnectionCheck - going to reconnect');
738
+ logger
739
+ .withExtraTags('scheduleConnectionCheck')
740
+ .warn('No events received within the health-check window. Reconnecting.');
690
741
  this._setHealth(false);
691
742
  this._reconnect();
692
743
  }