@webex/calling 3.12.0-mobius-socket.19 → 3.12.0-mobius-socket.20

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 (31) hide show
  1. package/dist/mobius-socket/errors.js +47 -6
  2. package/dist/mobius-socket/errors.js.map +1 -1
  3. package/dist/mobius-socket/index.js +4 -10
  4. package/dist/mobius-socket/index.js.map +1 -1
  5. package/dist/mobius-socket/mobius-socket.js +151 -140
  6. package/dist/mobius-socket/mobius-socket.js.map +1 -1
  7. package/dist/mobius-socket/mobius-socket.test.js +18 -11
  8. package/dist/mobius-socket/mobius-socket.test.js.map +1 -1
  9. package/dist/mobius-socket/socket/constants.js +14 -0
  10. package/dist/mobius-socket/socket/constants.js.map +1 -1
  11. package/dist/mobius-socket/socket/socket-base.js +93 -138
  12. package/dist/mobius-socket/socket/socket-base.js.map +1 -1
  13. package/dist/mobius-socket/socket/types.js.map +1 -1
  14. package/dist/mobius-socket/socket.test.js +3 -3
  15. package/dist/mobius-socket/socket.test.js.map +1 -1
  16. package/dist/mobius-socket/types.js.map +1 -1
  17. package/dist/module/mobius-socket/errors.js +17 -0
  18. package/dist/module/mobius-socket/mobius-socket.js +39 -41
  19. package/dist/module/mobius-socket/socket/socket-base.js +26 -58
  20. package/dist/types/mobius-socket/errors.d.ts +4 -1
  21. package/dist/types/mobius-socket/errors.d.ts.map +1 -1
  22. package/dist/types/mobius-socket/index.d.ts.map +1 -1
  23. package/dist/types/mobius-socket/mobius-socket.d.ts +14 -1
  24. package/dist/types/mobius-socket/mobius-socket.d.ts.map +1 -1
  25. package/dist/types/mobius-socket/socket/constants.d.ts.map +1 -1
  26. package/dist/types/mobius-socket/socket/socket-base.d.ts +0 -1
  27. package/dist/types/mobius-socket/socket/socket-base.d.ts.map +1 -1
  28. package/dist/types/mobius-socket/socket/types.d.ts +0 -8
  29. package/dist/types/mobius-socket/socket/types.d.ts.map +1 -1
  30. package/dist/types/mobius-socket/types.d.ts.map +1 -1
  31. package/package.json +1 -1
@@ -17,7 +17,6 @@ var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/ar
17
17
  var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
18
18
  var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
19
19
  var _now = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/date/now"));
20
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
21
20
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
22
21
  var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/typeof"));
23
22
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
@@ -26,6 +25,7 @@ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime
26
25
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
27
26
  var _get2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/get"));
28
27
  var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
28
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
29
29
  var _events = require("events");
30
30
  var _backoff = _interopRequireDefault(require("backoff"));
31
31
  var _socket = _interopRequireDefault(require("./socket"));
