@webex/plugin-meetings 3.0.0-beta.17 → 3.0.0-beta.171

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 (427) hide show
  1. package/README.md +45 -7
  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 +359 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +216 -0
  9. package/dist/breakouts/breakout.js.map +1 -0
  10. package/dist/breakouts/collection.js +23 -0
  11. package/dist/breakouts/collection.js.map +1 -0
  12. package/dist/breakouts/edit-lock-error.js +52 -0
  13. package/dist/breakouts/edit-lock-error.js.map +1 -0
  14. package/dist/breakouts/events.js +45 -0
  15. package/dist/breakouts/events.js.map +1 -0
  16. package/dist/breakouts/index.js +1048 -0
  17. package/dist/breakouts/index.js.map +1 -0
  18. package/dist/breakouts/request.js +78 -0
  19. package/dist/breakouts/request.js.map +1 -0
  20. package/dist/breakouts/utils.js +67 -0
  21. package/dist/breakouts/utils.js.map +1 -0
  22. package/dist/common/errors/webex-errors.js +3 -2
  23. package/dist/common/errors/webex-errors.js.map +1 -1
  24. package/dist/common/logs/logger-proxy.js +1 -1
  25. package/dist/common/logs/logger-proxy.js.map +1 -1
  26. package/dist/config.js +6 -8
  27. package/dist/config.js.map +1 -1
  28. package/dist/constants.js +194 -28
  29. package/dist/constants.js.map +1 -1
  30. package/dist/controls-options-manager/constants.js +14 -0
  31. package/dist/controls-options-manager/constants.js.map +1 -0
  32. package/dist/controls-options-manager/enums.js +27 -0
  33. package/dist/controls-options-manager/enums.js.map +1 -0
  34. package/dist/controls-options-manager/index.js +297 -0
  35. package/dist/controls-options-manager/index.js.map +1 -0
  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 +300 -0
  39. package/dist/controls-options-manager/util.js.map +1 -0
  40. package/dist/index.js +107 -0
  41. package/dist/index.js.map +1 -1
  42. package/dist/interpretation/collection.js +23 -0
  43. package/dist/interpretation/collection.js.map +1 -0
  44. package/dist/interpretation/index.js +214 -0
  45. package/dist/interpretation/index.js.map +1 -0
  46. package/dist/interpretation/siLanguage.js +25 -0
  47. package/dist/interpretation/siLanguage.js.map +1 -0
  48. package/dist/locus-info/controlsUtils.js +92 -2
  49. package/dist/locus-info/controlsUtils.js.map +1 -1
  50. package/dist/locus-info/index.js +350 -41
  51. package/dist/locus-info/index.js.map +1 -1
  52. package/dist/locus-info/mediaSharesUtils.js +43 -1
  53. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  54. package/dist/locus-info/parser.js +2 -1
  55. package/dist/locus-info/parser.js.map +1 -1
  56. package/dist/locus-info/selfUtils.js +97 -14
  57. package/dist/locus-info/selfUtils.js.map +1 -1
  58. package/dist/media/index.js +41 -136
  59. package/dist/media/index.js.map +1 -1
  60. package/dist/media/properties.js +33 -94
  61. package/dist/media/properties.js.map +1 -1
  62. package/dist/mediaQualityMetrics/config.js +505 -493
  63. package/dist/mediaQualityMetrics/config.js.map +1 -1
  64. package/dist/meeting/in-meeting-actions.js +76 -2
  65. package/dist/meeting/in-meeting-actions.js.map +1 -1
  66. package/dist/meeting/index.js +2757 -2439
  67. package/dist/meeting/index.js.map +1 -1
  68. package/dist/meeting/locusMediaRequest.js +291 -0
  69. package/dist/meeting/locusMediaRequest.js.map +1 -0
  70. package/dist/meeting/muteState.js +229 -124
  71. package/dist/meeting/muteState.js.map +1 -1
  72. package/dist/meeting/request.js +191 -167
  73. package/dist/meeting/request.js.map +1 -1
  74. package/dist/meeting/request.type.js.map +1 -1
  75. package/dist/meeting/util.js +477 -466
  76. package/dist/meeting/util.js.map +1 -1
  77. package/dist/meeting-info/index.js +48 -7
  78. package/dist/meeting-info/index.js.map +1 -1
  79. package/dist/meeting-info/meeting-info-v2.js +172 -50
  80. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  81. package/dist/meeting-info/utilv2.js +20 -5
  82. package/dist/meeting-info/utilv2.js.map +1 -1
  83. package/dist/meetings/collection.js +22 -0
  84. package/dist/meetings/collection.js.map +1 -1
  85. package/dist/meetings/index.js +377 -82
  86. package/dist/meetings/index.js.map +1 -1
  87. package/dist/meetings/meetings.types.js +7 -0
  88. package/dist/meetings/meetings.types.js.map +1 -0
  89. package/dist/meetings/request.js +16 -12
  90. package/dist/meetings/request.js.map +1 -1
  91. package/dist/meetings/util.js +88 -1
  92. package/dist/meetings/util.js.map +1 -1
  93. package/dist/member/index.js +43 -0
  94. package/dist/member/index.js.map +1 -1
  95. package/dist/member/types.js +15 -0
  96. package/dist/member/types.js.map +1 -0
  97. package/dist/member/util.js +97 -3
  98. package/dist/member/util.js.map +1 -1
  99. package/dist/members/collection.js +10 -0
  100. package/dist/members/collection.js.map +1 -1
  101. package/dist/members/index.js +94 -11
  102. package/dist/members/index.js.map +1 -1
  103. package/dist/members/request.js +109 -39
  104. package/dist/members/request.js.map +1 -1
  105. package/dist/members/types.js +15 -0
  106. package/dist/members/types.js.map +1 -0
  107. package/dist/members/util.js +316 -233
  108. package/dist/members/util.js.map +1 -1
  109. package/dist/metrics/constants.js +3 -5
  110. package/dist/metrics/constants.js.map +1 -1
  111. package/dist/metrics/index.js +1 -468
  112. package/dist/metrics/index.js.map +1 -1
  113. package/dist/multistream/mediaRequestManager.js +265 -36
  114. package/dist/multistream/mediaRequestManager.js.map +1 -1
  115. package/dist/multistream/receiveSlot.js +52 -19
  116. package/dist/multistream/receiveSlot.js.map +1 -1
  117. package/dist/multistream/receiveSlotManager.js +53 -33
  118. package/dist/multistream/receiveSlotManager.js.map +1 -1
  119. package/dist/multistream/remoteMedia.js +44 -18
  120. package/dist/multistream/remoteMedia.js.map +1 -1
  121. package/dist/multistream/remoteMediaGroup.js +60 -3
  122. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  123. package/dist/multistream/remoteMediaManager.js +322 -103
  124. package/dist/multistream/remoteMediaManager.js.map +1 -1
  125. package/dist/networkQualityMonitor/index.js +4 -2
  126. package/dist/networkQualityMonitor/index.js.map +1 -1
  127. package/dist/reachability/index.js +117 -60
  128. package/dist/reachability/index.js.map +1 -1
  129. package/dist/reachability/request.js +12 -5
  130. package/dist/reachability/request.js.map +1 -1
  131. package/dist/reactions/constants.js +13 -0
  132. package/dist/reactions/constants.js.map +1 -0
  133. package/dist/reactions/reactions.js +2 -2
  134. package/dist/reactions/reactions.js.map +1 -1
  135. package/dist/reactions/reactions.type.js +18 -18
  136. package/dist/reactions/reactions.type.js.map +1 -1
  137. package/dist/reconnection-manager/index.js +216 -162
  138. package/dist/reconnection-manager/index.js.map +1 -1
  139. package/dist/recording-controller/enums.js +17 -0
  140. package/dist/recording-controller/enums.js.map +1 -0
  141. package/dist/recording-controller/index.js +363 -0
  142. package/dist/recording-controller/index.js.map +1 -0
  143. package/dist/recording-controller/util.js +64 -0
  144. package/dist/recording-controller/util.js.map +1 -0
  145. package/dist/roap/index.js +21 -29
  146. package/dist/roap/index.js.map +1 -1
  147. package/dist/roap/request.js +135 -94
  148. package/dist/roap/request.js.map +1 -1
  149. package/dist/roap/turnDiscovery.js +135 -53
  150. package/dist/roap/turnDiscovery.js.map +1 -1
  151. package/dist/statsAnalyzer/global.js +1 -93
  152. package/dist/statsAnalyzer/global.js.map +1 -1
  153. package/dist/statsAnalyzer/index.js +329 -314
  154. package/dist/statsAnalyzer/index.js.map +1 -1
  155. package/dist/statsAnalyzer/mqaUtil.js +103 -54
  156. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  157. package/dist/types/annotation/annotation.types.d.ts +43 -0
  158. package/dist/types/annotation/constants.d.ts +31 -0
  159. package/dist/types/annotation/index.d.ts +124 -0
  160. package/dist/types/breakouts/breakout.d.ts +8 -0
  161. package/dist/types/breakouts/collection.d.ts +5 -0
  162. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  163. package/dist/types/breakouts/events.d.ts +8 -0
  164. package/dist/types/breakouts/index.d.ts +5 -0
  165. package/dist/types/breakouts/request.d.ts +22 -0
  166. package/dist/types/breakouts/utils.d.ts +15 -0
  167. package/dist/types/common/browser-detection.d.ts +9 -0
  168. package/dist/types/common/collection.d.ts +48 -0
  169. package/dist/types/common/config.d.ts +2 -0
  170. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  171. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  172. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  173. package/dist/types/common/errors/media.d.ts +15 -0
  174. package/dist/types/common/errors/parameter.d.ts +15 -0
  175. package/dist/types/common/errors/password-error.d.ts +15 -0
  176. package/dist/types/common/errors/permission.d.ts +14 -0
  177. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  178. package/dist/types/common/errors/reconnection.d.ts +15 -0
  179. package/dist/types/common/errors/stats.d.ts +15 -0
  180. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  181. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  182. package/dist/types/common/events/events-scope.d.ts +17 -0
  183. package/dist/types/common/events/events.d.ts +12 -0
  184. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  185. package/dist/types/common/events/util.d.ts +2 -0
  186. package/dist/types/common/logs/logger-config.d.ts +2 -0
  187. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  188. package/dist/types/common/logs/request.d.ts +34 -0
  189. package/dist/types/common/queue.d.ts +32 -0
  190. package/dist/types/config.d.ts +72 -0
  191. package/dist/types/constants.d.ts +1007 -0
  192. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  193. package/dist/types/controls-options-manager/enums.d.ts +15 -0
  194. package/dist/types/controls-options-manager/index.d.ts +136 -0
  195. package/dist/types/controls-options-manager/types.d.ts +43 -0
  196. package/dist/types/controls-options-manager/util.d.ts +1 -0
  197. package/dist/types/index.d.ts +7 -0
  198. package/dist/types/interpretation/collection.d.ts +5 -0
  199. package/dist/types/interpretation/index.d.ts +5 -0
  200. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  201. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  202. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  203. package/dist/types/locus-info/fullState.d.ts +2 -0
  204. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  205. package/dist/types/locus-info/index.d.ts +315 -0
  206. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  207. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  208. package/dist/types/locus-info/parser.d.ts +212 -0
  209. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  210. package/dist/types/media/index.d.ts +34 -0
  211. package/dist/types/media/properties.d.ts +93 -0
  212. package/dist/types/media/util.d.ts +2 -0
  213. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  214. package/dist/types/meeting/in-meeting-actions.d.ts +149 -0
  215. package/dist/types/meeting/index.d.ts +1462 -0
  216. package/dist/types/meeting/locusMediaRequest.d.ts +70 -0
  217. package/dist/types/meeting/muteState.d.ts +184 -0
  218. package/dist/types/meeting/request.d.ts +270 -0
  219. package/dist/types/meeting/request.type.d.ts +11 -0
  220. package/dist/types/meeting/state.d.ts +9 -0
  221. package/dist/types/meeting/util.d.ts +77 -0
  222. package/dist/types/meeting-info/collection.d.ts +20 -0
  223. package/dist/types/meeting-info/index.d.ts +62 -0
  224. package/dist/types/meeting-info/meeting-info-v2.d.ts +122 -0
  225. package/dist/types/meeting-info/request.d.ts +22 -0
  226. package/dist/types/meeting-info/util.d.ts +2 -0
  227. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  228. package/dist/types/meetings/collection.d.ts +31 -0
  229. package/dist/types/meetings/index.d.ts +365 -0
  230. package/dist/types/meetings/meetings.types.d.ts +4 -0
  231. package/dist/types/meetings/request.d.ts +27 -0
  232. package/dist/types/meetings/util.d.ts +18 -0
  233. package/dist/types/member/index.d.ts +158 -0
  234. package/dist/types/member/types.d.ts +21 -0
  235. package/dist/types/member/util.d.ts +2 -0
  236. package/dist/types/members/collection.d.ts +29 -0
  237. package/dist/types/members/index.d.ts +353 -0
  238. package/dist/types/members/request.d.ts +114 -0
  239. package/dist/types/members/types.d.ts +24 -0
  240. package/dist/types/members/util.d.ts +210 -0
  241. package/dist/types/metrics/constants.d.ts +55 -0
  242. package/dist/types/metrics/index.d.ts +45 -0
  243. package/dist/types/multistream/mediaRequestManager.d.ts +118 -0
  244. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  245. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  246. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  247. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  248. package/dist/types/multistream/remoteMediaManager.d.ts +277 -0
  249. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  250. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  251. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  252. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  253. package/dist/types/reachability/index.d.ts +152 -0
  254. package/dist/types/reachability/request.d.ts +37 -0
  255. package/dist/types/reactions/constants.d.ts +3 -0
  256. package/dist/types/reactions/reactions.d.ts +4 -0
  257. package/dist/types/reactions/reactions.type.d.ts +52 -0
  258. package/dist/types/reconnection-manager/index.d.ts +126 -0
  259. package/dist/types/recording-controller/enums.d.ts +7 -0
  260. package/dist/types/recording-controller/index.d.ts +208 -0
  261. package/dist/types/recording-controller/util.d.ts +14 -0
  262. package/dist/types/roap/index.d.ts +77 -0
  263. package/dist/types/roap/request.d.ts +36 -0
  264. package/dist/types/roap/turnDiscovery.d.ts +91 -0
  265. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  266. package/dist/types/statsAnalyzer/index.d.ts +200 -0
  267. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  268. package/dist/types/transcription/index.d.ts +64 -0
  269. package/package.json +29 -21
  270. package/src/annotation/annotation.types.ts +52 -0
  271. package/src/annotation/constants.ts +36 -0
  272. package/src/annotation/index.ts +343 -0
  273. package/src/breakouts/README.md +220 -0
  274. package/src/breakouts/breakout.ts +188 -0
  275. package/src/breakouts/collection.ts +19 -0
  276. package/src/breakouts/edit-lock-error.ts +25 -0
  277. package/src/breakouts/events.ts +56 -0
  278. package/src/breakouts/index.ts +925 -0
  279. package/src/breakouts/request.ts +55 -0
  280. package/src/breakouts/utils.ts +57 -0
  281. package/src/common/errors/webex-errors.ts +6 -2
  282. package/src/common/logs/logger-proxy.ts +1 -1
  283. package/src/config.ts +5 -7
  284. package/src/constants.ts +183 -22
  285. package/src/controls-options-manager/constants.ts +5 -0
  286. package/src/controls-options-manager/enums.ts +18 -0
  287. package/src/controls-options-manager/index.ts +278 -0
  288. package/src/controls-options-manager/types.ts +59 -0
  289. package/src/controls-options-manager/util.ts +286 -0
  290. package/src/index.ts +39 -0
  291. package/src/interpretation/README.md +51 -0
  292. package/src/interpretation/collection.ts +19 -0
  293. package/src/interpretation/index.ts +182 -0
  294. package/src/interpretation/siLanguage.ts +18 -0
  295. package/src/locus-info/controlsUtils.ts +110 -0
  296. package/src/locus-info/index.ts +374 -38
  297. package/src/locus-info/mediaSharesUtils.ts +48 -0
  298. package/src/locus-info/parser.ts +2 -1
  299. package/src/locus-info/selfUtils.ts +86 -2
  300. package/src/media/index.ts +78 -144
  301. package/src/media/properties.ts +55 -99
  302. package/src/mediaQualityMetrics/config.ts +379 -377
  303. package/src/meeting/in-meeting-actions.ts +151 -3
  304. package/src/meeting/index.ts +2181 -2052
  305. package/src/meeting/locusMediaRequest.ts +309 -0
  306. package/src/meeting/muteState.ts +228 -132
  307. package/src/meeting/request.ts +100 -91
  308. package/src/meeting/request.type.ts +2 -0
  309. package/src/meeting/util.ts +450 -439
  310. package/src/meeting-info/index.ts +54 -8
  311. package/src/meeting-info/meeting-info-v2.ts +150 -14
  312. package/src/meeting-info/utilv2.ts +13 -3
  313. package/src/meetings/collection.ts +20 -0
  314. package/src/meetings/index.ts +396 -89
  315. package/src/meetings/meetings.types.ts +12 -0
  316. package/src/meetings/request.ts +3 -1
  317. package/src/meetings/util.ts +103 -4
  318. package/src/member/index.ts +42 -0
  319. package/src/member/types.ts +24 -0
  320. package/src/member/util.ts +95 -1
  321. package/src/members/collection.ts +8 -0
  322. package/src/members/index.ts +108 -6
  323. package/src/members/request.ts +98 -17
  324. package/src/members/types.ts +28 -0
  325. package/src/members/util.ts +319 -240
  326. package/src/metrics/constants.ts +2 -4
  327. package/src/metrics/index.ts +1 -490
  328. package/src/multistream/mediaRequestManager.ts +337 -63
  329. package/src/multistream/receiveSlot.ts +68 -26
  330. package/src/multistream/receiveSlotManager.ts +61 -38
  331. package/src/multistream/remoteMedia.ts +29 -3
  332. package/src/multistream/remoteMediaGroup.ts +61 -2
  333. package/src/multistream/remoteMediaManager.ts +260 -66
  334. package/src/networkQualityMonitor/index.ts +6 -6
  335. package/src/reachability/index.ts +75 -25
  336. package/src/reachability/request.ts +10 -5
  337. package/src/reactions/constants.ts +4 -0
  338. package/src/reactions/reactions.ts +4 -4
  339. package/src/reactions/reactions.type.ts +28 -3
  340. package/src/reconnection-manager/index.ts +83 -49
  341. package/src/recording-controller/enums.ts +8 -0
  342. package/src/recording-controller/index.ts +333 -0
  343. package/src/recording-controller/util.ts +75 -0
  344. package/src/roap/index.ts +21 -30
  345. package/src/roap/request.ts +72 -61
  346. package/src/roap/turnDiscovery.ts +51 -27
  347. package/src/statsAnalyzer/global.ts +1 -94
  348. package/src/statsAnalyzer/index.ts +380 -390
  349. package/src/statsAnalyzer/mqaUtil.ts +106 -99
  350. package/test/integration/spec/converged-space-meetings.js +233 -0
  351. package/test/integration/spec/journey.js +336 -259
  352. package/test/integration/spec/space-meeting.js +77 -4
  353. package/test/unit/spec/annotation/index.ts +436 -0
  354. package/test/unit/spec/breakouts/breakout.ts +237 -0
  355. package/test/unit/spec/breakouts/collection.ts +15 -0
  356. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  357. package/test/unit/spec/breakouts/events.ts +89 -0
  358. package/test/unit/spec/breakouts/index.ts +1790 -0
  359. package/test/unit/spec/breakouts/request.ts +104 -0
  360. package/test/unit/spec/breakouts/utils.js +72 -0
  361. package/test/unit/spec/controls-options-manager/index.js +287 -0
  362. package/test/unit/spec/controls-options-manager/util.js +518 -0
  363. package/test/unit/spec/fixture/locus.js +1 -0
  364. package/test/unit/spec/interpretation/collection.ts +15 -0
  365. package/test/unit/spec/interpretation/index.ts +329 -0
  366. package/test/unit/spec/interpretation/siLanguage.ts +26 -0
  367. package/test/unit/spec/locus-info/controlsUtils.js +323 -30
  368. package/test/unit/spec/locus-info/index.js +792 -4
  369. package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
  370. package/test/unit/spec/locus-info/selfConstant.js +48 -0
  371. package/test/unit/spec/locus-info/selfUtils.js +275 -0
  372. package/test/unit/spec/media/index.ts +130 -24
  373. package/test/unit/spec/media/properties.ts +9 -9
  374. package/test/unit/spec/meeting/in-meeting-actions.ts +75 -3
  375. package/test/unit/spec/meeting/index.js +2834 -1442
  376. package/test/unit/spec/meeting/locusMediaRequest.ts +436 -0
  377. package/test/unit/spec/meeting/muteState.js +370 -208
  378. package/test/unit/spec/meeting/request.js +354 -42
  379. package/test/unit/spec/meeting/utils.js +384 -170
  380. package/test/unit/spec/meeting-info/index.js +181 -0
  381. package/test/unit/spec/meeting-info/meetinginfov2.js +383 -5
  382. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  383. package/test/unit/spec/meetings/collection.js +14 -0
  384. package/test/unit/spec/meetings/index.js +847 -121
  385. package/test/unit/spec/meetings/utils.js +206 -2
  386. package/test/unit/spec/member/index.js +31 -0
  387. package/test/unit/spec/member/util.js +408 -32
  388. package/test/unit/spec/members/index.js +320 -1
  389. package/test/unit/spec/members/request.js +206 -27
  390. package/test/unit/spec/members/utils.js +184 -0
  391. package/test/unit/spec/metrics/index.js +1 -50
  392. package/test/unit/spec/multistream/mediaRequestManager.ts +1012 -109
  393. package/test/unit/spec/multistream/receiveSlot.ts +77 -18
  394. package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
  395. package/test/unit/spec/multistream/remoteMedia.ts +32 -2
  396. package/test/unit/spec/multistream/remoteMediaGroup.ts +271 -5
  397. package/test/unit/spec/multistream/remoteMediaManager.ts +672 -65
  398. package/test/unit/spec/networkQualityMonitor/index.js +4 -4
  399. package/test/unit/spec/reachability/index.ts +176 -25
  400. package/test/unit/spec/reachability/request.js +66 -0
  401. package/test/unit/spec/reconnection-manager/index.js +95 -13
  402. package/test/unit/spec/recording-controller/index.js +307 -0
  403. package/test/unit/spec/recording-controller/util.js +229 -0
  404. package/test/unit/spec/roap/index.ts +28 -52
  405. package/test/unit/spec/roap/request.ts +225 -0
  406. package/test/unit/spec/roap/turnDiscovery.ts +73 -34
  407. package/test/unit/spec/stats-analyzer/index.js +94 -43
  408. package/test/utils/constants.js +9 -0
  409. package/test/utils/integrationTestUtils.js +46 -0
  410. package/test/utils/testUtils.js +0 -45
  411. package/test/utils/webex-config.js +4 -0
  412. package/test/utils/webex-test-users.js +7 -3
  413. package/tsconfig.json +6 -0
  414. package/dist/media/internal-media-core-wrapper.js +0 -18
  415. package/dist/media/internal-media-core-wrapper.js.map +0 -1
  416. package/dist/meeting/effectsState.js +0 -262
  417. package/dist/meeting/effectsState.js.map +0 -1
  418. package/dist/metrics/config.js +0 -299
  419. package/dist/metrics/config.js.map +0 -1
  420. package/dist/multistream/multistreamMedia.js +0 -106
  421. package/dist/multistream/multistreamMedia.js.map +0 -1
  422. package/src/index.js +0 -15
  423. package/src/media/internal-media-core-wrapper.ts +0 -9
  424. package/src/meeting/effectsState.ts +0 -211
  425. package/src/metrics/config.ts +0 -495
  426. package/src/multistream/multistreamMedia.ts +0 -93
  427. package/test/unit/spec/meeting/effectsState.js +0 -281
