@webex/plugin-meetings 3.0.0-beta.2 → 3.0.0-beta.200

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 (576) hide show
  1. package/README.md +45 -7
  2. package/UPGRADING.md +9 -9
  3. package/browsers.js +19 -24
  4. package/dist/annotation/annotation.types.js +7 -0
  5. package/dist/annotation/annotation.types.js.map +1 -0
  6. package/dist/annotation/constants.js +49 -0
  7. package/dist/annotation/constants.js.map +1 -0
  8. package/dist/annotation/index.js +342 -0
  9. package/dist/annotation/index.js.map +1 -0
  10. package/dist/breakouts/breakout.js +216 -0
  11. package/dist/breakouts/breakout.js.map +1 -0
  12. package/dist/breakouts/collection.js +23 -0
  13. package/dist/breakouts/collection.js.map +1 -0
  14. package/dist/breakouts/edit-lock-error.js +52 -0
  15. package/dist/breakouts/edit-lock-error.js.map +1 -0
  16. package/dist/breakouts/events.js +45 -0
  17. package/dist/breakouts/events.js.map +1 -0
  18. package/dist/breakouts/index.js +1048 -0
  19. package/dist/breakouts/index.js.map +1 -0
  20. package/dist/breakouts/request.js +78 -0
  21. package/dist/breakouts/request.js.map +1 -0
  22. package/dist/breakouts/utils.js +67 -0
  23. package/dist/breakouts/utils.js.map +1 -0
  24. package/dist/common/browser-detection.js +1 -20
  25. package/dist/common/browser-detection.js.map +1 -1
  26. package/dist/common/collection.js +5 -20
  27. package/dist/common/collection.js.map +1 -1
  28. package/dist/common/config.js +0 -7
  29. package/dist/common/config.js.map +1 -1
  30. package/dist/common/errors/captcha-error.js +10 -24
  31. package/dist/common/errors/captcha-error.js.map +1 -1
  32. package/dist/common/errors/intent-to-join.js +11 -24
  33. package/dist/common/errors/intent-to-join.js.map +1 -1
  34. package/dist/common/errors/join-meeting.js +12 -25
  35. package/dist/common/errors/join-meeting.js.map +1 -1
  36. package/dist/common/errors/media.js +10 -24
  37. package/dist/common/errors/media.js.map +1 -1
  38. package/dist/common/errors/parameter.js +5 -33
  39. package/dist/common/errors/parameter.js.map +1 -1
  40. package/dist/common/errors/password-error.js +10 -24
  41. package/dist/common/errors/password-error.js.map +1 -1
  42. package/dist/common/errors/permission.js +9 -23
  43. package/dist/common/errors/permission.js.map +1 -1
  44. package/dist/common/errors/reconnection-in-progress.js +0 -17
  45. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  46. package/dist/common/errors/reconnection.js +10 -24
  47. package/dist/common/errors/reconnection.js.map +1 -1
  48. package/dist/common/errors/stats.js +10 -24
  49. package/dist/common/errors/stats.js.map +1 -1
  50. package/dist/common/errors/webex-errors.js +9 -43
  51. package/dist/common/errors/webex-errors.js.map +1 -1
  52. package/dist/common/errors/webex-meetings-error.js +5 -25
  53. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  54. package/dist/common/events/events-scope.js +0 -22
  55. package/dist/common/events/events-scope.js.map +1 -1
  56. package/dist/common/events/events.js +0 -23
  57. package/dist/common/events/events.js.map +1 -1
  58. package/dist/common/events/trigger-proxy.js +0 -12
  59. package/dist/common/events/trigger-proxy.js.map +1 -1
  60. package/dist/common/events/util.js +0 -15
  61. package/dist/common/events/util.js.map +1 -1
  62. package/dist/common/logs/logger-config.js +0 -4
  63. package/dist/common/logs/logger-config.js.map +1 -1
  64. package/dist/common/logs/logger-proxy.js +1 -8
  65. package/dist/common/logs/logger-proxy.js.map +1 -1
  66. package/dist/common/logs/request.js +37 -60
  67. package/dist/common/logs/request.js.map +1 -1
  68. package/dist/common/queue.js +28 -23
  69. package/dist/common/queue.js.map +1 -1
  70. package/dist/config.js +8 -13
  71. package/dist/config.js.map +1 -1
  72. package/dist/constants.js +250 -66
  73. package/dist/constants.js.map +1 -1
  74. package/dist/controls-options-manager/constants.js +14 -0
  75. package/dist/controls-options-manager/constants.js.map +1 -0
  76. package/dist/controls-options-manager/enums.js +27 -0
  77. package/dist/controls-options-manager/enums.js.map +1 -0
  78. package/dist/controls-options-manager/index.js +297 -0
  79. package/dist/controls-options-manager/index.js.map +1 -0
  80. package/dist/controls-options-manager/types.js +7 -0
  81. package/dist/controls-options-manager/types.js.map +1 -0
  82. package/dist/controls-options-manager/util.js +319 -0
  83. package/dist/controls-options-manager/util.js.map +1 -0
  84. package/dist/index.js +108 -17
  85. package/dist/index.js.map +1 -1
  86. package/dist/interpretation/collection.js +23 -0
  87. package/dist/interpretation/collection.js.map +1 -0
  88. package/dist/interpretation/index.js +366 -0
  89. package/dist/interpretation/index.js.map +1 -0
  90. package/dist/interpretation/siLanguage.js +25 -0
  91. package/dist/interpretation/siLanguage.js.map +1 -0
  92. package/dist/locus-info/controlsUtils.js +101 -29
  93. package/dist/locus-info/controlsUtils.js.map +1 -1
  94. package/dist/locus-info/embeddedAppsUtils.js +3 -26
  95. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  96. package/dist/locus-info/fullState.js +0 -15
  97. package/dist/locus-info/fullState.js.map +1 -1
  98. package/dist/locus-info/hostUtils.js +4 -12
  99. package/dist/locus-info/hostUtils.js.map +1 -1
  100. package/dist/locus-info/index.js +532 -240
  101. package/dist/locus-info/index.js.map +1 -1
  102. package/dist/locus-info/infoUtils.js +3 -37
  103. package/dist/locus-info/infoUtils.js.map +1 -1
  104. package/dist/locus-info/mediaSharesUtils.js +54 -38
  105. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  106. package/dist/locus-info/parser.js +284 -154
  107. package/dist/locus-info/parser.js.map +1 -1
  108. package/dist/locus-info/selfUtils.js +110 -92
  109. package/dist/locus-info/selfUtils.js.map +1 -1
  110. package/dist/media/index.js +95 -226
  111. package/dist/media/index.js.map +1 -1
  112. package/dist/media/properties.js +99 -194
  113. package/dist/media/properties.js.map +1 -1
  114. package/dist/media/util.js +2 -9
  115. package/dist/media/util.js.map +1 -1
  116. package/dist/mediaQualityMetrics/config.js +505 -495
  117. package/dist/mediaQualityMetrics/config.js.map +1 -1
  118. package/dist/meeting/in-meeting-actions.js +83 -14
  119. package/dist/meeting/in-meeting-actions.js.map +1 -1
  120. package/dist/meeting/index.js +3478 -3563
  121. package/dist/meeting/index.js.map +1 -1
  122. package/dist/meeting/locusMediaRequest.js +291 -0
  123. package/dist/meeting/locusMediaRequest.js.map +1 -0
  124. package/dist/meeting/muteState.js +247 -183
  125. package/dist/meeting/muteState.js.map +1 -1
  126. package/dist/meeting/request.js +344 -344
  127. package/dist/meeting/request.js.map +1 -1
  128. package/dist/meeting/request.type.js +7 -0
  129. package/dist/meeting/request.type.js.map +1 -0
  130. package/dist/meeting/state.js +21 -31
  131. package/dist/meeting/state.js.map +1 -1
  132. package/dist/meeting/util.js +529 -588
  133. package/dist/meeting/util.js.map +1 -1
  134. package/dist/meeting-info/collection.js +6 -25
  135. package/dist/meeting-info/collection.js.map +1 -1
  136. package/dist/meeting-info/index.js +62 -39
  137. package/dist/meeting-info/index.js.map +1 -1
  138. package/dist/meeting-info/meeting-info-v2.js +328 -283
  139. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  140. package/dist/meeting-info/request.js +3 -15
  141. package/dist/meeting-info/request.js.map +1 -1
  142. package/dist/meeting-info/util.js +98 -183
  143. package/dist/meeting-info/util.js.map +1 -1
  144. package/dist/meeting-info/utilv2.js +156 -232
  145. package/dist/meeting-info/utilv2.js.map +1 -1
  146. package/dist/meetings/collection.js +26 -19
  147. package/dist/meetings/collection.js.map +1 -1
  148. package/dist/meetings/index.js +795 -574
  149. package/dist/meetings/index.js.map +1 -1
  150. package/dist/meetings/meetings.types.js +7 -0
  151. package/dist/meetings/meetings.types.js.map +1 -0
  152. package/dist/meetings/request.js +26 -41
  153. package/dist/meetings/request.js.map +1 -1
  154. package/dist/meetings/util.js +186 -155
  155. package/dist/meetings/util.js.map +1 -1
  156. package/dist/member/index.js +126 -85
  157. package/dist/member/index.js.map +1 -1
  158. package/dist/member/types.js +25 -0
  159. package/dist/member/types.js.map +1 -0
  160. package/dist/member/util.js +147 -88
  161. package/dist/member/util.js.map +1 -1
  162. package/dist/members/collection.js +13 -12
  163. package/dist/members/collection.js.map +1 -1
  164. package/dist/members/index.js +178 -204
  165. package/dist/members/index.js.map +1 -1
  166. package/dist/members/request.js +113 -68
  167. package/dist/members/request.js.map +1 -1
  168. package/dist/members/types.js +15 -0
  169. package/dist/members/types.js.map +1 -0
  170. package/dist/members/util.js +314 -260
  171. package/dist/members/util.js.map +1 -1
  172. package/dist/metrics/constants.js +4 -7
  173. package/dist/metrics/constants.js.map +1 -1
  174. package/dist/metrics/index.js +11 -558
  175. package/dist/metrics/index.js.map +1 -1
  176. package/dist/multistream/mediaRequestManager.js +264 -50
  177. package/dist/multistream/mediaRequestManager.js.map +1 -1
  178. package/dist/multistream/receiveSlot.js +58 -65
  179. package/dist/multistream/receiveSlot.js.map +1 -1
  180. package/dist/multistream/receiveSlotManager.js +76 -95
  181. package/dist/multistream/receiveSlotManager.js.map +1 -1
  182. package/dist/multistream/remoteMedia.js +62 -76
  183. package/dist/multistream/remoteMedia.js.map +1 -1
  184. package/dist/multistream/remoteMediaGroup.js +66 -43
  185. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  186. package/dist/multistream/remoteMediaManager.js +502 -442
  187. package/dist/multistream/remoteMediaManager.js.map +1 -1
  188. package/dist/networkQualityMonitor/index.js +40 -59
  189. package/dist/networkQualityMonitor/index.js.map +1 -1
  190. package/dist/personal-meeting-room/index.js +21 -45
  191. package/dist/personal-meeting-room/index.js.map +1 -1
  192. package/dist/personal-meeting-room/request.js +1 -31
  193. package/dist/personal-meeting-room/request.js.map +1 -1
  194. package/dist/personal-meeting-room/util.js +0 -13
  195. package/dist/personal-meeting-room/util.js.map +1 -1
  196. package/dist/reachability/index.js +192 -191
  197. package/dist/reachability/index.js.map +1 -1
  198. package/dist/reachability/request.js +15 -23
  199. package/dist/reachability/request.js.map +1 -1
  200. package/dist/reactions/constants.js +13 -0
  201. package/dist/reactions/constants.js.map +1 -0
  202. package/dist/reactions/reactions.js +109 -0
  203. package/dist/reactions/reactions.js.map +1 -0
  204. package/dist/reactions/reactions.type.js +36 -0
  205. package/dist/reactions/reactions.type.js.map +1 -0
  206. package/dist/reconnection-manager/index.js +384 -476
  207. package/dist/reconnection-manager/index.js.map +1 -1
  208. package/dist/recording-controller/enums.js +17 -0
  209. package/dist/recording-controller/enums.js.map +1 -0
  210. package/dist/recording-controller/index.js +363 -0
  211. package/dist/recording-controller/index.js.map +1 -0
  212. package/dist/recording-controller/util.js +64 -0
  213. package/dist/recording-controller/util.js.map +1 -0
  214. package/dist/roap/index.js +58 -91
  215. package/dist/roap/index.js.map +1 -1
  216. package/dist/roap/request.js +137 -135
  217. package/dist/roap/request.js.map +1 -1
  218. package/dist/roap/turnDiscovery.js +148 -100
  219. package/dist/roap/turnDiscovery.js.map +1 -1
  220. package/dist/rtcMetrics/constants.js +12 -0
  221. package/dist/rtcMetrics/constants.js.map +1 -0
  222. package/dist/rtcMetrics/index.js +115 -0
  223. package/dist/rtcMetrics/index.js.map +1 -0
  224. package/dist/statsAnalyzer/global.js +1 -95
  225. package/dist/statsAnalyzer/global.js.map +1 -1
  226. package/dist/statsAnalyzer/index.js +385 -460
  227. package/dist/statsAnalyzer/index.js.map +1 -1
  228. package/dist/statsAnalyzer/mqaUtil.js +143 -87
  229. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  230. package/dist/transcription/index.js +22 -47
  231. package/dist/transcription/index.js.map +1 -1
  232. package/dist/types/annotation/annotation.types.d.ts +42 -0
  233. package/dist/types/annotation/constants.d.ts +31 -0
  234. package/dist/types/annotation/index.d.ts +117 -0
  235. package/dist/types/breakouts/breakout.d.ts +8 -0
  236. package/dist/types/breakouts/collection.d.ts +5 -0
  237. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  238. package/dist/types/breakouts/events.d.ts +8 -0
  239. package/dist/types/breakouts/index.d.ts +5 -0
  240. package/dist/types/breakouts/request.d.ts +22 -0
  241. package/dist/types/breakouts/utils.d.ts +15 -0
  242. package/dist/types/common/browser-detection.d.ts +9 -0
  243. package/dist/types/common/collection.d.ts +48 -0
  244. package/dist/types/common/config.d.ts +2 -0
  245. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  246. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  247. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  248. package/dist/types/common/errors/media.d.ts +15 -0
  249. package/dist/types/common/errors/parameter.d.ts +15 -0
  250. package/dist/types/common/errors/password-error.d.ts +15 -0
  251. package/dist/types/common/errors/permission.d.ts +14 -0
  252. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  253. package/dist/types/common/errors/reconnection.d.ts +15 -0
  254. package/dist/types/common/errors/stats.d.ts +15 -0
  255. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  256. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  257. package/dist/types/common/events/events-scope.d.ts +17 -0
  258. package/dist/types/common/events/events.d.ts +12 -0
  259. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  260. package/dist/types/common/events/util.d.ts +2 -0
  261. package/dist/types/common/logs/logger-config.d.ts +2 -0
  262. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  263. package/dist/types/common/logs/request.d.ts +34 -0
  264. package/dist/types/common/queue.d.ts +34 -0
  265. package/dist/types/config.d.ts +72 -0
  266. package/dist/types/constants.d.ts +1016 -0
  267. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  268. package/dist/types/controls-options-manager/enums.d.ts +15 -0
  269. package/dist/types/controls-options-manager/index.d.ts +136 -0
  270. package/dist/types/controls-options-manager/types.d.ts +43 -0
  271. package/dist/types/controls-options-manager/util.d.ts +1 -0
  272. package/dist/types/index.d.ts +7 -0
  273. package/dist/types/interpretation/collection.d.ts +5 -0
  274. package/dist/types/interpretation/index.d.ts +5 -0
  275. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  276. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  277. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  278. package/dist/types/locus-info/fullState.d.ts +2 -0
  279. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  280. package/dist/types/locus-info/index.d.ts +322 -0
  281. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  282. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  283. package/dist/types/locus-info/parser.d.ts +271 -0
  284. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  285. package/dist/types/media/index.d.ts +34 -0
  286. package/dist/types/media/properties.d.ts +93 -0
  287. package/dist/types/media/util.d.ts +2 -0
  288. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  289. package/dist/types/meeting/in-meeting-actions.d.ts +153 -0
  290. package/dist/types/meeting/index.d.ts +1471 -0
  291. package/dist/types/meeting/locusMediaRequest.d.ts +70 -0
  292. package/dist/types/meeting/muteState.d.ts +184 -0
  293. package/dist/types/meeting/request.d.ts +257 -0
  294. package/dist/types/meeting/request.type.d.ts +11 -0
  295. package/dist/types/meeting/state.d.ts +9 -0
  296. package/dist/types/meeting/util.d.ts +78 -0
  297. package/dist/types/meeting-info/collection.d.ts +20 -0
  298. package/dist/types/meeting-info/index.d.ts +62 -0
  299. package/dist/types/meeting-info/meeting-info-v2.d.ts +122 -0
  300. package/dist/types/meeting-info/request.d.ts +22 -0
  301. package/dist/types/meeting-info/util.d.ts +2 -0
  302. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  303. package/dist/types/meetings/collection.d.ts +31 -0
  304. package/dist/types/meetings/index.d.ts +367 -0
  305. package/dist/types/meetings/meetings.types.d.ts +4 -0
  306. package/dist/types/meetings/request.d.ts +27 -0
  307. package/dist/types/meetings/util.d.ts +18 -0
  308. package/dist/types/member/index.d.ts +159 -0
  309. package/dist/types/member/types.d.ts +32 -0
  310. package/dist/types/member/util.d.ts +2 -0
  311. package/dist/types/members/collection.d.ts +29 -0
  312. package/dist/types/members/index.d.ts +353 -0
  313. package/dist/types/members/request.d.ts +114 -0
  314. package/dist/types/members/types.d.ts +24 -0
  315. package/dist/types/members/util.d.ts +210 -0
  316. package/dist/types/metrics/constants.d.ts +55 -0
  317. package/dist/types/metrics/index.d.ts +45 -0
  318. package/dist/types/multistream/mediaRequestManager.d.ts +118 -0
  319. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  320. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  321. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  322. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  323. package/dist/types/multistream/remoteMediaManager.d.ts +277 -0
  324. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  325. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  326. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  327. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  328. package/dist/types/reachability/index.d.ts +152 -0
  329. package/dist/types/reachability/request.d.ts +37 -0
  330. package/dist/types/reactions/constants.d.ts +3 -0
  331. package/dist/types/reactions/reactions.d.ts +4 -0
  332. package/dist/types/reactions/reactions.type.d.ts +52 -0
  333. package/dist/types/reconnection-manager/index.d.ts +126 -0
  334. package/dist/types/recording-controller/enums.d.ts +7 -0
  335. package/dist/types/recording-controller/index.d.ts +208 -0
  336. package/dist/types/recording-controller/util.d.ts +14 -0
  337. package/dist/types/roap/index.d.ts +77 -0
  338. package/dist/types/roap/request.d.ts +36 -0
  339. package/dist/types/roap/turnDiscovery.d.ts +91 -0
  340. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  341. package/dist/types/rtcMetrics/index.d.ts +46 -0
  342. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  343. package/dist/types/statsAnalyzer/index.d.ts +200 -0
  344. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  345. package/dist/types/transcription/index.d.ts +64 -0
  346. package/internal-README.md +7 -6
  347. package/package.json +29 -21
  348. package/src/annotation/annotation.types.ts +50 -0
  349. package/src/annotation/constants.ts +36 -0
  350. package/src/annotation/index.ts +328 -0
  351. package/src/breakouts/README.md +220 -0
  352. package/src/breakouts/breakout.ts +188 -0
  353. package/src/breakouts/collection.ts +19 -0
  354. package/src/breakouts/edit-lock-error.ts +25 -0
  355. package/src/breakouts/events.ts +56 -0
  356. package/src/breakouts/index.ts +925 -0
  357. package/src/breakouts/request.ts +55 -0
  358. package/src/breakouts/utils.ts +57 -0
  359. package/src/common/{browser-detection.js → browser-detection.ts} +9 -6
  360. package/src/common/collection.ts +9 -7
  361. package/src/common/{config.js → config.ts} +1 -1
  362. package/src/common/errors/{captcha-error.js → captcha-error.ts} +11 -7
  363. package/src/common/errors/{intent-to-join.js → intent-to-join.ts} +12 -7
  364. package/src/common/errors/{join-meeting.js → join-meeting.ts} +17 -8
  365. package/src/common/errors/{media.js → media.ts} +11 -7
  366. package/src/common/errors/parameter.ts +11 -7
  367. package/src/common/errors/{password-error.js → password-error.ts} +11 -7
  368. package/src/common/errors/{permission.js → permission.ts} +10 -6
  369. package/src/common/errors/{reconnection.js → reconnection.ts} +11 -7
  370. package/src/common/errors/{stats.js → stats.ts} +11 -7
  371. package/src/common/errors/{webex-errors.js → webex-errors.ts} +14 -9
  372. package/src/common/errors/{webex-meetings-error.js → webex-meetings-error.ts} +4 -2
  373. package/src/common/events/{events-scope.js → events-scope.ts} +6 -2
  374. package/src/common/events/{events.js → events.ts} +5 -1
  375. package/src/common/events/{trigger-proxy.js → trigger-proxy.ts} +9 -5
  376. package/src/common/events/{util.js → util.ts} +2 -3
  377. package/src/common/logs/{logger-config.js → logger-config.ts} +1 -2
  378. package/src/common/logs/logger-proxy.ts +44 -0
  379. package/src/common/logs/{request.js → request.ts} +22 -9
  380. package/src/common/queue.ts +22 -9
  381. package/src/{config.js → config.ts} +17 -17
  382. package/src/constants.ts +197 -22
  383. package/src/controls-options-manager/constants.ts +5 -0
  384. package/src/controls-options-manager/enums.ts +18 -0
  385. package/src/controls-options-manager/index.ts +278 -0
  386. package/src/controls-options-manager/types.ts +59 -0
  387. package/src/controls-options-manager/util.ts +300 -0
  388. package/src/index.ts +39 -0
  389. package/src/interpretation/README.md +60 -0
  390. package/src/interpretation/collection.ts +19 -0
  391. package/src/interpretation/index.ts +332 -0
  392. package/src/interpretation/siLanguage.ts +18 -0
  393. package/src/locus-info/controlsUtils.ts +222 -0
  394. package/src/locus-info/{embeddedAppsUtils.js → embeddedAppsUtils.ts} +5 -6
  395. package/src/locus-info/{fullState.js → fullState.ts} +16 -12
  396. package/src/locus-info/{hostUtils.js → hostUtils.ts} +9 -8
  397. package/src/locus-info/{index.js → index.ts} +518 -111
  398. package/src/locus-info/{infoUtils.js → infoUtils.ts} +19 -8
  399. package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +65 -17
  400. package/src/locus-info/{parser.js → parser.ts} +271 -98
  401. package/src/locus-info/{selfUtils.js → selfUtils.ts} +199 -68
  402. package/src/media/index.ts +456 -0
  403. package/src/media/{properties.js → properties.ts} +80 -102
  404. package/src/media/{util.js → util.ts} +2 -2
  405. package/src/mediaQualityMetrics/config.ts +384 -0
  406. package/src/meeting/in-meeting-actions.ts +171 -3
  407. package/src/meeting/index.ts +7070 -0
  408. package/src/meeting/locusMediaRequest.ts +309 -0
  409. package/src/meeting/muteState.ts +450 -0
  410. package/src/meeting/{request.js → request.ts} +354 -214
  411. package/src/meeting/request.type.ts +13 -0
  412. package/src/meeting/{state.js → state.ts} +50 -35
  413. package/src/meeting/util.ts +615 -0
  414. package/src/meeting-info/{collection.js → collection.ts} +6 -2
  415. package/src/meeting-info/index.ts +183 -0
  416. package/src/meeting-info/meeting-info-v2.ts +407 -0
  417. package/src/meeting-info/{request.js → request.ts} +14 -4
  418. package/src/meeting-info/{util.js → util.ts} +60 -51
  419. package/src/meeting-info/{utilv2.js → utilv2.ts} +77 -60
  420. package/src/meetings/{collection.js → collection.ts} +26 -3
  421. package/src/meetings/index.ts +1467 -0
  422. package/src/meetings/meetings.types.ts +12 -0
  423. package/src/meetings/{request.js → request.ts} +34 -25
  424. package/src/meetings/{util.js → util.ts} +137 -36
  425. package/src/member/{index.js → index.ts} +151 -56
  426. package/src/member/types.ts +38 -0
  427. package/src/member/util.ts +383 -0
  428. package/src/members/{collection.js → collection.ts} +10 -2
  429. package/src/members/{index.js → index.ts} +323 -145
  430. package/src/members/request.ts +255 -0
  431. package/src/members/types.ts +28 -0
  432. package/src/members/util.ts +339 -0
  433. package/src/metrics/{constants.js → constants.ts} +2 -6
  434. package/src/metrics/index.ts +73 -0
  435. package/src/multistream/mediaRequestManager.ts +337 -61
  436. package/src/multistream/receiveSlot.ts +69 -26
  437. package/src/multistream/receiveSlotManager.ts +66 -42
  438. package/src/multistream/remoteMedia.ts +40 -5
  439. package/src/multistream/remoteMediaGroup.ts +63 -3
  440. package/src/multistream/remoteMediaManager.ts +263 -66
  441. package/src/networkQualityMonitor/{index.js → index.ts} +41 -29
  442. package/src/personal-meeting-room/{index.js → index.ts} +28 -19
  443. package/src/personal-meeting-room/{request.js → request.ts} +13 -4
  444. package/src/personal-meeting-room/{util.js → util.ts} +4 -4
  445. package/src/reachability/{index.js → index.ts} +157 -94
  446. package/src/reachability/request.ts +46 -35
  447. package/src/reactions/constants.ts +4 -0
  448. package/src/reactions/reactions.ts +104 -0
  449. package/src/reactions/reactions.type.ts +62 -0
  450. package/src/reconnection-manager/{index.js → index.ts} +254 -136
  451. package/src/recording-controller/enums.ts +8 -0
  452. package/src/recording-controller/index.ts +333 -0
  453. package/src/recording-controller/util.ts +75 -0
  454. package/src/roap/{index.js → index.ts} +86 -78
  455. package/src/roap/request.ts +163 -0
  456. package/src/roap/turnDiscovery.ts +111 -49
  457. package/src/rtcMetrics/constants.ts +3 -0
  458. package/src/rtcMetrics/index.ts +96 -0
  459. package/src/statsAnalyzer/global.ts +37 -0
  460. package/src/statsAnalyzer/index.ts +1272 -0
  461. package/src/statsAnalyzer/mqaUtil.ts +291 -0
  462. package/src/transcription/{index.js → index.ts} +46 -39
  463. package/test/integration/spec/converged-space-meetings.js +233 -0
  464. package/test/integration/spec/journey.js +804 -526
  465. package/test/integration/spec/space-meeting.js +391 -204
  466. package/test/integration/spec/transcription.js +7 -8
  467. package/test/unit/spec/annotation/index.ts +418 -0
  468. package/test/unit/spec/breakouts/breakout.ts +237 -0
  469. package/test/unit/spec/breakouts/collection.ts +15 -0
  470. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  471. package/test/unit/spec/breakouts/events.ts +89 -0
  472. package/test/unit/spec/breakouts/index.ts +1790 -0
  473. package/test/unit/spec/breakouts/request.ts +104 -0
  474. package/test/unit/spec/breakouts/utils.js +72 -0
  475. package/test/unit/spec/common/browser-detection.js +9 -28
  476. package/test/unit/spec/common/queue.js +31 -2
  477. package/test/unit/spec/controls-options-manager/index.js +287 -0
  478. package/test/unit/spec/controls-options-manager/util.js +582 -0
  479. package/test/unit/spec/fixture/locus.js +93 -90
  480. package/test/unit/spec/interpretation/collection.ts +15 -0
  481. package/test/unit/spec/interpretation/index.ts +589 -0
  482. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  483. package/test/unit/spec/locus-info/controlsUtils.js +325 -32
  484. package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
  485. package/test/unit/spec/locus-info/index.js +1176 -18
  486. package/test/unit/spec/locus-info/infoUtils.js +41 -32
  487. package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
  488. package/test/unit/spec/locus-info/lib/SeqCmp.json +513 -685
  489. package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
  490. package/test/unit/spec/locus-info/parser.js +65 -31
  491. package/test/unit/spec/locus-info/selfConstant.js +120 -103
  492. package/test/unit/spec/locus-info/selfUtils.js +296 -12
  493. package/test/unit/spec/media/index.ts +162 -68
  494. package/test/unit/spec/media/properties.ts +9 -9
  495. package/test/unit/spec/meeting/in-meeting-actions.ts +82 -3
  496. package/test/unit/spec/meeting/index.js +4569 -1773
  497. package/test/unit/spec/meeting/locusMediaRequest.ts +436 -0
  498. package/test/unit/spec/meeting/muteState.js +382 -211
  499. package/test/unit/spec/meeting/request.js +444 -78
  500. package/test/unit/spec/meeting/utils.js +517 -192
  501. package/test/unit/spec/meeting-info/index.js +181 -0
  502. package/test/unit/spec/meeting-info/meetinginfov2.js +481 -76
  503. package/test/unit/spec/meeting-info/request.js +7 -9
  504. package/test/unit/spec/meeting-info/util.js +11 -12
  505. package/test/unit/spec/meeting-info/utilv2.js +131 -74
  506. package/test/unit/spec/meetings/collection.js +15 -1
  507. package/test/unit/spec/meetings/index.js +1254 -330
  508. package/test/unit/spec/meetings/utils.js +220 -14
  509. package/test/unit/spec/member/index.js +58 -5
  510. package/test/unit/spec/member/util.js +494 -26
  511. package/test/unit/spec/members/index.js +423 -55
  512. package/test/unit/spec/members/request.js +228 -40
  513. package/test/unit/spec/members/utils.js +191 -4
  514. package/test/unit/spec/metrics/index.js +12 -66
  515. package/test/unit/spec/multistream/mediaRequestManager.ts +1013 -106
  516. package/test/unit/spec/multistream/receiveSlot.ts +77 -18
  517. package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
  518. package/test/unit/spec/multistream/remoteMedia.ts +40 -2
  519. package/test/unit/spec/multistream/remoteMediaGroup.ts +271 -5
  520. package/test/unit/spec/multistream/remoteMediaManager.ts +730 -65
  521. package/test/unit/spec/networkQualityMonitor/index.js +24 -18
  522. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -7
  523. package/test/unit/spec/reachability/index.ts +176 -27
  524. package/test/unit/spec/reachability/request.js +66 -0
  525. package/test/unit/spec/reconnection-manager/index.js +155 -9
  526. package/test/unit/spec/recording-controller/index.js +307 -0
  527. package/test/unit/spec/recording-controller/util.js +229 -0
  528. package/test/unit/spec/roap/index.ts +28 -52
  529. package/test/unit/spec/roap/request.ts +225 -0
  530. package/test/unit/spec/roap/turnDiscovery.ts +92 -50
  531. package/test/unit/spec/rtcMetrics/index.ts +60 -0
  532. package/test/unit/spec/stats-analyzer/index.js +116 -60
  533. package/test/utils/cmr.js +44 -42
  534. package/test/utils/constants.js +9 -0
  535. package/test/utils/integrationTestUtils.js +46 -0
  536. package/test/utils/testUtils.js +63 -99
  537. package/test/utils/webex-config.js +22 -18
  538. package/test/utils/webex-test-users.js +57 -50
  539. package/tsconfig.json +6 -0
  540. package/dist/media/internal-media-core-wrapper.js +0 -22
  541. package/dist/media/internal-media-core-wrapper.js.map +0 -1
  542. package/dist/meeting/effectsState.js +0 -327
  543. package/dist/meeting/effectsState.js.map +0 -1
  544. package/dist/metrics/config.js +0 -301
  545. package/dist/metrics/config.js.map +0 -1
  546. package/dist/multistream/multistreamMedia.js +0 -116
  547. package/dist/multistream/multistreamMedia.js.map +0 -1
  548. package/dist/peer-connection-manager/util.js +0 -124
  549. package/dist/peer-connection-manager/util.js.map +0 -1
  550. package/src/common/logs/logger-proxy.js +0 -33
  551. package/src/index.js +0 -15
  552. package/src/locus-info/controlsUtils.js +0 -102
  553. package/src/media/index.js +0 -459
  554. package/src/media/internal-media-core-wrapper.ts +0 -9
  555. package/src/mediaQualityMetrics/config.js +0 -382
  556. package/src/meeting/effectsState.js +0 -205
  557. package/src/meeting/index.js +0 -6284
  558. package/src/meeting/muteState.js +0 -318
  559. package/src/meeting/util.js +0 -506
  560. package/src/meeting-info/index.js +0 -131
  561. package/src/meeting-info/meeting-info-v2.js +0 -255
  562. package/src/meetings/index.js +0 -1015
  563. package/src/member/util.js +0 -254
  564. package/src/members/request.js +0 -131
  565. package/src/members/util.js +0 -258
  566. package/src/metrics/config.js +0 -324
  567. package/src/metrics/index.js +0 -530
  568. package/src/multistream/multistreamMedia.ts +0 -92
  569. package/src/peer-connection-manager/util.ts +0 -117
  570. package/src/roap/request.js +0 -127
  571. package/src/statsAnalyzer/global.js +0 -133
  572. package/src/statsAnalyzer/index.js +0 -1006
  573. package/src/statsAnalyzer/mqaUtil.js +0 -173
  574. package/test/unit/spec/meeting/effectsState.js +0 -291
  575. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -389
  576. /package/src/common/errors/{reconnection-in-progress.js → reconnection-in-progress.ts} +0 -0
