@webex/plugin-meetings 3.8.1-web-workers-keepalive.1 → 3.9.0-webinar5k.1

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 (87) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/constants.js +8 -2
  4. package/dist/constants.js.map +1 -1
  5. package/dist/hashTree/constants.js +23 -0
  6. package/dist/hashTree/constants.js.map +1 -0
  7. package/dist/hashTree/hashTree.js +516 -0
  8. package/dist/hashTree/hashTree.js.map +1 -0
  9. package/dist/hashTree/hashTreeParser.js +521 -0
  10. package/dist/hashTree/hashTreeParser.js.map +1 -0
  11. package/dist/interpretation/index.js +1 -1
  12. package/dist/interpretation/siLanguage.js +1 -1
  13. package/dist/locus-info/index.js +301 -59
  14. package/dist/locus-info/index.js.map +1 -1
  15. package/dist/meeting/brbState.js +14 -12
  16. package/dist/meeting/brbState.js.map +1 -1
  17. package/dist/meeting/index.js +110 -12
  18. package/dist/meeting/index.js.map +1 -1
  19. package/dist/meeting/muteState.js +2 -5
  20. package/dist/meeting/muteState.js.map +1 -1
  21. package/dist/meeting/request.js +19 -0
  22. package/dist/meeting/request.js.map +1 -1
  23. package/dist/meeting/request.type.js.map +1 -1
  24. package/dist/meeting/util.js +8 -11
  25. package/dist/meeting/util.js.map +1 -1
  26. package/dist/meetings/index.js +6 -2
  27. package/dist/meetings/index.js.map +1 -1
  28. package/dist/member/index.js.map +1 -1
  29. package/dist/member/types.js.map +1 -1
  30. package/dist/members/collection.js +13 -0
  31. package/dist/members/collection.js.map +1 -1
  32. package/dist/members/index.js +44 -23
  33. package/dist/members/index.js.map +1 -1
  34. package/dist/members/request.js +3 -3
  35. package/dist/members/request.js.map +1 -1
  36. package/dist/members/util.js +18 -6
  37. package/dist/members/util.js.map +1 -1
  38. package/dist/multistream/sendSlotManager.js +32 -2
  39. package/dist/multistream/sendSlotManager.js.map +1 -1
  40. package/dist/types/constants.d.ts +6 -0
  41. package/dist/types/hashTree/constants.d.ts +8 -0
  42. package/dist/types/hashTree/hashTree.d.ts +128 -0
  43. package/dist/types/hashTree/hashTreeParser.d.ts +152 -0
  44. package/dist/types/locus-info/index.d.ts +93 -3
  45. package/dist/types/meeting/brbState.d.ts +0 -1
  46. package/dist/types/meeting/index.d.ts +29 -3
  47. package/dist/types/meeting/request.d.ts +9 -1
  48. package/dist/types/meeting/request.type.d.ts +74 -0
  49. package/dist/types/meeting/util.d.ts +3 -3
  50. package/dist/types/member/types.d.ts +1 -0
  51. package/dist/types/members/collection.d.ts +6 -0
  52. package/dist/types/members/index.d.ts +15 -3
  53. package/dist/types/members/request.d.ts +1 -1
  54. package/dist/types/members/util.d.ts +5 -2
  55. package/dist/types/multistream/sendSlotManager.d.ts +16 -0
  56. package/dist/webinar/index.js +1 -1
  57. package/package.json +24 -23
  58. package/src/constants.ts +7 -0
  59. package/src/hashTree/constants.ts +12 -0
  60. package/src/hashTree/hashTree.ts +460 -0
  61. package/src/hashTree/hashTreeParser.ts +556 -0
  62. package/src/locus-info/index.ts +393 -58
  63. package/src/meeting/brbState.ts +9 -7
  64. package/src/meeting/index.ts +104 -6
  65. package/src/meeting/muteState.ts +2 -6
  66. package/src/meeting/request.ts +16 -0
  67. package/src/meeting/request.type.ts +64 -0
  68. package/src/meeting/util.ts +17 -20
  69. package/src/meetings/index.ts +17 -3
  70. package/src/member/index.ts +1 -0
  71. package/src/member/types.ts +1 -0
  72. package/src/members/collection.ts +11 -0
  73. package/src/members/index.ts +33 -7
  74. package/src/members/request.ts +2 -2
  75. package/src/members/util.ts +14 -3
  76. package/src/multistream/sendSlotManager.ts +34 -2
  77. package/test/unit/spec/hashTree/hashTree.ts +394 -0
  78. package/test/unit/spec/hashTree/hashTreeParser.ts +156 -0
  79. package/test/unit/spec/locus-info/index.js +506 -55
  80. package/test/unit/spec/meeting/brbState.ts +9 -9
  81. package/test/unit/spec/meeting/index.js +475 -42
  82. package/test/unit/spec/meeting/request.js +71 -0
  83. package/test/unit/spec/members/index.js +33 -10
  84. package/test/unit/spec/members/request.js +2 -2
  85. package/test/unit/spec/members/utils.js +27 -7
  86. package/test/unit/spec/multistream/sendSlotManager.ts +59 -0
  87. package/test/unit/spec/reachability/index.ts +3 -1