@@ -2,14 +2,16 @@
2
2
 
3
3
  import '@webex/internal-plugin-mercury';
4
4
  import '@webex/internal-plugin-conversation';
5
+ import '@webex/internal-plugin-metrics';
5
6
  // @ts-ignore
6
7
  import {WebexPlugin} from '@webex/webex-core';
7
- import {MediaConnection as MC} from '@webex/internal-media-core';
8
+ import {setLogger} from '@webex/internal-media-core';
9
+
10
+ import * as mediaHelpersModule from '@webex/media-helpers';
8
11
 
9
12
  import 'webrtc-adapter';
10
13
 
11
14
  import Metrics from '../metrics';
12
- import {trigger, eventType} from '../metrics/config';
13
15
  import LoggerConfig from '../common/logs/logger-config';
14
16
  import StaticConfig from '../common/config';
15
17
  import LoggerProxy from '../common/logs/logger-proxy';
@@ -40,6 +42,9 @@ import {
40
42
  MEETING_REMOVED_REASON,
41
43
  _CONVERSATION_URL_,
42
44
  CONVERSATION_URL,
45
+ MEETINGNUMBER,
46
+ _JOINED_,
47
+ _MOVED_,
43
48
  } from '../constants';
44
49
  import BEHAVIORAL_METRICS from '../metrics/constants';