@@ -34,14 +34,15 @@ function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymb
34
34
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
35
35
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
36
36
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
37
- function _superPropGet(t, o, e, r) { var p = (0, _get2.default)((0, _getPrototypeOf2.default)(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; } // @ts-nocheck
38
- /* eslint-disable require-jsdoc */ /*!
37
+ function _superPropGet(t, o, e, r) { var p = (0, _get2.default)((0, _getPrototypeOf2.default)(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; } /*!
39
38
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file
40
- */
39
+ */ // @ts-ignore - backoff library does not have type definitions
41
40
  var normalReconnectReasons = ['idle', 'done (forced)'];
42
41
  var MOBIUS_SOCKET_NAMESPACE = 'MobiusSocket';
43
42
  var TOKEN_REFRESH_INTERVAL_MS = 1 * 60 * 60 * 1000; // 1 hour
44
43
 
44
+ // Extended Socket type with dynamic properties
45
+
45
46
  function normalizeMobiusAuthToken(token) {
46
47
  return token.replace(/^Bearer\s+/i, '');
47
48
  }
@@ -51,6 +52,22 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
51
52
  var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
52
53
  (0, _classCallCheck2.default)(this, MobiusSocket);
53
54
  _this = _callSuper(this, MobiusSocket);
55
+ (0, _defineProperty2.default)(_this, "webex", void 0);
56
+ (0, _defineProperty2.default)(_this, "config", void 0);
57
+ (0, _defineProperty2.default)(_this, "logger", void 0);
58
+ (0, _defineProperty2.default)(_this, "connected", void 0);
59
+ (0, _defineProperty2.default)(_this, "connecting", void 0);
60
+ (0, _defineProperty2.default)(_this, "hasEverConnected", void 0);
61
+ (0, _defineProperty2.default)(_this, "socket", void 0);
62
+ (0, _defineProperty2.default)(_this, "backoffCall", void 0);
63
+ // backoff library has no types
64
+ (0, _defineProperty2.default)(_this, "shutdownSwitchoverBackoffCall", void 0);
65
+ // backoff library has no types
66
+ (0, _defineProperty2.default)(_this, "seenAsyncEventIds", void 0);
67
+ (0, _defineProperty2.default)(_this, "connectPromise", void 0);
68
+ (0, _defineProperty2.default)(_this, "socketUrl", void 0);
69
+ (0, _defineProperty2.default)(_this, "tokenRefreshTimer", void 0);
70
+ (0, _defineProperty2.default)(_this, "tokenRefreshInFlight", void 0);
54
71
  if (!webex) {
55
72
  throw new Error('A Webex instance is required when initializing MobiusSocket');
56
73
  }
@@ -82,8 +99,7 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
82
99
 
83
100
  /**
84
101
  * Attach event listeners to a socket.
85
- * @param {Socket} socket - The socket to attach listeners to
86
- * @returns {void}
102
+ * @param socket - The socket to attach listeners to
87
103
  */
88
104
  }, {
89
105
  key: "attachSocketEventListeners",
@@ -92,15 +108,15 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
92
108
  socket.on('close', function (event) {
93
109
  return _this2.onclose(event, socket);
94
110
  });
95
- socket.on('message', function () {
96
- return _this2.onmessage.apply(_this2, arguments);
111
+ socket.on('message', function (event) {
112
+ return _this2.onmessage(event);
97
113
  });
98
114
  }
99
115
 
100
116
  /**
101
117
  * Tracks a newly seen async_event ID and reports whether a duplicate should be suppressed.
102
- * @param {object} envelope - Parsed websocket message envelope.
103
- * @returns {boolean} True when the event has already been seen.
118
+ * @param envelope - Parsed websocket message envelope
119
+ * @returns True when the event has already been seen
104
120
  */
105
121
  }, {
106
122
  key: "trackAsyncEventAndShouldSuppressDuplicate",
@@ -111,7 +127,7 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
111
127
  if (this.seenAsyncEventIds.has(envelope.eventId)) {
112
128
  // Refresh recency so frequently retransmitted eventIds stay protected longer.
113
129
  // This deletion and setting again makes the data recent since javascript map maintains order as well
114
- var previousValue = this.seenAsyncEventIds.get(envelope.eventId);
130
+ var previousValue = this.seenAsyncEventIds.get(envelope.eventId) || true;
115
131
  this.seenAsyncEventIds.delete(envelope.eventId);
116
132
  this.seenAsyncEventIds.set(envelope.eventId, previousValue);
117
133
  this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": duplicate async_event suppressed, eventId=").concat(envelope.eventId));
@@ -119,8 +135,8 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
119
135
  }
120
136
  this.logger.log("".concat(MOBIUS_SOCKET_NAMESPACE, ": tracking async_event, eventId=").concat(envelope.eventId));
121
137
  this.seenAsyncEventIds.set(envelope.eventId, true);
122
- if (this.seenAsyncEventIds.size > this.config.dedupCacheMaxSize) {
123
- var oldestEventId = this.seenAsyncEventIds.keys().next().value;
138
+ if (this.config.dedupCacheMaxSize && this.seenAsyncEventIds.size > this.config.dedupCacheMaxSize) {
139
+ var oldestEventId = this.seenAsyncEventIds.keys().next().value || '';
124
140
  this.seenAsyncEventIds.delete(oldestEventId);
125
141
  this.logger.log("".concat(MOBIUS_SOCKET_NAMESPACE, ": evicted oldest async_event from dedup cache, eventId=").concat(oldestEventId));
126
142
  }
@@ -182,7 +198,7 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
182
198
 
183
199
  /**
184
200
  * Get the websocket URL for the currently connected socket.
185
- * @returns {string|undefined} The connected websocket URL, or undefined when not connected.
201
+ * @returns The connected websocket URL, or undefined when not connected
186
202
  */
187
203
  }, {
188
204
  key: "getConnectedWebSocketUrl",
@@ -196,14 +212,13 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
196
212
 
197
213
  /**
198
214
  * Sends a websocket request and resolves when the matching response arrives.
199
- * @param {MobiusSocketRequestPayload} payload - The websocket request payload.
200
- * @param {MobiusSocketRequestOptions} [options={}] - Additional request options.
201
- * @returns {Promise<SocketResponse>}
215
+ * @param payload - The websocket request payload
216
+ * @param options - Additional request options
217
+ * @returns Promise that resolves with the socket response
202
218
  */
203
219
  }, {
204
220
  key: "sendWssRequest",
205
221
  value: function sendWssRequest(payload) {
206
- var _this4 = this;
207
222
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
208
223
  if (!payload || (0, _typeof2.default)(payload) !== 'object' || (0, _isArray.default)(payload)) {
209
224
  return _promise.default.reject(new Error('`payload` is required'));
@@ -211,34 +226,14 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
211
226
  if (!this.socket || !this.socket.connected) {
212
227
  return _promise.default.reject(new Error('Mobius socket is not connected'));
213
228
  }
214
- var requestConfigOptions = {
215
- timeout: options.timeout,
216
- matchesResponse: function matchesResponse(response, request) {
217
- return (response === null || response === void 0 ? void 0 : response.type) === 'response_event' && (response === null || response === void 0 ? void 0 : response.subtype) === request.type && (response === null || response === void 0 ? void 0 : response.trackingId) === request.trackingId;
218
- },
219
- getStatusCode: function getStatusCode(response) {
220
- return response === null || response === void 0 ? void 0 : response.statusCode;
221
- },
222
- getStatusMessage: function getStatusMessage(response) {
223
- return response === null || response === void 0 ? void 0 : response.statusMessage;
224
- },
225
- createError: function createError(response, statusCode, statusMessage) {
226
- return _this4.createWssResponseError(response, statusCode, statusMessage);
227
- },
228
- createTimeoutError: function createTimeoutError(request) {
229
- return _this4.createWssResponseError({
230
- type: 'response_event',
231
- subtype: request.type,
232
- trackingId: request.trackingId
233
- }, 408, 'Mobius websocket response timed out');
234
- }
235
- };
236
- return this.socket.sendRequest(payload, requestConfigOptions);
229
+ return this.socket.sendRequest(payload, {
230
+ timeout: options.timeout
231
+ });
237
232
  }
238
233
 
239
234
  /**
240
235
  * Check if the socket is connected.
241
- * @returns {boolean} True if connected.
236
+ * @returns True if connected
242
237
  */
243
238
  }, {
244
239
  key: "isConnected",
@@ -248,15 +243,17 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
248
243
 
249
244
  /**
250
245
  * Connect to Mobius.
251
- * @param {string} [webSocketUrl] - Optional websocket URL override. Falls back to the device websocket URL.
252
- * @returns {Promise<void>} Resolves when connection flow completes.
246
+ * @param webSocketUrl - Optional websocket URL override. Falls back to the device websocket URL
247
+ * @returns Promise that resolves when connection flow completes
253
248
  */
254
249
  }, {
255
250
  key: "connect",
256
251
  value: function connect(webSocketUrl) {
257
252
  var _this$socket2,
258
253
  _this$socket3,
259
- _this5 = this;
254
+ _this$webex$internal$,
255
+ _this$webex$internal$2,
256
+ _this4 = this;
260
257
  if (this.connectPromise) {
261
258
  this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connection already in progress, returning existing promise"));
262
259
  return this.connectPromise;
@@ -278,11 +275,11 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
278
275
  }
279
276
  this.connecting = true;
280
277
  this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": starting connection attempt").concat(Number(this.config.initialConnectionMaxRetries) === 0 && !this.hasEverConnected ? ' (initial retries disabled)' : ''));
281
- var connectPromise = _promise.default.resolve(this.webex.internal.device.registered || this.webex.internal.device.register()).then(function () {
282
- _this5.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connecting"));
283
- return _this5.connectWithBackoff(_this5.socketUrl);
278
+ var connectPromise = _promise.default.resolve(this.webex.internal.device.registered || ((_this$webex$internal$ = (_this$webex$internal$2 = this.webex.internal.device).register) === null || _this$webex$internal$ === void 0 ? void 0 : _this$webex$internal$.call(_this$webex$internal$2))).then(function () {
279
+ _this4.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connecting"));
280
+ return _this4.connectWithBackoff(_this4.socketUrl);
284
281
  }).finally(function () {
285
- _this5.connectPromise = undefined;
282
+ _this4.connectPromise = undefined;
286
283
  });
287
284
  this.connectPromise = connectPromise;
288
285
  return connectPromise;
@@ -290,13 +287,13 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
290
287
 
291
288
  /**
292
289
  * Disconnect the Mobius socket.
293
- * @param {MobiusSocketCloseOptions} [options] - Optional websocket close options (code, reason).
294
- * @returns {Promise<void>} Resolves after disconnect cleanup and close handling complete.
290
+ * @param options - Optional websocket close options (code, reason)
291
+ * @returns Promise that resolves after disconnect cleanup and close handling complete
295
292
  */
296
293
  }, {
297
294
  key: "disconnect",
298
295
  value: function disconnect(options) {
299
- var _this6 = this;
296
+ var _this5 = this;
300
297
  this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, "#disconnect: connecting state: ").concat(this.connecting, ",\n connected state: ").concat(this.connected, ", socket exists: ").concat(!!this.socket, ",\n options: ").concat((0, _stringify.default)(options)));
301
298
  if (this.backoffCall) {
302
299
  this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": aborting connection"));
@@ -319,41 +316,30 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
319
316
  this.socket.connecting = false;
320
317
  this.socket.connected = false;
321
318
  return _promise.default.resolve(this.socket.close(options || undefined)).finally(function () {
322
- _this6.connected = false;
323
- _this6.stopTokenRefreshTimer();
319
+ _this5.connected = false;
320
+ _this5.stopTokenRefreshTimer();
324
321
  });
325
322
  }
326
-
327
- // eslint-disable-next-line class-methods-use-this
328
- }, {
329
- key: "createWssResponseError",
330
- value: function createWssResponseError(response, statusCode, statusMessage) {
331
- var error = new Error(statusMessage || "Mobius websocket request failed with status ".concat(statusCode || 'unknown'));
332
- error.name = 'MobiusSocketResponseError';
333
- error.statusCode = statusCode;
334
- error.statusMessage = statusMessage;
335
- error.response = response;
336
- error.trackingId = response === null || response === void 0 ? void 0 : response.trackingId;
337
- return error;
338
- }
339
323
  }, {
340
324
  key: "prepareUrl",
341
325
  value: function prepareUrl(webSocketUrl) {
342
326
  if (!webSocketUrl) {
343
327
  // TODO: Circle back to this logic when mobius implements the shutdown switchover
344
- webSocketUrl = this.webex.internal.device.webSocketUrl;
328
+ webSocketUrl = this.webex.internal.device.webSocketUrl || '';
345
329
  }
346
330
  return _promise.default.resolve(webSocketUrl);
347
331
  }
348
332
  }, {
349
333
  key: "attemptConnection",
350
334
  value: function attemptConnection(socketUrl, callback) {
351
- var _this7 = this;
335
+ var _this6 = this;
352
336
  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
353
337
  var _options$isShutdownSw = options.isShutdownSwitchover,
354
338
  isShutdownSwitchover = _options$isShutdownSw === void 0 ? false : _options$isShutdownSw,
355
- _options$onSuccess = options.onSuccess,
356
- onSuccess = _options$onSuccess === void 0 ? null : _options$onSuccess;
339
+ _options$attemptOptio = options.attemptOptions,
340
+ attemptOptions = _options$attemptOptio === void 0 ? {} : _options$attemptOptio;
341
+ var _attemptOptions$onSuc = attemptOptions.onSuccess,
342
+ onSuccess = _attemptOptions$onSuc === void 0 ? null : _attemptOptions$onSuc;
357
343
  var socket = new _socket.default();
358
344
  socket.connecting = true;
359
345
  var newWSUrl;
@@ -378,7 +364,7 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
378
364
  }
379
365
  return this.prepareAndOpenSocket(socket, socketUrl, isShutdownSwitchover).then(function (webSocketUrl) {
380
366
  newWSUrl = webSocketUrl;
381
- _this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(isShutdownSwitchover ? '[shutdown] switchover' : '', " connected to mobius socket, success, url: ").concat(newWSUrl));
367
+ _this6.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(isShutdownSwitchover ? '[shutdown] switchover' : '', " connected to mobius socket, success, url: ").concat(newWSUrl));
382
368
 
383
369
  // Custom success handler for shutdown switchover
384
370
  if (onSuccess) {
@@ -393,52 +379,54 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
393
379
  }).catch(function (reason) {
394
380
  // For shutdown, simpler error handling - just callback for retry
395
381
  if (isShutdownSwitchover) {
396
- _this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover attempt failed"), reason);
382
+ _this6.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover attempt failed"), reason);
397
383
  return callback(reason);
398
384
  }
399
385
 
400
386
  // Normal connection error handling
401
- var backoffCallNormal = _this7.backoffCall;
387
+ var backoffCallNormal = _this6.backoffCall;
402
388
  // Suppress connection errors that appear to be network related (code 1006).
403
389
  if (reason.code !== 1006 && backoffCallNormal && (backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.getNumRetries()) > 0) {
404
- _this7.emitEvent('connection_failed', reason, {
390
+ _this6.emitEvent('connection_failed', reason, {
405
391
  retries: backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.getNumRetries()
406
392
  });
407
393
  }
408
- _this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connection attempt failed"), reason, (backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.getNumRetries()) === 0 ? reason.stack : '');
394
+ _this6.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connection attempt failed"), reason, (backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.getNumRetries()) === 0 ? reason.stack : '');
409
395
 
410
396
  // UnknownResponse is produced by IE for any 4XXX; treat it like a bad
411
397
  // web socket url and let WDM handle the token checking
412
398
  if (reason instanceof _errors.UnknownResponse) {
413
- _this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": received unknown response code, refreshing device registration"));
414
- return _this7.webex.internal.device.refresh().then(function () {
399
+ var _this6$webex$internal, _this6$webex$internal2;
400
+ _this6.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": received unknown response code, refreshing device registration"));
401
+ return (_this6$webex$internal = (_this6$webex$internal2 = _this6.webex.internal.device).refresh) === null || _this6$webex$internal === void 0 ? void 0 : _this6$webex$internal.call(_this6$webex$internal2).then(function () {
415
402
  return callback(reason);
416
403
  });
417
404
  }
418
405
  // NotAuthorized implies expired token
419
406
  if (reason instanceof _errors.NotAuthorized) {
420
- _this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": received authorization error, reauthorizing"));
421
- return _this7.webex.credentials.refresh({
407
+ var _this6$webex$credenti, _this6$webex$credenti2;
408
+ _this6.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": received authorization error, reauthorizing"));
409
+ return (_this6$webex$credenti = (_this6$webex$credenti2 = _this6.webex.credentials).refresh) === null || _this6$webex$credenti === void 0 ? void 0 : _this6$webex$credenti.call(_this6$webex$credenti2, {
422
410
  force: true
423
411
  }).then(function () {
424
412
  return callback(reason);
425
413
  });
426
414
  }
