@webex/plugin-meetings 3.0.0-beta.7 → 3.0.0-beta.71

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 (506) hide show
  1. package/UPGRADING.md +9 -9
  2. package/browsers.js +19 -24
  3. package/dist/breakouts/breakout.js +178 -0
  4. package/dist/breakouts/breakout.js.map +1 -0
  5. package/dist/breakouts/collection.js +23 -0
  6. package/dist/breakouts/collection.js.map +1 -0
  7. package/dist/breakouts/edit-lock-error.js +52 -0
  8. package/dist/breakouts/edit-lock-error.js.map +1 -0
  9. package/dist/breakouts/index.js +843 -0
  10. package/dist/breakouts/index.js.map +1 -0
  11. package/dist/breakouts/request.js +78 -0
  12. package/dist/breakouts/request.js.map +1 -0
  13. package/dist/breakouts/utils.js +56 -0
  14. package/dist/breakouts/utils.js.map +1 -0
  15. package/dist/common/browser-detection.js +1 -20
  16. package/dist/common/browser-detection.js.map +1 -1
  17. package/dist/common/collection.js +5 -20
  18. package/dist/common/collection.js.map +1 -1
  19. package/dist/common/config.js +0 -7
  20. package/dist/common/config.js.map +1 -1
  21. package/dist/common/errors/captcha-error.js +10 -24
  22. package/dist/common/errors/captcha-error.js.map +1 -1
  23. package/dist/common/errors/intent-to-join.js +11 -24
  24. package/dist/common/errors/intent-to-join.js.map +1 -1
  25. package/dist/common/errors/join-meeting.js +12 -25
  26. package/dist/common/errors/join-meeting.js.map +1 -1
  27. package/dist/common/errors/media.js +10 -24
  28. package/dist/common/errors/media.js.map +1 -1
  29. package/dist/common/errors/parameter.js +5 -33
  30. package/dist/common/errors/parameter.js.map +1 -1
  31. package/dist/common/errors/password-error.js +10 -24
  32. package/dist/common/errors/password-error.js.map +1 -1
  33. package/dist/common/errors/permission.js +9 -23
  34. package/dist/common/errors/permission.js.map +1 -1
  35. package/dist/common/errors/reconnection-in-progress.js +0 -17
  36. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  37. package/dist/common/errors/reconnection.js +10 -24
  38. package/dist/common/errors/reconnection.js.map +1 -1
  39. package/dist/common/errors/stats.js +10 -24
  40. package/dist/common/errors/stats.js.map +1 -1
  41. package/dist/common/errors/webex-errors.js +6 -41
  42. package/dist/common/errors/webex-errors.js.map +1 -1
  43. package/dist/common/errors/webex-meetings-error.js +5 -25
  44. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  45. package/dist/common/events/events-scope.js +0 -22
  46. package/dist/common/events/events-scope.js.map +1 -1
  47. package/dist/common/events/events.js +0 -23
  48. package/dist/common/events/events.js.map +1 -1
  49. package/dist/common/events/trigger-proxy.js +0 -12
  50. package/dist/common/events/trigger-proxy.js.map +1 -1
  51. package/dist/common/events/util.js +0 -15
  52. package/dist/common/events/util.js.map +1 -1
  53. package/dist/common/logs/logger-config.js +0 -4
  54. package/dist/common/logs/logger-config.js.map +1 -1
  55. package/dist/common/logs/logger-proxy.js +1 -8
  56. package/dist/common/logs/logger-proxy.js.map +1 -1
  57. package/dist/common/logs/request.js +37 -60
  58. package/dist/common/logs/request.js.map +1 -1
  59. package/dist/common/queue.js +4 -14
  60. package/dist/common/queue.js.map +1 -1
  61. package/dist/config.js +6 -6
  62. package/dist/config.js.map +1 -1
  63. package/dist/constants.js +143 -52
  64. package/dist/constants.js.map +1 -1
  65. package/dist/controls-options-manager/constants.js +14 -0
  66. package/dist/controls-options-manager/constants.js.map +1 -0
  67. package/dist/controls-options-manager/enums.js +16 -0
  68. package/dist/controls-options-manager/enums.js.map +1 -0
  69. package/dist/controls-options-manager/index.js +261 -0
  70. package/dist/controls-options-manager/index.js.map +1 -0
  71. package/dist/controls-options-manager/util.js +39 -0
  72. package/dist/controls-options-manager/util.js.map +1 -0
  73. package/dist/index.js +11 -18
  74. package/dist/index.js.map +1 -1
  75. package/dist/locus-info/controlsUtils.js +31 -29
  76. package/dist/locus-info/controlsUtils.js.map +1 -1
  77. package/dist/locus-info/embeddedAppsUtils.js +3 -26
  78. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  79. package/dist/locus-info/fullState.js +0 -15
  80. package/dist/locus-info/fullState.js.map +1 -1
  81. package/dist/locus-info/hostUtils.js +4 -12
  82. package/dist/locus-info/hostUtils.js.map +1 -1
  83. package/dist/locus-info/index.js +237 -198
  84. package/dist/locus-info/index.js.map +1 -1
  85. package/dist/locus-info/infoUtils.js +3 -37
  86. package/dist/locus-info/infoUtils.js.map +1 -1
  87. package/dist/locus-info/mediaSharesUtils.js +12 -38
  88. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  89. package/dist/locus-info/parser.js +92 -118
  90. package/dist/locus-info/parser.js.map +1 -1
  91. package/dist/locus-info/selfUtils.js +80 -89
  92. package/dist/locus-info/selfUtils.js.map +1 -1
  93. package/dist/media/index.js +56 -146
  94. package/dist/media/index.js.map +1 -1
  95. package/dist/media/properties.js +83 -117
  96. package/dist/media/properties.js.map +1 -1
  97. package/dist/media/util.js +2 -9
  98. package/dist/media/util.js.map +1 -1
  99. package/dist/mediaQualityMetrics/config.js +505 -495
  100. package/dist/mediaQualityMetrics/config.js.map +1 -1
  101. package/dist/meeting/in-meeting-actions.js +31 -14
  102. package/dist/meeting/in-meeting-actions.js.map +1 -1
  103. package/dist/meeting/index.js +2225 -2244
  104. package/dist/meeting/index.js.map +1 -1
  105. package/dist/meeting/muteState.js +102 -100
  106. package/dist/meeting/muteState.js.map +1 -1
  107. package/dist/meeting/request.js +308 -264
  108. package/dist/meeting/request.js.map +1 -1
  109. package/dist/meeting/request.type.js +7 -0
  110. package/dist/meeting/request.type.js.map +1 -0
  111. package/dist/meeting/state.js +21 -31
  112. package/dist/meeting/state.js.map +1 -1
  113. package/dist/meeting/util.js +63 -217
  114. package/dist/meeting/util.js.map +1 -1
  115. package/dist/meeting-info/collection.js +6 -25
  116. package/dist/meeting-info/collection.js.map +1 -1
  117. package/dist/meeting-info/index.js +14 -32
  118. package/dist/meeting-info/index.js.map +1 -1
  119. package/dist/meeting-info/meeting-info-v2.js +193 -268
  120. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  121. package/dist/meeting-info/request.js +3 -15
  122. package/dist/meeting-info/request.js.map +1 -1
  123. package/dist/meeting-info/util.js +98 -183
  124. package/dist/meeting-info/util.js.map +1 -1
  125. package/dist/meeting-info/utilv2.js +137 -228
  126. package/dist/meeting-info/utilv2.js.map +1 -1
  127. package/dist/meetings/collection.js +26 -19
  128. package/dist/meetings/collection.js.map +1 -1
  129. package/dist/meetings/index.js +565 -552
  130. package/dist/meetings/index.js.map +1 -1
  131. package/dist/meetings/request.js +26 -41
  132. package/dist/meetings/request.js.map +1 -1
  133. package/dist/meetings/util.js +151 -155
  134. package/dist/meetings/util.js.map +1 -1
  135. package/dist/member/index.js +100 -85
  136. package/dist/member/index.js.map +1 -1
  137. package/dist/member/types.js +15 -0
  138. package/dist/member/types.js.map +1 -0
  139. package/dist/member/util.js +90 -68
  140. package/dist/member/util.js.map +1 -1
  141. package/dist/members/collection.js +13 -12
  142. package/dist/members/collection.js.map +1 -1
  143. package/dist/members/index.js +152 -204
  144. package/dist/members/index.js.map +1 -1
  145. package/dist/members/request.js +35 -39
  146. package/dist/members/request.js.map +1 -1
  147. package/dist/members/types.js +15 -0
  148. package/dist/members/types.js.map +1 -0
  149. package/dist/members/util.js +76 -46
  150. package/dist/members/util.js.map +1 -1
  151. package/dist/metrics/config.js +4 -14
  152. package/dist/metrics/config.js.map +1 -1
  153. package/dist/metrics/constants.js +1 -6
  154. package/dist/metrics/constants.js.map +1 -1
  155. package/dist/metrics/index.js +59 -156
  156. package/dist/metrics/index.js.map +1 -1
  157. package/dist/multistream/mediaRequestManager.js +116 -52
  158. package/dist/multistream/mediaRequestManager.js.map +1 -1
  159. package/dist/multistream/receiveSlot.js +58 -65
  160. package/dist/multistream/receiveSlot.js.map +1 -1
  161. package/dist/multistream/receiveSlotManager.js +58 -93
  162. package/dist/multistream/receiveSlotManager.js.map +1 -1
  163. package/dist/multistream/remoteMedia.js +55 -74
  164. package/dist/multistream/remoteMedia.js.map +1 -1
  165. package/dist/multistream/remoteMediaGroup.js +6 -40
  166. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  167. package/dist/multistream/remoteMediaManager.js +466 -442
  168. package/dist/multistream/remoteMediaManager.js.map +1 -1
  169. package/dist/networkQualityMonitor/index.js +40 -59
  170. package/dist/networkQualityMonitor/index.js.map +1 -1
  171. package/dist/personal-meeting-room/index.js +21 -45
  172. package/dist/personal-meeting-room/index.js.map +1 -1
  173. package/dist/personal-meeting-room/request.js +1 -31
  174. package/dist/personal-meeting-room/request.js.map +1 -1
  175. package/dist/personal-meeting-room/util.js +0 -13
  176. package/dist/personal-meeting-room/util.js.map +1 -1
  177. package/dist/reachability/index.js +192 -191
  178. package/dist/reachability/index.js.map +1 -1
  179. package/dist/reachability/request.js +15 -23
  180. package/dist/reachability/request.js.map +1 -1
  181. package/dist/reactions/constants.js +13 -0
  182. package/dist/reactions/constants.js.map +1 -0
  183. package/dist/reactions/reactions.js +109 -0
  184. package/dist/reactions/reactions.js.map +1 -0
  185. package/dist/reactions/reactions.type.js +36 -0
  186. package/dist/reactions/reactions.type.js.map +1 -0
  187. package/dist/reconnection-manager/index.js +342 -460
  188. package/dist/reconnection-manager/index.js.map +1 -1
  189. package/dist/recording-controller/enums.js +17 -0
  190. package/dist/recording-controller/enums.js.map +1 -0
  191. package/dist/recording-controller/index.js +343 -0
  192. package/dist/recording-controller/index.js.map +1 -0
  193. package/dist/recording-controller/util.js +63 -0
  194. package/dist/recording-controller/util.js.map +1 -0
  195. package/dist/roap/index.js +48 -70
  196. package/dist/roap/index.js.map +1 -1
  197. package/dist/roap/request.js +143 -131
  198. package/dist/roap/request.js.map +1 -1
  199. package/dist/roap/turnDiscovery.js +91 -98
  200. package/dist/roap/turnDiscovery.js.map +1 -1
  201. package/dist/statsAnalyzer/global.js +1 -95
  202. package/dist/statsAnalyzer/global.js.map +1 -1
  203. package/dist/statsAnalyzer/index.js +372 -455
  204. package/dist/statsAnalyzer/index.js.map +1 -1
  205. package/dist/statsAnalyzer/mqaUtil.js +143 -87
  206. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  207. package/dist/transcription/index.js +22 -47
  208. package/dist/transcription/index.js.map +1 -1
  209. package/dist/types/breakouts/breakout.d.ts +8 -0
  210. package/dist/types/breakouts/collection.d.ts +5 -0
  211. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  212. package/dist/types/breakouts/index.d.ts +5 -0
  213. package/dist/types/breakouts/request.d.ts +22 -0
  214. package/dist/types/breakouts/utils.d.ts +8 -0
  215. package/dist/types/common/browser-detection.d.ts +9 -0
  216. package/dist/types/common/collection.d.ts +48 -0
  217. package/dist/types/common/config.d.ts +2 -0
  218. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  219. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  220. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  221. package/dist/types/common/errors/media.d.ts +15 -0
  222. package/dist/types/common/errors/parameter.d.ts +15 -0
  223. package/dist/types/common/errors/password-error.d.ts +15 -0
  224. package/dist/types/common/errors/permission.d.ts +14 -0
  225. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  226. package/dist/types/common/errors/reconnection.d.ts +15 -0
  227. package/dist/types/common/errors/stats.d.ts +15 -0
  228. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  229. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  230. package/dist/types/common/events/events-scope.d.ts +17 -0
  231. package/dist/types/common/events/events.d.ts +12 -0
  232. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  233. package/dist/types/common/events/util.d.ts +2 -0
  234. package/dist/types/common/logs/logger-config.d.ts +2 -0
  235. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  236. package/dist/types/common/logs/request.d.ts +34 -0
  237. package/dist/types/common/queue.d.ts +32 -0
  238. package/dist/types/config.d.ts +77 -0
  239. package/dist/types/constants.d.ts +944 -0
  240. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  241. package/dist/types/controls-options-manager/enums.d.ts +6 -0
  242. package/dist/types/controls-options-manager/index.d.ts +128 -0
  243. package/dist/types/controls-options-manager/util.d.ts +9 -0
  244. package/dist/types/index.d.ts +6 -0
  245. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  246. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  247. package/dist/types/locus-info/fullState.d.ts +2 -0
  248. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  249. package/dist/types/locus-info/index.d.ts +276 -0
  250. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  251. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  252. package/dist/types/locus-info/parser.d.ts +212 -0
  253. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  254. package/dist/types/media/index.d.ts +32 -0
  255. package/dist/types/media/properties.d.ts +108 -0
  256. package/dist/types/media/util.d.ts +2 -0
  257. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  258. package/dist/types/meeting/in-meeting-actions.d.ts +101 -0
  259. package/dist/types/meeting/index.d.ts +1720 -0
  260. package/dist/types/meeting/muteState.d.ts +132 -0
  261. package/dist/types/meeting/request.d.ts +271 -0
  262. package/dist/types/meeting/request.type.d.ts +11 -0
  263. package/dist/types/meeting/state.d.ts +9 -0
  264. package/dist/types/meeting/util.d.ts +2 -0
  265. package/dist/types/meeting-info/collection.d.ts +20 -0
  266. package/dist/types/meeting-info/index.d.ts +57 -0
  267. package/dist/types/meeting-info/meeting-info-v2.d.ts +93 -0
  268. package/dist/types/meeting-info/request.d.ts +22 -0
  269. package/dist/types/meeting-info/util.d.ts +2 -0
  270. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  271. package/dist/types/meetings/collection.d.ts +31 -0
  272. package/dist/types/meetings/index.d.ts +315 -0
  273. package/dist/types/meetings/request.d.ts +27 -0
  274. package/dist/types/meetings/util.d.ts +18 -0
  275. package/dist/types/member/index.d.ts +156 -0
  276. package/dist/types/member/types.d.ts +21 -0
  277. package/dist/types/member/util.d.ts +2 -0
  278. package/dist/types/members/collection.d.ts +29 -0
  279. package/dist/types/members/index.d.ts +343 -0
  280. package/dist/types/members/request.d.ts +58 -0
  281. package/dist/types/members/types.d.ts +24 -0
  282. package/dist/types/members/util.d.ts +2 -0
  283. package/dist/types/metrics/config.d.ts +171 -0
  284. package/dist/types/metrics/constants.d.ts +53 -0
  285. package/dist/types/metrics/index.d.ts +152 -0
  286. package/dist/types/multistream/mediaRequestManager.d.ts +68 -0
  287. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  288. package/dist/types/multistream/receiveSlotManager.d.ts +49 -0
  289. package/dist/types/multistream/remoteMedia.d.ts +100 -0
  290. package/dist/types/multistream/remoteMediaGroup.d.ts +56 -0
  291. package/dist/types/multistream/remoteMediaManager.d.ts +263 -0
  292. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  293. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  294. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  295. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  296. package/dist/types/reachability/index.d.ts +152 -0
  297. package/dist/types/reachability/request.d.ts +37 -0
  298. package/dist/types/reactions/constants.d.ts +3 -0
  299. package/dist/types/reactions/reactions.d.ts +4 -0
  300. package/dist/types/reactions/reactions.type.d.ts +52 -0
  301. package/dist/types/reconnection-manager/index.d.ts +126 -0
  302. package/dist/types/recording-controller/enums.d.ts +7 -0
  303. package/dist/types/recording-controller/index.d.ts +193 -0
  304. package/dist/types/recording-controller/util.d.ts +13 -0
  305. package/dist/types/roap/index.d.ts +77 -0
  306. package/dist/types/roap/request.d.ts +38 -0
  307. package/dist/types/roap/turnDiscovery.d.ts +74 -0
  308. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  309. package/dist/types/statsAnalyzer/index.d.ts +195 -0
  310. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  311. package/dist/types/transcription/index.d.ts +64 -0
  312. package/internal-README.md +7 -6
  313. package/package.json +27 -21
  314. package/src/breakouts/README.md +219 -0
  315. package/src/breakouts/breakout.ts +153 -0
  316. package/src/breakouts/collection.ts +19 -0
  317. package/src/breakouts/edit-lock-error.ts +25 -0
  318. package/src/breakouts/index.ts +745 -0
  319. package/src/breakouts/request.ts +55 -0
  320. package/src/breakouts/utils.ts +44 -0
  321. package/src/common/{browser-detection.js → browser-detection.ts} +9 -6
  322. package/src/common/collection.ts +9 -7
  323. package/src/common/{config.js → config.ts} +1 -1
  324. package/src/common/errors/{captcha-error.js → captcha-error.ts} +11 -7
  325. package/src/common/errors/{intent-to-join.js → intent-to-join.ts} +12 -7
  326. package/src/common/errors/{join-meeting.js → join-meeting.ts} +17 -8
  327. package/src/common/errors/{media.js → media.ts} +11 -7
  328. package/src/common/errors/parameter.ts +11 -7
  329. package/src/common/errors/{password-error.js → password-error.ts} +11 -7
  330. package/src/common/errors/{permission.js → permission.ts} +10 -6
  331. package/src/common/errors/{reconnection.js → reconnection.ts} +11 -7
  332. package/src/common/errors/{stats.js → stats.ts} +11 -7
  333. package/src/common/errors/{webex-errors.js → webex-errors.ts} +8 -7
  334. package/src/common/errors/{webex-meetings-error.js → webex-meetings-error.ts} +4 -2
  335. package/src/common/events/{events-scope.js → events-scope.ts} +6 -2
  336. package/src/common/events/{events.js → events.ts} +5 -1
  337. package/src/common/events/{trigger-proxy.js → trigger-proxy.ts} +9 -5
  338. package/src/common/events/{util.js → util.ts} +2 -3
  339. package/src/common/logs/{logger-config.js → logger-config.ts} +1 -2
  340. package/src/common/logs/logger-proxy.ts +44 -0
  341. package/src/common/logs/{request.js → request.ts} +22 -9
  342. package/src/common/queue.ts +1 -2
  343. package/src/{config.js → config.ts} +17 -12
  344. package/src/constants.ts +92 -5
  345. package/src/controls-options-manager/constants.ts +5 -0
  346. package/src/controls-options-manager/enums.ts +7 -0
  347. package/src/controls-options-manager/index.ts +240 -0
  348. package/src/controls-options-manager/util.ts +30 -0
  349. package/src/index.js +4 -1
  350. package/src/locus-info/controlsUtils.ts +141 -0
  351. package/src/locus-info/{embeddedAppsUtils.js → embeddedAppsUtils.ts} +5 -6
  352. package/src/locus-info/{fullState.js → fullState.ts} +16 -12
  353. package/src/locus-info/{hostUtils.js → hostUtils.ts} +9 -8
  354. package/src/locus-info/{index.js → index.ts} +211 -71
  355. package/src/locus-info/{infoUtils.js → infoUtils.ts} +19 -8
  356. package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +17 -17
  357. package/src/locus-info/{parser.js → parser.ts} +67 -79
  358. package/src/locus-info/{selfUtils.js → selfUtils.ts} +183 -67
  359. package/src/media/{index.js → index.ts} +179 -176
  360. package/src/media/{properties.js → properties.ts} +60 -37
  361. package/src/media/{util.js → util.ts} +2 -2
  362. package/src/mediaQualityMetrics/config.ts +384 -0
  363. package/src/meeting/in-meeting-actions.ts +67 -3
  364. package/src/meeting/{index.js → index.ts} +2605 -1605
  365. package/src/meeting/{muteState.js → muteState.ts} +138 -73
  366. package/src/meeting/{request.js → request.ts} +326 -142
  367. package/src/meeting/request.type.ts +13 -0
  368. package/src/meeting/{state.js → state.ts} +50 -35
  369. package/src/meeting/{util.js → util.ts} +131 -115
  370. package/src/meeting-info/{collection.js → collection.ts} +6 -2
  371. package/src/meeting-info/{index.js → index.ts} +42 -36
  372. package/src/meeting-info/meeting-info-v2.ts +273 -0
  373. package/src/meeting-info/{request.js → request.ts} +14 -4
  374. package/src/meeting-info/{util.js → util.ts} +60 -51
  375. package/src/meeting-info/{utilv2.js → utilv2.ts} +65 -58
  376. package/src/meetings/{collection.js → collection.ts} +26 -3
  377. package/src/meetings/index.ts +1275 -0
  378. package/src/meetings/{request.js → request.ts} +34 -25
  379. package/src/meetings/{util.js → util.ts} +99 -33
  380. package/src/member/{index.js → index.ts} +124 -56
  381. package/src/member/types.ts +24 -0
  382. package/src/member/{util.js → util.ts} +105 -25
  383. package/src/members/{collection.js → collection.ts} +10 -2
  384. package/src/members/{index.js → index.ts} +281 -144
  385. package/src/members/{request.js → request.ts} +80 -16
  386. package/src/members/types.ts +28 -0
  387. package/src/members/{util.js → util.ts} +108 -55
  388. package/src/metrics/{config.js → config.ts} +255 -92
  389. package/src/metrics/{constants.js → constants.ts} +0 -6
  390. package/src/metrics/{index.js → index.ts} +110 -94
  391. package/src/multistream/mediaRequestManager.ts +144 -40
  392. package/src/multistream/receiveSlot.ts +69 -26
  393. package/src/multistream/receiveSlotManager.ts +50 -38
  394. package/src/multistream/remoteMedia.ts +30 -4
  395. package/src/multistream/remoteMediaGroup.ts +4 -3
  396. package/src/multistream/remoteMediaManager.ts +230 -66
  397. package/src/networkQualityMonitor/{index.js → index.ts} +41 -29
  398. package/src/personal-meeting-room/{index.js → index.ts} +28 -19
  399. package/src/personal-meeting-room/{request.js → request.ts} +13 -4
  400. package/src/personal-meeting-room/{util.js → util.ts} +4 -4
  401. package/src/reachability/{index.js → index.ts} +157 -94
  402. package/src/reachability/request.ts +46 -35
  403. package/src/reactions/constants.ts +4 -0
  404. package/src/reactions/reactions.ts +104 -0
  405. package/src/reactions/reactions.type.ts +62 -0
  406. package/src/reconnection-manager/{index.js → index.ts} +228 -120
  407. package/src/recording-controller/enums.ts +8 -0
  408. package/src/recording-controller/index.ts +315 -0
  409. package/src/recording-controller/util.ts +58 -0
  410. package/src/roap/{index.js → index.ts} +77 -60
  411. package/src/roap/request.ts +172 -0
  412. package/src/roap/turnDiscovery.ts +81 -41
  413. package/src/statsAnalyzer/global.ts +37 -0
  414. package/src/statsAnalyzer/index.ts +1242 -0
  415. package/src/statsAnalyzer/mqaUtil.ts +291 -0
  416. package/src/transcription/{index.js → index.ts} +46 -39
  417. package/test/integration/spec/converged-space-meetings.js +176 -0
  418. package/test/integration/spec/journey.js +665 -464
  419. package/test/integration/spec/space-meeting.js +320 -206
  420. package/test/integration/spec/transcription.js +7 -8
  421. package/test/unit/spec/breakouts/breakout.ts +178 -0
  422. package/test/unit/spec/breakouts/collection.ts +15 -0
  423. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  424. package/test/unit/spec/breakouts/index.ts +1252 -0
  425. package/test/unit/spec/breakouts/request.ts +104 -0
  426. package/test/unit/spec/breakouts/utils.js +54 -0
  427. package/test/unit/spec/common/browser-detection.js +9 -28
  428. package/test/unit/spec/controls-options-manager/index.js +204 -0
  429. package/test/unit/spec/controls-options-manager/util.js +86 -0
  430. package/test/unit/spec/fixture/locus.js +92 -90
  431. package/test/unit/spec/locus-info/controlsUtils.js +133 -34
  432. package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
  433. package/test/unit/spec/locus-info/index.js +303 -2
  434. package/test/unit/spec/locus-info/infoUtils.js +41 -32
  435. package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
  436. package/test/unit/spec/locus-info/lib/SeqCmp.json +513 -685
  437. package/test/unit/spec/locus-info/parser.js +3 -9
  438. package/test/unit/spec/locus-info/selfConstant.js +101 -103
  439. package/test/unit/spec/locus-info/selfUtils.js +165 -12
  440. package/test/unit/spec/media/index.ts +72 -8
  441. package/test/unit/spec/media/properties.ts +9 -9
  442. package/test/unit/spec/meeting/in-meeting-actions.ts +29 -2
  443. package/test/unit/spec/meeting/index.js +2503 -802
  444. package/test/unit/spec/meeting/muteState.js +146 -61
  445. package/test/unit/spec/meeting/request.js +141 -43
  446. package/test/unit/spec/meeting/utils.js +135 -164
  447. package/test/unit/spec/meeting-info/meetinginfov2.js +100 -73
  448. package/test/unit/spec/meeting-info/request.js +7 -9
  449. package/test/unit/spec/meeting-info/util.js +11 -12
  450. package/test/unit/spec/meeting-info/utilv2.js +110 -74
  451. package/test/unit/spec/meetings/collection.js +15 -1
  452. package/test/unit/spec/meetings/index.js +622 -263
  453. package/test/unit/spec/meetings/utils.js +65 -14
  454. package/test/unit/spec/member/index.js +24 -1
  455. package/test/unit/spec/member/util.js +359 -32
  456. package/test/unit/spec/members/index.js +294 -54
  457. package/test/unit/spec/members/request.js +50 -20
  458. package/test/unit/spec/members/utils.js +147 -4
  459. package/test/unit/spec/metrics/index.js +16 -21
  460. package/test/unit/spec/multistream/mediaRequestManager.ts +369 -68
  461. package/test/unit/spec/multistream/receiveSlot.ts +76 -17
  462. package/test/unit/spec/multistream/receiveSlotManager.ts +60 -38
  463. package/test/unit/spec/multistream/remoteMedia.ts +32 -2
  464. package/test/unit/spec/multistream/remoteMediaGroup.ts +5 -5
  465. package/test/unit/spec/multistream/remoteMediaManager.ts +549 -65
  466. package/test/unit/spec/networkQualityMonitor/index.js +24 -18
  467. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -7
  468. package/test/unit/spec/reachability/index.ts +176 -27
  469. package/test/unit/spec/reachability/request.js +66 -0
  470. package/test/unit/spec/reconnection-manager/index.js +58 -30
  471. package/test/unit/spec/recording-controller/index.js +231 -0
  472. package/test/unit/spec/recording-controller/util.js +102 -0
  473. package/test/unit/spec/roap/index.ts +12 -8
  474. package/test/unit/spec/roap/request.ts +217 -0
  475. package/test/unit/spec/roap/turnDiscovery.ts +72 -49
  476. package/test/unit/spec/stats-analyzer/index.js +108 -57
  477. package/test/utils/cmr.js +44 -42
  478. package/test/utils/constants.js +9 -0
  479. package/test/utils/testUtils.js +98 -77
  480. package/test/utils/webex-config.js +22 -18
  481. package/test/utils/webex-test-users.js +57 -50
  482. package/tsconfig.json +6 -0
  483. package/dist/media/internal-media-core-wrapper.js +0 -22
  484. package/dist/media/internal-media-core-wrapper.js.map +0 -1
  485. package/dist/meeting/effectsState.js +0 -327
  486. package/dist/meeting/effectsState.js.map +0 -1
  487. package/dist/multistream/multistreamMedia.js +0 -116
  488. package/dist/multistream/multistreamMedia.js.map +0 -1
  489. package/dist/peer-connection-manager/util.js +0 -124
  490. package/dist/peer-connection-manager/util.js.map +0 -1
  491. package/src/common/logs/logger-proxy.js +0 -33
  492. package/src/locus-info/controlsUtils.js +0 -102
  493. package/src/media/internal-media-core-wrapper.ts +0 -9
  494. package/src/mediaQualityMetrics/config.js +0 -382
  495. package/src/meeting/effectsState.js +0 -205
  496. package/src/meeting-info/meeting-info-v2.js +0 -255
  497. package/src/meetings/index.js +0 -1015
  498. package/src/multistream/multistreamMedia.ts +0 -92
  499. package/src/peer-connection-manager/util.ts +0 -117
  500. package/src/roap/request.js +0 -127
  501. package/src/statsAnalyzer/global.js +0 -133
  502. package/src/statsAnalyzer/index.js +0 -1006
  503. package/src/statsAnalyzer/mqaUtil.js +0 -173
  504. package/test/unit/spec/meeting/effectsState.js +0 -291
  505. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -389
  506. /package/src/common/errors/{reconnection-in-progress.js → reconnection-in-progress.ts} +0 -0