45
50
  import MeetingInfo from '../meeting-info';
@@ -53,6 +58,8 @@ import CaptchaError from '../common/errors/captcha-error';
53
58
 
54
59
  import MeetingCollection from './collection';
55
60
  import MeetingsUtil from './util';
61
+ import PermissionError from '../common/errors/permission';
62
+ import {INoiseReductionEffect, IVirtualBackgroundEffect} from './meetings.types';
56
63
 
57
64
  let mediaLogger;
58
65
 
@@ -144,7 +151,8 @@ export default class Meetings extends WebexPlugin {
144
151
  request: any;
145
152
  geoHintInfo: any;
146
153
  meetingInfo: any;
147
-
154
+ mediaHelpers: any;
155
+ breakoutLocusForHandleLater: any;
148
156
  namespace = MEETINGS;
149
157
 
150
158
  /**
@@ -156,6 +164,17 @@ export default class Meetings extends WebexPlugin {
156
164
  constructor(...args) {
157
165
  super(...args);
158
166
 
167
+ /**
168
+ * The webrtc-core media helpers. This is a temporary solution required for the SDK sample app
169
+ * to be able to call media helper functions.
170
+ *
171
+ * @instance
172
+ * @type {Object}
173
+ * @private
174
+ * @memberof Meetings
175
+ */
176
+ this.mediaHelpers = mediaHelpersModule;
177
+
159
178
  /**
160
179
  * The Meetings request to interact with server
161
180
  * @instance
@@ -221,34 +240,142 @@ export default class Meetings extends WebexPlugin {
221
240
  */
222
241
  this.media = {
223
242
  getUserMedia: Media.getUserMedia,
224
- getSupportedDevice: Media.getSupportedDevice,
225
243
  };
226
244
 
227
245
  this.onReady();
228
246
  }
