@webex/internal-plugin-mercury 3.8.1 → 3.9.0-multiple-llm.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.
- package/dist/mercury.js +321 -130
- package/dist/mercury.js.map +1 -1
- package/dist/socket/socket-base.js +15 -0
- package/dist/socket/socket-base.js.map +1 -1
- package/package.json +18 -18
- package/src/mercury.js +281 -105
- package/src/socket/socket-base.js +13 -0
- package/test/unit/spec/mercury-events.js +21 -2
- package/test/unit/spec/mercury.js +74 -28
package/dist/mercury.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _Array$from = require("@babel/runtime-corejs2/core-js/array/from");
|
|
4
|
+
var _Symbol = require("@babel/runtime-corejs2/core-js/symbol");
|
|
5
|
+
var _Symbol$iterator = require("@babel/runtime-corejs2/core-js/symbol/iterator");
|
|
6
|
+
var _Array$isArray = require("@babel/runtime-corejs2/core-js/array/is-array");
|
|
3
7
|
var _Object$keys2 = require("@babel/runtime-corejs2/core-js/object/keys");
|
|
4
8
|
var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
|
|
5
9
|
var _Object$getOwnPropertyDescriptor2 = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
|
|
@@ -11,6 +15,7 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
11
15
|
value: true
|
|
12
16
|
});
|
|
13
17
|
exports.default = void 0;
|
|
18
|
+
var _map = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/map"));
|
|
14
19
|
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
|
|
15
20
|
var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
|
|
16
21
|
var _assign = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/assign"));
|
|
@@ -34,10 +39,14 @@ var _dec, _dec2, _obj;
|
|
|
34
39
|
*/
|
|
35
40
|
function ownKeys(e, r) { var t = _Object$keys2(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor2(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
36
41
|
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$getOwnPropertyDescriptor2(t, r)); }); } return e; }
|
|
42
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && o[_Symbol$iterator] || o["@@iterator"]; if (!it) { if (_Array$isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
43
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return _Array$from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
44
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
37
45
|
var normalReconnectReasons = ['idle', 'done (forced)', 'pong not received', 'pong mismatch'];
|
|
38
46
|
var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mercury#listen(): Use Mercury#connect() instead'), _dec2 = (0, _common.deprecated)('Mercury#stopListening(): Use Mercury#disconnect() instead'), (_obj = {
|
|
39
47
|
namespace: 'Mercury',
|
|
40
48
|
lastError: undefined,
|
|
49
|
+
defaultSessionId: 'mercury-default-session',
|
|
41
50
|
session: {
|
|
42
51
|
connected: {
|
|
43
52
|
default: false,
|
|
@@ -51,7 +60,18 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
51
60
|
default: false,
|
|
52
61
|
type: 'boolean'
|
|
53
62
|
},
|
|
54
|
-
|
|
63
|
+
sockets: {
|
|
64
|
+
default: function _default() {
|
|
65
|
+
return new _map.default();
|
|
66
|
+
},
|
|
67
|
+
type: 'object'
|
|
68
|
+
},
|
|
69
|
+
backoffCalls: {
|
|
70
|
+
default: function _default() {
|
|
71
|
+
return new _map.default();
|
|
72
|
+
},
|
|
73
|
+
type: 'object'
|
|
74
|
+
},
|
|
55
75
|
localClusterServiceUrls: 'object',
|
|
56
76
|
mercuryTimeOffset: {
|
|
57
77
|
default: undefined,
|
|
@@ -87,41 +107,159 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
87
107
|
getLastError: function getLastError() {
|
|
88
108
|
return this.lastError;
|
|
89
109
|
},
|
|
110
|
+
/**
|
|
111
|
+
* Get all active socket connections
|
|
112
|
+
* @returns {Map} Map of sessionId to socket instances
|
|
113
|
+
*/
|
|
114
|
+
getSockets: function getSockets() {
|
|
115
|
+
return this.sockets;
|
|
116
|
+
},
|
|
117
|
+
/**
|
|
118
|
+
* Get a specific socket by connection ID
|
|
119
|
+
* @param {string} sessionId - The connection identifier
|
|
120
|
+
* @returns {Socket|undefined} The socket instance or undefined if not found
|
|
121
|
+
*/
|
|
122
|
+
getSocket: function getSocket() {
|
|
123
|
+
var sessionId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.defaultSessionId;
|
|
124
|
+
return this.sockets.get(sessionId);
|
|
125
|
+
},
|
|
126
|
+
/**
|
|
127
|
+
* Check if any sockets are connected
|
|
128
|
+
* @returns {boolean} True if at least one socket is connected
|
|
129
|
+
*/
|
|
130
|
+
hasConnectedSockets: function hasConnectedSockets() {
|
|
131
|
+
var _iterator = _createForOfIteratorHelper(this.sockets.values()),
|
|
132
|
+
_step;
|
|
133
|
+
try {
|
|
134
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
135
|
+
var socket = _step.value;
|
|
136
|
+
if (socket && socket.connected) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
} catch (err) {
|
|
141
|
+
_iterator.e(err);
|
|
142
|
+
} finally {
|
|
143
|
+
_iterator.f();
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
},
|
|
147
|
+
/**
|
|
148
|
+
* Check if any sockets are connecting
|
|
149
|
+
* @returns {boolean} True if at least one socket is connected
|
|
150
|
+
*/
|
|
151
|
+
hasConnectingSockets: function hasConnectingSockets() {
|
|
152
|
+
var _iterator2 = _createForOfIteratorHelper(this.sockets.values()),
|
|
153
|
+
_step2;
|
|
154
|
+
try {
|
|
155
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
156
|
+
var socket = _step2.value;
|
|
157
|
+
if (socket && socket.connecting) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
} catch (err) {
|
|
162
|
+
_iterator2.e(err);
|
|
163
|
+
} finally {
|
|
164
|
+
_iterator2.f();
|
|
165
|
+
}
|
|
166
|
+
return false;
|
|
167
|
+
},
|
|
168
|
+
// @oneFlight
|
|
90
169
|
connect: function connect(webSocketUrl) {
|
|
91
170
|
var _this2 = this;
|
|
92
|
-
|
|
93
|
-
|
|
171
|
+
var sessionId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.defaultSessionId;
|
|
172
|
+
if (!this._connectPromises) this._connectPromises = new _map.default();
|
|
173
|
+
|
|
174
|
+
// First check if there's already a connection promise for this session
|
|
175
|
+
if (this._connectPromises.has(sessionId)) {
|
|
176
|
+
this.logger.info("".concat(this.namespace, ": connection ").concat(sessionId, " already in progress, returning existing promise"));
|
|
177
|
+
return this._connectPromises.get(sessionId);
|
|
178
|
+
}
|
|
179
|
+
var sessionSocket = this.sockets.get(sessionId);
|
|
180
|
+
if (sessionSocket !== null && sessionSocket !== void 0 && sessionSocket.connected || sessionSocket !== null && sessionSocket !== void 0 && sessionSocket.connecting) {
|
|
181
|
+
this.logger.info("".concat(this.namespace, ": connection ").concat(sessionId, " already connected, will not connect again"));
|
|
94
182
|
return _promise.default.resolve();
|
|
95
183
|
}
|
|
96
184
|
this.connecting = true;
|
|
97
|
-
this.logger.info("".concat(this.namespace, ": starting connection attempt"));
|
|
185
|
+
this.logger.info("".concat(this.namespace, ": starting connection attempt for ").concat(sessionId));
|
|
98
186
|
this.logger.info("".concat(this.namespace, ": debug_mercury_logging stack: "), new Error('debug_mercury_logging').stack);
|
|
99
|
-
|
|
100
|
-
_this2.logger.info("".concat(_this2.namespace, ": connecting"));
|
|
101
|
-
return _this2._connectWithBackoff(webSocketUrl);
|
|
187
|
+
var connectPromise = _promise.default.resolve(this.webex.internal.device.registered || this.webex.internal.device.register()).then(function () {
|
|
188
|
+
_this2.logger.info("".concat(_this2.namespace, ": connecting ").concat(sessionId));
|
|
189
|
+
return _this2._connectWithBackoff(webSocketUrl, sessionId);
|
|
190
|
+
}).finally(function () {
|
|
191
|
+
_this2._connectPromises.delete(sessionId);
|
|
102
192
|
});
|
|
193
|
+
this._connectPromises.set(sessionId, connectPromise);
|
|
194
|
+
return connectPromise;
|
|
103
195
|
},
|
|
104
196
|
logout: function logout() {
|
|
105
197
|
this.logger.info("".concat(this.namespace, ": logout() called"));
|
|
106
198
|
this.logger.info("".concat(this.namespace, ": debug_mercury_logging stack: "), new Error('debug_mercury_logging').stack);
|
|
107
|
-
return this.
|
|
199
|
+
return this.disconnectAll(this.config.beforeLogoutOptionsCloseReason && !normalReconnectReasons.includes(this.config.beforeLogoutOptionsCloseReason) ? {
|
|
108
200
|
code: 3050,
|
|
109
201
|
reason: this.config.beforeLogoutOptionsCloseReason
|
|
110
202
|
} : undefined);
|
|
111
203
|
},
|
|
204
|
+
// @oneFlight
|
|
112
205
|
disconnect: function disconnect(options) {
|
|
113
206
|
var _this3 = this;
|
|
207
|
+
var sessionId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.defaultSessionId;
|
|
114
208
|
return new _promise.default(function (resolve) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
_this3.
|
|
209
|
+
var backoffCall = _this3.backoffCalls.get(sessionId);
|
|
210
|
+
if (backoffCall) {
|
|
211
|
+
_this3.logger.info("".concat(_this3.namespace, ": aborting connection ").concat(sessionId));
|
|
212
|
+
backoffCall.abort();
|
|
213
|
+
_this3.backoffCalls.delete(sessionId);
|
|
118
214
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
215
|
+
|
|
216
|
+
// Clean up any pending connection promises
|
|
217
|
+
if (_this3._connectPromises) {
|
|
218
|
+
_this3._connectPromises.delete(sessionId);
|
|
219
|
+
}
|
|
220
|
+
var sessionSocket = _this3.sockets.get(sessionId);
|
|
221
|
+
var suffix = sessionId === _this3.defaultSessionId ? '' : ":".concat(sessionId);
|
|
222
|
+
if (sessionSocket) {
|
|
223
|
+
sessionSocket.removeAllListeners('message');
|
|
224
|
+
sessionSocket.connecting = false;
|
|
225
|
+
sessionSocket.connected = false;
|
|
226
|
+
_this3.once(sessionId === _this3.defaultSessionId ? 'offline' : "offline".concat(suffix), resolve);
|
|
227
|
+
resolve(sessionSocket.close(options || undefined));
|
|
123
228
|
}
|
|
124
229
|
resolve();
|
|
230
|
+
|
|
231
|
+
// Update overall connected status
|
|
232
|
+
_this3.connected = _this3.hasConnectedSockets();
|
|
233
|
+
});
|
|
234
|
+
},
|
|
235
|
+
/**
|
|
236
|
+
* Disconnect all socket connections
|
|
237
|
+
* @param {object} options - Close options
|
|
238
|
+
* @returns {Promise} Promise that resolves when all connections are closed
|
|
239
|
+
*/
|
|
240
|
+
disconnectAll: function disconnectAll(options) {
|
|
241
|
+
var _this4 = this;
|
|
242
|
+
var disconnectPromises = [];
|
|
243
|
+
var _iterator3 = _createForOfIteratorHelper(this.sockets.keys()),
|
|
244
|
+
_step3;
|
|
245
|
+
try {
|
|
246
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
247
|
+
var sessionId = _step3.value;
|
|
248
|
+
disconnectPromises.push(this.disconnect(options, sessionId));
|
|
249
|
+
}
|
|
250
|
+
} catch (err) {
|
|
251
|
+
_iterator3.e(err);
|
|
252
|
+
} finally {
|
|
253
|
+
_iterator3.f();
|
|
254
|
+
}
|
|
255
|
+
return _promise.default.all(disconnectPromises).then(function () {
|
|
256
|
+
_this4.connected = false;
|
|
257
|
+
_this4.sockets.clear();
|
|
258
|
+
_this4.backoffCalls.clear();
|
|
259
|
+
// Clear connection promises to prevent stale promises
|
|
260
|
+
if (_this4._connectPromises) {
|
|
261
|
+
_this4._connectPromises.clear();
|
|
262
|
+
}
|
|
125
263
|
});
|
|
126
264
|
},
|
|
127
265
|
listen: function listen() {
|
|
@@ -145,19 +283,19 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
145
283
|
});
|
|
146
284
|
},
|
|
147
285
|
_prepareUrl: function _prepareUrl(webSocketUrl) {
|
|
148
|
-
var
|
|
286
|
+
var _this5 = this;
|
|
149
287
|
if (!webSocketUrl) {
|
|
150
288
|
webSocketUrl = this.webex.internal.device.webSocketUrl;
|
|
151
289
|
}
|
|
152
290
|
return this.webex.internal.feature.getFeature('developer', 'web-high-availability').then(function (haMessagingEnabled) {
|
|
153
291
|
if (haMessagingEnabled) {
|
|
154
|
-
return
|
|
292
|
+
return _this5.webex.internal.services.convertUrlToPriorityHostUrl(webSocketUrl);
|
|
155
293
|
}
|
|
156
294
|
return webSocketUrl;
|
|
157
295
|
}).then(function (wsUrl) {
|
|
158
296
|
webSocketUrl = wsUrl;
|
|
159
297
|
}).then(function () {
|
|
160
|
-
return
|
|
298
|
+
return _this5.webex.internal.feature.getFeature('developer', 'web-shared-mercury');
|
|
161
299
|
}).then(function (webSharedMercury) {
|
|
162
300
|
webSocketUrl = _url.default.parse(webSocketUrl, true);
|
|
163
301
|
(0, _assign.default)(webSocketUrl.query, {
|
|
@@ -172,104 +310,117 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
172
310
|
});
|
|
173
311
|
(0, _deleteProperty.default)(webSocketUrl.query, 'bufferStates');
|
|
174
312
|
}
|
|
175
|
-
if ((0, _lodash.get)(
|
|
313
|
+
if ((0, _lodash.get)(_this5, 'webex.config.device.ephemeral', false)) {
|
|
176
314
|
webSocketUrl.query.multipleConnections = true;
|
|
177
315
|
}
|
|
178
316
|
webSocketUrl.query.clientTimestamp = (0, _now.default)();
|
|
179
317
|
return _url.default.format(webSocketUrl);
|
|
180
318
|
});
|
|
181
319
|
},
|
|
182
|
-
_attemptConnection: function _attemptConnection(socketUrl, callback) {
|
|
183
|
-
var
|
|
320
|
+
_attemptConnection: function _attemptConnection(socketUrl, sessionId, callback) {
|
|
321
|
+
var _this6 = this;
|
|
184
322
|
var socket = new _socket.default();
|
|
323
|
+
socket.connecting = true;
|
|
185
324
|
var attemptWSUrl;
|
|
325
|
+
var suffix = sessionId === this.defaultSessionId ? '' : ":".concat(sessionId);
|
|
186
326
|
socket.on('close', function () {
|
|
187
|
-
|
|
327
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
328
|
+
args[_key] = arguments[_key];
|
|
329
|
+
}
|
|
330
|
+
return _this6._onclose.apply(_this6, [sessionId].concat(args));
|
|
188
331
|
});
|
|
189
332
|
socket.on('message', function () {
|
|
190
|
-
|
|
333
|
+
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
334
|
+
args[_key2] = arguments[_key2];
|
|
335
|
+
}
|
|
336
|
+
return _this6._onmessage.apply(_this6, [sessionId].concat(args));
|
|
191
337
|
});
|
|
192
338
|
socket.on('pong', function () {
|
|
193
|
-
|
|
339
|
+
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
340
|
+
args[_key3] = arguments[_key3];
|
|
341
|
+
}
|
|
342
|
+
return _this6._setTimeOffset.apply(_this6, [sessionId].concat(args));
|
|
194
343
|
});
|
|
195
344
|
socket.on('sequence-mismatch', function () {
|
|
196
|
-
for (var
|
|
197
|
-
args[
|
|
345
|
+
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
346
|
+
args[_key4] = arguments[_key4];
|
|
198
347
|
}
|
|
199
|
-
return
|
|
348
|
+
return _this6._emit.apply(_this6, ["sequence-mismatch".concat(suffix)].concat(args));
|
|
200
349
|
});
|
|
201
350
|
socket.on('ping-pong-latency', function () {
|
|
202
|
-
for (var
|
|
203
|
-
args[
|
|
351
|
+
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
|
|
352
|
+
args[_key5] = arguments[_key5];
|
|
204
353
|
}
|
|
205
|
-
return
|
|
354
|
+
return _this6._emit.apply(_this6, ["ping-pong-latency".concat(suffix)].concat(args));
|
|
206
355
|
});
|
|
207
356
|
_promise.default.all([this._prepareUrl(socketUrl), this.webex.credentials.getUserToken()]).then(function (_ref) {
|
|
208
357
|
var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
|
|
209
358
|
webSocketUrl = _ref2[0],
|
|
210
359
|
token = _ref2[1];
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
360
|
+
var backoffCall = _this6.backoffCalls.get(sessionId);
|
|
361
|
+
if (!backoffCall) {
|
|
362
|
+
var msg = "".concat(_this6.namespace, ": prevent socket open when backoffCall no longer defined for ").concat(sessionId);
|
|
363
|
+
_this6.logger.info(msg);
|
|
214
364
|
return _promise.default.reject(new Error(msg));
|
|
215
365
|
}
|
|
216
366
|
attemptWSUrl = webSocketUrl;
|
|
217
367
|
var options = {
|
|
218
|
-
forceCloseDelay:
|
|
219
|
-
pingInterval:
|
|
220
|
-
pongTimeout:
|
|
368
|
+
forceCloseDelay: _this6.config.forceCloseDelay,
|
|
369
|
+
pingInterval: _this6.config.pingInterval,
|
|
370
|
+
pongTimeout: _this6.config.pongTimeout,
|
|
221
371
|
token: token.toString(),
|
|
222
|
-
trackingId: "".concat(
|
|
223
|
-
logger:
|
|
372
|
+
trackingId: "".concat(_this6.webex.sessionId, "_").concat(sessionId, "_").concat((0, _now.default)()),
|
|
373
|
+
logger: _this6.logger
|
|
224
374
|
};
|
|
225
375
|
|
|
226
376
|
// if the consumer has supplied request options use them
|
|
227
|
-
if (
|
|
228
|
-
|
|
229
|
-
options = _objectSpread(_objectSpread({}, options),
|
|
377
|
+
if (_this6.webex.config.defaultMercuryOptions) {
|
|
378
|
+
_this6.logger.info("".concat(_this6.namespace, ": setting custom options for ").concat(sessionId));
|
|
379
|
+
options = _objectSpread(_objectSpread({}, options), _this6.webex.config.defaultMercuryOptions);
|
|
230
380
|
}
|
|
231
381
|
|
|
232
382
|
// Set the socket before opening it. This allows a disconnect() to close
|
|
233
383
|
// the socket if it is in the process of being opened.
|
|
234
|
-
|
|
235
|
-
|
|
384
|
+
_this6.sockets.set(sessionId, socket);
|
|
385
|
+
_this6.socket = _this6.sockets.get(_this6.defaultSessionId) || socket;
|
|
386
|
+
_this6.logger.info("".concat(_this6.namespace, " connection url for ").concat(sessionId, ": ").concat(webSocketUrl));
|
|
236
387
|
return socket.open(webSocketUrl, options);
|
|
237
388
|
}).then(function () {
|
|
238
|
-
|
|
389
|
+
_this6.logger.info("".concat(_this6.namespace, ": connected to mercury, success, action: connected, sessionId: ").concat(sessionId, ", url: ").concat(attemptWSUrl));
|
|
239
390
|
callback();
|
|
240
|
-
return
|
|
391
|
+
return _this6.webex.internal.feature.getFeature('developer', 'web-high-availability').then(function (haMessagingEnabled) {
|
|
241
392
|
if (haMessagingEnabled) {
|
|
242
|
-
return
|
|
393
|
+
return _this6.webex.internal.device.refresh();
|
|
243
394
|
}
|
|
244
395
|
return _promise.default.resolve();
|
|
245
396
|
});
|
|
246
397
|
}).catch(function (reason) {
|
|
247
|
-
|
|
248
|
-
_this5.lastError = reason; // remember the last error
|
|
398
|
+
_this6.lastError = reason; // remember the last error
|
|
249
399
|
|
|
400
|
+
var backoffCall = _this6.backoffCalls.get(sessionId);
|
|
250
401
|
// Suppress connection errors that appear to be network related. This
|
|
251
402
|
// may end up suppressing metrics during outages, but we might not care
|
|
252
403
|
// (especially since many of our outages happen in a way that client
|
|
253
404
|
// metrics can't be trusted).
|
|
254
|
-
if (reason.code !== 1006 &&
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
retries:
|
|
405
|
+
if (reason.code !== 1006 && backoffCall && (backoffCall === null || backoffCall === void 0 ? void 0 : backoffCall.getNumRetries()) > 0) {
|
|
406
|
+
_this6._emit("connection_failed".concat(suffix), reason, {
|
|
407
|
+
sessionId: sessionId,
|
|
408
|
+
retries: backoffCall === null || backoffCall === void 0 ? void 0 : backoffCall.getNumRetries()
|
|
258
409
|
});
|
|
259
410
|
}
|
|
260
|
-
|
|
411
|
+
_this6.logger.info("".concat(_this6.namespace, ": connection attempt failed for ").concat(sessionId), reason, (backoffCall === null || backoffCall === void 0 ? void 0 : backoffCall.getNumRetries()) === 0 ? reason.stack : '');
|
|
261
412
|
// UnknownResponse is produced by IE for any 4XXX; treated it like a bad
|
|
262
413
|
// web socket url and let WDM handle the token checking
|
|
263
414
|
if (reason instanceof _errors.UnknownResponse) {
|
|
264
|
-
|
|
265
|
-
return
|
|
415
|
+
_this6.logger.info("".concat(_this6.namespace, ": received unknown response code for ").concat(sessionId, ", refreshing device registration"));
|
|
416
|
+
return _this6.webex.internal.device.refresh().then(function () {
|
|
266
417
|
return callback(reason);
|
|
267
418
|
});
|
|
268
419
|
}
|
|
269
420
|
// NotAuthorized implies expired token
|
|
270
421
|
if (reason instanceof _errors.NotAuthorized) {
|
|
271
|
-
|
|
272
|
-
return
|
|
422
|
+
_this6.logger.info("".concat(_this6.namespace, ": received authorization error for ").concat(sessionId, ", reauthorizing"));
|
|
423
|
+
return _this6.webex.credentials.refresh({
|
|
273
424
|
force: true
|
|
274
425
|
}).then(function () {
|
|
275
426
|
return callback(reason);
|
|
@@ -284,15 +435,15 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
284
435
|
// BadRequest implies current credentials are for a Service Account
|
|
285
436
|
// Forbidden implies current user is not entitle for Webex
|
|
286
437
|
if (reason instanceof _errors.BadRequest || reason instanceof _errors.Forbidden) {
|
|
287
|
-
|
|
288
|
-
|
|
438
|
+
_this6.logger.warn("".concat(_this6.namespace, ": received unrecoverable response from mercury for ").concat(sessionId));
|
|
439
|
+
backoffCall === null || backoffCall === void 0 ? void 0 : backoffCall.abort();
|
|
289
440
|
return callback(reason);
|
|
290
441
|
}
|
|
291
442
|
if (reason instanceof _errors.ConnectionError) {
|
|
292
|
-
return
|
|
443
|
+
return _this6.webex.internal.feature.getFeature('developer', 'web-high-availability').then(function (haMessagingEnabled) {
|
|
293
444
|
if (haMessagingEnabled) {
|
|
294
|
-
|
|
295
|
-
return
|
|
445
|
+
_this6.logger.info("".concat(_this6.namespace, ": received a generic connection error for ").concat(sessionId, ", will try to connect to another datacenter. failed, action: 'failed', url: ").concat(attemptWSUrl, " error: ").concat(reason.message));
|
|
446
|
+
return _this6.webex.internal.services.markFailedUrl(attemptWSUrl);
|
|
296
447
|
}
|
|
297
448
|
return null;
|
|
298
449
|
}).then(function () {
|
|
@@ -301,72 +452,96 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
301
452
|
}
|
|
302
453
|
return callback(reason);
|
|
303
454
|
}).catch(function (reason) {
|
|
304
|
-
|
|
455
|
+
_this6.logger.error("".concat(_this6.namespace, ": failed to handle connection failure for ").concat(sessionId), reason);
|
|
305
456
|
callback(reason);
|
|
306
457
|
});
|
|
307
458
|
},
|
|
308
|
-
_connectWithBackoff: function _connectWithBackoff(webSocketUrl) {
|
|
309
|
-
var
|
|
459
|
+
_connectWithBackoff: function _connectWithBackoff(webSocketUrl, sessionId) {
|
|
460
|
+
var _this7 = this;
|
|
310
461
|
return new _promise.default(function (resolve, reject) {
|
|
311
462
|
// eslint gets confused about whether or not call is actually used
|
|
312
463
|
// eslint-disable-next-line prefer-const
|
|
313
464
|
var call;
|
|
314
465
|
var onComplete = function onComplete(err) {
|
|
315
|
-
|
|
316
|
-
|
|
466
|
+
var sid = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : sessionId;
|
|
467
|
+
_this7.backoffCalls.delete(sid);
|
|
317
468
|
if (err) {
|
|
318
|
-
|
|
469
|
+
_this7.logger.info("".concat(_this7.namespace, ": failed to connect ").concat(sid, " after ").concat(call.getNumRetries(), " retries; log statement about next retry was inaccurate; ").concat(err));
|
|
319
470
|
return reject(err);
|
|
320
471
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
472
|
+
// Update overall connected status
|
|
473
|
+
var sessionSocket = _this7.sockets.get(sid);
|
|
474
|
+
if (sessionSocket) {
|
|
475
|
+
sessionSocket.connecting = false;
|
|
476
|
+
sessionSocket.connected = true;
|
|
477
|
+
}
|
|
478
|
+
// @ts-ignore
|
|
479
|
+
_this7.connecting = _this7.hasConnectingSockets();
|
|
480
|
+
_this7.connected = _this7.hasConnectedSockets();
|
|
481
|
+
_this7.hasEverConnected = true;
|
|
482
|
+
var suffix = sid === _this7.defaultSessionId ? '' : ":".concat(sid);
|
|
483
|
+
_this7._emit("online".concat(suffix), {
|
|
484
|
+
sessionId: sid
|
|
485
|
+
});
|
|
486
|
+
_this7.webex.internal.newMetrics.callDiagnosticMetrics.setMercuryConnectedStatus(true);
|
|
324
487
|
return resolve();
|
|
325
488
|
};
|
|
326
|
-
|
|
327
489
|
// eslint-disable-next-line prefer-reflect
|
|
328
490
|
call = _backoff.default.call(function (callback) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
},
|
|
491
|
+
_this7.logger.info("".concat(_this7.namespace, ": executing connection attempt ").concat(call.getNumRetries(), " for ").concat(sessionId));
|
|
492
|
+
_this7._attemptConnection(webSocketUrl, sessionId, callback);
|
|
493
|
+
}, function (err) {
|
|
494
|
+
return onComplete(err, sessionId);
|
|
495
|
+
});
|
|
332
496
|
call.setStrategy(new _backoff.default.ExponentialStrategy({
|
|
333
|
-
initialDelay:
|
|
334
|
-
maxDelay:
|
|
497
|
+
initialDelay: _this7.config.backoffTimeReset,
|
|
498
|
+
maxDelay: _this7.config.backoffTimeMax
|
|
335
499
|
}));
|
|
336
|
-
if (
|
|
337
|
-
call.failAfter(
|
|
338
|
-
} else if (
|
|
339
|
-
call.failAfter(
|
|
500
|
+
if (_this7.config.initialConnectionMaxRetries && !_this7.hasEverConnected) {
|
|
501
|
+
call.failAfter(_this7.config.initialConnectionMaxRetries);
|
|
502
|
+
} else if (_this7.config.maxRetries) {
|
|
503
|
+
call.failAfter(_this7.config.maxRetries);
|
|
340
504
|
}
|
|
505
|
+
|
|
506
|
+
// Store the call BEFORE setting up event handlers to prevent race conditions
|
|
507
|
+
_this7.backoffCalls.set(sessionId, call);
|
|
341
508
|
call.on('abort', function () {
|
|
342
|
-
|
|
343
|
-
reject(new Error(
|
|
509
|
+
_this7.logger.info("".concat(_this7.namespace, ": connection aborted for ").concat(sessionId));
|
|
510
|
+
reject(new Error("Mercury Connection Aborted for ".concat(sessionId)));
|
|
344
511
|
});
|
|
345
512
|
call.on('callback', function (err) {
|
|
346
513
|
if (err) {
|
|
347
514
|
var number = call.getNumRetries();
|
|
348
|
-
var delay = Math.min(call.strategy_.nextBackoffDelay_,
|
|
349
|
-
|
|
515
|
+
var delay = Math.min(call.strategy_.nextBackoffDelay_, _this7.config.backoffTimeMax);
|
|
516
|
+
_this7.logger.info("".concat(_this7.namespace, ": failed to connect ").concat(sessionId, "; attempting retry ").concat(number + 1, " in ").concat(delay, " ms"));
|
|
350
517
|
/* istanbul ignore if */
|
|
351
518
|
if (process.env.NODE_ENV === 'development') {
|
|
352
|
-
|
|
519
|
+
_this7.logger.debug("".concat(_this7.namespace, ": "), err, err.stack);
|
|
353
520
|
}
|
|
354
521
|
return;
|
|
355
522
|
}
|
|
356
|
-
|
|
523
|
+
_this7.logger.info("".concat(_this7.namespace, ": connected ").concat(sessionId));
|
|
357
524
|
});
|
|
358
525
|
call.start();
|
|
359
|
-
_this6.backoffCall = call;
|
|
360
526
|
});
|
|
361
527
|
},
|
|
362
528
|
_emit: function _emit() {
|
|
363
|
-
for (var
|
|
364
|
-
args[
|
|
529
|
+
for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
|
|
530
|
+
args[_key6] = arguments[_key6];
|
|
365
531
|
}
|
|
366
532
|
try {
|
|
367
|
-
|
|
533
|
+
// Validate args before processing
|
|
534
|
+
if (args && args.length > 0) {
|
|
535
|
+
this.trigger.apply(this, args);
|
|
536
|
+
}
|
|
368
537
|
} catch (error) {
|
|
369
|
-
|
|
538
|
+
// Safely handle errors without causing additional issues during cleanup
|
|
539
|
+
try {
|
|
540
|
+
this.logger.error("".concat(this.namespace, ": error occurred in event handler:"), error, ' with args: ', args);
|
|
541
|
+
} catch (logError) {
|
|
542
|
+
// If even logging fails, just ignore to prevent cascading errors during cleanup
|
|
543
|
+
this.logger.error('Mercury _emit error handling failed:', logError);
|
|
544
|
+
}
|
|
370
545
|
}
|
|
371
546
|
},
|
|
372
547
|
_getEventHandlers: function _getEventHandlers(eventType) {
|
|
@@ -387,35 +562,48 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
387
562
|
}
|
|
388
563
|
return handlers;
|
|
389
564
|
},
|
|
390
|
-
_onclose: function _onclose(event) {
|
|
565
|
+
_onclose: function _onclose(sessionId, event) {
|
|
391
566
|
// I don't see any way to avoid the complexity or statement count in here.
|
|
392
567
|
/* eslint complexity: [0] */
|
|
393
568
|
|
|
394
569
|
try {
|
|
570
|
+
var _sessionSocket;
|
|
395
571
|
var reason = event.reason && event.reason.toLowerCase();
|
|
396
|
-
var
|
|
397
|
-
|
|
398
|
-
this.
|
|
399
|
-
|
|
400
|
-
this.
|
|
572
|
+
var sessionSocket = this.sockets.get(sessionId);
|
|
573
|
+
var socketUrl = (_sessionSocket = sessionSocket) === null || _sessionSocket === void 0 ? void 0 : _sessionSocket.url;
|
|
574
|
+
var suffix = sessionId === this.defaultSessionId ? '' : ":".concat(sessionId);
|
|
575
|
+
event.sessionId = sessionId;
|
|
576
|
+
this.sockets.delete(sessionId);
|
|
577
|
+
if (sessionSocket) {
|
|
578
|
+
sessionSocket.removeAllListeners();
|
|
579
|
+
sessionSocket = null;
|
|
580
|
+
this._emit("offline".concat(suffix), event);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// Update overall connected status
|
|
584
|
+
this.connecting = this.hasConnectingSockets();
|
|
585
|
+
this.connected = this.hasConnectedSockets();
|
|
586
|
+
if (!this.connected) {
|
|
587
|
+
this.webex.internal.newMetrics.callDiagnosticMetrics.setMercuryConnectedStatus(false);
|
|
588
|
+
}
|
|
401
589
|
switch (event.code) {
|
|
402
590
|
case 1003:
|
|
403
591
|
// metric: disconnect
|
|
404
|
-
this.logger.info("".concat(this.namespace, ": Mercury service rejected last message; will not reconnect: ").concat(event.reason));
|
|
405
|
-
this._emit(
|
|
592
|
+
this.logger.info("".concat(this.namespace, ": Mercury service rejected last message for ").concat(sessionId, "; will not reconnect: ").concat(event.reason));
|
|
593
|
+
this._emit("offline.permanent".concat(suffix), event);
|
|
406
594
|
break;
|
|
407
595
|
case 4000:
|
|
408
596
|
// metric: disconnect
|
|
409
|
-
this.logger.info("".concat(this.namespace, ": socket replaced; will not reconnect"));
|
|
410
|
-
this._emit(
|
|
597
|
+
this.logger.info("".concat(this.namespace, ": socket ").concat(sessionId, " replaced; will not reconnect"));
|
|
598
|
+
this._emit("offline.replaced".concat(suffix), event);
|
|
411
599
|
break;
|
|
412
600
|
case 1001:
|
|
413
601
|
case 1005:
|
|
414
602
|
case 1006:
|
|
415
603
|
case 1011:
|
|
416
|
-
this.logger.info("".concat(this.namespace, ": socket disconnected; reconnecting"));
|
|
417
|
-
this._emit(
|
|
418
|
-
this._reconnect(socketUrl);
|
|
604
|
+
this.logger.info("".concat(this.namespace, ": socket ").concat(sessionId, " disconnected; reconnecting"));
|
|
605
|
+
this._emit("offline.transient".concat(suffix), event);
|
|
606
|
+
this._reconnect(socketUrl, sessionId);
|
|
419
607
|
// metric: disconnect
|
|
420
608
|
// if (code == 1011 && reason !== ping error) metric: unexpected disconnect
|
|
421
609
|
break;
|
|
@@ -423,32 +611,33 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
423
611
|
case 3050:
|
|
424
612
|
// 3050 indicates logout form of closure, default to old behavior, use config reason defined by consumer to proceed with the permanent block
|
|
425
613
|
if (normalReconnectReasons.includes(reason)) {
|
|
426
|
-
this.logger.info("".concat(this.namespace, ": socket disconnected; reconnecting"));
|
|
427
|
-
this._emit(
|
|
428
|
-
this._reconnect(socketUrl);
|
|
614
|
+
this.logger.info("".concat(this.namespace, ": socket ").concat(sessionId, " disconnected; reconnecting"));
|
|
615
|
+
this._emit("offline.transient".concat(suffix), event);
|
|
616
|
+
this._reconnect(socketUrl, sessionId);
|
|
429
617
|
// metric: disconnect
|
|
430
618
|
// if (reason === done forced) metric: force closure
|
|
431
619
|
} else {
|
|
432
|
-
this.logger.info("".concat(this.namespace, ": socket disconnected; will not reconnect: ").concat(event.reason));
|
|
433
|
-
this._emit(
|
|
620
|
+
this.logger.info("".concat(this.namespace, ": socket ").concat(sessionId, " disconnected; will not reconnect: ").concat(event.reason));
|
|
621
|
+
this._emit("offline.permanent".concat(suffix), event);
|
|
434
622
|
}
|
|
435
623
|
break;
|
|
436
624
|
default:
|
|
437
|
-
this.logger.info("".concat(this.namespace, ": socket disconnected unexpectedly; will not reconnect"));
|
|
625
|
+
this.logger.info("".concat(this.namespace, ": socket ").concat(sessionId, " disconnected unexpectedly; will not reconnect"));
|
|
438
626
|
// unexpected disconnect
|
|
439
|
-
this._emit(
|
|
627
|
+
this._emit("offline.permanent".concat(suffix), event);
|
|
440
628
|
}
|
|
441
629
|
} catch (error) {
|
|
442
|
-
this.logger.error("".concat(this.namespace, ": error occurred in close handler"), error);
|
|
630
|
+
this.logger.error("".concat(this.namespace, ": error occurred in close handler for ").concat(sessionId), error);
|
|
443
631
|
}
|
|
444
632
|
},
|
|
445
|
-
_onmessage: function _onmessage(event) {
|
|
446
|
-
var
|
|
447
|
-
this._setTimeOffset(event);
|
|
633
|
+
_onmessage: function _onmessage(sessionId, event) {
|
|
634
|
+
var _this8 = this;
|
|
635
|
+
this._setTimeOffset(sessionId, event);
|
|
448
636
|
var envelope = event.data;
|
|
449
637
|
if (process.env.ENABLE_MERCURY_LOGGING) {
|
|
450
|
-
this.logger.debug("".concat(this.namespace, ": message envelope: "), envelope);
|
|
638
|
+
this.logger.debug("".concat(this.namespace, ": message envelope from ").concat(sessionId, ": "), envelope);
|
|
451
639
|
}
|
|
640
|
+
envelope.sessionId = sessionId;
|
|
452
641
|
var data = envelope.data;
|
|
453
642
|
this._applyOverrides(data);
|
|
454
643
|
return this._getEventHandlers(data.eventType).reduce(function (promise, handler) {
|
|
@@ -456,37 +645,39 @@ var Mercury = _webexCore.WebexPlugin.extend((_dec = (0, _common.deprecated)('Mer
|
|
|
456
645
|
var namespace = handler.namespace,
|
|
457
646
|
name = handler.name;
|
|
458
647
|
return new _promise.default(function (resolve) {
|
|
459
|
-
return resolve((
|
|
648
|
+
return resolve((_this8.webex[namespace] || _this8.webex.internal[namespace])[name](data));
|
|
460
649
|
}).catch(function (reason) {
|
|
461
|
-
return
|
|
650
|
+
return _this8.logger.error("".concat(_this8.namespace, ": error occurred in autowired event handler for ").concat(data.eventType, " from ").concat(sessionId), reason);
|
|
462
651
|
});
|
|
463
652
|
});
|
|
464
653
|
}, _promise.default.resolve()).then(function () {
|
|
465
|
-
|
|
654
|
+
var suffix = sessionId === _this8.defaultSessionId ? '' : ":".concat(sessionId);
|
|
655
|
+
_this8._emit("event".concat(suffix), envelope);
|
|
466
656
|
var _data$eventType$split = data.eventType.split('.'),
|
|
467
657
|
_data$eventType$split2 = (0, _slicedToArray2.default)(_data$eventType$split, 1),
|
|
468
658
|
namespace = _data$eventType$split2[0];
|
|
469
659
|
if (namespace === data.eventType) {
|
|
470
|
-
|
|
660
|
+
_this8._emit("event:".concat(namespace).concat(suffix), envelope);
|
|
471
661
|
} else {
|
|
472
|
-
|
|
473
|
-
|
|
662
|
+
_this8._emit("event:".concat(namespace).concat(suffix), envelope);
|
|
663
|
+
_this8._emit("event:".concat(data.eventType).concat(suffix), envelope);
|
|
474
664
|
}
|
|
475
665
|
}).catch(function (reason) {
|
|
476
|
-
|
|
666
|
+
_this8.logger.error("".concat(_this8.namespace, ": error occurred processing socket message from ").concat(sessionId), reason);
|
|
477
667
|
});
|
|
478
668
|
},
|
|
479
|
-
_setTimeOffset: function _setTimeOffset(event) {
|
|
669
|
+
_setTimeOffset: function _setTimeOffset(sessionId, event) {
|
|
480
670
|
var wsWriteTimestamp = event.data.wsWriteTimestamp;
|
|
481
671
|
if (typeof wsWriteTimestamp === 'number' && wsWriteTimestamp > 0) {
|
|
482
672
|
this.mercuryTimeOffset = (0, _now.default)() - wsWriteTimestamp;
|
|
483
673
|
}
|
|
484
674
|
},
|
|
485
675
|
_reconnect: function _reconnect(webSocketUrl) {
|
|
486
|
-
|
|
487
|
-
|
|
676
|
+
var sessionId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.defaultSessionId;
|
|
677
|
+
this.logger.info("".concat(this.namespace, ": reconnecting ").concat(sessionId));
|
|
678
|
+
return this.connect(webSocketUrl, sessionId);
|
|
488
679
|
},
|
|
489
|
-
version: "3.
|
|
490
|
-
}, ((0, _applyDecoratedDescriptor2.default)(_obj, "
|
|
491
|
-
var
|
|
680
|
+
version: "3.9.0-multiple-llm.2"
|
|
681
|
+
}, ((0, _applyDecoratedDescriptor2.default)(_obj, "listen", [_dec], (0, _getOwnPropertyDescriptor.default)(_obj, "listen"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "stopListening", [_dec2], (0, _getOwnPropertyDescriptor.default)(_obj, "stopListening"), _obj)), _obj)));
|
|
682
|
+
var _default2 = exports.default = Mercury;
|
|
492
683
|
//# sourceMappingURL=mercury.js.map
|