genesys-cloud-streaming-client 19.4.1-develop.11 → 19.4.1-develop.13

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.
@@ -346,6 +346,7 @@ export class Notifications {
346
346
  return this.xmppUnsubscribe(topic);
347
347
  }
348
348
  bulkSubscribe(topics, options = { replace: false, force: false }, priorities = {}) {
349
+ var _a;
349
350
  return __awaiter(this, void 0, void 0, function* () {
350
351
  this.setTopicPriorities(priorities);
351
352
  let toSubscribe = mergeAndDedup(topics, []);
@@ -362,29 +363,38 @@ export class Notifications {
362
363
  if (response && response.data && 'entities' in response.data && Array.isArray(response.data.entities)) {
363
364
  topicResponseEntities = response.data.entities;
364
365
  }
365
- const topicResponsesById = {};
366
+ const result = {};
366
367
  for (const topicEntity of topicResponseEntities) {
367
- topicResponsesById[topicEntity.id] = topicEntity;
368
+ const { id, state, rejectionReason } = topicEntity;
369
+ result[id] = { topic: id, state, rejectionReason };
370
+ // If response entity is a combined topic ID like "a.b?c&d" include individualized topic IDs
371
+ // as keys in the map. This could either point to the same result as the combined topic ID
372
+ // or to a specific result for that individual topic if backend provides a specific result.
373
+ // Example: caller asked to subscribe "a.b?c&d" but user lacks permission for topic "a.b.d"
374
+ // In this case, API response will include "a.b?c&d" as success along with "a.b.d" as failure.
375
+ if (id.includes('?')) {
376
+ for (const individualTopic of splitIntoIndividualTopics(id)) {
377
+ const hasIndividualTopicResult = result.hasOwnProperty(individualTopic);
378
+ // Only use the combined topic result for this individual topic ID if there isn't already
379
+ // a result for the individual topic itself. Exact topic result takes precedence.
380
+ if (!hasIndividualTopicResult) {
381
+ result[individualTopic] = result[id];
382
+ }
383
+ }
384
+ }
368
385
  }
369
- const result = {};
370
386
  if (options.replace) {
371
387
  this.bulkSubscriptions = {};
372
388
  }
373
389
  topics.forEach(topic => {
374
390
  this.bulkSubscriptions[topic] = true;
375
- if (this.enablePartialBulkResubscribe) {
376
- if (topic in topicResponsesById) {
377
- const { state, rejectionReason } = topicResponsesById[topic];
378
- result[topic] = { topic, state, rejectionReason };
379
- }
380
- else {
381
- result[topic] = { topic, state: 'Unknown' };
382
- }
383
- }
384
- else {
385
- result[topic] = { topic, state: 'Permitted' };
386
- }
387
391
  });
392
+ // Add a fallback result for any topic in the toSubscribe list that isn't already in result.
393
+ // With partial bulk resubscribe enabled missing result means "Unknown" state but when not
394
+ // enabled the fallback is "Permitted" for backward compatibility (success response means OK).
395
+ for (const topic of toSubscribe) {
396
+ (_a = result[topic]) !== null && _a !== void 0 ? _a : (result[topic] = { topic, state: this.enablePartialBulkResubscribe ? 'Unknown' : 'Permitted' });
397
+ }
388
398
  return result;
389
399
  });
390
400
  }
@@ -116,12 +116,13 @@ export interface IError {
116
116
  name: string;
117
117
  stack?: string;
118
118
  }
119
- export declare type SessionTypesAsStrings = 'softphone' | 'screenShare' | 'screenRecording' | 'collaborateVideo' | 'unknown';
119
+ export declare type SessionTypesAsStrings = 'softphone' | 'screenShare' | 'screenRecording' | 'liveScreenMonitoring' | 'collaborateVideo' | 'unknown';
120
120
  export declare enum SessionTypes {
121
121
  softphone = "softphone",
122
122
  collaborateVideo = "collaborateVideo",
123
123
  acdScreenShare = "screenShare",
124
124
  screenRecording = "screenRecording",
125
+ liveScreenMonitoring = "liveScreenMonitoring",
125
126
  unknown = "unknown"
126
127
  }
127
128
  export interface ISessionInfo extends IPendingSession {
@@ -10,5 +10,6 @@ export var SessionTypes;
10
10
  SessionTypes["collaborateVideo"] = "collaborateVideo";
11
11
  SessionTypes["acdScreenShare"] = "screenShare";
12
12
  SessionTypes["screenRecording"] = "screenRecording";
13
+ SessionTypes["liveScreenMonitoring"] = "liveScreenMonitoring";
13
14
  SessionTypes["unknown"] = "unknown";
14
15
  })(SessionTypes || (SessionTypes = {}));
