@webex/plugin-meetings 3.0.0-beta.39 → 3.0.0-beta.391

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 (393) hide show
  1. package/README.md +58 -8
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +342 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +94 -15
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/events.js +45 -0
  11. package/dist/breakouts/events.js.map +1 -0
  12. package/dist/breakouts/index.js +671 -81
  13. package/dist/breakouts/index.js.map +1 -1
  14. package/dist/breakouts/utils.js +45 -1
  15. package/dist/breakouts/utils.js.map +1 -1
  16. package/dist/common/errors/no-meeting-info.js +51 -0
  17. package/dist/common/errors/no-meeting-info.js.map +1 -0
  18. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  19. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  20. package/dist/common/errors/webex-errors.js +48 -7
  21. package/dist/common/errors/webex-errors.js.map +1 -1
  22. package/dist/common/logs/logger-proxy.js +1 -1
  23. package/dist/common/logs/logger-proxy.js.map +1 -1
  24. package/dist/common/logs/request.js +5 -1
  25. package/dist/common/logs/request.js.map +1 -1
  26. package/dist/common/queue.js +24 -9
  27. package/dist/common/queue.js.map +1 -1
  28. package/dist/config.js +5 -10
  29. package/dist/config.js.map +1 -1
  30. package/dist/constants.js +242 -33
  31. package/dist/constants.js.map +1 -1
  32. package/dist/controls-options-manager/enums.js +14 -2
  33. package/dist/controls-options-manager/enums.js.map +1 -1
  34. package/dist/controls-options-manager/index.js +109 -15
  35. package/dist/controls-options-manager/index.js.map +1 -1
  36. package/dist/controls-options-manager/types.js +7 -0
  37. package/dist/controls-options-manager/types.js.map +1 -0
  38. package/dist/controls-options-manager/util.js +309 -18
  39. package/dist/controls-options-manager/util.js.map +1 -1
  40. package/dist/index.js +110 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/interceptors/index.js +15 -0
  43. package/dist/interceptors/index.js.map +1 -0
  44. package/dist/interceptors/locusRetry.js +93 -0
  45. package/dist/interceptors/locusRetry.js.map +1 -0
  46. package/dist/interpretation/collection.js +23 -0
  47. package/dist/interpretation/collection.js.map +1 -0
  48. package/dist/interpretation/index.js +380 -0
  49. package/dist/interpretation/index.js.map +1 -0
  50. package/dist/interpretation/siLanguage.js +25 -0
  51. package/dist/interpretation/siLanguage.js.map +1 -0
  52. package/dist/locus-info/controlsUtils.js +91 -2
  53. package/dist/locus-info/controlsUtils.js.map +1 -1
  54. package/dist/locus-info/index.js +386 -62
  55. package/dist/locus-info/index.js.map +1 -1
  56. package/dist/locus-info/infoUtils.js +7 -1
  57. package/dist/locus-info/infoUtils.js.map +1 -1
  58. package/dist/locus-info/mediaSharesUtils.js +71 -1
  59. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  60. package/dist/locus-info/parser.js +249 -72
  61. package/dist/locus-info/parser.js.map +1 -1
  62. package/dist/locus-info/selfUtils.js +89 -14
  63. package/dist/locus-info/selfUtils.js.map +1 -1
  64. package/dist/media/index.js +65 -102
  65. package/dist/media/index.js.map +1 -1
  66. package/dist/media/properties.js +73 -124
  67. package/dist/media/properties.js.map +1 -1
  68. package/dist/mediaQualityMetrics/config.js +135 -330
  69. package/dist/mediaQualityMetrics/config.js.map +1 -1
  70. package/dist/meeting/in-meeting-actions.js +86 -2
  71. package/dist/meeting/in-meeting-actions.js.map +1 -1
  72. package/dist/meeting/index.js +4075 -2827
  73. package/dist/meeting/index.js.map +1 -1
  74. package/dist/meeting/locusMediaRequest.js +292 -0
  75. package/dist/meeting/locusMediaRequest.js.map +1 -0
  76. package/dist/meeting/muteState.js +224 -136
  77. package/dist/meeting/muteState.js.map +1 -1
  78. package/dist/meeting/request.js +177 -152
  79. package/dist/meeting/request.js.map +1 -1
  80. package/dist/meeting/util.js +672 -417
  81. package/dist/meeting/util.js.map +1 -1
  82. package/dist/meeting-info/index.js +73 -7
  83. package/dist/meeting-info/index.js.map +1 -1
  84. package/dist/meeting-info/meeting-info-v2.js +192 -51
  85. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  86. package/dist/meeting-info/util.js +1 -1
  87. package/dist/meeting-info/util.js.map +1 -1
  88. package/dist/meeting-info/utilv2.js +36 -36
  89. package/dist/meeting-info/utilv2.js.map +1 -1
  90. package/dist/meetings/collection.js +39 -0
  91. package/dist/meetings/collection.js.map +1 -1
  92. package/dist/meetings/index.js +484 -119
  93. package/dist/meetings/index.js.map +1 -1
  94. package/dist/meetings/meetings.types.js +7 -0
  95. package/dist/meetings/meetings.types.js.map +1 -0
  96. package/dist/meetings/request.js +2 -0
  97. package/dist/meetings/request.js.map +1 -1
  98. package/dist/meetings/util.js +73 -7
  99. package/dist/meetings/util.js.map +1 -1
  100. package/dist/member/index.js +58 -0
  101. package/dist/member/index.js.map +1 -1
  102. package/dist/member/types.js +25 -0
  103. package/dist/member/types.js.map +1 -0
  104. package/dist/member/util.js +132 -25
  105. package/dist/member/util.js.map +1 -1
  106. package/dist/members/collection.js +10 -0
  107. package/dist/members/collection.js.map +1 -1
  108. package/dist/members/index.js +102 -6
  109. package/dist/members/index.js.map +1 -1
  110. package/dist/members/request.js +106 -38
  111. package/dist/members/request.js.map +1 -1
  112. package/dist/members/types.js +15 -0
  113. package/dist/members/types.js.map +1 -0
  114. package/dist/members/util.js +326 -232
  115. package/dist/members/util.js.map +1 -1
  116. package/dist/metrics/constants.js +18 -1
  117. package/dist/metrics/constants.js.map +1 -1
  118. package/dist/metrics/index.js +1 -446
  119. package/dist/metrics/index.js.map +1 -1
  120. package/dist/multistream/mediaRequestManager.js +223 -32
  121. package/dist/multistream/mediaRequestManager.js.map +1 -1
  122. package/dist/multistream/receiveSlot.js +10 -0
  123. package/dist/multistream/receiveSlot.js.map +1 -1
  124. package/dist/multistream/receiveSlotManager.js +39 -36
  125. package/dist/multistream/receiveSlotManager.js.map +1 -1
  126. package/dist/multistream/remoteMedia.js +3 -1
  127. package/dist/multistream/remoteMedia.js.map +1 -1
  128. package/dist/multistream/remoteMediaGroup.js +76 -5
  129. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  130. package/dist/multistream/remoteMediaManager.js +366 -104
  131. package/dist/multistream/remoteMediaManager.js.map +1 -1
  132. package/dist/multistream/sendSlotManager.js +255 -0
  133. package/dist/multistream/sendSlotManager.js.map +1 -0
  134. package/dist/reachability/clusterReachability.js +356 -0
  135. package/dist/reachability/clusterReachability.js.map +1 -0
  136. package/dist/reachability/index.js +263 -390
  137. package/dist/reachability/index.js.map +1 -1
  138. package/dist/reachability/request.js +6 -4
  139. package/dist/reachability/request.js.map +1 -1
  140. package/dist/reachability/util.js +29 -0
  141. package/dist/reachability/util.js.map +1 -0
  142. package/dist/reconnection-manager/index.js +266 -202
  143. package/dist/reconnection-manager/index.js.map +1 -1
  144. package/dist/recording-controller/index.js +21 -2
  145. package/dist/recording-controller/index.js.map +1 -1
  146. package/dist/recording-controller/util.js +9 -8
  147. package/dist/recording-controller/util.js.map +1 -1
  148. package/dist/roap/index.js +51 -28
  149. package/dist/roap/index.js.map +1 -1
  150. package/dist/roap/request.js +48 -64
  151. package/dist/roap/request.js.map +1 -1
  152. package/dist/roap/turnDiscovery.js +220 -70
  153. package/dist/roap/turnDiscovery.js.map +1 -1
  154. package/dist/rtcMetrics/constants.js +12 -0
  155. package/dist/rtcMetrics/constants.js.map +1 -0
  156. package/dist/rtcMetrics/index.js +179 -0
  157. package/dist/rtcMetrics/index.js.map +1 -0
  158. package/dist/statsAnalyzer/index.js +357 -295
  159. package/dist/statsAnalyzer/index.js.map +1 -1
  160. package/dist/statsAnalyzer/mqaUtil.js +296 -156
  161. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  162. package/dist/types/annotation/annotation.types.d.ts +42 -0
  163. package/dist/types/annotation/constants.d.ts +31 -0
  164. package/dist/types/annotation/index.d.ts +117 -0
  165. package/dist/types/breakouts/events.d.ts +8 -0
  166. package/dist/types/breakouts/utils.d.ts +14 -0
  167. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  168. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  169. package/dist/types/common/errors/webex-errors.d.ts +25 -1
  170. package/dist/types/common/logs/request.d.ts +2 -0
  171. package/dist/types/common/queue.d.ts +9 -7
  172. package/dist/types/config.d.ts +2 -7
  173. package/dist/types/constants.d.ts +203 -31
  174. package/dist/types/controls-options-manager/enums.d.ts +11 -1
  175. package/dist/types/controls-options-manager/index.d.ts +17 -1
  176. package/dist/types/controls-options-manager/types.d.ts +43 -0
  177. package/dist/types/controls-options-manager/util.d.ts +1 -7
  178. package/dist/types/index.d.ts +6 -5
  179. package/dist/types/interceptors/index.d.ts +2 -0
  180. package/dist/types/interceptors/locusRetry.d.ts +27 -0
  181. package/dist/types/interpretation/collection.d.ts +5 -0
  182. package/dist/types/interpretation/index.d.ts +5 -0
  183. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  184. package/dist/types/locus-info/index.d.ts +57 -4
  185. package/dist/types/locus-info/parser.d.ts +66 -6
  186. package/dist/types/media/index.d.ts +2 -0
  187. package/dist/types/media/properties.d.ts +34 -49
  188. package/dist/types/mediaQualityMetrics/config.d.ts +99 -223
  189. package/dist/types/meeting/in-meeting-actions.d.ts +86 -2
  190. package/dist/types/meeting/index.d.ts +567 -496
  191. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  192. package/dist/types/meeting/muteState.d.ts +93 -25
  193. package/dist/types/meeting/request.d.ts +64 -43
  194. package/dist/types/meeting/util.d.ts +117 -1
  195. package/dist/types/meeting-info/index.d.ts +13 -1
  196. package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
  197. package/dist/types/meetings/collection.d.ts +17 -0
  198. package/dist/types/meetings/index.d.ts +113 -21
  199. package/dist/types/meetings/meetings.types.d.ts +4 -0
  200. package/dist/types/member/index.d.ts +14 -0
  201. package/dist/types/member/types.d.ts +32 -0
  202. package/dist/types/members/collection.d.ts +5 -0
  203. package/dist/types/members/index.d.ts +35 -2
  204. package/dist/types/members/request.d.ts +73 -9
  205. package/dist/types/members/types.d.ts +25 -0
  206. package/dist/types/members/util.d.ts +214 -1
  207. package/dist/types/metrics/constants.d.ts +17 -0
  208. package/dist/types/metrics/index.d.ts +4 -111
  209. package/dist/types/multistream/mediaRequestManager.d.ts +72 -3
  210. package/dist/types/multistream/receiveSlot.d.ts +7 -3
  211. package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
  212. package/dist/types/multistream/remoteMedia.d.ts +3 -31
  213. package/dist/types/multistream/remoteMediaGroup.d.ts +2 -9
  214. package/dist/types/multistream/remoteMediaManager.d.ts +62 -2
  215. package/dist/types/multistream/sendSlotManager.d.ts +70 -0
  216. package/dist/types/reachability/clusterReachability.d.ts +109 -0
  217. package/dist/types/reachability/index.d.ts +60 -95
  218. package/dist/types/reachability/request.d.ts +3 -1
  219. package/dist/types/reachability/util.d.ts +8 -0
  220. package/dist/types/reconnection-manager/index.d.ts +19 -0
  221. package/dist/types/recording-controller/index.d.ts +15 -1
  222. package/dist/types/recording-controller/util.d.ts +5 -4
  223. package/dist/types/roap/index.d.ts +2 -1
  224. package/dist/types/roap/request.d.ts +9 -8
  225. package/dist/types/roap/turnDiscovery.d.ts +39 -5
  226. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  227. package/dist/types/rtcMetrics/index.d.ts +61 -0
  228. package/dist/types/statsAnalyzer/index.d.ts +34 -12
  229. package/dist/types/statsAnalyzer/mqaUtil.d.ts +28 -4
  230. package/dist/types/webinar/collection.d.ts +16 -0
  231. package/dist/types/webinar/index.d.ts +5 -0
  232. package/dist/webinar/collection.js +44 -0
  233. package/dist/webinar/collection.js.map +1 -0
  234. package/dist/webinar/index.js +69 -0
  235. package/dist/webinar/index.js.map +1 -0
  236. package/package.json +22 -19
  237. package/src/annotation/annotation.types.ts +50 -0
  238. package/src/annotation/constants.ts +36 -0
  239. package/src/annotation/index.ts +328 -0
  240. package/src/breakouts/README.md +35 -11
  241. package/src/breakouts/breakout.ts +67 -9
  242. package/src/breakouts/events.ts +56 -0
  243. package/src/breakouts/index.ts +558 -59
  244. package/src/breakouts/utils.ts +42 -0
  245. package/src/common/errors/no-meeting-info.ts +24 -0
  246. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  247. package/src/common/errors/webex-errors.ts +44 -2
  248. package/src/common/logs/logger-proxy.ts +1 -1
  249. package/src/common/logs/request.ts +5 -1
  250. package/src/common/queue.ts +22 -8
  251. package/src/config.ts +4 -9
  252. package/src/constants.ts +229 -21
  253. package/src/controls-options-manager/enums.ts +12 -0
  254. package/src/controls-options-manager/index.ts +116 -21
  255. package/src/controls-options-manager/types.ts +59 -0
  256. package/src/controls-options-manager/util.ts +294 -14
  257. package/src/index.ts +44 -0
  258. package/src/interceptors/index.ts +3 -0
  259. package/src/interceptors/locusRetry.ts +67 -0
  260. package/src/interpretation/README.md +60 -0
  261. package/src/interpretation/collection.ts +19 -0
  262. package/src/interpretation/index.ts +349 -0
  263. package/src/interpretation/siLanguage.ts +18 -0
  264. package/src/locus-info/controlsUtils.ts +108 -0
  265. package/src/locus-info/index.ts +417 -59
  266. package/src/locus-info/infoUtils.ts +10 -2
  267. package/src/locus-info/mediaSharesUtils.ts +80 -0
  268. package/src/locus-info/parser.ts +258 -47
  269. package/src/locus-info/selfUtils.ts +81 -5
  270. package/src/media/index.ts +100 -108
  271. package/src/media/properties.ts +88 -117
  272. package/src/mediaQualityMetrics/config.ts +103 -238
  273. package/src/meeting/in-meeting-actions.ts +171 -3
  274. package/src/meeting/index.ts +3411 -2435
  275. package/src/meeting/locusMediaRequest.ts +313 -0
  276. package/src/meeting/muteState.ts +223 -136
  277. package/src/meeting/request.ts +155 -120
  278. package/src/meeting/util.ts +685 -395
  279. package/src/meeting-info/index.ts +81 -8
  280. package/src/meeting-info/meeting-info-v2.ts +170 -14
  281. package/src/meeting-info/util.ts +1 -1
  282. package/src/meeting-info/utilv2.ts +23 -23
  283. package/src/meetings/collection.ts +33 -0
  284. package/src/meetings/index.ts +507 -127
  285. package/src/meetings/meetings.types.ts +12 -0
  286. package/src/meetings/request.ts +2 -0
  287. package/src/meetings/util.ts +81 -12
  288. package/src/member/index.ts +58 -0
  289. package/src/member/types.ts +38 -0
  290. package/src/member/util.ts +141 -25
  291. package/src/members/collection.ts +8 -0
  292. package/src/members/index.ts +134 -8
  293. package/src/members/request.ts +97 -17
  294. package/src/members/types.ts +29 -0
  295. package/src/members/util.ts +333 -240
  296. package/src/metrics/constants.ts +17 -0
  297. package/src/metrics/index.ts +1 -469
  298. package/src/multistream/mediaRequestManager.ts +271 -56
  299. package/src/multistream/receiveSlot.ts +11 -4
  300. package/src/multistream/receiveSlotManager.ts +34 -24
  301. package/src/multistream/remoteMedia.ts +5 -3
  302. package/src/multistream/remoteMediaGroup.ts +78 -0
  303. package/src/multistream/remoteMediaManager.ts +248 -44
  304. package/src/multistream/sendSlotManager.ts +199 -0
  305. package/src/reachability/clusterReachability.ts +320 -0
  306. package/src/reachability/index.ts +229 -346
  307. package/src/reachability/request.ts +8 -4
  308. package/src/reachability/util.ts +24 -0
  309. package/src/reconnection-manager/index.ts +128 -97
  310. package/src/recording-controller/index.ts +20 -3
  311. package/src/recording-controller/util.ts +26 -9
  312. package/src/roap/index.ts +52 -23
  313. package/src/roap/request.ts +48 -67
  314. package/src/roap/turnDiscovery.ts +147 -49
  315. package/src/rtcMetrics/constants.ts +3 -0
  316. package/src/rtcMetrics/index.ts +166 -0
  317. package/src/statsAnalyzer/index.ts +457 -416
  318. package/src/statsAnalyzer/mqaUtil.ts +317 -170
  319. package/src/webinar/collection.ts +31 -0
  320. package/src/webinar/index.ts +62 -0
  321. package/test/integration/spec/converged-space-meetings.js +60 -3
  322. package/test/integration/spec/journey.js +320 -261
  323. package/test/integration/spec/space-meeting.js +76 -3
  324. package/test/unit/spec/annotation/index.ts +418 -0
  325. package/test/unit/spec/breakouts/breakout.ts +118 -28
  326. package/test/unit/spec/breakouts/events.ts +89 -0
  327. package/test/unit/spec/breakouts/index.ts +1349 -114
  328. package/test/unit/spec/breakouts/utils.js +52 -1
  329. package/test/unit/spec/common/queue.js +31 -2
  330. package/test/unit/spec/controls-options-manager/index.js +163 -0
  331. package/test/unit/spec/controls-options-manager/util.js +576 -60
  332. package/test/unit/spec/fixture/locus.js +1 -0
  333. package/test/unit/spec/interceptors/locusRetry.ts +131 -0
  334. package/test/unit/spec/interpretation/collection.ts +15 -0
  335. package/test/unit/spec/interpretation/index.ts +625 -0
  336. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  337. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  338. package/test/unit/spec/locus-info/index.js +1363 -37
  339. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  340. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  341. package/test/unit/spec/locus-info/mediaSharesUtils.ts +41 -0
  342. package/test/unit/spec/locus-info/parser.js +116 -35
  343. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  344. package/test/unit/spec/locus-info/selfUtils.js +208 -17
  345. package/test/unit/spec/media/index.ts +173 -81
  346. package/test/unit/spec/media/properties.ts +2 -2
  347. package/test/unit/spec/meeting/in-meeting-actions.ts +85 -3
  348. package/test/unit/spec/meeting/index.js +6821 -2172
  349. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  350. package/test/unit/spec/meeting/muteState.js +402 -212
  351. package/test/unit/spec/meeting/request.js +473 -54
  352. package/test/unit/spec/meeting/utils.js +773 -67
  353. package/test/unit/spec/meeting-info/index.js +300 -0
  354. package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
  355. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  356. package/test/unit/spec/meetings/collection.js +26 -0
  357. package/test/unit/spec/meetings/index.js +1415 -213
  358. package/test/unit/spec/meetings/utils.js +229 -2
  359. package/test/unit/spec/member/index.js +61 -6
  360. package/test/unit/spec/member/util.js +510 -34
  361. package/test/unit/spec/members/index.js +432 -1
  362. package/test/unit/spec/members/request.js +206 -27
  363. package/test/unit/spec/members/utils.js +210 -0
  364. package/test/unit/spec/metrics/index.js +1 -50
  365. package/test/unit/spec/multistream/mediaRequestManager.ts +781 -114
  366. package/test/unit/spec/multistream/receiveSlot.ts +9 -1
  367. package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
  368. package/test/unit/spec/multistream/remoteMedia.ts +2 -0
  369. package/test/unit/spec/multistream/remoteMediaGroup.ts +345 -0
  370. package/test/unit/spec/multistream/remoteMediaManager.ts +525 -0
  371. package/test/unit/spec/multistream/sendSlotManager.ts +274 -0
  372. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  373. package/test/unit/spec/reachability/index.ts +551 -14
  374. package/test/unit/spec/reachability/request.js +3 -1
  375. package/test/unit/spec/reachability/util.ts +40 -0
  376. package/test/unit/spec/reconnection-manager/index.js +171 -11
  377. package/test/unit/spec/recording-controller/index.js +294 -218
  378. package/test/unit/spec/recording-controller/util.js +223 -96
  379. package/test/unit/spec/roap/index.ts +180 -83
  380. package/test/unit/spec/roap/request.ts +100 -62
  381. package/test/unit/spec/roap/turnDiscovery.ts +388 -96
  382. package/test/unit/spec/rtcMetrics/index.ts +122 -0
  383. package/test/unit/spec/stats-analyzer/index.js +1252 -12
  384. package/test/unit/spec/webinar/collection.ts +13 -0
  385. package/test/unit/spec/webinar/index.ts +60 -0
  386. package/test/utils/integrationTestUtils.js +46 -0
  387. package/test/utils/testUtils.js +0 -57
  388. package/test/utils/webex-test-users.js +12 -4
  389. package/dist/metrics/config.js +0 -289
  390. package/dist/metrics/config.js.map +0 -1
  391. package/dist/types/metrics/config.d.ts +0 -169
  392. package/src/index.js +0 -18
  393. package/src/metrics/config.ts +0 -485