@@ -1,16 +1,24 @@
1
1
  "use strict";
2
2
 
3
+ var _typeof = require("@babel/runtime-corejs2/helpers/typeof");
3
4
  var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
5
+ var _Object$keys2 = require("@babel/runtime-corejs2/core-js/object/keys");
6
+ var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
7
+ var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
8
+ var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
9
+ var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");
10
+ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
4
11
  var _Array$from = require("@babel/runtime-corejs2/core-js/array/from");
5
12
  var _Symbol = require("@babel/runtime-corejs2/core-js/symbol");
6
13
  var _Symbol$iterator = require("@babel/runtime-corejs2/core-js/symbol/iterator");
7
14
  var _Array$isArray2 = require("@babel/runtime-corejs2/core-js/array/is-array");
8
- var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
15
+ var _WeakMap = require("@babel/runtime-corejs2/core-js/weak-map");
9
16
  var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
10
17
  _Object$defineProperty(exports, "__esModule", {
11
18
  value: true
12
19
  });
13
20
  exports.default = void 0;
21
+ var _map = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/map"));
14
22
  var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
15
23
  var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
16
24
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
@@ -34,11 +42,18 @@ var _mediaSharesUtils = _interopRequireDefault(require("./mediaSharesUtils"));
34
42
  var _parser = _interopRequireDefault(require("./parser"));
35
43
  var _metrics = _interopRequireDefault(require("../metrics"));
36
44
  var _constants2 = _interopRequireDefault(require("../metrics/constants"));