229
247
 
230
248
  /**
231
- * handle locus events and takes meeting actions with them as they come in
249
+ * check whether you need to handle this main session's locus data or not
250
+ * @param {Object} meeting current meeting data
251
+ * @param {Object} newLocus new locus data
252
+ * @returns {boolean}
253
+ * @private
254
+ * @memberof Meetings
255
+ */
256
+ private isNeedHandleMainLocus(meeting: any, newLocus: any) {
257
+ const breakoutUrl = newLocus.controls?.breakout?.url;
258
+ const breakoutLocus = this.meetingCollection.getActiveBreakoutLocus(breakoutUrl);
259
+
260
+ const isSelfJoined = newLocus?.self?.state === _JOINED_;
261
+ const isSelfMoved = newLocus?.self?.state === _LEFT_ && newLocus?.self?.reason === _MOVED_;
262
+ // @ts-ignore
263
+ const deviceFromNewLocus = MeetingsUtil.getThisDevice(newLocus, this.webex.internal.device.url);
264
+ const isResourceMovedOnThisDevice =
265
+ deviceFromNewLocus?.state === _LEFT_ && deviceFromNewLocus?.reason === _MOVED_;
266
+
267
+ const isNewLocusJoinThisDevice = MeetingsUtil.joinedOnThisDevice(
268
+ meeting,
269
+ newLocus,
270
+ // @ts-ignore
271
+ this.webex.internal.device.url
272
+ );
273
+ const isBreakoutLocusJoinThisDevice =
274
+ breakoutLocus?.joinedWith?.correlationId &&
275
+ breakoutLocus.joinedWith.correlationId === meeting?.correlationId;
276
+
277
+ if (isSelfJoined && isNewLocusJoinThisDevice) {
278
+ LoggerProxy.logger.log(
279
+ 'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
280
+ );
281
+ if (breakoutLocus?.joinedWith && deviceFromNewLocus) {
282
+ const breakoutReplaceAt =
283
+ breakoutLocus.joinedWith.replaces?.length > 0
284
+ ? breakoutLocus.joinedWith.replaces[0].replaceAt
285
+ : '';
286
+ const newLocusReplaceAt =
287
+ deviceFromNewLocus.replaces?.length > 0 ? deviceFromNewLocus.replaces[0].replaceAt : '';
288
+ if (breakoutReplaceAt && newLocusReplaceAt && breakoutReplaceAt > newLocusReplaceAt) {
289
+ LoggerProxy.logger.log(
290
+ `Meetings:index#isNeedHandleMainLocus --> this is expired main joined status locus_dto replacedAt ${newLocusReplaceAt} bo replacedAt ${breakoutReplaceAt}`
291
+ );
292
+
293
+ return false;
294
+ }
295
+ }
296
+
297
+ return true;
298
+ }
299
+ if (isBreakoutLocusJoinThisDevice) {
300
+ LoggerProxy.logger.log(
301
+ `Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: ${breakoutUrl}`
302
+ );
303
+
304
+ return false;
305
+ }
306
+ if (isSelfMoved && (newLocus?.self?.removed || isResourceMovedOnThisDevice)) {
307
+ LoggerProxy.logger.log(
308
+ 'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
309
+ );
310
+
311
+ return false;
312
+ }
313
+ if (isSelfJoined && isResourceMovedOnThisDevice) {
314
+ LoggerProxy.logger.log(
315
+ 'Meetings:index#isNeedHandleMainLocus --> self device left&moved in main locus with self joined status, not need to handle'
316
+ );
317
+
318
+ return false;
319
+ }
320
+ LoggerProxy.logger.log(
321
+ 'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
322
+ );
323
+
324
+ return true;
325
+ }
326
+
327
+ /**
328
+ * check whether you need to handle this locus data or not
329
+ * @param {Object} meeting old locus data
330
+ * @param {Object} newLocus new locus data
331
+ * @returns {boolean}
332
+ * @private
333
+ * @memberof Meetings
334
+ */
335
+ private isNeedHandleLocusDTO(meeting: any, newLocus: any) {
336
+ if (newLocus) {
337
+ const isNewLocusAsBreakout = MeetingsUtil.isBreakoutLocusDTO(newLocus);
338
+ const isSelfMoved = newLocus?.self?.state === _LEFT_ && newLocus?.self?.reason === _MOVED_;
339
+ if (!meeting) {
340
+ if (isNewLocusAsBreakout) {
341
+ LoggerProxy.logger.log(
342
+ `Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: ${newLocus.fullState?.active}`
343
+ );
344
+
345
+ return newLocus.self?.state === _JOINED_;
346
+ }
347
+
348
+ return this.isNeedHandleMainLocus(meeting, newLocus);
349
+ }
350
+ if (!isNewLocusAsBreakout) {
351
+ return this.isNeedHandleMainLocus(meeting, newLocus);
352
+ }
353
+
354
+ return !isSelfMoved;
355
+ }
356
+
357
+ return true;
358
+ }
359
+
360
+ /**
361
+ * get corresponding meeting object by locus data
232
362
  * @param {Object} data a locus event
233
363
  * @param {String} data.locusUrl
234
364
  * @param {Object} data.locus
235
- * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
236
- * @param {String} data.eventType
237
- * @returns {undefined}
365
+ * @returns {Object}
238
366
  * @private
239
367
  * @memberof Meetings
240
368
  */
