@webex/plugin-meetings 3.11.0 → 3.12.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/dist/aiEnableRequest/index.js +184 -0
  2. package/dist/aiEnableRequest/index.js.map +1 -0
  3. package/dist/aiEnableRequest/utils.js +36 -0
  4. package/dist/aiEnableRequest/utils.js.map +1 -0
  5. package/dist/annotation/index.js +14 -5
  6. package/dist/annotation/index.js.map +1 -1
  7. package/dist/breakouts/breakout.js +1 -1
  8. package/dist/breakouts/index.js +1 -1
  9. package/dist/config.js +7 -2
  10. package/dist/config.js.map +1 -1
  11. package/dist/constants.js +28 -6
  12. package/dist/constants.js.map +1 -1
  13. package/dist/hashTree/constants.js +3 -1
  14. package/dist/hashTree/constants.js.map +1 -1
  15. package/dist/hashTree/hashTree.js +18 -0
  16. package/dist/hashTree/hashTree.js.map +1 -1
  17. package/dist/hashTree/hashTreeParser.js +850 -410
  18. package/dist/hashTree/hashTreeParser.js.map +1 -1
  19. package/dist/hashTree/types.js +4 -2
  20. package/dist/hashTree/types.js.map +1 -1
  21. package/dist/hashTree/utils.js +10 -0
  22. package/dist/hashTree/utils.js.map +1 -1
  23. package/dist/index.js +11 -2
  24. package/dist/index.js.map +1 -1
  25. package/dist/interceptors/constant.js +12 -0
  26. package/dist/interceptors/constant.js.map +1 -0
  27. package/dist/interceptors/dataChannelAuthToken.js +290 -0
  28. package/dist/interceptors/dataChannelAuthToken.js.map +1 -0
  29. package/dist/interceptors/index.js +7 -0
  30. package/dist/interceptors/index.js.map +1 -1
  31. package/dist/interceptors/utils.js +27 -0
  32. package/dist/interceptors/utils.js.map +1 -0
  33. package/dist/interpretation/index.js +2 -2
  34. package/dist/interpretation/index.js.map +1 -1
  35. package/dist/interpretation/siLanguage.js +1 -1
  36. package/dist/locus-info/controlsUtils.js +5 -3
  37. package/dist/locus-info/controlsUtils.js.map +1 -1
  38. package/dist/locus-info/index.js +522 -131
  39. package/dist/locus-info/index.js.map +1 -1
  40. package/dist/locus-info/selfUtils.js +1 -0
  41. package/dist/locus-info/selfUtils.js.map +1 -1
  42. package/dist/locus-info/types.js.map +1 -1
  43. package/dist/media/MediaConnectionAwaiter.js +57 -1
  44. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  45. package/dist/media/properties.js +4 -2
  46. package/dist/media/properties.js.map +1 -1
  47. package/dist/meeting/in-meeting-actions.js +7 -1
  48. package/dist/meeting/in-meeting-actions.js.map +1 -1
  49. package/dist/meeting/index.js +1173 -877
  50. package/dist/meeting/index.js.map +1 -1
  51. package/dist/meeting/request.js +50 -0
  52. package/dist/meeting/request.js.map +1 -1
  53. package/dist/meeting/request.type.js.map +1 -1
  54. package/dist/meeting/util.js +133 -3
  55. package/dist/meeting/util.js.map +1 -1
  56. package/dist/meetings/index.js +117 -48
  57. package/dist/meetings/index.js.map +1 -1
  58. package/dist/member/index.js +10 -0
  59. package/dist/member/index.js.map +1 -1
  60. package/dist/member/util.js +10 -0
  61. package/dist/member/util.js.map +1 -1
  62. package/dist/metrics/constants.js +2 -1
  63. package/dist/metrics/constants.js.map +1 -1
  64. package/dist/multistream/mediaRequestManager.js +9 -60
  65. package/dist/multistream/mediaRequestManager.js.map +1 -1
  66. package/dist/multistream/remoteMediaManager.js +11 -0
  67. package/dist/multistream/remoteMediaManager.js.map +1 -1
  68. package/dist/reachability/index.js +18 -10
  69. package/dist/reachability/index.js.map +1 -1
  70. package/dist/reactions/reactions.type.js.map +1 -1
  71. package/dist/reconnection-manager/index.js +0 -1
  72. package/dist/reconnection-manager/index.js.map +1 -1
  73. package/dist/types/aiEnableRequest/index.d.ts +5 -0
  74. package/dist/types/aiEnableRequest/utils.d.ts +2 -0
  75. package/dist/types/config.d.ts +4 -0
  76. package/dist/types/constants.d.ts +23 -1
  77. package/dist/types/hashTree/constants.d.ts +1 -0
  78. package/dist/types/hashTree/hashTree.d.ts +7 -0
  79. package/dist/types/hashTree/hashTreeParser.d.ts +122 -14
  80. package/dist/types/hashTree/types.d.ts +3 -0
  81. package/dist/types/hashTree/utils.d.ts +6 -0
  82. package/dist/types/index.d.ts +1 -0
  83. package/dist/types/interceptors/constant.d.ts +5 -0
  84. package/dist/types/interceptors/dataChannelAuthToken.d.ts +43 -0
  85. package/dist/types/interceptors/index.d.ts +2 -1
  86. package/dist/types/interceptors/utils.d.ts +1 -0
  87. package/dist/types/locus-info/index.d.ts +60 -8
  88. package/dist/types/locus-info/types.d.ts +7 -0
  89. package/dist/types/media/MediaConnectionAwaiter.d.ts +10 -1
  90. package/dist/types/media/properties.d.ts +2 -1
  91. package/dist/types/meeting/in-meeting-actions.d.ts +6 -0
  92. package/dist/types/meeting/index.d.ts +61 -7
  93. package/dist/types/meeting/request.d.ts +16 -1
  94. package/dist/types/meeting/request.type.d.ts +5 -0
  95. package/dist/types/meeting/util.d.ts +31 -0
  96. package/dist/types/meetings/index.d.ts +4 -2
  97. package/dist/types/member/index.d.ts +1 -0
  98. package/dist/types/member/util.d.ts +5 -0
  99. package/dist/types/metrics/constants.d.ts +1 -0
  100. package/dist/types/multistream/mediaRequestManager.d.ts +0 -23
  101. package/dist/types/reactions/reactions.type.d.ts +1 -0
  102. package/dist/types/webinar/utils.d.ts +6 -0
  103. package/dist/webinar/index.js +291 -91
  104. package/dist/webinar/index.js.map +1 -1
  105. package/dist/webinar/utils.js +25 -0
  106. package/dist/webinar/utils.js.map +1 -0
  107. package/package.json +24 -23
  108. package/src/aiEnableRequest/README.md +84 -0
  109. package/src/aiEnableRequest/index.ts +170 -0
  110. package/src/aiEnableRequest/utils.ts +25 -0
  111. package/src/annotation/index.ts +27 -7
  112. package/src/config.ts +4 -0
  113. package/src/constants.ts +29 -1
  114. package/src/hashTree/constants.ts +1 -0
  115. package/src/hashTree/hashTree.ts +17 -0
  116. package/src/hashTree/hashTreeParser.ts +745 -252
  117. package/src/hashTree/types.ts +4 -0
  118. package/src/hashTree/utils.ts +9 -0
  119. package/src/index.ts +8 -1
  120. package/src/interceptors/constant.ts +6 -0
  121. package/src/interceptors/dataChannelAuthToken.ts +170 -0
  122. package/src/interceptors/index.ts +2 -1
  123. package/src/interceptors/utils.ts +16 -0
  124. package/src/interpretation/index.ts +2 -2
  125. package/src/locus-info/controlsUtils.ts +11 -0
  126. package/src/locus-info/index.ts +579 -113
  127. package/src/locus-info/selfUtils.ts +1 -0
  128. package/src/locus-info/types.ts +8 -0
  129. package/src/media/MediaConnectionAwaiter.ts +41 -1
  130. package/src/media/properties.ts +3 -1
  131. package/src/meeting/in-meeting-actions.ts +12 -0
  132. package/src/meeting/index.ts +291 -76
  133. package/src/meeting/request.ts +42 -0
  134. package/src/meeting/request.type.ts +6 -0
  135. package/src/meeting/util.ts +160 -2
  136. package/src/meetings/index.ts +157 -44
  137. package/src/member/index.ts +10 -0
  138. package/src/member/util.ts +12 -0
  139. package/src/metrics/constants.ts +1 -0
  140. package/src/multistream/mediaRequestManager.ts +4 -54
  141. package/src/multistream/remoteMediaManager.ts +13 -0
  142. package/src/reachability/index.ts +9 -0
  143. package/src/reactions/reactions.type.ts +1 -0
  144. package/src/reconnection-manager/index.ts +0 -1
  145. package/src/webinar/index.ts +191 -6
  146. package/src/webinar/utils.ts +16 -0
  147. package/test/unit/spec/aiEnableRequest/index.ts +981 -0
  148. package/test/unit/spec/aiEnableRequest/utils.ts +130 -0
  149. package/test/unit/spec/annotation/index.ts +69 -7
  150. package/test/unit/spec/hashTree/hashTree.ts +66 -0
  151. package/test/unit/spec/hashTree/hashTreeParser.ts +2225 -189
  152. package/test/unit/spec/interceptors/dataChannelAuthToken.ts +210 -0
  153. package/test/unit/spec/interceptors/utils.ts +75 -0
  154. package/test/unit/spec/locus-info/controlsUtils.js +29 -0
  155. package/test/unit/spec/locus-info/index.js +1134 -55
  156. package/test/unit/spec/media/MediaConnectionAwaiter.ts +41 -1
  157. package/test/unit/spec/media/properties.ts +12 -3
  158. package/test/unit/spec/meeting/in-meeting-actions.ts +8 -2
  159. package/test/unit/spec/meeting/index.js +829 -115
  160. package/test/unit/spec/meeting/request.js +70 -0
  161. package/test/unit/spec/meeting/utils.js +438 -26
  162. package/test/unit/spec/meetings/index.js +653 -32
  163. package/test/unit/spec/member/index.js +28 -4
  164. package/test/unit/spec/member/util.js +65 -27
  165. package/test/unit/spec/multistream/mediaRequestManager.ts +2 -85
  166. package/test/unit/spec/multistream/remoteMediaManager.ts +30 -0
  167. package/test/unit/spec/reachability/index.ts +23 -0
  168. package/test/unit/spec/reconnection-manager/index.js +4 -8
  169. package/test/unit/spec/webinar/index.ts +474 -37
  170. package/test/unit/spec/webinar/utils.ts +39 -0
