@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.
- package/dist/CallingClient/CallingClient.js +463 -205
- package/dist/CallingClient/CallingClient.js.map +1 -1
- package/dist/CallingClient/CallingClient.test.js +170 -77
- package/dist/CallingClient/CallingClient.test.js.map +1 -1
- package/dist/CallingClient/calling/call.js +11 -8
- package/dist/CallingClient/calling/call.js.map +1 -1
- package/dist/CallingClient/calling/call.test.js +45 -4
- package/dist/CallingClient/calling/call.test.js.map +1 -1
- package/dist/CallingClient/calling/callManager.js +53 -30
- package/dist/CallingClient/calling/callManager.js.map +1 -1
- package/dist/CallingClient/calling/callManager.test.js +35 -0
- package/dist/CallingClient/calling/callManager.test.js.map +1 -1
- package/dist/CallingClient/calling/types.js +2 -0
- package/dist/CallingClient/calling/types.js.map +1 -1
- package/dist/CallingClient/constants.js +24 -3
- package/dist/CallingClient/constants.js.map +1 -1
- package/dist/CallingClient/line/line.test.js +16 -1
- package/dist/CallingClient/line/line.test.js.map +1 -1
- package/dist/CallingClient/registration/register.js +694 -406
- package/dist/CallingClient/registration/register.js.map +1 -1
- package/dist/CallingClient/registration/register.test.js +202 -21
- package/dist/CallingClient/registration/register.test.js.map +1 -1
- package/dist/CallingClient/registration/types.js.map +1 -1
- package/dist/CallingClient/registration/webWorker.js +41 -104
- package/dist/CallingClient/registration/webWorker.js.map +1 -1
- package/dist/CallingClient/registration/webWorker.test.js +39 -153
- package/dist/CallingClient/registration/webWorker.test.js.map +1 -1
- package/dist/CallingClient/registration/webWorkerStr.js +1 -1
- package/dist/CallingClient/registration/webWorkerStr.js.map +1 -1
- package/dist/CallingClient/utils/constants.js +46 -0
- package/dist/CallingClient/utils/constants.js.map +1 -0
- package/dist/CallingClient/utils/index.js +63 -0
- package/dist/CallingClient/utils/index.js.map +1 -0
- package/dist/CallingClient/utils/mobiusSocketMapper.js +122 -0
- package/dist/CallingClient/utils/mobiusSocketMapper.js.map +1 -0
- package/dist/CallingClient/utils/mobiusSocketMapper.test.js +211 -0
- package/dist/CallingClient/utils/mobiusSocketMapper.test.js.map +1 -0
- package/dist/CallingClient/utils/request.js +349 -0
- package/dist/CallingClient/utils/request.js.map +1 -0
- package/dist/CallingClient/utils/request.test.js +881 -0
- package/dist/CallingClient/utils/request.test.js.map +1 -0
- package/dist/CallingClient/utils/types.js +7 -0
- package/dist/CallingClient/utils/types.js.map +1 -0
- package/dist/CallingClient/utils/wsFeatureFlag.js +28 -0
- package/dist/CallingClient/utils/wsFeatureFlag.js.map +1 -0
- package/dist/CallingClient/utils/wsFeatureFlag.test.js +139 -0
- package/dist/CallingClient/utils/wsFeatureFlag.test.js.map +1 -0
- package/dist/Contacts/ContactsClient.test.js +3 -8
- package/dist/Contacts/ContactsClient.test.js.map +1 -1
- package/dist/Metrics/index.js +60 -0
- package/dist/Metrics/index.js.map +1 -1
- package/dist/Metrics/index.test.js +356 -0
- package/dist/Metrics/index.test.js.map +1 -1
- package/dist/Metrics/types.js +11 -1
- package/dist/Metrics/types.js.map +1 -1
- package/dist/SDKConnector/types.js.map +1 -1
- package/dist/common/Utils.js +138 -44
- package/dist/common/Utils.js.map +1 -1
- package/dist/common/testUtil.js +8 -4
- package/dist/common/testUtil.js.map +1 -1
- package/dist/common/types.js +2 -0
- package/dist/common/types.js.map +1 -1
- package/dist/mobius-socket/config.js +24 -0
- package/dist/mobius-socket/config.js.map +1 -0
- package/dist/mobius-socket/errors.js +150 -0
- package/dist/mobius-socket/errors.js.map +1 -0
- package/dist/mobius-socket/index.js +57 -0
- package/dist/mobius-socket/index.js.map +1 -0
- package/dist/mobius-socket/mobius-socket-events.test.js +485 -0
- package/dist/mobius-socket/mobius-socket-events.test.js.map +1 -0
- package/dist/mobius-socket/mobius-socket.js +804 -0
- package/dist/mobius-socket/mobius-socket.js.map +1 -0
- package/dist/mobius-socket/mobius-socket.test.js +1833 -0
- package/dist/mobius-socket/mobius-socket.test.js.map +1 -0
- package/dist/mobius-socket/socket/constants.js +34 -0
- package/dist/mobius-socket/socket/constants.js.map +1 -0
- package/dist/mobius-socket/socket/index.js +15 -0
- package/dist/mobius-socket/socket/index.js.map +1 -0
- package/dist/mobius-socket/socket/socket-base.js +604 -0
- package/dist/mobius-socket/socket/socket-base.js.map +1 -0
- package/dist/mobius-socket/socket/socket.js +19 -0
- package/dist/mobius-socket/socket/socket.js.map +1 -0
- package/dist/mobius-socket/socket/socket.shim.js +26 -0
- package/dist/mobius-socket/socket/socket.shim.js.map +1 -0
- package/dist/mobius-socket/socket/types.js +7 -0
- package/dist/mobius-socket/socket/types.js.map +1 -0
- package/dist/mobius-socket/socket.test.js +727 -0
- package/dist/mobius-socket/socket.test.js.map +1 -0
- package/dist/mobius-socket/test/mocha-helpers.js +23 -0
- package/dist/mobius-socket/test/mocha-helpers.js.map +1 -0
- package/dist/mobius-socket/test/promise-tick.js +28 -0
- package/dist/mobius-socket/test/promise-tick.js.map +1 -0
- package/dist/mobius-socket/types.js +7 -0
- package/dist/mobius-socket/types.js.map +1 -0
- package/dist/module/CallingClient/CallingClient.js +141 -10
- package/dist/module/CallingClient/calling/call.js +9 -6
- package/dist/module/CallingClient/calling/callManager.js +27 -7
- package/dist/module/CallingClient/calling/types.js +2 -0
- package/dist/module/CallingClient/constants.js +20 -0
- package/dist/module/CallingClient/registration/register.js +226 -62
- package/dist/module/CallingClient/registration/webWorker.js +42 -61
- package/dist/module/CallingClient/registration/webWorkerStr.js +47 -82
- package/dist/module/CallingClient/utils/constants.js +30 -0
- package/dist/module/CallingClient/utils/index.js +5 -0
- package/dist/module/CallingClient/utils/mobiusSocketMapper.js +72 -0
- package/dist/module/CallingClient/utils/request.js +162 -0
- package/dist/module/CallingClient/utils/types.js +1 -0
- package/dist/module/CallingClient/utils/wsFeatureFlag.js +12 -0
- package/dist/module/Metrics/index.js +46 -0
- package/dist/module/Metrics/types.js +10 -0
- package/dist/module/common/Utils.js +52 -12
- package/dist/module/common/testUtil.js +5 -1
- package/dist/module/common/types.js +2 -0
- package/dist/module/mobius-socket/config.js +15 -0
- package/dist/module/mobius-socket/errors.js +64 -0
- package/dist/module/mobius-socket/index.js +24 -0
- package/dist/module/mobius-socket/mobius-socket.js +571 -0
- package/dist/module/mobius-socket/socket/constants.js +10 -0
- package/dist/module/mobius-socket/socket/index.js +4 -0
- package/dist/module/mobius-socket/socket/socket-base.js +368 -0
- package/dist/module/mobius-socket/socket/socket.js +9 -0
- package/dist/module/mobius-socket/socket/socket.shim.js +12 -0
- package/dist/module/mobius-socket/socket/types.js +1 -0
- package/dist/module/mobius-socket/types.js +1 -0
- package/dist/types/CallingClient/CallingClient.d.ts +7 -0
- package/dist/types/CallingClient/CallingClient.d.ts.map +1 -1
- package/dist/types/CallingClient/calling/call.d.ts +1 -0
- package/dist/types/CallingClient/calling/call.d.ts.map +1 -1
- package/dist/types/CallingClient/calling/callManager.d.ts +3 -2
- package/dist/types/CallingClient/calling/callManager.d.ts.map +1 -1
- package/dist/types/CallingClient/calling/types.d.ts +21 -9
- package/dist/types/CallingClient/calling/types.d.ts.map +1 -1
- package/dist/types/CallingClient/constants.d.ts +20 -0
- package/dist/types/CallingClient/constants.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/register.d.ts +6 -0
- package/dist/types/CallingClient/registration/register.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/types.d.ts +3 -1
- package/dist/types/CallingClient/registration/types.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/webWorker.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/webWorkerStr.d.ts +1 -1
- package/dist/types/CallingClient/registration/webWorkerStr.d.ts.map +1 -1
- package/dist/types/CallingClient/utils/constants.d.ts +30 -0
- package/dist/types/CallingClient/utils/constants.d.ts.map +1 -0
- package/dist/types/CallingClient/utils/index.d.ts +6 -0
- package/dist/types/CallingClient/utils/index.d.ts.map +1 -0
- package/dist/types/CallingClient/utils/mobiusSocketMapper.d.ts +5 -0
- package/dist/types/CallingClient/utils/mobiusSocketMapper.d.ts.map +1 -0
- package/dist/types/CallingClient/utils/request.d.ts +23 -0
- package/dist/types/CallingClient/utils/request.d.ts.map +1 -0
- package/dist/types/CallingClient/utils/types.d.ts +29 -0
- package/dist/types/CallingClient/utils/types.d.ts.map +1 -0
- package/dist/types/CallingClient/utils/wsFeatureFlag.d.ts +4 -0
- package/dist/types/CallingClient/utils/wsFeatureFlag.d.ts.map +1 -0
- package/dist/types/Metrics/index.d.ts.map +1 -1
- package/dist/types/Metrics/types.d.ts +11 -1
- package/dist/types/Metrics/types.d.ts.map +1 -1
- package/dist/types/SDKConnector/types.d.ts +24 -0
- package/dist/types/SDKConnector/types.d.ts.map +1 -1
- package/dist/types/common/Utils.d.ts +9 -2
- package/dist/types/common/Utils.d.ts.map +1 -1
- package/dist/types/common/testUtil.d.ts +4 -1
- package/dist/types/common/testUtil.d.ts.map +1 -1
- package/dist/types/common/types.d.ts +3 -0
- package/dist/types/common/types.d.ts.map +1 -1
- package/dist/types/mobius-socket/config.d.ts +17 -0
- package/dist/types/mobius-socket/config.d.ts.map +1 -0
- package/dist/types/mobius-socket/errors.d.ts +32 -0
- package/dist/types/mobius-socket/errors.d.ts.map +1 -0
- package/dist/types/mobius-socket/index.d.ts +14 -0
- package/dist/types/mobius-socket/index.d.ts.map +1 -0
- package/dist/types/mobius-socket/mobius-socket.d.ts +48 -0
- package/dist/types/mobius-socket/mobius-socket.d.ts.map +1 -0
- package/dist/types/mobius-socket/socket/constants.d.ts +11 -0
- package/dist/types/mobius-socket/socket/constants.d.ts.map +1 -0
- package/dist/types/mobius-socket/socket/index.d.ts +5 -0
- package/dist/types/mobius-socket/socket/index.d.ts.map +1 -0
- package/dist/types/mobius-socket/socket/socket-base.d.ts +43 -0
- package/dist/types/mobius-socket/socket/socket-base.d.ts.map +1 -0
- package/dist/types/mobius-socket/socket/socket.d.ts +6 -0
- package/dist/types/mobius-socket/socket/socket.d.ts.map +1 -0
- package/dist/types/mobius-socket/socket/socket.shim.d.ts +6 -0
- package/dist/types/mobius-socket/socket/socket.shim.d.ts.map +1 -0
- package/dist/types/mobius-socket/socket/types.d.ts +61 -0
- package/dist/types/mobius-socket/socket/types.d.ts.map +1 -0
- package/dist/types/mobius-socket/types.d.ts +21 -0
- package/dist/types/mobius-socket/types.d.ts.map +1 -0
- package/package.json +16 -2
- package/src/mobius-socket/socket/socket.shim.ts +22 -0
- 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
|