@webex/plugin-meetings 3.10.0-next.1 → 3.10.0-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.
Files changed (246) hide show
  1. package/dist/annotation/annotation.types.js.map +1 -1
  2. package/dist/annotation/constants.js.map +1 -1
  3. package/dist/annotation/index.js +19 -22
  4. package/dist/annotation/index.js.map +1 -1
  5. package/dist/breakouts/breakout.js +6 -6
  6. package/dist/breakouts/breakout.js.map +1 -1
  7. package/dist/breakouts/collection.js.map +1 -1
  8. package/dist/breakouts/edit-lock-error.js +9 -11
  9. package/dist/breakouts/edit-lock-error.js.map +1 -1
  10. package/dist/breakouts/events.js.map +1 -1
  11. package/dist/breakouts/index.js +126 -127
  12. package/dist/breakouts/index.js.map +1 -1
  13. package/dist/breakouts/request.js +6 -8
  14. package/dist/breakouts/request.js.map +1 -1
  15. package/dist/breakouts/utils.js.map +1 -1
  16. package/dist/common/browser-detection.js.map +1 -1
  17. package/dist/common/collection.js +1 -2
  18. package/dist/common/collection.js.map +1 -1
  19. package/dist/common/config.js.map +1 -1
  20. package/dist/common/errors/captcha-error.js +9 -11
  21. package/dist/common/errors/captcha-error.js.map +1 -1
  22. package/dist/common/errors/intent-to-join.js +10 -12
  23. package/dist/common/errors/intent-to-join.js.map +1 -1
  24. package/dist/common/errors/join-forbidden-error.js +10 -12
  25. package/dist/common/errors/join-forbidden-error.js.map +1 -1
  26. package/dist/common/errors/join-meeting.js +10 -12
  27. package/dist/common/errors/join-meeting.js.map +1 -1
  28. package/dist/common/errors/join-webinar-error.js +9 -11
  29. package/dist/common/errors/join-webinar-error.js.map +1 -1
  30. package/dist/common/errors/media.js +9 -11
  31. package/dist/common/errors/media.js.map +1 -1
  32. package/dist/common/errors/multistream-not-supported-error.js +9 -11
  33. package/dist/common/errors/multistream-not-supported-error.js.map +1 -1
  34. package/dist/common/errors/no-meeting-info.js +9 -11
  35. package/dist/common/errors/no-meeting-info.js.map +1 -1
  36. package/dist/common/errors/parameter.js +11 -14
  37. package/dist/common/errors/parameter.js.map +1 -1
  38. package/dist/common/errors/password-error.js +9 -11
  39. package/dist/common/errors/password-error.js.map +1 -1
  40. package/dist/common/errors/permission.js +9 -11
  41. package/dist/common/errors/permission.js.map +1 -1
  42. package/dist/common/errors/reclaim-host-role-errors.js +32 -38
  43. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -1
  44. package/dist/common/errors/reconnection-not-started.js +5 -6
  45. package/dist/common/errors/reconnection-not-started.js.map +1 -1
  46. package/dist/common/errors/reconnection.js +9 -11
  47. package/dist/common/errors/reconnection.js.map +1 -1
  48. package/dist/common/errors/stats.js +9 -11
  49. package/dist/common/errors/stats.js.map +1 -1
  50. package/dist/common/errors/webex-errors.js +38 -27
  51. package/dist/common/errors/webex-errors.js.map +1 -1
  52. package/dist/common/errors/webex-meetings-error.js +9 -12
  53. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  54. package/dist/common/events/events-scope.js +9 -10
  55. package/dist/common/events/events-scope.js.map +1 -1
  56. package/dist/common/events/events.js +9 -10
  57. package/dist/common/events/events.js.map +1 -1
  58. package/dist/common/events/trigger-proxy.js.map +1 -1
  59. package/dist/common/events/util.js.map +1 -1
  60. package/dist/common/logs/logger-config.js.map +1 -1
  61. package/dist/common/logs/logger-proxy.js.map +1 -1
  62. package/dist/common/logs/request.js +17 -17
  63. package/dist/common/logs/request.js.map +1 -1
  64. package/dist/common/queue.js +1 -2
  65. package/dist/common/queue.js.map +1 -1
  66. package/dist/config.js +0 -1
  67. package/dist/config.js.map +1 -1
  68. package/dist/constants.js +12 -8
  69. package/dist/constants.js.map +1 -1
  70. package/dist/controls-options-manager/constants.js.map +1 -1
  71. package/dist/controls-options-manager/enums.js.map +1 -1
  72. package/dist/controls-options-manager/index.js +1 -2
  73. package/dist/controls-options-manager/index.js.map +1 -1
  74. package/dist/controls-options-manager/types.js.map +1 -1
  75. package/dist/controls-options-manager/util.js +1 -2
  76. package/dist/controls-options-manager/util.js.map +1 -1
  77. package/dist/hashTree/hashTreeParser.js +165 -0
  78. package/dist/hashTree/hashTreeParser.js.map +1 -0
  79. package/dist/hashTree/types.js +15 -0
  80. package/dist/hashTree/types.js.map +1 -0
  81. package/dist/index.js +8 -2
  82. package/dist/index.js.map +1 -1
  83. package/dist/interceptors/index.js.map +1 -1
  84. package/dist/interceptors/locusRetry.js +6 -8
  85. package/dist/interceptors/locusRetry.js.map +1 -1
  86. package/dist/interceptors/locusRouteToken.js +6 -8
  87. package/dist/interceptors/locusRouteToken.js.map +1 -1
  88. package/dist/interpretation/collection.js.map +1 -1
  89. package/dist/interpretation/index.js +1 -2
  90. package/dist/interpretation/index.js.map +1 -1
  91. package/dist/interpretation/siLanguage.js +1 -1
  92. package/dist/interpretation/siLanguage.js.map +1 -1
  93. package/dist/locus-info/controlsUtils.js.map +1 -1
  94. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  95. package/dist/locus-info/fullState.js.map +1 -1
  96. package/dist/locus-info/hostUtils.js.map +1 -1
  97. package/dist/locus-info/index.js +532 -94
  98. package/dist/locus-info/index.js.map +1 -1
  99. package/dist/locus-info/infoUtils.js.map +1 -1
  100. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  101. package/dist/locus-info/parser.js +3 -4
  102. package/dist/locus-info/parser.js.map +1 -1
  103. package/dist/locus-info/selfUtils.js.map +1 -1
  104. package/dist/locus-info/types.js +7 -0
  105. package/dist/locus-info/types.js.map +1 -0
  106. package/dist/media/MediaConnectionAwaiter.js +1 -2
  107. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  108. package/dist/media/index.js +5 -2
  109. package/dist/media/index.js.map +1 -1
  110. package/dist/media/properties.js +15 -17
  111. package/dist/media/properties.js.map +1 -1
  112. package/dist/media/util.js.map +1 -1
  113. package/dist/meeting/brbState.js +8 -9
  114. package/dist/meeting/brbState.js.map +1 -1
  115. package/dist/meeting/connectionStateHandler.js +10 -13
  116. package/dist/meeting/connectionStateHandler.js.map +1 -1
  117. package/dist/meeting/in-meeting-actions.js.map +1 -1
  118. package/dist/meeting/index.js +1556 -1528
  119. package/dist/meeting/index.js.map +1 -1
  120. package/dist/meeting/locusMediaRequest.js +13 -17
  121. package/dist/meeting/locusMediaRequest.js.map +1 -1
  122. package/dist/meeting/muteState.js +11 -12
  123. package/dist/meeting/muteState.js.map +1 -1
  124. package/dist/meeting/request.js +101 -104
  125. package/dist/meeting/request.js.map +1 -1
  126. package/dist/meeting/request.type.js.map +1 -1
  127. package/dist/meeting/state.js.map +1 -1
  128. package/dist/meeting/type.js.map +1 -1
  129. package/dist/meeting/util.js +24 -23
  130. package/dist/meeting/util.js.map +1 -1
  131. package/dist/meeting/voicea-meeting.js +3 -3
  132. package/dist/meeting/voicea-meeting.js.map +1 -1
  133. package/dist/meeting-info/collection.js +7 -10
  134. package/dist/meeting-info/collection.js.map +1 -1
  135. package/dist/meeting-info/index.js +1 -2
  136. package/dist/meeting-info/index.js.map +1 -1
  137. package/dist/meeting-info/meeting-info-v2.js +135 -146
  138. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  139. package/dist/meeting-info/request.js +1 -2
  140. package/dist/meeting-info/request.js.map +1 -1
  141. package/dist/meeting-info/util.js +36 -37
  142. package/dist/meeting-info/util.js.map +1 -1
  143. package/dist/meeting-info/utilv2.js +30 -31
  144. package/dist/meeting-info/utilv2.js.map +1 -1
  145. package/dist/meetings/collection.js +6 -8
  146. package/dist/meetings/collection.js.map +1 -1
  147. package/dist/meetings/index.js +179 -141
  148. package/dist/meetings/index.js.map +1 -1
  149. package/dist/meetings/meetings.types.js.map +1 -1
  150. package/dist/meetings/request.js +6 -8
  151. package/dist/meetings/request.js.map +1 -1
  152. package/dist/meetings/util.js +25 -23
  153. package/dist/meetings/util.js.map +1 -1
  154. package/dist/member/index.js +1 -2
  155. package/dist/member/index.js.map +1 -1
  156. package/dist/member/types.js +6 -3
  157. package/dist/member/types.js.map +1 -1
  158. package/dist/member/util.js.map +1 -1
  159. package/dist/members/collection.js +1 -2
  160. package/dist/members/collection.js.map +1 -1
  161. package/dist/members/index.js +18 -21
  162. package/dist/members/index.js.map +1 -1
  163. package/dist/members/request.js +8 -11
  164. package/dist/members/request.js.map +1 -1
  165. package/dist/members/types.js.map +1 -1
  166. package/dist/members/util.js.map +1 -1
  167. package/dist/metrics/constants.js +3 -1
  168. package/dist/metrics/constants.js.map +1 -1
  169. package/dist/metrics/index.js +3 -4
  170. package/dist/metrics/index.js.map +1 -1
  171. package/dist/multistream/mediaRequestManager.js +1 -2
  172. package/dist/multistream/mediaRequestManager.js.map +1 -1
  173. package/dist/multistream/receiveSlot.js +34 -45
  174. package/dist/multistream/receiveSlot.js.map +1 -1
  175. package/dist/multistream/receiveSlotManager.js +8 -9
  176. package/dist/multistream/receiveSlotManager.js.map +1 -1
  177. package/dist/multistream/remoteMedia.js +12 -15
  178. package/dist/multistream/remoteMedia.js.map +1 -1
  179. package/dist/multistream/remoteMediaGroup.js +1 -2
  180. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  181. package/dist/multistream/remoteMediaManager.js +122 -123
  182. package/dist/multistream/remoteMediaManager.js.map +1 -1
  183. package/dist/multistream/sendSlotManager.js +29 -30
  184. package/dist/multistream/sendSlotManager.js.map +1 -1
  185. package/dist/personal-meeting-room/index.js +16 -19
  186. package/dist/personal-meeting-room/index.js.map +1 -1
  187. package/dist/personal-meeting-room/request.js +7 -10
  188. package/dist/personal-meeting-room/request.js.map +1 -1
  189. package/dist/personal-meeting-room/util.js.map +1 -1
  190. package/dist/reachability/clusterReachability.js +36 -39
  191. package/dist/reachability/clusterReachability.js.map +1 -1
  192. package/dist/reachability/index.js +203 -205
  193. package/dist/reachability/index.js.map +1 -1
  194. package/dist/reachability/reachability.types.js.map +1 -1
  195. package/dist/reachability/request.js.map +1 -1
  196. package/dist/reachability/util.js.map +1 -1
  197. package/dist/reactions/constants.js.map +1 -1
  198. package/dist/reactions/reactions.js.map +1 -1
  199. package/dist/reactions/reactions.type.js.map +1 -1
  200. package/dist/reconnection-manager/index.js +178 -176
  201. package/dist/reconnection-manager/index.js.map +1 -1
  202. package/dist/recording-controller/enums.js.map +1 -1
  203. package/dist/recording-controller/index.js +1 -2
  204. package/dist/recording-controller/index.js.map +1 -1
  205. package/dist/recording-controller/util.js.map +1 -1
  206. package/dist/roap/index.js +12 -15
  207. package/dist/roap/index.js.map +1 -1
  208. package/dist/roap/request.js +24 -26
  209. package/dist/roap/request.js.map +1 -1
  210. package/dist/roap/turnDiscovery.js +75 -76
  211. package/dist/roap/turnDiscovery.js.map +1 -1
  212. package/dist/roap/types.js.map +1 -1
  213. package/dist/transcription/index.js +4 -5
  214. package/dist/transcription/index.js.map +1 -1
  215. package/dist/types/common/errors/webex-errors.d.ts +12 -0
  216. package/dist/types/constants.d.ts +26 -21
  217. package/dist/types/hashTree/hashTreeParser.d.ts +109 -0
  218. package/dist/types/hashTree/types.d.ts +16 -0
  219. package/dist/types/index.d.ts +2 -1
  220. package/dist/types/locus-info/index.d.ts +91 -42
  221. package/dist/types/locus-info/types.d.ts +45 -0
  222. package/dist/types/meeting/index.d.ts +22 -9
  223. package/dist/types/meetings/index.d.ts +9 -2
  224. package/dist/types/metrics/constants.d.ts +2 -0
  225. package/dist/webinar/collection.js +1 -2
  226. package/dist/webinar/collection.js.map +1 -1
  227. package/dist/webinar/index.js +148 -158
  228. package/dist/webinar/index.js.map +1 -1
  229. package/package.json +16 -16
  230. package/src/common/errors/webex-errors.ts +19 -0
  231. package/src/constants.ts +14 -2
  232. package/src/hashTree/hashTreeParser.ts +146 -0
  233. package/src/hashTree/types.ts +20 -0
  234. package/src/index.ts +2 -0
  235. package/src/locus-info/index.ts +534 -85
  236. package/src/locus-info/types.ts +46 -0
  237. package/src/media/index.ts +6 -0
  238. package/src/meeting/index.ts +61 -27
  239. package/src/meeting/util.ts +1 -0
  240. package/src/meetings/index.ts +104 -51
  241. package/src/metrics/constants.ts +2 -0
  242. package/test/unit/spec/locus-info/index.js +576 -1
  243. package/test/unit/spec/media/index.ts +140 -9
  244. package/test/unit/spec/meeting/index.js +178 -94
  245. package/test/unit/spec/meeting/utils.js +77 -0
  246. package/test/unit/spec/meetings/index.js +71 -28
