@webex/plugin-meetings 3.0.0-beta.31 → 3.0.0-beta.310

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 (378) hide show
  1. package/README.md +46 -8
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +342 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +94 -15
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/edit-lock-error.js +52 -0
  11. package/dist/breakouts/edit-lock-error.js.map +1 -0
  12. package/dist/breakouts/events.js +45 -0
  13. package/dist/breakouts/events.js.map +1 -0
  14. package/dist/breakouts/index.js +709 -35
  15. package/dist/breakouts/index.js.map +1 -1
  16. package/dist/breakouts/utils.js +45 -1
  17. package/dist/breakouts/utils.js.map +1 -1
  18. package/dist/common/errors/no-meeting-info.js +51 -0
  19. package/dist/common/errors/no-meeting-info.js.map +1 -0
  20. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  21. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  22. package/dist/common/errors/webex-errors.js +48 -7
  23. package/dist/common/errors/webex-errors.js.map +1 -1
  24. package/dist/common/logs/logger-proxy.js +1 -1
  25. package/dist/common/logs/logger-proxy.js.map +1 -1
  26. package/dist/common/logs/request.js +5 -1
  27. package/dist/common/logs/request.js.map +1 -1
  28. package/dist/common/queue.js +24 -9
  29. package/dist/common/queue.js.map +1 -1
  30. package/dist/config.js +5 -11
  31. package/dist/config.js.map +1 -1
  32. package/dist/constants.js +233 -29
  33. package/dist/constants.js.map +1 -1
  34. package/dist/controls-options-manager/enums.js +14 -2
  35. package/dist/controls-options-manager/enums.js.map +1 -1
  36. package/dist/controls-options-manager/index.js +109 -15
  37. package/dist/controls-options-manager/index.js.map +1 -1
  38. package/dist/controls-options-manager/types.js +7 -0
  39. package/dist/controls-options-manager/types.js.map +1 -0
  40. package/dist/controls-options-manager/util.js +309 -18
  41. package/dist/controls-options-manager/util.js.map +1 -1
  42. package/dist/index.js +112 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/interpretation/collection.js +23 -0
  45. package/dist/interpretation/collection.js.map +1 -0
  46. package/dist/interpretation/index.js +366 -0
  47. package/dist/interpretation/index.js.map +1 -0
  48. package/dist/interpretation/siLanguage.js +25 -0
  49. package/dist/interpretation/siLanguage.js.map +1 -0
  50. package/dist/locus-info/controlsUtils.js +91 -2
  51. package/dist/locus-info/controlsUtils.js.map +1 -1
  52. package/dist/locus-info/index.js +383 -62
  53. package/dist/locus-info/index.js.map +1 -1
  54. package/dist/locus-info/infoUtils.js +7 -1
  55. package/dist/locus-info/infoUtils.js.map +1 -1
  56. package/dist/locus-info/mediaSharesUtils.js +57 -1
  57. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  58. package/dist/locus-info/parser.js +249 -72
  59. package/dist/locus-info/parser.js.map +1 -1
  60. package/dist/locus-info/selfUtils.js +89 -14
  61. package/dist/locus-info/selfUtils.js.map +1 -1
  62. package/dist/media/index.js +61 -116
  63. package/dist/media/index.js.map +1 -1
  64. package/dist/media/properties.js +73 -124
  65. package/dist/media/properties.js.map +1 -1
  66. package/dist/meeting/in-meeting-actions.js +82 -2
  67. package/dist/meeting/in-meeting-actions.js.map +1 -1
  68. package/dist/meeting/index.js +3777 -2929
  69. package/dist/meeting/index.js.map +1 -1
  70. package/dist/meeting/locusMediaRequest.js +292 -0
  71. package/dist/meeting/locusMediaRequest.js.map +1 -0
  72. package/dist/meeting/muteState.js +230 -124
  73. package/dist/meeting/muteState.js.map +1 -1
  74. package/dist/meeting/request.js +260 -196
  75. package/dist/meeting/request.js.map +1 -1
  76. package/dist/meeting/util.js +601 -417
  77. package/dist/meeting/util.js.map +1 -1
  78. package/dist/meeting-info/index.js +73 -7
  79. package/dist/meeting-info/index.js.map +1 -1
  80. package/dist/meeting-info/meeting-info-v2.js +192 -51
  81. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  82. package/dist/meeting-info/util.js +1 -1
  83. package/dist/meeting-info/util.js.map +1 -1
  84. package/dist/meeting-info/utilv2.js +36 -36
  85. package/dist/meeting-info/utilv2.js.map +1 -1
  86. package/dist/meetings/collection.js +39 -0
  87. package/dist/meetings/collection.js.map +1 -1
  88. package/dist/meetings/index.js +415 -115
  89. package/dist/meetings/index.js.map +1 -1
  90. package/dist/meetings/meetings.types.js +7 -0
  91. package/dist/meetings/meetings.types.js.map +1 -0
  92. package/dist/meetings/request.js +2 -0
  93. package/dist/meetings/request.js.map +1 -1
  94. package/dist/meetings/util.js +72 -6
  95. package/dist/meetings/util.js.map +1 -1
  96. package/dist/member/index.js +58 -0
  97. package/dist/member/index.js.map +1 -1
  98. package/dist/member/types.js +25 -0
  99. package/dist/member/types.js.map +1 -0
  100. package/dist/member/util.js +132 -25
  101. package/dist/member/util.js.map +1 -1
  102. package/dist/members/collection.js +10 -0
  103. package/dist/members/collection.js.map +1 -1
  104. package/dist/members/index.js +102 -6
  105. package/dist/members/index.js.map +1 -1
  106. package/dist/members/request.js +106 -38
  107. package/dist/members/request.js.map +1 -1
  108. package/dist/members/types.js +15 -0
  109. package/dist/members/types.js.map +1 -0
  110. package/dist/members/util.js +326 -232
  111. package/dist/members/util.js.map +1 -1
  112. package/dist/metrics/constants.js +13 -5
  113. package/dist/metrics/constants.js.map +1 -1
  114. package/dist/metrics/index.js +1 -468
  115. package/dist/metrics/index.js.map +1 -1
  116. package/dist/multistream/mediaRequestManager.js +238 -49
  117. package/dist/multistream/mediaRequestManager.js.map +1 -1
  118. package/dist/multistream/receiveSlot.js +29 -16
  119. package/dist/multistream/receiveSlot.js.map +1 -1
  120. package/dist/multistream/receiveSlotManager.js +39 -36
  121. package/dist/multistream/receiveSlotManager.js.map +1 -1
  122. package/dist/multistream/remoteMedia.js +44 -18
  123. package/dist/multistream/remoteMedia.js.map +1 -1
  124. package/dist/multistream/remoteMediaGroup.js +60 -3
  125. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  126. package/dist/multistream/remoteMediaManager.js +209 -59
  127. package/dist/multistream/remoteMediaManager.js.map +1 -1
  128. package/dist/multistream/sendSlotManager.js +233 -0
  129. package/dist/multistream/sendSlotManager.js.map +1 -0
  130. package/dist/reachability/index.js +225 -59
  131. package/dist/reachability/index.js.map +1 -1
  132. package/dist/reachability/request.js +17 -8
  133. package/dist/reachability/request.js.map +1 -1
  134. package/dist/reconnection-manager/index.js +201 -156
  135. package/dist/reconnection-manager/index.js.map +1 -1
  136. package/dist/recording-controller/index.js +21 -2
  137. package/dist/recording-controller/index.js.map +1 -1
  138. package/dist/recording-controller/util.js +9 -8
  139. package/dist/recording-controller/util.js.map +1 -1
  140. package/dist/roap/index.js +62 -32
  141. package/dist/roap/index.js.map +1 -1
  142. package/dist/roap/request.js +112 -97
  143. package/dist/roap/request.js.map +1 -1
  144. package/dist/roap/turnDiscovery.js +95 -36
  145. package/dist/roap/turnDiscovery.js.map +1 -1
  146. package/dist/rtcMetrics/constants.js +12 -0
  147. package/dist/rtcMetrics/constants.js.map +1 -0
  148. package/dist/rtcMetrics/index.js +117 -0
  149. package/dist/rtcMetrics/index.js.map +1 -0
  150. package/dist/statsAnalyzer/index.js +86 -78
  151. package/dist/statsAnalyzer/index.js.map +1 -1
  152. package/dist/statsAnalyzer/mqaUtil.js +11 -10
  153. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  154. package/dist/types/annotation/annotation.types.d.ts +42 -0
  155. package/dist/types/annotation/constants.d.ts +31 -0
  156. package/dist/types/annotation/index.d.ts +117 -0
  157. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  158. package/dist/types/breakouts/events.d.ts +8 -0
  159. package/dist/types/breakouts/utils.d.ts +14 -0
  160. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  161. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  162. package/dist/types/common/errors/webex-errors.d.ts +25 -1
  163. package/dist/types/common/logs/request.d.ts +2 -0
  164. package/dist/types/common/queue.d.ts +9 -7
  165. package/dist/types/config.d.ts +1 -7
  166. package/dist/types/constants.d.ts +194 -24
  167. package/dist/types/controls-options-manager/enums.d.ts +11 -1
  168. package/dist/types/controls-options-manager/index.d.ts +17 -1
  169. package/dist/types/controls-options-manager/types.d.ts +43 -0
  170. package/dist/types/controls-options-manager/util.d.ts +1 -7
  171. package/dist/types/index.d.ts +6 -4
  172. package/dist/types/interpretation/collection.d.ts +5 -0
  173. package/dist/types/interpretation/index.d.ts +5 -0
  174. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  175. package/dist/types/locus-info/index.d.ts +57 -4
  176. package/dist/types/locus-info/parser.d.ts +67 -6
  177. package/dist/types/media/index.d.ts +2 -0
  178. package/dist/types/media/properties.d.ts +34 -48
  179. package/dist/types/meeting/in-meeting-actions.d.ts +82 -2
  180. package/dist/types/meeting/index.d.ts +463 -510
  181. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  182. package/dist/types/meeting/muteState.d.ts +99 -23
  183. package/dist/types/meeting/request.d.ts +72 -43
  184. package/dist/types/meeting/util.d.ts +101 -1
  185. package/dist/types/meeting-info/index.d.ts +13 -1
  186. package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
  187. package/dist/types/meetings/collection.d.ts +17 -0
  188. package/dist/types/meetings/index.d.ts +98 -20
  189. package/dist/types/meetings/meetings.types.d.ts +4 -0
  190. package/dist/types/member/index.d.ts +14 -0
  191. package/dist/types/member/types.d.ts +32 -0
  192. package/dist/types/members/collection.d.ts +5 -0
  193. package/dist/types/members/index.d.ts +35 -2
  194. package/dist/types/members/request.d.ts +73 -9
  195. package/dist/types/members/types.d.ts +25 -0
  196. package/dist/types/members/util.d.ts +214 -1
  197. package/dist/types/metrics/constants.d.ts +12 -4
  198. package/dist/types/metrics/index.d.ts +4 -119
  199. package/dist/types/multistream/mediaRequestManager.d.ts +73 -5
  200. package/dist/types/multistream/receiveSlot.d.ts +13 -11
  201. package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
  202. package/dist/types/multistream/remoteMedia.d.ts +8 -29
  203. package/dist/types/multistream/remoteMediaGroup.d.ts +0 -9
  204. package/dist/types/multistream/remoteMediaManager.d.ts +46 -2
  205. package/dist/types/multistream/sendSlotManager.d.ts +61 -0
  206. package/dist/types/reachability/index.d.ts +61 -7
  207. package/dist/types/reachability/request.d.ts +7 -3
  208. package/dist/types/reconnection-manager/index.d.ts +9 -0
  209. package/dist/types/recording-controller/index.d.ts +15 -1
  210. package/dist/types/recording-controller/util.d.ts +5 -4
  211. package/dist/types/roap/index.d.ts +2 -1
  212. package/dist/types/roap/request.d.ts +15 -11
  213. package/dist/types/roap/turnDiscovery.d.ts +21 -3
  214. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  215. package/dist/types/rtcMetrics/index.d.ts +47 -0
  216. package/dist/types/statsAnalyzer/index.d.ts +7 -1
  217. package/dist/types/webinar/collection.d.ts +16 -0
  218. package/dist/types/webinar/index.d.ts +5 -0
  219. package/dist/webinar/collection.js +44 -0
  220. package/dist/webinar/collection.js.map +1 -0
  221. package/dist/webinar/index.js +69 -0
  222. package/dist/webinar/index.js.map +1 -0
  223. package/package.json +23 -20
  224. package/src/annotation/annotation.types.ts +50 -0
  225. package/src/annotation/constants.ts +36 -0
  226. package/src/annotation/index.ts +328 -0
  227. package/src/breakouts/README.md +42 -12
  228. package/src/breakouts/breakout.ts +67 -9
  229. package/src/breakouts/edit-lock-error.ts +25 -0
  230. package/src/breakouts/events.ts +56 -0
  231. package/src/breakouts/index.ts +592 -20
  232. package/src/breakouts/utils.ts +42 -0
  233. package/src/common/errors/no-meeting-info.ts +24 -0
  234. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  235. package/src/common/errors/webex-errors.ts +44 -2
  236. package/src/common/logs/logger-proxy.ts +1 -1
  237. package/src/common/logs/request.ts +5 -1
  238. package/src/common/queue.ts +22 -8
  239. package/src/config.ts +4 -10
  240. package/src/constants.ts +221 -19
  241. package/src/controls-options-manager/enums.ts +12 -0
  242. package/src/controls-options-manager/index.ts +116 -21
  243. package/src/controls-options-manager/types.ts +59 -0
  244. package/src/controls-options-manager/util.ts +294 -14
  245. package/src/index.ts +40 -0
  246. package/src/interpretation/README.md +60 -0
  247. package/src/interpretation/collection.ts +19 -0
  248. package/src/interpretation/index.ts +332 -0
  249. package/src/interpretation/siLanguage.ts +18 -0
  250. package/src/locus-info/controlsUtils.ts +108 -0
  251. package/src/locus-info/index.ts +413 -59
  252. package/src/locus-info/infoUtils.ts +10 -2
  253. package/src/locus-info/mediaSharesUtils.ts +64 -0
  254. package/src/locus-info/parser.ts +258 -47
  255. package/src/locus-info/selfUtils.ts +81 -5
  256. package/src/media/index.ts +102 -122
  257. package/src/media/properties.ts +87 -110
  258. package/src/meeting/in-meeting-actions.ts +163 -3
  259. package/src/meeting/index.ts +3132 -2541
  260. package/src/meeting/locusMediaRequest.ts +313 -0
  261. package/src/meeting/muteState.ts +229 -131
  262. package/src/meeting/request.ts +177 -121
  263. package/src/meeting/util.ts +588 -394
  264. package/src/meeting-info/index.ts +81 -8
  265. package/src/meeting-info/meeting-info-v2.ts +170 -14
  266. package/src/meeting-info/util.ts +1 -1
  267. package/src/meeting-info/utilv2.ts +23 -23
  268. package/src/meetings/collection.ts +33 -0
  269. package/src/meetings/index.ts +445 -123
  270. package/src/meetings/meetings.types.ts +12 -0
  271. package/src/meetings/request.ts +2 -0
  272. package/src/meetings/util.ts +80 -11
  273. package/src/member/index.ts +58 -0
  274. package/src/member/types.ts +38 -0
  275. package/src/member/util.ts +141 -25
  276. package/src/members/collection.ts +8 -0
  277. package/src/members/index.ts +134 -8
  278. package/src/members/request.ts +97 -17
  279. package/src/members/types.ts +29 -0
  280. package/src/members/util.ts +333 -240
  281. package/src/metrics/constants.ts +12 -4
  282. package/src/metrics/index.ts +1 -490
  283. package/src/multistream/mediaRequestManager.ts +289 -79
  284. package/src/multistream/receiveSlot.ts +31 -17
  285. package/src/multistream/receiveSlotManager.ts +34 -24
  286. package/src/multistream/remoteMedia.ts +27 -2
  287. package/src/multistream/remoteMediaGroup.ts +59 -0
  288. package/src/multistream/remoteMediaManager.ts +148 -30
  289. package/src/multistream/sendSlotManager.ts +170 -0
  290. package/src/reachability/index.ts +228 -37
  291. package/src/reachability/request.ts +17 -8
  292. package/src/reconnection-manager/index.ts +83 -56
  293. package/src/recording-controller/index.ts +20 -3
  294. package/src/recording-controller/util.ts +26 -9
  295. package/src/roap/index.ts +63 -32
  296. package/src/roap/request.ts +100 -104
  297. package/src/roap/turnDiscovery.ts +48 -26
  298. package/src/rtcMetrics/constants.ts +3 -0
  299. package/src/rtcMetrics/index.ts +100 -0
  300. package/src/statsAnalyzer/index.ts +105 -91
  301. package/src/statsAnalyzer/mqaUtil.ts +13 -14
  302. package/src/webinar/collection.ts +31 -0
  303. package/src/webinar/index.ts +62 -0
  304. package/test/integration/spec/converged-space-meetings.js +60 -3
  305. package/test/integration/spec/journey.js +320 -261
  306. package/test/integration/spec/space-meeting.js +76 -3
  307. package/test/unit/spec/annotation/index.ts +418 -0
  308. package/test/unit/spec/breakouts/breakout.ts +118 -28
  309. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  310. package/test/unit/spec/breakouts/events.ts +89 -0
  311. package/test/unit/spec/breakouts/index.ts +1395 -69
  312. package/test/unit/spec/breakouts/utils.js +52 -1
  313. package/test/unit/spec/common/queue.js +31 -2
  314. package/test/unit/spec/controls-options-manager/index.js +163 -0
  315. package/test/unit/spec/controls-options-manager/util.js +576 -60
  316. package/test/unit/spec/fixture/locus.js +1 -0
  317. package/test/unit/spec/interpretation/collection.ts +15 -0
  318. package/test/unit/spec/interpretation/index.ts +589 -0
  319. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  320. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  321. package/test/unit/spec/locus-info/index.js +1304 -33
  322. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  323. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  324. package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
  325. package/test/unit/spec/locus-info/parser.js +116 -35
  326. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  327. package/test/unit/spec/locus-info/selfUtils.js +208 -17
  328. package/test/unit/spec/media/index.ts +104 -37
  329. package/test/unit/spec/media/properties.ts +2 -2
  330. package/test/unit/spec/meeting/in-meeting-actions.ts +81 -3
  331. package/test/unit/spec/meeting/index.js +5216 -1956
  332. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  333. package/test/unit/spec/meeting/muteState.js +408 -208
  334. package/test/unit/spec/meeting/request.js +483 -49
  335. package/test/unit/spec/meeting/utils.js +679 -64
  336. package/test/unit/spec/meeting-info/index.js +300 -0
  337. package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
  338. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  339. package/test/unit/spec/meetings/collection.js +26 -0
  340. package/test/unit/spec/meetings/index.js +1011 -205
  341. package/test/unit/spec/meetings/utils.js +202 -2
  342. package/test/unit/spec/member/index.js +61 -6
  343. package/test/unit/spec/member/util.js +510 -34
  344. package/test/unit/spec/members/index.js +432 -1
  345. package/test/unit/spec/members/request.js +206 -27
  346. package/test/unit/spec/members/utils.js +210 -0
  347. package/test/unit/spec/metrics/index.js +1 -50
  348. package/test/unit/spec/multistream/mediaRequestManager.ts +803 -162
  349. package/test/unit/spec/multistream/receiveSlot.ts +28 -20
  350. package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
  351. package/test/unit/spec/multistream/remoteMedia.ts +30 -0
  352. package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
  353. package/test/unit/spec/multistream/remoteMediaManager.ts +326 -0
  354. package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
  355. package/test/unit/spec/reachability/index.ts +549 -9
  356. package/test/unit/spec/reachability/request.js +68 -0
  357. package/test/unit/spec/reconnection-manager/index.js +85 -9
  358. package/test/unit/spec/recording-controller/index.js +294 -218
  359. package/test/unit/spec/recording-controller/util.js +223 -96
  360. package/test/unit/spec/roap/index.ts +178 -64
  361. package/test/unit/spec/roap/request.ts +203 -85
  362. package/test/unit/spec/roap/turnDiscovery.ts +82 -36
  363. package/test/unit/spec/rtcMetrics/index.ts +73 -0
  364. package/test/unit/spec/stats-analyzer/index.js +136 -2
  365. package/test/unit/spec/webinar/collection.ts +13 -0
  366. package/test/unit/spec/webinar/index.ts +60 -0
  367. package/test/utils/integrationTestUtils.js +46 -0
  368. package/test/utils/testUtils.js +0 -52
  369. package/dist/meeting/effectsState.js +0 -262
  370. package/dist/meeting/effectsState.js.map +0 -1
  371. package/dist/metrics/config.js +0 -299
  372. package/dist/metrics/config.js.map +0 -1
  373. package/dist/types/meeting/effectsState.d.ts +0 -42
  374. package/dist/types/metrics/config.d.ts +0 -178
  375. package/src/index.js +0 -16
  376. package/src/meeting/effectsState.ts +0 -211
  377. package/src/metrics/config.ts +0 -495
  378. package/test/unit/spec/meeting/effectsState.js +0 -285