427
415
  if (reason instanceof _errors.BadRequest || reason instanceof _errors.Forbidden) {
428
- _this7.logger.warn("".concat(MOBIUS_SOCKET_NAMESPACE, ": received unrecoverable response from ").concat(MOBIUS_SOCKET_NAMESPACE));
416
+ _this6.logger.warn("".concat(MOBIUS_SOCKET_NAMESPACE, ": received unrecoverable response from ").concat(MOBIUS_SOCKET_NAMESPACE));
429
417
  backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.abort();
430
418
  return callback(reason);
431
419
  }
432
420
  return callback(reason);
433
421
  }).catch(function (reason) {
434
- _this7.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": failed to handle connection failure"), reason);
422
+ _this6.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": failed to handle connection failure"), reason);
435
423
  callback(reason);
436
424
  });
437
425
  }
438
426
  }, {
439
427
  key: "prepareAndOpenSocket",
440
428
  value: function prepareAndOpenSocket(socket, socketUrl) {
441
- var _this8 = this;
429
+ var _this7 = this;
442
430
  var isShutdownSwitchover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
443
431
  var logPrefix = isShutdownSwitchover ? '[shutdown] switchover' : 'connection';
444
432
  return _promise.default.all([this.prepareUrl(socketUrl), this.webex.credentials.getUserToken()]).then(function (_ref) {
@@ -446,27 +434,27 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
446
434
  webSocketUrl = _ref2[0],
447
435
  token = _ref2[1];
448
436
  var options = {
449
- forceCloseDelay: _this8.config.forceCloseDelay,
450
- wssResponseTimeout: _this8.config.wssResponseTimeout,
437
+ forceCloseDelay: _this7.config.forceCloseDelay,
438
+ wssResponseTimeout: _this7.config.wssResponseTimeout,
451
439
  token: normalizeMobiusAuthToken(token.toString()),
452
440
  refreshToken: function refreshToken() {
453
- return _this8.refreshToken();
441
+ return _this7.refreshToken();
454
442
  },
455
- trackingId: "".concat(_this8.webex.sessionId, "_").concat((0, _now.default)()),
456
- logger: _this8.logger
443
+ trackingId: "".concat(_this7.webex.sessionId, "_").concat((0, _now.default)()),
444
+ logger: _this7.logger
457
445
  };
458
- if (_this8.webex.config.defaultMobiusSocketOptions) {
446
+ if (_this7.webex.config.defaultMobiusSocketOptions) {
459
447
  var customOptionsMsg = isShutdownSwitchover ? 'setting custom options for switchover' : 'setting custom options';
460
- _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(customOptionsMsg));
461
- options = _objectSpread(_objectSpread({}, options), _this8.webex.config.defaultMobiusSocketOptions);
448
+ _this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(customOptionsMsg));
449
+ options = _objectSpread(_objectSpread({}, options), _this7.webex.config.defaultMobiusSocketOptions);
462
450
  }
463
451
 
464
452
  // Only promote the socket reference for normal connections.
465
453
  // Shutdown switchover keeps the old socket active until the new one succeeds.
466
454
  if (!isShutdownSwitchover) {
467
- _this8.socket = socket;
455
+ _this7.socket = socket;
468
456
  }
469
- _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, " ").concat(logPrefix, " url: ").concat(webSocketUrl));
457
+ _this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, " ").concat(logPrefix, " url: ").concat(webSocketUrl));
470
458
  return socket.open(webSocketUrl, options).then(function () {
471
459
  return webSocketUrl;
472
460
  });