@@ -1,8 +1,7 @@
1
1
  import sinon from 'sinon';
2
2
  import {assert} from '@webex/test-helper-chai';
3
3
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
4
- import createMuteState from '@webex/plugin-meetings/src/meeting/muteState';
5
- import Media from '@webex/plugin-meetings/src/media/index';
4
+ import {createMuteState, MuteState} from '@webex/plugin-meetings/src/meeting/muteState';
6
5
  import PermissionError from '@webex/plugin-meetings/src/common/errors/permission';
7
6
  import {AUDIO, VIDEO} from '@webex/plugin-meetings/src/constants';
8
7
 
@@ -16,29 +15,44 @@ describe('plugin-meetings', () => {
16
15
 
17
16
  const fakeLocus = {info: 'this is a fake locus'};
18
17
 
19
- beforeEach(() => {
18
+ const createFakeLocalTrack = (id, muted) => {
19
+ return {
20
+ id,
21
+ setMuted: sinon.stub(),
22
+ setServerMuted: sinon.stub(),
23
+ setUnmuteAllowed: sinon.stub(),
24
+ muted,
25
+ };
26
+ };
27
+
28
+ beforeEach(async () => {
20
29
  meeting = {
21
30
  mediaProperties: {
22
- audioTrack: 'fake audio track',
23
- videoTrack: 'fake video track'
31
+ audioTrack: createFakeLocalTrack('fake audio track', false),
32
+ videoTrack: createFakeLocalTrack('fake video track', false),
24
33
  },
25
34
  remoteMuted: false,
26
35
  unmuteAllowed: true,
36
+ remoteVideoMuted: false,
37
+ unmuteVideoAllowed: true,
38
+
27
39
  locusInfo: {
28
- onFullLocus: sinon.stub()
40
+ handleLocusDelta: sinon.stub(),
29
41
  },
30
42
  members: {
31
43
  selfId: 'fake self id',
32
- muteMember: sinon.stub().resolves()
33
- }
44
+ muteMember: sinon.stub().resolves(),
45
+ },
34
46
  };
35
- audio = createMuteState(AUDIO, meeting, {sendAudio: true});
36
- video = createMuteState(VIDEO, meeting, {sendVideo: true});
37
47
 
38
48
  originalRemoteUpdateAudioVideo = MeetingUtil.remoteUpdateAudioVideo;
39
49
 
40
50
  MeetingUtil.remoteUpdateAudioVideo = sinon.stub().resolves(fakeLocus);
41
- Media.setLocalTrack = sinon.stub();
51
+
52
+ audio = createMuteState(AUDIO, meeting, true);
53
+ video = createMuteState(VIDEO, meeting, true);
54
+
55
+ await testUtils.flushPromises();
42
56
  });
43
57
 
44
58
  afterEach(() => {
@@ -46,63 +60,61 @@ describe('plugin-meetings', () => {
46
60
  });
47
61
 
48
62
  describe('mute state library', () => {
49
- it('does not create an audio instance if we are not sending audio', async () => {
50
- assert.isNull(createMuteState(AUDIO, meeting, {sendAudio: false}));
51
- assert.isNull(createMuteState(AUDIO, meeting, {}));
52
- });
53
-
54
- it('does not create a video instance if we are not sending video', async () => {
55
- assert.isNull(createMuteState(VIDEO, meeting, {sendVideo: false}));
56
- assert.isNull(createMuteState(VIDEO, meeting, {}));
57
- });
58
-
59
63
  it('takes into account current remote mute status when instantiated', async () => {
60
64
  // simulate being already remote muted
61
65
  meeting.remoteMuted = true;
62
- // create a new MuteState intance
63
- audio = createMuteState(AUDIO, meeting, {sendAudio: true});
66
+
67
+ // create a new MuteState instance
68
+ audio = createMuteState(AUDIO, meeting, true);
69
+
70
+ await testUtils.flushPromises();
64
71
 
65
72
  assert.isTrue(audio.isMuted());
66
- assert.isFalse(audio.isSelf());
73
+ assert.isTrue(audio.isRemotelyMuted());
67
74
 
68
75
  // now check the opposite case
69
76
  meeting.remoteMuted = false;
70
77
 
71
- // create a new MuteState intance
72
- audio = createMuteState(AUDIO, meeting, {sendAudio: true});
78
+ // create a new MuteState instance
79
+ audio = createMuteState(AUDIO, meeting, true);
73
80
 
74
- assert.isFalse(audio.isMuted());
75
- assert.isFalse(audio.isSelf());
81
+ await testUtils.flushPromises();
82
+
83
+ assert.isTrue(audio.isMuted()); // because we start with no track
84
+ assert.isFalse(audio.isRemotelyMuted());
76
85
  });
77
86
 
78
87
  it('initialises correctly for video', async () => {
79
- // setup fields related to audio remote state
80
- meeting.remoteMuted = true;
81
- meeting.unmuteAllowed = false;
82
- // create a new video MuteState intance
83
- video = createMuteState(VIDEO, meeting, {sendVideo: true});
88
+ // setup fields related to video remote state
89
+ meeting.remoteVideoMuted = false;
90
+ meeting.unmuteVideoAllowed = false;
84
91
 
85
- assert.isFalse(video.isMuted());
92
+ // create a new video MuteState instance
93
+ video = createMuteState(VIDEO, meeting, true);
94
+
95
+ await testUtils.flushPromises();
96
+
97
+ assert.isTrue(video.isMuted()); // because we start with no track
98
+ assert.isFalse(video.isRemotelyMuted());
86
99
  assert.isFalse(video.state.server.remoteMute);
87
- assert.isTrue(video.state.server.unmuteAllowed);
100
+ assert.isFalse(video.state.server.unmuteAllowed);
88
101
  });
89
102
 
90
103
  it('takes remote mute into account when reporting current state', async () => {
91
- assert.isFalse(audio.isMuted());
104
+ assert.isFalse(audio.isRemotelyMuted());
92
105
 
93
106
  // simulate remote mute
94
- audio.handleServerRemoteMuteUpdate(true, true);
107
+ audio.handleServerRemoteMuteUpdate(meeting, true, true);
95
108
 
96
- assert.isTrue(audio.isMuted());
97
- assert.isFalse(audio.isSelf());
109
+ assert.isTrue(audio.isRemotelyMuted());
98
110
  });
99
111
 
100
112
  it('does local unmute if localAudioUnmuteRequired is received', async () => {
101
- // first we need to mute
102
- await audio.handleClientRequest(meeting, true);
113
+ // first we need to mute have the local track muted
114
+ meeting.mediaProperties.audioTrack.muted = true;
115
+ audio.handleLocalTrackChange(meeting);
103
116
 
104
117
  assert.isTrue(audio.isMuted());
105
- assert.isTrue(audio.isSelf());
106
118
 
107
119
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
108
120
 
@@ -110,169 +122,162 @@ describe('plugin-meetings', () => {
110
122
  audio.handleServerLocalUnmuteRequired(meeting);
111
123
  await testUtils.flushPromises();
112
124
 
113
- // check that local track was enabled
114
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.audioTrack);
125
+ // check that local track was unmuted
126
+ assert.calledWith(meeting.mediaProperties.audioTrack.setServerMuted, false, 'localUnmuteRequired');
115
127
 
116
128
  // and local unmute was sent to server
117
129
  assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
118
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, false, undefined, meeting);
130
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, false, undefined);
119
131
 
120
132
  assert.isFalse(audio.isMuted());
121
- assert.isFalse(audio.isSelf());
122
133
  });
123
134
 
124
- it('rejects client request in progress if localAudioUnmuteRequired is received', async () => {
125
- let clientPromiseResolved = false;
126
- let clientPromiseRejected = false;
127
-
128
- // first we need to mute and make that request last forever
129
- let serverResponseResolve;
130
-
131
- MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(new Promise((resolve) => {
132
- serverResponseResolve = resolve;
133
- }));
135
+ it('does local video unmute if localVideoUnmuteRequired is received', async () => {
136
+ // first we need to mute
137
+ meeting.mediaProperties.videoTrack.muted = true;
138
+ video.handleLocalTrackChange(meeting);
134
139
 
135
- audio.handleClientRequest(meeting, true)
136
- .then(() => {
137
- clientPromiseResolved = true;
138
- })
139
- .catch(() => {
140
- clientPromiseRejected = true;
141
- });
140
+ assert.isTrue(video.isMuted());
142
141
 
143
142
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
144
143
 
145
144
  // now simulate server requiring us to locally unmute
146
- audio.handleServerLocalUnmuteRequired(meeting);
145
+ video.handleServerLocalUnmuteRequired(meeting);
147
146
  await testUtils.flushPromises();
148
147
 
149
- // the original client request should have been rejected by now
150
- assert.isTrue(clientPromiseRejected);
151
- assert.isFalse(clientPromiseResolved);
152
-
153
- // now make the server respond to the original mute request
154
- serverResponseResolve();
155
- await testUtils.flushPromises();
148
+ // check that local track was unmuted
149
+ assert.calledWith(meeting.mediaProperties.videoTrack.setServerMuted, false, 'localUnmuteRequired');
156
150
 
157
- // local unmute should be sent to server
151
+ // and local unmute was sent to server
158
152
  assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
159
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, false, undefined, meeting);
160
-
161
- // and local track should be enabled
162
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.audioTrack);
153
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, false);
163
154
 
164
- assert.isFalse(audio.isMuted());
165
- assert.isFalse(audio.isSelf());
155
+ assert.isFalse(video.isMuted());
166
156
  });
167
157
 
168
- describe('#handleClientRequest', () => {
169
- it('disables/enables the local audio track when audio is muted/unmuted', async () => {
170
- // mute
171
- audio.handleClientRequest(meeting, true);
172
- assert.calledWith(Media.setLocalTrack, false, meeting.mediaProperties.audioTrack);
158
+ describe('#isLocallyMuted()', () => {
159
+ it('does not consider remote mute status for audio', async () => {
160
+ // simulate being already remote muted
161
+ meeting.remoteMuted = true;
173
162
 
174
- // even when calling mute when it's already muted should still call setLocalTrack
175
- audio.handleClientRequest(meeting, true);
176
- assert.calledWith(Media.setLocalTrack, false, meeting.mediaProperties.audioTrack);
163
+ // create a new MuteState instance
164
+ audio = createMuteState(AUDIO, meeting, true);
165
+ audio.handleLocalTrackChange(meeting);
177
166
 
178
- // unmute
179
- audio.handleClientRequest(meeting, false);
180
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.audioTrack);
167
+ await testUtils.flushPromises();
181
168
 
182
- // even when calling unmute when it's already unmuted should still call setLocalTrack
183
- audio.handleClientRequest(meeting, false);
184
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.audioTrack);
169
+ assert.isFalse(audio.isLocallyMuted());
185
170
  });
186
171
 
187
- it('disables/enables the local video track when video is muted/unmuted', async () => {
188
- // mute
189
- video.handleClientRequest(meeting, true);
190
- assert.calledWith(Media.setLocalTrack, false, meeting.mediaProperties.videoTrack);
172
+ it('does not consider remote mute status for video', async () => {
173
+ // simulate being already remote muted
174
+ meeting.remoteVideoMuted = true;
191
175
 
192
- // even when calling mute when it's already muted should still call setLocalTrack
193
- video.handleClientRequest(meeting, false);
194
- assert.calledWith(Media.setLocalTrack, false, meeting.mediaProperties.videoTrack);
176
+ // create a new MuteState instance
177
+ video = createMuteState(VIDEO, meeting, true);
178
+ video.handleLocalTrackChange(meeting);
195
179
 
196
- // unmute
197
- video.handleClientRequest(meeting, false);
198
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.videoTrack);
180
+ await testUtils.flushPromises();
199
181
 
200
- // even when calling unmute when it's already unmuted should still call setLocalTrack
201
- video.handleClientRequest(meeting, false);
202
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.videoTrack);
182
+ assert.isFalse(video.isLocallyMuted());
203
183
  });
184
+ });
204
185
 
205
- it('returns correct value in isMuted()/isSelf() methods after client mute/unmute requests', async () => {
206
- // mute
207
- audio.handleClientRequest(meeting, true);
186
+ describe('handling local track mute events', () => {
187
+
188
+ beforeEach(async () => {
189
+ audio.handleLocalTrackChange(meeting);
190
+ video.handleLocalTrackChange(meeting);
208
191
 
192
+ await testUtils.flushPromises();
193
+ });
194
+
195
+ const simulateAudioMuteChange = async (muteValue) => {
196
+ meeting.mediaProperties.audioTrack.muted = muteValue;
197
+ audio.handleLocalTrackMuteStateChange(meeting, muteValue);
198
+
199
+ await testUtils.flushPromises();
200
+ }
201
+
202
+ const simulateVideoMuteChange = async (muteValue) => {
203
+ meeting.mediaProperties.videoTrack.muted = muteValue;
204
+ video.handleLocalTrackMuteStateChange(meeting, muteValue);
205
+
206
+ await testUtils.flushPromises();
207
+ }
208
+
209
+ it('returns correct value in isMuted() methods after local track is muted/unmuted', async () => {
210
+ // mute
211
+ await simulateAudioMuteChange(true);
209
212
  assert.isTrue(audio.isMuted());
210
- assert.isTrue(audio.isSelf());
211
213
 
212
214
  // unmute
213
- audio.handleClientRequest(meeting, false);
214
-
215
+ await simulateAudioMuteChange(false);
215
216
  assert.isFalse(audio.isMuted());
216
- assert.isFalse(audio.isSelf());
217
217
  });
218
218
 
219
219
  it('does remote unmute when unmuting and remote mute is on', async () => {
220
220
  // simulate remote mute
221
- audio.handleServerRemoteMuteUpdate(true, true);
221
+ audio.handleServerRemoteMuteUpdate(meeting, true, true);
222
222
 
223
223
  // unmute
224
- await audio.handleClientRequest(meeting, false);
224
+ await simulateAudioMuteChange(false);
225
225
 
226
226
  // check that remote unmute was sent to server
227
227
  assert.calledOnce(meeting.members.muteMember);
228
- assert.calledWith(meeting.members.muteMember, meeting.members.selfId, false);
228
+ assert.calledWith(meeting.members.muteMember, meeting.members.selfId, false, true);
229
229
 
230
230
  assert.isFalse(audio.isMuted());
231
- assert.isFalse(audio.isSelf());
232
231
  });
233
232
 
234
- it('resolves client request promise once the server is updated', async () => {
235
- let clientPromiseResolved = false;
233
+ it('does video remote unmute when unmuting and remote mute is on', async () => {
234
+ // simulate remote mute
235
+ video.handleServerRemoteMuteUpdate(meeting, true, true);
236
236
 
237
- let serverResponseResolve;
237
+ // unmute
238
+ await simulateVideoMuteChange(false);
238
239
 
239
- MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(new Promise((resolve) => {
240
- serverResponseResolve = resolve;
241
- }));
240
+ // check that remote unmute was sent to server
241
+ assert.calledOnce(meeting.members.muteMember);
242
+ assert.calledWith(meeting.members.muteMember, meeting.members.selfId, false, false);
242
243
 
243
- audio.handleClientRequest(meeting, true)
244
- .then(() => {
245
- clientPromiseResolved = true;
246
- });
244
+ assert.isFalse(video.isMuted());
245
+ });
246
+
247
+ it('does not video remote unmute when unmuting and remote mute is off', async () => {
248
+ // simulate remote mute
249
+ video.handleServerRemoteMuteUpdate(meeting, false, true);
247
250
 
248
- // do a small delay to make sure that the client promise doesn't resolve in that time
249
- await testUtils.waitUntil(200);
250
- assert.isFalse(clientPromiseResolved);
251
+ // unmute
252
+ await simulateVideoMuteChange(false);
251
253
 
252
- // now allow the server response to arrive, this should trigger the client promise to get resolved
253
- serverResponseResolve();
254
- await testUtils.flushPromises();
254
+ // check that remote unmute was not sent to server
255
+ assert.notCalled(meeting.members.muteMember);
255
256
 
256
- assert.isTrue(clientPromiseResolved);
257
+ assert.isFalse(video.isMuted());
257
258
  });
258
259
 
259
- it('rejects client request promise if server request for local mute fails', async () => {
260
- MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(new Promise((resolve, reject) => {
261
- reject();
262
- }));
260
+ it('calls setServerMuted with "clientRequestFailed" when server request for local mute fails', async () => {
261
+ MeetingUtil.remoteUpdateAudioVideo = sinon.stub().rejects(new Error('fake error'));
262
+
263
+ await simulateAudioMuteChange(true);
263
264
 
264
- assert.isRejected(audio.handleClientRequest(meeting, true));
265
+ assert.calledOnceWithExactly(meeting.mediaProperties.audioTrack.setServerMuted , false, 'clientRequestFailed');
265
266
  });
266
267
 
267
- it('rejects client request promise if server request for remote mute fails', async () => {
268
+ it('calls setServerMuted with "clientRequestFailed" if server request for remote mute fails', async () => {
268
269
  // we only send remote mute requests when we're unmuting, so first we need to do a remote mute
269
- audio.handleServerRemoteMuteUpdate(true, true);
270
+ audio.handleServerRemoteMuteUpdate(meeting, true, true);
271
+
272
+ await testUtils.flushPromises();
270
273
 
271
274
  // setup the stub to simulate server error response
272
275
  meeting.members.muteMember = sinon.stub().rejects();
276
+ meeting.mediaProperties.audioTrack.setServerMuted.resetHistory();
273
277
 
274
- // try to unmute - it should fail
275
- await assert.isRejected(audio.handleClientRequest(meeting, false));
278
+ await simulateAudioMuteChange(false);
279
+
280
+ assert.calledOnceWithExactly(meeting.mediaProperties.audioTrack.setServerMuted , true, 'clientRequestFailed');
276
281
 
277
282
  // even though remote mute update in the server failed, isMuted() should still return true,
278
283
  // because of local mute
@@ -282,16 +287,19 @@ describe('plugin-meetings', () => {
282
287
  it('does not send a server request if client state matches the server', async () => {
283
288
  let serverResponseResolve;
284
289
 
285
- MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(new Promise((resolve) => {
286
- serverResponseResolve = resolve;
287
- }));
290
+ MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(
291
+ new Promise((resolve) => {
292
+ serverResponseResolve = resolve;
293
+ })
294
+ );
288
295
 
289
- // simulate many client requests, with the last one matching the initial one
290
- audio.handleClientRequest(meeting, true);
291
- audio.handleClientRequest(meeting, false);
292
- audio.handleClientRequest(meeting, true);
293
- audio.handleClientRequest(meeting, false);
294
- audio.handleClientRequest(meeting, true);
296
+ // the track is initially unmuted
297
+ // simulate many mute changes with the last one matching the first one
298
+ await simulateAudioMuteChange(true);
299
+ await simulateAudioMuteChange(false);
300
+ await simulateAudioMuteChange(true);
301
+ await simulateAudioMuteChange(false);
302
+ await simulateAudioMuteChange(true);
295
303
 
296
304
  // so far there should have been only 1 request to server (because our stub hasn't resolved yet
297
305
  // and MuteState sends only 1 server request at a time)
@@ -306,112 +314,275 @@ describe('plugin-meetings', () => {
306
314
  assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
307
315
  });
308
316
 
309
- it('queues up server requests when multiple client requests are received', async () => {
317
+ it('queues up server requests when multiple mute changes happen to local track', async () => {
310
318
  let serverResponseResolve;
311
319
 
312
- MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(new Promise((resolve) => {
313
- serverResponseResolve = resolve;
314
- }));
315
-
316
- let firstClientPromiseResolved = false;
317
- let secondClientPromiseResolved = false;
320
+ MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(
321
+ new Promise((resolve) => {
322
+ serverResponseResolve = resolve;
323
+ })
324
+ );
318
325
 
319
326
  // 2 client requests, one after another without waiting for first one to resolve
320
- audio.handleClientRequest(meeting, true)
321
- .then(() => {
322
- firstClientPromiseResolved = true;
323
- });
324
- audio.handleClientRequest(meeting, false)
325
- .then(() => {
326
- secondClientPromiseResolved = true;
327
- });
328
-
329
- await testUtils.flushPromises();
327
+ await simulateAudioMuteChange(true);
328
+ await simulateAudioMuteChange(false);
330
329
 
331
330
  assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
332
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, true, undefined, meeting);
331
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, true, undefined);
333
332
 
334
333
  // now allow the first request to complete
335
334
  serverResponseResolve();
336
335
  await testUtils.flushPromises();
337
- assert.isTrue(firstClientPromiseResolved);
338
336
 
339
337
  // that should trigger the second server request to be sent
340
338
  assert.calledTwice(MeetingUtil.remoteUpdateAudioVideo);
341
- assert.strictEqual(false, MeetingUtil.remoteUpdateAudioVideo.getCall(1).args[0]);
342
- assert.strictEqual(undefined, MeetingUtil.remoteUpdateAudioVideo.getCall(1).args[1]);
343
- assert.strictEqual(meeting, MeetingUtil.remoteUpdateAudioVideo.getCall(1).args[2]);
339
+ assert.deepEqual([meeting, false, undefined], MeetingUtil.remoteUpdateAudioVideo.getCall(1).args);
344
340
 
345
341
  serverResponseResolve();
346
- await testUtils.flushPromises();
347
-
348
- assert.isTrue(secondClientPromiseResolved);
349
- });
350
-
351
- it('rejects client request to unmute if hard mute is used', (done) => {
352
- audio.handleServerRemoteMuteUpdate(true, false);
353
-
354
- audio.handleClientRequest(meeting, false)
355
- .then(() => {
356
- done(new Error('expected handleClientRequest to fail, but it did not!'));
357
- })
358
- .catch((e) => {
359
- assert.isTrue(e instanceof PermissionError);
360
- done();
361
- });
362
342
  });
363
343
 
364
344
  it('does not send remote mute for video', async () => {
365
345
  // mute
366
- await video.handleClientRequest(meeting, true);
346
+ await simulateVideoMuteChange(true);
367
347
 
368
348
  assert.isTrue(video.isMuted());
369
- assert.isTrue(video.isSelf());
370
349
 
371
350
  // check local mute is done, but not remote one
372
- assert.calledWith(Media.setLocalTrack, false, meeting.mediaProperties.videoTrack);
373
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, undefined, true, meeting);
351
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, true);
374
352
  assert.notCalled(meeting.members.muteMember);
375
353
 
376
- Media.setLocalTrack.resetHistory();
377
354
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
378
355
  meeting.members.muteMember.resetHistory();
379
356
 
380
357
  // unmute
381
- await video.handleClientRequest(meeting, false);
358
+ await simulateVideoMuteChange(false);
382
359
 
383
360
  assert.isFalse(video.isMuted());
384
- assert.isFalse(video.isSelf());
385
361
 
386
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.videoTrack);
387
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, undefined, false, meeting);
362
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, false);
388
363
  assert.notCalled(meeting.members.muteMember);
389
364
  });
390
365
 
391
- it('sends correct audio value when sending local mute for video', async () => {
366
+ it('sends undefined value for the other media type when sending local mute', async () => {
392
367
  // make sure the meeting object has mute state machines for both audio and video
393
368
  meeting.audio = audio;
394
369
  meeting.video = video;
395
370
 
396
- // mute audio -> request sent to server should have video unmuted
397
- await audio.handleClientRequest(meeting, true);
398
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, true, false, meeting);
371
+ // mute audio -> the call to remoteUpdateAudioVideo should have video undefined
372
+ await simulateAudioMuteChange(true);
373
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, true, undefined);
399
374
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
400
375
 
401
- // now mute video -> request sent to server should have mute for both audio and video
402
- await video.handleClientRequest(meeting, true);
403
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, true, true, meeting);
376
+ // now mute video -> the call to remoteUpdateAudioVideo should have mute for video and undefined for audio
377
+ await simulateVideoMuteChange(true);
378
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, true);
404
379
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
405
380
 
406
- // now unmute the audio -> request sent to server should still have video muted
407
- await audio.handleClientRequest(meeting, false);
408
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, false, true, meeting);
381
+ // now unmute the audio -> the call to remoteUpdateAudioVideo should have video undefined
382
+ await simulateAudioMuteChange(false);
383
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, false, undefined);
409
384
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
410
385
 
411
- // unmute video -> request sent to server should have both audio and video unmuted
412
- await video.handleClientRequest(meeting, false);
413
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, false, false, meeting);
386
+ // unmute video -> the call to remoteUpdateAudioVideo should have both audio undefined
387
+ await simulateVideoMuteChange(false);
388
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, false);
414
389
  });
415
390
  });
391
+
392
+ describe('#init, #handleLocalTrackChange', () => {
393
+ let meeting;
394
+ let muteState;
395
+ let setServerMutedSpy;
396
+ let setMutedSpy, setUnmuteAllowedSpy;
397
+
398
+ const setupMeeting = (mediaType, remoteMuted = false, muted = false, defineTracks = true) => {
399
+ const remoteMuteField = mediaType === AUDIO ? 'remoteMuted' : 'remoteVideoMuted';
400
+
401
+ meeting = {
402
+ mediaProperties: {
403
+ audioTrack: defineTracks ? createFakeLocalTrack('fake audio track', muted) : undefined,
404
+ videoTrack: defineTracks ? createFakeLocalTrack('fake video track', muted) : undefined,
405
+ },
406
+ [remoteMuteField]: remoteMuted,
407
+ unmuteAllowed: true,
408
+ unmuteVideoAllowed: true,
409
+
410
+ locusInfo: {
411
+ onFullLocus: sinon.stub(),
412
+ },
413
+ members: {
414
+ selfId: 'fake self id',
415
+ muteMember: sinon.stub().resolves(),
416
+ },
417
+ };
418
+ };
419
+
420
+ const setup = async (mediaType, remoteMuted = false, muted = false, defineTracks = true) => {
421
+
422
+ setupMeeting(mediaType, remoteMuted, muted, defineTracks);
423
+
424
+ muteState = createMuteState(mediaType, meeting, true);
425
+ muteState.handleLocalTrackChange(meeting);
426
+
427
+ await testUtils.flushPromises();
428
+
429
+ MeetingUtil.remoteUpdateAudioVideo.resetHistory();
430
+ }
431
+
432
+ const setupSpies = (mediaType) => {
433
+ setUnmuteAllowedSpy = mediaType === AUDIO ? meeting.mediaProperties.audioTrack?.setUnmuteAllowed : meeting.mediaProperties.videoTrack?.setUnmuteAllowed;
434
+ setServerMutedSpy = mediaType === AUDIO ? meeting.mediaProperties.audioTrack?.setServerMuted : meeting.mediaProperties.videoTrack?.setServerMuted;
435
+ setMutedSpy = mediaType === AUDIO ? meeting.mediaProperties.audioTrack?.setMuted : meeting.mediaProperties.videoTrack?.setMuted;
436
+
437
+ clearSpies();
438
+ };
439
+
440
+ const clearSpies = () => {
441
+ setUnmuteAllowedSpy?.resetHistory();
442
+ setServerMutedSpy?.resetHistory();
443
+ setMutedSpy?.resetHistory();
444
+ };
445
+ const tests = [
446
+ {mediaType: AUDIO, title: 'audio'},
447
+ {mediaType: VIDEO, title: 'video'}
448
+ ];
449
+
450
+ tests.forEach(({mediaType, title}) =>
451
+ describe(title, () => {
452
+ let originalRemoteUpdateAudioVideo;
453
+
454
+ beforeEach(() => {
455
+ originalRemoteUpdateAudioVideo = MeetingUtil.remoteUpdateAudioVideo;
456
+ MeetingUtil.remoteUpdateAudioVideo = sinon.stub().resolves({info: 'fake locus'});
457
+ });
458
+
459
+ afterEach(() => {
460
+ MeetingUtil.remoteUpdateAudioVideo = originalRemoteUpdateAudioVideo;
461
+ sinon.restore();
462
+ });
463
+
464
+ describe('#handleLocalTrackChange',() => {
465
+
466
+ it('calls init()', async () => {
467
+ await setup(mediaType);
468
+ const spy = sinon.spy(muteState, 'init');
469
+ muteState.handleLocalTrackChange(meeting);
470
+ assert.calledOnceWithExactly(spy, meeting);
471
+ });
472
+ });
473
+
474
+ describe('#init', () => {
475
+
476
+ // does the setup by calling new MuteState() so that MuteState.init() doesn't get called
477
+ const setupWithoutInit = async (mediaType, remoteMuted = false, muted = false, defineTracks = true) => {
478
+
479
+ setupMeeting(mediaType, remoteMuted, muted, defineTracks);
480
+
481
+ muteState = new MuteState(mediaType, meeting, true);
482
+ }
483
+
484
+ it('nothing goes bad when track is undefined', async () => {
485
+ await setupWithoutInit(mediaType, false, false, false);
486
+ setupSpies(mediaType);
487
+
488
+ muteState.init(meeting);
489
+
490
+ assert.isTrue(muteState.state.client.localMute);
491
+ });
492
+
493
+ it('tests when track muted is true and remoteMuted is false', async () => {
494
+ await setupWithoutInit(mediaType, false, true);
495
+ setupSpies(mediaType);
496
+
497
+ muteState.init(meeting);
498
+
499
+ assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
500
+ assert.notCalled(setServerMutedSpy);
501
+ assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
502
+ assert.isTrue(muteState.state.client.localMute);
503
+ });
504
+
505
+
506
+ it('tests when track muted is false and remoteMuted is false', async () => {
507
+ await setupWithoutInit(mediaType, false, false);
508
+ setupSpies(mediaType);
509
+ muteState.state.server.localMute = true;
510
+
511
+ muteState.init(meeting);
512
+
513
+ assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
514
+ assert.notCalled(setServerMutedSpy);
515
+ assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
516
+ assert.isFalse(muteState.state.client.localMute);
517
+ });
518
+
519
+ it('tests when remoteMuted is true', async () => {
520
+ // testing that muteLocalTrack is called
521
+ await setupWithoutInit(mediaType, true);
522
+ setupSpies(mediaType);
523
+
524
+ muteState.init(meeting);
525
+
526
+ assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
527
+ assert.calledOnceWithExactly(setServerMutedSpy, true, 'remotelyMuted');
528
+ });
529
+ });
530
+
531
+ describe('#handleLocalTrackMuteStateChange', () => {
532
+
533
+ it('checks when ignoreMuteStateChange is true nothing changes', async () => {
534
+ await setup(mediaType, false, false);
535
+ muteState.ignoreMuteStateChange = true;
536
+
537
+ muteState.handleLocalTrackMuteStateChange(meeting, true);
538
+ assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
539
+
540
+ assert.isFalse(muteState.state.client.localMute);
541
+ });
542
+
543
+ it('tests localMute - true to false', async () => {
544
+ await setup(mediaType, false, true);
545
+
546
+ muteState.handleLocalTrackMuteStateChange(meeting, false);
547
+ assert.equal(muteState.state.client.localMute, false);
548
+ assert.called(MeetingUtil.remoteUpdateAudioVideo);
549
+ });
550
+
551
+ it('tests localMute - false to true', async () => {
552
+ await setup(mediaType, false, false);
553
+
554
+ muteState.handleLocalTrackMuteStateChange(meeting, true);
555
+ assert.equal(muteState.state.client.localMute, true);
556
+ assert.called(MeetingUtil.remoteUpdateAudioVideo);
557
+ });
558
+ });
559
+
560
+ describe('#applyClientStateLocally', () => {
561
+
562
+ afterEach(() => {
563
+ sinon.restore();
564
+ });
565
+
566
+ it('calls setServerMuted on the track', async () => {
567
+ await setup(mediaType);
568
+ setupSpies(mediaType);
569
+
570
+ muteState.applyClientStateLocally(meeting, 'somereason');
571
+ assert.calledOnceWithExactly(setServerMutedSpy, muteState.state.client.localMute, 'somereason');
572
+ assert.notCalled(setMutedSpy);
573
+ });
574
+
575
+ it('nothing explodes when tracks are undefined', async () => {
576
+ await setup(mediaType, false, false, false);
577
+ setupSpies(mediaType);
578
+
579
+ muteState.applyClientStateLocally(meeting, 'somereason');
580
+ });
581
+ });
582
+
583
+ })
584
+ );
585
+ });
586
+
416
587
  });
417
588
  });