@webex/plugin-meetings 3.12.0-next.5 → 3.12.0-next.50

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 (136) hide show
  1. package/AGENTS.md +9 -0
  2. package/dist/aiEnableRequest/index.js +15 -2
  3. package/dist/aiEnableRequest/index.js.map +1 -1
  4. package/dist/breakouts/breakout.js +6 -2
  5. package/dist/breakouts/breakout.js.map +1 -1
  6. package/dist/breakouts/index.js +1 -1
  7. package/dist/config.js +1 -0
  8. package/dist/config.js.map +1 -1
  9. package/dist/constants.js +6 -3
  10. package/dist/constants.js.map +1 -1
  11. package/dist/controls-options-manager/constants.js +11 -1
  12. package/dist/controls-options-manager/constants.js.map +1 -1
  13. package/dist/controls-options-manager/index.js +38 -24
  14. package/dist/controls-options-manager/index.js.map +1 -1
  15. package/dist/controls-options-manager/util.js +91 -0
  16. package/dist/controls-options-manager/util.js.map +1 -1
  17. package/dist/hashTree/constants.js +10 -1
  18. package/dist/hashTree/constants.js.map +1 -1
  19. package/dist/hashTree/hashTreeParser.js +593 -358
  20. package/dist/hashTree/hashTreeParser.js.map +1 -1
  21. package/dist/hashTree/utils.js +22 -0
  22. package/dist/hashTree/utils.js.map +1 -1
  23. package/dist/index.js +7 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/interceptors/locusRetry.js +23 -8
  26. package/dist/interceptors/locusRetry.js.map +1 -1
  27. package/dist/interpretation/index.js +10 -1
  28. package/dist/interpretation/index.js.map +1 -1
  29. package/dist/interpretation/siLanguage.js +1 -1
  30. package/dist/locus-info/controlsUtils.js +4 -1
  31. package/dist/locus-info/controlsUtils.js.map +1 -1
  32. package/dist/locus-info/index.js +277 -86
  33. package/dist/locus-info/index.js.map +1 -1
  34. package/dist/locus-info/types.js +16 -0
  35. package/dist/locus-info/types.js.map +1 -1
  36. package/dist/media/properties.js +1 -0
  37. package/dist/media/properties.js.map +1 -1
  38. package/dist/meeting/in-meeting-actions.js +3 -1
  39. package/dist/meeting/in-meeting-actions.js.map +1 -1
  40. package/dist/meeting/index.js +842 -521
  41. package/dist/meeting/index.js.map +1 -1
  42. package/dist/meeting/util.js +19 -2
  43. package/dist/meeting/util.js.map +1 -1
  44. package/dist/meetings/index.js +199 -77
  45. package/dist/meetings/index.js.map +1 -1
  46. package/dist/meetings/meetings.types.js +6 -1
  47. package/dist/meetings/meetings.types.js.map +1 -1
  48. package/dist/meetings/request.js +39 -0
  49. package/dist/meetings/request.js.map +1 -1
  50. package/dist/meetings/util.js +67 -5
  51. package/dist/meetings/util.js.map +1 -1
  52. package/dist/member/index.js +10 -0
  53. package/dist/member/index.js.map +1 -1
  54. package/dist/member/types.js.map +1 -1
  55. package/dist/member/util.js +3 -0
  56. package/dist/member/util.js.map +1 -1
  57. package/dist/metrics/constants.js +2 -1
  58. package/dist/metrics/constants.js.map +1 -1
  59. package/dist/recording-controller/index.js +1 -3
  60. package/dist/recording-controller/index.js.map +1 -1
  61. package/dist/types/config.d.ts +1 -0
  62. package/dist/types/constants.d.ts +2 -0
  63. package/dist/types/controls-options-manager/constants.d.ts +6 -1
  64. package/dist/types/controls-options-manager/index.d.ts +10 -0
  65. package/dist/types/hashTree/constants.d.ts +1 -0
  66. package/dist/types/hashTree/hashTreeParser.d.ts +61 -15
  67. package/dist/types/hashTree/utils.d.ts +11 -0
  68. package/dist/types/index.d.ts +2 -0
  69. package/dist/types/interceptors/locusRetry.d.ts +4 -4
  70. package/dist/types/locus-info/index.d.ts +46 -6
  71. package/dist/types/locus-info/types.d.ts +17 -1
  72. package/dist/types/media/properties.d.ts +1 -0
  73. package/dist/types/meeting/in-meeting-actions.d.ts +2 -0
  74. package/dist/types/meeting/index.d.ts +70 -1
  75. package/dist/types/meeting/util.d.ts +8 -0
  76. package/dist/types/meetings/index.d.ts +18 -1
  77. package/dist/types/meetings/meetings.types.d.ts +15 -0
  78. package/dist/types/meetings/request.d.ts +14 -0
  79. package/dist/types/member/index.d.ts +1 -0
  80. package/dist/types/member/types.d.ts +1 -0
  81. package/dist/types/member/util.d.ts +1 -0
  82. package/dist/types/metrics/constants.d.ts +1 -0
  83. package/dist/webinar/index.js +361 -235
  84. package/dist/webinar/index.js.map +1 -1
  85. package/package.json +22 -22
  86. package/src/aiEnableRequest/index.ts +16 -0
  87. package/src/breakouts/breakout.ts +2 -1
  88. package/src/config.ts +1 -0
  89. package/src/constants.ts +5 -1
  90. package/src/controls-options-manager/constants.ts +14 -1
  91. package/src/controls-options-manager/index.ts +47 -24
  92. package/src/controls-options-manager/util.ts +81 -1
  93. package/src/hashTree/constants.ts +9 -0
  94. package/src/hashTree/hashTreeParser.ts +306 -160
  95. package/src/hashTree/utils.ts +17 -0
  96. package/src/index.ts +5 -0
  97. package/src/interceptors/locusRetry.ts +25 -4
  98. package/src/interpretation/index.ts +25 -8
  99. package/src/locus-info/controlsUtils.ts +3 -1
  100. package/src/locus-info/index.ts +276 -93
  101. package/src/locus-info/types.ts +19 -1
  102. package/src/media/properties.ts +1 -0
  103. package/src/meeting/in-meeting-actions.ts +4 -0
  104. package/src/meeting/index.ts +315 -26
  105. package/src/meeting/util.ts +20 -2
  106. package/src/meetings/index.ts +104 -43
  107. package/src/meetings/meetings.types.ts +19 -0
  108. package/src/meetings/request.ts +43 -0
  109. package/src/meetings/util.ts +80 -1
  110. package/src/member/index.ts +10 -0
  111. package/src/member/types.ts +1 -0
  112. package/src/member/util.ts +3 -0
  113. package/src/metrics/constants.ts +1 -0
  114. package/src/recording-controller/index.ts +1 -2
  115. package/src/webinar/index.ts +162 -21
  116. package/test/unit/spec/aiEnableRequest/index.ts +86 -0
  117. package/test/unit/spec/breakouts/breakout.ts +7 -3
  118. package/test/unit/spec/controls-options-manager/index.js +140 -29
  119. package/test/unit/spec/controls-options-manager/util.js +165 -0
  120. package/test/unit/spec/hashTree/hashTreeParser.ts +1294 -191
  121. package/test/unit/spec/hashTree/utils.ts +88 -1
  122. package/test/unit/spec/interceptors/locusRetry.ts +205 -4
  123. package/test/unit/spec/interpretation/index.ts +26 -4
  124. package/test/unit/spec/locus-info/controlsUtils.js +172 -57
  125. package/test/unit/spec/locus-info/index.js +443 -81
  126. package/test/unit/spec/meeting/in-meeting-actions.ts +2 -0
  127. package/test/unit/spec/meeting/index.js +836 -41
  128. package/test/unit/spec/meeting/muteState.js +3 -0
  129. package/test/unit/spec/meeting/utils.js +33 -0
  130. package/test/unit/spec/meetings/index.js +275 -10
  131. package/test/unit/spec/meetings/request.js +141 -0
  132. package/test/unit/spec/meetings/utils.js +161 -0
  133. package/test/unit/spec/member/index.js +7 -0
  134. package/test/unit/spec/member/util.js +24 -0
  135. package/test/unit/spec/recording-controller/index.js +9 -8
  136. package/test/unit/spec/webinar/index.ts +141 -16