@@ -1,37 +1,40 @@
1
1
  "use strict";
2
2
 
3
3
  var _typeof = require("@babel/runtime-corejs2/helpers/typeof");
4
- var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
4
+ var _Array$from = require("@babel/runtime-corejs2/core-js/array/from");
5
+ var _Symbol = require("@babel/runtime-corejs2/core-js/symbol");
6
+ var _Symbol$iterator = require("@babel/runtime-corejs2/core-js/symbol/iterator");
7
+ var _Array$isArray2 = require("@babel/runtime-corejs2/core-js/array/is-array");
5
8
  var _Object$keys2 = require("@babel/runtime-corejs2/core-js/object/keys");
6
9
  var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
7
10
  var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
8
11
  var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
9
12
  var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");
10
13
  var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
11
- var _Array$from = require("@babel/runtime-corejs2/core-js/array/from");
12
- var _Symbol = require("@babel/runtime-corejs2/core-js/symbol");
13
- var _Symbol$iterator = require("@babel/runtime-corejs2/core-js/symbol/iterator");
14
- var _Array$isArray2 = require("@babel/runtime-corejs2/core-js/array/is-array");
14
+ var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
15
15
  var _WeakMap = require("@babel/runtime-corejs2/core-js/weak-map");
16
16
  var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
17
17
  _Object$defineProperty(exports, "__esModule", {
18
18
  value: true
19
19
  });
20
+ exports.createLocusFromHashTreeMessage = createLocusFromHashTreeMessage;
20
21
  exports.default = void 0;
22
+ exports.findMeetingForHashTreeMessage = findMeetingForHashTreeMessage;
21
23
  var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
22
- var _map = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/map"));
23
- var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
24
- var _assign = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/assign"));
25
- var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
26
- var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
27
- var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
28
24
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
25
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
29
26
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
30
27
  var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
31
28
  var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
32
29
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
33
30
  var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
34
31
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
32
+ var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
33
+ var _assign = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/assign"));
34
+ var _map = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/map"));
35
+ var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
36
+ var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
37
+ var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
35
38
  var _lodash = require("lodash");
36
39
  var _loggerProxy = _interopRequireDefault(require("../common/logs/logger-proxy"));
37
40
  var _eventsScope = _interopRequireDefault(require("../common/events/events-scope"));
@@ -46,26 +49,190 @@ var _mediaSharesUtils = _interopRequireDefault(require("./mediaSharesUtils"));
46
49
  var _parser = _interopRequireDefault(require("./parser"));
47
50
  var _metrics = _interopRequireDefault(require("../metrics"));
48
51
  var _constants2 = _interopRequireDefault(require("../metrics/constants"));
49
- var _hashTreeParser = _interopRequireWildcard(require("../hashTree/hashTreeParser"));
52
+ var _hashTreeParser2 = _interopRequireWildcard(require("../hashTree/hashTreeParser"));
50
53
  var _types = require("../hashTree/types");
51
54
  var _utils = require("../hashTree/utils");
55
+ var _util = _interopRequireDefault(require("../meetings/util"));
52
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); }
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
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
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; }
60
+ 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; }
53
61
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof _Symbol && r[_Symbol$iterator] || r["@@iterator"]; if (!t) { if (_Array$isArray2(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
54
62
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? _Array$from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
55
63
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
56
- 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; }
57
- 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; }
58
- 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)); }
59
- function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
60
64
  // list of top level keys in Locus DTO relevant for Hash Tree DTOs processing
61
65
  // it does not contain fields specific to classic Locus DTOs like sequence or baseSequence