@@ -1,4 +1,4 @@
1
- import {isEqual} from 'lodash';
1
+ import {isEqual, assignWith, cloneDeep, isEmpty} from 'lodash';
2
2
 
3
3
  import LoggerProxy from '../common/logs/logger-proxy';
4
4
  import EventsScope from '../common/events/events-scope';
@@ -17,8 +17,6 @@ import {
17
17
  CALL_REMOVED_REASON,
18
18
  RECORDING_STATE,
19
19
  } from '../constants';
20
- import Metrics from '../metrics';
21
- import {eventType} from '../metrics/config';
22
20
  import InfoUtils from './infoUtils';
23
21
  import FullState from './fullState';
24
22
  import SelfUtils from './selfUtils';
@@ -27,6 +25,8 @@ import ControlsUtils from './controlsUtils';
27
25
  import EmbeddedAppsUtils from './embeddedAppsUtils';
28
26
  import MediaSharesUtils from './mediaSharesUtils';
29
27
  import LocusDeltaParser from './parser';
28
+ import Metrics from '../metrics';
29
+ import BEHAVIORAL_METRICS from '../metrics/constants';
30
30
 
31
31
  /**
32
32
  * @description LocusInfo extends ChildEmitter to convert locusInfo info a private emitter to parent object
@@ -59,11 +59,19 @@ export default class LocusInfo extends EventsScope {
59
59
  fullState: any;
60
60
  host: any;
61
61
  info: any;
62
+ roles: any;
62
63
  mediaShares: any;
63
64
  replace: any;
64
65
  url: any;
65
66
  services: any;
66
-
67
+ mainSessionLocusCache: any;
68
+ /**
69
+ * Constructor
70
+ * @param {function} updateMeeting callback to update the meeting object from an object
71
+ * @param {object} webex
72
+ * @param {string} meetingId
73
+ * @returns {undefined}
74
+ */
67
75
  constructor(updateMeeting, webex, meetingId) {
68
76
  super();
69
77
  this.parsedLocus = {
@@ -77,6 +85,82 @@ export default class LocusInfo extends EventsScope {
77
85
  this.locusParser = new LocusDeltaParser();
78
86
  }
79
87
 
88
+ /**
89
+ * Does a Locus sync. It tries to get the latest delta DTO or if it can't, it falls back to getting the full Locus DTO.
90
+ *
91
+ * @param {Meeting} meeting
92
+ * @returns {undefined}
93
+ */
94
+ private doLocusSync(meeting: any) {
95
+ let isDelta;
96
+ let url;
97
+
98
+ if (this.locusParser.workingCopy.syncUrl) {
99
+ url = this.locusParser.workingCopy.syncUrl;
100
+ isDelta = true;
101
+ } else {
102
+ url = meeting.locusUrl;
103
+ isDelta = false;
104
+ }
105
+
106
+ LoggerProxy.logger.info(
107
+ `Locus-info:index#doLocusSync --> doing Locus sync (getting ${
108
+ isDelta ? 'delta' : 'full'
109
+ } DTO)`
110
+ );
111
+
112
+ // return value ignored on purpose
113
+ meeting.meetingRequest
114
+ .getLocusDTO({url})
115
+ .catch((e) => {
116
+ if (isDelta) {
117
+ LoggerProxy.logger.info(
118
+ 'Locus-info:index#doLocusSync --> delta sync failed, falling back to full sync'
119
+ );
120
+
121
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.LOCUS_DELTA_SYNC_FAILED, {
122
+ correlationId: meeting.correlationId,
123
+ url,
124
+ reason: e.message,
125
+ errorName: e.name,
126
+ stack: e.stack,
127
+ code: e.code,
128
+ });
129
+
130
+ isDelta = false;
131
+
132
+ return meeting.meetingRequest.getLocusDTO({url: meeting.locusUrl}).catch((err) => {
133
+ LoggerProxy.logger.info(
134
+ 'Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting'
135
+ );
136
+ this.webex.meetings.destroy(meeting, MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
137
+ throw err;
138
+ });
139
+ }
140
+ LoggerProxy.logger.info(
141
+ 'Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting'
142
+ );
143
+ this.webex.meetings.destroy(meeting, MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
144
+ throw e;
145
+ })
146
+ .then((res) => {
147
+ if (isDelta) {
148
+ if (!isEmpty(res.body)) {
149
+ meeting.locusInfo.handleLocusDelta(res.body, meeting);
150
+ } else {
151
+ LoggerProxy.logger.info(
152
+ 'Locus-info:index#doLocusSync --> received empty body from syncUrl, so we already have latest Locus DTO'
153
+ );
154
+ }
155
+ } else {
156
+ meeting.locusInfo.onFullLocus(res.body);
157
+ }
158
+ // Notify parser to resume processing delta events.
159
+ // Any deltas in the queue that have now been superseded by this sync will simply be ignored
160
+ this.locusParser.resume();
161
+ });
162
+ }
163
+
80
164
  /**
81
165
  * Apply locus delta data to meeting
82
166
  * @param {string} action Locus delta action
@@ -85,28 +169,19 @@ export default class LocusInfo extends EventsScope {
85
169
  * @returns {undefined}
86
170
  */
87
171
  applyLocusDeltaData(action: string, locus: any, meeting: any) {
88
- const {DESYNC, USE_CURRENT, USE_INCOMING} = LocusDeltaParser.loci;
172
+ const {DESYNC, USE_CURRENT, USE_INCOMING, WAIT, LOCUS_URL_CHANGED} = LocusDeltaParser.loci;
89
173
 
90
174
  switch (action) {
91
175
  case USE_INCOMING:
92
176
  meeting.locusInfo.onDeltaLocus(locus);
93
177
  break;
94
178
  case USE_CURRENT:
95
- meeting.locusDesync = false;
96
- meeting.needToGetFullLocus = false;
179
+ case WAIT:
180
+ // do nothing
97
181
  break;
98
182
  case DESYNC:
99
- meeting.meetingRequest
100
- .getFullLocus({
101
- desync: true,
102
- locusUrl: meeting.locusUrl,
103
- })
104
- .then((res) => {
105
- meeting.locusInfo.onFullLocus(res.body);
106
- // Notify parser to resume processing delta events
107
- // now that we have full locus from DESYNC.
108
- this.locusParser.resume();
109
- });
183
+ case LOCUS_URL_CHANGED:
184
+ this.doLocusSync(meeting);
110
185
  break;
111
186
  default:
112
187
  LoggerProxy.logger.info(
@@ -172,12 +247,13 @@ export default class LocusInfo extends EventsScope {
172
247
  */
173
248
  this.deltaParticipants = [];
174
249
 
250
+ this.updateLocusCache(locus);
175
251
  // above section only updates the locusInfo object
176
252
  // The below section makes sure it updates the locusInfo as well as updates the meeting object
177
253
  this.updateParticipants(locus.participants);
178
254
  // For 1:1 space meeting the conversation Url does not exist in locus.conversation
179
255
  this.updateConversationUrl(locus.conversationUrl, locus.info);
180
- this.updateControls(locus.controls);
256
+ this.updateControls(locus.controls, locus.self);
181
257
  this.updateLocusUrl(locus.url);
182
258
  this.updateFullState(locus.fullState);
183
259
  this.updateMeetingInfo(locus.info);
@@ -195,6 +271,7 @@ export default class LocusInfo extends EventsScope {
195
271
  * @memberof LocusInfo
196
272
  */
197
273
  initialSetup(locus: object) {
274
+ this.updateLocusCache(locus);
198
275
  this.onFullLocus(locus);
199
276
 
200
277
  // Change it to true after it receives it first locus object
@@ -210,7 +287,7 @@ export default class LocusInfo extends EventsScope {
210
287
  parse(meeting: any, data: any) {
211
288
  // eslint-disable-next-line @typescript-eslint/no-shadow
212
289
  const {eventType} = data;
213
-
290
+ const locus = this.getTheLocusToUpdate(data.locus);
214
291
  LoggerProxy.logger.info(`Locus-info:index#parse --> received locus data: ${eventType}`);
215
292
 
216
293
  switch (eventType) {
@@ -228,16 +305,16 @@ export default class LocusInfo extends EventsScope {
228
305
  case LOCUSEVENT.PARTICIPANT_DECLINED:
229
306
  case LOCUSEVENT.FLOOR_GRANTED:
230
307
  case LOCUSEVENT.FLOOR_RELEASED:
231
- this.onFullLocus(data.locus, eventType);
308
+ this.onFullLocus(locus, eventType);
232
309
  break;
233
310
  case LOCUSEVENT.DIFFERENCE:
234
- this.handleLocusDelta(data.locus, meeting);
311
+ this.handleLocusDelta(locus, meeting);
235
312
  break;
236
313
 
237
314
  default:
238
315
  // Why will there be a event with no eventType ????
239
316
  // we may not need this, we can get full locus
240
- this.handleLocusDelta(data.locus, meeting);
317
+ this.handleLocusDelta(locus, meeting);
241
318
  }
242
319
  }
243
320
 
@@ -259,18 +336,27 @@ export default class LocusInfo extends EventsScope {
259
336
  * @returns {object} null
260
337
  * @memberof LocusInfo
261
338
  */
262
- // eslint-disable-next-line @typescript-eslint/no-shadow
263
339
  onFullLocus(locus: any, eventType?: string) {
264
340
  if (!locus) {
265
341
  LoggerProxy.logger.error(
266
342
  'Locus-info:index#onFullLocus --> object passed as argument was invalid, continuing.'
267
343
  );
268
344
  }
345
+
346
+ if (!this.locusParser.isNewFullLocus(locus)) {
347
+ LoggerProxy.logger.info(
348
+ `Locus-info:index#onFullLocus --> ignoring old full locus DTO, eventType=${eventType}`
349
+ );
350
+
351
+ return;
352
+ }
353
+
269
354
  this.updateParticipantDeltas(locus.participants);
270
355
  this.scheduledMeeting = locus.meeting || null;
271
356
  this.participants = locus.participants;
357
+ const isReplaceMembers = ControlsUtils.isNeedReplaceMembers(this.controls, locus.controls);
272
358
  this.updateLocusInfo(locus);
273
- this.updateParticipants(locus.participants);
359
+ this.updateParticipants(locus.participants, isReplaceMembers);
274
360
  this.isMeetingActive();
275
361
  this.handleOneOnOneEvent(eventType);
276
362
  this.updateEmbeddedApps(locus.embeddedApps);
@@ -329,8 +415,9 @@ export default class LocusInfo extends EventsScope {
329
415
  * @memberof LocusInfo
330
416
  */
331
417
  onDeltaLocus(locus: any) {
418
+ const isReplaceMembers = ControlsUtils.isNeedReplaceMembers(this.controls, locus.controls);
332
419
  this.updateLocusInfo(locus);
333
- this.updateParticipants(locus.participants);
420
+ this.updateParticipants(locus.participants, isReplaceMembers);
334
421
  this.isMeetingActive();
335
422
  }
336
423
 
@@ -347,7 +434,7 @@ export default class LocusInfo extends EventsScope {
347
434
  return;
348
435
  }
349
436
 
350
- this.updateControls(locus.controls);
437
+ this.updateControls(locus.controls, locus.self);
351
438
  this.updateConversationUrl(locus.conversationUrl, locus.info);
352
439
  this.updateCreated(locus.created);
353
440
  this.updateFullState(locus.fullState);
@@ -418,10 +505,15 @@ export default class LocusInfo extends EventsScope {
418
505
  LoggerProxy.logger.warn(
419
506
  'Locus-info:index#isMeetingActive --> Call Ended, locus state is inactive.'
420
507
  );
421
- Metrics.postEvent({
422
- event: eventType.REMOTE_ENDED,
423
- meetingId: this.meetingId,
508
+
509
+ // @ts-ignore
510
+ this.webex.internal.newMetrics.submitClientEvent({
511
+ name: 'client.call.remote-ended',
512
+ options: {
513
+ meetingId: this.meetingId,
514
+ },
424
515
  });
516
+
425
517
  this.emitScoped(
426
518
  {
427
519
  file: 'locus-info',
@@ -440,9 +532,12 @@ export default class LocusInfo extends EventsScope {
440
532
  this.parsedLocus.self.state === MEETING_STATE.STATES.NOTIFIED ||
441
533
  this.parsedLocus.self.state === MEETING_STATE.STATES.JOINED)
442
534
  ) {
443
- Metrics.postEvent({
444
- event: eventType.REMOTE_ENDED,
445
- meetingId: this.meetingId,
535
+ // @ts-ignore
536
+ this.webex.internal.newMetrics.submitClientEvent({
537
+ name: 'client.call.remote-ended',
538
+ options: {
539
+ meetingId: this.meetingId,
540
+ },
446
541
  });
447
542
  this.emitScoped(
448
543
  {
@@ -464,10 +559,14 @@ export default class LocusInfo extends EventsScope {
464
559
  partner.state === MEETING_STATE.STATES.NOTIFIED ||
465
560
  partner.state === MEETING_STATE.STATES.IDLE) // Happens when user just joins and adds no Media
466
561
  ) {
467
- Metrics.postEvent({
468
- event: eventType.REMOTE_ENDED,
469
- meetingId: this.meetingId,
562
+ // @ts-ignore
563
+ this.webex.internal.newMetrics.submitClientEvent({
564
+ name: 'client.call.remote-ended',
565
+ options: {
566
+ meetingId: this.meetingId,
567
+ },
470
568
  });
569
+
471
570
  this.emitScoped(
472
571
  {
473
572
  file: 'locus-info',
@@ -490,9 +589,13 @@ export default class LocusInfo extends EventsScope {
490
589
  LoggerProxy.logger.warn(
491
590
  'Locus-info:index#isMeetingActive --> Meeting is ending due to inactive or terminating'
492
591
  );
493
- Metrics.postEvent({
494
- event: eventType.REMOTE_ENDED,
495
- meetingId: this.meetingId,
592
+
593
+ // @ts-ignore
594
+ this.webex.internal.newMetrics.submitClientEvent({
595
+ name: 'client.call.remote-ended',
596
+ options: {
597
+ meetingId: this.meetingId,
598
+ },
496
599
  });
497
600
  this.emitScoped(
498
601
  {
@@ -507,9 +610,13 @@ export default class LocusInfo extends EventsScope {
507
610
  );
508
611
  } else if (this.fullState && this.fullState.removed) {
509
612
  // user has been dropped from a meeting
510
- Metrics.postEvent({
511
- event: eventType.REMOTE_ENDED,
512
- meetingId: this.meetingId,
613
+
614
+ // @ts-ignore
615
+ this.webex.internal.newMetrics.submitClientEvent({
616
+ name: 'client.call.remote-ended',
617
+ options: {
618
+ meetingId: this.meetingId,
619
+ },
513
620
  });
514
621
  this.emitScoped(
515
622
  {
@@ -646,13 +753,13 @@ export default class LocusInfo extends EventsScope {
646
753
  }
647
754
 
648
755
  /**
649
- *
756
+ * update meeting's members
650
757
  * @param {Object} participants new participants object
651
- * @param {boolen} deltaParticpantFlag delta event
758
+ * @param {Boolean} isReplace is replace the whole members
652
759
  * @returns {Array} updatedParticipants
653
760
  * @memberof LocusInfo
654
761
  */
655
- updateParticipants(participants: object) {
762
+ updateParticipants(participants: object, isReplace?: boolean) {
656
763
  this.emitScoped(
657
764
  {
658
765
  file: 'locus-info',
@@ -665,16 +772,18 @@ export default class LocusInfo extends EventsScope {
665
772
  selfIdentity: this.parsedLocus.self && this.parsedLocus.self.selfIdentity,
666
773
  selfId: this.parsedLocus.self && this.parsedLocus.self.selfId,
667
774
  hostId: this.parsedLocus.host && this.parsedLocus.host.hostId,
775
+ isReplace,
668
776
  }
669
777
  );
670
778
  }
671
779
 
672
780
  /**
673
781
  * @param {Object} controls
782
+ * @param {Object} self
674
783
  * @returns {undefined}
675
784
  * @memberof LocusInfo
676
785
  */
677
- updateControls(controls: object) {
786
+ updateControls(controls: object, self: object) {
678
787
  if (controls && !isEqual(this.controls, controls)) {
679
788
  this.parsedLocus.controls = ControlsUtils.parse(controls);
680
789
  const {
@@ -685,10 +794,76 @@ export default class LocusInfo extends EventsScope {
685
794
  hasTranscribeChanged,
686
795
  hasEntryExitToneChanged,
687
796
  hasBreakoutChanged,
797
+ hasVideoEnabledChanged,
798
+ hasMuteOnEntryChanged,
799
+ hasShareControlChanged,
800
+ hasDisallowUnmuteChanged,
801
+ hasReactionsChanged,
802
+ hasReactionDisplayNamesChanged,
803
+ hasViewTheParticipantListChanged,
804
+ hasRaiseHandChanged,
805
+ hasVideoChanged,
806
+ hasInterpretationChanged,
688
807
  },
689
808
  current,
690
809
  } = ControlsUtils.getControls(this.controls, controls);
691
810
 
811
+ if (hasMuteOnEntryChanged) {
812
+ this.emitScoped(
813
+ {file: 'locus-info', function: 'updateControls'},
814
+ LOCUSINFO.EVENTS.CONTROLS_MUTE_ON_ENTRY_CHANGED,
815
+ {state: current.muteOnEntry}
816
+ );
817
+ }
818
+
819
+ if (hasShareControlChanged) {
820
+ this.emitScoped(
821
+ {file: 'locus-info', function: 'updateControls'},
822
+ LOCUSINFO.EVENTS.CONTROLS_SHARE_CONTROL_CHANGED,
823
+ {state: current.shareControl}
824
+ );
825
+ }
826
+
827
+ if (hasDisallowUnmuteChanged) {
828
+ this.emitScoped(
829
+ {file: 'locus-info', function: 'updateControls'},
830
+ LOCUSINFO.EVENTS.CONTROLS_DISALLOW_UNMUTE_CHANGED,
831
+ {state: current.disallowUnmute}
832
+ );
833
+ }
834
+
835
+ if (hasReactionsChanged || hasReactionDisplayNamesChanged) {
836
+ this.emitScoped(
837
+ {file: 'locus-info', function: 'updateControls'},
838
+ LOCUSINFO.EVENTS.CONTROLS_REACTIONS_CHANGED,
839
+ {state: current.reactions}
840
+ );
841
+ }
842
+
843
+ if (hasViewTheParticipantListChanged) {
844
+ this.emitScoped(
845
+ {file: 'locus-info', function: 'updateControls'},
846
+ LOCUSINFO.EVENTS.CONTROLS_VIEW_THE_PARTICIPANTS_LIST_CHANGED,
847
+ {state: current.viewTheParticipantList}
848
+ );
849
+ }
850
+
851
+ if (hasRaiseHandChanged) {
852
+ this.emitScoped(
853
+ {file: 'locus-info', function: 'updateControls'},
854
+ LOCUSINFO.EVENTS.CONTROLS_RAISE_HAND_CHANGED,
855
+ {state: current.raiseHand}
856
+ );
857
+ }
858
+
859
+ if (hasVideoChanged) {
860
+ this.emitScoped(
861
+ {file: 'locus-info', function: 'updateControls'},
862
+ LOCUSINFO.EVENTS.CONTROLS_VIDEO_CHANGED,
863
+ {state: current.video}
864
+ );
865
+ }
866
+
692
867
  if (hasRecordingChanged || hasRecordingPausedChanged) {
693
868
  let state = null;
694
869
 
@@ -750,7 +925,10 @@ export default class LocusInfo extends EventsScope {
750
925
 
751
926
  if (hasBreakoutChanged) {
752
927
  const {breakout} = current;
753
-
928
+ breakout.breakoutMoveId = SelfUtils.getReplacedBreakoutMoveId(
929
+ self,
930
+ this.webex.internal.device.url
931
+ );
754
932
  this.emitScoped(
755
933
  {
756
934
  file: 'locus-info',
@@ -763,9 +941,25 @@ export default class LocusInfo extends EventsScope {
763
941
  );
764
942
  }
765
943
 
944
+ if (hasInterpretationChanged) {
945
+ const {interpretation} = current;
946
+ this.emitScoped(
947
+ {
948
+ file: 'locus-info',
949
+ function: 'updateControls',
950
+ },
951
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_INTERPRETATION_UPDATED,
952
+ {
953
+ interpretation,
954
+ }
955
+ );
956
+ }
957
+
766
958
  if (hasEntryExitToneChanged) {
767
959
  const {entryExitTone} = current;
768
960
 
961
+ this.updateMeeting({entryExitTone});
962
+
769
963
  this.emitScoped(
770
964
  {
771
965
  file: 'locus-info',
@@ -776,8 +970,26 @@ export default class LocusInfo extends EventsScope {
776
970
  entryExitTone,
777
971
  }
778
972
  );
973
+ }
779
974
 
780
- this.updateMeeting({entryExitTone});
975
+ // videoEnabled is handled differently than other controls,
976
+ // to fit with audio mute status logic
977
+ if (hasVideoEnabledChanged) {
978
+ const {videoEnabled} = current;
979
+
980
+ this.updateMeeting({unmuteVideoAllowed: videoEnabled});
981
+
982
+ this.emitScoped(
983
+ {
984
+ file: 'locus-info',
985
+ function: 'updateControls',
986
+ },
987
+ LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED,
988
+ {
989
+ // muted: not part of locus.controls
990
+ unmuteAllowed: videoEnabled,
991
+ }
992
+ );
781
993
  }
782
994
 
783
995
  this.controls = controls;
@@ -918,20 +1130,14 @@ export default class LocusInfo extends EventsScope {
918
1130
  * @memberof LocusInfo
919
1131
  */
920
1132
  updateMeetingInfo(info: object, self?: object) {
921
- if (info && !isEqual(this.info, info)) {
922
- const roles = self ? SelfUtils.getRoles(self) : this.parsedLocus.self?.roles || [];
1133
+ const roles = self ? SelfUtils.getRoles(self) : this.parsedLocus.self?.roles || [];
1134
+ if (
1135
+ (info && !isEqual(this.info, info)) ||
1136
+ (roles.length && !isEqual(this.roles, roles) && info)
1137
+ ) {
923
1138
  const isJoined = SelfUtils.isJoined(self || this.parsedLocus.self);
924
1139
  const parsedInfo = InfoUtils.getInfos(this.parsedLocus.info, info, roles, isJoined);
925
1140
 
926
- this.emitScoped(
927
- {
928
- file: 'locus-info',
929
- function: 'updateMeetingInfo',
930
- },
931
- LOCUSINFO.EVENTS.MEETING_INFO_UPDATED,
932
- {info: parsedInfo.current, self}
933
- );
934
-
935
1141
  if (parsedInfo.updates.isLocked) {
936
1142
  this.emitScoped(
937
1143
  {
@@ -957,7 +1163,19 @@ export default class LocusInfo extends EventsScope {
957
1163
  this.parsedLocus.info = parsedInfo.current;
958
1164
  // Parses the info and adds necessary values
959
1165
  this.updateMeeting(parsedInfo.current);
1166
+
1167
+ this.emitScoped(
1168
+ {
1169
+ file: 'locus-info',
1170
+ function: 'updateMeetingInfo',
1171
+ },
1172
+ LOCUSINFO.EVENTS.MEETING_INFO_UPDATED,
1173
+ {
1174
+ isInitializing: !self, // if self is undefined, then the update is caused by locus init
1175
+ }
1176
+ );
960
1177
  }
1178
+ this.roles = roles;
961
1179
  }
962
1180
 
963
1181
  /**
@@ -1099,6 +1317,20 @@ export default class LocusInfo extends EventsScope {
1099
1317
  );
1100
1318
  }
1101
1319
 
1320
+ if (parsedSelves.updates.interpretationChanged) {
1321
+ this.emitScoped(
1322
+ {
1323
+ file: 'locus-info',
1324
+ function: 'updateSelf',
1325
+ },
1326
+ LOCUSINFO.EVENTS.SELF_MEETING_INTERPRETATION_CHANGED,
1327
+ {
1328
+ interpretation: parsedSelves.current.interpretation,
1329
+ selfParticipantId: parsedSelves.current.selfId,
1330
+ }
1331
+ );
1332
+ }
1333
+
1102
1334
  if (parsedSelves.updates.isMediaInactiveOrReleased) {
1103
1335
  this.emitScoped(
1104
1336
  {
@@ -1120,6 +1352,31 @@ export default class LocusInfo extends EventsScope {
1120
1352
  self
1121
1353
  );
1122
1354
  }
1355
+
1356
+ if (parsedSelves.updates.isRolesChanged) {
1357
+ this.emitScoped(
1358
+ {
1359
+ file: 'locus-info',
1360
+ function: 'updateSelf',
1361
+ },
1362
+ LOCUSINFO.EVENTS.SELF_ROLES_CHANGED,
1363
+ {oldRoles: parsedSelves.previous?.roles, newRoles: parsedSelves.current?.roles}
1364
+ );
1365
+ }
1366
+
1367
+ if (parsedSelves.updates.isVideoMutedByOthersChanged) {
1368
+ this.emitScoped(
1369
+ {
1370
+ file: 'locus-info',
1371
+ function: 'updateSelf',
1372
+ },
1373
+ LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED,
1374
+ {
1375
+ muted: parsedSelves.current.remoteVideoMuted,
1376
+ // unmuteAllowed: not part of .self
1377
+ }
1378
+ );
1379
+ }
1123
1380
  if (parsedSelves.updates.localAudioUnmuteRequiredByServer) {
1124
1381
  this.emitScoped(
1125
1382
  {
@@ -1334,4 +1591,105 @@ export default class LocusInfo extends EventsScope {
1334
1591
  this.identities = identities;
1335
1592
  }
1336
1593
  }
1594
+
1595
+ /**
1596
+ * check the locus is main session's one or not, if is main session's, update main session cache
1597
+ * @param {Object} locus
1598
+ * @returns {undefined}
1599
+ * @memberof LocusInfo
1600
+ */
1601
+ updateLocusCache(locus: any) {
1602
+ const isMainSessionDTO = ControlsUtils.isMainSessionDTO(locus);
1603
+ if (isMainSessionDTO) {
1604
+ this.updateMainSessionLocusCache(locus);
1605
+ }
1606
+ }
1607
+
1608
+ /**
1609
+ * if return from breakout to main session, need to use cached main session DTO since locus won't send the full locus (participants)
1610
+ * if join breakout from main session, main session is not active for the attendee and remove main session locus cache
1611
+ * @param {Object} newLocus
1612
+ * @returns {Object}
1613
+ * @memberof LocusInfo
1614
+ */
1615
+ getTheLocusToUpdate(newLocus: any) {
1616
+ const switchStatus = ControlsUtils.getSessionSwitchStatus(this.controls, newLocus?.controls);
1617
+ if (switchStatus.isReturnToMain && this.mainSessionLocusCache) {
1618
+ return cloneDeep(this.mainSessionLocusCache);
1619
+ }
1620
+ const isMainSessionDTO =
1621
+ this.mainSessionLocusCache && ControlsUtils.isMainSessionDTO(this.mainSessionLocusCache);
1622
+
1623
+ if (isMainSessionDTO) {
1624
+ const isActive =
1625
+ [LOCUS.STATE.ACTIVE, LOCUS.STATE.INITIALIZING, LOCUS.STATE.TERMINATING].includes(
1626
+ this.fullState?.state
1627
+ ) && !this.mainSessionLocusCache?.self?.removed;
1628
+
1629
+ if (!isActive) {
1630
+ this.clearMainSessionLocusCache();
1631
+ }
1632
+ }
1633
+
1634
+ return newLocus;
1635
+ }
1636
+
1637
+ /**
1638
+ * merge participants by participant id
1639
+ * @param {Array} participants
1640
+ * @param {Array} sourceParticipants
1641
+ * @returns {Array} merged participants
1642
+ * @memberof LocusInfo
1643
+ */
1644
+ // eslint-disable-next-line class-methods-use-this
1645
+ mergeParticipants(participants, sourceParticipants) {
1646
+ if (!sourceParticipants || !sourceParticipants.length) return participants;
1647
+ if (!participants || !participants.length) {
1648
+ return sourceParticipants;
1649
+ }
1650
+ sourceParticipants.forEach((participant) => {
1651
+ const existIndex = participants.findIndex((p) => p.id === participant.id);
1652
+ if (existIndex > -1) {
1653
+ participants.splice(existIndex, 1, participant);
1654
+ } else {
1655
+ participants.push(participant);
1656
+ }
1657
+ });
1658
+
1659
+ return participants;
1660
+ }
1661
+
1662
+ /**
1663
+ * need cache main sessions' participants since locus will not send the full list when cohost/host leave breakout
1664
+ * @param {Object} mainLocus
1665
+ * @returns {undefined}
1666
+ * @memberof LocusInfo
1667
+ */
1668
+ updateMainSessionLocusCache(mainLocus: any) {
1669
+ if (!mainLocus) {
1670
+ return;
1671
+ }
1672
+ const locusClone = cloneDeep(mainLocus);
1673
+ if (this.mainSessionLocusCache) {
1674
+ // shallow merge and do special merge for participants
1675
+ assignWith(this.mainSessionLocusCache, locusClone, (objValue, srcValue, key) => {
1676
+ if (key === 'participants') {
1677
+ return this.mergeParticipants(objValue, srcValue);
1678
+ }
1679
+
1680
+ return srcValue || objValue;
1681
+ });
1682
+ } else {
1683
+ this.mainSessionLocusCache = locusClone;
1684
+ }
1685
+ }
1686
+
1687
+ /**
1688
+ * clear main session cache
1689
+ * @returns {undefined}
1690
+ * @memberof LocusInfo
1691
+ */
1692
+ clearMainSessionLocusCache() {
1693
+ this.mainSessionLocusCache = null;
1694
+ }
1337
1695
  }