@webex/plugin-meetings 3.11.0 → 3.12.0

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.
Files changed (170) hide show
  1. package/dist/aiEnableRequest/index.js +184 -0
  2. package/dist/aiEnableRequest/index.js.map +1 -0
  3. package/dist/aiEnableRequest/utils.js +36 -0
  4. package/dist/aiEnableRequest/utils.js.map +1 -0
  5. package/dist/annotation/index.js +14 -5
  6. package/dist/annotation/index.js.map +1 -1
  7. package/dist/breakouts/breakout.js +1 -1
  8. package/dist/breakouts/index.js +1 -1
  9. package/dist/config.js +5 -1
  10. package/dist/config.js.map +1 -1
  11. package/dist/constants.js +28 -6
  12. package/dist/constants.js.map +1 -1
  13. package/dist/hashTree/constants.js +3 -1
  14. package/dist/hashTree/constants.js.map +1 -1
  15. package/dist/hashTree/hashTree.js +18 -0
  16. package/dist/hashTree/hashTree.js.map +1 -1
  17. package/dist/hashTree/hashTreeParser.js +709 -380
  18. package/dist/hashTree/hashTreeParser.js.map +1 -1
  19. package/dist/hashTree/types.js +4 -2
  20. package/dist/hashTree/types.js.map +1 -1
  21. package/dist/hashTree/utils.js +10 -0
  22. package/dist/hashTree/utils.js.map +1 -1
  23. package/dist/index.js +11 -2
  24. package/dist/index.js.map +1 -1
  25. package/dist/interceptors/constant.js +12 -0
  26. package/dist/interceptors/constant.js.map +1 -0
  27. package/dist/interceptors/dataChannelAuthToken.js +290 -0
  28. package/dist/interceptors/dataChannelAuthToken.js.map +1 -0
  29. package/dist/interceptors/index.js +7 -0
  30. package/dist/interceptors/index.js.map +1 -1
  31. package/dist/interceptors/utils.js +27 -0
  32. package/dist/interceptors/utils.js.map +1 -0
  33. package/dist/interpretation/index.js +2 -2
  34. package/dist/interpretation/index.js.map +1 -1
  35. package/dist/interpretation/siLanguage.js +1 -1
  36. package/dist/locus-info/controlsUtils.js +5 -3
  37. package/dist/locus-info/controlsUtils.js.map +1 -1
  38. package/dist/locus-info/index.js +217 -79
  39. package/dist/locus-info/index.js.map +1 -1
  40. package/dist/locus-info/selfUtils.js +1 -0
  41. package/dist/locus-info/selfUtils.js.map +1 -1
  42. package/dist/locus-info/types.js.map +1 -1
  43. package/dist/media/MediaConnectionAwaiter.js +57 -1
  44. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  45. package/dist/media/properties.js +4 -2
  46. package/dist/media/properties.js.map +1 -1
  47. package/dist/meeting/in-meeting-actions.js +7 -1
  48. package/dist/meeting/in-meeting-actions.js.map +1 -1
  49. package/dist/meeting/index.js +1082 -861
  50. package/dist/meeting/index.js.map +1 -1
  51. package/dist/meeting/request.js +50 -0
  52. package/dist/meeting/request.js.map +1 -1
  53. package/dist/meeting/request.type.js.map +1 -1
  54. package/dist/meeting/util.js +133 -3
  55. package/dist/meeting/util.js.map +1 -1
  56. package/dist/meetings/index.js +100 -45
  57. package/dist/meetings/index.js.map +1 -1
  58. package/dist/member/index.js +10 -0
  59. package/dist/member/index.js.map +1 -1
  60. package/dist/member/util.js +10 -0
  61. package/dist/member/util.js.map +1 -1
  62. package/dist/metrics/constants.js +2 -1
  63. package/dist/metrics/constants.js.map +1 -1
  64. package/dist/multistream/mediaRequestManager.js +9 -60
  65. package/dist/multistream/mediaRequestManager.js.map +1 -1
  66. package/dist/multistream/remoteMediaManager.js +11 -0
  67. package/dist/multistream/remoteMediaManager.js.map +1 -1
  68. package/dist/reachability/index.js +18 -10
  69. package/dist/reachability/index.js.map +1 -1
  70. package/dist/reactions/reactions.type.js.map +1 -1
  71. package/dist/reconnection-manager/index.js +0 -1
  72. package/dist/reconnection-manager/index.js.map +1 -1
  73. package/dist/types/aiEnableRequest/index.d.ts +5 -0
  74. package/dist/types/aiEnableRequest/utils.d.ts +2 -0
  75. package/dist/types/config.d.ts +3 -0
  76. package/dist/types/constants.d.ts +23 -1
  77. package/dist/types/hashTree/constants.d.ts +1 -0
  78. package/dist/types/hashTree/hashTree.d.ts +7 -0
  79. package/dist/types/hashTree/hashTreeParser.d.ts +99 -14
  80. package/dist/types/hashTree/types.d.ts +3 -0
  81. package/dist/types/hashTree/utils.d.ts +6 -0
  82. package/dist/types/index.d.ts +1 -0
  83. package/dist/types/interceptors/constant.d.ts +5 -0
  84. package/dist/types/interceptors/dataChannelAuthToken.d.ts +43 -0
  85. package/dist/types/interceptors/index.d.ts +2 -1
  86. package/dist/types/interceptors/utils.d.ts +1 -0
  87. package/dist/types/locus-info/index.d.ts +21 -2
  88. package/dist/types/locus-info/types.d.ts +1 -0
  89. package/dist/types/media/MediaConnectionAwaiter.d.ts +10 -1
  90. package/dist/types/media/properties.d.ts +2 -1
  91. package/dist/types/meeting/in-meeting-actions.d.ts +6 -0
  92. package/dist/types/meeting/index.d.ts +38 -6
  93. package/dist/types/meeting/request.d.ts +16 -1
  94. package/dist/types/meeting/request.type.d.ts +5 -0
  95. package/dist/types/meeting/util.d.ts +31 -0
  96. package/dist/types/meetings/index.d.ts +4 -2
  97. package/dist/types/member/index.d.ts +1 -0
  98. package/dist/types/member/util.d.ts +5 -0
  99. package/dist/types/metrics/constants.d.ts +1 -0
  100. package/dist/types/multistream/mediaRequestManager.d.ts +0 -23
  101. package/dist/types/reactions/reactions.type.d.ts +1 -0
  102. package/dist/types/webinar/utils.d.ts +6 -0
  103. package/dist/webinar/index.js +260 -90
  104. package/dist/webinar/index.js.map +1 -1
  105. package/dist/webinar/utils.js +25 -0
  106. package/dist/webinar/utils.js.map +1 -0
  107. package/package.json +24 -23
  108. package/src/aiEnableRequest/README.md +84 -0
  109. package/src/aiEnableRequest/index.ts +170 -0
  110. package/src/aiEnableRequest/utils.ts +25 -0
  111. package/src/annotation/index.ts +27 -7
  112. package/src/config.ts +3 -0
  113. package/src/constants.ts +29 -1
  114. package/src/hashTree/constants.ts +1 -0
  115. package/src/hashTree/hashTree.ts +17 -0
  116. package/src/hashTree/hashTreeParser.ts +627 -249
  117. package/src/hashTree/types.ts +4 -0
  118. package/src/hashTree/utils.ts +9 -0
  119. package/src/index.ts +8 -1
  120. package/src/interceptors/constant.ts +6 -0
  121. package/src/interceptors/dataChannelAuthToken.ts +170 -0
  122. package/src/interceptors/index.ts +2 -1
  123. package/src/interceptors/utils.ts +16 -0
  124. package/src/interpretation/index.ts +2 -2
  125. package/src/locus-info/controlsUtils.ts +11 -0
  126. package/src/locus-info/index.ts +231 -61
  127. package/src/locus-info/selfUtils.ts +1 -0
  128. package/src/locus-info/types.ts +1 -0
  129. package/src/media/MediaConnectionAwaiter.ts +41 -1
  130. package/src/media/properties.ts +3 -1
  131. package/src/meeting/in-meeting-actions.ts +12 -0
  132. package/src/meeting/index.ts +205 -44
  133. package/src/meeting/request.ts +42 -0
  134. package/src/meeting/request.type.ts +6 -0
  135. package/src/meeting/util.ts +160 -2
  136. package/src/meetings/index.ts +135 -41
  137. package/src/member/index.ts +10 -0
  138. package/src/member/util.ts +12 -0
  139. package/src/metrics/constants.ts +1 -0
  140. package/src/multistream/mediaRequestManager.ts +4 -54
  141. package/src/multistream/remoteMediaManager.ts +13 -0
  142. package/src/reachability/index.ts +9 -0
  143. package/src/reactions/reactions.type.ts +1 -0
  144. package/src/reconnection-manager/index.ts +0 -1
  145. package/src/webinar/index.ts +162 -5
  146. package/src/webinar/utils.ts +16 -0
  147. package/test/unit/spec/aiEnableRequest/index.ts +981 -0
  148. package/test/unit/spec/aiEnableRequest/utils.ts +130 -0
  149. package/test/unit/spec/annotation/index.ts +69 -7
  150. package/test/unit/spec/hashTree/hashTree.ts +66 -0
  151. package/test/unit/spec/hashTree/hashTreeParser.ts +1869 -189
  152. package/test/unit/spec/interceptors/dataChannelAuthToken.ts +210 -0
  153. package/test/unit/spec/interceptors/utils.ts +75 -0
  154. package/test/unit/spec/locus-info/controlsUtils.js +29 -0
  155. package/test/unit/spec/locus-info/index.js +383 -46
  156. package/test/unit/spec/media/MediaConnectionAwaiter.ts +41 -1
  157. package/test/unit/spec/media/properties.ts +12 -3
  158. package/test/unit/spec/meeting/in-meeting-actions.ts +8 -2
  159. package/test/unit/spec/meeting/index.js +716 -115
  160. package/test/unit/spec/meeting/request.js +70 -0
  161. package/test/unit/spec/meeting/utils.js +438 -26
  162. package/test/unit/spec/meetings/index.js +652 -31
  163. package/test/unit/spec/member/index.js +28 -4
  164. package/test/unit/spec/member/util.js +65 -27
  165. package/test/unit/spec/multistream/mediaRequestManager.ts +2 -85
  166. package/test/unit/spec/multistream/remoteMediaManager.ts +30 -0
  167. package/test/unit/spec/reachability/index.ts +23 -0
  168. package/test/unit/spec/reconnection-manager/index.js +4 -8
  169. package/test/unit/spec/webinar/index.ts +348 -36
  170. package/test/unit/spec/webinar/utils.ts +39 -0