@@ -1,4 +1,4 @@
1
- import {SELF_ROLES, DISPLAY_HINTS} from '../constants';
1
+ import {SELF_ROLES, DISPLAY_HINTS, INTERSTITIAL_DISPLAY_HINTS} from '../constants';
2
2
 
3
3
  const InfoUtils: any = {};
4
4
 
@@ -9,7 +9,15 @@ InfoUtils.parse = (info, roles, isJoined = true) => {
9
9
  coHost: InfoUtils.parseCoHost(info),
10
10
  };
11
11
 
12
- let userDisplayHints = isJoined ? {...parsed.policy} : {};
12
+ let userDisplayHints = isJoined
13
+ ? {...parsed.policy}
14
+ : {
15
+ ...Object.fromEntries(
16
+ Object.entries(parsed.policy).filter(([hint]) =>
17
+ INTERSTITIAL_DISPLAY_HINTS.includes(hint)
18
+ )
19
+ ),
20
+ };
13
21
 
14
22
  if (roles.includes(SELF_ROLES.COHOST)) {
15
23
  userDisplayHints = {...userDisplayHints, ...parsed.coHost};
@@ -13,6 +13,10 @@ MediaSharesUtils.parse = (mediaShares: object) => {
13
13
  content: {
14
14
  beneficiaryId: MediaSharesUtils.getContentBeneficiaryId(mediaShares),
15
15
  disposition: MediaSharesUtils.getContentDisposition(mediaShares),
16
+ annotation: MediaSharesUtils.getContentAnnotation(mediaShares),
17
+ url: MediaSharesUtils.getContentUrl(mediaShares),
18
+ shareInstanceId: MediaSharesUtils.getShareInstanceId(mediaShares),
19
+ deviceUrlSharing: MediaSharesUtils.getContentBeneficiaryDeviceUrl(mediaShares),
16
20
  },
17
21
  whiteboard: {
18
22
  beneficiaryId: MediaSharesUtils.getWhiteboardBeneficiaryId(mediaShares),
@@ -140,6 +144,66 @@ MediaSharesUtils.getContentBeneficiaryId = (mediaShares: object) => {
140
144
  return contentFloor.beneficiary.id;
141
145
  };
142
146
 
147
+ /**
148
+ * get live annotation is sharing from media shares (content)
149
+ * @param {Object} mediaShares
150
+ * @returns {Object}
151
+ */
152
+ MediaSharesUtils.getContentAnnotation = (mediaShares: object) => {
153
+ const extractContent = MediaSharesUtils.extractContent(mediaShares);
154
+
155
+ if (!extractContent || !extractContent.annotation) {
156
+ return undefined;
157
+ }
158
+
159
+ return extractContent.annotation;
160
+ };
161
+
162
+ /**
163
+ * get url is sharing from media shares (content)
164
+ * @param {Object} mediaShares
165
+ * @returns {Object}
166
+ */
167
+ MediaSharesUtils.getContentUrl = (mediaShares: object) => {
168
+ const extractContent = MediaSharesUtils.extractContent(mediaShares);
169
+
170
+ if (!extractContent || !extractContent.url) {
171
+ return undefined;
172
+ }
173
+
174
+ return extractContent.url;
175
+ };
176
+
177
+ /**
178
+ * get shareInstanceId is sharing from media shares (content)
179
+ * @param {Object} mediaShares
180
+ * @returns {Object}
181
+ */
182
+ MediaSharesUtils.getShareInstanceId = (mediaShares: object) => {
183
+ const extractContent = MediaSharesUtils.extractContent(mediaShares);
184
+
185
+ if (!extractContent || !extractContent.floor || !extractContent.floor.shareInstanceId) {
186
+ return undefined;
187
+ }
188
+
189
+ return extractContent.floor.shareInstanceId;
190
+ };
191
+
192
+ /**
193
+ * get deviceUrl that is requesting the floor for media shares (content)
194
+ * @param {Object} mediaShares
195
+ * @returns {Object}
196
+ */
197
+ MediaSharesUtils.getContentBeneficiaryDeviceUrl = (mediaShares: object) => {
198
+ const contentFloor = MediaSharesUtils.extractContentFloor(mediaShares);
199
+
200
+ if (!contentFloor || !contentFloor.beneficiary || !contentFloor.beneficiary.deviceUrl) {
201
+ return null;
202
+ }
203
+
204
+ return contentFloor.beneficiary.deviceUrl;
205
+ };
206
+
143
207
  /**
144
208
  * get who is sharing from media shares (whiteboard)
145
209
  * @param {Object} mediaShares
@@ -1,8 +1,30 @@
1
1
  import {difference} from 'lodash';
2
2
 
3
- import SimpleQueue from '../common/queue';
3
+ import SortedQueue from '../common/queue';
4
4
  import LoggerProxy from '../common/logs/logger-proxy';
5
5
 
6
+ import Metrics from '../metrics';
7
+ import BEHAVIORAL_METRICS from '../metrics/constants';
8
+
9
+ const MAX_OOO_DELTA_COUNT = 5; // when we receive an out-of-order delta and the queue builds up to MAX_OOO_DELTA_COUNT, we do a sync with Locus
10
+ const OOO_DELTA_WAIT_TIME = 10000; // [ms] minimum wait time before we do a sync if we get out-of-order deltas
11
+ const OOO_DELTA_WAIT_TIME_RANDOM_DELAY = 5000; // [ms] max random delay added to OOO_DELTA_WAIT_TIME
12
+
13
+ type LocusDeltaDto = {
14
+ url: string;
15
+ baseSequence: {
16
+ rangeStart: number;
17
+ rangeEnd: number;
18
+ entries: number[];
19
+ };
20
+ sequence: {
21
+ rangeStart: number;
22
+ rangeEnd: number;
23
+ entries: number[];
24
+ };
25
+ syncUrl: string;
26
+ };
27
+
6
28
  /**
7
29
  * Locus Delta Parser
8
30
  * @private
@@ -10,11 +32,11 @@ import LoggerProxy from '../common/logs/logger-proxy';
10
32
  */
11
33
  export default class Parser {
12
34
  // processing status
13
- static status = {
14
- IDLE: 'IDLE',
15
- PAUSED: 'PAUSED',
16
- WORKING: 'WORKING',
17
- };
35
+ status:
36
+ | 'IDLE' // not doing anything
37
+ | 'PAUSED' // paused, because we are doing a sync
38
+ | 'WORKING' // processing a delta event
39
+ | 'BLOCKED'; // received an out-of-order delta, so waiting for the missing one
18
40
 
19
41
  // loci comparison states
20
42
  static loci = {
@@ -24,21 +46,60 @@ export default class Parser {
24
46
  DESYNC: 'DESYNC',
25
47
  USE_INCOMING: 'USE_INCOMING',
26
48
  USE_CURRENT: 'USE_CURRENT',
49
+ WAIT: 'WAIT',
27
50
  ERROR: 'ERROR',
51
+ LOCUS_URL_CHANGED: 'LOCUS_URL_CHANGED',
28
52
  };
29
53
 
30
- queue: any;
54
+ queue: SortedQueue<LocusDeltaDto>;
31
55
  workingCopy: any;
56
+ syncTimer: null | number | NodeJS.Timeout;
32
57
 
33
58
  /**
34
59
  * @constructs Parser
35
60
  */
36
61
  constructor() {
37
- this.queue = new SimpleQueue();
38
- // @ts-ignore - This is declared as static class member and again being initialized here from same
39
- this.status = Parser.status.IDLE;
62
+ const deltaCompareFunc = (left: LocusDeltaDto, right: LocusDeltaDto) => {
63
+ const {LT, GT} = Parser.loci;
64
+ const {extractComparisonState: extract} = Parser;
65
+
66
+ if (Parser.isSequenceEmpty(left)) {
67
+ return -1;
68
+ }
69
+ if (Parser.isSequenceEmpty(right)) {
70
+ return 1;
71
+ }
72
+ const result = extract(Parser.compareSequence(left.baseSequence, right.baseSequence));
73
+
74
+ if (result === LT) {
75
+ return -1;
76
+ }
77
+ if (result === GT) {
78
+ return 1;
79
+ }
80
+
81
+ return 0;
82
+ };
83
+
84
+ this.queue = new SortedQueue<LocusDeltaDto>(deltaCompareFunc);
85
+ this.status = 'IDLE';
40
86
  this.onDeltaAction = null;
41
87
  this.workingCopy = null;
88
+ this.syncTimer = null;
89
+ }
90
+
91
+ /**
92
+ * Returns a debug string representing a locus delta - useful for logging
93
+ *
94
+ * @param {LocusDeltaDto} locus Locus delta
95
+ * @returns {string}
96
+ */
97
+ static locus2string(locus: LocusDeltaDto) {
98
+ if (!locus.sequence?.entries) {
99
+ return 'invalid';
100
+ }
101
+
102
+ return locus.sequence.entries.length ? `seq=${locus.sequence.entries.at(-1)}` : 'empty';
42
103
  }
43
104
 
44
105
  /**
@@ -208,7 +269,7 @@ export default class Parser {
208
269
  * @returns {string} loci comparison state
209
270
  */
210
271
  private static compareDelta(current, incoming) {
211
- const {LT, GT, EQ, DESYNC, USE_INCOMING} = Parser.loci;
272
+ const {LT, GT, EQ, DESYNC, USE_INCOMING, WAIT, LOCUS_URL_CHANGED} = Parser.loci;
212
273
 
213
274
  const {extractComparisonState: extract} = Parser;
214
275
  const {packComparisonResult: pack} = Parser;
@@ -220,6 +281,13 @@ export default class Parser {
220
281
  return pack(Parser.compareToAction(comparison), result);
221
282
  }
222
283
 
284
+ if (incoming.url !== current.url) {
285
+ // when moving to/from a breakout session, the locus URL will change and also
286
+ // the baseSequence, making incoming and current incomparable, so use a
287
+ // unique comparison state
288
+ return pack(LOCUS_URL_CHANGED, result);
289
+ }
290
+
223
291
  comparison = Parser.compareSequence(current.sequence, incoming.baseSequence);
224
292
 
225
293
  switch (extract(comparison)) {
@@ -228,6 +296,21 @@ export default class Parser {
228
296
  comparison = USE_INCOMING;
229
297
  break;
230
298
 
299
+ case LT:
300
+ if (extract(Parser.compareSequence(incoming.baseSequence, incoming.sequence)) === EQ) {
301
+ // special case where Locus sends a delta with baseSequence === sequence to trigger a sync,
302
+ // because the delta event is too large to be sent over mercury connection
303
+ comparison = DESYNC;
304
+ } else {
305
+ // the incoming locus has baseSequence from the future, so it is out-of-order,
306
+ // we are missing 1 or more locus that should be in front of it, we need to wait for it
307
+ comparison = WAIT;
308
+
309
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.LOCUS_DELTA_OUT_OF_ORDER, {
310
+ stack: new Error().stack,
311
+ });
312
+ }
313
+ break;
231
314
  default:
232
315
  comparison = DESYNC;
233
316
  }
@@ -235,6 +318,49 @@ export default class Parser {
235
318
  return pack(comparison, result);
236
319
  }
237
320
 
321
+ /**
322
+ * Compares Locus sequences - it should be called only for full Locus DTOs, not deltas
323
+ *
324
+ * @param {Types~Locus} current Current working copy
325
+ * @param {Types~Locus} incomingFullDto New Full Locus DTO
326
+ * @returns {string} either Parser.loci.USE_INCOMING or Parser.loci.USE_CURRENT
327
+ */
328
+ static compareFullDtoSequence(current, incomingFullDto) {
329
+ if (Parser.isSequenceEmpty(current) || Parser.isSequenceEmpty(incomingFullDto)) {
330
+ return Parser.loci.USE_INCOMING;
331
+ }
332
+
333
+ // the sequence.entries list will always contain at least 1 entry
334
+ // https://sqbu-github.cisco.com/WebExSquared/cloud-apps/wiki/Locus-Sequence-Comparison-Algorithm
335
+
336
+ return incomingFullDto.sequence.entries.slice(-1)[0] > current.sequence.entries.slice(-1)[0]
337
+ ? Parser.loci.USE_INCOMING
338
+ : Parser.loci.USE_CURRENT;
339
+ }
340
+
341
+ /**
342
+ * Returns true if the incoming full locus DTO is newer than the current working copy
343
+ *
344
+ * @param {Types~Locus} incomingFullDto New Full Locus DTO
345
+ * @returns {string} either Parser.loci.USE_INCOMING or Parser.loci.USE_CURRENT
346
+ */
347
+ isNewFullLocus(incomingFullDto) {
348
+ if (!Parser.isLoci(incomingFullDto)) {
349
+ LoggerProxy.logger.info('Locus-info:parser#isNewFullLocus --> Ignoring non-locus object.');
350
+
351
+ return false;
352
+ }
353
+
354
+ if (!this.workingCopy) {
355
+ // we don't have a working copy yet, so any full locus is better than nothing
356
+ return true;
357
+ }
358
+
359
+ const comparisonResult = Parser.compareFullDtoSequence(this.workingCopy, incomingFullDto);
360
+
361
+ return comparisonResult === Parser.loci.USE_INCOMING;
362
+ }
363
+
238
364
  /**
239
365
  * Compares Locus sequences
240
366
  * @param {Types~Locus} current Current working copy
@@ -393,17 +519,10 @@ export default class Parser {
393
519
  */
394
520
  isValidLocus(newLoci) {
395
521
  let isValid = false;
396
- const {IDLE} = Parser.status;
397
522
  const {isLoci} = Parser;
398
- // @ts-ignore
399
- const setStatus = (status) => {
400
- // @ts-ignore
401
- this.status = status;
402
- };
403
523
 
404
524
  // one or both objects are not locus delta events
405
525
  if (!isLoci(this.workingCopy) || !isLoci(newLoci)) {
406
- setStatus(IDLE);
407
526
  LoggerProxy.logger.info(
408
527
  'Locus-info:parser#processDeltaEvent --> Ignoring non-locus object. workingCopy:',
409
528
  this.workingCopy,
@@ -455,19 +574,25 @@ export default class Parser {
455
574
  * @returns {undefined}
456
575
  */
457
576
  nextEvent() {
458
- // @ts-ignore
459
- if (this.status === Parser.status.PAUSED) {
577
+ if (this.status === 'PAUSED') {
460
578
  LoggerProxy.logger.info('Locus-info:parser#nextEvent --> Locus parser paused.');
461
579
 
462
580
  return;
463
581
  }
464
582
 
583
+ if (this.status === 'BLOCKED') {
584
+ LoggerProxy.logger.info(
585
+ 'Locus-info:parser#nextEvent --> Locus parser blocked by out-of-order delta.'
586
+ );
587
+
588
+ return;
589
+ }
590
+
465
591
  // continue processing until queue is empty
466
592
  if (this.queue.size() > 0) {
467
593
  this.processDeltaEvent();
468
594
  } else {
469
- // @ts-ignore
470
- this.status = Parser.status.IDLE;
595
+ this.status = 'IDLE';
471
596
  }
472
597
  }
473
598
 
@@ -478,7 +603,7 @@ export default class Parser {
478
603
  * @param {Types~Locus} locus Locus delta
479
604
  * @returns {undefined}
480
605
  */
481
- // eslint-disable-next-line no-unused-vars
606
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
482
607
  onDeltaAction(action: string, locus) {}
483
608
 
484
609
  /**
@@ -489,15 +614,20 @@ export default class Parser {
489
614
  onDeltaEvent(loci) {
490
615
  // enqueue the new loci
491
616
  this.queue.enqueue(loci);
492
- // start processing events in the queue if idle
493
- // and a function handler is defined
494
- // @ts-ignore
495
- if (this.status === Parser.status.IDLE && this.onDeltaAction) {
496
- // Update status, ensure we only process one event at a time.
497
- // @ts-ignore
498
- this.status = Parser.status.WORKING;
499
617
 
500
- this.processDeltaEvent();
618
+ if (this.onDeltaAction) {
619
+ if (this.status === 'BLOCKED') {
620
+ if (this.queue.size() > MAX_OOO_DELTA_COUNT) {
621
+ this.triggerSync('queue too big, blocked on out-of-order delta');
622
+ } else {
623
+ this.processDeltaEvent();
624
+ }
625
+ } else if (this.status === 'IDLE') {
626
+ // Update status, ensure we only process one event at a time.
627
+ this.status = 'WORKING';
628
+
629
+ this.processDeltaEvent();
630
+ }
501
631
  }
502
632
  }
503
633
 
@@ -516,11 +646,55 @@ export default class Parser {
516
646
  * @returns {undefined}
517
647
  */
518
648
  pause() {
519
- // @ts-ignore
520
- this.status = Parser.status.PAUSED;
649
+ this.status = 'PAUSED';
521
650
  LoggerProxy.logger.info('Locus-info:parser#pause --> Locus parser paused.');
522
651
  }
523
652
 
653
+ /**
654
+ * Triggers a sync with Locus
655
+ *
656
+ * @param {string} reason used just for logging
657
+ * @returns {undefined}
658
+ */
659
+ private triggerSync(reason: string) {
660
+ LoggerProxy.logger.info(`Locus-info:parser#triggerSync --> doing sync, reason: ${reason}`);
661
+ this.stopSyncTimer();
662
+ this.pause();
663
+ this.onDeltaAction(Parser.loci.DESYNC, this.workingCopy);
664
+ }
665
+
666
+ /**
667
+ * Starts a timer with a random delay. When that timer expires we will do a sync.
668
+ *
669
+ * The main purpose of this timer is to handle a case when we get some out-of-order deltas,
670
+ * so we start waiting to receive the missing delta. If that delta never arrives, this timer
671
+ * will trigger a sync with Locus.
672
+ *
673
+ * @returns {undefined}
674
+ */
675
+ private startSyncTimer() {
676
+ if (this.syncTimer === null) {
677
+ const timeout = OOO_DELTA_WAIT_TIME + Math.random() * OOO_DELTA_WAIT_TIME_RANDOM_DELAY;
678
+
679
+ this.syncTimer = setTimeout(() => {
680
+ this.syncTimer = null;
681
+ this.triggerSync('timer expired, blocked on out-of-order delta');
682
+ }, timeout);
683
+ }
684
+ }
685
+
686
+ /**
687
+ * Stops the timer for triggering a sync
688
+ *
689
+ * @returns {undefined}
690
+ */
691
+ private stopSyncTimer() {
692
+ if (this.syncTimer !== null) {
693
+ clearTimeout(this.syncTimer);
694
+ this.syncTimer = null;
695
+ }
696
+ }
697
+
524
698
  /**
525
699
  * Processes next locus delta in the queue,
526
700
  * continues until the queue is empty
@@ -528,11 +702,13 @@ export default class Parser {
528
702
  * @returns {undefined}
529
703
  */
530
704
  processDeltaEvent() {
531
- const {DESYNC, USE_INCOMING} = Parser.loci;
705
+ const {DESYNC, USE_INCOMING, WAIT, LOCUS_URL_CHANGED} = Parser.loci;
532
706
  const {extractComparisonState: extract} = Parser;
533
707
  const newLoci = this.queue.dequeue();
534
708
 
535
709
  if (!this.isValidLocus(newLoci)) {
710
+ this.nextEvent();
711
+
536
712
  return;
537
713
  }
538
714
 
@@ -543,23 +719,59 @@ export default class Parser {
543
719
  // for full debugging.
544
720
  LoggerProxy.logger.debug(`Locus-info:parser#processDeltaEvent --> Locus Debug: ${result}`);
545
721
 
546
- if (lociComparison === DESYNC) {
547
- // wait for desync response
548
- this.pause();
549
- } else if (lociComparison === USE_INCOMING) {
550
- // update working copy for future comparisons.
551
- // Note: The working copy of parser gets updated in .onFullLocus()
552
- // and here when USE_INCOMING locus.
553
- this.workingCopy = newLoci;
722
+ let needToWait = false;
723
+
724
+ switch (lociComparison) {
725
+ case DESYNC:
726
+ // wait for desync response
727
+ this.pause();
728
+ break;
729
+
730
+ case USE_INCOMING:
731
+ case LOCUS_URL_CHANGED:
732
+ // update working copy for future comparisons.
733
+ // Note: The working copy of parser gets updated in .onFullLocus()
734
+ // and here when USE_INCOMING or LOCUS_URL_CHANGED locus.
735
+ this.workingCopy = newLoci;
736
+ break;
737
+
738
+ case WAIT:
739
+ // we've taken newLoci from the front of the queue, so put it back there as we have to wait
740
+ // for the one that should be in front of it, before we can process it
741
+ this.queue.enqueue(newLoci);
742
+ needToWait = true;
743
+ break;
744
+
745
+ default:
746
+ break;
747
+ }
748
+
749
+ if (needToWait) {
750
+ this.status = 'BLOCKED';
751
+ this.startSyncTimer();
752
+ } else {
753
+ this.stopSyncTimer();
754
+
755
+ if (this.status === 'BLOCKED') {
756
+ // we are not blocked anymore
757
+ this.status = 'WORKING';
758
+
759
+ LoggerProxy.logger.info(
760
+ `Locus-info:parser#processDeltaEvent --> received delta that we were waiting for ${Parser.locus2string(
761
+ newLoci
762
+ )}, not blocked anymore`
763
+ );
764
+ }
554
765
  }
555
766
 
556
767
  if (this.onDeltaAction) {
557
768
  LoggerProxy.logger.info(
558
- `Locus-info:parser#processDeltaEvent --> Locus Delta Action: ${lociComparison}`
769
+ `Locus-info:parser#processDeltaEvent --> Locus Delta ${Parser.locus2string(
770
+ newLoci
771
+ )}, Action: ${lociComparison}`
559
772
  );
560
773
 
561
- // eslint-disable-next-line no-useless-call
562
- this.onDeltaAction.call(this, lociComparison, newLoci);
774
+ this.onDeltaAction(lociComparison, newLoci);
563
775
  }
564
776
 
565
777
  this.nextEvent();
@@ -571,8 +783,7 @@ export default class Parser {
571
783
  */
572
784
  resume() {
573
785
  LoggerProxy.logger.info('Locus-info:parser#resume --> Locus parser resumed.');
574
- // @ts-ignore
575
- this.status = Parser.status.WORKING;
786
+ this.status = 'WORKING';
576
787
  this.nextEvent();
577
788
  }
578
789