@@ -0,0 +1,46 @@
1
+ import {HtMeta} from '../hashTree/types';
2
+
3
+ export type LocusDTO = {
4
+ controls?: any;
5
+ fullState?: {
6
+ active: boolean;
7
+ count: number;
8
+ lastActive: string;
9
+ locked: boolean;
10
+ sessionId: string;
11
+ seessionIds: string[];
12
+ startTime: number;
13
+ state: string;
14
+ type: string;
15
+ };
16
+ host?: {
17
+ id: string;
18
+ incomingCallProtocols: any[];
19
+ isExternal: boolean;
20
+ name: string;
21
+ orgId: string;
22
+ };
23
+ htMeta?: HtMeta;
24
+ info?: any;
25
+ jsSdkMeta?: {
26
+ removedParticipantIds: string[]; // list of ids of participants that are removed in the last update
27
+ };
28
+ links?: any;
29
+ mediaShares?: any[];
30
+ meetings?: any[];
31
+ participants: any[];
32
+ replaces?: any[];
33
+ self?: any;
34
+ sequence?: {
35
+ dirtyParticipants: number;
36
+ entries: number[];
37
+ rangeEnd: number;
38
+ rangeStart: number;
39
+ sequenceHash: number;
40
+ sessionToken: string;
41
+ since: string;
42
+ totalParticipants: number;
43
+ };
44
+ syncUrl?: string;
45
+ url?: string;
46
+ };
@@ -194,6 +194,12 @@ Media.createMediaConnection = (
194
194
  config.stopIceGatheringAfterFirstRelayCandidate = stopIceGatheringAfterFirstRelayCandidate;
195
195
  }
