@webex/calling 3.8.0 → 3.8.1-next.10
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/CallHistory/CallHistory.js +100 -63
- package/dist/CallHistory/CallHistory.js.map +1 -1
- package/dist/CallHistory/CallHistory.test.js +115 -19
- package/dist/CallHistory/CallHistory.test.js.map +1 -1
- package/dist/CallHistory/constants.js +9 -1
- package/dist/CallHistory/constants.js.map +1 -1
- package/dist/CallSettings/CallSettings.js +46 -13
- package/dist/CallSettings/CallSettings.js.map +1 -1
- package/dist/CallSettings/UcmBackendConnector.js +62 -18
- package/dist/CallSettings/UcmBackendConnector.js.map +1 -1
- package/dist/CallSettings/UcmBackendConnector.test.js +70 -7
- package/dist/CallSettings/UcmBackendConnector.test.js.map +1 -1
- package/dist/CallSettings/WxCallBackendConnector.js +153 -103
- package/dist/CallSettings/WxCallBackendConnector.js.map +1 -1
- package/dist/CallSettings/WxCallBackendConnector.test.js +52 -15
- package/dist/CallSettings/WxCallBackendConnector.test.js.map +1 -1
- package/dist/CallSettings/constants.js +15 -1
- package/dist/CallSettings/constants.js.map +1 -1
- package/dist/CallingClient/CallingClient.js +220 -159
- package/dist/CallingClient/CallingClient.js.map +1 -1
- package/dist/CallingClient/CallingClient.test.js +58 -27
- package/dist/CallingClient/CallingClient.test.js.map +1 -1
- package/dist/CallingClient/calling/call.js +251 -189
- package/dist/CallingClient/calling/call.js.map +1 -1
- package/dist/CallingClient/calling/call.test.js +96 -41
- package/dist/CallingClient/calling/call.test.js.map +1 -1
- package/dist/CallingClient/calling/callManager.js +73 -48
- package/dist/CallingClient/calling/callManager.js.map +1 -1
- package/dist/CallingClient/calling/callManager.test.js +96 -37
- package/dist/CallingClient/calling/callManager.test.js.map +1 -1
- package/dist/CallingClient/constants.js +105 -3
- package/dist/CallingClient/constants.js.map +1 -1
- package/dist/CallingClient/line/index.js +47 -18
- package/dist/CallingClient/line/index.js.map +1 -1
- package/dist/CallingClient/line/line.test.js +6 -12
- package/dist/CallingClient/line/line.test.js.map +1 -1
- package/dist/CallingClient/registration/register.js +590 -522
- package/dist/CallingClient/registration/register.js.map +1 -1
- package/dist/CallingClient/registration/register.test.js +821 -394
- 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 +115 -0
- package/dist/CallingClient/registration/webWorker.js.map +1 -0
- package/dist/CallingClient/registration/webWorker.test.js +256 -0
- package/dist/CallingClient/registration/webWorker.test.js.map +1 -0
- package/dist/CallingClient/registration/webWorkerStr.js +15 -0
- package/dist/CallingClient/registration/webWorkerStr.js.map +1 -0
- package/dist/Contacts/ContactsClient.js +156 -102
- package/dist/Contacts/ContactsClient.js.map +1 -1
- package/dist/Contacts/ContactsClient.test.js +197 -49
- package/dist/Contacts/ContactsClient.test.js.map +1 -1
- package/dist/Contacts/constants.js +11 -1
- package/dist/Contacts/constants.js.map +1 -1
- package/dist/Errors/types.js +2 -0
- package/dist/Errors/types.js.map +1 -1
- package/dist/Events/impl/index.js +1 -1
- package/dist/Events/impl/index.js.map +1 -1
- package/dist/Metrics/index.js +102 -41
- package/dist/Metrics/index.js.map +1 -1
- package/dist/Metrics/index.test.js +10 -4
- package/dist/Metrics/index.test.js.map +1 -1
- package/dist/Metrics/types.js +4 -1
- package/dist/Metrics/types.js.map +1 -1
- package/dist/SDKConnector/types.js.map +1 -1
- package/dist/Voicemail/BroadworksBackendConnector.js +154 -91
- package/dist/Voicemail/BroadworksBackendConnector.js.map +1 -1
- package/dist/Voicemail/BroadworksBackendConnector.test.js +99 -19
- package/dist/Voicemail/BroadworksBackendConnector.test.js.map +1 -1
- package/dist/Voicemail/UcmBackendConnector.js +105 -54
- package/dist/Voicemail/UcmBackendConnector.js.map +1 -1
- package/dist/Voicemail/UcmBackendConnector.test.js +127 -17
- package/dist/Voicemail/UcmBackendConnector.test.js.map +1 -1
- package/dist/Voicemail/Voicemail.js +198 -79
- package/dist/Voicemail/Voicemail.js.map +1 -1
- package/dist/Voicemail/Voicemail.test.js +188 -23
- package/dist/Voicemail/Voicemail.test.js.map +1 -1
- package/dist/Voicemail/WxCallBackendConnector.js +277 -161
- package/dist/Voicemail/WxCallBackendConnector.js.map +1 -1
- package/dist/Voicemail/WxCallBackendConnector.test.js +268 -10
- package/dist/Voicemail/WxCallBackendConnector.test.js.map +1 -1
- package/dist/Voicemail/constants.js +25 -1
- package/dist/Voicemail/constants.js.map +1 -1
- package/dist/Voicemail/types.js.map +1 -1
- package/dist/common/Utils.js +168 -104
- package/dist/common/Utils.js.map +1 -1
- package/dist/common/Utils.test.js +199 -35
- package/dist/common/Utils.test.js.map +1 -1
- package/dist/common/constants.js +2 -1
- package/dist/common/constants.js.map +1 -1
- package/dist/common/testUtil.js +3 -0
- package/dist/common/testUtil.js.map +1 -1
- package/dist/common/types.js +8 -1
- package/dist/common/types.js.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/module/CallHistory/CallHistory.js +32 -13
- package/dist/module/CallHistory/constants.js +6 -0
- package/dist/module/CallSettings/CallSettings.js +36 -3
- package/dist/module/CallSettings/UcmBackendConnector.js +50 -5
- package/dist/module/CallSettings/WxCallBackendConnector.js +54 -18
- package/dist/module/CallSettings/constants.js +12 -0
- package/dist/module/CallingClient/CallingClient.js +54 -16
- package/dist/module/CallingClient/calling/call.js +172 -121
- package/dist/module/CallingClient/calling/callManager.js +51 -26
- package/dist/module/CallingClient/constants.js +102 -2
- package/dist/module/CallingClient/line/index.js +37 -8
- package/dist/module/CallingClient/registration/register.js +151 -112
- package/dist/module/CallingClient/registration/webWorker.js +59 -0
- package/dist/module/CallingClient/registration/webWorkerStr.js +93 -0
- package/dist/module/Contacts/ContactsClient.js +65 -21
- package/dist/module/Contacts/constants.js +10 -0
- package/dist/module/Errors/types.js +2 -0
- package/dist/module/Events/impl/index.js +1 -1
- package/dist/module/Metrics/index.js +57 -2
- package/dist/module/Metrics/types.js +3 -0
- package/dist/module/Voicemail/BroadworksBackendConnector.js +66 -17
- package/dist/module/Voicemail/UcmBackendConnector.js +51 -11
- package/dist/module/Voicemail/Voicemail.js +109 -9
- package/dist/module/Voicemail/WxCallBackendConnector.js +67 -18
- package/dist/module/Voicemail/constants.js +21 -0
- package/dist/module/common/Utils.js +51 -12
- package/dist/module/common/constants.js +1 -0
- package/dist/module/common/testUtil.js +3 -0
- package/dist/module/common/types.js +7 -0
- package/dist/module/index.js +1 -0
- package/dist/types/CallHistory/CallHistory.d.ts.map +1 -1
- package/dist/types/CallHistory/constants.d.ts +6 -0
- package/dist/types/CallHistory/constants.d.ts.map +1 -1
- package/dist/types/CallSettings/CallSettings.d.ts.map +1 -1
- package/dist/types/CallSettings/UcmBackendConnector.d.ts.map +1 -1
- package/dist/types/CallSettings/WxCallBackendConnector.d.ts.map +1 -1
- package/dist/types/CallSettings/constants.d.ts +12 -0
- package/dist/types/CallSettings/constants.d.ts.map +1 -1
- package/dist/types/CallingClient/CallingClient.d.ts +2 -3
- package/dist/types/CallingClient/CallingClient.d.ts.map +1 -1
- package/dist/types/CallingClient/calling/call.d.ts.map +1 -1
- package/dist/types/CallingClient/calling/callManager.d.ts.map +1 -1
- package/dist/types/CallingClient/constants.d.ts +102 -2
- package/dist/types/CallingClient/constants.d.ts.map +1 -1
- package/dist/types/CallingClient/line/index.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/register.d.ts +4 -3
- package/dist/types/CallingClient/registration/register.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/types.d.ts +1 -0
- package/dist/types/CallingClient/registration/types.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/webWorker.d.ts +2 -0
- package/dist/types/CallingClient/registration/webWorker.d.ts.map +1 -0
- package/dist/types/CallingClient/registration/webWorkerStr.d.ts +3 -0
- package/dist/types/CallingClient/registration/webWorkerStr.d.ts.map +1 -0
- package/dist/types/Contacts/ContactsClient.d.ts.map +1 -1
- package/dist/types/Contacts/constants.d.ts +10 -0
- package/dist/types/Contacts/constants.d.ts.map +1 -1
- package/dist/types/Errors/types.d.ts +2 -0
- package/dist/types/Errors/types.d.ts.map +1 -1
- package/dist/types/Metrics/index.d.ts +1 -1
- package/dist/types/Metrics/index.d.ts.map +1 -1
- package/dist/types/Metrics/types.d.ts +7 -2
- package/dist/types/Metrics/types.d.ts.map +1 -1
- package/dist/types/SDKConnector/types.d.ts +11 -2
- package/dist/types/SDKConnector/types.d.ts.map +1 -1
- package/dist/types/Voicemail/BroadworksBackendConnector.d.ts.map +1 -1
- package/dist/types/Voicemail/UcmBackendConnector.d.ts.map +1 -1
- package/dist/types/Voicemail/Voicemail.d.ts +1 -1
- package/dist/types/Voicemail/Voicemail.d.ts.map +1 -1
- package/dist/types/Voicemail/WxCallBackendConnector.d.ts +3 -1
- package/dist/types/Voicemail/WxCallBackendConnector.d.ts.map +1 -1
- package/dist/types/Voicemail/constants.d.ts +21 -0
- package/dist/types/Voicemail/constants.d.ts.map +1 -1
- package/dist/types/Voicemail/types.d.ts +1 -1
- package/dist/types/Voicemail/types.d.ts.map +1 -1
- package/dist/types/common/Utils.d.ts +4 -4
- package/dist/types/common/Utils.d.ts.map +1 -1
- package/dist/types/common/constants.d.ts +1 -0
- package/dist/types/common/constants.d.ts.map +1 -1
- package/dist/types/common/testUtil.d.ts +3 -0
- package/dist/types/common/testUtil.d.ts.map +1 -1
- package/dist/types/common/types.d.ts +24 -0
- package/dist/types/common/types.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +4 -3
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { v4 as uuid } from 'uuid';
|
|
2
|
-
import {
|
|
3
|
-
import { emitFinalFailure, handleRegistrationErrors } from '../../common';
|
|
4
|
-
import
|
|
2
|
+
import { METHOD_START_MESSAGE } from '../../common/constants';
|
|
3
|
+
import { emitFinalFailure, handleRegistrationErrors, uploadLogs } from '../../common';
|
|
4
|
+
import webWorkerStr from './webWorkerStr';
|
|
5
|
+
import { METRIC_EVENT, METRIC_TYPE, REG_ACTION, } from '../../Metrics/types';
|
|
5
6
|
import { getMetricManager } from '../../Metrics';
|
|
6
7
|
import { getCallManager } from '../calling';
|
|
7
8
|
import log from '../../Logger';
|
|
8
9
|
import SDKConnector from '../../SDKConnector';
|
|
9
|
-
import { ALLOWED_SERVICES, HTTP_METHODS, RegistrationStatus, ServiceIndicator, } from '../../common/types';
|
|
10
|
-
import { CALLING_USER_AGENT, CISCO_DEVICE_URL, DEVICES_ENDPOINT_RESOURCE, SPARK_USER_AGENT, WEBEX_WEB_CLIENT, BASE_REG_RETRY_TIMER_VAL_IN_SEC, BASE_REG_TIMER_MFACTOR, SEC_TO_MSEC_MFACTOR, REG_RANDOM_T_FACTOR_UPPER_LIMIT, REG_TRY_BACKUP_TIMER_VAL_IN_SEC, MINUTES_TO_SEC_MFACTOR,
|
|
10
|
+
import { ALLOWED_SERVICES, HTTP_METHODS, RegistrationStatus, ServiceIndicator, WorkerMessageType, } from '../../common/types';
|
|
11
|
+
import { CALLING_USER_AGENT, CISCO_DEVICE_URL, DEVICES_ENDPOINT_RESOURCE, SPARK_USER_AGENT, WEBEX_WEB_CLIENT, BASE_REG_RETRY_TIMER_VAL_IN_SEC, BASE_REG_TIMER_MFACTOR, SEC_TO_MSEC_MFACTOR, REG_RANDOM_T_FACTOR_UPPER_LIMIT, REG_TRY_BACKUP_TIMER_VAL_IN_SEC, MINUTES_TO_SEC_MFACTOR, REG_429_RETRY_UTIL, REG_FAILBACK_429_MAX_RETRIES, FAILBACK_UTIL, REGISTRATION_FILE, DEFAULT_REHOMING_INTERVAL_MIN, DEFAULT_REHOMING_INTERVAL_MAX, DEFAULT_KEEPALIVE_INTERVAL, REG_TRY_BACKUP_TIMER_VAL_FOR_CC_IN_SEC, FAILOVER_UTIL, REGISTER_UTIL, RETRY_TIMER_UPPER_LIMIT, KEEPALIVE_UTIL, REGISTRATION_UTIL, METHODS, } from '../constants';
|
|
11
12
|
import { LINE_EVENTS } from '../line/types';
|
|
12
13
|
export class Registration {
|
|
13
14
|
sdkConnector;
|
|
@@ -18,7 +19,6 @@ export class Registration {
|
|
|
18
19
|
registrationStatus;
|
|
19
20
|
failbackTimer;
|
|
20
21
|
activeMobiusUrl;
|
|
21
|
-
keepaliveTimer;
|
|
22
22
|
rehomingIntervalMin;
|
|
23
23
|
rehomingIntervalMax;
|
|
24
24
|
mutex;
|
|
@@ -33,6 +33,9 @@ export class Registration {
|
|
|
33
33
|
jwe;
|
|
34
34
|
isCCFlow = false;
|
|
35
35
|
failoverImmediately = false;
|
|
36
|
+
retryAfter;
|
|
37
|
+
scheduled429Retry = false;
|
|
38
|
+
webWorker;
|
|
36
39
|
constructor(webex, serviceData, mutex, lineEmitter, logLevel, jwe) {
|
|
37
40
|
this.jwe = jwe;
|
|
38
41
|
this.sdkConnector = SDKConnector;
|
|
@@ -59,25 +62,18 @@ export class Registration {
|
|
|
59
62
|
return this.activeMobiusUrl;
|
|
60
63
|
}
|
|
61
64
|
setActiveMobiusUrl(url) {
|
|
62
|
-
log.info(
|
|
65
|
+
log.info(`${METHOD_START_MESSAGE} with ${url}`, {
|
|
66
|
+
method: METHODS.UPDATE_ACTIVE_MOBIUS,
|
|
67
|
+
file: REGISTRATION_FILE,
|
|
68
|
+
});
|
|
63
69
|
this.activeMobiusUrl = url;
|
|
64
70
|
this.callManager.updateActiveMobius(url);
|
|
65
71
|
}
|
|
66
72
|
setMobiusServers(primaryMobiusUris, backupMobiusUris) {
|
|
73
|
+
log.log(METHOD_START_MESSAGE, { method: METHODS.SET_MOBIUS_SERVERS, file: REGISTRATION_FILE });
|
|
67
74
|
this.primaryMobiusUris = primaryMobiusUris;
|
|
68
75
|
this.backupMobiusUris = backupMobiusUris;
|
|
69
76
|
}
|
|
70
|
-
async postKeepAlive(url) {
|
|
71
|
-
return this.webex.request({
|
|
72
|
-
uri: `${url}/status`,
|
|
73
|
-
method: HTTP_METHODS.POST,
|
|
74
|
-
headers: {
|
|
75
|
-
[CISCO_DEVICE_URL]: this.webex.internal.device.url,
|
|
76
|
-
[SPARK_USER_AGENT]: CALLING_USER_AGENT,
|
|
77
|
-
},
|
|
78
|
-
service: ALLOWED_SERVICES.MOBIUS,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
77
|
async deleteRegistration(url, deviceId, deviceUrl) {
|
|
82
78
|
let response;
|
|
83
79
|
try {
|
|
@@ -92,7 +88,10 @@ export class Registration {
|
|
|
92
88
|
});
|
|
93
89
|
}
|
|
94
90
|
catch (error) {
|
|
95
|
-
log.warn(`Delete failed with Mobius`, {
|
|
91
|
+
log.warn(`Delete failed with Mobius ${error}`, {
|
|
92
|
+
file: REGISTRATION_FILE,
|
|
93
|
+
method: METHODS.DEREGISTER,
|
|
94
|
+
});
|
|
96
95
|
}
|
|
97
96
|
this.setStatus(RegistrationStatus.INACTIVE);
|
|
98
97
|
this.lineEmitter(LINE_EVENTS.UNREGISTERED);
|
|
@@ -122,21 +121,27 @@ export class Registration {
|
|
|
122
121
|
}
|
|
123
122
|
return abort;
|
|
124
123
|
}
|
|
125
|
-
async
|
|
126
|
-
if (
|
|
127
|
-
|
|
124
|
+
async handle429Retry(retryAfter, caller) {
|
|
125
|
+
if (caller === FAILBACK_UTIL) {
|
|
126
|
+
if (this.failback429RetryAttempts >= REG_FAILBACK_429_MAX_RETRIES) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
this.clearFailbackTimer();
|
|
130
|
+
this.failback429RetryAttempts += 1;
|
|
131
|
+
log.log(`Received 429 while rehoming, 429 retry count : ${this.failback429RetryAttempts}`, {
|
|
132
|
+
file: REGISTRATION_FILE,
|
|
133
|
+
method: REG_429_RETRY_UTIL,
|
|
134
|
+
});
|
|
135
|
+
const interval = this.getRegRetryInterval(this.failback429RetryAttempts);
|
|
136
|
+
this.startFailbackTimer(interval);
|
|
137
|
+
this.scheduled429Retry = true;
|
|
138
|
+
const abort = await this.restorePreviousRegistration(REG_429_RETRY_UTIL);
|
|
139
|
+
if (!abort && !this.isDeviceRegistered()) {
|
|
140
|
+
await this.restartRegistration(REG_429_RETRY_UTIL);
|
|
141
|
+
}
|
|
128
142
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
log.log(`Received 429 while rehoming, 429 retry count : ${this.failback429RetryAttempts}`, {
|
|
132
|
-
file: REGISTRATION_FILE,
|
|
133
|
-
method: FAILBACK_429_RETRY_UTIL,
|
|
134
|
-
});
|
|
135
|
-
const interval = this.getRegRetryInterval(this.failback429RetryAttempts);
|
|
136
|
-
this.startFailbackTimer(interval);
|
|
137
|
-
const abort = await this.restorePreviousRegistration(FAILBACK_429_RETRY_UTIL);
|
|
138
|
-
if (!abort && !this.isDeviceRegistered()) {
|
|
139
|
-
await this.restartRegistration(FAILBACK_429_RETRY_UTIL);
|
|
143
|
+
else {
|
|
144
|
+
this.retryAfter = retryAfter;
|
|
140
145
|
}
|
|
141
146
|
}
|
|
142
147
|
getRegRetryInterval(attempt = 1) {
|
|
@@ -149,7 +154,7 @@ export class Registration {
|
|
|
149
154
|
async startFailoverTimer(attempt = 1, timeElapsed = 0) {
|
|
150
155
|
const loggerContext = {
|
|
151
156
|
file: REGISTRATION_FILE,
|
|
152
|
-
method:
|
|
157
|
+
method: FAILOVER_UTIL,
|
|
153
158
|
};
|
|
154
159
|
let interval = this.getRegRetryInterval(attempt);
|
|
155
160
|
const TIMER_THRESHOLD = this.isCCFlow
|
|
@@ -159,12 +164,18 @@ export class Registration {
|
|
|
159
164
|
const excessVal = timeElapsed + interval - TIMER_THRESHOLD;
|
|
160
165
|
interval -= excessVal;
|
|
161
166
|
}
|
|
167
|
+
if (this.retryAfter != null && interval < this.retryAfter) {
|
|
168
|
+
this.failoverImmediately = this.retryAfter + timeElapsed > TIMER_THRESHOLD;
|
|
169
|
+
}
|
|
162
170
|
let abort;
|
|
163
171
|
if (interval > BASE_REG_RETRY_TIMER_VAL_IN_SEC && !this.failoverImmediately) {
|
|
164
172
|
const scheduledTime = Math.floor(Date.now() / 1000);
|
|
173
|
+
if (this.retryAfter != null) {
|
|
174
|
+
interval = Math.max(interval, this.retryAfter);
|
|
175
|
+
}
|
|
165
176
|
setTimeout(async () => {
|
|
166
177
|
await this.mutex.runExclusive(async () => {
|
|
167
|
-
abort = await this.attemptRegistrationWithServers(
|
|
178
|
+
abort = await this.attemptRegistrationWithServers(FAILOVER_UTIL);
|
|
168
179
|
const currentTime = Math.floor(Date.now() / 1000);
|
|
169
180
|
if (!abort && !this.isDeviceRegistered()) {
|
|
170
181
|
await this.startFailoverTimer(attempt + 1, timeElapsed + (currentTime - scheduledTime));
|
|
@@ -174,15 +185,19 @@ export class Registration {
|
|
|
174
185
|
log.log(`Scheduled retry with primary in ${interval} seconds, number of attempts : ${attempt}`, loggerContext);
|
|
175
186
|
}
|
|
176
187
|
else if (this.backupMobiusUris.length) {
|
|
177
|
-
log.
|
|
188
|
+
log.info('Failing over to backup servers.', loggerContext);
|
|
178
189
|
this.failoverImmediately = false;
|
|
179
|
-
abort = await this.attemptRegistrationWithServers(
|
|
190
|
+
abort = await this.attemptRegistrationWithServers(FAILOVER_UTIL, this.backupMobiusUris);
|
|
180
191
|
if (!abort && !this.isDeviceRegistered()) {
|
|
181
192
|
interval = this.getRegRetryInterval();
|
|
193
|
+
if (this.retryAfter != null && this.retryAfter < RETRY_TIMER_UPPER_LIMIT) {
|
|
194
|
+
interval = interval < this.retryAfter ? this.retryAfter : interval;
|
|
195
|
+
}
|
|
182
196
|
setTimeout(async () => {
|
|
183
197
|
await this.mutex.runExclusive(async () => {
|
|
184
|
-
abort = await this.attemptRegistrationWithServers(
|
|
198
|
+
abort = await this.attemptRegistrationWithServers(FAILOVER_UTIL, this.backupMobiusUris);
|
|
185
199
|
if (!abort && !this.isDeviceRegistered()) {
|
|
200
|
+
await uploadLogs();
|
|
186
201
|
emitFinalFailure((clientError) => {
|
|
187
202
|
this.lineEmitter(LINE_EVENTS.ERROR, undefined, clientError);
|
|
188
203
|
}, loggerContext);
|
|
@@ -193,6 +208,7 @@ export class Registration {
|
|
|
193
208
|
}
|
|
194
209
|
}
|
|
195
210
|
else {
|
|
211
|
+
await uploadLogs();
|
|
196
212
|
emitFinalFailure((clientError) => {
|
|
197
213
|
this.lineEmitter(LINE_EVENTS.ERROR, undefined, clientError);
|
|
198
214
|
}, loggerContext);
|
|
@@ -241,19 +257,20 @@ export class Registration {
|
|
|
241
257
|
});
|
|
242
258
|
await this.deregister();
|
|
243
259
|
const abort = await this.attemptRegistrationWithServers(FAILBACK_UTIL);
|
|
244
|
-
if (
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
260
|
+
if (this.scheduled429Retry || abort || this.isDeviceRegistered()) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const abortNew = await this.restorePreviousRegistration(FAILBACK_UTIL);
|
|
264
|
+
if (abortNew) {
|
|
265
|
+
this.clearFailbackTimer();
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (!this.isDeviceRegistered()) {
|
|
269
|
+
await this.restartRegistration(this.executeFailback.name);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
this.failbackTimer = undefined;
|
|
273
|
+
this.initiateFailback();
|
|
257
274
|
}
|
|
258
275
|
}
|
|
259
276
|
else {
|
|
@@ -298,9 +315,13 @@ export class Registration {
|
|
|
298
315
|
}
|
|
299
316
|
}
|
|
300
317
|
async handleConnectionRestoration(retry) {
|
|
318
|
+
log.info(METHOD_START_MESSAGE, {
|
|
319
|
+
method: METHODS.HANDLE_CONNECTION_RESTORATION,
|
|
320
|
+
file: REGISTRATION_FILE,
|
|
321
|
+
});
|
|
301
322
|
await this.mutex.runExclusive(async () => {
|
|
302
323
|
if (retry) {
|
|
303
|
-
log.
|
|
324
|
+
log.log('Mercury connection is up again, re-registering with Webex Calling if needed', {
|
|
304
325
|
file: REGISTRATION_FILE,
|
|
305
326
|
method: this.handleConnectionRestoration.name,
|
|
306
327
|
});
|
|
@@ -345,7 +366,7 @@ export class Registration {
|
|
|
345
366
|
}
|
|
346
367
|
async triggerRegistration() {
|
|
347
368
|
if (this.primaryMobiusUris.length > 0) {
|
|
348
|
-
const abort = await this.attemptRegistrationWithServers(
|
|
369
|
+
const abort = await this.attemptRegistrationWithServers(REGISTRATION_UTIL, this.primaryMobiusUris);
|
|
349
370
|
if (!this.isDeviceRegistered() && !abort) {
|
|
350
371
|
await this.startFailoverTimer();
|
|
351
372
|
}
|
|
@@ -353,34 +374,42 @@ export class Registration {
|
|
|
353
374
|
}
|
|
354
375
|
async attemptRegistrationWithServers(caller, servers = this.primaryMobiusUris) {
|
|
355
376
|
let abort = false;
|
|
377
|
+
this.retryAfter = undefined;
|
|
356
378
|
if (this.failoverImmediately) {
|
|
357
379
|
return abort;
|
|
358
380
|
}
|
|
359
381
|
if (this.isDeviceRegistered()) {
|
|
360
|
-
log.
|
|
382
|
+
log.info(`[${caller}] : Device already registered with : ${this.activeMobiusUrl}`, {
|
|
361
383
|
file: REGISTRATION_FILE,
|
|
362
|
-
method:
|
|
384
|
+
method: REGISTER_UTIL,
|
|
363
385
|
});
|
|
364
386
|
return abort;
|
|
365
387
|
}
|
|
366
388
|
for (const url of servers) {
|
|
389
|
+
const serverType = (this.primaryMobiusUris.includes(url) && 'PRIMARY') ||
|
|
390
|
+
(this.backupMobiusUris?.includes(url) && 'BACKUP') ||
|
|
391
|
+
'UNKNOWN';
|
|
367
392
|
try {
|
|
368
393
|
abort = false;
|
|
369
394
|
this.registrationStatus = RegistrationStatus.INACTIVE;
|
|
370
395
|
this.lineEmitter(LINE_EVENTS.CONNECTING);
|
|
371
|
-
log.
|
|
396
|
+
log.info(`[${caller}] : Mobius url to contact: ${url}`, {
|
|
372
397
|
file: REGISTRATION_FILE,
|
|
373
|
-
method:
|
|
398
|
+
method: REGISTER_UTIL,
|
|
374
399
|
});
|
|
375
400
|
const resp = await this.postRegistration(url);
|
|
376
401
|
this.deviceInfo = resp.body;
|
|
377
402
|
this.registrationStatus = RegistrationStatus.ACTIVE;
|
|
378
403
|
this.lineEmitter(LINE_EVENTS.REGISTERED, resp.body);
|
|
404
|
+
log.log(`Registration successful for deviceId: ${this.deviceInfo.device?.deviceId} userId: ${this.userId}`, {
|
|
405
|
+
file: REGISTRATION_FILE,
|
|
406
|
+
method: METHODS.REGISTER,
|
|
407
|
+
});
|
|
379
408
|
this.setActiveMobiusUrl(url);
|
|
380
409
|
this.setIntervalValues(this.deviceInfo);
|
|
381
410
|
this.metricManager.setDeviceInfo(this.deviceInfo);
|
|
382
|
-
this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION, REG_ACTION.REGISTER, METRIC_TYPE.BEHAVIORAL, undefined);
|
|
383
|
-
this.startKeepaliveTimer(this.deviceInfo.device?.uri, this.deviceInfo.keepaliveInterval);
|
|
411
|
+
this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION, REG_ACTION.REGISTER, METRIC_TYPE.BEHAVIORAL, caller, serverType, resp.headers?.trackingid ?? '', undefined, undefined);
|
|
412
|
+
this.startKeepaliveTimer(this.deviceInfo.device?.uri, this.deviceInfo.keepaliveInterval, serverType);
|
|
384
413
|
this.initiateFailback();
|
|
385
414
|
break;
|
|
386
415
|
}
|
|
@@ -393,8 +422,8 @@ export class Registration {
|
|
|
393
422
|
else {
|
|
394
423
|
this.lineEmitter(LINE_EVENTS.UNREGISTERED);
|
|
395
424
|
}
|
|
396
|
-
this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION_ERROR, REG_ACTION.REGISTER, METRIC_TYPE.BEHAVIORAL, clientError);
|
|
397
|
-
}, { method:
|
|
425
|
+
this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION_ERROR, REG_ACTION.REGISTER, METRIC_TYPE.BEHAVIORAL, caller, serverType, body.headers?.trackingid ?? '', undefined, clientError);
|
|
426
|
+
}, { method: caller, file: REGISTRATION_FILE }, (retryAfter, retryCaller) => this.handle429Retry(retryAfter, retryCaller), this.restoreRegistrationCallBack());
|
|
398
427
|
if (this.registrationStatus === RegistrationStatus.ACTIVE) {
|
|
399
428
|
log.info(`[${caller}] : Device is already restored, active mobius url: ${this.activeMobiusUrl}`, {
|
|
400
429
|
file: REGISTRATION_FILE,
|
|
@@ -406,69 +435,71 @@ export class Registration {
|
|
|
406
435
|
this.setStatus(RegistrationStatus.INACTIVE);
|
|
407
436
|
break;
|
|
408
437
|
}
|
|
409
|
-
else if (caller === this.executeFailback.name) {
|
|
410
|
-
const error = body.statusCode;
|
|
411
|
-
if (error === ERROR_CODE.TOO_MANY_REQUESTS) {
|
|
412
|
-
await this.scheduleFailback429Retry();
|
|
413
|
-
abort = true;
|
|
414
|
-
break;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
438
|
}
|
|
418
439
|
}
|
|
419
440
|
return abort;
|
|
420
441
|
}
|
|
421
|
-
startKeepaliveTimer(url, interval) {
|
|
422
|
-
let keepAliveRetryCount = 0;
|
|
442
|
+
async startKeepaliveTimer(url, interval, serverType) {
|
|
423
443
|
this.clearKeepaliveTimer();
|
|
424
444
|
const RETRY_COUNT_THRESHOLD = this.isCCFlow ? 4 : 5;
|
|
425
|
-
this.
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
445
|
+
await this.mutex.runExclusive(async () => {
|
|
446
|
+
if (this.isDeviceRegistered()) {
|
|
447
|
+
const accessToken = await this.webex.credentials.getUserToken();
|
|
448
|
+
if (!this.webWorker) {
|
|
449
|
+
const blob = new Blob([webWorkerStr], { type: 'application/javascript' });
|
|
450
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
451
|
+
this.webWorker = new Worker(blobUrl);
|
|
452
|
+
URL.revokeObjectURL(blobUrl);
|
|
453
|
+
this.webWorker.postMessage({
|
|
454
|
+
type: WorkerMessageType.START_KEEPALIVE,
|
|
455
|
+
accessToken: String(accessToken),
|
|
456
|
+
deviceUrl: String(this.webex.internal.device.url),
|
|
457
|
+
interval,
|
|
458
|
+
retryCountThreshold: RETRY_COUNT_THRESHOLD,
|
|
459
|
+
url,
|
|
460
|
+
});
|
|
461
|
+
this.webWorker.onmessage = async (event) => {
|
|
462
|
+
const logContext = {
|
|
463
|
+
file: REGISTRATION_FILE,
|
|
464
|
+
method: this.startKeepaliveTimer.name,
|
|
465
|
+
};
|
|
466
|
+
if (event.data.type === WorkerMessageType.KEEPALIVE_SUCCESS) {
|
|
467
|
+
log.info(`Sent Keepalive, status: ${event.data.statusCode}`, logContext);
|
|
436
468
|
this.lineEmitter(LINE_EVENTS.RECONNECTED);
|
|
437
469
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
470
|
+
if (event.data.type === WorkerMessageType.KEEPALIVE_FAILURE) {
|
|
471
|
+
const error = event.data.err;
|
|
472
|
+
log.warn(`Keep-alive missed ${event.data.keepAliveRetryCount} times. Status -> ${error.statusCode} `, logContext);
|
|
473
|
+
const abort = await handleRegistrationErrors(error, (clientError, finalError) => {
|
|
474
|
+
if (finalError) {
|
|
475
|
+
this.lineEmitter(LINE_EVENTS.ERROR, undefined, clientError);
|
|
476
|
+
}
|
|
477
|
+
this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION, REG_ACTION.KEEPALIVE_FAILURE, METRIC_TYPE.BEHAVIORAL, KEEPALIVE_UTIL, serverType, error.headers?.trackingid ?? '', event.data.keepAliveRetryCount, clientError);
|
|
478
|
+
}, { method: KEEPALIVE_UTIL, file: REGISTRATION_FILE });
|
|
479
|
+
if (abort || event.data.keepAliveRetryCount >= RETRY_COUNT_THRESHOLD) {
|
|
480
|
+
this.failoverImmediately = this.isCCFlow;
|
|
481
|
+
this.setStatus(RegistrationStatus.INACTIVE);
|
|
482
|
+
this.clearKeepaliveTimer();
|
|
483
|
+
this.clearFailbackTimer();
|
|
484
|
+
this.lineEmitter(LINE_EVENTS.UNREGISTERED);
|
|
485
|
+
if (!abort) {
|
|
486
|
+
await this.reconnectOnFailure(KEEPALIVE_UTIL);
|
|
487
|
+
}
|
|
447
488
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
if (abort || keepAliveRetryCount >= RETRY_COUNT_THRESHOLD) {
|
|
451
|
-
this.failoverImmediately = this.isCCFlow;
|
|
452
|
-
this.setStatus(RegistrationStatus.INACTIVE);
|
|
453
|
-
this.clearKeepaliveTimer();
|
|
454
|
-
this.clearFailbackTimer();
|
|
455
|
-
this.lineEmitter(LINE_EVENTS.UNREGISTERED);
|
|
456
|
-
if (!abort) {
|
|
457
|
-
await this.reconnectOnFailure(this.startKeepaliveTimer.name);
|
|
489
|
+
else {
|
|
490
|
+
this.lineEmitter(LINE_EVENTS.RECONNECTING);
|
|
458
491
|
}
|
|
459
492
|
}
|
|
460
|
-
|
|
461
|
-
this.lineEmitter(LINE_EVENTS.RECONNECTING);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
493
|
+
};
|
|
464
494
|
}
|
|
465
|
-
}
|
|
466
|
-
}
|
|
495
|
+
}
|
|
496
|
+
});
|
|
467
497
|
}
|
|
468
498
|
clearKeepaliveTimer() {
|
|
469
|
-
if (this.
|
|
470
|
-
|
|
471
|
-
this.
|
|
499
|
+
if (this.webWorker) {
|
|
500
|
+
this.webWorker.postMessage({ type: WorkerMessageType.CLEAR_KEEPALIVE });
|
|
501
|
+
this.webWorker.terminate();
|
|
502
|
+
this.webWorker = undefined;
|
|
472
503
|
}
|
|
473
504
|
}
|
|
474
505
|
isReconnectPending() {
|
|
@@ -477,9 +508,16 @@ export class Registration {
|
|
|
477
508
|
async deregister() {
|
|
478
509
|
try {
|
|
479
510
|
await this.deleteRegistration(this.activeMobiusUrl, this.deviceInfo.device?.deviceId, this.deviceInfo.device?.clientDeviceUri);
|
|
511
|
+
log.log('Registration successfully deregistered', {
|
|
512
|
+
file: REGISTRATION_FILE,
|
|
513
|
+
method: METHODS.DEREGISTER,
|
|
514
|
+
});
|
|
480
515
|
}
|
|
481
516
|
catch (err) {
|
|
482
|
-
log.warn(`Delete failed with Mobius`, {
|
|
517
|
+
log.warn(`Delete failed with Mobius: ${err}`, {
|
|
518
|
+
file: REGISTRATION_FILE,
|
|
519
|
+
method: METHODS.DEREGISTER,
|
|
520
|
+
});
|
|
483
521
|
}
|
|
484
522
|
this.clearKeepaliveTimer();
|
|
485
523
|
this.setStatus(RegistrationStatus.INACTIVE);
|
|
@@ -508,6 +546,7 @@ export class Registration {
|
|
|
508
546
|
return false;
|
|
509
547
|
}
|
|
510
548
|
async reconnectOnFailure(caller) {
|
|
549
|
+
log.info(METHOD_START_MESSAGE, { method: METHODS.RECONNECT_ON_FAILURE, file: REGISTRATION_FILE });
|
|
511
550
|
this.reconnectPending = false;
|
|
512
551
|
if (!this.isDeviceRegistered()) {
|
|
513
552
|
if (Object.keys(this.callManager.getActiveCalls()).length === 0) {
|
|
@@ -520,7 +559,7 @@ export class Registration {
|
|
|
520
559
|
this.reconnectPending = true;
|
|
521
560
|
log.info('Active call(s) present, deferred reconnect till call cleanup.', {
|
|
522
561
|
file: REGISTRATION_FILE,
|
|
523
|
-
method:
|
|
562
|
+
method: METHODS.RECONNECT_ON_FAILURE,
|
|
524
563
|
});
|
|
525
564
|
}
|
|
526
565
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { v4 as uuid } from 'uuid';
|
|
2
|
+
import { HTTP_METHODS, WorkerMessageType } from '../../common/types';
|
|
3
|
+
let keepaliveTimer;
|
|
4
|
+
export const messageHandler = (event) => {
|
|
5
|
+
const { type } = event.data;
|
|
6
|
+
const postKeepAlive = async (accessToken, deviceUrl, url) => {
|
|
7
|
+
const response = await fetch(`${url}/status`, {
|
|
8
|
+
method: HTTP_METHODS.POST,
|
|
9
|
+
headers: {
|
|
10
|
+
'cisco-device-url': deviceUrl,
|
|
11
|
+
'spark-user-agent': 'webex-calling/beta',
|
|
12
|
+
Authorization: `${accessToken}`,
|
|
13
|
+
trackingId: `web_worker_${uuid()}`,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
if (!response.ok) {
|
|
17
|
+
throw new Error(`Keepalive failed with status: ${response.status}`);
|
|
18
|
+
}
|
|
19
|
+
return response;
|
|
20
|
+
};
|
|
21
|
+
if (type === WorkerMessageType.START_KEEPALIVE) {
|
|
22
|
+
let keepAliveRetryCount = 0;
|
|
23
|
+
const { accessToken, deviceUrl, interval, retryCountThreshold, url } = event.data;
|
|
24
|
+
if (keepaliveTimer) {
|
|
25
|
+
clearInterval(keepaliveTimer);
|
|
26
|
+
keepaliveTimer = undefined;
|
|
27
|
+
}
|
|
28
|
+
keepaliveTimer = setInterval(async () => {
|
|
29
|
+
if (keepAliveRetryCount < retryCountThreshold) {
|
|
30
|
+
try {
|
|
31
|
+
const res = await postKeepAlive(accessToken, deviceUrl, url);
|
|
32
|
+
const statusCode = res.status;
|
|
33
|
+
if (keepAliveRetryCount > 0) {
|
|
34
|
+
postMessage({
|
|
35
|
+
type: WorkerMessageType.KEEPALIVE_SUCCESS,
|
|
36
|
+
statusCode,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
keepAliveRetryCount = 0;
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
keepAliveRetryCount += 1;
|
|
43
|
+
postMessage({
|
|
44
|
+
type: WorkerMessageType.KEEPALIVE_FAILURE,
|
|
45
|
+
err,
|
|
46
|
+
keepAliveRetryCount,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, interval * 1000);
|
|
51
|
+
}
|
|
52
|
+
if (type === WorkerMessageType.CLEAR_KEEPALIVE) {
|
|
53
|
+
if (keepaliveTimer) {
|
|
54
|
+
clearInterval(keepaliveTimer);
|
|
55
|
+
keepaliveTimer = undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
self.addEventListener('message', messageHandler);
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const webWorkerStr = `/* eslint-env worker */
|
|
2
|
+
|
|
3
|
+
const uuid = () => {
|
|
4
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
5
|
+
const r = (Math.random() * 16) | 0;
|
|
6
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
7
|
+
return v.toString(16);
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// Enum values from the original imports
|
|
12
|
+
const HTTP_METHODS = {
|
|
13
|
+
GET: 'GET',
|
|
14
|
+
POST: 'POST',
|
|
15
|
+
PUT: 'PUT',
|
|
16
|
+
DELETE: 'DELETE',
|
|
17
|
+
PATCH: 'PATCH',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const WorkerMessageType = {
|
|
21
|
+
START_KEEPALIVE: 'START_KEEPALIVE',
|
|
22
|
+
CLEAR_KEEPALIVE: 'CLEAR_KEEPALIVE',
|
|
23
|
+
KEEPALIVE_SUCCESS: 'KEEPALIVE_SUCCESS',
|
|
24
|
+
KEEPALIVE_FAILURE: 'KEEPALIVE_FAILURE',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
let keepaliveTimer;
|
|
28
|
+
|
|
29
|
+
const messageHandler = (event) => {
|
|
30
|
+
const {type} = event.data;
|
|
31
|
+
|
|
32
|
+
const postKeepAlive = async (accessToken, deviceUrl, url) => {
|
|
33
|
+
const response = await fetch(\`\${url}/status\`, {
|
|
34
|
+
method: HTTP_METHODS.POST,
|
|
35
|
+
headers: {
|
|
36
|
+
'cisco-device-url': deviceUrl,
|
|
37
|
+
'spark-user-agent': 'webex-calling/beta',
|
|
38
|
+
Authorization: \`\${accessToken}\`,
|
|
39
|
+
trackingId: \`web_worker_\${uuid()}\`,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
throw new Error(\`Keepalive failed with status: \${response.status}\`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return response;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
if (type === WorkerMessageType.START_KEEPALIVE) {
|
|
51
|
+
let keepAliveRetryCount = 0;
|
|
52
|
+
const {accessToken, deviceUrl, interval, retryCountThreshold, url} = event.data;
|
|
53
|
+
|
|
54
|
+
if (keepaliveTimer) {
|
|
55
|
+
clearInterval(keepaliveTimer);
|
|
56
|
+
keepaliveTimer = undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
keepaliveTimer = setInterval(async () => {
|
|
60
|
+
if (keepAliveRetryCount < retryCountThreshold) {
|
|
61
|
+
try {
|
|
62
|
+
const res = await postKeepAlive(accessToken, deviceUrl, url);
|
|
63
|
+
const statusCode = res.status;
|
|
64
|
+
if (keepAliveRetryCount > 0) {
|
|
65
|
+
self.postMessage({
|
|
66
|
+
type: WorkerMessageType.KEEPALIVE_SUCCESS,
|
|
67
|
+
statusCode,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
keepAliveRetryCount = 0;
|
|
71
|
+
} catch (err) {
|
|
72
|
+
keepAliveRetryCount += 1;
|
|
73
|
+
self.postMessage({
|
|
74
|
+
type: WorkerMessageType.KEEPALIVE_FAILURE,
|
|
75
|
+
err,
|
|
76
|
+
keepAliveRetryCount,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}, interval * 1000);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (type === WorkerMessageType.CLEAR_KEEPALIVE) {
|
|
84
|
+
if (keepaliveTimer) {
|
|
85
|
+
clearInterval(keepaliveTimer);
|
|
86
|
+
keepaliveTimer = undefined;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
self.addEventListener('message', messageHandler);
|
|
92
|
+
`;
|
|
93
|
+
export default webWorkerStr;
|