@@ -475,48 +463,47 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
475
463
  }, {
476
464
  key: "connectWithBackoff",
477
465
  value: function connectWithBackoff(webSocketUrl) {
478
- var _this9 = this;
466
+ var _this8 = this;
479
467
  var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
480
468
  var _context$isShutdownSw = context.isShutdownSwitchover,
481
469
  isShutdownSwitchover = _context$isShutdownSw === void 0 ? false : _context$isShutdownSw,
482
470
  _context$attemptOptio = context.attemptOptions,
483
471
  attemptOptions = _context$attemptOptio === void 0 ? {} : _context$attemptOptio;
484
472
  return new _promise.default(function (resolve, reject) {
485
- // eslint-disable-next-line prefer-const
486
473
  var call;
487
- var isInitialConnect = !isShutdownSwitchover && !_this9.hasEverConnected;
488
- var initialRetryLimit = _this9.config.initialConnectionMaxRetries == null ? null : Number(_this9.config.initialConnectionMaxRetries);
474
+ var isInitialConnect = !isShutdownSwitchover && !_this8.hasEverConnected;
475
+ var initialRetryLimit = _this8.config.initialConnectionMaxRetries == null ? null : Number(_this8.config.initialConnectionMaxRetries);
489
476
  var isInitialConnectWithoutRetries = isInitialConnect && initialRetryLimit === 0;
490
477
  var onComplete = function onComplete(err) {
491
478
  if (isShutdownSwitchover) {
492
- _this9.shutdownSwitchoverBackoffCall = undefined;
479
+ _this8.shutdownSwitchoverBackoffCall = undefined;
493
480
  } else {
494
- _this9.backoffCall = undefined;
481
+ _this8.backoffCall = undefined;
495
482
  }
496
483
  if (err) {
497
484
  var msg = isShutdownSwitchover ? "[shutdown] switchover failed after ".concat(call.getNumRetries(), " retries") : "failed to connect after ".concat(call.getNumRetries(), " retries");
498
- _this9.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(msg, "; ").concat(err));
485
+ _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(msg, "; ").concat(err));
499
486
  // Only mutate socket flags for normal connections.
500
487
  // During shutdown switchover, this.socket is the old live socket — don't touch it.
501
- if (!isShutdownSwitchover && _this9.socket) {
502
- _this9.socket.connecting = false;
503
- _this9.socket.connected = false;
488
+ if (!isShutdownSwitchover && _this8.socket) {
489
+ _this8.socket.connecting = false;
490
+ _this8.socket.connected = false;
504
491
  }
505
492
  return reject(err);
506
493
  }
507
494
 
508
495
  // For normal connections, mark the socket as connected.
509
496
  // Shutdown switchover promotion is handled by the onSuccess callback.
510
- if (!isShutdownSwitchover && _this9.socket) {
511
- _this9.socket.connecting = false;
512
- _this9.socket.connected = true;
497
+ if (!isShutdownSwitchover && _this8.socket) {
498
+ _this8.socket.connecting = false;
499
+ _this8.socket.connected = true;
513
500
  }
514
501
  if (!isShutdownSwitchover) {
515
- _this9.connecting = false;
516
- _this9.connected = true;
517
- _this9.hasEverConnected = true;
518
- _this9.startTokenRefreshTimer();
519
- _this9.emitEvent('online');
502
+ _this8.connecting = false;
503
+ _this8.connected = true;
504
+ _this8.hasEverConnected = true;
505
+ _this8.startTokenRefreshTimer();
506
+ _this8.emitEvent('online');
520
507
  }
521
508
  return resolve();
522
509
  };
@@ -524,57 +511,63 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
524
511
  call = _backoff.default.call(function (callback) {
525
512
  var attemptNum = call.getNumRetries();
526
513
  var attemptLogPrefix = isShutdownSwitchover ? '[shutdown] switchover' : 'connection';
527
- _this9.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": executing ").concat(attemptLogPrefix, " attempt ").concat(attemptNum));
528
- _this9.attemptConnection(webSocketUrl, callback, attemptOptions);
514
+ _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": executing ").concat(attemptLogPrefix, " attempt ").concat(attemptNum));
515
+ _this8.attemptConnection(webSocketUrl, callback, attemptOptions);
529
516
  }, function (err) {
530
517
  return onComplete(err);
531
518
  });