196
196
 
197
+ if (BrowserInfo.isEdge() || BrowserInfo.isChrome()) {
198
+ // we need this for getting inbound audio metadata
199
+ // but the audioLevel that we use is only available on Chromium based browsers
200
+ config.enableInboundAudioLevelMonitoring = true;
201
+ }
202
+
197
203
  return new MultistreamRoapMediaConnection(
198
204
  config,
199
205
  meetingId,
@@ -30,6 +30,7 @@ import {
30
30
  NetworkQualityMonitor,
31
31
  StatsMonitor,
32
32
  StatsMonitorEventNames,
33
+ InboundAudioIssueSubTypes,
33
34
  } from '@webex/internal-media-core';
34
35
 
35
36
  import {
@@ -57,6 +58,7 @@ import {
57
58
  NoMediaEstablishedYetError,
58
59
  UserNotJoinedError,
59
60
  AddMediaFailed,
61
+ SdpResponseTimeoutError,
60
62
  } from '../common/errors/webex-errors';
61
63
 
62
64
  import LoggerProxy from '../common/logs/logger-proxy';
@@ -68,7 +70,7 @@ import Media, {type BundlePolicy} from '../media';
68
70
  import MediaProperties from '../media/properties';
69
71
  import MeetingStateMachine from './state';
70
72
  import {createMuteState} from './muteState';
71
- import LocusInfo from '../locus-info';
73
+ import LocusInfo, {LocusLLMEvent} from '../locus-info';
72
74
  import Metrics from '../metrics';
73
75
  import ReconnectionManager from '../reconnection-manager';
74
76
  import ReconnectionNotStartedError from '../common/errors/reconnection-not-started';
@@ -124,6 +126,8 @@ import {
124
126
  JOIN_BEFORE_HOST,
125
127
  REGISTRATION_ID_STATUS,
126
128
  STAGE_MANAGER_TYPE,
129
+ LOCUSEVENT,
130
+ LOCUS_LLM_EVENT,
127
131
  } from '../constants';
128
132
  import BEHAVIORAL_METRICS from '../metrics/constants';
129
133
  import ParameterError from '../common/errors/parameter';
@@ -169,6 +173,8 @@ import JoinForbiddenError from '../common/errors/join-forbidden-error';
169
173
  import {ReachabilityMetrics} from '../reachability/reachability.types';
170
174
  import {SetStageOptions, SetStageVideoLayout, UnsetStageVideoLayout} from './request.type';
171
175
  import {Invitee} from './type';
176
+ import {DataSet} from '../hashTree/hashTreeParser';
177
+ import {LocusDTO} from '../locus-info/types';
172
178
 
173
179
  // default callback so we don't call an undefined function, but in practice it should never be used
174
180
  const DEFAULT_ICE_PHASE_CALLBACK = () => 'JOIN_MEETING_FINAL';
@@ -4549,40 +4555,45 @@ export default class Meeting extends StatelessWebexPlugin {
4549
4555
  }
4550
4556
 
4551
4557
  /**
4552
- * Set the locus info the class instance
4553
- * @param {Object} locus
4554
- * @param {Array} locus.mediaConnections
4555
- * @param {String} locus.locusUrl
4556
- * @param {String} locus.locusId
4557
- * @param {String} locus.mediaId
4558
- * @param {Object} locus.host
4558
+ * Set the locus info the class instance. Should be called with the parsed locus
4559
+ * we got in the join response.
4560
+ *
4561
+ * @param {Object} data
4562
+ * @param {Array} data.mediaConnections
4563
+ * @param {String} data.locusUrl
4564
+ * @param {String} data.locusId
4565
+ * @param {String} data.mediaId
4566
+ * @param {Object} data.host
4559
4567
  * @todo change name to genertic parser
4560
4568
  * @returns {undefined}
4561
4569
  * @private
4562
4570
  * @memberof Meeting
4563
4571
  */
4564
- setLocus(
4565
- locus:
4566
- | {
4567
- mediaConnections: Array<any>;
4568
- locusUrl: string;
4569
- locusId: string;
4570
- mediaId: string;
4571
- host: object;
4572
- }
4573
- | any
4574
- ) {
4575
- const mtgLocus: any = locus.locus || locus;
4572
+ setLocus(data: {
4573
+ locus: LocusDTO;
4574
+ mediaConnections: Array<any>;
4575
+ locusUrl: string;
4576
+ locusId: string;
4577
+ mediaId: string;
4578
+ host: object;
4579
+ selfId: string;
4580
+ dataSets: DataSet[];
4581
+ }) {
4582
+ const mtgLocus: any = data.locus;
4576
4583
 
4577
4584
  // LocusInfo object saves the locus object
4578
4585
  // this.locus = mtgLocus;
4579
- this.mediaConnections = locus.mediaConnections;
4580
- this.locusUrl = locus.locusUrl || locus.url;
4581
- this.locusId = locus.locusId;
4582
- this.selfId = locus.selfId;
4583
- this.mediaId = locus.mediaId;
4586
+ this.mediaConnections = data.mediaConnections;
4587
+ this.locusUrl = data.locusUrl;
4588
+ this.locusId = data.locusId;
4589
+ this.selfId = data.selfId;
4590
+ this.mediaId = data.mediaId;
4584
4591
  this.hostId = mtgLocus.host ? mtgLocus.host.id : this.hostId;
4585
- this.locusInfo.initialSetup(mtgLocus);
4592
+ this.locusInfo.initialSetup({
4593
+ trigger: 'join-response',
4594
+ locus: mtgLocus,
4595
+ dataSets: data.dataSets,
4596
+ });
4586
4597
  }
4587
4598
 
4588
4599
  /**
@@ -5695,6 +5706,21 @@ export default class Meeting extends StatelessWebexPlugin {
5695
5706
  }
5696
5707
  }
5697
5708
 
5709
+ /** Handles Locus LLM events
5710
+ *
5711
+ * @param {LocusLLMEvent} event - The Locus LLM event to process
5712
+ * @returns {void}
5713
+ */
5714
+ private processLocusLLMEvent = (event: LocusLLMEvent): void => {
5715
+ if (event.data.eventType === LOCUSEVENT.HASH_TREE_DATA_UPDATED) {
5716
+ this.locusInfo.parse(this, event.data);
5717
+ } else {
5718
+ LoggerProxy.logger.warn(
5719
+ `Meeting:index#processLocusLLMEvent --> Unknown event type: ${event.data.eventType}`
5720
+ );
5721
+ }
5722
+ };
5723
+
5698
5724
  /**
5699
5725
  * Callback called when a relay event is received from meeting LLM Connection
5700
5726
  * @param {RelayEvent} e Event object coming from LLM Connection
@@ -6106,6 +6132,8 @@ export default class Meeting extends StatelessWebexPlugin {
6106
6132
  );
6107
6133
  // @ts-ignore - Fix type
6108
6134
  this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
6135
+ // @ts-ignore - Fix type
6136
+ this.webex.internal.llm.off(LOCUS_LLM_EVENT, this.processLocusLLMEvent);
6109
6137
  }
6110
6138
 
6111
6139
  if (!isJoined) {
@@ -6120,6 +6148,10 @@ export default class Meeting extends StatelessWebexPlugin {
6120
6148
  this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
6121
6149
  // @ts-ignore - Fix type
6122
6150
  this.webex.internal.llm.on('event:relay.event', this.processRelayEvent);
6151
+ // @ts-ignore - Fix type
6152
+ this.webex.internal.llm.off(LOCUS_LLM_EVENT, this.processLocusLLMEvent);
6153
+ // @ts-ignore - Fix type
6154
+ this.webex.internal.llm.on(LOCUS_LLM_EVENT, this.processLocusLLMEvent);
6123
6155
  LoggerProxy.logger.info(
6124
6156
  'Meeting:index#updateLLMConnection --> enabled to receive relay events!'
6125
6157
  );
@@ -7451,7 +7483,7 @@ export default class Meeting extends StatelessWebexPlugin {
7451
7483
  } seconds`
7452
7484
  );
7453
7485
 
7454
- const error = new Error('Timed out waiting for REMOTE SDP ANSWER');
7486
+ const error = new SdpResponseTimeoutError();
7455
7487
 
7456
7488
  // @ts-ignore
7457
7489
  this.webex.internal.newMetrics.submitClientEvent({
@@ -9371,6 +9403,8 @@ export default class Meeting extends StatelessWebexPlugin {
9371
9403
 
9372
9404
  // @ts-ignore - fix types
9373
9405
  this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
9406
+ // @ts-ignore - Fix type
9407
+ this.webex.internal.llm.off(LOCUS_LLM_EVENT, this.processLocusLLMEvent);
9374
9408
  };
9375
9409
 
9376
9410
  /**
@@ -31,6 +31,7 @@ const MeetingUtil = {
31
31
 
32
32
  // First todo: add check for existance
33
33
  parsed.locus = response.body.locus;
34
+ parsed.dataSets = response.body.dataSets;
34
35
  parsed.mediaConnections = response.body.mediaConnections;
35
36
  parsed.locusUrl = parsed.locus.url;
36
37
  parsed.locusId = parsed.locus.url.split('/').pop();
@@ -1,5 +1,5 @@
1
1
  /* eslint no-shadow: ["error", { "allow": ["eventType"] }] */
2
- import {cloneDeep, clone} from 'lodash';
2
+ import {cloneDeep, clone, set} from 'lodash';
3
3
  import '@webex/internal-plugin-mercury';
4
4
  import '@webex/internal-plugin-conversation';
5
5
  import '@webex/internal-plugin-metrics';
@@ -66,6 +66,7 @@ import JoinWebinarError from '../common/errors/join-webinar-error';
66
66
  import {SpaceIDDeprecatedError} from '../common/errors/webex-errors';
67
67
  import NoMeetingInfoError from '../common/errors/no-meeting-info';
68
68
  import JoinForbiddenError from '../common/errors/join-forbidden-error';
69
+ import {HashTreeMessage} from '../hashTree/hashTreeParser';
69
70
 
70
71
  let mediaLogger;
71
72
 
@@ -94,6 +95,18 @@ class MediaLogger {
94
95
  LoggerProxy.logger.debug(...args);
95
96
  }
96
97
  }
98
+
99
+ export type LocusEvent = {
100
+ eventType: LOCUSEVENT;
101
+
102
+ // fields populated for "classic" locus events (eventType = 'locus.difference' and others, see LOCUSEVENT)
103
+ locusUrl?: string;
104
+ locus?: any;
105
+
106
+ // fields populated for "hash tree" locus events (eventType = 'locus.state_message' - see LOCUSEVENT.HASH_TREE_DATA_UPDATED)
107
+ stateElementsMessage?: HashTreeMessage;
108
+ };
109
+
97
110
  /**
98
111
  * Meetings Ready Event
99
112
  * Emitted when the meetings instance on webex is ready
@@ -406,7 +419,17 @@ export default class Meetings extends WebexPlugin {
406
419
  * @private
407
420
  * @memberof Meetings
408
421
  */
409
- getCorrespondingMeetingByLocus(data) {
422
+ getCorrespondingMeetingByLocus(data: LocusEvent) {
423
+ if (
424
+ data.eventType === LOCUSEVENT.HASH_TREE_DATA_UPDATED &&
425
+ data.stateElementsMessage?.locusUrl
426
+ ) {
427
+ return this.meetingCollection.getByKey(
428
+ MEETING_KEY.LOCUS_URL,
429
+ data.stateElementsMessage.locusUrl
430
+ );
431
+ }
432
+
410
433
  // getting meeting by correlationId. This will happen for the new event
411
434
  // Either the locus
412
435
  // TODO : Add check for the callBack Address
@@ -420,15 +443,13 @@ export default class Meetings extends WebexPlugin {
420
443
  ) ||
421
444
  this.meetingCollection.getByKey(
422
445
  MEETING_KEY.SIP_URI,
423
- data.locus.self &&
424
- data.locus.self.callbackInfo &&
425
- data.locus.self.callbackInfo.callbackAddress
446
+ data.locus?.self?.callbackInfo?.callbackAddress
426
447
  ) ||
427
- (data.locus.info?.isUnifiedSpaceMeeting
448
+ (data.locus?.info?.isUnifiedSpaceMeeting
428
449
  ? undefined
429
450
  : this.meetingCollection.getByKey(
430
451
  MEETING_KEY.CONVERSATION_URL,
431
- data.locus.conversationUrl
452
+ data.locus?.conversationUrl
432
453
  )) ||
433
454
  this.meetingCollection.getByKey(MEETING_KEY.MEETINGNUMBER, data.locus?.info?.webExMeetingId)
434
455
  );
@@ -445,30 +466,33 @@ export default class Meetings extends WebexPlugin {
445
466
  * @private
446
467
  * @memberof Meetings
447
468
  */
448
- private handleLocusEvent(data: {locusUrl: string; locus: any}, useRandomDelayForInfo = false) {
469
+ private handleLocusEvent(data: LocusEvent, useRandomDelayForInfo = false) {
449
470
  let meeting = this.getCorrespondingMeetingByLocus(data);
450
471
 
451
472
  // Special case when locus has got replaced, This only happend once if a replace locus exists
452
473
  // https://sqbu-github.cisco.com/WebExSquared/locus/wiki/Locus-changing-mid-call
453
474
 
454
- if (!meeting && data.locus?.replaces?.length > 0) {
455
- // Always the last element in the replace is the active one
456
- meeting = this.meetingCollection.getByKey(
457
- MEETING_KEY.LOCUS_URL,
458
- data.locus.replaces[data.locus.replaces.length - 1].locusUrl
459
- );
460
- }
475
+ if (data.eventType !== LOCUSEVENT.HASH_TREE_DATA_UPDATED) {
476
+ if (!meeting && data.locus?.replaces?.length > 0) {
477
+ // Always the last element in the replace is the active one
478
+ meeting = this.meetingCollection.getByKey(
479
+ MEETING_KEY.LOCUS_URL,
480
+ data.locus.replaces[data.locus.replaces.length - 1].locusUrl
481
+ );
482
+ }
461
483
 
462
- if (meeting && !MeetingsUtil.isBreakoutLocusDTO(data.locus)) {
463
- meeting.locusInfo.updateMainSessionLocusCache(data.locus);
464
- }
465
- if (!this.isNeedHandleLocusDTO(meeting, data.locus)) {
466
- LoggerProxy.logger.log(
467
- `Meetings:index#handleLocusEvent --> doesn't need to process locus event`
468
- );
484
+ if (meeting && !MeetingsUtil.isBreakoutLocusDTO(data.locus)) {
485
+ meeting.locusInfo.updateMainSessionLocusCache(data.locus);
486
+ }
487
+ if (!this.isNeedHandleLocusDTO(meeting, data.locus)) {
488
+ LoggerProxy.logger.log(
489
+ `Meetings:index#handleLocusEvent --> doesn't need to process locus event`
490
+ );
469
491
 
470
- return;
492
+ return;
493
+ }
471
494
  }
495
+
472
496
  if (!meeting) {
473
497
  // TODO: create meeting when we get a meeting object
474
498
  // const checkForEnded = (locus) => {
@@ -489,42 +513,65 @@ export default class Meetings extends WebexPlugin {
489
513
  // };
490
514
  // rather then locus object change to locus url
491
515
 
492
- if (
493
- data.locus &&
494
- data.locus.fullState &&
495
- data.locus.fullState.state === LOCUS.STATE.INACTIVE
496
- ) {
497
- // just ignore the event as its already ended and not active
498
- LoggerProxy.logger.warn(
499
- 'Meetings:index#handleLocusEvent --> Locus event received for meeting, after it was ended.'
500
- );
516
+ if (data.eventType !== LOCUSEVENT.HASH_TREE_DATA_UPDATED) {
517
+ if (
518
+ data.locus &&
519
+ data.locus.fullState &&
520
+ data.locus.fullState.state === LOCUS.STATE.INACTIVE
521
+ ) {
522
+ // just ignore the event as its already ended and not active
523
+ LoggerProxy.logger.warn(
524
+ 'Meetings:index#handleLocusEvent --> Locus event received for meeting, after it was ended.'
525
+ );
501
526
 
502
- return;
503
- }
527
+ return;
528
+ }
504
529
 
505
- // When its wireless share or guest and user leaves the meeting we dont have to keep the meeting object
506
- // Any future events will be neglected
530
+ // When its wireless share or guest and user leaves the meeting we dont have to keep the meeting object
531
+ // Any future events will be neglected
532
+
533
+ if (
534
+ data.locus &&
535
+ data.locus.self &&
536
+ data.locus.self.state === _LEFT_ &&
537
+ data.locus.self.removed === true
538
+ ) {
539
+ // just ignore the event as its already ended and not active
540
+ LoggerProxy.logger.warn(
541
+ 'Meetings:index#handleLocusEvent --> Locus event received for meeting, after it was ended.'
542
+ );
507
543
 
508
- if (
509
- data.locus &&
510
- data.locus.self &&
511
- data.locus.self.state === _LEFT_ &&
512
- data.locus.self.removed === true
513
- ) {
514
- // just ignore the event as its already ended and not active
515
- LoggerProxy.logger.warn(
516
- 'Meetings:index#handleLocusEvent --> Locus event received for meeting, after it was ended.'
517
- );
544
+ return;
545
+ }
546
+ }
518
547
 
519
- return;
548
+ if (data.eventType === LOCUSEVENT.HASH_TREE_DATA_UPDATED) {
549
+ // in hash tree messages we don't ge the locus object, but the meeting constructor needs at least locus.url
550
+ set(data, 'locus.url', data.stateElementsMessage.locusUrl);
520
551
  }
521
552
 
522
553
  this.create(data.locus, DESTINATION_TYPE.LOCUS_ID, useRandomDelayForInfo)
523
- .then((newMeeting) => {
554
+ .then(async (newMeeting) => {
524
555
  meeting = newMeeting;
525
556
 
526
- // It's a new meeting so initialize the locus data
527
- meeting.locusInfo.initialSetup(data.locus);
557
+ try {
558
+ // It's a new meeting so initialize the locus data
559
+ await meeting.locusInfo.initialSetup({
560
+ trigger:
561
+ data.eventType === LOCUSEVENT.SDK_LOCUS_FROM_SYNC_MEETINGS
562
+ ? 'get-loci-response'
563
+ : 'locus-message',
564
+ locus: data.locus,
565
+ hashTreeMessage: data.stateElementsMessage,
566
+ });
567
+ } catch (error) {
568
+ LoggerProxy.logger.warn(
569
+ `Meetings:index#handleLocusEvent --> Error initializing locus data: ${error.message}`
570
+ );
571
+ // @ts-ignore
572
+ this.destroy(meeting, MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
573
+ }
574
+
528
575
  this.checkHandleBreakoutLocus(data.locus);
529
576
  })
530
577
  .catch((e) => {
@@ -1739,6 +1786,7 @@ export default class Meetings extends WebexPlugin {
1739
1786
  lociToUpdate.forEach((locus) => {
1740
1787
  activeLocusUrl.push(locus.url);
1741
1788
  this.handleLocusEvent({
1789
+ eventType: LOCUSEVENT.SDK_LOCUS_FROM_SYNC_MEETINGS,
1742
1790
  locus,
1743
1791
  locusUrl: locus.url,
1744
1792
  });
@@ -1786,6 +1834,7 @@ export default class Meetings extends WebexPlugin {
1786
1834
  (mainLocus) => mainLocus.controls?.breakout?.url === breakoutLocus.controls?.breakout?.url
1787
1835
  );
1788
1836
  const existCorrespondingMeeting = this.getCorrespondingMeetingByLocus({
1837
+ eventType: LOCUSEVENT.SDK_NO_EVENT,
1789
1838
  locus: breakoutLocus,
1790
1839
  locusUrl: breakoutLocus.url,
1791
1840
  });
@@ -1831,7 +1880,11 @@ export default class Meetings extends WebexPlugin {
1831
1880
  }
1832
1881
 
1833
1882
  const associateBreakoutLocus = this.breakoutLocusForHandleLater[existIndex];
1834
- this.handleLocusEvent({locus: associateBreakoutLocus, locusUrl: associateBreakoutLocus.url});
1883
+ this.handleLocusEvent({
1884
+ eventType: LOCUSEVENT.SDK_NO_EVENT,
1885
+ locus: associateBreakoutLocus,
1886
+ locusUrl: associateBreakoutLocus.url,
1887
+ });
1835
1888
  this.breakoutLocusForHandleLater.splice(existIndex, 1);
1836
1889
  }
1837
1890
 
@@ -87,6 +87,8 @@ const BEHAVIORAL_METRICS = {
87
87
  VERIFY_REGISTRATION_ID_ERROR: 'js_sdk_verify_registrationId_error',
88
88
  JOIN_FORBIDDEN_ERROR: 'js_sdk_join_forbidden_error',
89
89
  MEDIA_ISSUE_DETECTED: 'js_sdk_media_issue_detected',
90
+ LOCUS_CLASSIC_VS_HASH_TREE_MISMATCH: 'js_sdk_locus_classic_vs_hash_tree_mismatch',
91
+ LOCUS_HASH_TREE_UNSUPPORTED_OPERATION: 'js_sdk_locus_hash_tree_unsupported_operation',
90
92
  };
91
93
 
92
94
  export {BEHAVIORAL_METRICS as default};