@webex/calling 3.12.0-next.27 → 3.12.0-next.29

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 (189) hide show
  1. package/dist/CallingClient/CallingClient.js +463 -205
  2. package/dist/CallingClient/CallingClient.js.map +1 -1
  3. package/dist/CallingClient/CallingClient.test.js +170 -77
  4. package/dist/CallingClient/CallingClient.test.js.map +1 -1
  5. package/dist/CallingClient/calling/call.js +11 -8
  6. package/dist/CallingClient/calling/call.js.map +1 -1
  7. package/dist/CallingClient/calling/call.test.js +45 -4
  8. package/dist/CallingClient/calling/call.test.js.map +1 -1
  9. package/dist/CallingClient/calling/callManager.js +53 -30
  10. package/dist/CallingClient/calling/callManager.js.map +1 -1
  11. package/dist/CallingClient/calling/callManager.test.js +35 -0
  12. package/dist/CallingClient/calling/callManager.test.js.map +1 -1
  13. package/dist/CallingClient/calling/types.js +2 -0
  14. package/dist/CallingClient/calling/types.js.map +1 -1
  15. package/dist/CallingClient/constants.js +24 -3
  16. package/dist/CallingClient/constants.js.map +1 -1
  17. package/dist/CallingClient/line/line.test.js +16 -1
  18. package/dist/CallingClient/line/line.test.js.map +1 -1
  19. package/dist/CallingClient/registration/register.js +694 -406
  20. package/dist/CallingClient/registration/register.js.map +1 -1
  21. package/dist/CallingClient/registration/register.test.js +202 -21
  22. package/dist/CallingClient/registration/register.test.js.map +1 -1
  23. package/dist/CallingClient/registration/types.js.map +1 -1
  24. package/dist/CallingClient/registration/webWorker.js +41 -104
  25. package/dist/CallingClient/registration/webWorker.js.map +1 -1
  26. package/dist/CallingClient/registration/webWorker.test.js +39 -153
  27. package/dist/CallingClient/registration/webWorker.test.js.map +1 -1
  28. package/dist/CallingClient/registration/webWorkerStr.js +1 -1
  29. package/dist/CallingClient/registration/webWorkerStr.js.map +1 -1
  30. package/dist/CallingClient/utils/constants.js +46 -0
  31. package/dist/CallingClient/utils/constants.js.map +1 -0
  32. package/dist/CallingClient/utils/index.js +63 -0
  33. package/dist/CallingClient/utils/index.js.map +1 -0
  34. package/dist/CallingClient/utils/mobiusSocketMapper.js +122 -0
  35. package/dist/CallingClient/utils/mobiusSocketMapper.js.map +1 -0
  36. package/dist/CallingClient/utils/mobiusSocketMapper.test.js +211 -0
  37. package/dist/CallingClient/utils/mobiusSocketMapper.test.js.map +1 -0
  38. package/dist/CallingClient/utils/request.js +349 -0
  39. package/dist/CallingClient/utils/request.js.map +1 -0
  40. package/dist/CallingClient/utils/request.test.js +881 -0
  41. package/dist/CallingClient/utils/request.test.js.map +1 -0
  42. package/dist/CallingClient/utils/types.js +7 -0
  43. package/dist/CallingClient/utils/types.js.map +1 -0
  44. package/dist/CallingClient/utils/wsFeatureFlag.js +28 -0
  45. package/dist/CallingClient/utils/wsFeatureFlag.js.map +1 -0
  46. package/dist/CallingClient/utils/wsFeatureFlag.test.js +139 -0
  47. package/dist/CallingClient/utils/wsFeatureFlag.test.js.map +1 -0
  48. package/dist/Contacts/ContactsClient.test.js +3 -8
  49. package/dist/Contacts/ContactsClient.test.js.map +1 -1
  50. package/dist/Metrics/index.js +60 -0
  51. package/dist/Metrics/index.js.map +1 -1
  52. package/dist/Metrics/index.test.js +356 -0
  53. package/dist/Metrics/index.test.js.map +1 -1
  54. package/dist/Metrics/types.js +11 -1
  55. package/dist/Metrics/types.js.map +1 -1
  56. package/dist/SDKConnector/types.js.map +1 -1
  57. package/dist/common/Utils.js +138 -44
  58. package/dist/common/Utils.js.map +1 -1
  59. package/dist/common/testUtil.js +8 -4
  60. package/dist/common/testUtil.js.map +1 -1
  61. package/dist/common/types.js +2 -0
  62. package/dist/common/types.js.map +1 -1
  63. package/dist/mobius-socket/config.js +24 -0
  64. package/dist/mobius-socket/config.js.map +1 -0
  65. package/dist/mobius-socket/errors.js +150 -0
  66. package/dist/mobius-socket/errors.js.map +1 -0
  67. package/dist/mobius-socket/index.js +57 -0
  68. package/dist/mobius-socket/index.js.map +1 -0
  69. package/dist/mobius-socket/mobius-socket-events.test.js +485 -0
  70. package/dist/mobius-socket/mobius-socket-events.test.js.map +1 -0
  71. package/dist/mobius-socket/mobius-socket.js +804 -0
  72. package/dist/mobius-socket/mobius-socket.js.map +1 -0
  73. package/dist/mobius-socket/mobius-socket.test.js +1833 -0
  74. package/dist/mobius-socket/mobius-socket.test.js.map +1 -0
  75. package/dist/mobius-socket/socket/constants.js +34 -0
  76. package/dist/mobius-socket/socket/constants.js.map +1 -0
  77. package/dist/mobius-socket/socket/index.js +15 -0
  78. package/dist/mobius-socket/socket/index.js.map +1 -0
  79. package/dist/mobius-socket/socket/socket-base.js +604 -0
  80. package/dist/mobius-socket/socket/socket-base.js.map +1 -0
  81. package/dist/mobius-socket/socket/socket.js +19 -0
  82. package/dist/mobius-socket/socket/socket.js.map +1 -0
  83. package/dist/mobius-socket/socket/socket.shim.js +26 -0
  84. package/dist/mobius-socket/socket/socket.shim.js.map +1 -0
  85. package/dist/mobius-socket/socket/types.js +7 -0
  86. package/dist/mobius-socket/socket/types.js.map +1 -0
  87. package/dist/mobius-socket/socket.test.js +727 -0
  88. package/dist/mobius-socket/socket.test.js.map +1 -0
  89. package/dist/mobius-socket/test/mocha-helpers.js +23 -0
  90. package/dist/mobius-socket/test/mocha-helpers.js.map +1 -0
  91. package/dist/mobius-socket/test/promise-tick.js +28 -0
  92. package/dist/mobius-socket/test/promise-tick.js.map +1 -0
  93. package/dist/mobius-socket/types.js +7 -0
  94. package/dist/mobius-socket/types.js.map +1 -0
  95. package/dist/module/CallingClient/CallingClient.js +141 -10
  96. package/dist/module/CallingClient/calling/call.js +9 -6
  97. package/dist/module/CallingClient/calling/callManager.js +27 -7
  98. package/dist/module/CallingClient/calling/types.js +2 -0
  99. package/dist/module/CallingClient/constants.js +20 -0
  100. package/dist/module/CallingClient/registration/register.js +226 -62
  101. package/dist/module/CallingClient/registration/webWorker.js +42 -61
  102. package/dist/module/CallingClient/registration/webWorkerStr.js +47 -82
  103. package/dist/module/CallingClient/utils/constants.js +30 -0
  104. package/dist/module/CallingClient/utils/index.js +5 -0
  105. package/dist/module/CallingClient/utils/mobiusSocketMapper.js +72 -0
  106. package/dist/module/CallingClient/utils/request.js +162 -0
  107. package/dist/module/CallingClient/utils/types.js +1 -0
  108. package/dist/module/CallingClient/utils/wsFeatureFlag.js +12 -0
  109. package/dist/module/Metrics/index.js +46 -0
  110. package/dist/module/Metrics/types.js +10 -0
  111. package/dist/module/common/Utils.js +52 -12
  112. package/dist/module/common/testUtil.js +5 -1
  113. package/dist/module/common/types.js +2 -0
  114. package/dist/module/mobius-socket/config.js +15 -0
  115. package/dist/module/mobius-socket/errors.js +64 -0
  116. package/dist/module/mobius-socket/index.js +24 -0
  117. package/dist/module/mobius-socket/mobius-socket.js +571 -0
  118. package/dist/module/mobius-socket/socket/constants.js +10 -0
  119. package/dist/module/mobius-socket/socket/index.js +4 -0
  120. package/dist/module/mobius-socket/socket/socket-base.js +368 -0
  121. package/dist/module/mobius-socket/socket/socket.js +9 -0
  122. package/dist/module/mobius-socket/socket/socket.shim.js +12 -0
  123. package/dist/module/mobius-socket/socket/types.js +1 -0
  124. package/dist/module/mobius-socket/types.js +1 -0
  125. package/dist/types/CallingClient/CallingClient.d.ts +7 -0
  126. package/dist/types/CallingClient/CallingClient.d.ts.map +1 -1
  127. package/dist/types/CallingClient/calling/call.d.ts +1 -0
  128. package/dist/types/CallingClient/calling/call.d.ts.map +1 -1
  129. package/dist/types/CallingClient/calling/callManager.d.ts +3 -2
  130. package/dist/types/CallingClient/calling/callManager.d.ts.map +1 -1
  131. package/dist/types/CallingClient/calling/types.d.ts +21 -9
  132. package/dist/types/CallingClient/calling/types.d.ts.map +1 -1
  133. package/dist/types/CallingClient/constants.d.ts +20 -0
  134. package/dist/types/CallingClient/constants.d.ts.map +1 -1
  135. package/dist/types/CallingClient/registration/register.d.ts +6 -0
  136. package/dist/types/CallingClient/registration/register.d.ts.map +1 -1
  137. package/dist/types/CallingClient/registration/types.d.ts +3 -1
  138. package/dist/types/CallingClient/registration/types.d.ts.map +1 -1
  139. package/dist/types/CallingClient/registration/webWorker.d.ts.map +1 -1
  140. package/dist/types/CallingClient/registration/webWorkerStr.d.ts +1 -1
  141. package/dist/types/CallingClient/registration/webWorkerStr.d.ts.map +1 -1
  142. package/dist/types/CallingClient/utils/constants.d.ts +30 -0
  143. package/dist/types/CallingClient/utils/constants.d.ts.map +1 -0
  144. package/dist/types/CallingClient/utils/index.d.ts +6 -0
  145. package/dist/types/CallingClient/utils/index.d.ts.map +1 -0
  146. package/dist/types/CallingClient/utils/mobiusSocketMapper.d.ts +5 -0
  147. package/dist/types/CallingClient/utils/mobiusSocketMapper.d.ts.map +1 -0
  148. package/dist/types/CallingClient/utils/request.d.ts +23 -0
  149. package/dist/types/CallingClient/utils/request.d.ts.map +1 -0
  150. package/dist/types/CallingClient/utils/types.d.ts +29 -0
  151. package/dist/types/CallingClient/utils/types.d.ts.map +1 -0
  152. package/dist/types/CallingClient/utils/wsFeatureFlag.d.ts +4 -0
  153. package/dist/types/CallingClient/utils/wsFeatureFlag.d.ts.map +1 -0
  154. package/dist/types/Metrics/index.d.ts.map +1 -1
  155. package/dist/types/Metrics/types.d.ts +11 -1
  156. package/dist/types/Metrics/types.d.ts.map +1 -1
  157. package/dist/types/SDKConnector/types.d.ts +24 -0
  158. package/dist/types/SDKConnector/types.d.ts.map +1 -1
  159. package/dist/types/common/Utils.d.ts +9 -2
  160. package/dist/types/common/Utils.d.ts.map +1 -1
  161. package/dist/types/common/testUtil.d.ts +4 -1
  162. package/dist/types/common/testUtil.d.ts.map +1 -1
  163. package/dist/types/common/types.d.ts +3 -0
  164. package/dist/types/common/types.d.ts.map +1 -1
  165. package/dist/types/mobius-socket/config.d.ts +17 -0
  166. package/dist/types/mobius-socket/config.d.ts.map +1 -0
  167. package/dist/types/mobius-socket/errors.d.ts +32 -0
  168. package/dist/types/mobius-socket/errors.d.ts.map +1 -0
  169. package/dist/types/mobius-socket/index.d.ts +14 -0
  170. package/dist/types/mobius-socket/index.d.ts.map +1 -0
  171. package/dist/types/mobius-socket/mobius-socket.d.ts +48 -0
  172. package/dist/types/mobius-socket/mobius-socket.d.ts.map +1 -0
  173. package/dist/types/mobius-socket/socket/constants.d.ts +11 -0
  174. package/dist/types/mobius-socket/socket/constants.d.ts.map +1 -0
  175. package/dist/types/mobius-socket/socket/index.d.ts +5 -0
  176. package/dist/types/mobius-socket/socket/index.d.ts.map +1 -0
  177. package/dist/types/mobius-socket/socket/socket-base.d.ts +43 -0
  178. package/dist/types/mobius-socket/socket/socket-base.d.ts.map +1 -0
  179. package/dist/types/mobius-socket/socket/socket.d.ts +6 -0
  180. package/dist/types/mobius-socket/socket/socket.d.ts.map +1 -0
  181. package/dist/types/mobius-socket/socket/socket.shim.d.ts +6 -0
  182. package/dist/types/mobius-socket/socket/socket.shim.d.ts.map +1 -0
  183. package/dist/types/mobius-socket/socket/types.d.ts +61 -0
  184. package/dist/types/mobius-socket/socket/types.d.ts.map +1 -0
  185. package/dist/types/mobius-socket/types.d.ts +21 -0
  186. package/dist/types/mobius-socket/types.d.ts.map +1 -0
  187. package/package.json +16 -2
  188. package/src/mobius-socket/socket/socket.shim.ts +22 -0
  189. package/src/mobius-socket/socket/socket.ts +14 -0