532
519
  call.setStrategy(new _backoff.default.ExponentialStrategy({
533
- initialDelay: _this9.config.backoffTimeReset,
534
- maxDelay: _this9.config.backoffTimeMax
520
+ initialDelay: _this8.config.backoffTimeReset,
521
+ maxDelay: _this8.config.backoffTimeMax
535
522
  }));
536
523
  if (isInitialConnectWithoutRetries) {
537
524
  call.retryIf(function () {
538
525
  return false;
539
526
  });
540
- } else if (isInitialConnect && initialRetryLimit > 0) {
527
+ } else if (isInitialConnect && initialRetryLimit !== null && initialRetryLimit > 0) {
541
528
  call.failAfter(initialRetryLimit);
542
- } else if (_this9.config.maxRetries) {
543
- call.failAfter(_this9.config.maxRetries);
529
+ } else if (_this8.config.maxRetries) {
530
+ call.failAfter(_this8.config.maxRetries);
544
531
  }
545
532
 
546
533
  // Store backoff call reference BEFORE starting (so it's available in attemptConnection)
547
534
  if (isShutdownSwitchover) {
548
- _this9.shutdownSwitchoverBackoffCall = call;
535
+ _this8.shutdownSwitchoverBackoffCall = call;
549
536
  } else {
550
- _this9.backoffCall = call;
537
+ _this8.backoffCall = call;
551
538
  }