45
+ var _hashTreeParser = _interopRequireWildcard(require("../hashTree/hashTreeParser"));
46
+ function _getRequireWildcardCache(e) { if ("function" != typeof _WeakMap) return null; var r = new _WeakMap(), t = new _WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
47
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = _Object$defineProperty && _Object$getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? _Object$getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? _Object$defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
37
48
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && o[_Symbol$iterator] || o["@@iterator"]; if (!it) { if (_Array$isArray2(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
38
49
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return _Array$from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
39
50
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
51
+ function ownKeys(e, r) { var t = _Object$keys2(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
52
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
40
53
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
41
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
54
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } /* eslint-disable class-methods-use-this */
55
+ var LocusDtoTopLevelKeys = ['controls', 'fullState', 'host', 'info', 'links', 'mediaShares', 'meetings', 'participants', 'replaces', 'self', 'sequence', 'syncUrl', 'url'];
56
+
42
57
  /**
43
58
  * @description LocusInfo extends ChildEmitter to convert locusInfo info a private emitter to parent object
44
59
  * @export
@@ -48,6 +63,8 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_R
48
63
  var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
49
64
  (0, _inherits2.default)(LocusInfo, _EventsScope);
50
65
  var _super = _createSuper(LocusInfo);
66
+ // mapping of hash tree object ids to participant ids
67
+
51
68
  /**
52
69
  * Constructor
53
70
  * @param {function} updateMeeting callback to update the meeting object from an object
@@ -91,6 +108,8 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
91
108
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "resources", void 0);
92
109
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "mainSessionLocusCache", void 0);
93
110
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "self", void 0);
111
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "hashTreeParser", void 0);
112
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "hashTreeObjectId2ParticipantId", void 0);
94
113
  _this.parsedLocus = {
95
114
  states: []
96
115
  };
@@ -100,6 +119,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
100
119
  _this.meetingId = meetingId;
101
120
  _this.updateMeeting = updateMeeting;
102
121
  _this.locusParser = new _parser.default();
122
+ _this.hashTreeObjectId2ParticipantId = new _map.default();
103
123
  return _this;
104
124
  }
105
125
 
@@ -115,6 +135,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
115
135
  var _this2 = this;
116
136
  var isDelta;
117
137
  var url;
138
+ var meetingDestroyed = false;
118
139
  if (this.locusParser.workingCopy.syncUrl) {
119
140
  url = this.locusParser.workingCopy.syncUrl;
120
141
  isDelta = true;
@@ -139,27 +160,44 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
139
160
  code: e.code
140
161
  });
141
162
  isDelta = false;
142
- return meeting.meetingRequest.getLocusDTO({
143
- url: meeting.locusUrl
144
- }).catch(function (err) {
145
- _loggerProxy.default.logger.info('Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting');
146
- _this2.webex.meetings.destroy(meeting, _constants.MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
147
- throw err;
148
- });
163
+
164
+ // Locus sometimes returns 403, for example if meeting has ended, no point trying the fallback to full sync in that case
165
+ if (e.statusCode !== 403) {
166
+ return meeting.meetingRequest.getLocusDTO({
167
+ url: meeting.locusUrl
168
+ }).catch(function (err) {
169
+ _loggerProxy.default.logger.info('Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting');
170
+ _this2.webex.meetings.destroy(meeting, _constants.MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
171
+ meetingDestroyed = true;
172
+ throw err;
173
+ });
174
+ }
175
+ _loggerProxy.default.logger.info('Locus-info:index#doLocusSync --> got 403 from Locus, skipping fallback to full sync, destroying the meeting');
176
+ } else {
177
+ _loggerProxy.default.logger.info('Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting');
149
178
  }
150
- _loggerProxy.default.logger.info('Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting');
151
179
  _this2.webex.meetings.destroy(meeting, _constants.MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
180
+ meetingDestroyed = true;
152
181
  throw e;
153
182
  }).then(function (res) {
154
- if (isDelta) {
155
- if (!(0, _lodash.isEmpty)(res.body)) {
156
- meeting.locusInfo.handleLocusDelta(res.body, meeting);
157
- } else {
183
+ if ((0, _lodash.isEmpty)(res.body)) {
184
+ if (isDelta) {
158
185
  _loggerProxy.default.logger.info('Locus-info:index#doLocusSync --> received empty body from syncUrl, so we already have latest Locus DTO');
186
+ } else {
187
+ _loggerProxy.default.logger.info('Locus-info:index#doLocusSync --> received empty body from full DTO sync request');
159
188
  }
160
- } else {
161
- meeting.locusInfo.onFullLocus(res.body);
189
+ return;
190
+ }
191
+ if (isDelta) {
192
+ if (res.body.baseSequence) {
193
+ meeting.locusInfo.handleLocusDelta(res.body, meeting); // todo: check if this is safe, is isDelta=true always only for non-hash tree locus
194
+
195
+ return;
196
+ }
197
+ // in some cases Locus might return us full DTO even when we asked for a delta
198
+ _loggerProxy.default.logger.info('Locus-info:index#doLocusSync --> got full DTO when we asked for delta');
162
199
  }
200
+ meeting.locusInfo.onFullLocus(res.body);
163
201
  }).catch(function (e) {
164
202
  _loggerProxy.default.logger.info("Locus-info:index#doLocusSync --> getLocusDTO succeeded but failed to handle result, locus parser will resume but not all data may be synced (".concat(e.toString(), ")"));
165
203
  _metrics.default.sendBehavioralMetric(_constants2.default.LOCUS_SYNC_HANDLING_FAILED, {
@@ -171,9 +209,11 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
171
209
  code: e.code
172
210
  });
173
211
  }).finally(function () {
174
- // Notify parser to resume processing delta events.
175
- // Any deltas in the queue that have now been superseded by this sync will simply be ignored
176
- _this2.locusParser.resume();
212
+ if (!meetingDestroyed) {
213
+ // Notify parser to resume processing delta events.
214
+ // Any deltas in the queue that have now been superseded by this sync will simply be ignored
215
+ _this2.locusParser.resume();
216
+ }
177
217
  });
178
218
  }
179
219
 
@@ -276,7 +316,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
276
316
  this.updateLocusCache(locus);
277
317
  // above section only updates the locusInfo object
278
318
  // The below section makes sure it updates the locusInfo as well as updates the meeting object
279
- this.updateParticipants(locus.participants);
319
+ this.updateParticipants(locus.participants, []);
280
320
  // For 1:1 space meeting the conversation Url does not exist in locus.conversation
281
321
  this.updateConversationUrl(locus.conversationUrl, locus.info);
282
322
  this.updateControls(locus.controls, locus.self);
@@ -294,19 +334,178 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
294
334
 
295
335
  /**
296
336
  * @param {Object} locus
337
+ * @param {DataSet[]} [dataSets=[]] - Array of data sets
297
338
  * @returns {undefined}
298
339
  * @memberof LocusInfo
299
340
  */
300
341
  }, {
301
342
  key: "initialSetup",
302
343
  value: function initialSetup(locus) {
344
+ var dataSets = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
303
345
  this.updateLocusCache(locus);
304
- this.onFullLocus(locus);
346
+ this.onFullLocus(locus, undefined, dataSets);
305
347
 
306
348
  // Change it to true after it receives it first locus object
307
349
  this.emitChange = true;
308
350
  }
309
351
 
352
+ /**
353
+ *
354
+ * @param {HashTreeObject} object data set object
355
+ * @param {any} locus
356
+ * @returns {void}
357
+ */
358
+ }, {
359
+ key: "updateHashTreeObjectInLocus",
360
+ value: function updateHashTreeObjectInLocus(object, locus) {
361
+ var type = object.htMeta.elementId.type.toLowerCase();
362
+ switch (type) {
363
+ case _hashTreeParser.ObjectType.locus:
364
+ {
365
+ if (!object.data) {
366
+ _loggerProxy.default.logger.warn("Locus-info:index#updateHashTreeObjectInLocus --> received LOCUS object without data, this is not supported!");
367
+ return locus;
368
+ }
369
+ // replace the main locus
370
+
371
+ // The Locus object from MAIN dataset has empty participants, so removing them to avoid it overriding the ones in our current locus object
372
+ // Also, it doesn't have "self". That's OK as it won't override existing locus.self and also existing SDK code can handle that missing self in Locus updates
373
+ var locusObjectFromData = object.data;
374
+ delete locusObjectFromData.participants;
375
+ locus = _objectSpread(_objectSpread({}, locus), locusObjectFromData);
376
+ locus.htMeta = object.htMeta;
377
+ break;
378
+ }
379
+ case _hashTreeParser.ObjectType.participant:
380
+ _loggerProxy.default.logger.info("Locus-info:index#updateHashTreeObjectInLocus --> participant id=".concat(object.htMeta.elementId.id, " ").concat(object.data ? 'updated' : 'removed'));
381
+ console.log('marcin: hashTreeObjectId2ParticipantId=', (0, _lodash.cloneDeep)(this.hashTreeObjectId2ParticipantId));
382
+ if (object.data) {
383
+ if (!locus.participants) {
384
+ locus.participants = [];
385
+ }
386
+ var participantObject = object.data;
387
+ participantObject.htMeta = object.htMeta;
388
+ locus.participants.push(participantObject);
389
+ this.hashTreeObjectId2ParticipantId.set(object.htMeta.elementId.id, participantObject.id);
390
+ } else {
391
+ var participantId = this.hashTreeObjectId2ParticipantId.get(object.htMeta.elementId.id);
392
+ if (!locus.jsSdkMeta) {
393
+ locus.jsSdkMeta = {
394
+ removedParticipantIds: []
395
+ };
396
+ }
397
+ locus.jsSdkMeta.removedParticipantIds.push(participantId);
398
+ this.hashTreeObjectId2ParticipantId.delete(object.htMeta.elementId.id);
399
+ }
400
+ break;
401
+ case _hashTreeParser.ObjectType.self:
402
+ if (!object.data) {
403
+ _loggerProxy.default.logger.warn("Locus-info:index#updateHashTreeObjectInLocus --> received SELF object without data, this is not supported!");
404
+ return locus;
405
+ }
406
+ locus.self = object.data;
407
+ break;
408
+ }
409
+ return locus;
410
+ }
411
+
412
+ /**
413
+ * Handles HTTP response from Locus API call when hash tree update.
414
+ * @param {Meeting} meeting meeting object
415
+ * @param {LocusApiResponseBody} responseBody body of the http reponse from Locus API call
416
+ * @returns {void}
417
+ */
418
+ }, {
419
+ key: "handleLocusAPIResponse",
420
+ value: function handleLocusAPIResponse(meeting, responseBody) {
421
+ console.log('marcin: locus response from API call:', responseBody);
422
+ if (responseBody.dataSets) {
423
+ if (!this.hashTreeParser) {
424
+ _loggerProxy.default.logger.warn("Locus-info:index#handleLocusAPIResponse --> received response with hash tree info from Locus API, but we don't have the hashTreeParser created");
425
+ return;
426
+ }
427
+ // Locus is using the new hash tree mechanism
428
+ // so update our data in the hash tree parser
429
+ this.hashTreeParser.handleLocusUpdate(responseBody);
430
+
431
+ // but the Locus object we receive in this case looks same like classic delta, so we can use existing delta method to process it
432
+ this.onDeltaLocus(responseBody.locus);
433
+ } else {
434
+ // classic Locus delta
435
+ this.handleLocusDelta(responseBody.locus, meeting);
436
+ }
437
+ }
438
+
439
+ /**
440
+ * Handles a hash tree message received from Locus.
441
+ *
442
+ * @param {Meeting} meeting - The meeting object
443
+ * @param {HashTreeMessage} message incoming hash tree message
444
+ * @returns {void}
445
+ */
446
+ }, {
447
+ key: "handleHashTreeMessage",
448
+ value: function handleHashTreeMessage(meeting, message) {
449
+ if (!this.hashTreeParser) {
450
+ _loggerProxy.default.logger.warn("Locus-info:index#handleHashTreeMessage --> received hash tree message, but we don't have the hashTreeParser");
451
+ return;
452
+ }
453
+ if (message.locusStateElements === undefined) {
454
+ // todo: need to see in practice how exactly the heartbeat messages look like
455
+ this.hashTreeParser.handleRootHashHeartBeatMessage(message);
456
+ } else {
457
+ this.hashTreeParser.handleMessage(message);
458
+ }
459
+ }
460
+
461
+ /**
462
+ * Updates our locus info based on the data parsed by the hash tree parser.
463
+ *
464
+ * @param {LocusInfoUpdateType} updateType - The type of update received.
465
+ * @param {Object} [data] - Additional data for the update, if applicable.
466
+ * @returns {void}
467
+ */
468
+ }, {
469
+ key: "updateFromHashTree",
470
+ value: function updateFromHashTree(updateType, data) {
471
+ var _this4 = this;
472
+ switch (updateType) {
473
+ case _hashTreeParser.LocusInfoUpdateType.OBJECTS_UPDATED:
474
+ {
475
+ // initialize the main locus with what we currently have
476
+ // but with empty participants array
477
+ var locus = {
478
+ participants: [],
479
+ jsSdkMeta: {
480
+ removedParticipantIds: []
481
+ }
482
+ };
483
+ LocusDtoTopLevelKeys.forEach(function (key) {
484
+ if (key === 'participants') {
485
+ locus[key] = [];
486
+ } else {
487
+ locus[key] = (0, _lodash.cloneDeep)(_this4[key]);
488
+ }
489
+ });
490
+
491
+ // apply the updates from the hash tree onto the locus
492
+ data.updatedObjects.forEach(function (object) {
493
+ locus = _this4.updateHashTreeObjectInLocus(object, locus);
494
+ });
495
+
496
+ // update our locus info with the new locus
497
+ this.onDeltaLocus(locus);
498
+ break;
499
+ }
500
+ case _hashTreeParser.LocusInfoUpdateType.MEETING_ENDED:
501
+ {
502
+ _loggerProxy.default.logger.info("Locus-info:index#updateFromHashTree --> received signal that meeting ended, destroying meeting ".concat(this.meetingId));
503
+ var meeting = this.webex.meetings.meetingCollection.get(this.meetingId);
504
+ this.webex.meetings.destroy(meeting, _constants.MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
505
+ }
506
+ }
507
+ }
508
+
310
509
  /**
311
510
  * @param {Meeting} meeting
312
511
  * @param {Object} data
@@ -316,34 +515,42 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
316
515
  }, {
317
516
  key: "parse",
318
517
  value: function parse(meeting, data) {
319
- // eslint-disable-next-line @typescript-eslint/no-shadow
320
- var eventType = data.eventType;
321
- var locus = this.getTheLocusToUpdate(data.locus);
322
- _loggerProxy.default.logger.info("Locus-info:index#parse --> received locus data: ".concat(eventType));
323
- switch (eventType) {
324
- case _constants.LOCUSEVENT.PARTICIPANT_JOIN:
325
- case _constants.LOCUSEVENT.PARTICIPANT_LEFT:
326
- case _constants.LOCUSEVENT.CONTROLS_UPDATED:
327
- case _constants.LOCUSEVENT.PARTICIPANT_AUDIO_MUTED:
328
- case _constants.LOCUSEVENT.PARTICIPANT_AUDIO_UNMUTED:
329
- case _constants.LOCUSEVENT.PARTICIPANT_VIDEO_MUTED:
330
- case _constants.LOCUSEVENT.PARTICIPANT_VIDEO_UNMUTED:
331
- case _constants.LOCUSEVENT.SELF_CHANGED:
332
- case _constants.LOCUSEVENT.PARTICIPANT_UPDATED:
333
- case _constants.LOCUSEVENT.PARTICIPANT_CONTROLS_UPDATED:
334
- case _constants.LOCUSEVENT.PARTICIPANT_ROLES_UPDATED:
335
- case _constants.LOCUSEVENT.PARTICIPANT_DECLINED:
336
- case _constants.LOCUSEVENT.FLOOR_GRANTED:
337
- case _constants.LOCUSEVENT.FLOOR_RELEASED:
338
- this.onFullLocus(locus, eventType);
339
- break;
340
- case _constants.LOCUSEVENT.DIFFERENCE:
341
- this.handleLocusDelta(locus, meeting);
342
- break;
343
- default:
344
- // Why will there be a event with no eventType ????
345
- // we may not need this, we can get full locus
346
- this.handleLocusDelta(locus, meeting);
518
+ if (data.eventType === 'locus.state_message') {
519
+ // this is the new hashmap Locus message format (only applicable to webinars for now)
520
+ this.handleHashTreeMessage(meeting, data.stateElementsMessage);
521
+ } else {
522
+ // eslint-disable-next-line @typescript-eslint/no-shadow
523
+ var eventType = data.eventType;
524
+ var locus = this.getTheLocusToUpdate(data.locus);
525
+ _loggerProxy.default.logger.info("Locus-info:index#parse --> received locus data: ".concat(eventType));
526
+ locus.jsSdkMeta = {
527
+ removedParticipantIds: []
528
+ };
529
+ switch (eventType) {
530
+ case _constants.LOCUSEVENT.PARTICIPANT_JOIN:
531
+ case _constants.LOCUSEVENT.PARTICIPANT_LEFT:
532
+ case _constants.LOCUSEVENT.CONTROLS_UPDATED:
533
+ case _constants.LOCUSEVENT.PARTICIPANT_AUDIO_MUTED:
534
+ case _constants.LOCUSEVENT.PARTICIPANT_AUDIO_UNMUTED:
535
+ case _constants.LOCUSEVENT.PARTICIPANT_VIDEO_MUTED:
536
+ case _constants.LOCUSEVENT.PARTICIPANT_VIDEO_UNMUTED:
537
+ case _constants.LOCUSEVENT.SELF_CHANGED:
538
+ case _constants.LOCUSEVENT.PARTICIPANT_UPDATED:
539
+ case _constants.LOCUSEVENT.PARTICIPANT_CONTROLS_UPDATED:
540
+ case _constants.LOCUSEVENT.PARTICIPANT_ROLES_UPDATED:
541
+ case _constants.LOCUSEVENT.PARTICIPANT_DECLINED:
542
+ case _constants.LOCUSEVENT.FLOOR_GRANTED:
543
+ case _constants.LOCUSEVENT.FLOOR_RELEASED:
544
+ this.onFullLocus(locus, eventType);
545
+ break;
546
+ case _constants.LOCUSEVENT.DIFFERENCE:
547
+ this.handleLocusDelta(locus, meeting);
548
+ break;
549
+ default:
550
+ // Why will there be a event with no eventType ????
551
+ // we may not need this, we can get full locus
552
+ this.handleLocusDelta(locus, meeting);
553
+ }
347
554
  }
348
555
  }
349
556
 
@@ -364,25 +571,57 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
364
571
  * updates the locus with full locus object
365
572
  * @param {object} locus locus object
366
573
  * @param {string} eventType particulat locus event
574
+ * @param {DataSet[]} dataSets
367
575
  * @returns {object} null
368
576
  * @memberof LocusInfo
369
577
  */
370
578
  }, {
371
579
  key: "onFullLocus",
372
- value: function onFullLocus(locus, eventType) {
580
+ value: function onFullLocus(locus, eventType, dataSets) {
581
+ var _this$participants,
582
+ _this5 = this,
583
+ _locus$jsSdkMeta;
373
584
  if (!locus) {
374
585
  _loggerProxy.default.logger.error('Locus-info:index#onFullLocus --> object passed as argument was invalid, continuing.');
375
586
  }
376
- if (!this.locusParser.isNewFullLocus(locus)) {
587
+ if (dataSets) {
588
+ // this is the new hashmap Locus DTO format (only applicable to webinars for now)
589
+ if (!this.hashTreeParser) {
590
+ _loggerProxy.default.logger.info("Locus-info:index#onFullLocus --> creating hash tree parser");
591
+ _loggerProxy.default.logger.info('Locus-info:index#onFullLocus --> dataSets:', dataSets, ' and locus:', locus);
592
+ this.hashTreeParser = new _hashTreeParser.default({
593
+ initialLocus: {
594
+ locus: locus,
595
+ dataSets: dataSets
596
+ },
597
+ webexRequest: this.webex.request.bind(this.webex),
598
+ locusInfoUpdateCallback: this.updateFromHashTree.bind(this),
599
+ debugId: "HT-".concat(this.meetingId.substring(0, 4))
600
+ });
601
+ } else {
602
+ // in this case the Locus we're getting is not necessarily the full one
603
+ // so treat it like if we just got it in a message
604
+ console.log('marcin: !!!!!!!! full DTO - this is not fully implemented/tested yet');
605
+ _loggerProxy.default.logger.warn('Locus-info:index#onFullLocus --> full DTO - this is not fully implemented/tested yet!!!!!!!!');
606
+ this.handleLocusAPIResponse(undefined, {
607
+ dataSets: dataSets,
608
+ locus: locus
609
+ });
610
+ return;
611
+ }
612
+ } else if (!this.locusParser.isNewFullLocus(locus)) {
377
613
  _loggerProxy.default.logger.info("Locus-info:index#onFullLocus --> ignoring old full locus DTO, eventType=".concat(eventType));
378
614
  return;
379
615
  }
380
616
  this.updateParticipantDeltas(locus.participants);
381
617
  this.scheduledMeeting = locus.meeting || null;
382
618
  this.participants = locus.participants;
619
+ (_this$participants = this.participants) === null || _this$participants === void 0 ? void 0 : _this$participants.forEach(function (participant) {
620
+ _this5.hashTreeObjectId2ParticipantId.set(participant.htMeta.elementId.id, participant.id);
621
+ });
383
622
  var isReplaceMembers = _controlsUtils.default.isNeedReplaceMembers(this.controls, locus.controls);
384
623
  this.updateLocusInfo(locus);
385
- this.updateParticipants(locus.participants, isReplaceMembers);
624
+ this.updateParticipants(locus.participants, (_locus$jsSdkMeta = locus.jsSdkMeta) === null || _locus$jsSdkMeta === void 0 ? void 0 : _locus$jsSdkMeta.removedParticipantIds, isReplaceMembers);
386
625
  this.isMeetingActive();
387
626
  this.handleOneOnOneEvent(eventType);
388
627
  this.updateEmbeddedApps(locus.embeddedApps);
@@ -434,10 +673,11 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
434
673
  }, {
435
674
  key: "onDeltaLocus",
436
675
  value: function onDeltaLocus(locus) {
676
+ var _locus$jsSdkMeta2;
437
677
  var isReplaceMembers = _controlsUtils.default.isNeedReplaceMembers(this.controls, locus.controls);
438
678
  this.mergeParticipants(this.participants, locus.participants);
439
679
  this.updateLocusInfo(locus);
440
- this.updateParticipants(locus.participants, isReplaceMembers);
680
+ this.updateParticipants(locus.participants, (_locus$jsSdkMeta2 = locus.jsSdkMeta) === null || _locus$jsSdkMeta2 === void 0 ? void 0 : _locus$jsSdkMeta2.removedParticipantIds, isReplaceMembers);
441
681
  this.isMeetingActive();
442
682
  }
443
683
 
@@ -461,12 +701,12 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
461
701
  this.updateCreated(locus.created);
462
702
  this.updateFullState(locus.fullState);
463
703
  this.updateHostInfo(locus.host);
704
+ this.updateLocusUrl(locus.url);
464
705
  this.updateMeetingInfo(locus.info, locus.self);
465
706
  this.updateMediaShares(locus.mediaShares);
466
707
  this.updateParticipantsUrl(locus.participantsUrl);
467
708
  this.updateReplace(locus.replace);
468
709
  this.updateSelf(locus.self);
469
- this.updateLocusUrl(locus.url);
470
710
  this.updateAclUrl(locus.aclUrl);
471
711
  this.updateBasequence(locus.baseSequence);
472
712
  this.updateSequence(locus.sequence);
@@ -678,7 +918,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
678
918
  }, {
679
919
  key: "updateParticipantDeltas",
680
920
  value: function updateParticipantDeltas() {
681
- var _this4 = this;
921
+ var _this6 = this;
682
922
  var participants = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
683
923
  // Used to find a participant within a participants collection.
684
924
  var findParticipant = function findParticipant(participant, collection) {
@@ -707,7 +947,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
707
947
  return deltas;
708
948
  };
709
949
  this.deltaParticipants = participants.reduce(function (collection, participant) {
710
- var existingParticipant = findParticipant(participant, _this4.participants || []) || {};
950
+ var existingParticipant = findParticipant(participant, _this6.participants || []) || {};
711
951
  var delta = generateDelta(existingParticipant.status, participant.status);
712
952
  var changed = (0, _keys.default)(delta).length > 0;
713
953
  if (changed) {
@@ -723,19 +963,21 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
723
963
  /**
724
964
  * update meeting's members
725
965
  * @param {Object} participants new participants object
966
+ * @param {Array} removedParticipantIds list of removed participants
726
967
  * @param {Boolean} isReplace is replace the whole members
727
968
  * @returns {Array} updatedParticipants
728
969
  * @memberof LocusInfo
729
970
  */
730
971
  }, {
731
972
  key: "updateParticipants",
732
- value: function updateParticipants(participants, isReplace) {
973
+ value: function updateParticipants(participants, removedParticipantIds, isReplace) {
733
974
  var _this$parsedLocus$con;
734
975
  this.emitScoped({
735
976
  file: 'locus-info',
736
977
  function: 'updateParticipants'
737
978
  }, _constants.EVENTS.LOCUS_INFO_UPDATE_PARTICIPANTS, {
738
979
  participants: participants,
980
+ removedParticipantIds: removedParticipantIds,
739
981
  recordingId: this.parsedLocus.controls && ((_this$parsedLocus$con = this.parsedLocus.controls.record) === null || _this$parsedLocus$con === void 0 ? void 0 : _this$parsedLocus$con.modifiedBy),
740
982
  selfIdentity: this.parsedLocus.self && this.parsedLocus.self.selfIdentity,
741
983
  selfId: this.parsedLocus.self && this.parsedLocus.self.selfId,
@@ -1637,7 +1879,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1637
1879
  }, {
1638
1880
  key: "updateMainSessionLocusCache",
1639
1881
  value: function updateMainSessionLocusCache(mainLocus) {
1640
- var _this5 = this;
1882
+ var _this7 = this;
1641
1883
  if (!mainLocus) {
1642
1884
  return;
1643
1885
  }
@@ -1646,7 +1888,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1646
1888
  // shallow merge and do special merge for participants
1647
1889
  (0, _lodash.assignWith)(this.mainSessionLocusCache, locusClone, function (objValue, srcValue, key) {
1648
1890
  if (key === 'participants') {
1649
- return _this5.mergeParticipants(objValue, srcValue);
1891
+ return _this7.mergeParticipants(objValue, srcValue);
1650
1892
  }
1651
1893
  return srcValue || objValue;
1652
1894
  });