@@ -0,0 +1,1275 @@
1
+ /* eslint no-shadow: ["error", { "allow": ["eventType"] }] */
2
+
3
+ import '@webex/internal-plugin-mercury';
4
+ import '@webex/internal-plugin-conversation';
5
+ // @ts-ignore
6
+ import {WebexPlugin} from '@webex/webex-core';
7
+ import {setLogger} from '@webex/internal-media-core';
8
+
9
+ import 'webrtc-adapter';
10
+
11
+ import Metrics from '../metrics';
12
+ import {trigger, eventType} from '../metrics/config';
13
+ import LoggerConfig from '../common/logs/logger-config';
14
+ import StaticConfig from '../common/config';
15
+ import LoggerProxy from '../common/logs/logger-proxy';
16
+ import LoggerRequest from '../common/logs/request';
17
+ import Trigger from '../common/events/trigger-proxy';
18
+ import Media from '../media';
19
+ import MeetingUtil from '../meeting/util';
20
+ import {
21
+ MEETINGS,
22
+ EVENTS,
23
+ EVENT_TRIGGERS,
24
+ READY,
25
+ LOCUSEVENT,
26
+ LOCUS_URL,
27
+ MAX_RANDOM_DELAY_FOR_MEETING_INFO,
28
+ ROAP,
29
+ ONLINE,
30
+ OFFLINE,
31
+ _MEETING_,
32
+ _JOIN_,
33
+ _LOCUS_ID_,
34
+ _INCOMING_,
35
+ LOCUS,
36
+ CORRELATION_ID,
37
+ SIP_URI,
38
+ _LEFT_,
39
+ _ID_,
40
+ MEETING_REMOVED_REASON,
41
+ _CONVERSATION_URL_,
42
+ CONVERSATION_URL,
43
+ MEETINGNUMBER,
44
+ BREAKOUTS,
45
+ _JOINED_,
46
+ _MOVED_,
47
+ } from '../constants';
48
+ import BEHAVIORAL_METRICS from '../metrics/constants';
49
+ import MeetingInfo from '../meeting-info';
50
+ import MeetingInfoV2 from '../meeting-info/meeting-info-v2';
51
+ import Meeting from '../meeting';
52
+ import PersonalMeetingRoom from '../personal-meeting-room';
53
+ import Reachability from '../reachability';
54
+ import Request from './request';
55
+ import PasswordError from '../common/errors/password-error';
56
+ import CaptchaError from '../common/errors/captcha-error';
57
+
58
+ import MeetingCollection from './collection';
59
+ import MeetingsUtil from './util';
60
+
61
+ let mediaLogger;
62
+
63
+ class MediaLogger {
64
+ info(...args) {
65
+ LoggerProxy.logger.info(...args);
66
+ }
67
+
68
+ log(...args) {
69
+ LoggerProxy.logger.log(...args);
70
+ }
71
+
72
+ error(...args) {
73
+ LoggerProxy.logger.error(...args);
74
+ }
75
+
76
+ warn(...args) {
77
+ LoggerProxy.logger.warn(...args);
78
+ }
79
+
80
+ trace(...args) {
81
+ LoggerProxy.logger.trace(...args);
82
+ }
83
+
84
+ debug(...args) {
85
+ LoggerProxy.logger.debug(...args);
86
+ }
87
+ }
88
+ /**
89
+ * Meetings Ready Event
90
+ * Emitted when the meetings instance on webex is ready
91
+ * @event meetings:ready
92
+ * @instance
93
+ * @memberof Meetings
94
+ */
95
+
96
+ /**
97
+ * Meetings Network Disconnected Event
98
+ * Emitted when the meetings instance is disconnected from
99
+ * the internal mercury server
100
+ * @event network:disconnected
101
+ * @instance
102
+ * @memberof Meetings
103
+ */
104
+
105
+ /**
106
+ * Meetings Registered Event
107
+ * Emitted when the meetings instance has been registered and listening
108
+ * @event meetings:registered
109
+ * @instance
110
+ * @memberof Meetings
111
+ */
112
+
113
+ /**
114
+ * Meeting Removed Event
115
+ * Emitted when a meeting was removed from the cache of meetings
116
+ * @event meeting:removed
117
+ * @instance
118
+ * @type {Object}
119
+ * @property {String} meetingId the removed meeting
120
+ * @property {Object} response the server response
121
+ * @property {String} type what type of meeting it was
122
+ * @memberof Meetings
123
+ */
124
+
125
+ /**
126
+ * Meeting Added Event
127
+ * Emitted when a meeting was added to the cache of meetings
128
+ * @event meeting:added
129
+ * @instance
130
+ * @type {Object}
131
+ * @property {String} meetingId the added meeting
132
+ * @property {String} type what type of meeting it was
133
+ * @memberof Meetings
134
+ */
135
+
136
+ /**
137
+ * Maintain a cache of meetings and sync with services.
138
+ * @class
139
+ */
140
+ export default class Meetings extends WebexPlugin {
141
+ loggerRequest: any;
142
+ media: any;
143
+ meetingCollection: any;
144
+ personalMeetingRoom: any;
145
+ preferredWebexSite: any;
146
+ reachability: any;
147
+ registered: any;
148
+ request: any;
149
+ geoHintInfo: any;
150
+ meetingInfo: any;
151
+
152
+ namespace = MEETINGS;
153
+
154
+ /**
155
+ * Initializes the Meetings Plugin
156
+ * @constructor
157
+ * @public
158
+ * @memberof Meetings
159
+ */
160
+ constructor(...args) {
161
+ super(...args);
162
+
163
+ /**
164
+ * The Meetings request to interact with server
165
+ * @instance
166
+ * @type {Object}
167
+ * @private
168
+ * @memberof Meetings
169
+ */
170
+ // @ts-ignore
171
+ this.request = new Request({}, {parent: this.webex});
172
+ /**
173
+ * Log upload request helper
174
+ * @instance
175
+ * @type {Object}
176
+ * @private
177
+ * @memberof Meetings
178
+ */
179
+ // @ts-ignore
180
+ this.loggerRequest = new LoggerRequest({webex: this.webex});
181
+ this.meetingCollection = new MeetingCollection();
182
+ /**
183
+ * The PersonalMeetingRoom object to interact with server
184
+ * @instance
185
+ * @type {Object}
186
+ * @public
187
+ * @memberof Meetings
188
+ */
189
+ this.personalMeetingRoom = null;
190
+ /**
191
+ * The Reachability object to interact with server, starts as null until {@link Meeting#setReachability} is called
192
+ * starts as null
193
+ * @instance
194
+ * @type {Object}
195
+ * @private
196
+ * @memberof Meetings
197
+ */
198
+ this.reachability = null;
199
+
200
+ /**
201
+ * If the meetings plugin has been registered and listening via {@link Meetings#register}
202
+ * @instance
203
+ * @type {Boolean}
204
+ * @public
205
+ * @memberof Meetings
206
+ */
207
+ this.registered = false;
208
+
209
+ /**
210
+ * This values indicates the preferred webex site the user will start there meeting, getsits value from {@link Meetings#register}
211
+ * @instance
212
+ * @type {String}
213
+ * @private
214
+ * @memberof Meetings
215
+ */
216
+ this.preferredWebexSite = '';
217
+
218
+ /**
219
+ * The public interface for the internal Media util files. These are helpful to expose outside the context
220
+ * of a meeting so that a user can access media without creating a meeting instance.
221
+ * @instance
222
+ * @type {Object}
223
+ * @private
224
+ * @memberof Meetings
225
+ */
226
+ this.media = {
227
+ getUserMedia: Media.getUserMedia,
228
+ getSupportedDevice: Media.getSupportedDevice,
229
+ };
230
+
231
+ this.onReady();
232
+ }
233
+
234
+ /**
235
+ * check whether you need to handle this main session's locus data or not
236
+ * @param {Object} meeting current meeting data
237
+ * @param {Object} newLocus new locus data
238
+ * @returns {boolean}
239
+ * @private
240
+ * @memberof Meetings
241
+ */
242
+ private isNeedHandleMainLocus(meeting: any, newLocus: any) {
243
+ const breakoutUrl = newLocus.controls?.breakout?.url;
244
+ const breakoutLocus = this.meetingCollection.getActiveBreakoutLocus(breakoutUrl);
245
+
246
+ const isSelfJoined = newLocus?.self?.state === _JOINED_;
247
+ const isSelfMoved = newLocus?.self?.state === _LEFT_ && newLocus?.self?.reason === _MOVED_;
248
+ const deviceFromNewLocus = MeetingsUtil.getThisDevice(newLocus);
249
+ const isNewLocusJoinThisDevice = MeetingsUtil.joinedOnThisDevice(meeting, newLocus);
250
+ const isBreakoutLocusJoinThisDevice =
251
+ breakoutLocus?.joinedWith?.correlationId &&
252
+ breakoutLocus.joinedWith.correlationId === meeting?.correlationId;
253
+
254
+ if (isSelfJoined && isNewLocusJoinThisDevice) {
255
+ LoggerProxy.logger.log(
256
+ 'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
257
+ );
258
+ if (breakoutLocus?.joinedWith && deviceFromNewLocus) {
259
+ const breakoutReplaceAt =
260
+ breakoutLocus.joinedWith.replaces?.length > 0
261
+ ? breakoutLocus.joinedWith.replaces[0].replaceAt
262
+ : '';
263
+ const newLocusReplaceAt =
264
+ deviceFromNewLocus.replaces?.length > 0 ? deviceFromNewLocus.replaces[0].replaceAt : '';
265
+ if (breakoutReplaceAt && newLocusReplaceAt && breakoutReplaceAt > newLocusReplaceAt) {
266
+ LoggerProxy.logger.log(
267
+ `Meetings:index#isNeedHandleMainLocus --> this is expired main joined status locus_dto replacedAt ${newLocusReplaceAt} bo replacedAt ${breakoutReplaceAt}`
268
+ );
269
+
270
+ return false;
271
+ }
272
+ }
273
+
274
+ return true;
275
+ }
276
+ if (isBreakoutLocusJoinThisDevice) {
277
+ LoggerProxy.logger.log(
278
+ `Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: ${breakoutUrl}`
279
+ );
280
+
281
+ return false;
282
+ }
283
+ if (isSelfMoved && newLocus?.self?.removed) {
284
+ LoggerProxy.logger.log(
285
+ 'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status, not need to handle'
286
+ );
287
+
288
+ return false;
289
+ }
290
+ LoggerProxy.logger.log(
291
+ 'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
292
+ );
293
+
294
+ return true;
295
+ }
296
+
297
+ /**
298
+ * check whether you need to handle this locus data or not
299
+ * @param {Object} meeting old locus data
300
+ * @param {Object} newLocus new locus data
301
+ * @returns {boolean}
302
+ * @private
303
+ * @memberof Meetings
304
+ */
305
+ private isNeedHandleLocusDTO(meeting: any, newLocus: any) {
306
+ if (newLocus) {
307
+ const isNewLocusAsBreakout =
308
+ newLocus.controls?.breakout?.sessionType === BREAKOUTS.SESSION_TYPES.BREAKOUT;
309
+ const isSelfMoved = newLocus?.self?.state === _LEFT_ && newLocus?.self?.reason === _MOVED_;
310
+ if (!meeting) {
311
+ if (isNewLocusAsBreakout) {
312
+ LoggerProxy.logger.log(
313
+ `Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: ${newLocus.fullState?.active}`
314
+ );
315
+
316
+ return newLocus.self?.state === _JOINED_;
317
+ }
318
+
319
+ return this.isNeedHandleMainLocus(meeting, newLocus);
320
+ }
321
+ if (!isNewLocusAsBreakout) {
322
+ return this.isNeedHandleMainLocus(meeting, newLocus);
323
+ }
324
+
325
+ return !isSelfMoved;
326
+ }
327
+
328
+ return true;
329
+ }
330
+
331
+ /**
332
+ * handle locus events and takes meeting actions with them as they come in
333
+ * @param {Object} data a locus event
334
+ * @param {String} data.locusUrl
335
+ * @param {Object} data.locus
336
+ * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
337
+ * @param {String} data.eventType
338
+ * @returns {undefined}
339
+ * @private
340
+ * @memberof Meetings
341
+ */
342
+ private handleLocusEvent(data: {locusUrl: string; locus: any}, useRandomDelayForInfo = false) {
343
+ let meeting = null;
344
+ // getting meeting by correlationId. This will happen for the new event
345
+ // Either the locus
346
+ // TODO : Add check for the callBack Address
347
+ meeting =
348
+ this.meetingCollection.getByKey(LOCUS_URL, data.locusUrl) ||
349
+ // @ts-ignore
350
+ this.meetingCollection.getByKey(
351
+ CORRELATION_ID,
352
+ // @ts-ignore
353
+ MeetingsUtil.checkForCorrelationId(this.webex.internal.device.url, data.locus)
354
+ ) ||
355
+ this.meetingCollection.getByKey(
356
+ SIP_URI,
357
+ data.locus.self &&
358
+ data.locus.self.callbackInfo &&
359
+ data.locus.self.callbackInfo.callbackAddress
360
+ ) ||
361
+ (data.locus.info?.isUnifiedSpaceMeeting
362
+ ? undefined
363
+ : this.meetingCollection.getByKey(CONVERSATION_URL, data.locus.conversationUrl)) ||
364
+ this.meetingCollection.getByKey(MEETINGNUMBER, data.locus?.info?.webExMeetingId);
365
+
366
+ // Special case when locus has got replaced, This only happend once if a replace locus exists
367
+ // https://sqbu-github.cisco.com/WebExSquared/locus/wiki/Locus-changing-mid-call
368
+
369
+ if (!meeting && data.locus?.replaces?.length > 0) {
370
+ // Always the last element in the replace is the active one
371
+ meeting = this.meetingCollection.getByKey(
372
+ LOCUS_URL,
373
+ data.locus.replaces[data.locus.replaces.length - 1].locusUrl
374
+ );
375
+ }
376
+
377
+ if (!this.isNeedHandleLocusDTO(meeting, data.locus)) {
378
+ LoggerProxy.logger.log(
379
+ `Meetings:index#handleLocusEvent --> doesn't need to process locus event`
380
+ );
381
+
382
+ return;
383
+ }
384
+ if (!meeting) {
385
+ // TODO: create meeting when we get a meeting object
386
+ // const checkForEnded = (locus) => {
387
+ // TODO: you already ended the meeting but you got an event later
388
+ // Mainly for 1:1 Callsor meeting
389
+ // Happens mainly after refresh
390
+
391
+ // 1:1 Meeting
392
+ // 1) You ended a call before but you got a mercury event
393
+ // Make sure end the call and cleanup the meeting only if the mercury
394
+ // event says so
395
+ // 2) Maintain lastSync time in the meetings object which helps to compare
396
+ // If the meeting came befor or after the sync . ANy meeting start time before the sync time is invalid
397
+
398
+ // For space Meeting
399
+ // Check the locus object and see who has joined
400
+
401
+ // };
402
+ // rather then locus object change to locus url
403
+
404
+ if (
405
+ data.locus &&
406
+ data.locus.fullState &&
407
+ data.locus.fullState.state === LOCUS.STATE.INACTIVE
408
+ ) {
409
+ // just ignore the event as its already ended and not active
410
+ LoggerProxy.logger.warn(
411
+ 'Meetings:index#handleLocusEvent --> Locus event received for meeting, after it was ended.'
412
+ );
413
+
414
+ return;
415
+ }
416
+
417
+ // When its wireless share or guest and user leaves the meeting we dont have to keep the meeting object
418
+ // Any future events will be neglected
419
+
420
+ if (
421
+ data.locus &&
422
+ data.locus.self &&
423
+ data.locus.self.state === _LEFT_ &&
424
+ data.locus.self.removed === true
425
+ ) {
426
+ // just ignore the event as its already ended and not active
427
+ LoggerProxy.logger.warn(
428
+ 'Meetings:index#handleLocusEvent --> Locus event received for meeting, after it was ended.'
429
+ );
430
+
431
+ return;
432
+ }
433
+
434
+ this.create(data.locus, _LOCUS_ID_, useRandomDelayForInfo)
435
+ .then((newMeeting) => {
436
+ meeting = newMeeting;
437
+
438
+ // It's a new meeting so initialize the locus data
439
+ meeting.locusInfo.initialSetup(data.locus);
440
+ })
441
+ .catch((e) => {
442
+ LoggerProxy.logger.error(e);
443
+ })
444
+ .finally(() => {
445
+ // There will be cases where locus event comes in gets created and deleted because its a 1:1 and meeting gets deleted
446
+ // because the other user left so before sending 'added' event make sure it exists in the collection
447
+
448
+ if (this.getMeetingByType(_ID_, meeting.id)) {
449
+ Metrics.postEvent({
450
+ event: eventType.REMOTE_STARTED,
451
+ meeting,
452
+ data: {trigger: trigger.MERCURY_EVENT},
453
+ });
454
+ Trigger.trigger(
455
+ this,
456
+ {
457
+ file: 'meetings',
458
+ function: 'handleLocusEvent',
459
+ },
460
+ EVENT_TRIGGERS.MEETING_ADDED,
461
+ {
462
+ meeting,
463
+ type: meeting.type === _MEETING_ ? _JOIN_ : _INCOMING_,
464
+ }
465
+ );
466
+ } else {
467
+ // Meeting got added but was not found in the collection. It might have got destroyed
468
+ LoggerProxy.logger.warn(
469
+ 'Meetings:index#handleLocusEvent --> Created and destroyed meeting object before sending an event'
470
+ );
471
+ }
472
+ });
473
+ } else {
474
+ meeting.locusInfo.parse(meeting, data);
475
+ }
476
+ }
477
+
478
+ /**
479
+ * handles locus events through mercury that are not roap
480
+ * @param {Object} envelope
481
+ * @param {Object} envelope.data
482
+ * @param {String} envelope.data.eventType
483
+ * @returns {undefined}
484
+ * @private
485
+ * @memberof Meetings
486
+ */
487
+ private handleLocusMercury(envelope: {data: any}) {
488
+ const {data} = envelope;
489
+ // eslint-disable-next-line @typescript-eslint/no-shadow
490
+ const {eventType} = data;
491
+
492
+ if (eventType && eventType !== LOCUSEVENT.MESSAGE_ROAP) {
493
+ this.handleLocusEvent(data, true);
494
+ }
495
+ }
496
+
497
+ /**
498
+ * handles mecury offline event
499
+ * @returns {undefined}
500
+ * @private
501
+ * @memberof Meetings
502
+ */
503
+ private handleMercuryOffline() {
504
+ Trigger.trigger(
505
+ this,
506
+ {
507
+ file: 'meetings/index',
508
+ function: 'handleMercuryOffline',
509
+ },
510
+ EVENT_TRIGGERS.MEETINGS_NETWORK_DISCONNECTED
511
+ );
512
+ }
513
+
514
+ /**
515
+ * registers for locus and roap mercury events
516
+ * @returns {undefined}
517
+ * @private
518
+ * @memberof Meetings
519
+ */
520
+ private listenForEvents() {
521
+ // @ts-ignore
522
+ this.webex.internal.mercury.on(LOCUSEVENT.LOCUS_MERCURY, (envelope) => {
523
+ this.handleLocusMercury(envelope);
524
+ });
525
+ // @ts-ignore
526
+ this.webex.internal.mercury.on(ROAP.ROAP_MERCURY, (envelope) => {
527
+ MeetingsUtil.handleRoapMercury(envelope, this.meetingCollection);
528
+ });
529
+
530
+ // @ts-ignore
531
+ this.webex.internal.mercury.on(ONLINE, () => {
532
+ this.syncMeetings();
533
+ });
534
+
535
+ // @ts-ignore
536
+ this.webex.internal.mercury.on(OFFLINE, () => {
537
+ this.handleMercuryOffline();
538
+ });
539
+ }
540
+
541
+ /**
542
+ * stops listening for locus and roap mercury events
543
+ * @returns {undefined}
544
+ * @private
545
+ * @memberof Meetings
546
+ */
547
+ private stopListeningForEvents() {
548
+ // @ts-ignore
549
+ this.webex.internal.mercury.off(LOCUSEVENT.LOCUS_MERCURY);
550
+ // @ts-ignore
551
+ this.webex.internal.mercury.off(ROAP.ROAP_MERCURY);
552
+ // @ts-ignore
553
+ this.webex.internal.mercury.off(ONLINE);
554
+ }
555
+
556
+ /**
557
+ * @returns {undefined}
558
+ * @private
559
+ * @memberof Meetings
560
+ */
561
+ private onReady() {
562
+ // @ts-ignore
563
+ this.webex.once(READY, () => {
564
+ // @ts-ignore
565
+ StaticConfig.set(this.config);
566
+ // @ts-ignore
567
+ LoggerConfig.set(this.config.logging);
568
+ // @ts-ignore
569
+ LoggerProxy.set(this.webex.logger);
570
+
571
+ mediaLogger = new MediaLogger();
572
+ setLogger(mediaLogger);
573
+
574
+ /**
575
+ * The MeetingInfo object to interact with server
576
+ * @instance
577
+ * @type {Object}
578
+ * @private
579
+ * @memberof Meetings
580
+ */
581
+ // @ts-ignore
582
+ this.meetingInfo = this.config.experimental.enableUnifiedMeetings
583
+ ? // @ts-ignore
584
+ new MeetingInfoV2(this.webex)
585
+ : // @ts-ignore
586
+ new MeetingInfo(this.webex);
587
+ // @ts-ignore
588
+ this.personalMeetingRoom = new PersonalMeetingRoom(
589
+ {meetingInfo: this.meetingInfo},
590
+ // @ts-ignore
591
+ {parent: this.webex}
592
+ );
593
+
594
+ Trigger.trigger(
595
+ this,
596
+ {
597
+ file: 'meetings',
598
+ function: 'onReady',
599
+ },
600
+ EVENT_TRIGGERS.MEETINGS_READY
601
+ );
602
+
603
+ MeetingsUtil.checkH264Support({disableNotifications: true});
604
+ // @ts-ignore
605
+ Metrics.initialSetup(this.meetingCollection, this.webex);
606
+ });
607
+ }
608
+
609
+ /**
610
+ * API to toggle unified meetings
611
+ * @param {Boolean} changeState
612
+ * @private
613
+ * @memberof Meetings
614
+ * @returns {undefined}
615
+ */
616
+ private _toggleUnifiedMeetings(changeState: boolean) {
617
+ if (typeof changeState !== 'boolean') {
618
+ return;
619
+ }
620
+ // @ts-ignore
621
+ if (this.config?.experimental?.enableUnifiedMeetings !== changeState) {
622
+ // @ts-ignore
623
+ this.config.experimental.enableUnifiedMeetings = changeState;
624
+ // @ts-ignore
625
+ this.meetingInfo = changeState ? new MeetingInfoV2(this.webex) : new MeetingInfo(this.webex);
626
+ }
627
+ }
628
+
629
+ /**
630
+ * API to enable or disable TURN discovery
631
+ * @param {Boolean} enable
632
+ * @private
633
+ * @memberof Meetings
634
+ * @returns {undefined}
635
+ */
636
+ private _toggleTurnDiscovery(enable: boolean) {
637
+ if (typeof enable !== 'boolean') {
638
+ return;
639
+ }
640
+ // @ts-ignore
641
+ this.config.experimental.enableTurnDiscovery = enable;
642
+ }
643
+
644
+ /**
645
+ * API to toggle starting adhoc meeting
646
+ * @param {Boolean} changeState
647
+ * @private
648
+ * @memberof Meetings
649
+ * @returns {undefined}
650
+ */
651
+ private _toggleAdhocMeetings(changeState: boolean) {
652
+ if (typeof changeState !== 'boolean') {
653
+ return;
654
+ }
655
+ // @ts-ignore
656
+ if (this.config?.experimental?.enableAdhocMeetings !== changeState) {
657
+ // @ts-ignore
658
+ this.config.experimental.enableAdhocMeetings = changeState;
659
+ }
660
+ }
661
+
662
+ /**
663
+ * Explicitly sets up the meetings plugin by registering
664
+ * the device, connecting to mercury, and listening for locus events.
665
+ *
666
+ * @returns {Promise}
667
+ * @public
668
+ * @memberof Meetings
669
+ */
670
+ public register() {
671
+ // @ts-ignore
672
+ if (!this.webex.canAuthorize) {
673
+ LoggerProxy.logger.error(
674
+ 'Meetings:index#register --> ERROR, Unable to register, SDK cannot authorize'
675
+ );
676
+
677
+ return Promise.reject(new Error('SDK cannot authorize'));
678
+ }
679
+
680
+ if (this.registered) {
681
+ LoggerProxy.logger.info(
682
+ 'Meetings:index#register --> INFO, Meetings plugin already registered'
683
+ );
684
+
685
+ return Promise.resolve();
686
+ }
687
+
688
+ return Promise.all([
689
+ this.fetchUserPreferredWebexSite(),
690
+ this.getGeoHint(),
691
+ this.startReachability().catch((error) => {
692
+ LoggerProxy.logger.error(`Meetings:index#register --> GDM error, ${error.message}`);
693
+ }),
694
+ // @ts-ignore
695
+ this.webex.internal.device
696
+ .register()
697
+ // @ts-ignore
698
+ .then(() =>
699
+ LoggerProxy.logger.info(
700
+ // @ts-ignore
701
+ `Meetings:index#register --> INFO, Device registered ${this.webex.internal.device.url}`
702
+ )
703
+ )
704
+ // @ts-ignore
705
+ .then(() => this.webex.internal.mercury.connect()),
706
+ MeetingsUtil.checkH264Support.call(this),
707
+ ])
708
+ .then(() => {
709
+ this.listenForEvents();
710
+ Trigger.trigger(
711
+ this,
712
+ {
713
+ file: 'meetings',
714
+ function: 'register',
715
+ },
716
+ EVENT_TRIGGERS.MEETINGS_REGISTERED
717
+ );
718
+ this.registered = true;
719
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETINGS_REGISTRATION_SUCCESS);
720
+ })
721
+ .catch((error) => {
722
+ LoggerProxy.logger.error(
723
+ `Meetings:index#register --> ERROR, Unable to register, ${error.message}`
724
+ );
725
+
726
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETINGS_REGISTRATION_FAILED, {
727
+ reason: error.message,
728
+ stack: error.stack,
729
+ });
730
+
731
+ return Promise.reject(error);
732
+ });
733
+ }
734
+
735
+ /**
736
+ * Explicitly tears down the meetings plugin by deregistering
737
+ * the device, disconnecting from mercury, and stops listening to locus events
738
+ *
739
+ * @returns {Promise}
740
+ * @public
741
+ * @memberof Meetings
742
+ */
743
+ unregister() {
744
+ if (!this.registered) {
745
+ LoggerProxy.logger.info(
746
+ 'Meetings:index#unregister --> INFO, Meetings plugin already unregistered'
747
+ );
748
+
749
+ return Promise.resolve();
750
+ }
751
+
752
+ this.stopListeningForEvents();
753
+
754
+ return (
755
+ // @ts-ignore
756
+ this.webex.internal.mercury
757
+ .disconnect()
758
+ // @ts-ignore
759
+ .then(() => this.webex.internal.device.unregister())
760
+ .then(() => {
761
+ Trigger.trigger(
762
+ this,
763
+ {
764
+ file: 'meetings',
765
+ function: 'unregister',
766
+ },
767
+ EVENT_TRIGGERS.MEETINGS_UNREGISTERED
768
+ );
769
+ this.registered = false;
770
+ })
771
+ );
772
+ }
773
+
774
+ /**
775
+ * Uploads logs to the webex services for tracking
776
+ * @param {Object} [options={}]
777
+ * @param {String} [options.callStart] Call Start Time
778
+ * @param {String} [options.feedbackId] ID used for tracking
779
+ * @param {String} [options.locusId]
780
+ * @param {String} [options.correlationId]
781
+ * @param {String} [options.meetingId] webex meeting ID
782
+ * @param {String} [options.userId] userId
783
+ * @param {String} [options.orgId] org id
784
+ * @returns {String} feedback ID logs were submitted under
785
+ */
786
+ uploadLogs(
787
+ options: {
788
+ callStart?: string;
789
+ feedbackId?: string;
790
+ locusId?: string;
791
+ correlationId?: string;
792
+ meetingId?: string;
793
+ userId?: string;
794
+ orgId?: string;
795
+ } = {}
796
+ ) {
797
+ LoggerProxy.logger.info('Meetings:index#uploadLogs --> uploading logs');
798
+
799
+ return this.loggerRequest
800
+ .uploadLogs(options)
801
+ .then((uploadResult) => {
802
+ LoggerProxy.logger.info(
803
+ 'Meetings:index#uploadLogs --> Upload logs for meeting completed.',
804
+ uploadResult
805
+ );
806
+ Trigger.trigger(
807
+ this,
808
+ {
809
+ file: 'meetings',
810
+ function: 'uploadLogs',
811
+ },
812
+ EVENT_TRIGGERS.MEETING_LOG_UPLOAD_SUCCESS,
813
+ {
814
+ meetingId: options.meetingId,
815
+ details: uploadResult,
816
+ }
817
+ );
818
+
819
+ return uploadResult;
820
+ })
821
+ .catch((uploadError) => {
822
+ LoggerProxy.logger.error(
823
+ 'Meetings:index#uploadLogs --> Unable to upload logs for meeting',
824
+ uploadError
825
+ );
826
+ Trigger.trigger(
827
+ this,
828
+ {
829
+ file: 'meetings',
830
+ function: 'uploadLogs',
831
+ },
832
+ EVENT_TRIGGERS.MEETING_LOG_UPLOAD_FAILURE,
833
+ {
834
+ meetingId: options.meetingId,
835
+ reason: uploadError,
836
+ }
837
+ );
838
+
839
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UPLOAD_LOGS_FAILURE, {
840
+ // @ts-ignore - seems like typo
841
+ meetingId: options.meetingsId,
842
+ reason: uploadError.message,
843
+ stack: uploadError.stack,
844
+ code: uploadError.code,
845
+ });
846
+ });
847
+ }
848
+
849
+ /**
850
+ * initializes the reachability instance for Meetings
851
+ * @returns {undefined}
852
+ * @public
853
+ * @memberof Meetings
854
+ */
855
+ setReachability() {
856
+ // @ts-ignore
857
+ this.reachability = new Reachability(this.webex);
858
+ }
859
+
860
+ /**
861
+ * gets the reachability instance for Meetings
862
+ * @returns {Reachability}
863
+ * @public
864
+ * @memberof Meetings
865
+ */
866
+ getReachability() {
867
+ return this.reachability;
868
+ }
869
+
870
+ /**
871
+ * initializes and starts gathering reachability for Meetings
872
+ * @returns {Promise}
873
+ * @public
874
+ * @memberof Meetings
875
+ */
876
+ startReachability() {
877
+ if (!this.reachability) {
878
+ this.setReachability();
879
+ }
880
+
881
+ return this.getReachability().gatherReachability();
882
+ }
883
+
884
+ /**
885
+ * Get geoHint for info for meetings
886
+ * @returns {Promise}
887
+ * @private
888
+ * @memberof Meetings
889
+ */
890
+ getGeoHint() {
891
+ return this.request.fetchGeoHint().then((res) => {
892
+ this.geoHintInfo = res;
893
+ });
894
+ }
895
+
896
+ /**
897
+ * Fetch user preferred webex site information
898
+ * This also has other infomation about the user
899
+ * @returns {Promise}
900
+ * @private
901
+ * @memberof Meetings
902
+ */
903
+ fetchUserPreferredWebexSite() {
904
+ return this.request.getMeetingPreferences().then((res) => {
905
+ if (res) {
906
+ this.preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
907
+ }
908
+ });
909
+ }
910
+
911
+ /**
912
+ * gets the personal meeting room instance, for saved PMR values for this user
913
+ * @returns {PersonalMeetingRoom}
914
+ * @public
915
+ * @memberof Meetings
916
+ */
917
+
918
+ getPersonalMeetingRoom() {
919
+ return this.personalMeetingRoom;
920
+ }
921
+
922
+ /**
923
+ * @param {Meeting} meeting
924
+ * @param {Object} reason
925
+ * @param {String} type
926
+ * @returns {Undefined}
927
+ * @private
928
+ * @memberof Meetings
929
+ */
930
+ private destroy(meeting: Meeting, reason: object) {
931
+ MeetingUtil.cleanUp(meeting);
932
+ this.meetingCollection.delete(meeting.id);
933
+ Trigger.trigger(
934
+ this,
935
+ {
936
+ file: 'meetings',
937
+ function: 'destroy',
938
+ },
939
+ EVENT_TRIGGERS.MEETING_REMOVED,
940
+ {
941
+ meetingId: meeting.id,
942
+ reason,
943
+ }
944
+ );
945
+ }
946
+
947
+ /**
948
+ * Create a meeting.
949
+ * @param {string} destination - sipURL, spaceId, phonenumber, or locus object}
950
+ * @param {string} [type] - the optional specified type, such as locusId
951
+ * @param {Boolean} useRandomDelayForInfo - whether a random delay should be added to fetching meeting info
952
+ * @returns {Promise<Meeting>} A new Meeting.
953
+ * @public
954
+ * @memberof Meetings
955
+ */
956
+ public create(destination: string, type: string = null, useRandomDelayForInfo = false) {
957
+ // TODO: type should be from a dictionary
958
+
959
+ // Validate meeting information based on the provided destination and
960
+ // type. This must be performed prior to determining if the meeting is
961
+ // found in the collection, as we mutate the destination for hydra person
962
+ // id values.
963
+ return (
964
+ this.meetingInfo
965
+ .fetchInfoOptions(destination, type)
966
+ // Catch a failure to fetch info options.
967
+ .catch((error) => {
968
+ LoggerProxy.logger.info(
969
+ `Meetings:index#create --> INFO, unable to determine info options: ${error.message}`
970
+ );
971
+ })
972
+ .then((options: any = {}) => {
973
+ // Normalize the destination.
974
+ const targetDest = options.destination || destination;
975
+
976
+ // check for the conversation URL then sip Url
977
+ let meeting = null;
978
+
979
+ if (type === _CONVERSATION_URL_ || options.type === _CONVERSATION_URL_) {
980
+ const foundMeeting = this.meetingCollection.getByKey(CONVERSATION_URL, targetDest);
981
+
982
+ if (foundMeeting) {
983
+ const foundMeetingIsNotCalendarMeeting = !foundMeeting.locusInfo.scheduledMeeting;
984
+
985
+ // If the found meeting is not a calendar meeting, return that meeting.
986
+ // This allows for the creation of instant-meetings when calendar meetings are present.
987
+ if (foundMeetingIsNotCalendarMeeting) {
988
+ meeting = foundMeeting;
989
+ }
990
+ }
991
+ }
992
+
993
+ // Attempt to collect the meeting if it exists.
994
+ if (!meeting) {
995
+ meeting = this.meetingCollection.getByKey(SIP_URI, targetDest);
996
+ }
997
+
998
+ // Validate if a meeting was found.
999
+ if (!meeting) {
1000
+ // Create a meeting based on the normalized destination and type.
1001
+ return this.createMeeting(targetDest, type, useRandomDelayForInfo).then(
1002
+ (createdMeeting: any) => {
1003
+ // If the meeting was successfully created.
1004
+ if (createdMeeting && createdMeeting.on) {
1005
+ // Create a destruction event for the meeting.
1006
+ createdMeeting.on(EVENTS.DESTROY_MEETING, (payload) => {
1007
+ // @ts-ignore
1008
+ if (this.config.autoUploadLogs) {
1009
+ this.uploadLogs({
1010
+ callStart: createdMeeting.locusInfo?.fullState?.lastActive,
1011
+ correlationId: createdMeeting.correlationId,
1012
+ feedbackId: createdMeeting.correlationId,
1013
+ locusId: createdMeeting.locusId,
1014
+ meetingId: createdMeeting.locusInfo?.info?.webExMeetingId,
1015
+ }).then(() => this.destroy(createdMeeting, payload.reason));
1016
+ } else {
1017
+ this.destroy(createdMeeting, payload.reason);
1018
+ }
1019
+ });
1020
+
1021
+ createdMeeting.on(EVENTS.REQUEST_UPLOAD_LOGS, (meetingInstance) => {
1022
+ // @ts-ignore
1023
+ if (this.config.autoUploadLogs) {
1024
+ this.uploadLogs({
1025
+ callStart: meetingInstance?.locusInfo?.fullState?.lastActive,
1026
+ correlationId: meetingInstance.correlationId,
1027
+ feedbackId: meetingInstance.correlationId,
1028
+ locusId: meetingInstance.locusId,
1029
+ meetingId: meetingInstance.locusInfo?.info?.webExMeetingId,
1030
+ });
1031
+ }
1032
+ });
1033
+ } else {
1034
+ LoggerProxy.logger.error(
1035
+ `Meetings:index#create --> ERROR, meeting does not have on method, will not be destroyed, meeting cleanup impossible for meeting: ${meeting}`
1036
+ );
1037
+ }
1038
+
1039
+ // Return the newly created meeting.
1040
+ return Promise.resolve(createdMeeting);
1041
+ }
1042
+ );
1043
+ }
1044
+
1045
+ // Return the existing meeting.
1046
+ return Promise.resolve(meeting);
1047
+ })
1048
+ );
1049
+ }
1050
+
1051
+ /**
1052
+ * @param {String} destination see create()
1053
+ * @param {String} type see create()
1054
+ * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
1055
+ * @returns {Promise} a new meeting instance complete with meeting info and destination
1056
+ * @private
1057
+ * @memberof Meetings
1058
+ */
1059
+ private async createMeeting(
1060
+ destination: any,
1061
+ type: string = null,
1062
+ useRandomDelayForInfo = false
1063
+ ) {
1064
+ const meeting = new Meeting(
1065
+ {
1066
+ // @ts-ignore
1067
+ userId: this.webex.internal.device.userId,
1068
+ // @ts-ignore
1069
+ deviceUrl: this.webex.internal.device.url,
1070
+ // @ts-ignore
1071
+ orgId: this.webex.internal.device.orgId,
1072
+ locus: type === _LOCUS_ID_ ? destination : null, // pass the locus object if present
1073
+ meetingInfoProvider: this.meetingInfo,
1074
+ destination,
1075
+ destinationType: type,
1076
+ },
1077
+ {
1078
+ // @ts-ignore
1079
+ parent: this.webex,
1080
+ }
1081
+ );
1082
+
1083
+ this.meetingCollection.set(meeting);
1084
+
1085
+ try {
1086
+ // if no participant has joined the scheduled meeting (meaning meeting is not active) and we get a locusEvent,
1087
+ // it means the meeting will start in 5-6 min. In that case, we want to fetchMeetingInfo
1088
+ // between 5 and 2 min (random between 3 minutes) before the meeting starts
1089
+ // to avoid a spike in traffic to the wbxappi service
1090
+ let waitingTime = 0;
1091
+
1092
+ if (destination.meeting) {
1093
+ const {startTime} = destination.meeting;
1094
+ const startTimeDate = new Date(startTime);
1095
+ const startTimeDatestamp = startTimeDate.getTime();
1096
+ const timeToStart = startTimeDatestamp - Date.now();
1097
+ const maxWaitingTime = Math.max(
1098
+ Math.min(timeToStart, MAX_RANDOM_DELAY_FOR_MEETING_INFO),
1099
+ 0
1100
+ );
1101
+
1102
+ waitingTime = Math.round(Math.random() * maxWaitingTime);
1103
+ }
1104
+ const isMeetingActive = !!destination.fullState?.active;
1105
+ // @ts-ignore
1106
+ const {enableUnifiedMeetings} = this.config.experimental;
1107
+
1108
+ if (enableUnifiedMeetings && !isMeetingActive && useRandomDelayForInfo && waitingTime > 0) {
1109
+ meeting.fetchMeetingInfoTimeoutId = setTimeout(
1110
+ () => meeting.fetchMeetingInfo({}),
1111
+ waitingTime
1112
+ );
1113
+ meeting.parseMeetingInfo(undefined, destination);
1114
+ } else {
1115
+ await meeting.fetchMeetingInfo({});
1116
+ }
1117
+ } catch (err) {
1118
+ if (!(err instanceof CaptchaError) && !(err instanceof PasswordError)) {
1119
+ // if there is no meeting info we assume its a 1:1 call or wireless share
1120
+ LoggerProxy.logger.info(
1121
+ `Meetings:index#createMeeting --> Info Unable to fetch meeting info for ${destination}.`
1122
+ );
1123
+ LoggerProxy.logger.info(
1124
+ 'Meetings:index#createMeeting --> Info assuming this destination is a 1:1 or wireless share'
1125
+ );
1126
+ }
1127
+ LoggerProxy.logger.debug(
1128
+ `Meetings:index#createMeeting --> Debug ${err} fetching /meetingInfo for creation.`
1129
+ );
1130
+ } finally {
1131
+ // For type LOCUS_ID we need to parse the locus object to get the information
1132
+ // about the caller and callee
1133
+ // Meeting Added event will be created in `handleLocusEvent`
1134
+ if (type !== _LOCUS_ID_) {
1135
+ if (!meeting.sipUri) {
1136
+ meeting.setSipUri(destination);
1137
+ }
1138
+
1139
+ // TODO: check if we have to move this to parser
1140
+ const meetingAddedType = MeetingsUtil.getMeetingAddedType(type);
1141
+
1142
+ // We typically shouldn't need to trigger both and event and return a promise.
1143
+ // Is this a special case? We want to make the public API usage as simple as possible.
1144
+ Trigger.trigger(
1145
+ this,
1146
+ {
1147
+ file: 'meetings',
1148
+ function: 'createMeeting',
1149
+ },
1150
+ EVENT_TRIGGERS.MEETING_ADDED,
1151
+ {
1152
+ meeting,
1153
+ type: meetingAddedType,
1154
+ }
1155
+ );
1156
+ }
1157
+ }
1158
+
1159
+ return meeting;
1160
+
1161
+ // Create the meeting calling the necessary service endpoints.
1162
+
1163
+ // Internally, there are many more destinations:
1164
+ //
1165
+ // - locusID
1166
+ // - meetingURL
1167
+ // - globalMeetingID, e.g, *00*meetingID
1168
+ // - meetingID
1169
+ // - meetingURL
1170
+ // - PSTN
1171
+ // - phone number
1172
+ //
1173
+ // Our job is to determine the appropriate one
1174
+ // and its corresponding service so that developers
1175
+ // need only sipURL or spaceID to get a meeting
1176
+ // and its ID, but have the option to use createWithType()
1177
+ // and specify those types to get meetingInfo
1178
+ }
1179
+
1180
+ /**
1181
+ * get a specifc meeting given it's type matched to the value, i.e., locus url
1182
+ * @param {String} type
1183
+ * @param {Object} value
1184
+ * @returns {Meeting}
1185
+ * @public
1186
+ * @memberof Meetings
1187
+ */
1188
+ public getMeetingByType(type: string, value: object) {
1189
+ return this.meetingCollection.getByKey(type, value);
1190
+ }
1191
+
1192
+ /**
1193
+ * Get all meetings.
1194
+ * @param {object} options
1195
+ * @param {object} options.startDate - get meetings after this start date
1196
+ * @param {object} options.endDate - get meetings before this end date
1197
+ * @returns {Object} All currently active meetings.
1198
+ * @public
1199
+ * @memberof Meetings
1200
+ */
1201
+ public getAllMeetings(
1202
+ options: {
1203
+ startDate: object;
1204
+ endDate: object;
1205
+ } = {} as any
1206
+ ) {
1207
+ // Options may include other parameters to filter this collection
1208
+ // of meetings.
1209
+ return this.meetingCollection.getAll(options);
1210
+ }
1211
+
1212
+ /**
1213
+ * syncs all the meeting from server
1214
+ * @returns {undefined}
1215
+ * @public
1216
+ * @memberof Meetings
1217
+ */
1218
+ public syncMeetings() {
1219
+ return this.request
1220
+ .getActiveMeetings()
1221
+ .then((locusArray) => {
1222
+ const activeLocusUrl = [];
1223
+
1224
+ if (locusArray?.loci && locusArray.loci.length > 0) {
1225
+ locusArray.loci.forEach((locus) => {
1226
+ activeLocusUrl.push(locus.url);
1227
+ this.handleLocusEvent({
1228
+ locus,
1229
+ locusUrl: locus.url,
1230
+ });
1231
+ });
1232
+ }
1233
+ const meetingsCollection = this.meetingCollection.getAll();
1234
+
1235
+ if (Object.keys(meetingsCollection).length > 0) {
1236
+ // Some time the mercury event is missed after mercury reconnect
1237
+ // if sync returns no locus then clear all the meetings
1238
+ for (const meeting of Object.values(meetingsCollection)) {
1239
+ // @ts-ignore
1240
+ if (!activeLocusUrl.includes(meeting.locusUrl)) {
1241
+ // destroy function also uploads logs
1242
+ // @ts-ignore
1243
+ this.destroy(meeting, MEETING_REMOVED_REASON.NO_MEETINGS_TO_SYNC);
1244
+ }
1245
+ }
1246
+ }
1247
+ })
1248
+ .catch((error) => {
1249
+ LoggerProxy.logger.error(
1250
+ `Meetings:index#syncMeetings --> failed to sync meetings, ${error}`
1251
+ );
1252
+ throw new Error(error);
1253
+ });
1254
+ }
1255
+
1256
+ /**
1257
+ * Get all scheduled meetings.
1258
+ * @param {object} options
1259
+ * @param {object} options.startDate - get meetings after this start date
1260
+ * @param {object} options.endDate - get meetings before this end date
1261
+ * @returns {Object} All scheduled meetings.
1262
+ * @memberof Meetings
1263
+ */
1264
+ getScheduledMeetings() {
1265
+ return this.meetingCollection.getAll({scheduled: true});
1266
+ }
1267
+
1268
+ /**
1269
+ * Get the logger instance for plugin-meetings
1270
+ * @returns {Logger}
1271
+ */
1272
+ getLogger() {
1273
+ return LoggerProxy.get();
1274
+ }
1275
+ }