552
539
  call.on('abort', function () {
553
540
  var msg = isShutdownSwitchover ? 'Shutdown Switchover' : 'Connection';
554
- _this9.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(msg, " aborted"));
541
+ _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(msg, " aborted"));
555
542
  reject(new Error("MobiusSocket ".concat(msg, " Aborted")));
556
543
  });
557
544
  call.on('callback', function (err) {
558
545
  if (err) {
559
546
  if (isInitialConnectWithoutRetries) {
560
- _this9.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": initial connect failed; retries already disabled"));
547
+ _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": initial connect failed; retries already disabled"));
561
548
  return;
562
549
  }
563
550
  var number = call.getNumRetries();
564
- var delay = Math.min(call.strategy_.nextBackoffDelay_, _this9.config.backoffTimeMax);
551
+ var delay = Math.min(call.strategy_.nextBackoffDelay_, _this8.config.backoffTimeMax || Infinity);
565
552
  var callbackLogPrefix = isShutdownSwitchover ? '[shutdown] switchover' : '';
566
- _this9.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(callbackLogPrefix, " failed to connect; attempting retry ").concat(number + 1, " in ").concat(delay, " ms"));
553
+ _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(callbackLogPrefix, " failed to connect; attempting retry ").concat(number + 1, " in ").concat(delay, " ms"));
567
554
  /* istanbul ignore if */