@@ -6,6 +6,7 @@
6
6
  import {isEqual, mapValues, mean} from 'lodash';
7
7
 
8
8
  import {Defer} from '@webex/common';
9
+ import {CapabilityState, WebCapabilities} from '@webex/web-capabilities';
9
10
  import LoggerProxy from '../common/logs/logger-proxy';
10
11
  import MeetingUtil from '../meeting/util';
11
12
 
@@ -196,6 +197,14 @@ export default class Reachability extends EventsScope {
196
197
  if (!this.webex.config.meetings.enableReachabilityChecks) {
197
198
  throw new Error('enableReachabilityChecks is disabled in config');
198
199
  }
200
+
201
+ if (WebCapabilities.supportsRTCPeerConnection() !== CapabilityState.CAPABLE) {
202
+ LoggerProxy.logger.warn(
203
+ 'Reachability:index#gatherReachability --> WebRTC API is not available, skipping reachability checks'
204
+ );
205
+
206
+ return {};
207
+ }
199
208
  // Fetch clusters and measure latency
200
209
  try {
201
210
  this.lastTrigger = trigger;
@@ -40,6 +40,7 @@ export enum SkinToneType {
40
40
  }
41
41
 
42
42
  export type Sender = {
43
+ displayName: string;
43
44
  participantId: string;
44
45
  };
45
46
 
@@ -609,7 +609,6 @@ export default class ReconnectionManager {
609
609
  if (this.meeting.isMultistream) {
610
610
  Object.values(this.meeting.mediaRequestManagers).forEach(
611
611
  (mediaRequestManager: MediaRequestManager) => {
612
- mediaRequestManager.clearPreviousRequests();
613
612
  mediaRequestManager.commit();
614
613
  }
615
614
  );
@@ -4,10 +4,21 @@
4
4
  import {WebexPlugin, config} from '@webex/webex-core';
5
5
  import uuid from 'uuid';
6
6
  import {get} from 'lodash';
7
- import {_ID_, HEADERS, HTTP_VERBS, MEETINGS, SELF_ROLES, SHARE_STATUS} from '../constants';
7
+ import {DataChannelTokenType} from '@webex/internal-plugin-llm';
8
+ import {
9
+ _ID_,
10
+ HEADERS,
11
+ HTTP_VERBS,
12
+ MEETINGS,
13
+ SELF_ROLES,
14
+ SHARE_STATUS,
15
+ DEFAULT_LARGE_SCALE_WEBINAR_ATTENDEE_SEARCH_LIMIT,
16
+ LLM_PRACTICE_SESSION,
17
+ } from '../constants';
8
18
 
9
19
  import WebinarCollection from './collection';
10
20
  import LoggerProxy from '../common/logs/logger-proxy';
21
+ import {sanitizeParams} from './utils';
11
22
 
12
23
  /**
13
24
  * @class Webinar
@@ -28,6 +39,14 @@ const Webinar = WebexPlugin.extend({
28
39
  meetingId: 'string',
29
40
  },
30
41
 
42
+ /**
43
+ * Calls this to clean up listeners
44
+ * @returns {void}
45
+ */
46
+ cleanUp() {
47
+ this.cleanupPSDataChannel();
48
+ },
49
+
31
50
  /**
32
51
  * Update the current locus url of the webinar
33
52
  * @param {string} locusUrl
@@ -96,10 +115,7 @@ const Webinar = WebexPlugin.extend({
96
115
  meeting?.locusInfo?.updateMediaShares(meeting?.locusInfo?.mediaShares, true);
97
116
  }
98
117
 
99
- if (this.practiceSessionEnabled) {
100
- // may need change data channel in practice session
101
- meeting?.updateLLMConnection();
102
- }
118
+ this.updatePSDataChannel();
103
119
  },
104
120
 
105
121
  /**
@@ -110,6 +126,112 @@ const Webinar = WebexPlugin.extend({
110
126
  return this.selfIsPanelist && this.practiceSessionEnabled;
111
127
  },
112
128
 
129
+ /**
130
+ * Disconnects the practice session data channel and removes its relay listener.
131
+ * @returns {Promise<void>}
132
+ */
133
+ async cleanupPSDataChannel() {
134
+ const meeting = this.webex.meetings.getMeetingByType(_ID_, this.meetingId);
135
+
136
+ // @ts-ignore - Fix type
137
+ await this.webex.internal.llm.disconnectLLM(
138
+ {
139
+ code: 3050,
140
+ reason: 'done (permanent)',
141
+ },
142
+ LLM_PRACTICE_SESSION
143
+ );
144
+ // @ts-ignore - Fix type
145
+ this.webex.internal.llm.off(
146
+ `event:relay.event:${LLM_PRACTICE_SESSION}`,
147
+ meeting?.processRelayEvent
148
+ );
149
+ },
150
+
151
+ /**
152
+ * Connects to low latency mercury and reconnects if the address has changed
153
+ * It will also disconnect if called when the meeting has ended
154
+ * @returns {Promise}
155
+ */
156
+ async updatePSDataChannel() {
157
+ const meeting = this.webex.meetings.getMeetingByType(_ID_, this.meetingId);
158
+ const isPracticeSession = meeting?.isJoined() && this.isJoinPracticeSessionDataChannel();
159
+
160
+ if (!isPracticeSession) {
161
+ await this.cleanupPSDataChannel();
162
+
163
+ return undefined;
164
+ }
165
+
166
+ // @ts-ignore - Fix type
167
+ const {
168
+ url = undefined,
169
+ info: {practiceSessionDatachannelUrl = undefined} = {},
170
+ self: {practiceSessionDatachannelToken = undefined} = {},
171
+ } = meeting?.locusInfo || {};
172
+
173
+ // @ts-ignore
174
+ const currentToken = this.webex.internal.llm.getDatachannelToken(
175
+ DataChannelTokenType.PracticeSession
176
+ );
177
+
178
+ const finalToken = currentToken ?? practiceSessionDatachannelToken;
179
+
180
+ const isCaptionBoxOn = this.webex.internal.voicea.getIsCaptionBoxOn();
181
+
182
+ if (!currentToken && practiceSessionDatachannelToken) {
183
+ // @ts-ignore
184
+ this.webex.internal.llm.setDatachannelToken(
185
+ practiceSessionDatachannelToken,
186
+ DataChannelTokenType.PracticeSession
187
+ );
188
+ }
189
+
190
+ if (!practiceSessionDatachannelUrl) {
191
+ return undefined;
192
+ }
193
+ // @ts-ignore - Fix type
194
+ if (this.webex.internal.llm.isConnected(LLM_PRACTICE_SESSION)) {
195
+ if (
196
+ // @ts-ignore - Fix type
197
+ url === this.webex.internal.llm.getLocusUrl(LLM_PRACTICE_SESSION) &&
198
+ // @ts-ignore - Fix type
199
+ practiceSessionDatachannelUrl ===
200
+ this.webex.internal.llm.getDatachannelUrl(LLM_PRACTICE_SESSION)
201
+ ) {
202
+ return undefined;
203
+ }
204
+
205
+ await this.cleanupPSDataChannel();
206
+ }
207
+
208
+ // @ts-ignore - Fix type
209
+ return this.webex.internal.llm
210
+ .registerAndConnect(url, practiceSessionDatachannelUrl, finalToken, LLM_PRACTICE_SESSION)
211
+ .then((registerAndConnectResult) => {
212
+ // @ts-ignore - Fix type
213
+ this.webex.internal.llm.off(
214
+ `event:relay.event:${LLM_PRACTICE_SESSION}`,
215
+ meeting?.processRelayEvent
216
+ );
217
+ // @ts-ignore - Fix type
218
+ this.webex.internal.llm.on(
219
+ `event:relay.event:${LLM_PRACTICE_SESSION}`,
220
+ meeting?.processRelayEvent
221
+ );
222
+ // @ts-ignore - Fix type
223
+ this.webex.internal.voicea?.announce?.();
224
+ if (isCaptionBoxOn) {
225
+ this.webex.internal.voicea.updateSubchannelSubscriptions({subscribe: ['transcription']});
226
+ }
227
+ LoggerProxy.logger.info(
228
+ `Webinar:index#updatePSDataChannel --> enabled to receive relay events for default session for ${LLM_PRACTICE_SESSION}!`
229
+ );
230
+
231
+ return Promise.resolve(registerAndConnectResult);
232
+ });
233
+ },
234
+
113
235
  /**
114
236
  * start or stop practice session for webinar
115
237
  * @param {boolean} enabled
@@ -137,6 +259,7 @@ const Webinar = WebexPlugin.extend({
137
259
  */
138
260
  updatePracticeSessionStatus(payload) {
139
261
  this.set('practiceSessionEnabled', !!payload?.enabled);
262
+ this.updatePSDataChannel().then(() => {});
140
263
  },
141
264
 
142
265
  /**
@@ -297,6 +420,40 @@ const Webinar = WebexPlugin.extend({
297
420
  throw error;
298
421
  });
299
422
  },
423
+
424
+ /**
425
+ * search large scale webinar attendees
426
+ * @param {object} payload
427
+ * @param {string} payload.queryString
428
+ * @param {number} payload.limit
429
+ * @param {string} payload.next
430
+ * @returns {Promise}
431
+ */
432
+ async searchLargeScaleWebinarAttendees(payload) {
433
+ const meeting = this.webex.meetings.getMeetingByType(_ID_, this.meetingId);
434
+ const rawParams = {
435
+ search_text: payload?.queryString,
436
+ limit: payload?.limit ?? DEFAULT_LARGE_SCALE_WEBINAR_ATTENDEE_SEARCH_LIMIT,
437
+ next: payload?.next,
438
+ };
439
+ const attendeeSearchUrl = meeting?.locusInfo?.links?.resources?.attendeeSearch?.url;
440
+ if (!attendeeSearchUrl) {
441
+ LoggerProxy.logger.error(`Meeting:webinar5k#searchLargeScaleWebinarAttendees failed`);
442
+ throw new Error('Meeting:webinar5k#Attendee search url is not available');
443
+ }
444
+
445
+ return this.request({
446
+ method: HTTP_VERBS.GET,
447
+ uri: `${attendeeSearchUrl}?${new URLSearchParams(sanitizeParams(rawParams)).toString()}`,
448
+ headers: {
449
+ authorization: await this.webex.credentials.getUserToken(),
450
+ trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`,
451
+ },
452
+ }).catch((error) => {
453
+ LoggerProxy.logger.error('Meeting:webinar5k#searchLargeScaleWebinarAttendees failed', error);
454
+ throw error;
455
+ });
456
+ },
300
457
  });
301
458
 
302
459
  export default Webinar;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Remove null/undefined/empty string values from an object
3
+ * @param {object} params
4
+ * @returns {object}
5
+ */
6
+ export const sanitizeParams = (params: Record<string, any>) => {
7
+ const result: Record<string, any> = {};
8
+ Object.keys(params).forEach((key) => {
9
+ const value = params[key];
10
+ if (value !== null && value !== undefined && value !== '') {
11
+ result[key] = value;
12
+ }
13
+ });
14
+
15
+ return result;
16
+ };