@@ -32,9 +32,9 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/he
32
32
  var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
33
33
  var _assign = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/assign"));
34
34
  var _map = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/map"));
35
+ var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
35
36
  var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
36
37
  var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
37
- var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
38
38
  var _lodash = require("lodash");
39
39
  var _loggerProxy = _interopRequireDefault(require("../common/logs/logger-proxy"));
40
40
  var _eventsScope = _interopRequireDefault(require("../common/events/events-scope"));
@@ -53,7 +53,7 @@ var _hashTreeParser2 = _interopRequireWildcard(require("../hashTree/hashTreePars
53
53
  var _types = require("../hashTree/types");
54
54
  var _utils = require("../hashTree/utils");
55
55
  var _util = _interopRequireDefault(require("../meetings/util"));
56
- function _interopRequireWildcard(e, t) { if ("function" == typeof _WeakMap) var r = new _WeakMap(), n = new _WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = _Object$defineProperty) && _Object$getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); }
56
+ function _interopRequireWildcard(e, t) { if ("function" == typeof _WeakMap) var r = new _WeakMap(), n = new _WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t3 in e) "default" !== _t3 && {}.hasOwnProperty.call(e, _t3) && ((i = (o = _Object$defineProperty) && _Object$getOwnPropertyDescriptor(e, _t3)) && (i.get || i.set) ? o(f, _t3, i) : f[_t3] = e[_t3]); return f; })(e, t); }
57
57
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
58
58
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
59
59
  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; }