568
555
  if (process.env.NODE_ENV === 'development') {
569
- _this9.logger.debug("".concat(MOBIUS_SOCKET_NAMESPACE, ": "), err, err.stack);
556
+ _this8.logger.debug("".concat(MOBIUS_SOCKET_NAMESPACE, ": "), err, err.stack);
570
557
  }
571
558
  return;
572
559
  }
573
- _this9.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connected"));
560
+ _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connected"));
574
561
  });
575
562
  call.start();
576
563
  });
577
564
  }
565
+
566
+ /**
567
+ * Safely emits an event, catching and logging any errors from event handlers.
568
+ * @param eventName - The name of the event to emit
569
+ * @param args - Arguments to pass to event handlers
570
+ */
578
571
  }, {
579
572
  key: "emitEvent",
580
573
  value: function emitEvent(eventName) {
@@ -591,19 +584,28 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
591
584
  this.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": error occurred in event handler:"), error, ' with args: ', [eventName].concat(args));
592
585
  }
593
586
  }
587
+
588
+ /**
589
+ * Starts a periodic timer to refresh the authentication token.
590
+ * Token refresh occurs every hour while connected.
591
+ */
594
592
  }, {
595
593
  key: "startTokenRefreshTimer",
596
594
  value: function startTokenRefreshTimer() {
597
- var _this0 = this;
595
+ var _this9 = this;
598
596
  if (this.tokenRefreshTimer || !this.connected) {
599
597
  return;
600
598
  }
601
599
  this.tokenRefreshTimer = setInterval(function () {
602
- _this0.refreshToken().catch(function (error) {
603
- _this0.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": periodic token refresh failed"), error);
600
+ _this9.refreshToken().catch(function (error) {
601
+ _this9.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": periodic token refresh failed"), error);
604
602
  });
605
603
  }, TOKEN_REFRESH_INTERVAL_MS);