62
- var LocusDtoTopLevelKeys = ['controls', 'fullState', 'host', 'info', 'links', 'mediaShares', 'meetings', 'participants', 'replaces', 'self', 'sequence', 'syncUrl', 'url', 'htMeta' // only exists when hash trees are used
66
+ var LocusDtoTopLevelKeys = ['controls', 'fullState', 'embeddedApps', 'host', 'info', 'links', 'mediaShares', 'meetings', 'participants', 'replaces', 'self', 'sequence', 'syncUrl', 'url', 'htMeta' // only exists when hash trees are used
63
67
  ];
68
+ // when we invoke APIs on the whole Locus like "mute all" backend returns the whole Locus in the response like this
69
+
64
70
  var LocusObjectStateAfterUpdates = {
65
71
  unchanged: 'unchanged',
66
72
  removed: 'removed',
67
73
  updated: 'updated'
68
74
  };
75
+ /**
76
+ * Gets the replacement information
77
+ *
78
+ * @param {any} self - "self" object from Locus DTO
79
+ * @param {string} deviceUrl - The URL of the user's device
80
+ * @returns {any} The replace information if available, otherwise undefined
81
+ */
82
+ function getReplaceInfoFromSelf(self, deviceUrl) {
83
+ if (self) {
84
+ var _device$replaces;
85
+ var device = _util.default.getThisDevice({
86
+ self: self
87
+ }, deviceUrl);
88
+ if ((device === null || device === void 0 ? void 0 : (_device$replaces = device.replaces) === null || _device$replaces === void 0 ? void 0 : _device$replaces.length) > 0) {
89
+ return device.replaces[0];
90
+ }
91
+ }
92
+ return undefined;
93
+ }
94
+
95
+ /**
96
+ * Finds a meeting by its locus URL in meeting collection. It checks all HashTreeParsers of all meetings in the collection.
97
+ *
98
+ * @param {MeetingCollection} meetingCollection - The collection of meetings to search
99
+ * @param {string} locusUrl - The locus URL to search for
100
+ * @returns {any} The meeting if found, otherwise undefined
101
+ */
102
+ function findLocusUrlInAnyHashTreeParser(meetingCollection, locusUrl) {
103
+ for (var _i = 0, _arr = (0, _values.default)(meetingCollection.getAll()); _i < _arr.length; _i++) {
104
+ var _meeting$locusInfo, _meeting$locusInfo$ha;
105
+ var meeting = _arr[_i];
106
+ if (meeting !== null && meeting !== void 0 && (_meeting$locusInfo = meeting.locusInfo) !== null && _meeting$locusInfo !== void 0 && (_meeting$locusInfo$ha = _meeting$locusInfo.hashTreeParsers) !== null && _meeting$locusInfo$ha !== void 0 && _meeting$locusInfo$ha.has(locusUrl)) {
107
+ return meeting;
108
+ }
109
+ }
110
+ return undefined;
111
+ }
112
+
113
+ /**
114
+ * Finds a meeting for a given hash tree message.
115
+ *
116
+ * @param {HashTreeMessage} message - The hash tree message to find the meeting for
117
+ * @param {MeetingCollection} meetingCollection - The collection of meetings to search
118
+ * @param {string} deviceUrl - The URL of the user's device
119
+ * @returns {any} The meeting if found, otherwise undefined
120
+ */
121
+ function findMeetingForHashTreeMessage(message, meetingCollection, deviceUrl) {
122
+ var _message$locusStateEl, _message$locusStateEl2;
123
+ var foundMeeting = findLocusUrlInAnyHashTreeParser(meetingCollection, message.locusUrl);
124
+ if (foundMeeting) {
125
+ return foundMeeting;
126
+ }
127
+
128
+ // if we haven't found anything, it may mean that message has a new locusUrl
129
+ // check if it indicates that it replaces some existing current locusUrl (this is indicated in "self")
130
+ var self = (_message$locusStateEl = message.locusStateElements) === null || _message$locusStateEl === void 0 ? void 0 : (_message$locusStateEl2 = _message$locusStateEl.find(function (el) {
131
+ return (0, _utils.isSelf)(el);
132
+ })) === null || _message$locusStateEl2 === void 0 ? void 0 : _message$locusStateEl2.data;
133
+ var replaces = getReplaceInfoFromSelf(self, deviceUrl);
134
+ if (replaces !== null && replaces !== void 0 && replaces.locusUrl) {
135
+ foundMeeting = findLocusUrlInAnyHashTreeParser(meetingCollection, replaces.locusUrl);
136
+ return foundMeeting;
137
+ }
138
+ return undefined;
139
+ }
140
+
141
+ /**
142
+ * Creates a locus object from the objects received in a hash tree message. It usually will be
143
+ * incomplete, because hash tree messages only contain the parts of locus that have changed,
144
+ * and some updates come separately over Mercury or LLM in separate messages.
145
+ *
146
+ * @param {HashTreeMessage} message hash tree message to created the locus from
147
+ * @returns {Object} the created locus object and metadata if present
148
+ */
149
+ function createLocusFromHashTreeMessage(message) {
150
+ var locus = {
151
+ participants: [],
152
+ url: message.locusUrl
153
+ };
154
+ var metadata;
155
+ if (!message.locusStateElements) {
156
+ return {
157
+ locus: locus,
158
+ metadata: metadata
159
+ };
160
+ }
161
+ var _iterator = _createForOfIteratorHelper(message.locusStateElements),
162
+ _step;
163
+ try {
164
+ var _loop = function _loop() {
165
+ var element = _step.value;
166
+ if (!element.data) {
167
+ // eslint-disable-next-line no-continue
168
+ return 1; // continue
169
+ }
170
+ var type = element.htMeta.elementId.type.toLowerCase();
171
+ switch (type) {
172
+ case _types.ObjectType.locus:
173
+ {
174
+ // spread locus object data onto the top level, but remove keys managed by other ObjectTypes
175
+ var locusObjectData = _objectSpread({}, element.data);
176
+ (0, _values.default)(_types.ObjectTypeToLocusKeyMap).forEach(function (locusDtoKey) {
177
+ delete locusObjectData[locusDtoKey];
178
+ });
179
+ (0, _assign.default)(locus, locusObjectData);
180
+ break;
181
+ }
182
+ case _types.ObjectType.participant:
183
+ locus.participants.push(element.data);
184
+ break;
185
+ case _types.ObjectType.mediaShare:
186
+ if (!locus.mediaShares) {
187
+ locus.mediaShares = [];
188
+ }
189
+ locus.mediaShares.push(element.data);
190
+ break;
191
+ case _types.ObjectType.embeddedApp:
192
+ if (!locus.embeddedApps) {
193
+ locus.embeddedApps = [];
194
+ }
195
+ locus.embeddedApps.push(element.data);
196
+ break;
197
+ case _types.ObjectType.control:
198
+ if (!locus.controls) {
199
+ locus.controls = {};
200
+ }
201
+ (0, _assign.default)(locus.controls, element.data);
202
+ break;
203
+ case _types.ObjectType.links:
204
+ case _types.ObjectType.info:
205
+ case _types.ObjectType.fullState:
206
+ case _types.ObjectType.self:
207
+ {
208
+ var locusDtoKey = _types.ObjectTypeToLocusKeyMap[type];
209
+ locus[locusDtoKey] = element.data;
210
+ break;
211
+ }
212
+ case _types.ObjectType.metadata:
213
+ // metadata is not part of Locus DTO
214
+ metadata = _objectSpread(_objectSpread({}, element.data), {}, {
215
+ htMeta: element.htMeta
216
+ });
217
+ break;
218
+ default:
219
+ break;
220
+ }
221
+ };
222
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
223
+ if (_loop()) continue;
224
+ }
225
+ } catch (err) {
226
+ _iterator.e(err);
227
+ } finally {
228
+ _iterator.f();
229
+ }
230
+ return {
231
+ locus: locus,
232
+ metadata: metadata
233
+ };
234
+ }
235
+
69
236
  /**
70
237
  * @description LocusInfo extends ChildEmitter to convert locusInfo info a private emitter to parent object
71
238
  * @export
@@ -110,7 +277,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
110
277
  (0, _defineProperty2.default)(_this, "links", void 0);
111
278
  (0, _defineProperty2.default)(_this, "mainSessionLocusCache", void 0);
112
279
  (0, _defineProperty2.default)(_this, "self", void 0);
113
- (0, _defineProperty2.default)(_this, "hashTreeParser", void 0);
280
+ (0, _defineProperty2.default)(_this, "hashTreeParsers", void 0);
114
281
  (0, _defineProperty2.default)(_this, "hashTreeObjectId2ParticipantId", void 0);
115
282
  // mapping of hash tree object ids to participant ids
116
283
  (0, _defineProperty2.default)(_this, "classicVsHashTreeMismatchMetricCounter", 0);
@@ -123,6 +290,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
123
290
  _this.meetingId = meetingId;
124
291
  _this.updateMeeting = updateMeeting;
125
292
  _this.locusParser = new _parser.default();
293
+ _this.hashTreeParsers = new _map.default();
126
294
  _this.hashTreeObjectId2ParticipantId = new _map.default();
127
295
  return _this;
128
296
  }
@@ -210,7 +378,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
210
378
  // in some cases Locus might return us full DTO even when we asked for a delta
211
379
  _loggerProxy.default.logger.info('Locus-info:index#doLocusSync --> got full DTO when we asked for delta');
212
380
  }
213
- meeting.locusInfo.onFullLocus(res.body);
381
+ meeting.locusInfo.onFullLocus('classic Locus sync', res.body);
214
382
  }).catch(function (e) {
215
383
  _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(), ")"));
216
384
  _metrics.default.sendBehavioralMetric(_constants2.default.LOCUS_SYNC_HANDLING_FAILED, {
@@ -332,20 +500,60 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
332
500
  }
333
501
 
334
502
  /**
335
- * Creates the HashTreeParser instance.
336
- * @param {Object} initial locus data
337
- * @returns {void}
503
+ * Creates a HashTreeParser instance for a given locusUrl and stores it in the map.
504
+ * @param {Object} params
505
+ * @param {string} params.locusUrl - the locus URL used as the map key
506
+ * @param {Object} params.initialLocus - initial locus data
507
+ * @param {Object} params.metadata - hash tree metadata
508
+ * @param {string} params.replacedAt - timestamp from Locus indicating when the replacement happened
509
+ * @returns {HashTreeParser} the newly created parser
338
510
  */