@@ -76,7 +76,7 @@ var LocusObjectStateAfterUpdates = {
76
76
  * Gets the replacement information
77
77
  *
78
78
  * @param {any} self - "self" object from Locus DTO
79
- * @param {string} deviceUrl - The URL of the user's device
79
+ * @param {string} deviceUrl - The URL of the specified device
80
80
  * @returns {any} The replace information if available, otherwise undefined
81
81
  */
82
82
  function getReplaceInfoFromSelf(self, deviceUrl) {
@@ -115,11 +115,13 @@ function findLocusUrlInAnyHashTreeParser(meetingCollection, locusUrl) {
115
115
  *
116
116
  * @param {HashTreeMessage} message - The hash tree message to find the meeting for
117
117
  * @param {MeetingCollection} meetingCollection - The collection of meetings to search
118
- * @param {string} deviceUrl - The URL of the user's device
119
118
  * @returns {any} The meeting if found, otherwise undefined
120
119
  */
121
- function findMeetingForHashTreeMessage(message, meetingCollection, deviceUrl) {
120
+ function findMeetingForHashTreeMessage(message, meetingCollection) {
122
121
  var _message$locusStateEl, _message$locusStateEl2;
122
+ if (!message) {
123
+ return undefined;
124
+ }
123
125
  var foundMeeting = findLocusUrlInAnyHashTreeParser(meetingCollection, message.locusUrl);
124
126
  if (foundMeeting) {
125
127
  return foundMeeting;
@@ -130,7 +132,7 @@ function findMeetingForHashTreeMessage(message, meetingCollection, deviceUrl) {
130
132
  var self = (_message$locusStateEl = message.locusStateElements) === null || _message$locusStateEl === void 0 ? void 0 : (_message$locusStateEl2 = _message$locusStateEl.find(function (el) {
131
133
  return (0, _utils.isSelf)(el);
132
134
  })) === null || _message$locusStateEl2 === void 0 ? void 0 : _message$locusStateEl2.data;
133
- var replaces = getReplaceInfoFromSelf(self, deviceUrl);
135
+ var replaces = getReplaceInfoFromSelf(self, self === null || self === void 0 ? void 0 : self.deviceUrl);
134
136
  if (replaces !== null && replaces !== void 0 && replaces.locusUrl) {
135
137
  foundMeeting = findLocusUrlInAnyHashTreeParser(meetingCollection, replaces.locusUrl);
136
138
  return foundMeeting;
@@ -511,7 +513,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
511
513
  }, {
512
514
  key: "createHashTreeParser",
513
515
  value: function createHashTreeParser(_ref) {
514
- var _this$webex$config$me;
516
+ var _locusUrl$split, _locusUrl$split$pop, _this$webex$config$me;
515
517
  var locusUrl = _ref.locusUrl,
516
518
  initialLocus = _ref.initialLocus,
517
519
  metadata = _ref.metadata,
@@ -521,7 +523,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
521
523
  metadata: metadata,
522
524
  webexRequest: this.webex.request.bind(this.webex),
523
525
  locusInfoUpdateCallback: this.updateFromHashTree.bind(this, locusUrl),
524
- debugId: "HT-".concat(locusUrl.split('/').pop().substring(0, 4)),
526
+ debugId: "HT-".concat((_locusUrl$split = locusUrl.split('/')) === null || _locusUrl$split === void 0 ? void 0 : (_locusUrl$split$pop = _locusUrl$split.pop()) === null || _locusUrl$split$pop === void 0 ? void 0 : _locusUrl$split$pop.substring(0, 4)),
525
527
  excludedDataSets: (_this$webex$config$me = this.webex.config.meetings.locus) === null || _this$webex$config$me === void 0 ? void 0 : _this$webex$config$me.excludedDataSets
526
528
  });
527
529
 
@@ -558,18 +560,20 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
558
560
 
559
561
  /**
560
562
  * @param {Object} data - data to initialize locus info with. It may be from a join or GET /loci response or from a Mercury event that triggers a creation of meeting object
563
+ * @param {Function} [onLocusSynced] - optional callback that will be called at the end of initial setup, when locus info is fully synced. It will be called with the full locus snapshot as an argument (which may be null if we haven't received any full locus DTOs during the initial setup, for example in case we receive only hash tree messages without full locus DTOs)
561
564
  * @returns {undefined}
562
565
  * @memberof LocusInfo
563
566
  */
564
567
  }, {
565
568
  key: "initialSetup",
566
569
  value: (function () {
567
- var _initialSetup = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee(data) {
570
+ var _initialSetup = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee(data, onLocusSynced) {
568
571
  var _data$locus, _data$locus$links, _data$locus$links$res, _data$locus$links$res2;
569
- var _data$hashTreeMessage, _metadataObject$data, metadataObject, hashTreeParser, _hashTreeParser, _t;
572
+ var initialFullLocus, _data$hashTreeMessage, _metadataObject$data, metadataObject, hashTreeParser, _hashTreeParser, _t;
570
573
  return _regenerator.default.wrap(function (_context) {
571
574
  while (1) switch (_context.prev = _context.next) {
572
575
  case 0:
576
+ initialFullLocus = null;
573
577
  _t = data.trigger;
574
578
  _context.next = _t === 'locus-message' ? 1 : _t === 'join-response' ? 6 : _t === 'get-loci-response' ? 7 : 10;
575
579
  break;
@@ -621,6 +625,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
621
625
  case 6:
622
626
  this.updateLocusCache(data.locus);
623
627
  this.onFullLocus('join response', data.locus, undefined, data.dataSets, data.metadata);
628
+ initialFullLocus = data.locus;
624
629
  return _context.abrupt("continue", 10);
625
630
  case 7:
626
631
  if (!((_data$locus = data.locus) !== null && _data$locus !== void 0 && (_data$locus$links = _data$locus.links) !== null && _data$locus$links !== void 0 && (_data$locus$links$res = _data$locus$links.resources) !== null && _data$locus$links$res !== void 0 && (_data$locus$links$res2 = _data$locus$links$res.visibleDataSets) !== null && _data$locus$links$res2 !== void 0 && _data$locus$links$res2.url)) {
@@ -646,7 +651,16 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
646
651
  // "classic" Locus case, no hash trees involved
647
652
  this.updateLocusCache(data.locus);
648
653
  this.onFullLocus('classic get-loci-response', data.locus, undefined);
654
+ initialFullLocus = data.locus || null;
649
655
  case 10:
656
+ if (onLocusSynced) {
657
+ try {
658
+ onLocusSynced(initialFullLocus || this.getCurrentLocusSnapshot());
659
+ } catch (error) {
660
+ _loggerProxy.default.logger.warn("Locus-info:index#initialSetup --> onLocusSynced callback failed: ".concat(error));
661
+ }
662
+ }
663
+
650
664
  // Change it to true after it receives it first locus object
651
665
  this.emitChange = true;
652
666
  case 11:
@@ -655,18 +669,40 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
655
669
  }
656
670
  }, _callee, this);
657
671
  }));
658
- function initialSetup(_x) {
672
+ function initialSetup(_x, _x2) {
659
673
  return _initialSetup.apply(this, arguments);
660
674
  }
661
675
  return initialSetup;
662
676
  }()
677
+ /**
678
+ * Builds a full locus DTO snapshot from current internal locus state.
679
+ *
680
+ * @returns {LocusDTO}
681
+ */
682
+ )
683
+ }, {
684
+ key: "getCurrentLocusSnapshot",
685
+ value: function getCurrentLocusSnapshot() {
686
+ var _this4 = this;
687
+ var locus = {};
688
+ LocusDtoTopLevelKeys.forEach(function (key) {
689
+ var value = _this4[key];
690
+ if (value !== undefined && value !== null) {
691
+ locus[key] = (0, _lodash.cloneDeep)(value);
692
+ }
693
+ });
694
+ if (!(0, _isArray.default)(locus.participants)) {
695
+ locus.participants = [];
696
+ }
697
+ return locus;
698
+ }
699
+
663
700
  /**
664
701
  * Handles HTTP response from Locus API call.
665
702
  * @param {Meeting} meeting meeting object
666
703
  * @param {LocusApiResponseBody} responseBody body of the http response from Locus API call
667
704
  * @returns {void}
668
705
  */
669
- )
670
706
  }, {
671
707
  key: "handleLocusAPIResponse",
672
708
  value: function handleLocusAPIResponse(meeting, responseBody) {
@@ -674,29 +710,39 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
674
710
  var isWrapped = 'locus' in responseBody;
675
711
  var locusUrl = isWrapped ? (_responseBody$locus = responseBody.locus) === null || _responseBody$locus === void 0 ? void 0 : _responseBody$locus.url : responseBody.url;
676
712
  var hashTreeParserEntry = locusUrl && this.hashTreeParsers.get(locusUrl);
677
- if (hashTreeParserEntry) {
678
- if (isWrapped) {
679
- if (!responseBody.dataSets) {
680
- this.sendClassicVsHashTreeMismatchMetric(meeting, "expected hash tree dataSets in API response but they are missing");
681
- // continuing as we can still manage without responseBody.dataSets, but this is very suspicious
713
+ var locus = isWrapped ? responseBody.locus : responseBody;
714
+ if (this.hashTreeParsers.size > 0) {
715
+ // We are in hash tree mode. Check if we need to create/reactivate a parser for this locusUrl.
716
+ if (!hashTreeParserEntry || hashTreeParserEntry.parser.state === 'stopped') {
717
+ if (!locusUrl) {
718
+ _loggerProxy.default.logger.warn('Locus-info:index#handleLocusAPIResponse --> API response has no locusUrl, cannot handle hash tree parser switch');
719
+ return;
682
720
  }
721
+ this.handleHashTreeParserSwitchForAPIResponse(locusUrl, locus);
722
+ return;
723
+ }
724
+
725
+ // Active parser found - pass the API response to it
726
+ if (isWrapped) {
683
727
  _loggerProxy.default.logger.info('Locus-info:index#handleLocusAPIResponse --> passing Locus API response to HashTreeParser: ', responseBody);
684
728
  // update the data in our hash trees
685
729
  hashTreeParserEntry.parser.handleLocusUpdate(responseBody);
686
730
  } else {
687
- // LocusDTO without wrapper - pass it through as if it had no dataSets
731
+ // LocusDTO without wrapper - pass it through as if it had no dataSets nor metadata
688
732
  hashTreeParserEntry.parser.handleLocusUpdate({
689
733
  locus: responseBody
690
734
  });
691
735
  }
692
- } else {
693
- if (isWrapped && responseBody.dataSets) {
694
- this.sendClassicVsHashTreeMismatchMetric(meeting, "unexpected hash tree dataSets in API response");
695
- }
696
- // classic Locus delta
697
- var locus = isWrapped ? responseBody.locus : responseBody;
698
- this.handleLocusDelta(locus, meeting);
736
+ return;
699
737
  }
738
+
739
+ // No hash tree parsers - classic Locus mode
740
+ if (isWrapped && responseBody.dataSets) {
741
+ this.sendClassicVsHashTreeMismatchMetric(meeting, "unexpected hash tree dataSets in API response");
742
+ }
743
+
744
+ // classic Locus delta
745
+ this.handleLocusDelta(locus, meeting);
700
746
  }
701
747
 
702
748
  /**
@@ -707,7 +753,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
707
753
  }, {
708
754
  key: "updateLocusFromHashTreeObject",
709
755
  value: function updateLocusFromHashTreeObject(object, locus) {
710
- var _this4 = this,
756
+ var _this5 = this,
711
757
  _locus$self;
712
758
  var type = object.htMeta.elementId.type.toLowerCase();
713
759
  var addParticipantObject = function addParticipantObject(obj) {
@@ -715,7 +761,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
715
761
  locus.participants = [];
716
762
  }
717
763
  locus.participants.push(obj.data);
718
- _this4.hashTreeObjectId2ParticipantId.set(obj.htMeta.elementId.id, obj.data.id);
764
+ _this5.hashTreeObjectId2ParticipantId.set(obj.htMeta.elementId.id, obj.data.id);
719
765
  };
720
766
  switch (type) {
721
767
  case _types.ObjectType.locus:
@@ -879,6 +925,81 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
879
925
  }
880
926
  }
881
927
 
928
+ /**
929
+ * Helper that handles the common logic for reactivating a stopped HashTreeParser when
930
+ * a newer "replaces" is detected. Used by both the message and API response parser switch methods.
931
+ *
932
+ * @param {string} callerName - name of the calling method, used in log messages
933
+ * @param {string} locusUrl - the locus URL of the stopped parser
934
+ * @param {HashTreeParserEntry} stoppedEntry - the stopped parser entry
935
+ * @param {ReplacesInfo} replaces - replacement info extracted from self
936
+ * @param {Function} resumeCallback - callback to invoke after reactivation to resume the parser
937
+ * @returns {void}
938
+ */
939
+ }, {
940
+ key: "resumeStoppedParser",
941
+ value: function resumeStoppedParser(callerName, locusUrl, stoppedEntry, replaces, resumeCallback) {
942
+ // this check is just for typescript, it should never happen, replaces should always be defined
943
+ if (!replaces) {
944
+ _loggerProxy.default.logger.info("Locus-info:index#".concat(callerName, " --> received data for stopped HashTreeParser with locusUrl ").concat(locusUrl, ", but no replaces info provided, so not re-activating the parser"));
945
+ return;
946
+ }
947
+ if (replaces.replacedAt <= (stoppedEntry.replacedAt || '')) {
948
+ _loggerProxy.default.logger.info("Locus-info:index#".concat(callerName, " --> received data for stopped HashTreeParser with locusUrl ").concat(locusUrl, ", but replaces info provided is not newer, so not re-activating the parser"));
949
+ return;
950
+ }
951
+ _loggerProxy.default.logger.info("Locus-info:index#".concat(callerName, " --> reactivating HashTreeParser for locusUrl=").concat(locusUrl, ", which replaces ").concat(replaces.locusUrl));
952
+ var replacedEntry = this.hashTreeParsers.get(replaces.locusUrl);
953
+ if (replacedEntry) {
954
+ replacedEntry.replacedAt = replaces.replacedAt;
955
+ replacedEntry.parser.stop();
956
+ } else {
957
+ _loggerProxy.default.logger.warn("Locus-info:index#".concat(callerName, " --> the parser that is supposed to be replaced with the currently reactivated parser is not found, locusUrl=").concat(replaces.locusUrl));
958
+ }
959
+ stoppedEntry.initializedFromHashTree = false;
960
+ this.hashTreeObjectId2ParticipantId.clear();
961
+ resumeCallback();
962
+ }
963
+
964
+ /**
965
+ * Handles an API response whose locusUrl doesn't match any active HashTreeParser
966
+ * (either no entry exists, or the existing entry is stopped).
967
+ * Creates a new parser or reactivates a stopped one using initializeFromGetLociResponse.
968
+ *
969
+ * @param {string} locusUrl - the locus URL from the API response
970
+ * @param {LocusDTO} locus - the locus DTO from the API response
971
+ * @returns {void}
972
+ */
973
+ }, {
974
+ key: "handleHashTreeParserSwitchForAPIResponse",
975
+ value: function handleHashTreeParserSwitchForAPIResponse(locusUrl, locus) {
976
+ var entry = this.hashTreeParsers.get(locusUrl);
977
+ var replaces = getReplaceInfoFromSelf(locus.self,
978
+ // @ts-ignore
979
+ this.webex.internal.device.url);
980
+ if (!entry) {
981
+ _loggerProxy.default.logger.info("Locus-info:index#handleHashTreeParserSwitchForAPIResponse --> no parser for locusUrl ".concat(locusUrl, ", creating a new one"));
982
+ var parser = this.createHashTreeParser({
983
+ locusUrl: locusUrl,
984
+ initialLocus: {
985
+ locus: null,
986
+ dataSets: []
987
+ },
988
+ metadata: null,
989
+ replacedAt: replaces === null || replaces === void 0 ? void 0 : replaces.replacedAt
990
+ });
991
+ parser.initializeFromGetLociResponse(locus);
992
+ return;
993
+ }
994
+ if (entry.parser.state !== 'stopped') {
995
+ _loggerProxy.default.logger.warn("Locus-info:index#handleHashTreeParserSwitchForAPIResponse --> unexpected parser state \"".concat(entry.parser.state, "\" for locusUrl ").concat(locusUrl));
996
+ return;
997
+ }
998
+ this.resumeStoppedParser('handleHashTreeParserSwitchForAPIResponse', locusUrl, entry, replaces, function () {
999
+ return entry.parser.resumeFromApiResponse(locus);
1000
+ });
1001
+ }
1002
+
882
1003
  /**
883
1004
  * Checks if the hash tree message should trigger a switch to a different HashTreeParser
884
1005
  *
@@ -903,7 +1024,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
903
1024
  var metadata = (_message$locusStateEl5 = message.locusStateElements) === null || _message$locusStateEl5 === void 0 ? void 0 : _message$locusStateEl5.find(function (el) {
904
1025
  return (0, _utils.isMetadata)(el);
905
1026
  });
906
- if ((metadata === null || metadata === void 0 ? void 0 : (_metadata$data = metadata.data) === null || _metadata$data === void 0 ? void 0 : (_metadata$data$visibl = _metadata$data.visibleDataSets) === null || _metadata$data$visibl === void 0 ? void 0 : _metadata$data$visibl.length) > 0) {
1027
+ if (metadata && ((_metadata$data = metadata.data) === null || _metadata$data === void 0 ? void 0 : (_metadata$data$visibl = _metadata$data.visibleDataSets) === null || _metadata$data$visibl === void 0 ? void 0 : _metadata$data$visibl.length) > 0) {
907
1028
  _loggerProxy.default.logger.info("Locus-info:index#handleHashTreeParserSwitch --> no hash tree parser found for locusUrl ".concat(message.locusUrl, ", creating a new one"));
908
1029
  var parser = this.createHashTreeParser({
909
1030
  locusUrl: message.locusUrl,
@@ -926,25 +1047,9 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
926
1047
  if (entry.parser.state === 'stopped') {
927
1048
  // the message matches a stopped parser, we need to check if maybe this is a new "replacement" and we need to re-activate the parser
928
1049
  // this happens when you move from breakout A -> breakout B -> back to breakout A
929
- if (replaces) {
930
- if (replaces.replacedAt > (entry.replacedAt || '')) {
931
- _loggerProxy.default.logger.info("Locus-info:index#handleHashTreeParserSwitch --> resuming a HashTreeParser for locusUrl=".concat(message.locusUrl, ", which replaces ").concat(replaces.locusUrl));
932
- var replacedEntry = this.hashTreeParsers.get(replaces.locusUrl);
933
- if (replacedEntry) {
934
- replacedEntry.replacedAt = replaces.replacedAt;
935
- entry.initializedFromHashTree = false;
936
- this.hashTreeObjectId2ParticipantId.clear();
937
- replacedEntry.parser.stop();
938
- entry.parser.resume(message);
939
- } else {
940
- _loggerProxy.default.logger.warn("Locus-info:index#handleHashTreeParserSwitch --> the parser that is supposed to be replaced with the currently resumed parser is not found, locusUrl=".concat(replaces.locusUrl));
941
- }
942
- } else {
943
- _loggerProxy.default.logger.info("Locus-info:index#handleHashTreeParserSwitch --> received message for stopped HashTreeParser with locusUrl ".concat(message.locusUrl, ", but replaces info provided is not newer, so not re-activating the parser"));
944
- }
945
- return true;
946
- }
947
- _loggerProxy.default.logger.info("Locus-info:index#handleHashTreeParserSwitch --> received message for stopped HashTreeParser with locusUrl ".concat(message.locusUrl, ", but no replaces info provided, so not re-activating the parser"));
1050
+ this.resumeStoppedParser('handleHashTreeParserSwitch', message.locusUrl, entry, replaces, function () {
1051
+ return entry.parser.resumeFromMessage(message);
1052
+ });
948
1053
  return true;
949
1054
  }
950
1055
  return false;
@@ -970,23 +1075,81 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
970
1075
  return;
971
1076
  }
972
1077
  var entry = this.hashTreeParsers.get(message.locusUrl);
973
- entry.parser.handleMessage(message);
1078
+
1079
+ // the check is just for typescript, the case of no entry in hashTreeParsers is handled in handleHashTreeParserSwitch() above
1080
+ if (entry) {
1081
+ entry.parser.handleMessage(message);
1082
+ }
974
1083
  }
975
1084
 
1085
+ /**
1086
+ * Triggers a sync of all hash tree datasets for all hash tree parsers associated with this meeting.
1087
+ * The syncs are executed sequentially within each parser.
1088
+ *
1089
+ * @returns {Promise<void>}
1090
+ */
1091
+ }, {
1092
+ key: "syncAllHashTreeDatasets",
1093
+ value: (function () {
1094
+ var _syncAllHashTreeDatasets = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
1095
+ var _iterator3, _step3, _step3$value, entry, _t2;
1096
+ return _regenerator.default.wrap(function (_context2) {
1097
+ while (1) switch (_context2.prev = _context2.next) {
1098
+ case 0:
1099
+ _iterator3 = _createForOfIteratorHelper(this.hashTreeParsers);
1100
+ _context2.prev = 1;
1101
+ _iterator3.s();
1102
+ case 2:
1103
+ if ((_step3 = _iterator3.n()).done) {
1104
+ _context2.next = 4;
1105
+ break;
1106
+ }
1107
+ _step3$value = (0, _slicedToArray2.default)(_step3.value, 2), entry = _step3$value[1];
1108
+ if (!entry.parser) {
1109
+ _context2.next = 3;
1110
+ break;
1111
+ }
1112
+ _context2.next = 3;
1113
+ return entry.parser.syncAllDatasets();
1114
+ case 3:
1115
+ _context2.next = 2;
1116
+ break;
1117
+ case 4:
1118
+ _context2.next = 6;
1119
+ break;
1120
+ case 5:
1121
+ _context2.prev = 5;
1122
+ _t2 = _context2["catch"](1);
1123
+ _iterator3.e(_t2);
1124
+ case 6:
1125
+ _context2.prev = 6;
1126
+ _iterator3.f();
1127
+ return _context2.finish(6);
1128
+ case 7:
1129
+ case "end":
1130
+ return _context2.stop();
1131
+ }
1132
+ }, _callee2, this, [[1, 5, 6, 7]]);
1133
+ }));
1134
+ function syncAllHashTreeDatasets() {
1135
+ return _syncAllHashTreeDatasets.apply(this, arguments);
1136
+ }
1137
+ return syncAllHashTreeDatasets;
1138
+ }()
976
1139
  /**
977
1140
  * Callback registered with HashTreeParser to receive locus info updates.
978
1141
  * Updates our locus info based on the data parsed by the hash tree parser.
979
1142
  *
980
1143
  * @param {string} locusUrl - the locus URL for which the update is received
981
- * @param {LocusInfoUpdateType} updateType - The type of update received.
982
- * @param {Object} [data] - Additional data for the update, if applicable.
1144
+ * @param {LocusInfoUpdate} update - Details about the update.
983
1145
  * @returns {void}
984
1146
  */
1147
+ )
985
1148
  }, {
986
1149
  key: "updateFromHashTree",
987
- value: function updateFromHashTree(locusUrl, updateType, data) {
988
- var _this5 = this;
989
- switch (updateType) {
1150
+ value: function updateFromHashTree(locusUrl, update) {
1151
+ var _this6 = this;
1152
+ switch (update.updateType) {
990
1153
  case _hashTreeParser2.LocusInfoUpdateType.OBJECTS_UPDATED:
991
1154
  {
992
1155
  // initialize our new locus
@@ -1000,7 +1163,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1000
1163
 
1001
1164
  // first go over all the updates and check what happens with the main locus object
1002
1165
  var locusObjectStateAfterUpdates = LocusObjectStateAfterUpdates.unchanged;
1003
- data.updatedObjects.forEach(function (object) {
1166
+ update.updatedObjects.forEach(function (object) {
1004
1167
  if (object.htMeta.elementId.type.toLowerCase() === _types.ObjectType.locus) {
1005
1168
  if (locusObjectStateAfterUpdates === LocusObjectStateAfterUpdates.updated) {
1006
1169
  var _object$data;
@@ -1009,7 +1172,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1009
1172
  // but these should never happen
1010
1173
  _loggerProxy.default.logger.warn("Locus-info:index#updateFromHashTree --> received multiple LOCUS objects in one update, this is unexpected!");
1011
1174
  _metrics.default.sendBehavioralMetric(_constants2.default.LOCUS_HASH_TREE_UNSUPPORTED_OPERATION, {
1012
- locusUrl: ((_object$data = object.data) === null || _object$data === void 0 ? void 0 : _object$data.url) || _this5.url,
1175
+ locusUrl: ((_object$data = object.data) === null || _object$data === void 0 ? void 0 : _object$data.url) || _this6.url,
1013
1176
  message: object.data ? 'multiple LOCUS object updates' : 'LOCUS object update followed by removal'
1014
1177
  });
1015
1178
  }
@@ -1021,12 +1184,17 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1021
1184
  }
1022
1185
  });
1023
1186
  var hashTreeParserEntry = this.hashTreeParsers.get(locusUrl);
1187
+ if (!hashTreeParserEntry) {
1188
+ _loggerProxy.default.logger.warn("Locus-info:index#updateFromHashTree --> no HashTreeParser found for locusUrl ".concat(locusUrl, " when trying to apply updates from hash tree"));
1189
+ return;
1190
+ }
1024
1191
  if (!hashTreeParserEntry.initializedFromHashTree) {
1025
1192
  // this is the first time we're getting an update for this locusUrl,
1026
1193
  // so it's probably a move to/from breakout. We need to start from a clean state,
1027
1194
  // so empty locus and we rely on Locus giving us sufficient data in the updates to populate it.
1028
1195
  _loggerProxy.default.logger.info("Locus-info:index#updateFromHashTree --> first INITIAL update for locusUrl ".concat(locusUrl, ", starting from empty state"));
1029
1196
  hashTreeParserEntry.initializedFromHashTree = true;
1197
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1030
1198
  locus.jsSdkMeta.forceReplaceMembers = true;
1031
1199
  } else if (
1032
1200
  // if Locus object is unchanged or removed, we need to keep using the existing locus
@@ -1038,7 +1206,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1038
1206
  // copy over all of existing locus except participants
1039
1207
  LocusDtoTopLevelKeys.forEach(function (key) {
1040
1208
  if (key !== 'participants') {
1041
- locus[key] = (0, _lodash.cloneDeep)(_this5[key]);
1209
+ locus[key] = (0, _lodash.cloneDeep)(_this6[key]);
1042
1210
  }
1043
1211
  });
1044
1212
  } else {
@@ -1046,11 +1214,11 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1046
1214
  // (except participants, which need to stay empty - that means "no participant changes")
1047
1215
  (0, _values.default)(_types.ObjectTypeToLocusKeyMap).forEach(function (locusDtoKey) {
1048
1216
  if (locusDtoKey !== 'participants') {
1049
- locus[locusDtoKey] = (0, _lodash.cloneDeep)(_this5[locusDtoKey]);
1217
+ locus[locusDtoKey] = (0, _lodash.cloneDeep)(_this6[locusDtoKey]);
1050
1218
  }
1051
1219
  });
1052
1220
  }
1053
- _loggerProxy.default.logger.info("Locus-info:index#updateFromHashTree --> LOCUS object is ".concat(locusObjectStateAfterUpdates, ", all updates: ").concat((0, _stringify.default)(data.updatedObjects.map(function (o) {
1221
+ _loggerProxy.default.logger.info("Locus-info:index#updateFromHashTree --> LOCUS object is ".concat(locusObjectStateAfterUpdates, ", all updates: ").concat((0, _stringify.default)(update.updatedObjects.map(function (o) {
1054
1222
  return {
1055
1223
  type: o.htMeta.elementId.type,
1056
1224
  id: o.htMeta.elementId.id,
@@ -1058,8 +1226,8 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1058
1226
  };
1059
1227
  }))));
1060
1228
  // now apply all the updates from the hash tree onto the locus
1061
- data.updatedObjects.forEach(function (object) {
1062
- locus = _this5.updateLocusFromHashTreeObject(object, locus);
1229
+ update.updatedObjects.forEach(function (object) {
1230
+ locus = _this6.updateLocusFromHashTreeObject(object, locus);
1063
1231
  });
1064
1232
 
1065
1233
  // update our locus info with the new locus
@@ -1087,7 +1255,13 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1087
1255
  key: "parse",
1088
1256
  value: function parse(meeting, data) {
1089
1257
  if (this.hashTreeParsers.size > 0) {
1090
- this.handleHashTreeMessage(meeting, data.eventType, data.stateElementsMessage);
1258
+ if (data.eventType === _constants.LOCUSEVENT.SDK_LOCUS_FROM_SYNC_MEETINGS) {
1259
+ // sync meetings response follows the format of "not wrapped" locus API responses,
1260
+ // so has no dataSets nor Metadata
1261
+ this.handleLocusAPIResponse(meeting, _objectSpread({}, data.locus));
1262
+ } else {
1263
+ this.handleHashTreeMessage(meeting, data.eventType, data.stateElementsMessage);
1264
+ }
1091
1265
  } else {
1092
1266
  var eventType = data.eventType;
1093
1267
  if (eventType === _constants.LOCUSEVENT.HASH_TREE_DATA_UPDATED) {
@@ -1148,13 +1322,13 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1148
1322
  * @param {string} debugText string explaining the trigger for this call, added to logs for debugging purposes
1149
1323
  * @param {object} locus locus object
1150
1324
  * @param {object} metadata locus hash trees metadata
1151
- * @param {string} eventType locus event
1152
1325
  * @param {DataSet[]} dataSets
1326
+ * @param {string} eventType locus event
1153
1327
  * @returns {void}
1154
1328
  */
1155
1329
  }, {
1156
1330
  key: "onFullLocusWithHashTrees",
1157
- value: function onFullLocusWithHashTrees(debugText, locus, metadata, eventType, dataSets) {
1331
+ value: function onFullLocusWithHashTrees(debugText, locus, metadata, dataSets, eventType) {
1158
1332
  if (!this.hashTreeParsers.has(locus.url)) {
1159
1333
  _loggerProxy.default.logger.info("Locus-info:index#onFullLocus (".concat(debugText, ") --> creating hash tree parser for locusUrl=").concat(locus.url));
1160
1334
  _loggerProxy.default.logger.info("Locus-info:index#onFullLocus (".concat(debugText, ") --> dataSets:"), dataSets, ' and locus:', locus, ' and metadata:', metadata);
@@ -1167,6 +1341,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1167
1341
  metadata: metadata
1168
1342
  });
1169
1343
  // we have a full locus to start with, so we consider Locus info to be "initialized"
1344
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1170
1345
  this.hashTreeParsers.get(locus.url).initializedFromHashTree = true;
1171
1346
  this.onFullLocusCommon(locus, eventType);
1172
1347
  } else {
@@ -1221,7 +1396,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1221
1396
  throw new Error("Locus-info:index#onFullLocus (".concat(debugText, ") --> hash tree metadata is missing with full Locus"));
1222
1397
  }
1223
1398
  // this is the new hashmap Locus DTO format (only applicable to webinars for now)
1224
- this.onFullLocusWithHashTrees(debugText, locus, metadata, eventType, dataSets);
1399
+ this.onFullLocusWithHashTrees(debugText, locus, metadata, dataSets, eventType);
1225
1400
  } else {
1226
1401
  this.onFullLocusClassic(debugText, locus, eventType);
1227
1402
  }
@@ -1237,7 +1412,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1237
1412
  key: "onFullLocusCommon",
1238
1413
  value: function onFullLocusCommon(locus, eventType) {
1239
1414
  var _this$participants,
1240
- _this6 = this,
1415
+ _this7 = this,
1241
1416
  _locus$jsSdkMeta;
1242
1417
  this.scheduledMeeting = locus.meeting || null;
1243
1418
  this.participants = locus.participants;
@@ -1245,7 +1420,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1245
1420
  var _participant$htMeta;
1246
1421
  // participant.htMeta is set only for hash tree based locus
1247
1422
  if (typeof ((_participant$htMeta = participant.htMeta) === null || _participant$htMeta === void 0 ? void 0 : _participant$htMeta.elementId.id) === 'number') {
1248
- _this6.hashTreeObjectId2ParticipantId.set(participant.htMeta.elementId.id, participant.id);
1423
+ _this7.hashTreeObjectId2ParticipantId.set(participant.htMeta.elementId.id, participant.id);
1249
1424
  }
1250
1425
  });
1251
1426
  var isReplaceMembers = _controlsUtils.default.isNeedReplaceMembers(this.controls, locus.controls);
@@ -1353,8 +1528,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1353
1528
  }, {
1354
1529
  key: "updateLocusInfo",
1355
1530
  value: function updateLocusInfo(locus) {
1356
- var _locus$self2, _locus$self3;
1357
- if (((_locus$self2 = locus.self) === null || _locus$self2 === void 0 ? void 0 : _locus$self2.reason) === 'MOVED' && ((_locus$self3 = locus.self) === null || _locus$self3 === void 0 ? void 0 : _locus$self3.state) === 'LEFT') {
1531
+ if (_util.default.isSelfMovedOrBreakoutEnded(locus)) {
1358
1532
  // When moved to a breakout session locus sends a message for the previous locus
1359
1533
  // indicating that we have been moved. It isn't helpful to continue parsing this
1360
1534
  // as it gets interpreted as if we have left the call
@@ -1474,10 +1648,8 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1474
1648
  });
1475
1649
  }
1476
1650
  } else if (((_this$parsedLocus$ful6 = this.parsedLocus.fullState) === null || _this$parsedLocus$ful6 === void 0 ? void 0 : _this$parsedLocus$ful6.type) === _constants._MEETING_) {
1477
- if (this.fullState && (this.fullState.state === _constants.LOCUS.STATE.INACTIVE ||
1478
- // @ts-ignore
1479
- this.fullState.state === _constants.LOCUS.STATE.TERMINATING)) {
1480
- _loggerProxy.default.logger.warn('Locus-info:index#isMeetingActive --> Meeting is ending due to inactive or terminating');
1651
+ if (this.fullState && _util.default.isWholeMeetingEnded(this.fullState)) {
1652
+ _loggerProxy.default.logger.warn('Locus-info:index#isMeetingActive --> Meeting is ending due to inactive');
1481
1653
 
1482
1654
  // @ts-ignore
1483
1655
  this.webex.internal.newMetrics.submitClientEvent({
@@ -1579,11 +1751,11 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1579
1751
  isReplace: isReplace
1580
1752
  });
1581
1753
  if (participants && (0, _isArray.default)(participants) && participants.length > 0) {
1582
- var _iterator3 = _createForOfIteratorHelper(participants),
1583
- _step3;
1754
+ var _iterator4 = _createForOfIteratorHelper(participants),
1755
+ _step4;
1584
1756
  try {
1585
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
1586
- var participant = _step3.value;
1757
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
1758
+ var participant = _step4.value;
1587
1759
  if (participant && (participant === null || participant === void 0 ? void 0 : participant.reason) === 'FAILURE') {
1588
1760
  var _participant$person;
1589
1761
  this.emitScoped({
@@ -1595,9 +1767,9 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1595
1767
  }
1596
1768
  }
1597
1769
  } catch (err) {
1598
- _iterator3.e(err);
1770
+ _iterator4.e(err);
1599
1771
  } finally {
1600
- _iterator3.f();
1772
+ _iterator4.f();
1601
1773
  }
1602
1774
  }
1603
1775
  }
@@ -1718,7 +1890,9 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1718
1890
  }, _constants.LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED, {
1719
1891
  state: state,
1720
1892
  modifiedBy: current.record.modifiedBy,
1721
- lastModified: current.record.lastModified
1893
+ lastModified: current.record.lastModified,
1894
+ modifiedByServiceAppName: current.record.modifiedByServiceAppName,
1895
+ modifiedByServiceAppId: current.record.modifiedByServiceAppId
1722
1896
  });
1723
1897
  }
1724
1898
  if (hasMeetingContainerChanged) {
@@ -2243,12 +2417,14 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
2243
2417
  });
2244
2418
  }
2245
2419
  if (parsedSelves.updates.isMutedByOthersChanged) {
2420
+ var _parsedSelves$current2;
2246
2421
  this.emitScoped({
2247
2422
  file: 'locus-info',
2248
2423
  function: 'updateSelf'
2249
2424
  }, _constants.LOCUSINFO.EVENTS.SELF_REMOTE_MUTE_STATUS_UPDATED, {
2250
2425
  muted: parsedSelves.current.remoteMuted,
2251
- unmuteAllowed: parsedSelves.current.unmuteAllowed
2426
+ unmuteAllowed: parsedSelves.current.unmuteAllowed,
2427
+ modifiedBy: (_parsedSelves$current2 = parsedSelves.current.modifiedBy) !== null && _parsedSelves$current2 !== void 0 ? _parsedSelves$current2 : null
2252
2428
  });
2253
2429
  }
2254
2430
  if (parsedSelves.updates.localAudioUnmuteRequestedByServer) {
@@ -2278,14 +2454,14 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
2278
2454
  _constants.LOCUSINFO.EVENTS.MEDIA_INACTIVITY, _selfUtils.default.getMediaStatus(self.mediaSessions));
2279
2455
  }
2280
2456
  if (parsedSelves.updates.audioStateChange || parsedSelves.updates.videoStateChange || parsedSelves.updates.shareStateChange) {
2281
- var _parsedSelves$current2, _parsedSelves$current3, _parsedSelves$current4;
2457
+ var _parsedSelves$current3, _parsedSelves$current4, _parsedSelves$current5;
2282
2458
  this.emitScoped({
2283
2459
  file: 'locus-info',
2284
2460
  function: 'updateSelf'
2285
2461
  }, _constants.LOCUSINFO.EVENTS.MEDIA_STATUS_CHANGE, {
2286
- audioStatus: (_parsedSelves$current2 = parsedSelves.current.currentMediaStatus) === null || _parsedSelves$current2 === void 0 ? void 0 : _parsedSelves$current2.audio,
2287
- videoStatus: (_parsedSelves$current3 = parsedSelves.current.currentMediaStatus) === null || _parsedSelves$current3 === void 0 ? void 0 : _parsedSelves$current3.video,
2288
- shareStatus: (_parsedSelves$current4 = parsedSelves.current.currentMediaStatus) === null || _parsedSelves$current4 === void 0 ? void 0 : _parsedSelves$current4.share
2462
+ audioStatus: (_parsedSelves$current3 = parsedSelves.current.currentMediaStatus) === null || _parsedSelves$current3 === void 0 ? void 0 : _parsedSelves$current3.audio,
2463
+ videoStatus: (_parsedSelves$current4 = parsedSelves.current.currentMediaStatus) === null || _parsedSelves$current4 === void 0 ? void 0 : _parsedSelves$current4.video,
2464
+ shareStatus: (_parsedSelves$current5 = parsedSelves.current.currentMediaStatus) === null || _parsedSelves$current5 === void 0 ? void 0 : _parsedSelves$current5.share
2289
2465
  });
2290
2466
  }
2291
2467
  if (parsedSelves.updates.isUserObserving) {
@@ -2467,7 +2643,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
2467
2643
  }, {
2468
2644
  key: "updateMainSessionLocusCache",
2469
2645
  value: function updateMainSessionLocusCache(mainLocus) {
2470
- var _this7 = this;
2646
+ var _this8 = this;
2471
2647
  if (!mainLocus) {
2472
2648
  return;
2473
2649
  }
@@ -2476,7 +2652,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
2476
2652
  // shallow merge and do special merge for participants
2477
2653
  (0, _lodash.assignWith)(this.mainSessionLocusCache, locusClone, function (objValue, srcValue, key) {
2478
2654
  if (key === 'participants') {
2479
- return _this7.mergeParticipants(objValue, srcValue);
2655
+ return _this8.mergeParticipants(objValue, srcValue);
2480
2656
  }
2481
2657
  return srcValue || objValue;
2482
2658
  });
@@ -2495,6 +2671,21 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
2495
2671
  value: function clearMainSessionLocusCache() {
2496
2672
  this.mainSessionLocusCache = null;
2497
2673
  }
2674
+
2675
+ /**
2676
+ * Cleans up all hash tree parsers and clears internal maps.
2677
+ * @returns {void}
2678
+ * @memberof LocusInfo
2679
+ */
2680
+ }, {
2681
+ key: "cleanUp",
2682
+ value: function cleanUp() {
2683
+ this.hashTreeParsers.forEach(function (entry) {
2684
+ entry.parser.cleanUp();
2685
+ });
2686
+ this.hashTreeParsers.clear();
2687
+ this.hashTreeObjectId2ParticipantId.clear();
2688
+ }
2498
2689
  }]);
2499
2690
  }(_eventsScope.default);
2500
2691
  //# sourceMappingURL=index.js.map