606
604
  }
605
+
606
+ /**
607
+ * Stops the periodic token refresh timer.
608
+ */
607
609
  }, {
608
610
  key: "stopTokenRefreshTimer",
609
611
  value: function stopTokenRefreshTimer() {
@@ -613,10 +615,18 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
613
615
  clearInterval(this.tokenRefreshTimer);
614
616
  this.tokenRefreshTimer = undefined;
615
617
  }
618
+
619
+ /**
620
+ * Refreshes the authentication token and re-authenticates the socket connection.
621
+ * @returns Promise that resolves when token refresh and re-authentication complete
622
+ */
616
623
  }, {
617
624
  key: "refreshToken",
618
625
  value: function refreshToken() {
619
- var _this1 = this;
626
+ var _this$webex$credentia,
627
+ _this$webex$credentia2,
628
+ _this$webex$credentia3,
629
+ _this0 = this;
620
630
  if (this.tokenRefreshInFlight) {
621
631
  return this.tokenRefreshInFlight;
622
632
  }
@@ -624,26 +634,27 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
624
634
  this.stopTokenRefreshTimer();
625
635
  return _promise.default.resolve();
626
636
  }
627
- var tokenPromise = this.webex.credentials.canRefresh ? this.webex.credentials.refresh({
637
+ var tokenPromise = this.webex.credentials.canRefresh ? (_this$webex$credentia = (_this$webex$credentia2 = this.webex.credentials).refresh) === null || _this$webex$credentia === void 0 ? void 0 : (_this$webex$credentia3 = _this$webex$credentia.call(_this$webex$credentia2, {
628
638
  force: true
629
- }).then(function () {
630
- return _this1.webex.credentials.getUserToken();
639
+ })) === null || _this$webex$credentia3 === void 0 ? void 0 : _this$webex$credentia3.then(function () {
640
+ return _this0.webex.credentials.getUserToken();
631
641
  }) : this.webex.credentials.getUserToken();
632
642
  this.tokenRefreshInFlight = tokenPromise.then(function (token) {
633
- var _this1$socket;
643
+ var _this0$socket;
634
644
  if (!token) {
635
645
  throw new Error('Mobius token refresh did not return a token');
636
646
  }
637
647
  var refreshedToken = normalizeMobiusAuthToken(token.toString());
638
- if ((_this1$socket = _this1.socket) !== null && _this1$socket !== void 0 && _this1$socket.connected) {
639
- return _this1.socket.refresh(refreshedToken);
648
+ if (!((_this0$socket = _this0.socket) !== null && _this0$socket !== void 0 && _this0$socket.connected)) {
649
+ _this0.logger.warn("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket is not connected, skipping token refresh"));
650
+ return undefined;
640
651
  }
641
- return undefined;
652
+ return _this0.socket.refresh(refreshedToken);
642
653
  }).catch(function (error) {
643
- _this1.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": failed to refresh/re-auth Mobius socket"), error);
654
+ _this0.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": failed to refresh/re-auth Mobius socket"), error);
644
655
  throw error;
645
656
  }).finally(function () {
646
- _this1.tokenRefreshInFlight = undefined;
657
+ _this0.tokenRefreshInFlight = undefined;
647
658
  });
648
659
  return this.tokenRefreshInFlight;
649
660
  }
@@ -713,7 +724,7 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
713
724
  break;
714
725
  case 1000:
715
726
  case 3050:
716
- if (normalReconnectReasons.includes(reason)) {
727
+ if (reason && normalReconnectReasons.includes(reason)) {
717
728
  this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket disconnected; reconnecting"));
718
729
  if (isActiveSocket) {
719
730
  this.emitEvent('offline.transient', event);