genesys-cloud-streaming-client 17.0.2-develop.83 → 17.0.2-develop.88
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/LICENSE +1 -1
- package/dist/cjs/client.d.ts +7 -0
- package/dist/cjs/client.js +85 -8
- package/dist/cjs/types/interfaces.d.ts +6 -0
- package/dist/cjs/utils.d.ts +1 -0
- package/dist/cjs/utils.js +9 -3
- package/dist/deploy-info.json +2 -2
- package/dist/es/client.d.ts +7 -0
- package/dist/es/client.js +86 -9
- package/dist/es/index.bundle.js +15387 -18815
- package/dist/es/types/interfaces.d.ts +6 -0
- package/dist/es/utils.d.ts +1 -0
- package/dist/es/utils.js +7 -2
- package/dist/npm/CHANGELOG.md +6 -0
- package/dist/npm/client.d.ts +7 -0
- package/dist/npm/client.js +85 -8
- package/dist/npm/types/interfaces.d.ts +6 -0
- package/dist/npm/utils.d.ts +1 -0
- package/dist/npm/utils.js +9 -3
- package/dist/streaming-client.browser.ie.js +11 -4
- package/dist/streaming-client.browser.js +13 -21
- package/dist/v17/streaming-client.browser.ie.js +11 -4
- package/dist/v17/streaming-client.browser.js +13 -21
- package/dist/v17.0.2/streaming-client.browser.ie.js +11 -4
- package/dist/v17.0.2/streaming-client.browser.js +13 -21
- package/package.json +4 -4
|
@@ -247,3 +247,9 @@ export declare type MediaStat = InsightAction<{
|
|
|
247
247
|
elapsedMsFromInitialRequest?: number;
|
|
248
248
|
}>;
|
|
249
249
|
export declare type NRProxyStat = FirstAlertingConversationStat | MediaStat;
|
|
250
|
+
export declare type SCConnectionData = {
|
|
251
|
+
currentDelayMs: number;
|
|
252
|
+
delayMsAfterNextReduction?: number;
|
|
253
|
+
nextDelayReductionTime?: number;
|
|
254
|
+
timeOfTotalReset?: number;
|
|
255
|
+
};
|
package/dist/es/utils.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare function timeoutPromise(fn: Function, timeoutMs: number, msg: string, details?: any): Promise<any>;
|
|
2
|
+
export declare function delay(ms: number): Promise<void>;
|
|
2
3
|
export declare function splitIntoIndividualTopics(topicString: string): string[];
|
|
3
4
|
export declare const isAcdJid: (jid: string) => boolean;
|
|
4
5
|
export declare const isScreenRecordingJid: (jid: string) => boolean;
|
package/dist/es/utils.js
CHANGED
|
@@ -16,6 +16,11 @@ export function timeoutPromise(fn, timeoutMs, msg, details) {
|
|
|
16
16
|
fn(done, reject);
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
+
export function delay(ms) {
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
setTimeout(resolve, ms);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
19
24
|
export function splitIntoIndividualTopics(topicString) {
|
|
20
25
|
const topics = [];
|
|
21
26
|
if (topicString.includes('?')) {
|
|
@@ -34,10 +39,10 @@ export function splitIntoIndividualTopics(topicString) {
|
|
|
34
39
|
return topics;
|
|
35
40
|
}
|
|
36
41
|
export const isAcdJid = function (jid) {
|
|
37
|
-
return jid.startsWith('acd-');
|
|
42
|
+
return jid.startsWith('acd-') && !isSoftphoneJid(jid);
|
|
38
43
|
};
|
|
39
44
|
export const isScreenRecordingJid = function (jid) {
|
|
40
|
-
return jid.startsWith('screenrecording-');
|
|
45
|
+
return jid.startsWith('screenrecording-') && !isSoftphoneJid(jid);
|
|
41
46
|
};
|
|
42
47
|
export const isSoftphoneJid = function (jid) {
|
|
43
48
|
if (!jid) {
|
package/dist/npm/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
7
|
# [Unreleased](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/v17.0.1...HEAD)
|
|
8
|
+
### Changed
|
|
9
|
+
* [PCM-2312](https://inindca.atlassian.net/browse/PCM-2312) bump logger version
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
* [PCM-2304](https://inindca.atlassian.net/browse/PCM-2304) Made connection backoff semi-persistent through the sessionStore. Updated stanza to circumvent browser intensive throttling on connection attempts.
|
|
13
|
+
* [PCM-2314](https://inindca.atlassian.net/browse/PCM-2314) Fix softphone calls with users' emails beginning with "acd-"
|
|
8
14
|
|
|
9
15
|
# [v17.0.1](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/v17.0.0...v17.0.1)
|
|
10
16
|
### Added
|
package/dist/npm/client.d.ts
CHANGED
|
@@ -24,6 +24,8 @@ export declare class Client extends EventEmitter {
|
|
|
24
24
|
private extensions;
|
|
25
25
|
private connectionManager;
|
|
26
26
|
private channelReuses;
|
|
27
|
+
private backoffReductionTimer;
|
|
28
|
+
private hasMadeInitialAttempt;
|
|
27
29
|
private boundStanzaDisconnect?;
|
|
28
30
|
private boundStanzaNoLongerSubscribed?;
|
|
29
31
|
private boundStanzaDuplicateId?;
|
|
@@ -45,6 +47,11 @@ export declare class Client extends EventEmitter {
|
|
|
45
47
|
private handleNoLongerSubscribed;
|
|
46
48
|
private handleDuplicateId;
|
|
47
49
|
disconnect(): Promise<any>;
|
|
50
|
+
private getConnectionData;
|
|
51
|
+
private setConnectionData;
|
|
52
|
+
private increaseBackoff;
|
|
53
|
+
private decreaseBackoff;
|
|
54
|
+
private getStartingDelay;
|
|
48
55
|
connect(connectOpts?: StreamingClientConnectOptions): Promise<void>;
|
|
49
56
|
private backoffConnectRetryHandler;
|
|
50
57
|
private makeConnectionAttempt;
|
package/dist/npm/client.js
CHANGED
|
@@ -26,6 +26,9 @@ const STANZA_DISCONNECTED = 'stanzaDisconnected';
|
|
|
26
26
|
const NO_LONGER_SUBSCRIBED = 'notify:no_longer_subscribed';
|
|
27
27
|
const DUPLICATE_ID = 'notify:duplicate_id';
|
|
28
28
|
const MAX_CHANNEL_REUSES = 10;
|
|
29
|
+
const SESSION_STORE_KEY = 'sc_connectionData';
|
|
30
|
+
const BACKOFF_DECREASE_DELAY_MULTIPLIER = 5;
|
|
31
|
+
const INITIAL_DELAY = 2000;
|
|
29
32
|
class Client extends events_1.default {
|
|
30
33
|
constructor(options) {
|
|
31
34
|
super();
|
|
@@ -37,6 +40,7 @@ class Client extends events_1.default {
|
|
|
37
40
|
this.autoReconnect = true;
|
|
38
41
|
this.extensions = [];
|
|
39
42
|
this.channelReuses = 0;
|
|
43
|
+
this.hasMadeInitialAttempt = false;
|
|
40
44
|
this.http = new http_client_1.HttpClient();
|
|
41
45
|
this.reconnectOnNoLongerSubscribed = options.reconnectOnNoLongerSubscribed !== false;
|
|
42
46
|
this.config = {
|
|
@@ -213,6 +217,64 @@ class Client extends events_1.default {
|
|
|
213
217
|
.then(resolve);
|
|
214
218
|
}, 5000, 'disconnecting streaming service');
|
|
215
219
|
}
|
|
220
|
+
getConnectionData() {
|
|
221
|
+
const connectionDataStr = sessionStorage.getItem(SESSION_STORE_KEY);
|
|
222
|
+
const defaultValue = {
|
|
223
|
+
currentDelayMs: 0,
|
|
224
|
+
};
|
|
225
|
+
if (connectionDataStr) {
|
|
226
|
+
try {
|
|
227
|
+
return JSON.parse(connectionDataStr);
|
|
228
|
+
}
|
|
229
|
+
catch (e) {
|
|
230
|
+
this.logger.warn('failed to parse streaming client connection data');
|
|
231
|
+
return defaultValue;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return defaultValue;
|
|
235
|
+
}
|
|
236
|
+
setConnectionData(data) {
|
|
237
|
+
sessionStorage.setItem(SESSION_STORE_KEY, JSON.stringify(data));
|
|
238
|
+
}
|
|
239
|
+
increaseBackoff() {
|
|
240
|
+
const connectionData = this.getConnectionData();
|
|
241
|
+
const currentDelay = Math.max(connectionData.currentDelayMs * 2, INITIAL_DELAY);
|
|
242
|
+
this.setConnectionData({
|
|
243
|
+
currentDelayMs: currentDelay,
|
|
244
|
+
delayMsAfterNextReduction: currentDelay / 2,
|
|
245
|
+
nextDelayReductionTime: new Date().getTime() + (currentDelay * BACKOFF_DECREASE_DELAY_MULTIPLIER),
|
|
246
|
+
timeOfTotalReset: new Date().getTime() + 1000 * 60 * 60 // one hour in the future
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
decreaseBackoff(newAmountMs) {
|
|
250
|
+
const data = this.getConnectionData();
|
|
251
|
+
const msUntilNextReduction = newAmountMs * BACKOFF_DECREASE_DELAY_MULTIPLIER;
|
|
252
|
+
const newConnectionData = {
|
|
253
|
+
currentDelayMs: newAmountMs,
|
|
254
|
+
delayMsAfterNextReduction: newAmountMs / 2,
|
|
255
|
+
nextDelayReductionTime: new Date().getTime() + (msUntilNextReduction),
|
|
256
|
+
timeOfTotalReset: data.timeOfTotalReset
|
|
257
|
+
};
|
|
258
|
+
// if we are past the total reset time, do that instead
|
|
259
|
+
if (data.timeOfTotalReset && data.timeOfTotalReset < new Date().getTime() || newAmountMs < INITIAL_DELAY) {
|
|
260
|
+
this.logger.debug('decreaseBackoff() called, but timeOfTotalReset has elasped or next delay is below 2s. Resetting backoff');
|
|
261
|
+
return this.setConnectionData({
|
|
262
|
+
currentDelayMs: 0
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
this.setConnectionData(newConnectionData);
|
|
266
|
+
clearTimeout(this.backoffReductionTimer);
|
|
267
|
+
this.logger.debug('Setting timer for next backoff reduction since we haven\'t reached total reset', { msUntilReduction: msUntilNextReduction, delayMsAfterNextReduction: newConnectionData.delayMsAfterNextReduction });
|
|
268
|
+
this.backoffReductionTimer = setTimeout(() => this.decreaseBackoff(newConnectionData.delayMsAfterNextReduction), msUntilNextReduction);
|
|
269
|
+
}
|
|
270
|
+
getStartingDelay(connectionData, maxDelay) {
|
|
271
|
+
// we don't want the delay to ever be less than 2 seconds
|
|
272
|
+
const minDelay = Math.max(connectionData.currentDelayMs, INITIAL_DELAY);
|
|
273
|
+
if (connectionData.timeOfTotalReset && connectionData.timeOfTotalReset < new Date().getTime()) {
|
|
274
|
+
return INITIAL_DELAY;
|
|
275
|
+
}
|
|
276
|
+
return Math.min(minDelay, maxDelay);
|
|
277
|
+
}
|
|
216
278
|
async connect(connectOpts) {
|
|
217
279
|
var _a;
|
|
218
280
|
if (this.connecting) {
|
|
@@ -227,13 +289,29 @@ class Client extends events_1.default {
|
|
|
227
289
|
// this maintains the previous functionality
|
|
228
290
|
maxAttempts = Infinity;
|
|
229
291
|
}
|
|
292
|
+
clearTimeout(this.backoffReductionTimer);
|
|
293
|
+
const connectionData = this.getConnectionData();
|
|
294
|
+
const startingDelay = this.getStartingDelay(connectionData, maxDelay);
|
|
295
|
+
const delayFirstAttempt = this.hasMadeInitialAttempt;
|
|
296
|
+
this.hasMadeInitialAttempt = true;
|
|
230
297
|
try {
|
|
231
|
-
await exponential_backoff_1.backOff(() =>
|
|
232
|
-
|
|
298
|
+
await exponential_backoff_1.backOff(async () => {
|
|
299
|
+
const connectionData = this.getConnectionData();
|
|
300
|
+
await this.makeConnectionAttempt();
|
|
301
|
+
if (connectionData.nextDelayReductionTime) {
|
|
302
|
+
const msUntilReduction = connectionData.nextDelayReductionTime - new Date().getTime();
|
|
303
|
+
this.logger.debug('Setting timer for next backoff reduction', { msUntilReduction, delayMsAfterNextReduction: connectionData.delayMsAfterNextReduction });
|
|
304
|
+
this.backoffReductionTimer = setTimeout(() => this.decreaseBackoff(connectionData.delayMsAfterNextReduction || 0), msUntilReduction);
|
|
305
|
+
}
|
|
306
|
+
}, {
|
|
307
|
+
jitter: 'none',
|
|
233
308
|
maxDelay,
|
|
234
309
|
numOfAttempts: maxAttempts,
|
|
235
|
-
startingDelay
|
|
236
|
-
|
|
310
|
+
startingDelay,
|
|
311
|
+
delayFirstAttempt,
|
|
312
|
+
retry: this.backoffConnectRetryHandler.bind(this, {
|
|
313
|
+
maxConnectionAttempts: maxAttempts,
|
|
314
|
+
}),
|
|
237
315
|
});
|
|
238
316
|
}
|
|
239
317
|
catch (err) {
|
|
@@ -317,14 +395,13 @@ class Client extends events_1.default {
|
|
|
317
395
|
let retryDelay = parseInt(retryAfter, 10) * 1000;
|
|
318
396
|
additionalErrorDetails.retryDelay = retryDelay;
|
|
319
397
|
this.logger.error('Failed streaming client connection attempt, respecting retry-after header and will retry afterwards.', additionalErrorDetails, { skipServer: err instanceof offline_error_1.default });
|
|
320
|
-
await
|
|
321
|
-
setTimeout(resolve, retryDelay);
|
|
322
|
-
});
|
|
398
|
+
await utils_1.delay(retryDelay);
|
|
323
399
|
this.logger.debug('finished waiting for retry-after');
|
|
324
400
|
return true;
|
|
325
401
|
}
|
|
326
402
|
}
|
|
327
403
|
this.logger.error('Failed streaming client connection attempt, retrying', additionalErrorDetails, { skipServer: err instanceof offline_error_1.default });
|
|
404
|
+
this.increaseBackoff();
|
|
328
405
|
return true;
|
|
329
406
|
}
|
|
330
407
|
async makeConnectionAttempt() {
|
|
@@ -373,7 +450,7 @@ class Client extends events_1.default {
|
|
|
373
450
|
}
|
|
374
451
|
if (!this.hardReconnectRequired) {
|
|
375
452
|
this.channelReuses++;
|
|
376
|
-
if (this.channelReuses
|
|
453
|
+
if (this.channelReuses >= MAX_CHANNEL_REUSES) {
|
|
377
454
|
this.logger.warn('Forcing a hard reconnect due to max channel reuses', { channelId: this.config.channelId, channelReuses: this.channelReuses });
|
|
378
455
|
this.channelReuses = 0;
|
|
379
456
|
this.hardReconnectRequired = true;
|
|
@@ -247,3 +247,9 @@ export declare type MediaStat = InsightAction<{
|
|
|
247
247
|
elapsedMsFromInitialRequest?: number;
|
|
248
248
|
}>;
|
|
249
249
|
export declare type NRProxyStat = FirstAlertingConversationStat | MediaStat;
|
|
250
|
+
export declare type SCConnectionData = {
|
|
251
|
+
currentDelayMs: number;
|
|
252
|
+
delayMsAfterNextReduction?: number;
|
|
253
|
+
nextDelayReductionTime?: number;
|
|
254
|
+
timeOfTotalReset?: number;
|
|
255
|
+
};
|
package/dist/npm/utils.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare function timeoutPromise(fn: Function, timeoutMs: number, msg: string, details?: any): Promise<any>;
|
|
2
|
+
export declare function delay(ms: number): Promise<void>;
|
|
2
3
|
export declare function splitIntoIndividualTopics(topicString: string): string[];
|
|
3
4
|
export declare const isAcdJid: (jid: string) => boolean;
|
|
4
5
|
export declare const isScreenRecordingJid: (jid: string) => boolean;
|
package/dist/npm/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculatePayloadSize = exports.parseJwt = exports.retryPromise = exports.isVideoJid = exports.isSoftphoneJid = exports.isScreenRecordingJid = exports.isAcdJid = exports.splitIntoIndividualTopics = exports.timeoutPromise = void 0;
|
|
3
|
+
exports.calculatePayloadSize = exports.parseJwt = exports.retryPromise = exports.isVideoJid = exports.isSoftphoneJid = exports.isScreenRecordingJid = exports.isAcdJid = exports.splitIntoIndividualTopics = exports.delay = exports.timeoutPromise = void 0;
|
|
4
4
|
const uuid_1 = require("uuid");
|
|
5
5
|
const timeout_error_1 = require("./types/timeout-error");
|
|
6
6
|
/* istanbul ignore next */
|
|
@@ -19,6 +19,12 @@ function timeoutPromise(fn, timeoutMs, msg, details) {
|
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
exports.timeoutPromise = timeoutPromise;
|
|
22
|
+
function delay(ms) {
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
setTimeout(resolve, ms);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
exports.delay = delay;
|
|
22
28
|
function splitIntoIndividualTopics(topicString) {
|
|
23
29
|
const topics = [];
|
|
24
30
|
if (topicString.includes('?')) {
|
|
@@ -38,11 +44,11 @@ function splitIntoIndividualTopics(topicString) {
|
|
|
38
44
|
}
|
|
39
45
|
exports.splitIntoIndividualTopics = splitIntoIndividualTopics;
|
|
40
46
|
const isAcdJid = function (jid) {
|
|
41
|
-
return jid.startsWith('acd-');
|
|
47
|
+
return jid.startsWith('acd-') && !exports.isSoftphoneJid(jid);
|
|
42
48
|
};
|
|
43
49
|
exports.isAcdJid = isAcdJid;
|
|
44
50
|
const isScreenRecordingJid = function (jid) {
|
|
45
|
-
return jid.startsWith('screenrecording-');
|
|
51
|
+
return jid.startsWith('screenrecording-') && !exports.isSoftphoneJid(jid);
|
|
46
52
|
};
|
|
47
53
|
exports.isScreenRecordingJid = isScreenRecordingJid;
|
|
48
54
|
const isSoftphoneJid = function (jid) {
|