241
- private handleLocusEvent(data: {locusUrl: string; locus: any}, useRandomDelayForInfo = false) {
242
- let meeting = null;
243
-
369
+ getCorrespondingMeetingByLocus(data) {
244
370
  // getting meeting by correlationId. This will happen for the new event
245
371
  // Either the locus
246
372
  // TODO : Add check for the callBack Address
247
- meeting =
373
+ return (
248
374
  this.meetingCollection.getByKey(LOCUS_URL, data.locusUrl) ||
249
375
  // @ts-ignore
250
376
  this.meetingCollection.getByKey(
251
377
  CORRELATION_ID,
378
+ // @ts-ignore
252
379
  MeetingsUtil.checkForCorrelationId(this.webex.internal.device.url, data.locus)
253
380
  ) ||
254
381
  this.meetingCollection.getByKey(
@@ -259,7 +386,24 @@ export default class Meetings extends WebexPlugin {
259
386
  ) ||
260
387
  (data.locus.info?.isUnifiedSpaceMeeting
261
388
  ? undefined
262
- : this.meetingCollection.getByKey(CONVERSATION_URL, data.locus.conversationUrl));
389
+ : this.meetingCollection.getByKey(CONVERSATION_URL, data.locus.conversationUrl)) ||
390
+ this.meetingCollection.getByKey(MEETINGNUMBER, data.locus?.info?.webExMeetingId)
391
+ );
392
+ }
393
+
394
+ /**
395
+ * handle locus events and takes meeting actions with them as they come in
396
+ * @param {Object} data a locus event
397
+ * @param {String} data.locusUrl
398
+ * @param {Object} data.locus
399
+ * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
400
+ * @param {String} data.eventType
401
+ * @returns {undefined}
402
+ * @private
403
+ * @memberof Meetings
404
+ */
405
+ private handleLocusEvent(data: {locusUrl: string; locus: any}, useRandomDelayForInfo = false) {
406
+ let meeting = this.getCorrespondingMeetingByLocus(data);
263
407
 
264
408
  // Special case when locus has got replaced, This only happend once if a replace locus exists
265
409
  // https://sqbu-github.cisco.com/WebExSquared/locus/wiki/Locus-changing-mid-call
@@ -272,6 +416,16 @@ export default class Meetings extends WebexPlugin {
272
416
  );
273
417
  }
274
418
 
419
+ if (meeting && !MeetingsUtil.isBreakoutLocusDTO(data.locus)) {
420
+ meeting.locusInfo.updateMainSessionLocusCache(data.locus);
421
+ }
422
+ if (!this.isNeedHandleLocusDTO(meeting, data.locus)) {
423
+ LoggerProxy.logger.log(
424
+ `Meetings:index#handleLocusEvent --> doesn't need to process locus event`
425
+ );
426
+
427
+ return;
428
+ }
275
429
  if (!meeting) {
276
430
  // TODO: create meeting when we get a meeting object
277
431
  // const checkForEnded = (locus) => {
@@ -328,6 +482,7 @@ export default class Meetings extends WebexPlugin {
328
482
 
329
483
  // It's a new meeting so initialize the locus data
330
484
  meeting.locusInfo.initialSetup(data.locus);
485
+ this.checkHandleBreakoutLocus(data.locus);
331
486
  })
332
487
  .catch((e) => {
333
488
  LoggerProxy.logger.error(e);
@@ -337,10 +492,15 @@ export default class Meetings extends WebexPlugin {
337
492
  // because the other user left so before sending 'added' event make sure it exists in the collection
338
493
 
339
494
  if (this.getMeetingByType(_ID_, meeting.id)) {
340
- Metrics.postEvent({
341
- event: eventType.REMOTE_STARTED,
342
- meeting,
343
- data: {trigger: trigger.MERCURY_EVENT},
495
+ // @ts-ignore
496
+ this.webex.internal.newMetrics.submitClientEvent({
497
+ name: 'client.call.remote-started',
498
+ payload: {
499
+ trigger: 'mercury-event',
500
+ },
501
+ options: {
502
+ meetingId: meeting.id,
503
+ },
344
504
  });
345
505
  Trigger.trigger(
346
506
  this,
@@ -460,7 +620,7 @@ export default class Meetings extends WebexPlugin {
460
620
  LoggerProxy.set(this.webex.logger);
461
621
 
462
622
  mediaLogger = new MediaLogger();
463
- MC.setLogger(mediaLogger);
623
+ setLogger(mediaLogger);
464
624
 
465
625
  /**
466
626
  * The MeetingInfo object to interact with server
@@ -471,11 +631,14 @@ export default class Meetings extends WebexPlugin {
471
631
  */
472
632
  // @ts-ignore
473
633
  this.meetingInfo = this.config.experimental.enableUnifiedMeetings
474
- ? new MeetingInfoV2(this.webex)
475
- : new MeetingInfo(this.webex);
634
+ ? // @ts-ignore
635
+ new MeetingInfoV2(this.webex)
636
+ : // @ts-ignore
637
+ new MeetingInfo(this.webex);
476
638
  // @ts-ignore
477
639
  this.personalMeetingRoom = new PersonalMeetingRoom(
478
640
  {meetingInfo: this.meetingInfo},
641
+ // @ts-ignore
479
642
  {parent: this.webex}
480
643
  );
481
644
 
@@ -490,7 +653,7 @@ export default class Meetings extends WebexPlugin {
490
653
 
491
654
  MeetingsUtil.checkH264Support({disableNotifications: true});
492
655
  // @ts-ignore
493
- Metrics.initialSetup(this.meetingCollection, this.webex);
656
+ Metrics.initialSetup(this.webex);
494
657
  });
495
658
  }
496
659
 
@@ -585,6 +748,7 @@ export default class Meetings extends WebexPlugin {
585
748
  // @ts-ignore
586
749
  .then(() =>
587
750
  LoggerProxy.logger.info(
751
+ // @ts-ignore
588
752
  `Meetings:index#register --> INFO, Device registered ${this.webex.internal.device.url}`
589
753
  )
590
754
  )
@@ -638,8 +802,8 @@ export default class Meetings extends WebexPlugin {
638
802
 
639
803
  this.stopListeningForEvents();
640
804
 
641
- // @ts-ignore
642
805
  return (
806
+ // @ts-ignore
643
807
  this.webex.internal.mercury
644
808
  .disconnect()
645
809
  // @ts-ignore
@@ -658,6 +822,36 @@ export default class Meetings extends WebexPlugin {
658
822
  );
659
823
  }
660
824
 
825
+ /**
826
+ * Creates a noise reduction effect
827
+ *
828
+ * @param {INoiseReductionEffect} options optional custom effect options
829
+ * @returns {Promise<effect>} noise reduction effect.
830
+ * @public
831
+ * @memberof Meetings
832
+ */
833
+ createNoiseReductionEffect = async (options?: INoiseReductionEffect) => {
834
+ // @ts-ignore
835
+ const authToken = this.webex.credentials.supertoken.access_token;
836
+
837
+ return new mediaHelpersModule.NoiseReductionEffect({authToken, ...options});
838
+ };
839
+
840
+ /**
841
+ * Creates a virtual background effect
842
+ *
843
+ * @param {IVirtualBackgroundEffect} options optional custom effect options
844
+ * @returns {Promise<effect>} virtual background effect.
845
+ * @public
846
+ * @memberof Meetings
847
+ */
848
+ createVirtualBackgroundEffect = async (options?: IVirtualBackgroundEffect) => {
849
+ // @ts-ignore
850
+ const authToken = this.webex.credentials.supertoken.access_token;
851
+
852
+ return new mediaHelpersModule.VirtualBackgroundEffect({authToken, ...options});
853
+ };
854
+
661
855
  /**
662
856
  * Uploads logs to the webex services for tracking
663
857
  * @param {Object} [options={}]
@@ -792,6 +986,29 @@ export default class Meetings extends WebexPlugin {
792
986
  if (res) {
793
987
  this.preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
794
988
  }
989
+
990
+ // fall back to getting the preferred site from the user information
991
+ if (!this.preferredWebexSite) {
992
+ // @ts-ignore
993
+ return this.webex.internal.user
994
+ .get()
995
+ .then((user) => {
996
+ const preferredWebexSite =
997
+ user?.userPreferences?.userPreferencesItems?.preferredWebExSite;
998
+ if (preferredWebexSite) {
999
+ this.preferredWebexSite = preferredWebexSite;
1000
+ } else {
1001
+ throw new Error('site not found');
1002
+ }
1003
+ })
1004
+ .catch(() => {
1005
+ LoggerProxy.logger.error(
1006
+ 'Failed to fetch preferred site from user - no site will be set'
1007
+ );
1008
+ });
1009
+ }
1010
+
1011
+ return Promise.resolve();
795
1012
  });
796
1013
  }
797
1014
 
@@ -836,11 +1053,17 @@ export default class Meetings extends WebexPlugin {
836
1053
  * @param {string} destination - sipURL, spaceId, phonenumber, or locus object}
837
1054
  * @param {string} [type] - the optional specified type, such as locusId
838
1055
  * @param {Boolean} useRandomDelayForInfo - whether a random delay should be added to fetching meeting info
1056
+ * @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
839
1057
  * @returns {Promise<Meeting>} A new Meeting.
840
1058
  * @public
841
1059
  * @memberof Meetings
842
1060
  */
843
- public create(destination: string, type: string = null, useRandomDelayForInfo = false) {
1061
+ public create(
1062
+ destination: string,
1063
+ type: string = null,
1064
+ useRandomDelayForInfo = false,
1065
+ infoExtraParams = {}
1066
+ ) {
844
1067
  // TODO: type should be from a dictionary
845
1068
 
846
1069
  // Validate meeting information based on the provided destination and
@@ -885,48 +1108,51 @@ export default class Meetings extends WebexPlugin {
885
1108
  // Validate if a meeting was found.
886
1109
  if (!meeting) {
887
1110
  // Create a meeting based on the normalized destination and type.
888
- return this.createMeeting(targetDest, type, useRandomDelayForInfo).then(
889
- (createdMeeting: any) => {
890
- // If the meeting was successfully created.
891
- if (createdMeeting && createdMeeting.on) {
892
- // Create a destruction event for the meeting.
893
- createdMeeting.on(EVENTS.DESTROY_MEETING, (payload) => {
894
- // @ts-ignore
895
- if (this.config.autoUploadLogs) {
896
- this.uploadLogs({
897
- callStart: createdMeeting.locusInfo?.fullState?.lastActive,
898
- correlationId: createdMeeting.correlationId,
899
- feedbackId: createdMeeting.correlationId,
900
- locusId: createdMeeting.locusId,
901
- meetingId: createdMeeting.locusInfo?.info?.webExMeetingId,
902
- }).then(() => this.destroy(createdMeeting, payload.reason));
903
- } else {
904
- this.destroy(createdMeeting, payload.reason);
905
- }
906
- });
907
-
908
- createdMeeting.on(EVENTS.REQUEST_UPLOAD_LOGS, (meetingInstance) => {
909
- // @ts-ignore
910
- if (this.config.autoUploadLogs) {
911
- this.uploadLogs({
912
- callStart: meetingInstance?.locusInfo?.fullState?.lastActive,
913
- correlationId: meetingInstance.correlationId,
914
- feedbackId: meetingInstance.correlationId,
915
- locusId: meetingInstance.locusId,
916
- meetingId: meetingInstance.locusInfo?.info?.webExMeetingId,
917
- });
918
- }
919
- });
920
- } else {
921
- LoggerProxy.logger.error(
922
- `Meetings:index#create --> ERROR, meeting does not have on method, will not be destroyed, meeting cleanup impossible for meeting: ${meeting}`
923
- );
924
- }
925
-
926
- // Return the newly created meeting.
927
- return Promise.resolve(createdMeeting);
1111
+ return this.createMeeting(
1112
+ targetDest,
1113
+ type,
1114
+ useRandomDelayForInfo,
1115
+ infoExtraParams
1116
+ ).then((createdMeeting: any) => {
1117
+ // If the meeting was successfully created.
1118
+ if (createdMeeting && createdMeeting.on) {
1119
+ // Create a destruction event for the meeting.
1120
+ createdMeeting.on(EVENTS.DESTROY_MEETING, (payload) => {
1121
+ // @ts-ignore
1122
+ if (this.config.autoUploadLogs) {
1123
+ this.uploadLogs({
1124
+ callStart: createdMeeting.locusInfo?.fullState?.lastActive,
1125
+ correlationId: createdMeeting.correlationId,
1126
+ feedbackId: createdMeeting.correlationId,
1127
+ locusId: createdMeeting.locusId,
1128
+ meetingId: createdMeeting.locusInfo?.info?.webExMeetingId,
1129
+ }).then(() => this.destroy(createdMeeting, payload.reason));
1130
+ } else {
1131
+ this.destroy(createdMeeting, payload.reason);
1132
+ }
1133
+ });
1134
+
1135
+ createdMeeting.on(EVENTS.REQUEST_UPLOAD_LOGS, (meetingInstance) => {
1136
+ // @ts-ignore
1137
+ if (this.config.autoUploadLogs) {
1138
+ this.uploadLogs({
1139
+ callStart: meetingInstance?.locusInfo?.fullState?.lastActive,
1140
+ correlationId: meetingInstance.correlationId,
1141
+ feedbackId: meetingInstance.correlationId,
1142
+ locusId: meetingInstance.locusId,
1143
+ meetingId: meetingInstance.locusInfo?.info?.webExMeetingId,
1144
+ });
1145
+ }
1146
+ });
1147
+ } else {
1148
+ LoggerProxy.logger.error(
1149
+ `Meetings:index#create --> ERROR, meeting does not have on method, will not be destroyed, meeting cleanup impossible for meeting: ${meeting}`
1150
+ );
928
1151
  }
929
- );
1152
+
1153
+ // Return the newly created meeting.
1154
+ return Promise.resolve(createdMeeting);
1155
+ });
930
1156
  }
931
1157
 
932
1158
  // Return the existing meeting.
@@ -939,6 +1165,7 @@ export default class Meetings extends WebexPlugin {
939
1165
  * @param {String} destination see create()
940
1166
  * @param {String} type see create()
941
1167
  * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
1168
+ * @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
942
1169
  * @returns {Promise} a new meeting instance complete with meeting info and destination
943
1170
  * @private
944
1171
  * @memberof Meetings
@@ -946,7 +1173,8 @@ export default class Meetings extends WebexPlugin {
946
1173
  private async createMeeting(
947
1174
  destination: any,
948
1175
  type: string = null,
949
- useRandomDelayForInfo = false
1176
+ useRandomDelayForInfo = false,
1177
+ infoExtraParams = {}
950
1178
  ) {
951
1179
  const meeting = new Meeting(
952
1180
  {
@@ -994,15 +1222,19 @@ export default class Meetings extends WebexPlugin {
994
1222
 
995
1223
  if (enableUnifiedMeetings && !isMeetingActive && useRandomDelayForInfo && waitingTime > 0) {
996
1224
  meeting.fetchMeetingInfoTimeoutId = setTimeout(
997
- () => meeting.fetchMeetingInfo({}),
1225
+ () => meeting.fetchMeetingInfo({extraParams: infoExtraParams}),
998
1226
  waitingTime
999
1227
  );
1000
1228
  meeting.parseMeetingInfo(undefined, destination);
1001
1229
  } else {
1002
- await meeting.fetchMeetingInfo({});
1230
+ await meeting.fetchMeetingInfo({extraParams: infoExtraParams});
1003
1231
  }
1004
1232
  } catch (err) {
1005
- if (!(err instanceof CaptchaError) && !(err instanceof PasswordError)) {
1233
+ if (
1234
+ !(err instanceof CaptchaError) &&
1235
+ !(err instanceof PasswordError) &&
1236
+ !(err instanceof PermissionError)
1237
+ ) {
1006
1238
  // if there is no meeting info we assume its a 1:1 call or wireless share
1007
1239
  LoggerProxy.logger.info(
1008
1240
  `Meetings:index#createMeeting --> Info Unable to fetch meeting info for ${destination}.`
@@ -1103,33 +1335,108 @@ export default class Meetings extends WebexPlugin {
1103
1335
  * @memberof Meetings
1104
1336
  */
1105
1337
  public syncMeetings() {
1106
- return this.request.getActiveMeetings().then((locusArray) => {
1107
- const activeLocusUrl = [];
1108
-
1109
- if (locusArray?.loci && locusArray.loci.length > 0) {
1110
- locusArray.loci.forEach((locus) => {
1111
- activeLocusUrl.push(locus.url);
1112
- this.handleLocusEvent({
1113
- locus,
1114
- locusUrl: locus.url,
1338
+ return this.request
1339
+ .getActiveMeetings()
1340
+ .then((locusArray) => {
1341
+ const activeLocusUrl = [];
1342
+
1343
+ if (locusArray?.loci && locusArray.loci.length > 0) {
1344
+ const lociToUpdate = this.sortLocusArrayToUpdate(locusArray.loci);
1345
+ lociToUpdate.forEach((locus) => {
1346
+ activeLocusUrl.push(locus.url);
1347
+ this.handleLocusEvent({
1348
+ locus,
1349
+ locusUrl: locus.url,
1350
+ });
1115
1351
  });
1116
- });
1117
- }
1118
- const meetingsCollection = this.meetingCollection.getAll();
1119
-
1120
- if (Object.keys(meetingsCollection).length > 0) {
1121
- // Some time the mercury event is missed after mercury reconnect
1122
- // if sync returns no locus then clear all the meetings
1123
- for (const meeting of Object.values(meetingsCollection)) {
1124
- // @ts-ignore
1125
- if (!activeLocusUrl.includes(meeting.locusUrl)) {
1126
- // destroy function also uploads logs
1352
+ }
1353
+ const meetingsCollection = this.meetingCollection.getAll();
1354
+
1355
+ if (Object.keys(meetingsCollection).length > 0) {
1356
+ // Some time the mercury event is missed after mercury reconnect
1357
+ // if sync returns no locus then clear all the meetings
1358
+ for (const meeting of Object.values(meetingsCollection)) {
1127
1359
  // @ts-ignore
1128
- this.destroy(meeting, MEETING_REMOVED_REASON.NO_MEETINGS_TO_SYNC);
1360
+ if (!activeLocusUrl.includes(meeting.locusUrl)) {
1361
+ // destroy function also uploads logs
1362
+ // @ts-ignore
1363
+ this.destroy(meeting, MEETING_REMOVED_REASON.NO_MEETINGS_TO_SYNC);
1364
+ }
1129
1365
  }
1130
1366
  }
1367
+ })
1368
+ .catch((error) => {
1369
+ LoggerProxy.logger.error(
1370
+ `Meetings:index#syncMeetings --> failed to sync meetings, ${error}`
1371
+ );
1372
+ throw new Error(error);
1373
+ });
1374
+ }
1375
+
1376
+ /**
1377
+ * sort out locus array for initial creating
1378
+ * @param {Array} loci original locus array
1379
+ * @returns {undefined}
1380
+ * @public
1381
+ * @memberof Meetings
1382
+ */
1383
+ sortLocusArrayToUpdate(loci: any[]) {
1384
+ const mainLoci = loci.filter((locus) => !MeetingsUtil.isBreakoutLocusDTO(locus));
1385
+ const breakoutLoci = loci.filter((locus) => MeetingsUtil.isValidBreakoutLocus(locus));
1386
+ this.breakoutLocusForHandleLater = [];
1387
+ const lociToUpdate = [...mainLoci];
1388
+ breakoutLoci.forEach((breakoutLocus) => {
1389
+ const associateMainLocus = mainLoci.find(
1390
+ (mainLocus) => mainLocus.controls?.breakout?.url === breakoutLocus.controls?.breakout?.url
1391
+ );
1392
+ const existCorrespondingMeeting = this.getCorrespondingMeetingByLocus({
1393
+ locus: breakoutLocus,
1394
+ locusUrl: breakoutLocus.url,
1395
+ });
1396
+
1397
+ if (associateMainLocus && !existCorrespondingMeeting) {
1398
+ // if exists both main session and breakout session locus of the same non-exist meeting, handle main locus first,
1399
+ // after meeting create with main locus, then handle the associate breakout locus.
1400
+ // if only handle breakout locus, will miss some date
1401
+ this.breakoutLocusForHandleLater.push(breakoutLocus);
1402
+ } else {
1403
+ lociToUpdate.push(breakoutLocus);
1131
1404
  }
1132
1405
  });
1406
+
1407
+ return lociToUpdate;
1408
+ }
1409
+
1410
+ /**
1411
+ * check breakout locus which waiting for main locus's meeting to be created, then handle the breakout locus
1412
+ * @param {Object} newCreatedLocus the locus which just create meeting object of it
1413
+ * @returns {undefined}
1414
+ * @public
1415
+ * @memberof Meetings
1416
+ */
1417
+ checkHandleBreakoutLocus(newCreatedLocus) {
1418
+ if (
1419
+ !newCreatedLocus ||
1420
+ !this.breakoutLocusForHandleLater ||
1421
+ !this.breakoutLocusForHandleLater.length
1422
+ ) {
1423
+ return;
1424
+ }
1425
+ if (MeetingsUtil.isBreakoutLocusDTO(newCreatedLocus)) {
1426
+ return;
1427
+ }
1428
+ const existIndex = this.breakoutLocusForHandleLater.findIndex(
1429
+ (breakoutLocus) =>
1430
+ breakoutLocus.controls?.breakout?.url === newCreatedLocus.controls?.breakout?.url
1431
+ );
1432
+
1433
+ if (existIndex < 0) {
1434
+ return;
1435
+ }
1436
+
1437
+ const associateBreakoutLocus = this.breakoutLocusForHandleLater[existIndex];
1438
+ this.handleLocusEvent({locus: associateBreakoutLocus, locusUrl: associateBreakoutLocus.url});
1439
+ this.breakoutLocusForHandleLater.splice(existIndex, 1);
1133
1440
  }
1134
1441
 
1135
1442
  /**