339
511
  }, {
340
512
  key: "createHashTreeParser",
341
513
  value: function createHashTreeParser(_ref) {
342
- var initialLocus = _ref.initialLocus;
343
- return new _hashTreeParser.default({
514
+ var _this$webex$config$me;
515
+ var locusUrl = _ref.locusUrl,
516
+ initialLocus = _ref.initialLocus,
517
+ metadata = _ref.metadata,
518
+ replacedAt = _ref.replacedAt;
519
+ var parser = new _hashTreeParser2.default({
344
520
  initialLocus: initialLocus,
521
+ metadata: metadata,
345
522
  webexRequest: this.webex.request.bind(this.webex),
346
- locusInfoUpdateCallback: this.updateFromHashTree.bind(this),
347
- debugId: "HT-".concat(this.meetingId.substring(0, 4))
523
+ locusInfoUpdateCallback: this.updateFromHashTree.bind(this, locusUrl),
524
+ debugId: "HT-".concat(locusUrl.split('/').pop().substring(0, 4)),
525
+ excludedDataSets: (_this$webex$config$me = this.webex.config.meetings.locus) === null || _this$webex$config$me === void 0 ? void 0 : _this$webex$config$me.excludedDataSets
348
526
  });
527
+
528
+ // When a new HashTreeParser is created, previous one should be stopped.
529
+ // Locus will only be sending us updates for the current one.
530
+ var _iterator2 = _createForOfIteratorHelper(this.hashTreeParsers),
531
+ _step2;
532
+ try {
533
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
534
+ var _step2$value = (0, _slicedToArray2.default)(_step2.value, 2),
535
+ existingLocusUrl = _step2$value[0],
536
+ existingEntry = _step2$value[1];
537
+ if (existingEntry.parser.state !== 'stopped') {
538
+ existingEntry.parser.stop();
539
+ if (replacedAt) {
540
+ existingEntry.replacedAt = replacedAt;
541
+ } else {
542
+ _loggerProxy.default.logger.warn("Locus-info:index#createHashTreeParser --> no replacedAt timestamp provided for new HashTreeParser with locusUrl ".concat(locusUrl, ", replacing ").concat(existingLocusUrl));
543
+ }
544
+ }
545
+ }
546
+ } catch (err) {
547
+ _iterator2.e(err);
548
+ } finally {
549
+ _iterator2.f();
550
+ }
551
+ this.hashTreeParsers.set(locusUrl, {
552
+ parser: parser,
553
+ initializedFromHashTree: false
554
+ });
555
+ this.hashTreeObjectId2ParticipantId.clear();
556
+ return parser;
349
557
  }
350
558
 
351
559
  /**
@@ -358,7 +566,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
358
566
  value: (function () {
359
567
  var _initialSetup = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee(data) {
360
568
  var _data$locus, _data$locus$links, _data$locus$links$res, _data$locus$links$res2;
361
- var _data$hashTreeMessage, _selfObject$data, selfObject, _data$locus2, _data$locus2$self, _t;
569
+ var _data$hashTreeMessage, _metadataObject$data, metadataObject, hashTreeParser, _hashTreeParser, _t;
362
570
  return _regenerator.default.wrap(function (_context) {
363
571
  while (1) switch (_context.prev = _context.next) {
364
572
  case 0:
@@ -370,47 +578,49 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
370
578
  _context.next = 4;
371
579
  break;
372
580
  }
373
- // we need the SELF object to be in the received message, because it contains visibleDataSets
581
+ // we need the Metadata object to be in the received message, because it contains visibleDataSets
374
582
  // and these are needed to initialize all the hash trees
375
- selfObject = (_data$hashTreeMessage = data.hashTreeMessage.locusStateElements) === null || _data$hashTreeMessage === void 0 ? void 0 : _data$hashTreeMessage.find(function (el) {
376
- return (0, _utils.isSelf)(el);
583
+ metadataObject = (_data$hashTreeMessage = data.hashTreeMessage.locusStateElements) === null || _data$hashTreeMessage === void 0 ? void 0 : _data$hashTreeMessage.find(function (el) {
584
+ return (0, _utils.isMetadata)(el);
377
585
  });
378
- if (selfObject !== null && selfObject !== void 0 && (_selfObject$data = selfObject.data) !== null && _selfObject$data !== void 0 && _selfObject$data.visibleDataSets) {
586
+ if (metadataObject !== null && metadataObject !== void 0 && (_metadataObject$data = metadataObject.data) !== null && _metadataObject$data !== void 0 && _metadataObject$data.visibleDataSets) {
379
587
  _context.next = 2;
380
588
  break;
381
589
  }
382
- _loggerProxy.default.logger.warn("Locus-info:index#initialSetup --> cannot initialize HashTreeParser, SELF object with visibleDataSets is missing in the message");
383
- throw new Error('SELF object with visibleDataSets is missing in the message');
590
+ // this is a common case (not an error)
591
+ // it happens for example after we leave the meeting and still get some heartbeats or delayed messages
592
+ _loggerProxy.default.logger.info("Locus-info:index#initialSetup --> cannot initialize HashTreeParser, Metadata object with visibleDataSets is missing in the message");
593
+
594
+ // throw so that handleLocusEvent() catches it and destroys the partially created meeting object
595
+ throw new Error('Metadata object with visibleDataSets is missing in the message');
384
596
  case 2:
385
597
  _loggerProxy.default.logger.info('Locus-info:index#initialSetup --> creating HashTreeParser from message');
386
598
  // first create the HashTreeParser, but don't initialize it with any data yet
387
- // pass just a fake locus that contains only the visibleDataSets
388
- this.hashTreeParser = this.createHashTreeParser({
599
+ hashTreeParser = this.createHashTreeParser({
600
+ locusUrl: data.hashTreeMessage.locusUrl,
389
601
  initialLocus: {
390
- locus: {
391
- self: {
392
- visibleDataSets: selfObject.data.visibleDataSets
393
- }
394
- },
395
- dataSets: [] // empty, because they will be populated in initializeFromMessage() call // dataSets: data.hashTreeMessage.dataSets,
602
+ locus: null,
603
+ dataSets: data.hashTreeMessage.dataSets
604
+ },
605
+ metadata: {
606
+ htMeta: metadataObject.htMeta,
607
+ visibleDataSets: metadataObject.data.visibleDataSets
396
608
  }
397
- });
398
-
399
- // now handle the message - that should populate all the visible datasets
609
+ }); // now handle the message - that should populate all the visible datasets
400
610
  _context.next = 3;
401
- return this.hashTreeParser.initializeFromMessage(data.hashTreeMessage);
611
+ return hashTreeParser.initializeFromMessage(data.hashTreeMessage);
402
612
  case 3:
403
613
  _context.next = 5;
404
614
  break;
405
615
  case 4:
406
616
  // "classic" Locus case, no hash trees involved
407
617
  this.updateLocusCache(data.locus);
408
- this.onFullLocus(data.locus, undefined);
618
+ this.onFullLocus('classic locus message', data.locus, undefined);
409
619
  case 5:
410
620
  return _context.abrupt("continue", 10);
411
621
  case 6:
412
622
  this.updateLocusCache(data.locus);
413
- this.onFullLocus(data.locus, undefined, data.dataSets);
623
+ this.onFullLocus('join response', data.locus, undefined, data.dataSets, data.metadata);
414
624
  return _context.abrupt("continue", 10);
415
625
  case 7:
416
626
  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)) {
@@ -419,28 +629,23 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
419
629
  }
420
630
  _loggerProxy.default.logger.info('Locus-info:index#initialSetup --> creating HashTreeParser from get-loci-response');
421
631
  // first create the HashTreeParser, but don't initialize it with any data yet
422
- // pass just a fake locus that contains only the visibleDataSets
423
- this.hashTreeParser = this.createHashTreeParser({
632
+ _hashTreeParser = this.createHashTreeParser({
633
+ locusUrl: data.locus.url,
424
634
  initialLocus: {
425
- locus: {
426
- self: {
427
- visibleDataSets: (_data$locus2 = data.locus) === null || _data$locus2 === void 0 ? void 0 : (_data$locus2$self = _data$locus2.self) === null || _data$locus2$self === void 0 ? void 0 : _data$locus2$self.visibleDataSets
428
- }
429
- },
635
+ locus: null,
430
636
  dataSets: [] // empty, because we don't have them yet
431
- }
432
- });
433
-
434
- // now initialize all the data
637
+ },
638
+ metadata: null // get-loci-response doesn't contain Metadata object
639
+ }); // now initialize all the data
435
640
  _context.next = 8;
436
- return this.hashTreeParser.initializeFromGetLociResponse(data.locus);
641
+ return _hashTreeParser.initializeFromGetLociResponse(data.locus);
437
642
  case 8:
438
643
  _context.next = 10;
439
644
  break;
440
645
  case 9:
441
646
  // "classic" Locus case, no hash trees involved
442
647
  this.updateLocusCache(data.locus);
443
- this.onFullLocus(data.locus, undefined);
648
+ this.onFullLocus('classic get-loci-response', data.locus, undefined);
444
649
  case 10:
445
650
  // Change it to true after it receives it first locus object
446
651
  this.emitChange = true;
@@ -465,25 +670,36 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
465
670
  }, {
466
671
  key: "handleLocusAPIResponse",
467
672
  value: function handleLocusAPIResponse(meeting, responseBody) {
468
- if (this.hashTreeParser) {
469
- if (!responseBody.dataSets) {
470
- this.sendClassicVsHashTreeMismatchMetric(meeting, "expected hash tree dataSets in API response but they are missing");
471
- // continuing as we can still manage without responseBody.dataSets, but this is very suspicious
472
- }
473
- _loggerProxy.default.logger.info('Locus-info:index#handleLocusAPIResponse --> passing Locus API response to HashTreeParser: ', responseBody);
474
- // update the data in our hash trees
475
- this.hashTreeParser.handleLocusUpdate(responseBody);
673
+ var _responseBody$locus;
674
+ var isWrapped = 'locus' in responseBody;
675
+ var locusUrl = isWrapped ? (_responseBody$locus = responseBody.locus) === null || _responseBody$locus === void 0 ? void 0 : _responseBody$locus.url : responseBody.url;
676
+ 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
682
+ }
683
+ _loggerProxy.default.logger.info('Locus-info:index#handleLocusAPIResponse --> passing Locus API response to HashTreeParser: ', responseBody);
684
+ // update the data in our hash trees
685
+ hashTreeParserEntry.parser.handleLocusUpdate(responseBody);
686
+ } else {
687
+ // LocusDTO without wrapper - pass it through as if it had no dataSets
688
+ hashTreeParserEntry.parser.handleLocusUpdate({
689
+ locus: responseBody
690
+ });
691
+ }
476
692
  } else {
477
- if (responseBody.dataSets) {
693
+ if (isWrapped && responseBody.dataSets) {
478
694
  this.sendClassicVsHashTreeMismatchMetric(meeting, "unexpected hash tree dataSets in API response");
479
695
  }
480
696
  // classic Locus delta
481
- this.handleLocusDelta(responseBody.locus, meeting);
697
+ var locus = isWrapped ? responseBody.locus : responseBody;
698
+ this.handleLocusDelta(locus, meeting);
482
699
  }
483
700
  }
484
701
 
485
702
  /**
486
- *
487
703
  * @param {HashTreeObject} object data set object
488
704
  * @param {any} locus
489
705
  * @returns {void}
@@ -491,7 +707,8 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
491
707
  }, {
492
708
  key: "updateLocusFromHashTreeObject",
493
709
  value: function updateLocusFromHashTreeObject(object, locus) {
494
- var _this4 = this;
710
+ var _this4 = this,
711
+ _locus$self;
495
712
  var type = object.htMeta.elementId.type.toLowerCase();
496
713
  var addParticipantObject = function addParticipantObject(obj) {
497
714
  if (!locus.participants) {
@@ -543,6 +760,27 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
543
760
  });
544
761
  }
545
762
  break;
763
+ case _types.ObjectType.embeddedApp:
764
+ if (object.data) {
765
+ var _locus$embeddedApps;
766
+ _loggerProxy.default.logger.info("Locus-info:index#updateLocusFromHashTreeObject --> embeddedApp id=".concat(object.htMeta.elementId.id, " url='").concat(object.data.url, "' updated version=").concat(object.htMeta.elementId.version, ":"), object.data);
767
+ var existingEmbeddedApp = (_locus$embeddedApps = locus.embeddedApps) === null || _locus$embeddedApps === void 0 ? void 0 : _locus$embeddedApps.find(function (ms) {
768
+ return ms.htMeta.elementId.id === object.htMeta.elementId.id;
769
+ });
770
+ if (existingEmbeddedApp) {
771
+ (0, _assign.default)(existingEmbeddedApp, object.data);
772
+ } else {
773
+ locus.embeddedApps = locus.embeddedApps || [];
774
+ locus.embeddedApps.push(object.data);
775
+ }
776
+ } else {
777
+ var _locus$embeddedApps2;
778
+ _loggerProxy.default.logger.info("Locus-info:index#updateLocusFromHashTreeObject --> embeddedApp id=".concat(object.htMeta.elementId.id, " removed, version=").concat(object.htMeta.elementId.version));
779
+ locus.embeddedApps = (_locus$embeddedApps2 = locus.embeddedApps) === null || _locus$embeddedApps2 === void 0 ? void 0 : _locus$embeddedApps2.filter(function (ms) {
780
+ return ms.htMeta.elementId.id !== object.htMeta.elementId.id;
781
+ });
782
+ }
783
+ break;
546
784
  case _types.ObjectType.participant:
547
785
  _loggerProxy.default.logger.info("Locus-info:index#updateLocusFromHashTreeObject --> participant id=".concat(object.htMeta.elementId.id, " ").concat(object.data ? 'updated' : 'removed', " version=").concat(object.htMeta.elementId.version));
548
786
  if (object.data) {
@@ -557,6 +795,16 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
557
795
  locus.jsSdkMeta.removedParticipantIds.push(participantId);
558
796
  this.hashTreeObjectId2ParticipantId.delete(object.htMeta.elementId.id);
559
797
  }
798
+ // Create self from the participant if it matches self identity and is being moved.
799
+ // We need this, because participant update comes in LLM message often before the self update from Mercury.
800
+ // Other parts of the code detect move only by looking at self, while some other parts of the SDK/webapp code
801
+ // look at participant for roles etc, so if participant is updated but not self, then it looks like we our lost roles temporarily
802
+ // (until self is updated)
803
+ // This will be fixed properly in SPARK-790239
804
+ if (object.data && object.data.identity === ((_locus$self = locus.self) === null || _locus$self === void 0 ? void 0 : _locus$self.identity) && object.data.state === 'LEFT' && object.data.reason === 'MOVED') {
805
+ _loggerProxy.default.logger.info("Locus-info:index#updateLocusFromHashTreeObject --> FOUND a match for MOVED self in participant object ".concat(object.htMeta.elementId.id));
806
+ (0, _assign.default)(locus[_types.ObjectTypeToLocusKeyMap[_types.ObjectType.self]], object.data);
807
+ }
560
808
  break;
561
809
  case _types.ObjectType.control:
562
810
  if (object.data) {
@@ -598,6 +846,10 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
598
846
  }
599
847
  }
600
848
  break;
849
+ case _types.ObjectType.metadata:
850
+ _loggerProxy.default.logger.info("Locus-info:index#updateLocusFromHashTreeObject --> metadata object updated to version ".concat(object.htMeta.elementId.version));
851
+ // we don't use hash tree metadata right now for anything, it's mainly used internally by HashTreeParser
852
+ break;
601
853
  default:
602
854
  _loggerProxy.default.logger.warn("Locus-info:index#updateLocusFromHashTreeObject --> received unsupported object type ".concat(type));
603
855
  break;
@@ -627,6 +879,77 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
627
879
  }
628
880
  }
629
881
 
882
+ /**
883
+ * Checks if the hash tree message should trigger a switch to a different HashTreeParser
884
+ *
885
+ * @param {HashTreeMessage} message incoming hash tree message
886
+ * @returns {boolean} true if the message was handled as a parser switch, false otherwise
887
+ */
888
+ }, {
889
+ key: "handleHashTreeParserSwitch",
890
+ value: function handleHashTreeParserSwitch(message) {
891
+ var _message$locusStateEl3, _message$locusStateEl4;
892
+ var entry = this.hashTreeParsers.get(message.locusUrl);
893
+ var self = (_message$locusStateEl3 = message.locusStateElements) === null || _message$locusStateEl3 === void 0 ? void 0 : (_message$locusStateEl4 = _message$locusStateEl3.find(function (el) {
894
+ return (0, _utils.isSelf)(el);
895
+ })) === null || _message$locusStateEl4 === void 0 ? void 0 : _message$locusStateEl4.data;
896
+ var replaces = getReplaceInfoFromSelf(self,
897
+ // @ts-ignore
898
+ this.webex.internal.device.url);
899
+ if (!entry) {
900
+ var _message$locusStateEl5, _metadata$data, _metadata$data$visibl;
901
+ // Metadata object that contains information about visible datasets is needed to initialize the HashTreeParser,
902
+ // but it's buried inside the message, we need to find it and pass it to HashTreeParser constructor
903
+ var metadata = (_message$locusStateEl5 = message.locusStateElements) === null || _message$locusStateEl5 === void 0 ? void 0 : _message$locusStateEl5.find(function (el) {
904
+ return (0, _utils.isMetadata)(el);
905
+ });
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) {
907
+ _loggerProxy.default.logger.info("Locus-info:index#handleHashTreeParserSwitch --> no hash tree parser found for locusUrl ".concat(message.locusUrl, ", creating a new one"));
908
+ var parser = this.createHashTreeParser({
909
+ locusUrl: message.locusUrl,
910
+ initialLocus: {
911
+ locus: null,
912
+ dataSets: message.dataSets
913
+ },
914
+ metadata: {
915
+ htMeta: metadata.htMeta,
916
+ visibleDataSets: metadata.data.visibleDataSets
917
+ },
918
+ replacedAt: replaces === null || replaces === void 0 ? void 0 : replaces.replacedAt
919
+ });
920
+
921
+ // handle the message with the new parser
922
+ parser.handleMessage(message);
923
+ }
924
+ return true;
925
+ }
926
+ if (entry.parser.state === 'stopped') {
927
+ // 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
+ // 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"));
948
+ return true;
949
+ }
950
+ return false;
951
+ }
952
+
630
953
  /**
631
954
  * Handles a hash tree message received from Locus.
632
955
  *
@@ -642,29 +965,36 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
642
965
  this.sendClassicVsHashTreeMismatchMetric(meeting, "got ".concat(eventType, ", expected ").concat(_constants.LOCUSEVENT.HASH_TREE_DATA_UPDATED));
643
966
  return;
644
967
  }
645
- this.hashTreeParser.handleMessage(message);
968
+ var parserSwitched = this.handleHashTreeParserSwitch(message);
969
+ if (parserSwitched) {
970
+ return;
971
+ }
972
+ var entry = this.hashTreeParsers.get(message.locusUrl);
973
+ entry.parser.handleMessage(message);
646
974
  }
647
975
 
648
976
  /**
649
977
  * Callback registered with HashTreeParser to receive locus info updates.
650
978
  * Updates our locus info based on the data parsed by the hash tree parser.
651
979
  *
980
+ * @param {string} locusUrl - the locus URL for which the update is received
652
981
  * @param {LocusInfoUpdateType} updateType - The type of update received.
653
982
  * @param {Object} [data] - Additional data for the update, if applicable.
654
983
  * @returns {void}
655
984
  */
656
985
  }, {
657
986
  key: "updateFromHashTree",
658
- value: function updateFromHashTree(updateType, data) {
987
+ value: function updateFromHashTree(locusUrl, updateType, data) {
659
988
  var _this5 = this;
660
989
  switch (updateType) {
661
- case _hashTreeParser.LocusInfoUpdateType.OBJECTS_UPDATED:
990
+ case _hashTreeParser2.LocusInfoUpdateType.OBJECTS_UPDATED:
662
991
  {
663
992
  // initialize our new locus
664
993
  var locus = {
665
994
  participants: [],
666
995
  jsSdkMeta: {
667
- removedParticipantIds: []
996
+ removedParticipantIds: [],
997
+ forceReplaceMembers: false
668
998
  }
669
999
  };
670
1000
 
@@ -690,13 +1020,21 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
690
1020
  }
691
1021
  }
692
1022
  });
693
-
1023
+ var hashTreeParserEntry = this.hashTreeParsers.get(locusUrl);
1024
+ if (!hashTreeParserEntry.initializedFromHashTree) {
1025
+ // this is the first time we're getting an update for this locusUrl,
1026
+ // so it's probably a move to/from breakout. We need to start from a clean state,
1027
+ // so empty locus and we rely on Locus giving us sufficient data in the updates to populate it.
1028
+ _loggerProxy.default.logger.info("Locus-info:index#updateFromHashTree --> first INITIAL update for locusUrl ".concat(locusUrl, ", starting from empty state"));
1029
+ hashTreeParserEntry.initializedFromHashTree = true;
1030
+ locus.jsSdkMeta.forceReplaceMembers = true;
1031
+ } else if (
694
1032
  // if Locus object is unchanged or removed, we need to keep using the existing locus
695
1033
  // because the rest of the locusInfo code expects locus to always be present (with at least some of the fields)
696
1034
  // if it gets updated, we only need to have the fields that are not part of "locus" object (like "info" or "mediaShares")
697
1035
  // so that when Locus object gets updated, if the new one is missing some field, that field will
698
1036
  // be removed from our locusInfo
699
- if (locusObjectStateAfterUpdates === LocusObjectStateAfterUpdates.unchanged || locusObjectStateAfterUpdates === LocusObjectStateAfterUpdates.removed) {
1037
+ locusObjectStateAfterUpdates === LocusObjectStateAfterUpdates.unchanged || locusObjectStateAfterUpdates === LocusObjectStateAfterUpdates.removed) {
700
1038
  // copy over all of existing locus except participants
701
1039
  LocusDtoTopLevelKeys.forEach(function (key) {
702
1040
  if (key !== 'participants') {
@@ -728,11 +1066,13 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
728
1066
  this.onDeltaLocus(locus);
729
1067
  break;
730
1068
  }
731
- case _hashTreeParser.LocusInfoUpdateType.MEETING_ENDED:
1069
+ case _hashTreeParser2.LocusInfoUpdateType.MEETING_ENDED:
732
1070
  {
733
- _loggerProxy.default.logger.info("Locus-info:index#updateFromHashTree --> received signal that meeting ended, destroying meeting ".concat(this.meetingId));
734
1071
  var meeting = this.webex.meetings.meetingCollection.get(this.meetingId);
735
- this.webex.meetings.destroy(meeting, _constants.MEETING_REMOVED_REASON.SELF_REMOVED);
1072
+ if (meeting) {
1073
+ _loggerProxy.default.logger.info("Locus-info:index#updateFromHashTree --> received signal that meeting ended, destroying meeting ".concat(this.meetingId));
1074
+ this.webex.meetings.destroy(meeting, _constants.MEETING_REMOVED_REASON.SELF_REMOVED);
1075
+ }
736
1076
  }
737
1077
  }
738
1078
  }
@@ -746,11 +1086,16 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
746
1086
  }, {
747
1087
  key: "parse",
748
1088
  value: function parse(meeting, data) {
749
- if (this.hashTreeParser) {
1089
+ if (this.hashTreeParsers.size > 0) {
750
1090
  this.handleHashTreeMessage(meeting, data.eventType, data.stateElementsMessage);
751
1091
  } else {
752
- // eslint-disable-next-line @typescript-eslint/no-shadow
753
1092
  var eventType = data.eventType;
1093
+ if (eventType === _constants.LOCUSEVENT.HASH_TREE_DATA_UPDATED) {
1094
+ // this can happen when we get an event before join http response
1095
+ // it's OK to just ignore it
1096
+ _loggerProxy.default.logger.info("Locus-info:index#parse --> received locus hash tree event before hashTreeParser is created");
1097
+ return;
1098
+ }
754
1099
  var locus = this.getTheLocusToUpdate(data.locus);
755
1100
  _loggerProxy.default.logger.info("Locus-info:index#parse --> received locus data: ".concat(eventType));
756
1101
  locus.jsSdkMeta = {
@@ -771,14 +1116,11 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
771
1116
  case _constants.LOCUSEVENT.PARTICIPANT_DECLINED:
772
1117
  case _constants.LOCUSEVENT.FLOOR_GRANTED:
773
1118
  case _constants.LOCUSEVENT.FLOOR_RELEASED:
774
- this.onFullLocus(locus, eventType);
1119
+ this.onFullLocus("classic locus event ".concat(eventType), locus, eventType);
775
1120
  break;
776
1121
  case _constants.LOCUSEVENT.DIFFERENCE:
777
1122
  this.handleLocusDelta(locus, meeting);
778
1123
  break;
779
- case _constants.LOCUSEVENT.HASH_TREE_DATA_UPDATED:
780
- this.sendClassicVsHashTreeMismatchMetric(meeting, "got ".concat(eventType, ", expected classic events"));
781
- break;
782
1124
  default:
783
1125
  // Why will there be a event with no eventType ????
784
1126
  // we may not need this, we can get full locus
@@ -803,32 +1145,39 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
803
1145
  /**
804
1146
  * Function for handling full locus when it's using hash trees (so not the "classic" one).
805
1147
  *
1148
+ * @param {string} debugText string explaining the trigger for this call, added to logs for debugging purposes
806
1149
  * @param {object} locus locus object
1150
+ * @param {object} metadata locus hash trees metadata
807
1151
  * @param {string} eventType locus event
808
1152
  * @param {DataSet[]} dataSets
809
1153
  * @returns {void}
810
1154
  */
811
1155
  }, {
812
1156
  key: "onFullLocusWithHashTrees",
813
- value: function onFullLocusWithHashTrees(locus, eventType, dataSets) {
814
- if (!this.hashTreeParser) {
815
- _loggerProxy.default.logger.info("Locus-info:index#onFullLocus --> creating hash tree parser");
816
- _loggerProxy.default.logger.info('Locus-info:index#onFullLocus --> dataSets:', dataSets, ' and locus:', locus);
817
- this.hashTreeParser = this.createHashTreeParser({
1157
+ value: function onFullLocusWithHashTrees(debugText, locus, metadata, eventType, dataSets) {
1158
+ if (!this.hashTreeParsers.has(locus.url)) {
1159
+ _loggerProxy.default.logger.info("Locus-info:index#onFullLocus (".concat(debugText, ") --> creating hash tree parser for locusUrl=").concat(locus.url));
1160
+ _loggerProxy.default.logger.info("Locus-info:index#onFullLocus (".concat(debugText, ") --> dataSets:"), dataSets, ' and locus:', locus, ' and metadata:', metadata);
1161
+ this.createHashTreeParser({
1162
+ locusUrl: locus.url,
818
1163
  initialLocus: {
819
1164
  locus: locus,
820
1165
  dataSets: dataSets
821
- }
1166
+ },
1167
+ metadata: metadata
822
1168
  });
1169
+ // we have a full locus to start with, so we consider Locus info to be "initialized"
1170
+ this.hashTreeParsers.get(locus.url).initializedFromHashTree = true;
823
1171
  this.onFullLocusCommon(locus, eventType);
824
1172
  } else {
825
1173
  // in this case the Locus we're getting is not necessarily the full one
826
1174
  // so treat it like if we just got it in any api response
827
1175
 
828
- _loggerProxy.default.logger.info('Locus-info:index#onFullLocus --> hash tree parser already exists, handling it like a normal API response');
1176
+ _loggerProxy.default.logger.info("Locus-info:index#onFullLocus (".concat(debugText, ") --> hash tree parser already exists, handling it like a normal API response"));
829
1177
  this.handleLocusAPIResponse(undefined, {
830
1178
  dataSets: dataSets,
831
- locus: locus
1179
+ locus: locus,
1180
+ metadata: metadata
832
1181
  });
833
1182
  }
834
1183
  }
@@ -836,15 +1185,16 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
836
1185
  /**
837
1186
  * Function for handling full locus when it's the "classic" one (not hash trees)
838
1187
  *
1188
+ * @param {string} debugText string explaining the trigger for this call, added to logs for debugging purposes
839
1189
  * @param {object} locus locus object
840
1190
  * @param {string} eventType locus event
841
1191
  * @returns {void}
842
1192
  */
843
1193
  }, {
844
1194
  key: "onFullLocusClassic",
845
- value: function onFullLocusClassic(locus, eventType) {
1195
+ value: function onFullLocusClassic(debugText, locus, eventType) {
846
1196
  if (!this.locusParser.isNewFullLocus(locus)) {
847
- _loggerProxy.default.logger.info("Locus-info:index#onFullLocus --> ignoring old full locus DTO, eventType=".concat(eventType));
1197
+ _loggerProxy.default.logger.info("Locus-info:index#onFullLocus (".concat(debugText, ") --> ignoring old full locus DTO, eventType=").concat(eventType));
848
1198
  return;
849
1199
  }
850
1200
  this.onFullLocusCommon(locus, eventType);
@@ -852,23 +1202,28 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
852
1202
 
853
1203
  /**
854
1204
  * updates the locus with full locus object
1205
+ * @param {string} debugText string explaining the trigger for this call, added to logs for debugging purposes
855
1206
  * @param {object} locus locus object
856
1207
  * @param {string} eventType locus event
857
1208
  * @param {DataSet[]} dataSets
1209
+ * @param {object} metadata locus hash trees metadata
858
1210
  * @returns {object} null
859
1211
  * @memberof LocusInfo
860
1212
  */
861
1213
  }, {
862
1214
  key: "onFullLocus",
863
- value: function onFullLocus(locus, eventType, dataSets) {
1215
+ value: function onFullLocus(debugText, locus, eventType, dataSets, metadata) {
864
1216
  if (!locus) {
865
- _loggerProxy.default.logger.error('Locus-info:index#onFullLocus --> object passed as argument was invalid, continuing.');
1217
+ _loggerProxy.default.logger.error("Locus-info:index#onFullLocus (".concat(debugText, ") --> object passed as argument was invalid, continuing."));
866
1218
  }
867
1219
  if (dataSets) {
1220
+ if (!metadata) {
1221
+ throw new Error("Locus-info:index#onFullLocus (".concat(debugText, ") --> hash tree metadata is missing with full Locus"));
1222
+ }
868
1223
  // this is the new hashmap Locus DTO format (only applicable to webinars for now)
869
- this.onFullLocusWithHashTrees(locus, eventType, dataSets);
1224
+ this.onFullLocusWithHashTrees(debugText, locus, metadata, eventType, dataSets);
870
1225
  } else {
871
- this.onFullLocusClassic(locus, eventType);
1226
+ this.onFullLocusClassic(debugText, locus, eventType);
872
1227
  }
873
1228
  }
874
1229
 
@@ -889,7 +1244,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
889
1244
  (_this$participants = this.participants) === null || _this$participants === void 0 ? void 0 : _this$participants.forEach(function (participant) {
890
1245
  var _participant$htMeta;
891
1246
  // participant.htMeta is set only for hash tree based locus
892
- if ((_participant$htMeta = participant.htMeta) !== null && _participant$htMeta !== void 0 && _participant$htMeta.elementId.id) {
1247
+ if (typeof ((_participant$htMeta = participant.htMeta) === null || _participant$htMeta === void 0 ? void 0 : _participant$htMeta.elementId.id) === 'number') {
893
1248
  _this6.hashTreeObjectId2ParticipantId.set(participant.htMeta.elementId.id, participant.id);
894
1249
  }
895
1250
  });
@@ -940,6 +1295,30 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
940
1295
  }
941
1296
  }
942
1297
 
1298
+ /**
1299
+ * Makes sure that passed in locus object has a participant object for self.
1300
+ *
1301
+ * @param {LocusDTO} locus The locus object to check and modify if needed
1302
+ * @returns {void}
1303
+ */
1304
+ }, {
1305
+ key: "ensureSelfParticipantExists",
1306
+ value: function ensureSelfParticipantExists(locus) {
1307
+ var self = locus.self;
1308
+
1309
+ // sanity check, this should never fail
1310
+ if (!(self !== null && self !== void 0 && self.identity) || !(0, _isArray.default)(locus.participants)) {
1311
+ _loggerProxy.default.logger.warn("Locus-info:index#ensureSelfParticipantExists --> locus object is missing required fields, cannot ensure self participant exists. self?.identity=\"".concat(self === null || self === void 0 ? void 0 : self.identity, "\""));
1312
+ return;
1313
+ }
1314
+ var selfExists = locus.participants.some(function (participant) {
1315
+ return participant.identity === self.identity;
1316
+ });
1317
+ if (!selfExists) {
1318
+ locus.participants.push(_objectSpread({}, self));
1319
+ }
1320
+ }
1321
+
943
1322
  /**
944
1323
  * @param {Object} locus
945
1324
  * @returns {undefined}
@@ -949,10 +1328,20 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
949
1328
  key: "onDeltaLocus",
950
1329
  value: function onDeltaLocus(locus) {
951
1330
  var _locus$jsSdkMeta2;
952
- var isReplaceMembers = _controlsUtils.default.isNeedReplaceMembers(this.controls, locus.controls);
1331
+ var isReplaceMembers = ((_locus$jsSdkMeta2 = locus.jsSdkMeta) === null || _locus$jsSdkMeta2 === void 0 ? void 0 : _locus$jsSdkMeta2.forceReplaceMembers) !== undefined ? locus.jsSdkMeta.forceReplaceMembers : _controlsUtils.default.isNeedReplaceMembers(this.controls, locus.controls);
1332
+ if (isReplaceMembers) {
1333
+ // when we're moving between breakouts, Locus sometimes doesn't send us
1334
+ // any participants at all for a few seconds
1335
+ // Web app relies on having at least the self participant always there
1336
+ // so we copy self into participants if it's not there.
1337
+ this.ensureSelfParticipantExists(locus);
1338
+ }
953
1339
  this.mergeParticipants(this.participants, locus.participants);
954
- this.updateLocusInfo(locus);
955
- this.updateParticipants(locus.participants, (_locus$jsSdkMeta2 = locus.jsSdkMeta) === null || _locus$jsSdkMeta2 === void 0 ? void 0 : _locus$jsSdkMeta2.removedParticipantIds, isReplaceMembers);
1340
+ var updatesApplied = this.updateLocusInfo(locus);
1341
+ if (updatesApplied) {
1342
+ var _locus$jsSdkMeta3;
1343
+ this.updateParticipants(locus.participants, (_locus$jsSdkMeta3 = locus.jsSdkMeta) === null || _locus$jsSdkMeta3 === void 0 ? void 0 : _locus$jsSdkMeta3.removedParticipantIds, isReplaceMembers);
1344
+ }
956
1345
  this.isMeetingActive();
957
1346
  }
958
1347
 
@@ -964,12 +1353,12 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
964
1353
  }, {
965
1354
  key: "updateLocusInfo",
966
1355
  value: function updateLocusInfo(locus) {
967
- var _locus$self, _locus$self2;
968
- if (((_locus$self = locus.self) === null || _locus$self === void 0 ? void 0 : _locus$self.reason) === 'MOVED' && ((_locus$self2 = locus.self) === null || _locus$self2 === void 0 ? void 0 : _locus$self2.state) === 'LEFT') {
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') {
969
1358
  // When moved to a breakout session locus sends a message for the previous locus
970
1359
  // indicating that we have been moved. It isn't helpful to continue parsing this
971
1360
  // as it gets interpreted as if we have left the call
972
- return;
1361
+ return false;
973
1362
  }
974
1363
  this.updateControls(locus.controls, locus.self);
975
1364
  this.updateConversationUrl(locus.conversationUrl, locus.info);
@@ -988,6 +1377,8 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
988
1377
  this.updateLinks(locus.links);
989
1378
  this.compareAndUpdate();
990
1379
  // update which required to compare different objects from locus
1380
+
1381
+ return true;
991
1382
  }
992
1383
 
993
1384
  /**
@@ -1102,23 +1493,6 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1102
1493
  reason: _constants.MEETING_REMOVED_REASON.MEETING_INACTIVE_TERMINATING,
1103
1494
  shouldLeave: false
1104
1495
  });
1105
- } else if (this.fullState && this.fullState.removed) {
1106
- // user has been dropped from a meeting
1107
-
1108
- // @ts-ignore
1109
- this.webex.internal.newMetrics.submitClientEvent({
1110
- name: 'client.call.remote-ended',
1111
- options: {
1112
- meetingId: this.meetingId
1113
- }
1114
- });
1115
- this.emitScoped({
1116
- file: 'locus-info',
1117
- function: 'isMeetingActive'
1118
- }, _constants.EVENTS.DESTROY_MEETING, {
1119
- reason: _constants.MEETING_REMOVED_REASON.FULLSTATE_REMOVED,
1120
- shouldLeave: false
1121
- });
1122
1496
  }
1123
1497
  // If you are guest and you are removed from the meeting
1124
1498
  // You wont get any further events
@@ -1205,11 +1579,11 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1205
1579
  isReplace: isReplace
1206
1580
  });
1207
1581
  if (participants && (0, _isArray.default)(participants) && participants.length > 0) {
1208
- var _iterator = _createForOfIteratorHelper(participants),
1209
- _step;
1582
+ var _iterator3 = _createForOfIteratorHelper(participants),
1583
+ _step3;
1210
1584
  try {
1211
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
1212
- var participant = _step.value;
1585
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
1586
+ var participant = _step3.value;
1213
1587
  if (participant && (participant === null || participant === void 0 ? void 0 : participant.reason) === 'FAILURE') {
1214
1588
  var _participant$person;
1215
1589
  this.emitScoped({
@@ -1221,9 +1595,9 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1221
1595
  }
1222
1596
  }
1223
1597
  } catch (err) {
1224
- _iterator.e(err);
1598
+ _iterator3.e(err);
1225
1599
  } finally {
1226
- _iterator.f();
1600
+ _iterator3.f();
1227
1601
  }
1228
1602
  }
1229
1603
  }
@@ -1246,6 +1620,7 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1246
1620
  hasMeetingContainerChanged = _ControlsUtils$getCon2.hasMeetingContainerChanged,
1247
1621
  hasTranscribeChanged = _ControlsUtils$getCon2.hasTranscribeChanged,
1248
1622
  hasHesiodLLMIdChanged = _ControlsUtils$getCon2.hasHesiodLLMIdChanged,
1623
+ hasAiSummaryNotificationChanged = _ControlsUtils$getCon2.hasAiSummaryNotificationChanged,
1249
1624
  hasTranscribeSpokenLanguageChanged = _ControlsUtils$getCon2.hasTranscribeSpokenLanguageChanged,
1250
1625
  hasManualCaptionChanged = _ControlsUtils$getCon2.hasManualCaptionChanged,
1251
1626
  hasEntryExitToneChanged = _ControlsUtils$getCon2.hasEntryExitToneChanged,
@@ -1376,6 +1751,14 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1376
1751
  hesiodLlmId: hesiodLlmId
1377
1752
  });
1378
1753
  }
1754
+ if (hasAiSummaryNotificationChanged) {
1755
+ this.emitScoped({
1756
+ file: 'locus-info',
1757
+ function: 'updateControls'
1758
+ }, _constants.LOCUSINFO.EVENTS.CONTROLS_AI_SUMMARY_NOTIFICATION_UPDATED, {
1759
+ aiSummaryNotification: current.transcribe.aiSummaryNotification
1760
+ });
1761
+ }
1379
1762
  if (hasTranscribeSpokenLanguageChanged) {
1380
1763
  var spokenLanguage = current.transcribe.spokenLanguage;
1381
1764
  this.emitScoped({
@@ -1800,6 +2183,14 @@ var LocusInfo = exports.default = /*#__PURE__*/function (_EventsScope) {
1800
2183
  brb: parsedSelves.current.brb
1801
2184
  });
1802
2185
  }
2186
+ if (parsedSelves.updates.selfIdChanged) {
2187
+ this.emitScoped({
2188
+ file: 'locus-info',
2189
+ function: 'updateSelf'
2190
+ }, _constants.LOCUSINFO.EVENTS.SELF_ID_CHANGED, {
2191
+ selfId: parsedSelves.current.selfId
2192
+ });
2193
+ }
1803
2194
  if (parsedSelves.updates.interpretationChanged) {
1804
2195
  this.emitScoped({
1805
2196
  file: 'locus-info',