@@ -15,6 +15,7 @@ export declare function delay(ms: number): Promise<void>;
15
15
  export declare function splitIntoIndividualTopics(topicString: string): string[];
16
16
  export declare const isAcdJid: (jid: string) => boolean;
17
17
  export declare const isScreenRecordingJid: (jid: string) => boolean;
18
+ export declare const isLiveScreenMonitoringJid: (jid: string) => boolean;
18
19
  export declare const isSoftphoneJid: (jid: string) => boolean;
19
20
  export declare const isVideoJid: (jid: string) => boolean;
20
21
  export declare type RetryPromise<T = any> = {
package/dist/es/utils.js CHANGED
@@ -70,6 +70,9 @@ export const isAcdJid = function (jid) {
70
70
  export const isScreenRecordingJid = function (jid) {
71
71
  return jid.startsWith('screenrecording-') && !isSoftphoneJid(jid);
72
72
  };
73
+ export const isLiveScreenMonitoringJid = function (jid) {
74
+ return jid.startsWith('livemonitor-') && !isSoftphoneJid(jid);
75
+ };
73
76
  export const isSoftphoneJid = function (jid) {
74
77
  if (!jid) {
75
78
  return false;
package/dist/es/webrtc.js CHANGED
@@ -7,7 +7,7 @@ import { v4 } from 'uuid';
7
7
  import throttle from 'lodash.throttle';
8
8
  import { isFirefox } from 'browserama';
9
9
  import { definitions } from './stanza-definitions/webrtc-signaling';
10
- import { isAcdJid, isScreenRecordingJid, isSoftphoneJid, isVideoJid, calculatePayloadSize, retryPromise, iceIsDifferent } from './utils';
10
+ import { isAcdJid, isScreenRecordingJid, isLiveScreenMonitoringJid, isSoftphoneJid, isVideoJid, calculatePayloadSize, retryPromise, iceIsDifferent } from './utils';
11
11
  import { Client } from './client';
12
12
  import { deepFlatten, formatStatsEvent } from './stats-formatter';
13
13
  import { SessionTypes } from './types/interfaces';
@@ -859,6 +859,9 @@ export class WebrtcExtension extends EventEmitter {
859
859
  else if (isScreenRecordingJid(jid)) {
860
860
  return SessionTypes.screenRecording;
861
861
  }
862
+ else if (isLiveScreenMonitoringJid(jid)) {
863
+ return SessionTypes.liveScreenMonitoring;
864
+ }
862
865
  else if (isSoftphoneJid(jid)) {
863
866
  return SessionTypes.softphone;
864
867
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": "19.4.1-develop",
3
- "build": "11",
4
- "buildDate": "2025-10-13T14:10:01.001Z",
3
+ "build": "13",
4
+ "buildDate": "2025-11-14T15:35:30.951Z",
5
5
  "indexFiles": [
6
6
  {
7
7
  "file": "v19.4.1/streaming-client.browser.js"
@@ -5,18 +5,19 @@ 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/v19.4.0...HEAD)
8
+ ### Changed
9
+ * [STREAM-941](https://inindca.atlassian.net/browse/STREAM-941) - Fix an issue where notifications.subscribe() with `enablePartialBulkResubscribe` would not resolve/reject based on API result when the requested topic was internally combined with others, e.g. "topic.a" and "topic.b" individually subscribed and bulk resubscribe combines them as "topic?a&b"
10
+ * [STREAM-950](https://inindca.atlassian.net/browse/STREAM-950) - Update genesys-cloud-client-logger to pick up change moving from `unload` to `visibilitychange`.
11
+ * [STREAM-824](https://inindca.atlassian.net/browse/STREAM-824) - Handle new SDP offer for live screen-monitoring.
8
12
 
9
13
  # [v19.4.0](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/v19.3.1...v19.4.0)
10
14
  ### Added
11
15
  * [STREAM-865](https://inindca.atlassian.net/browse/STREAM-865) - Generate a test report in JUnit.xml format.
12
16
  * [STREAM-892](https://inindca.atlassian.net/browse/STREAM-892) - Add `enablePartialBulkResubscribe` client option to make notifications bulk subscription changes succeed or fail each topic independently rather than a single failed topic causing the whole bulk operation to fail.
13
17
 
14
- ### Changed
15
- * [STREAM-865](https://inindca.atlassian.net/browse/STREAM-865) - Remove the SDP payload from SDP answer logs.
16
-
17
- # [Unreleased](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/19.3.1...HEAD)
18
18
  ### Changed
19
19
  * [STREAM-643](https://inindca.atlassian.net/browse/STREAM-643) - Bumped webpack dependency to 5.94.0
20
+ * [STREAM-865](https://inindca.atlassian.net/browse/STREAM-865) - Remove the SDP payload from SDP answer logs.
20
21
 
21
22
  # [v19.3.1](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/v19.3.0...v19.3.1)
22
23
  * [STREAM-801](https://inindca.atlassian.net/browse/STREAM-801) - Update genesys-cloud-client-logger and axios to address Snyk vulnerability.
@@ -345,6 +345,7 @@ class Notifications {
345
345
  return this.xmppUnsubscribe(topic);
346
346
  }
347
347
  async bulkSubscribe(topics, options = { replace: false, force: false }, priorities = {}) {
348
+ var _a;
348
349
  this.setTopicPriorities(priorities);
349
350
  let toSubscribe = mergeAndDedup(topics, []);
350
351
  if (options.replace && !options.force) {
@@ -360,29 +361,38 @@ class Notifications {
360
361
  if (response && response.data && 'entities' in response.data && Array.isArray(response.data.entities)) {
361
362
  topicResponseEntities = response.data.entities;
362
363
  }
363
- const topicResponsesById = {};
364
+ const result = {};
364
365
  for (const topicEntity of topicResponseEntities) {
365
- topicResponsesById[topicEntity.id] = topicEntity;
366
+ const { id, state, rejectionReason } = topicEntity;
367
+ result[id] = { topic: id, state, rejectionReason };
368
+ // If response entity is a combined topic ID like "a.b?c&d" include individualized topic IDs
369
+ // as keys in the map. This could either point to the same result as the combined topic ID
370
+ // or to a specific result for that individual topic if backend provides a specific result.
371
+ // Example: caller asked to subscribe "a.b?c&d" but user lacks permission for topic "a.b.d"
372
+ // In this case, API response will include "a.b?c&d" as success along with "a.b.d" as failure.
373
+ if (id.includes('?')) {
374
+ for (const individualTopic of (0, utils_1.splitIntoIndividualTopics)(id)) {
375
+ const hasIndividualTopicResult = result.hasOwnProperty(individualTopic);
376
+ // Only use the combined topic result for this individual topic ID if there isn't already
377
+ // a result for the individual topic itself. Exact topic result takes precedence.
378
+ if (!hasIndividualTopicResult) {
379
+ result[individualTopic] = result[id];
380
+ }
381
+ }
382
+ }
366
383
  }
367
- const result = {};
368
384
  if (options.replace) {
369
385
  this.bulkSubscriptions = {};
370
386
  }
371
387
  topics.forEach(topic => {
372
388
  this.bulkSubscriptions[topic] = true;
373
- if (this.enablePartialBulkResubscribe) {
374
- if (topic in topicResponsesById) {
375
- const { state, rejectionReason } = topicResponsesById[topic];
376
- result[topic] = { topic, state, rejectionReason };
377
- }
378
- else {
379
- result[topic] = { topic, state: 'Unknown' };
380
- }
381
- }
382
- else {
383
- result[topic] = { topic, state: 'Permitted' };
384
- }
385
389
  });
390
+ // Add a fallback result for any topic in the toSubscribe list that isn't already in result.
391
+ // With partial bulk resubscribe enabled missing result means "Unknown" state but when not
392
+ // enabled the fallback is "Permitted" for backward compatibility (success response means OK).
393
+ for (const topic of toSubscribe) {
394
+ (_a = result[topic]) !== null && _a !== void 0 ? _a : (result[topic] = { topic, state: this.enablePartialBulkResubscribe ? 'Unknown' : 'Permitted' });
395
+ }
386
396
  return result;
387
397
  }
388
398
  get expose() {
@@ -116,12 +116,13 @@ export interface IError {
116
116
  name: string;
117
117
  stack?: string;
118
118
  }
119
- export declare type SessionTypesAsStrings = 'softphone' | 'screenShare' | 'screenRecording' | 'collaborateVideo' | 'unknown';
119
+ export declare type SessionTypesAsStrings = 'softphone' | 'screenShare' | 'screenRecording' | 'liveScreenMonitoring' | 'collaborateVideo' | 'unknown';
120
120
  export declare enum SessionTypes {
121
121
  softphone = "softphone",
122
122
  collaborateVideo = "collaborateVideo",
123
123
  acdScreenShare = "screenShare",
124
124
  screenRecording = "screenRecording",
125
+ liveScreenMonitoring = "liveScreenMonitoring",
125
126
  unknown = "unknown"
126
127
  }
127
128
  export interface ISessionInfo extends IPendingSession {
@@ -13,5 +13,6 @@ var SessionTypes;
13
13
  SessionTypes["collaborateVideo"] = "collaborateVideo";
14
14
  SessionTypes["acdScreenShare"] = "screenShare";
15
15
  SessionTypes["screenRecording"] = "screenRecording";
16
+ SessionTypes["liveScreenMonitoring"] = "liveScreenMonitoring";
16
17
  SessionTypes["unknown"] = "unknown";
17
18
  })(SessionTypes = exports.SessionTypes || (exports.SessionTypes = {}));
@@ -15,6 +15,7 @@ export declare function delay(ms: number): Promise<void>;
15
15
  export declare function splitIntoIndividualTopics(topicString: string): string[];
16
16
  export declare const isAcdJid: (jid: string) => boolean;
17
17
  export declare const isScreenRecordingJid: (jid: string) => boolean;
18
+ export declare const isLiveScreenMonitoringJid: (jid: string) => boolean;
18
19
  export declare const isSoftphoneJid: (jid: string) => boolean;
19
20
  export declare const isVideoJid: (jid: string) => boolean;
20
21
  export declare type RetryPromise<T = any> = {
package/dist/npm/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.iceIsDifferent = exports.getIcePwdFromSdp = exports.getUfragFromSdp = exports.calculatePayloadSize = exports.parseJwt = exports.retryPromise = exports.isVideoJid = exports.isSoftphoneJid = exports.isScreenRecordingJid = exports.isAcdJid = exports.splitIntoIndividualTopics = exports.delay = exports.timeoutPromise = exports.StreamingSubscriptionError = exports.StreamingClientError = void 0;
3
+ exports.iceIsDifferent = exports.getIcePwdFromSdp = exports.getUfragFromSdp = exports.calculatePayloadSize = exports.parseJwt = exports.retryPromise = exports.isVideoJid = exports.isSoftphoneJid = exports.isLiveScreenMonitoringJid = exports.isScreenRecordingJid = exports.isAcdJid = exports.splitIntoIndividualTopics = exports.delay = exports.timeoutPromise = exports.StreamingSubscriptionError = exports.StreamingClientError = void 0;
4
4
  const uuid_1 = require("uuid");
5
5
  const timeout_error_1 = require("./types/timeout-error");
6
6
  const interfaces_1 = require("./types/interfaces");
@@ -79,6 +79,10 @@ const isScreenRecordingJid = function (jid) {
79
79
  return jid.startsWith('screenrecording-') && !(0, exports.isSoftphoneJid)(jid);
80
80
  };
81
81
  exports.isScreenRecordingJid = isScreenRecordingJid;
82
+ const isLiveScreenMonitoringJid = function (jid) {
83
+ return jid.startsWith('livemonitor-') && !(0, exports.isSoftphoneJid)(jid);
84
+ };
85
+ exports.isLiveScreenMonitoringJid = isLiveScreenMonitoringJid;
82
86
  const isSoftphoneJid = function (jid) {
83
87
  if (!jid) {
84
88
  return false;
@@ -838,6 +838,9 @@ class WebrtcExtension extends events_1.EventEmitter {
838
838
  else if ((0, utils_1.isScreenRecordingJid)(jid)) {
839
839
  return interfaces_1.SessionTypes.screenRecording;
840
840
  }
841
+ else if ((0, utils_1.isLiveScreenMonitoringJid)(jid)) {
842
+ return interfaces_1.SessionTypes.liveScreenMonitoring;
843
+ }
841
844
  else if ((0, utils_1.isSoftphoneJid)(jid)) {
842
845
  return interfaces_1.SessionTypes.softphone;
843
846
  }