@@ -0,0 +1,804 @@
1
+ "use strict";
2
+
3
+ var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
4
+ var _Object$keys = require("@babel/runtime-corejs2/core-js/object/keys");
5
+ var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
6
+ var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
7
+ var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
8
+ var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");
9
+ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
10
+ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
11
+ _Object$defineProperty(exports, "__esModule", {
12
+ value: true
13
+ });
14
+ exports.default = void 0;
15
+ var _map = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/map"));
16
+ var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
17
+ var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
18
+ var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
19
+ var _now = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/date/now"));
20
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
21
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/typeof"));
22
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
23
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
24
+ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
25
+ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
26
+ var _get2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/get"));
27
+ var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
28
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
29
+ var _events = require("events");
30
+ var _backoff = _interopRequireDefault(require("backoff"));
31
+ var _socket = _interopRequireDefault(require("./socket"));
32
+ var _errors = require("./errors");
33
+ function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
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
+ 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
+ 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; } /*!
38
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file
39
+ */ // @ts-ignore - backoff library does not have type definitions
40
+ var normalReconnectReasons = ['idle', 'done (forced)'];
41
+ var MOBIUS_SOCKET_NAMESPACE = 'MobiusSocket';
42
+ var TOKEN_REFRESH_INTERVAL_MS = 1 * 60 * 60 * 1000; // 1 hour
43
+
44
+ // Extended Socket type with dynamic properties
45
+
46
+ function normalizeMobiusAuthToken(token) {
47
+ return token.replace(/^Bearer\s+/i, '');
48
+ }
49
+ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
50
+ function MobiusSocket(webex) {
51
+ var _this;
52
+ var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
53
+ (0, _classCallCheck2.default)(this, MobiusSocket);
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);
71
+ if (!webex) {
72
+ throw new Error('A Webex instance is required when initializing MobiusSocket');
73
+ }
74
+ _this.webex = webex;
75
+ _this.config = config;
76
+ _this.logger = webex.logger || console;
77
+ _this.connected = false;
78
+ _this.connecting = false;
79
+ _this.hasEverConnected = false;
80
+ _this.socket = undefined;
81
+ _this.backoffCall = undefined;
82
+ _this.shutdownSwitchoverBackoffCall = undefined;
83
+ _this.seenAsyncEventIds = new _map.default();
84
+ _this.connectPromise = undefined;
85
+ _this.tokenRefreshTimer = undefined;
86
+ _this.tokenRefreshInFlight = undefined;
87
+ return _this;
88
+ }
89
+ (0, _inherits2.default)(MobiusSocket, _EventEmitter);
90
+ return (0, _createClass2.default)(MobiusSocket, [{
91
+ key: "off",
92
+ value: function off(eventName, listener) {
93
+ if (listener) {
94
+ return _superPropGet(MobiusSocket, "off", this, 3)([eventName, listener]);
95
+ }
96
+ this.removeAllListeners(eventName);
97
+ return this;
98
+ }
99
+
100
+ /**
101
+ * Attach event listeners to a socket.
102
+ * @param socket - The socket to attach listeners to
103
+ */
104
+ }, {
105
+ key: "attachSocketEventListeners",
106
+ value: function attachSocketEventListeners(socket) {
107
+ var _this2 = this;
108
+ socket.on('close', function (event) {
109
+ return _this2.onclose(event, socket);
110
+ });
111
+ socket.on('message', function (event) {
112
+ return _this2.onmessage(event);
113
+ });
114
+ }
115
+
116
+ /**
117
+ * Tracks a newly seen async_event ID and reports whether a duplicate should be suppressed.
118
+ * @param envelope - Parsed websocket message envelope
119
+ * @returns True when the event has already been seen
120
+ */
121
+ }, {
122
+ key: "trackAsyncEventAndShouldSuppressDuplicate",
123
+ value: function trackAsyncEventAndShouldSuppressDuplicate(envelope) {
124
+ if ((envelope === null || envelope === void 0 ? void 0 : envelope.type) !== 'async_event' || !envelope.eventId) {
125
+ return false;
126
+ }
127
+ if (this.seenAsyncEventIds.has(envelope.eventId)) {
128
+ // Refresh recency so frequently retransmitted eventIds stay protected longer.
129
+ // This deletion and setting again makes the data recent since javascript map maintains order as well
130
+ var previousValue = this.seenAsyncEventIds.get(envelope.eventId) || true;
131
+ this.seenAsyncEventIds.delete(envelope.eventId);
132
+ this.seenAsyncEventIds.set(envelope.eventId, previousValue);
133
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": duplicate async_event suppressed, eventId=").concat(envelope.eventId));
134
+ return true;
135
+ }
136
+ this.logger.log("".concat(MOBIUS_SOCKET_NAMESPACE, ": tracking async_event, eventId=").concat(envelope.eventId));
137
+ this.seenAsyncEventIds.set(envelope.eventId, true);
138
+ if (this.config.dedupCacheMaxSize && this.seenAsyncEventIds.size > this.config.dedupCacheMaxSize) {
139
+ var oldestEventId = this.seenAsyncEventIds.keys().next().value || '';
140
+ this.seenAsyncEventIds.delete(oldestEventId);
141
+ this.logger.log("".concat(MOBIUS_SOCKET_NAMESPACE, ": evicted oldest async_event from dedup cache, eventId=").concat(oldestEventId));
142
+ }
143
+ return false;
144
+ }
145
+
146
+ /**
147
+ * Handle imminent shutdown by establishing a new connection while keeping
148
+ * the current one alive (make-before-break).
149
+ * Idempotent: will no-op if already in progress.
150
+ */
151
+ }, {
152
+ key: "handleImminentShutdown",
153
+ value: function handleImminentShutdown() {
154
+ var _this3 = this;
155
+ var oldSocket = this.socket;
156
+ try {
157
+ if (this.shutdownSwitchoverBackoffCall) {
158
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover already in progress"));
159
+ return;
160
+ }
161
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover start"));
162
+ this.connectWithBackoff(undefined, {
163
+ isShutdownSwitchover: true,
164
+ attemptOptions: {
165
+ isShutdownSwitchover: true,
166
+ onSuccess: function onSuccess(newSocket, webSocketUrl) {
167
+ _this3.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover connected, url: ").concat(webSocketUrl));
168
+
169
+ // Promote the new socket now that the switchover succeeded
170
+ newSocket.connecting = false;
171
+ newSocket.connected = true;
172
+ _this3.socket = newSocket;
173
+ _this3.connected = true;
174
+ _this3.emitEvent('event:mobius_shutdown_switchover_complete', {
175
+ url: webSocketUrl
176
+ });
177
+ if (oldSocket) {
178
+ _this3.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] old socket retained; server will close with 4001"));
179
+ }
180
+ }
181
+ }
182
+ }).then(function () {
183
+ _this3.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover completed successfully"));
184
+ }).catch(function (err) {
185
+ _this3.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover exhausted retries; will fall back to normal reconnection: "), err);
186
+ _this3.emitEvent('event:mobius_shutdown_switchover_failed', {
187
+ reason: err
188
+ });
189
+ });
190
+ } catch (e) {
191
+ this.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] error during switchover"), e);
192
+ this.shutdownSwitchoverBackoffCall = undefined;
193
+ this.emitEvent('event:mobius_shutdown_switchover_failed', {
194
+ reason: e
195
+ });
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Get the websocket URL for the currently connected socket.
201
+ * @returns The connected websocket URL, or undefined when not connected
202
+ */
203
+ }, {
204
+ key: "getConnectedWebSocketUrl",
205
+ value: function getConnectedWebSocketUrl() {
206
+ var _this$socket;
207
+ if (!((_this$socket = this.socket) !== null && _this$socket !== void 0 && _this$socket.connected)) {
208
+ return undefined;
209
+ }
210
+ return this.socket.url;
211
+ }
212
+
213
+ /**
214
+ * Sends a websocket request and resolves when the matching response arrives.
215
+ * @param payload - The websocket request payload
216
+ * @param options - Additional request options
217
+ * @returns Promise that resolves with the socket response
218
+ */
219
+ }, {
220
+ key: "sendWssRequest",
221
+ value: function sendWssRequest(payload) {
222
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
223
+ if (!payload || (0, _typeof2.default)(payload) !== 'object' || (0, _isArray.default)(payload)) {
224
+ return _promise.default.reject(new Error('`payload` is required'));
225
+ }
226
+ if (!this.socket || !this.socket.connected) {
227
+ return _promise.default.reject(new Error('Mobius socket is not connected'));
228
+ }
229
+ return this.socket.sendRequest(payload, {
230
+ timeout: options.timeout
231
+ });
232
+ }
233
+
234
+ /**
235
+ * Check if the socket is connected.
236
+ * @returns True if connected
237
+ */
238
+ }, {
239
+ key: "isConnected",
240
+ value: function isConnected() {
241
+ return this.connected;
242
+ }
243
+
244
+ /**
245
+ * Connect to Mobius.
246
+ * @param webSocketUrl - Optional websocket URL override. Falls back to the device websocket URL
247
+ * @returns Promise that resolves when connection flow completes
248
+ */
249
+ }, {
250
+ key: "connect",
251
+ value: function connect(webSocketUrl) {
252
+ var _this$socket2,
253
+ _this$socket3,
254
+ _this$webex$internal$,
255
+ _this$webex$internal$2,
256
+ _this4 = this;
257
+ if (this.connectPromise) {
258
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connection already in progress, returning existing promise"));
259
+ return this.connectPromise;
260
+ }
261
+ if ((_this$socket2 = this.socket) !== null && _this$socket2 !== void 0 && _this$socket2.connected || (_this$socket3 = this.socket) !== null && _this$socket3 !== void 0 && _this$socket3.connecting) {
262
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": already connected, will not connect again"));
263
+ return _promise.default.resolve();
264
+ }
265
+
266
+ // Treat a connect() call that targets a different Mobius websocket URL
267
+ // as a fresh initial connection for retry purposes.
268
+ if (webSocketUrl && this.socketUrl && webSocketUrl !== this.socketUrl) {
269
+ this.hasEverConnected = false;
270
+ }
271
+
272
+ // Cache the caller-provided URL for reconnect
273
+ if (webSocketUrl) {
274
+ this.socketUrl = webSocketUrl;
275
+ }
276
+ this.connecting = true;
277
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": starting connection attempt").concat(Number(this.config.initialConnectionMaxRetries) === 0 && !this.hasEverConnected ? ' (initial retries disabled)' : ''));
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);
281
+ }).finally(function () {
282
+ _this4.connectPromise = undefined;
283
+ });
284
+ this.connectPromise = connectPromise;
285
+ return connectPromise;
286
+ }
287
+
288
+ /**
289
+ * Disconnect the Mobius socket.
290
+ * @param options - Optional websocket close options (code, reason)
291
+ * @returns Promise that resolves after disconnect cleanup and close handling complete
292
+ */
293
+ }, {
294
+ key: "disconnect",
295
+ value: function disconnect(options) {
296
+ var _this5 = this;
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)));
298
+ if (this.backoffCall) {
299
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": aborting connection"));
300
+ this.backoffCall.abort();
301
+ this.backoffCall = undefined;
302
+ }
303
+ if (this.shutdownSwitchoverBackoffCall) {
304
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": aborting shutdown switchover connection"));
305
+ this.shutdownSwitchoverBackoffCall.abort();
306
+ this.shutdownSwitchoverBackoffCall = undefined;
307
+ }
308
+ this.connectPromise = undefined;
309
+ this.seenAsyncEventIds.clear();
310
+ if (!this.socket) {
311
+ this.connected = false;
312
+ this.stopTokenRefreshTimer();
313
+ return _promise.default.resolve();
314
+ }
315
+ this.socket.removeAllListeners('message');
316
+ this.socket.connecting = false;
317
+ this.socket.connected = false;
318
+ return _promise.default.resolve(this.socket.close(options || undefined)).finally(function () {
319
+ _this5.connected = false;
320
+ _this5.stopTokenRefreshTimer();
321
+ });
322
+ }
323
+ }, {
324
+ key: "prepareUrl",
325
+ value: function prepareUrl(webSocketUrl) {
326
+ if (!webSocketUrl) {
327
+ // TODO: Circle back to this logic when mobius implements the shutdown switchover
328
+ webSocketUrl = this.webex.internal.device.webSocketUrl || '';
329
+ }
330
+ return _promise.default.resolve(webSocketUrl);
331
+ }
332
+ }, {
333
+ key: "attemptConnection",
334
+ value: function attemptConnection(socketUrl, callback) {
335
+ var _this6 = this;
336
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
337
+ var _options$isShutdownSw = options.isShutdownSwitchover,
338
+ isShutdownSwitchover = _options$isShutdownSw === void 0 ? false : _options$isShutdownSw,
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;
343
+ var socket = new _socket.default();
344
+ socket.connecting = true;
345
+ var newWSUrl;
346
+ this.attachSocketEventListeners(socket);
347
+ var backoffCall = isShutdownSwitchover ? this.shutdownSwitchoverBackoffCall : this.backoffCall;
348
+
349
+ // Check appropriate backoff call based on connection type
350
+ if (!backoffCall) {
351
+ var mode = isShutdownSwitchover ? 'switchover backoff call' : 'backoffCall';
352
+ var msg = "".concat(MOBIUS_SOCKET_NAMESPACE, ": prevent socket open when ").concat(mode, " no longer defined");
353
+ var err = new Error(msg);
354
+ this.logger.info(msg);
355
+ // Call the callback with the error before rejecting
356
+ callback(err);
357
+ return _promise.default.reject(err);
358
+ }
359
+
360
+ // For shutdown switchover, don't set socket yet (make-before-break)
361
+ // For normal connection, set socket before opening to allow disconnect() to close it
362
+ if (!isShutdownSwitchover) {
363
+ this.socket = socket;
364
+ }
365
+ return this.prepareAndOpenSocket(socket, socketUrl, isShutdownSwitchover).then(function (webSocketUrl) {
366
+ newWSUrl = webSocketUrl;
367
+ _this6.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(isShutdownSwitchover ? '[shutdown] switchover' : '', " connected to mobius socket, success, url: ").concat(newWSUrl));
368
+
369
+ // Custom success handler for shutdown switchover
370
+ if (onSuccess) {
371
+ onSuccess(socket, webSocketUrl);
372
+ callback();
373
+ return _promise.default.resolve();
374
+ }
375
+
376
+ // Default behavior for normal connection
377
+ callback();
378
+ return _promise.default.resolve();
379
+ }).catch(function (reason) {
380
+ // For shutdown, simpler error handling - just callback for retry
381
+ if (isShutdownSwitchover) {
382
+ _this6.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover attempt failed"), reason);
383
+ return callback(reason);
384
+ }
385
+
386
+ // Normal connection error handling
387
+ var backoffCallNormal = _this6.backoffCall;
388
+ // Suppress connection errors that appear to be network related (code 1006).
389
+ if (reason.code !== 1006 && backoffCallNormal && (backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.getNumRetries()) > 0) {
390
+ _this6.emitEvent('connection_failed', reason, {
391
+ retries: backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.getNumRetries()
392
+ });
393
+ }
394
+ _this6.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connection attempt failed"), reason, (backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.getNumRetries()) === 0 ? reason.stack : '');
395
+
396
+ // UnknownResponse is produced by IE for any 4XXX; treat it like a bad
397
+ // web socket url and let WDM handle the token checking
398
+ if (reason instanceof _errors.UnknownResponse) {
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 () {
402
+ return callback(reason);
403
+ });
404
+ }
405
+ // NotAuthorized implies expired token
406
+ if (reason instanceof _errors.NotAuthorized) {
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, {
410
+ force: true
411
+ }).then(function () {
412
+ return callback(reason);
413
+ });
414
+ }
415
+ if (reason instanceof _errors.BadRequest || reason instanceof _errors.Forbidden) {
416
+ _this6.logger.warn("".concat(MOBIUS_SOCKET_NAMESPACE, ": received unrecoverable response from ").concat(MOBIUS_SOCKET_NAMESPACE));
417
+ backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.abort();
418
+ return callback(reason);
419
+ }
420
+ return callback(reason);
421
+ }).catch(function (reason) {
422
+ _this6.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": failed to handle connection failure"), reason);
423
+ callback(reason);
424
+ });
425
+ }
426
+ }, {
427
+ key: "prepareAndOpenSocket",
428
+ value: function prepareAndOpenSocket(socket, socketUrl) {
429
+ var _this7 = this;
430
+ var isShutdownSwitchover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
431
+ var logPrefix = isShutdownSwitchover ? '[shutdown] switchover' : 'connection';
432
+ return _promise.default.all([this.prepareUrl(socketUrl), this.webex.credentials.getUserToken()]).then(function (_ref) {
433
+ var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
434
+ webSocketUrl = _ref2[0],
435
+ token = _ref2[1];
436
+ var options = {
437
+ forceCloseDelay: _this7.config.forceCloseDelay,
438
+ wssResponseTimeout: _this7.config.wssResponseTimeout,
439
+ token: normalizeMobiusAuthToken(token.toString()),
440
+ refreshToken: function refreshToken() {
441
+ return _this7.refreshToken();
442
+ },
443
+ trackingId: "".concat(_this7.webex.sessionId, "_").concat((0, _now.default)()),
444
+ logger: _this7.logger
445
+ };
446
+ if (_this7.webex.config.defaultMobiusSocketOptions) {
447
+ var customOptionsMsg = isShutdownSwitchover ? 'setting custom options for switchover' : 'setting custom options';
448
+ _this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(customOptionsMsg));
449
+ options = _objectSpread(_objectSpread({}, options), _this7.webex.config.defaultMobiusSocketOptions);
450
+ }
451
+
452
+ // Only promote the socket reference for normal connections.
453
+ // Shutdown switchover keeps the old socket active until the new one succeeds.
454
+ if (!isShutdownSwitchover) {
455
+ _this7.socket = socket;
456
+ }
457
+ _this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, " ").concat(logPrefix, " url: ").concat(webSocketUrl));
458
+ return socket.open(webSocketUrl, options).then(function () {
459
+ return webSocketUrl;
460
+ });
461
+ });
462
+ }
463
+ }, {
464
+ key: "connectWithBackoff",
465
+ value: function connectWithBackoff(webSocketUrl) {
466
+ var _this8 = this;
467
+ var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
468
+ var _context$isShutdownSw = context.isShutdownSwitchover,
469
+ isShutdownSwitchover = _context$isShutdownSw === void 0 ? false : _context$isShutdownSw,
470
+ _context$attemptOptio = context.attemptOptions,
471
+ attemptOptions = _context$attemptOptio === void 0 ? {} : _context$attemptOptio;
472
+ return new _promise.default(function (resolve, reject) {
473
+ var call;
474
+ var isInitialConnect = !isShutdownSwitchover && !_this8.hasEverConnected;
475
+ var initialRetryLimit = _this8.config.initialConnectionMaxRetries == null ? null : Number(_this8.config.initialConnectionMaxRetries);
476
+ var isInitialConnectWithoutRetries = isInitialConnect && initialRetryLimit === 0;
477
+ var onComplete = function onComplete(err) {
478
+ if (isShutdownSwitchover) {
479
+ _this8.shutdownSwitchoverBackoffCall = undefined;
480
+ } else {
481
+ _this8.backoffCall = undefined;
482
+ }
483
+ if (err) {
484
+ var msg = isShutdownSwitchover ? "[shutdown] switchover failed after ".concat(call.getNumRetries(), " retries") : "failed to connect after ".concat(call.getNumRetries(), " retries");
485
+ _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(msg, "; ").concat(err));
486
+ // Only mutate socket flags for normal connections.
487
+ // During shutdown switchover, this.socket is the old live socket — don't touch it.
488
+ if (!isShutdownSwitchover && _this8.socket) {
489
+ _this8.socket.connecting = false;
490
+ _this8.socket.connected = false;
491
+ }
492
+ return reject(err);
493
+ }
494
+
495
+ // For normal connections, mark the socket as connected.
496
+ // Shutdown switchover promotion is handled by the onSuccess callback.
497
+ if (!isShutdownSwitchover && _this8.socket) {
498
+ _this8.socket.connecting = false;
499
+ _this8.socket.connected = true;
500
+ }
501
+ if (!isShutdownSwitchover) {
502
+ _this8.connecting = false;
503
+ _this8.connected = true;
504
+ _this8.hasEverConnected = true;
505
+ _this8.startTokenRefreshTimer();
506
+ _this8.emitEvent('online');
507
+ }
508
+ return resolve();
509
+ };
510
+ // eslint-disable-next-line prefer-reflect
511
+ call = _backoff.default.call(function (callback) {
512
+ var attemptNum = call.getNumRetries();
513
+ var attemptLogPrefix = isShutdownSwitchover ? '[shutdown] switchover' : 'connection';
514
+ _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": executing ").concat(attemptLogPrefix, " attempt ").concat(attemptNum));
515
+ _this8.attemptConnection(webSocketUrl, callback, attemptOptions);
516
+ }, function (err) {
517
+ return onComplete(err);
518
+ });
519
+ call.setStrategy(new _backoff.default.ExponentialStrategy({
520
+ initialDelay: _this8.config.backoffTimeReset,
521
+ maxDelay: _this8.config.backoffTimeMax
522
+ }));
523
+ if (isInitialConnectWithoutRetries) {
524
+ call.retryIf(function () {
525
+ return false;
526
+ });
527
+ } else if (isInitialConnect && initialRetryLimit !== null && initialRetryLimit > 0) {
528
+ call.failAfter(initialRetryLimit);
529
+ } else if (_this8.config.maxRetries) {
530
+ call.failAfter(_this8.config.maxRetries);
531
+ }
532
+
533
+ // Store backoff call reference BEFORE starting (so it's available in attemptConnection)
534
+ if (isShutdownSwitchover) {
535
+ _this8.shutdownSwitchoverBackoffCall = call;
536
+ } else {
537
+ _this8.backoffCall = call;
538
+ }
539
+ call.on('abort', function () {
540
+ var msg = isShutdownSwitchover ? 'Shutdown Switchover' : 'Connection';
541
+ _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(msg, " aborted"));
542
+ reject(new Error("MobiusSocket ".concat(msg, " Aborted")));
543
+ });
544
+ call.on('callback', function (err) {
545
+ if (err) {
546
+ if (isInitialConnectWithoutRetries) {
547
+ _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": initial connect failed; retries already disabled"));
548
+ return;
549
+ }
550
+ var number = call.getNumRetries();
551
+ var delay = Math.min(call.strategy_.nextBackoffDelay_, _this8.config.backoffTimeMax || Infinity);
552
+ var callbackLogPrefix = isShutdownSwitchover ? '[shutdown] switchover' : '';
553
+ _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(callbackLogPrefix, " failed to connect; attempting retry ").concat(number + 1, " in ").concat(delay, " ms"));
554
+ /* istanbul ignore if */
555
+ if (process.env.NODE_ENV === 'development') {
556
+ _this8.logger.debug("".concat(MOBIUS_SOCKET_NAMESPACE, ": "), err, err.stack);
557
+ }
558
+ return;
559
+ }
560
+ _this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connected"));
561
+ });
562
+ call.start();
563
+ });
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
+ */
571
+ }, {
572
+ key: "emitEvent",
573
+ value: function emitEvent(eventName) {
574
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
575
+ args[_key - 1] = arguments[_key];
576
+ }
577
+ try {
578
+ if (!eventName) {
579
+ return;
580
+ }
581
+ this.emit.apply(this, [eventName].concat(args));
582
+ } catch (error) {
583
+ // Safely handle errors without causing additional issues during cleanup
584
+ this.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": error occurred in event handler:"), error, ' with args: ', [eventName].concat(args));
585
+ }
586
+ }
587
+
588
+ /**
589
+ * Starts a periodic timer to refresh the authentication token.
590
+ * Token refresh occurs every hour while connected.
591
+ */
592
+ }, {
593
+ key: "startTokenRefreshTimer",
594
+ value: function startTokenRefreshTimer() {
595
+ var _this9 = this;
596
+ if (this.tokenRefreshTimer || !this.connected) {
597
+ return;
598
+ }
599
+ this.tokenRefreshTimer = setInterval(function () {
600
+ _this9.refreshToken().catch(function (error) {
601
+ _this9.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": periodic token refresh failed"), error);
602
+ });
603
+ }, TOKEN_REFRESH_INTERVAL_MS);
604
+ }
605
+
606
+ /**
607
+ * Stops the periodic token refresh timer.
608
+ */
609
+ }, {
610
+ key: "stopTokenRefreshTimer",
611
+ value: function stopTokenRefreshTimer() {
612
+ if (!this.tokenRefreshTimer) {
613
+ return;
614
+ }
615
+ clearInterval(this.tokenRefreshTimer);
616
+ this.tokenRefreshTimer = undefined;
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
+ */
623
+ }, {
624
+ key: "refreshToken",
625
+ value: function refreshToken() {
626
+ var _this$webex$credentia,
627
+ _this$webex$credentia2,
628
+ _this$webex$credentia3,
629
+ _this0 = this;
630
+ if (this.tokenRefreshInFlight) {
631
+ return this.tokenRefreshInFlight;
632
+ }
633
+ if (!this.connected) {
634
+ this.stopTokenRefreshTimer();
635
+ return _promise.default.resolve();
636
+ }
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, {
638
+ force: true
639
+ })) === null || _this$webex$credentia3 === void 0 ? void 0 : _this$webex$credentia3.then(function () {
640
+ return _this0.webex.credentials.getUserToken();
641
+ }) : this.webex.credentials.getUserToken();
642
+ this.tokenRefreshInFlight = tokenPromise.then(function (token) {
643
+ var _this0$socket;
644
+ if (!token) {
645
+ throw new Error('Mobius token refresh did not return a token');
646
+ }
647
+ var refreshedToken = normalizeMobiusAuthToken(token.toString());
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;
651
+ }
652
+ return _this0.socket.refresh(refreshedToken);
653
+ }).catch(function (error) {
654
+ _this0.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": failed to refresh/re-auth Mobius socket"), error);
655
+ throw error;
656
+ }).finally(function () {
657
+ _this0.tokenRefreshInFlight = undefined;
658
+ });
659
+ return this.tokenRefreshInFlight;
660
+ }
661
+ }, {
662
+ key: "onclose",
663
+ value: function onclose(event, sourceSocket) {
664
+ // I don't see any way to avoid the complexity or statement count in here.
665
+ /* eslint complexity: [0] */
666
+
667
+ try {
668
+ var reason = event.reason && event.reason.toLowerCase();
669
+ var socketUrl;
670
+ var isActiveSocket = sourceSocket === this.socket;
671
+ if (sourceSocket) {
672
+ socketUrl = sourceSocket.url;
673
+ }
674
+
675
+ // Only tear down state if the currently active socket closed
676
+ if (isActiveSocket) {
677
+ if (this.socket) {
678
+ this.socket.removeAllListeners();
679
+ this.socket = undefined;
680
+ this.emitEvent('offline', event);
681
+ }
682
+ this.connecting = false;
683
+ this.connected = false;
684
+ this.stopTokenRefreshTimer();
685
+ } else {
686
+ // Old socket closed; do not flip connection state
687
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] non-active socket closed, code=").concat(event.code));
688
+ // Clean up listeners from old socket now that it's closed
689
+ if (sourceSocket) {
690
+ sourceSocket.removeAllListeners();
691
+ }
692
+ }
693
+ switch (event.code) {
694
+ case 1003:
695
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": service rejected last message; will not reconnect: ").concat(event.reason));
696
+ if (isActiveSocket) this.emitEvent('offline.permanent', event);
697
+ break;
698
+ case 4000:
699
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket replaced; will not reconnect"));
700
+ if (isActiveSocket) this.emitEvent('offline.replaced', event);
701
+ break;
702
+ case 4001:
703
+ // replaced during shutdown
704
+ if (isActiveSocket) {
705
+ // Server closed active socket with 4001, meaning it expected this connection
706
+ // to be replaced, but the switchover in handleImminentShutdown failed.
707
+ this.logger.warn("".concat(MOBIUS_SOCKET_NAMESPACE, ": active socket closed with 4001; shutdown switchover failed"));
708
+ this.emitEvent('offline.permanent', event);
709
+ } else {
710
+ // Expected: old socket closed after successful switchover
711
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": old socket closed with 4001 (replaced during shutdown); no reconnect needed"));
712
+ this.emitEvent('offline.replaced', event);
713
+ }
714
+ break;
715
+ case 1001:
716
+ case 1005:
717
+ case 1006:
718
+ case 1011:
719
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket disconnected; reconnecting"));
720
+ if (isActiveSocket) {
721
+ this.emitEvent('offline.transient', event);
722
+ this.reconnect(socketUrl);
723
+ }
724
+ break;
725
+ case 1000:
726
+ case 3050:
727
+ if (reason && normalReconnectReasons.includes(reason)) {
728
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket disconnected; reconnecting"));
729
+ if (isActiveSocket) {
730
+ this.emitEvent('offline.transient', event);
731
+ this.reconnect(socketUrl);
732
+ }
733
+ } else {
734
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket disconnected; will not reconnect: ").concat(event.reason));
735
+ if (isActiveSocket) this.emitEvent('offline.permanent', event);
736
+ }
737
+ break;
738
+ default:
739
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket disconnected unexpectedly; will not reconnect"));
740
+ if (isActiveSocket) this.emitEvent('offline.permanent', event);
741
+ }
742
+ } catch (error) {
743
+ this.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": error occurred in close handler"), error);
744
+ }
745
+ }
746
+ }, {
747
+ key: "onmessage",
748
+ value: function onmessage(event) {
749
+ var envelope = event.data;
750
+ if (process.env.ENABLE_MOBIUS_LOGGING) {
751
+ this.logger.debug("".concat(MOBIUS_SOCKET_NAMESPACE, ": message envelope: "), envelope);
752
+ }
753
+
754
+ // Handle shutdown message shape: { type: 'shutdown' }
755
+ if (envelope && envelope.type === 'shutdown') {
756
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] imminent shutdown message received"));
757
+ this.emitEvent('event:mobius_shutdown_imminent', envelope); // This is not yet not implemented, keeping for future support
758
+
759
+ this.handleImminentShutdown();
760
+ return _promise.default.resolve();
761
+ }
762
+ if (this.trackAsyncEventAndShouldSuppressDuplicate(envelope)) {
763
+ return _promise.default.resolve();
764
+ }
765
+
766
+ // Emit event:<type> for typed messages (e.g., register.response)
767
+ if (envelope.type) {
768
+ this.emitEvent("event:".concat(envelope.type), envelope);
769
+ }
770
+
771
+ // Use data/payload if present, otherwise treat the envelope itself as the data (flat format)
772
+ var data = envelope.data || envelope;
773
+
774
+ // Support both Mobius-enveloped (data.eventType) and flat (eventType) formats
775
+ var eventType = (data === null || data === void 0 ? void 0 : data.eventType) || envelope.eventType;
776
+ if (!eventType) {
777
+ this.emitEvent('event', envelope);
778
+ return _promise.default.resolve();
779
+ }
780
+ try {
781
+ // TODO: Remove if event:namespace is not required
782
+ this.emitEvent('event', envelope);
783
+ var _eventType$split = eventType.split('.'),
784
+ _eventType$split2 = (0, _slicedToArray2.default)(_eventType$split, 1),
785
+ namespace = _eventType$split2[0];
786
+ this.emitEvent("event:".concat(namespace), envelope);
787
+ if (namespace !== eventType) {
788
+ this.emitEvent("event:".concat(eventType), envelope);
789
+ }
790
+ } catch (reason) {
791
+ this.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": error occurred processing socket message"), reason);
792
+ }
793
+ return _promise.default.resolve();
794
+ }
795
+ }, {
796
+ key: "reconnect",
797
+ value: function reconnect(webSocketUrl) {
798
+ this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": reconnecting"));
799
+ return this.connect(webSocketUrl || this.socketUrl);
800
+ }
801
+ }]);
802
+ }(_events.EventEmitter);
803
+ var _default = exports.default = MobiusSocket;
804
+ //# sourceMappingURL=mobius-socket.js.map