@webex/plugin-meetings 3.7.0 → 3.8.0

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 (351) hide show
  1. package/dist/annotation/annotation.types.d.ts +42 -0
  2. package/dist/annotation/constants.d.ts +31 -0
  3. package/dist/annotation/index.d.ts +117 -0
  4. package/dist/annotation/index.js +17 -0
  5. package/dist/annotation/index.js.map +1 -1
  6. package/dist/breakouts/breakout.d.ts +8 -0
  7. package/dist/breakouts/breakout.js +1 -1
  8. package/dist/breakouts/collection.d.ts +5 -0
  9. package/dist/breakouts/edit-lock-error.d.ts +15 -0
  10. package/dist/breakouts/events.d.ts +8 -0
  11. package/dist/breakouts/index.d.ts +5 -0
  12. package/dist/breakouts/index.js +1 -1
  13. package/dist/breakouts/request.d.ts +22 -0
  14. package/dist/breakouts/utils.d.ts +15 -0
  15. package/dist/common/browser-detection.d.ts +9 -0
  16. package/dist/common/collection.d.ts +48 -0
  17. package/dist/common/config.d.ts +2 -0
  18. package/dist/common/errors/captcha-error.d.ts +15 -0
  19. package/dist/common/errors/intent-to-join.d.ts +16 -0
  20. package/dist/common/errors/join-forbidden-error.js +52 -0
  21. package/dist/common/errors/join-forbidden-error.js.map +1 -0
  22. package/dist/common/errors/join-meeting.d.ts +17 -0
  23. package/dist/common/errors/{webinar-registration-error.js → join-webinar-error.js} +12 -12
  24. package/dist/common/errors/join-webinar-error.js.map +1 -0
  25. package/dist/common/errors/media.d.ts +15 -0
  26. package/dist/common/errors/multistream-not-supported-error.js +53 -0
  27. package/dist/common/errors/multistream-not-supported-error.js.map +1 -0
  28. package/dist/common/errors/no-meeting-info.d.ts +14 -0
  29. package/dist/common/errors/parameter.d.ts +15 -0
  30. package/dist/common/errors/password-error.d.ts +15 -0
  31. package/dist/common/errors/permission.d.ts +14 -0
  32. package/dist/common/errors/reclaim-host-role-error.js +149 -0
  33. package/dist/common/errors/reclaim-host-role-error.js.map +1 -0
  34. package/dist/common/errors/reclaim-host-role-errors.d.ts +60 -0
  35. package/dist/common/errors/reconnection-in-progress.d.ts +9 -0
  36. package/dist/common/errors/reconnection-in-progress.js +33 -0
  37. package/dist/common/errors/reconnection-in-progress.js.map +1 -0
  38. package/dist/common/errors/reconnection.d.ts +15 -0
  39. package/dist/common/errors/stats.d.ts +15 -0
  40. package/dist/common/errors/webex-errors.d.ts +93 -0
  41. package/dist/common/errors/webex-meetings-error.d.ts +20 -0
  42. package/dist/common/events/events-scope.d.ts +17 -0
  43. package/dist/common/events/events.d.ts +12 -0
  44. package/dist/common/events/trigger-proxy.d.ts +2 -0
  45. package/dist/common/events/util.d.ts +2 -0
  46. package/dist/common/logs/logger-config.d.ts +2 -0
  47. package/dist/common/logs/logger-proxy.d.ts +2 -0
  48. package/dist/common/logs/request.d.ts +36 -0
  49. package/dist/common/queue.d.ts +34 -0
  50. package/dist/config.d.ts +72 -0
  51. package/dist/config.js +2 -1
  52. package/dist/config.js.map +1 -1
  53. package/dist/constants.d.ts +1088 -0
  54. package/dist/constants.js +68 -6
  55. package/dist/constants.js.map +1 -1
  56. package/dist/controls-options-manager/constants.d.ts +4 -0
  57. package/dist/controls-options-manager/enums.d.ts +15 -0
  58. package/dist/controls-options-manager/index.d.ts +136 -0
  59. package/dist/controls-options-manager/types.d.ts +43 -0
  60. package/dist/controls-options-manager/util.d.ts +1 -0
  61. package/dist/index.d.ts +7 -0
  62. package/dist/index.js +16 -11
  63. package/dist/index.js.map +1 -1
  64. package/dist/interceptors/index.d.ts +2 -0
  65. package/dist/interceptors/locusRetry.d.ts +27 -0
  66. package/dist/interpretation/collection.d.ts +5 -0
  67. package/dist/interpretation/index.d.ts +5 -0
  68. package/dist/interpretation/index.js +1 -1
  69. package/dist/interpretation/siLanguage.d.ts +5 -0
  70. package/dist/interpretation/siLanguage.js +1 -1
  71. package/dist/locus-info/controlsUtils.d.ts +2 -0
  72. package/dist/locus-info/embeddedAppsUtils.d.ts +2 -0
  73. package/dist/locus-info/fullState.d.ts +2 -0
  74. package/dist/locus-info/hostUtils.d.ts +2 -0
  75. package/dist/locus-info/index.d.ts +322 -0
  76. package/dist/locus-info/index.js +14 -3
  77. package/dist/locus-info/index.js.map +1 -1
  78. package/dist/locus-info/infoUtils.d.ts +2 -0
  79. package/dist/locus-info/mediaSharesUtils.d.ts +2 -0
  80. package/dist/locus-info/parser.d.ts +272 -0
  81. package/dist/locus-info/selfUtils.d.ts +2 -0
  82. package/dist/locus-info/selfUtils.js +35 -17
  83. package/dist/locus-info/selfUtils.js.map +1 -1
  84. package/dist/media/MediaConnectionAwaiter.js +1 -0
  85. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  86. package/dist/media/index.d.ts +34 -0
  87. package/dist/media/properties.d.ts +93 -0
  88. package/dist/media/properties.js +30 -16
  89. package/dist/media/properties.js.map +1 -1
  90. package/dist/media/util.d.ts +2 -0
  91. package/dist/mediaQualityMetrics/config.d.ts +241 -0
  92. package/dist/mediaQualityMetrics/config.js +502 -0
  93. package/dist/mediaQualityMetrics/config.js.map +1 -0
  94. package/dist/meeting/brbState.js +167 -0
  95. package/dist/meeting/brbState.js.map +1 -0
  96. package/dist/meeting/effectsState.js +260 -0
  97. package/dist/meeting/effectsState.js.map +1 -0
  98. package/dist/meeting/in-meeting-actions.d.ts +167 -0
  99. package/dist/meeting/in-meeting-actions.js +13 -1
  100. package/dist/meeting/in-meeting-actions.js.map +1 -1
  101. package/dist/meeting/index.d.ts +1825 -0
  102. package/dist/meeting/index.js +1331 -1051
  103. package/dist/meeting/index.js.map +1 -1
  104. package/dist/meeting/locusMediaRequest.d.ts +74 -0
  105. package/dist/meeting/locusMediaRequest.js +11 -6
  106. package/dist/meeting/locusMediaRequest.js.map +1 -1
  107. package/dist/meeting/muteState.d.ts +178 -0
  108. package/dist/meeting/muteState.js +1 -6
  109. package/dist/meeting/muteState.js.map +1 -1
  110. package/dist/meeting/request.d.ts +295 -0
  111. package/dist/meeting/request.js +51 -29
  112. package/dist/meeting/request.js.map +1 -1
  113. package/dist/meeting/request.type.d.ts +11 -0
  114. package/dist/meeting/request.type.js.map +1 -1
  115. package/dist/meeting/state.d.ts +9 -0
  116. package/dist/meeting/util.d.ts +119 -0
  117. package/dist/meeting/util.js +103 -67
  118. package/dist/meeting/util.js.map +1 -1
  119. package/dist/meeting/voicea-meeting.d.ts +16 -0
  120. package/dist/meeting-info/collection.d.ts +20 -0
  121. package/dist/meeting-info/index.d.ts +69 -0
  122. package/dist/meeting-info/meeting-info-v2.d.ts +123 -0
  123. package/dist/meeting-info/meeting-info-v2.js +115 -45
  124. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  125. package/dist/meeting-info/request.d.ts +22 -0
  126. package/dist/meeting-info/util.d.ts +2 -0
  127. package/dist/meeting-info/utilv2.d.ts +2 -0
  128. package/dist/meeting-info/utilv2.js +6 -2
  129. package/dist/meeting-info/utilv2.js.map +1 -1
  130. package/dist/meetings/collection.d.ts +40 -0
  131. package/dist/meetings/index.d.ts +390 -0
  132. package/dist/meetings/index.js +107 -55
  133. package/dist/meetings/index.js.map +1 -1
  134. package/dist/meetings/meetings.types.d.ts +4 -0
  135. package/dist/meetings/meetings.types.js +2 -0
  136. package/dist/meetings/meetings.types.js.map +1 -1
  137. package/dist/meetings/request.d.ts +27 -0
  138. package/dist/meetings/util.d.ts +18 -0
  139. package/dist/meetings/util.js +1 -1
  140. package/dist/meetings/util.js.map +1 -1
  141. package/dist/member/index.d.ts +160 -0
  142. package/dist/member/index.js +9 -0
  143. package/dist/member/index.js.map +1 -1
  144. package/dist/member/member.types.js +17 -0
  145. package/dist/member/member.types.js.map +1 -0
  146. package/dist/member/types.d.ts +32 -0
  147. package/dist/member/types.js.map +1 -1
  148. package/dist/member/util.d.ts +2 -0
  149. package/dist/member/util.js +39 -28
  150. package/dist/member/util.js.map +1 -1
  151. package/dist/members/collection.d.ts +29 -0
  152. package/dist/members/index.d.ts +353 -0
  153. package/dist/members/request.d.ts +114 -0
  154. package/dist/members/types.d.ts +25 -0
  155. package/dist/members/util.d.ts +215 -0
  156. package/dist/members/util.js +4 -2
  157. package/dist/members/util.js.map +1 -1
  158. package/dist/metrics/config.js +276 -0
  159. package/dist/metrics/config.js.map +1 -0
  160. package/dist/metrics/constants.d.ts +70 -0
  161. package/dist/metrics/constants.js +6 -1
  162. package/dist/metrics/constants.js.map +1 -1
  163. package/dist/metrics/index.d.ts +45 -0
  164. package/dist/multistream/mediaRequestManager.d.ts +119 -0
  165. package/dist/multistream/receiveSlot.d.ts +68 -0
  166. package/dist/multistream/receiveSlotManager.d.ts +56 -0
  167. package/dist/multistream/remoteMedia.d.ts +72 -0
  168. package/dist/multistream/remoteMedia.js +30 -15
  169. package/dist/multistream/remoteMedia.js.map +1 -1
  170. package/dist/multistream/remoteMediaGroup.d.ts +49 -0
  171. package/dist/multistream/remoteMediaManager.d.ts +300 -0
  172. package/dist/multistream/sendSlotManager.d.ts +69 -0
  173. package/dist/multistream/sendSlotManager.js +24 -0
  174. package/dist/multistream/sendSlotManager.js.map +1 -1
  175. package/dist/networkQualityMonitor/index.d.ts +70 -0
  176. package/dist/networkQualityMonitor/index.js +13 -19
  177. package/dist/networkQualityMonitor/index.js.map +1 -1
  178. package/dist/peer-connection-manager/index.js +671 -0
  179. package/dist/peer-connection-manager/index.js.map +1 -0
  180. package/dist/peer-connection-manager/util.js +109 -0
  181. package/dist/peer-connection-manager/util.js.map +1 -0
  182. package/dist/personal-meeting-room/index.d.ts +47 -0
  183. package/dist/personal-meeting-room/request.d.ts +14 -0
  184. package/dist/personal-meeting-room/util.d.ts +2 -0
  185. package/dist/reachability/clusterReachability.d.ts +109 -0
  186. package/dist/reachability/clusterReachability.js +12 -15
  187. package/dist/reachability/clusterReachability.js.map +1 -1
  188. package/dist/reachability/index.d.ts +105 -0
  189. package/dist/reachability/index.js +461 -136
  190. package/dist/reachability/index.js.map +1 -1
  191. package/dist/reachability/reachability.types.js +7 -0
  192. package/dist/reachability/reachability.types.js.map +1 -0
  193. package/dist/reachability/request.d.ts +39 -0
  194. package/dist/reachability/request.js +21 -8
  195. package/dist/reachability/request.js.map +1 -1
  196. package/dist/reachability/util.d.ts +8 -0
  197. package/dist/reactions/constants.d.ts +3 -0
  198. package/dist/reactions/reactions.d.ts +4 -0
  199. package/dist/reactions/reactions.type.d.ts +52 -0
  200. package/dist/reconnection-manager/index.d.ts +136 -0
  201. package/dist/recording-controller/enums.d.ts +7 -0
  202. package/dist/recording-controller/enums.js +8 -4
  203. package/dist/recording-controller/enums.js.map +1 -1
  204. package/dist/recording-controller/index.d.ts +207 -0
  205. package/dist/recording-controller/index.js +18 -9
  206. package/dist/recording-controller/index.js.map +1 -1
  207. package/dist/recording-controller/util.d.ts +14 -0
  208. package/dist/recording-controller/util.js +13 -9
  209. package/dist/recording-controller/util.js.map +1 -1
  210. package/dist/roap/collection.js +62 -0
  211. package/dist/roap/collection.js.map +1 -0
  212. package/dist/roap/handler.js +275 -0
  213. package/dist/roap/handler.js.map +1 -0
  214. package/dist/roap/index.d.ts +86 -0
  215. package/dist/roap/index.js +15 -15
  216. package/dist/roap/index.js.map +1 -1
  217. package/dist/roap/request.d.ts +39 -0
  218. package/dist/roap/request.js +45 -79
  219. package/dist/roap/request.js.map +1 -1
  220. package/dist/roap/state.js +126 -0
  221. package/dist/roap/state.js.map +1 -0
  222. package/dist/roap/turnDiscovery.d.ts +155 -0
  223. package/dist/roap/turnDiscovery.js +3 -6
  224. package/dist/roap/turnDiscovery.js.map +1 -1
  225. package/dist/roap/util.js +75 -0
  226. package/dist/roap/util.js.map +1 -0
  227. package/dist/rtcMetrics/constants.d.ts +4 -0
  228. package/dist/rtcMetrics/index.d.ts +61 -0
  229. package/dist/statsAnalyzer/global.d.ts +36 -0
  230. package/dist/statsAnalyzer/global.js +126 -0
  231. package/dist/statsAnalyzer/global.js.map +1 -0
  232. package/dist/statsAnalyzer/index.d.ts +217 -0
  233. package/dist/statsAnalyzer/index.js +1013 -0
  234. package/dist/statsAnalyzer/index.js.map +1 -0
  235. package/dist/statsAnalyzer/mqaUtil.d.ts +48 -0
  236. package/dist/statsAnalyzer/mqaUtil.js +179 -0
  237. package/dist/statsAnalyzer/mqaUtil.js.map +1 -0
  238. package/dist/transcription/index.d.ts +64 -0
  239. package/dist/types/annotation/index.d.ts +5 -0
  240. package/dist/types/common/errors/join-forbidden-error.d.ts +15 -0
  241. package/dist/types/common/errors/{webinar-registration-error.d.ts → join-webinar-error.d.ts} +2 -2
  242. package/dist/types/common/errors/multistream-not-supported-error.d.ts +17 -0
  243. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  244. package/dist/types/config.d.ts +1 -0
  245. package/dist/types/constants.d.ts +53 -1
  246. package/dist/types/index.d.ts +3 -3
  247. package/dist/types/locus-info/index.d.ts +2 -1
  248. package/dist/types/mediaQualityMetrics/config.d.ts +241 -0
  249. package/dist/types/meeting/brbState.d.ts +54 -0
  250. package/dist/types/meeting/in-meeting-actions.d.ts +12 -0
  251. package/dist/types/meeting/index.d.ts +64 -14
  252. package/dist/types/meeting/locusMediaRequest.d.ts +6 -3
  253. package/dist/types/meeting/request.d.ts +14 -3
  254. package/dist/types/meeting/request.type.d.ts +6 -0
  255. package/dist/types/meeting/util.d.ts +3 -3
  256. package/dist/types/meeting-info/meeting-info-v2.d.ts +30 -5
  257. package/dist/types/meetings/index.d.ts +20 -2
  258. package/dist/types/meetings/meetings.types.d.ts +8 -0
  259. package/dist/types/member/index.d.ts +1 -0
  260. package/dist/types/member/types.d.ts +7 -0
  261. package/dist/types/members/util.d.ts +2 -0
  262. package/dist/types/metrics/constants.d.ts +6 -1
  263. package/dist/types/multistream/sendSlotManager.d.ts +8 -1
  264. package/dist/types/reachability/clusterReachability.d.ts +1 -10
  265. package/dist/types/reachability/index.d.ts +83 -36
  266. package/dist/types/reachability/reachability.types.d.ts +64 -0
  267. package/dist/types/reachability/request.d.ts +5 -1
  268. package/dist/types/recording-controller/enums.d.ts +5 -2
  269. package/dist/types/recording-controller/index.d.ts +1 -0
  270. package/dist/types/recording-controller/util.d.ts +2 -1
  271. package/dist/types/roap/request.d.ts +1 -13
  272. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  273. package/dist/types/statsAnalyzer/index.d.ts +217 -0
  274. package/dist/types/statsAnalyzer/mqaUtil.d.ts +48 -0
  275. package/dist/webinar/collection.d.ts +16 -0
  276. package/dist/webinar/index.d.ts +5 -0
  277. package/dist/webinar/index.js +390 -7
  278. package/dist/webinar/index.js.map +1 -1
  279. package/package.json +23 -22
  280. package/src/annotation/index.ts +16 -0
  281. package/src/common/errors/join-forbidden-error.ts +26 -0
  282. package/src/common/errors/join-webinar-error.ts +24 -0
  283. package/src/common/errors/multistream-not-supported-error.ts +30 -0
  284. package/src/config.ts +1 -0
  285. package/src/constants.ts +61 -3
  286. package/src/index.ts +5 -3
  287. package/src/locus-info/index.ts +20 -3
  288. package/src/locus-info/selfUtils.ts +24 -6
  289. package/src/media/MediaConnectionAwaiter.ts +2 -0
  290. package/src/media/properties.ts +34 -13
  291. package/src/meeting/brbState.ts +169 -0
  292. package/src/meeting/in-meeting-actions.ts +25 -0
  293. package/src/meeting/index.ts +443 -87
  294. package/src/meeting/locusMediaRequest.ts +11 -8
  295. package/src/meeting/muteState.ts +1 -6
  296. package/src/meeting/request.ts +30 -12
  297. package/src/meeting/request.type.ts +7 -0
  298. package/src/meeting/util.ts +32 -13
  299. package/src/meeting-info/meeting-info-v2.ts +83 -12
  300. package/src/meeting-info/utilv2.ts +17 -3
  301. package/src/meetings/index.ts +79 -20
  302. package/src/meetings/meetings.types.ts +10 -0
  303. package/src/meetings/util.ts +2 -1
  304. package/src/member/index.ts +9 -0
  305. package/src/member/types.ts +8 -0
  306. package/src/member/util.ts +34 -24
  307. package/src/members/util.ts +1 -0
  308. package/src/metrics/constants.ts +6 -1
  309. package/src/multistream/remoteMedia.ts +28 -15
  310. package/src/multistream/sendSlotManager.ts +31 -0
  311. package/src/reachability/clusterReachability.ts +5 -15
  312. package/src/reachability/index.ts +311 -75
  313. package/src/reachability/reachability.types.ts +85 -0
  314. package/src/reachability/request.ts +55 -31
  315. package/src/recording-controller/enums.ts +5 -2
  316. package/src/recording-controller/index.ts +17 -4
  317. package/src/recording-controller/util.ts +20 -5
  318. package/src/roap/index.ts +14 -13
  319. package/src/roap/request.ts +30 -44
  320. package/src/roap/turnDiscovery.ts +2 -4
  321. package/src/webinar/index.ts +235 -9
  322. package/test/unit/spec/annotation/index.ts +46 -1
  323. package/test/unit/spec/locus-info/index.js +292 -60
  324. package/test/unit/spec/locus-info/selfConstant.js +7 -0
  325. package/test/unit/spec/locus-info/selfUtils.js +101 -1
  326. package/test/unit/spec/media/properties.ts +15 -0
  327. package/test/unit/spec/meeting/brbState.ts +114 -0
  328. package/test/unit/spec/meeting/in-meeting-actions.ts +15 -1
  329. package/test/unit/spec/meeting/index.js +851 -107
  330. package/test/unit/spec/meeting/locusMediaRequest.ts +18 -11
  331. package/test/unit/spec/meeting/muteState.js +0 -24
  332. package/test/unit/spec/meeting/request.js +3 -26
  333. package/test/unit/spec/meeting/utils.js +73 -28
  334. package/test/unit/spec/meeting-info/meetinginfov2.js +46 -4
  335. package/test/unit/spec/meeting-info/utilv2.js +26 -0
  336. package/test/unit/spec/meetings/index.js +159 -18
  337. package/test/unit/spec/meetings/utils.js +10 -0
  338. package/test/unit/spec/member/util.js +52 -11
  339. package/test/unit/spec/members/utils.js +95 -0
  340. package/test/unit/spec/multistream/remoteMedia.ts +11 -7
  341. package/test/unit/spec/reachability/clusterReachability.ts +7 -0
  342. package/test/unit/spec/reachability/index.ts +383 -9
  343. package/test/unit/spec/reachability/request.js +48 -12
  344. package/test/unit/spec/recording-controller/index.js +61 -5
  345. package/test/unit/spec/recording-controller/util.js +39 -3
  346. package/test/unit/spec/roap/index.ts +48 -1
  347. package/test/unit/spec/roap/request.ts +51 -109
  348. package/test/unit/spec/roap/turnDiscovery.ts +202 -147
  349. package/test/unit/spec/webinar/index.ts +504 -0
  350. package/dist/common/errors/webinar-registration-error.js.map +0 -1
  351. package/src/common/errors/webinar-registration-error.ts +0 -27
@@ -9,64 +9,31 @@ import {Defer} from '@webex/common';
9
9
  import LoggerProxy from '../common/logs/logger-proxy';
10
10
  import MeetingUtil from '../meeting/util';
11
11
 
12
- import {REACHABILITY} from '../constants';
12
+ import {IP_VERSION, REACHABILITY} from '../constants';
13
13
 
14
14
  import ReachabilityRequest, {ClusterList} from './request';
15
+ import {
16
+ ClusterReachabilityResult,
17
+ TransportResult,
18
+ ClientMediaPreferences,
19
+ ReachabilityMetrics,
20
+ ReachabilityReportV0,
21
+ ReachabilityReportV1,
22
+ ReachabilityResults,
23
+ ReachabilityResultsForBackend,
24
+ TransportResultForBackend,
25
+ GetClustersTrigger,
26
+ } from './reachability.types';
15
27
  import {
16
28
  ClientMediaIpsUpdatedEventData,
17
29
  ClusterReachability,
18
- ClusterReachabilityResult,
19
30
  Events,
20
31
  ResultEventData,
21
- TransportResult,
22
32
  } from './clusterReachability';
23
33
  import EventsScope from '../common/events/events-scope';
24
34
  import BEHAVIORAL_METRICS from '../metrics/constants';
25
35
  import Metrics from '../metrics';
26
36
 
27
- export type ReachabilityMetrics = {
28
- reachability_public_udp_success: number;
29
- reachability_public_udp_failed: number;
30
- reachability_public_tcp_success: number;
31
- reachability_public_tcp_failed: number;
32
- reachability_public_xtls_success: number;
33
- reachability_public_xtls_failed: number;
34
- reachability_vmn_udp_success: number;
35
- reachability_vmn_udp_failed: number;
36
- reachability_vmn_tcp_success: number;
37
- reachability_vmn_tcp_failed: number;
38
- reachability_vmn_xtls_success: number;
39
- reachability_vmn_xtls_failed: number;
40
- };
41
-
42
- /**
43
- * This is the type that matches what backend expects us to send to them. It is a bit weird, because
44
- * it uses strings instead of booleans and numbers, but that's what they require.
45
- */
46
- export type TransportResultForBackend = {
47
- reachable?: 'true' | 'false';
48
- latencyInMilliseconds?: string;
49
- clientMediaIPs?: string[];
50
- untested?: 'true';
51
- };
52
-
53
- export type ReachabilityResultForBackend = {
54
- udp: TransportResultForBackend;
55
- tcp: TransportResultForBackend;
56
- xtls: TransportResultForBackend;
57
- };
58
-
59
- // this is the type that is required by the backend when we send them reachability results
60
- export type ReachabilityResultsForBackend = Record<string, ReachabilityResultForBackend>;
61
-
62
- // this is the type used by Reachability class internally and stored in local storage
63
- export type ReachabilityResults = Record<
64
- string,
65
- ClusterReachabilityResult & {
66
- isVideoMesh?: boolean;
67
- }
68
- >;
69
-
70
37
  // timeouts in seconds
71
38
  const DEFAULT_TIMEOUT = 3;
72
39
  const VIDEO_MESH_TIMEOUT = 1;
@@ -84,6 +51,9 @@ export default class Reachability extends EventsScope {
84
51
  [key: string]: ClusterReachability;
85
52
  };
86
53
 
54
+ minRequiredClusters?: number;
55
+ orpheusApiVersion?: number;
56
+
87
57
  reachabilityDefer?: Defer;
88
58
 
89
59
  vmnTimer?: ReturnType<typeof setTimeout>;
@@ -92,6 +62,8 @@ export default class Reachability extends EventsScope {
92
62
 
93
63
  expectedResultsCount = {videoMesh: {udp: 0}, public: {udp: 0, tcp: 0, xtls: 0}};
94
64
  resultsCount = {videoMesh: {udp: 0}, public: {udp: 0, tcp: 0, xtls: 0}};
65
+ startTime = undefined;
66
+ totalDuration = undefined;
95
67
 
96
68
  protected lastTrigger?: string;
97
69
 
@@ -118,14 +90,35 @@ export default class Reachability extends EventsScope {
118
90
 
119
91
  /**
120
92
  * Fetches the list of media clusters from the backend
93
+ * @param {string} trigger - explains the reason for starting reachability, used by Orpheus
94
+ * @param {Object} previousReport - last reachability report
121
95
  * @param {boolean} isRetry
122
96
  * @private
123
97
  * @returns {Promise<{clusters: ClusterList, joinCookie: any}>}
124
98
  */
125
- async getClusters(isRetry = false): Promise<{clusters: ClusterList; joinCookie: any}> {
99
+ async getClusters(
100
+ trigger: GetClustersTrigger,
101
+ previousReport?: any,
102
+ isRetry = false
103
+ ): Promise<{
104
+ clusters: ClusterList;
105
+ joinCookie: any;
106
+ }> {
126
107
  try {
127
- const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(
128
- MeetingUtil.getIpVersion(this.webex)
108
+ const {clusters, joinCookie, discoveryOptions} = await this.reachabilityRequest.getClusters(
109
+ trigger,
110
+ MeetingUtil.getIpVersion(this.webex),
111
+ previousReport
112
+ );
113
+
114
+ this.minRequiredClusters = discoveryOptions?.['early-call-min-clusters'];
115
+ this.orpheusApiVersion = discoveryOptions?.['report-version'];
116
+
117
+ // @ts-ignore
118
+ await this.webex.boundedStorage.put(
119
+ this.namespace,
120
+ REACHABILITY.localStorageJoinCookie,
121
+ JSON.stringify(joinCookie)
129
122
  );
130
123
 
131
124
  return {clusters, joinCookie};
@@ -138,7 +131,7 @@ export default class Reachability extends EventsScope {
138
131
  `Reachability:index#getClusters --> Failed with error: ${error}, retrying...`
139
132
  );
140
133
 
141
- return this.getClusters(true);
134
+ return this.getClusters(trigger, previousReport, true);
142
135
  }
143
136
  }
144
137
 
@@ -159,14 +152,7 @@ export default class Reachability extends EventsScope {
159
152
  // @ts-ignore
160
153
  this.webex.internal.device.ipNetworkDetector.detect(true);
161
154
 
162
- const {clusters, joinCookie} = await this.getClusters();
163
-
164
- // @ts-ignore
165
- await this.webex.boundedStorage.put(
166
- this.namespace,
167
- REACHABILITY.localStorageJoinCookie,
168
- JSON.stringify(joinCookie)
169
- );
155
+ const {clusters} = await this.getClusters('startup');
170
156
 
171
157
  this.reachabilityDefer = new Defer();
172
158
 
@@ -181,6 +167,124 @@ export default class Reachability extends EventsScope {
181
167
  }
182
168
  }
183
169
 
170
+ /**
171
+ * Gets the last join cookie we got from Orpheus
172
+ *
173
+ * @returns {Promise<Object>} join cookie
174
+ */
175
+ async getJoinCookie() {
176
+ // @ts-ignore
177
+ const joinCookieRaw = await this.webex.boundedStorage
178
+ .get(REACHABILITY.namespace, REACHABILITY.localStorageJoinCookie)
179
+ .catch(() => {});
180
+
181
+ let joinCookie;
182
+
183
+ if (joinCookieRaw) {
184
+ try {
185
+ joinCookie = JSON.parse(joinCookieRaw);
186
+ } catch (e) {
187
+ LoggerProxy.logger.error(
188
+ `MeetingRequest#constructor --> Error in parsing join cookie data: ${e}`
189
+ );
190
+ }
191
+ }
192
+
193
+ return joinCookie;
194
+ }
195
+
196
+ /**
197
+ * Returns the reachability report that needs to be attached to the ROAP messages
198
+ * that we send to the backend.
199
+ *
200
+ * @returns {Promise<Object>}
201
+ */
202
+ async getReachabilityReport(): Promise<
203
+ | {
204
+ joinCookie: any;
205
+ reachability?: ReachabilityReportV1;
206
+ }
207
+ | {
208
+ reachability: ReachabilityReportV0;
209
+ }
210
+ > {
211
+ const reachabilityResult = await this.getReachabilityResults();
212
+ const joinCookie = await this.getJoinCookie();
213
+
214
+ // Orpheus API version 0
215
+ if (!this.orpheusApiVersion) {
216
+ return {
217
+ reachability: reachabilityResult,
218
+ };
219
+ }
220
+
221
+ // Orpheus API version 1
222
+ return {
223
+ reachability: {
224
+ version: 1,
225
+ result: {
226
+ usedDiscoveryOptions: {
227
+ 'early-call-min-clusters': this.minRequiredClusters,
228
+ },
229
+ metrics: {
230
+ 'total-duration-ms': this.totalDuration,
231
+ },
232
+ tests: reachabilityResult,
233
+ },
234
+ },
235
+ joinCookie,
236
+ };
237
+ }
238
+
239
+ /**
240
+ * This method is called when we don't succeed in reaching the minimum number of clusters
241
+ * required by Orpheus. It sends the results to Orpheus and gets a new list that it tries to reach again.
242
+ * @returns {Promise<ReachabilityResults>} reachability results
243
+ * @public
244
+ * @memberof Reachability
245
+ */
246
+ public async gatherReachabilityFallback(): Promise<void> {
247
+ try {
248
+ const reachabilityReport = await this.getReachabilityReport();
249
+
250
+ const {clusters} = await this.getClusters('early-call/no-min-reached', reachabilityReport);
251
+
252
+ // stop all previous reachability checks that might still be going on in the background
253
+ this.abortCurrentChecks();
254
+
255
+ // Perform Reachability Check
256
+ await this.performReachabilityChecks(clusters);
257
+ } catch (error) {
258
+ LoggerProxy.logger.error(`Reachability:index#gatherReachabilityFallback --> Error:`, error);
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Stops all reachability checks that are in progress
264
+ * @public
265
+ * @memberof Reachability
266
+ * @returns {void}
267
+ */
268
+ public stopReachability() {
269
+ // overallTimer is always there only if there is reachability in progress
270
+ if (this.overallTimer) {
271
+ LoggerProxy.logger.log(
272
+ 'Reachability:index#stopReachability --> stopping reachability checks'
273
+ );
274
+ this.abortCurrentChecks();
275
+ this.emit(
276
+ {
277
+ file: 'reachability',
278
+ function: 'stopReachability',
279
+ },
280
+ 'reachability:stopped',
281
+ {}
282
+ );
283
+ this.sendMetric(true);
284
+ this.resolveReachabilityPromise();
285
+ }
286
+ }
287
+
184
288
  /**
185
289
  * Returns statistics about last reachability results. The returned value is an object
186
290
  * with a flat list of properties so that it can be easily sent with metrics
@@ -304,7 +408,7 @@ export default class Reachability extends EventsScope {
304
408
  } catch (e) {
305
409
  // empty storage, that's ok
306
410
  LoggerProxy.logger.warn(
307
- 'Roap:request#attachReachabilityData --> Error parsing reachability data: ',
411
+ 'Reachability:index#getReachabilityResults --> Error parsing reachability data: ',
308
412
  e
309
413
  );
310
414
  }
@@ -336,7 +440,7 @@ export default class Reachability extends EventsScope {
336
440
  );
337
441
  } catch (e) {
338
442
  LoggerProxy.logger.error(
339
- `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`
443
+ `Reachability:index#isAnyPublicClusterReachable --> Error in parsing reachability data: ${e}`
340
444
  );
341
445
  }
342
446
  }
@@ -393,7 +497,7 @@ export default class Reachability extends EventsScope {
393
497
  );
394
498
  } catch (e) {
395
499
  LoggerProxy.logger.error(
396
- `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`
500
+ `Reachability:index#isWebexMediaBackendUnreachable --> Error in parsing reachability data: ${e}`
397
501
  );
398
502
  }
399
503
  }
@@ -427,6 +531,30 @@ export default class Reachability extends EventsScope {
427
531
  return unreachableList;
428
532
  }
429
533
 
534
+ /**
535
+ * Gets the number of reachable clusters from last run reachability check
536
+ * @returns {number} reachable clusters count
537
+ * @private
538
+ * @memberof Reachability
539
+ */
540
+ private getNumberOfReachableClusters(): number {
541
+ let count = 0;
542
+
543
+ Object.entries(this.clusterReachability).forEach(([key, clusterReachability]) => {
544
+ const result = clusterReachability.getResult();
545
+
546
+ if (
547
+ result.udp.result === 'reachable' ||
548
+ result.tcp.result === 'reachable' ||
549
+ result.xtls.result === 'reachable'
550
+ ) {
551
+ count += 1;
552
+ }
553
+ });
554
+
555
+ return count;
556
+ }
557
+
430
558
  /**
431
559
  * Make a log of unreachable clusters.
432
560
  * @returns {undefined}
@@ -465,18 +593,27 @@ export default class Reachability extends EventsScope {
465
593
 
466
594
  /**
467
595
  * Resolves the promise returned by gatherReachability() method
596
+ * @param {boolean} checkMinRequiredClusters - if true, it will check if we have reached the minimum required clusters and do a fallback if needed
468
597
  * @returns {void}
469
598
  */
470
- private resolveReachabilityPromise() {
471
- if (this.vmnTimer) {
472
- clearTimeout(this.vmnTimer);
473
- }
474
- if (this.publicCloudTimer) {
475
- clearTimeout(this.publicCloudTimer);
476
- }
599
+ private resolveReachabilityPromise(checkMinRequiredClusters = true) {
600
+ this.totalDuration = performance.now() - this.startTime;
601
+
602
+ this.clearTimer('vmnTimer');
603
+ this.clearTimer('publicCloudTimer');
477
604
 
478
605
  this.logUnreachableClusters();
479
606
  this.reachabilityDefer?.resolve();
607
+
608
+ if (checkMinRequiredClusters) {
609
+ const numReachableClusters = this.getNumberOfReachableClusters();
610
+ if (this.minRequiredClusters && numReachableClusters < this.minRequiredClusters) {
611
+ LoggerProxy.logger.log(
612
+ `Reachability:index#resolveReachabilityPromise --> minRequiredClusters not reached (${numReachableClusters} < ${this.minRequiredClusters}), doing reachability fallback`
613
+ );
614
+ this.gatherReachabilityFallback();
615
+ }
616
+ }
480
617
  }
481
618
 
482
619
  /**
@@ -526,9 +663,10 @@ export default class Reachability extends EventsScope {
526
663
  /**
527
664
  * Sends a metric with all the statistics about how long reachability took
528
665
  *
666
+ * @param {boolean} aborted true if the reachability checks were aborted
529
667
  * @returns {void}
530
668
  */
531
- protected async sendMetric() {
669
+ protected async sendMetric(aborted = false) {
532
670
  const results = [];
533
671
 
534
672
  Object.values(this.clusterReachability).forEach((clusterReachability) => {
@@ -539,6 +677,7 @@ export default class Reachability extends EventsScope {
539
677
  });
540
678
 
541
679
  const stats = {
680
+ aborted,
542
681
  vmn: {
543
682
  udp: this.getStatistics(results, 'udp', true),
544
683
  },
@@ -591,6 +730,8 @@ export default class Reachability extends EventsScope {
591
730
  `Reachability:index#startTimers --> Reachability checks timed out (${DEFAULT_TIMEOUT}s)`
592
731
  );
593
732
 
733
+ // check against minimum required clusters, do a new call if we don't have enough
734
+
594
735
  // resolve the promise, so that the client won't be blocked waiting on meetings.register() for too long
595
736
  this.resolveReachabilityPromise();
596
737
  }, DEFAULT_TIMEOUT * 1000);
@@ -646,6 +787,32 @@ export default class Reachability extends EventsScope {
646
787
  this.resultsCount.public.xtls = 0;
647
788
  }
648
789
 
790
+ /**
791
+ * Clears the timer
792
+ *
793
+ * @param {string} timer name of the timer to clear
794
+ * @returns {void}
795
+ */
796
+ private clearTimer(timer: string) {
797
+ if (this[timer]) {
798
+ clearTimeout(this[timer]);
799
+ this[timer] = undefined;
800
+ }
801
+ }
802
+
803
+ /**
804
+ * Aborts current checks that are in progress
805
+ *
806
+ * @returns {void}
807
+ */
808
+ private abortCurrentChecks() {
809
+ this.clearTimer('vmnTimer');
810
+ this.clearTimer('publicCloudTimer');
811
+ this.clearTimer('overallTimer');
812
+
813
+ this.abortClusterReachability();
814
+ }
815
+
649
816
  /**
650
817
  * Performs reachability checks for all clusters
651
818
  * @param {ClusterList} clusterList
@@ -656,9 +823,7 @@ export default class Reachability extends EventsScope {
656
823
 
657
824
  this.clusterReachability = {};
658
825
 
659
- if (!clusterList || !Object.keys(clusterList).length) {
660
- return;
661
- }
826
+ this.startTime = performance.now();
662
827
 
663
828
  LoggerProxy.logger.log(
664
829
  `Reachability:index#performReachabilityChecks --> doing UDP${
@@ -671,7 +836,6 @@ export default class Reachability extends EventsScope {
671
836
  );
672
837
 
673
838
  this.resetResultCounters();
674
- this.startTimers();
675
839
 
676
840
  // sanitize the urls in the clusterList
677
841
  Object.keys(clusterList).forEach((key) => {
@@ -721,6 +885,24 @@ export default class Reachability extends EventsScope {
721
885
  // save the initialized results (in case we don't get any "resultReady" events at all)
722
886
  await this.storeResults(results);
723
887
 
888
+ if (!clusterList || !Object.keys(clusterList).length) {
889
+ // nothing to do, finish immediately
890
+ this.resolveReachabilityPromise(false);
891
+
892
+ this.emit(
893
+ {
894
+ file: 'reachability',
895
+ function: 'performReachabilityChecks',
896
+ },
897
+ 'reachability:done',
898
+ {}
899
+ );
900
+
901
+ return;
902
+ }
903
+
904
+ this.startTimers();
905
+
724
906
  // now start the reachability on all the clusters
725
907
  Object.keys(clusterList).forEach((key) => {
726
908
  const cluster = clusterList[key];
@@ -753,8 +935,7 @@ export default class Reachability extends EventsScope {
753
935
  await this.storeResults(results);
754
936
 
755
937
  if (areAllResultsReady) {
756
- clearTimeout(this.overallTimer);
757
- this.overallTimer = undefined;
938
+ this.clearTimer('overallTimer');
758
939
  this.emit(
759
940
  {
760
941
  file: 'reachability',
@@ -785,4 +966,59 @@ export default class Reachability extends EventsScope {
785
966
  this.clusterReachability[key].start(); // not awaiting on purpose
786
967
  });
787
968
  }
969
+
970
+ /**
971
+ * Returns the clientMediaPreferences object that needs to be sent to the backend
972
+ * when joining a meeting
973
+ *
974
+ * @param {boolean} isMultistream
975
+ * @param {IP_VERSION} ipver
976
+ * @returns {Object}
977
+ */
978
+ async getClientMediaPreferences(
979
+ isMultistream: boolean,
980
+ ipver?: IP_VERSION
981
+ ): Promise<ClientMediaPreferences> {
982
+ // if 0 or undefined, we assume version 0 and don't send any reachability in clientMediaPreferences
983
+ if (!this.orpheusApiVersion) {
984
+ return {
985
+ ipver,
986
+ joinCookie: await this.getJoinCookie(),
987
+ preferTranscoding: !isMultistream,
988
+ };
989
+ }
990
+
991
+ // must be version 1
992
+
993
+ // for version 1, the reachability report goes into clientMediaPreferences (and it contains joinCookie)
994
+ const reachabilityReport = (await this.getReachabilityReport()) as {
995
+ joinCookie: any;
996
+ reachability?: ReachabilityReportV1;
997
+ };
998
+
999
+ return {
1000
+ ipver,
1001
+ preferTranscoding: !isMultistream,
1002
+ ...reachabilityReport,
1003
+ };
1004
+ }
1005
+
1006
+ /**
1007
+ * Returns the reachability report that needs to be attached to the ROAP messages
1008
+ * that we send to the backend.
1009
+ * It may return undefined, if reachability is not needed to be attached to ROAP messages (that's the case for v1 or Orpheus API)
1010
+ *
1011
+ * @returns {Promise<ReachabilityReportV0>} object that needs to be attached to Roap messages
1012
+ */
1013
+ async getReachabilityReportToAttachToRoap(): Promise<ReachabilityReportV0 | undefined> {
1014
+ // version 0
1015
+ if (!this.orpheusApiVersion) {
1016
+ return this.getReachabilityResults();
1017
+ }
1018
+
1019
+ // version 1
1020
+
1021
+ // for version 1 we don't attach anything to Roap messages, reachability report is sent inside clientMediaPreferences
1022
+ return undefined;
1023
+ }
788
1024
  }
@@ -0,0 +1,85 @@
1
+ import {IP_VERSION} from '../constants';
2
+
3
+ // result for a specific transport protocol (like udp or tcp)
4
+ export type TransportResult = {
5
+ result: 'reachable' | 'unreachable' | 'untested';
6
+ latencyInMilliseconds?: number; // amount of time it took to get the first ICE candidate
7
+ clientMediaIPs?: string[];
8
+ };
9
+
10
+ // reachability result for a specific media cluster
11
+ export type ClusterReachabilityResult = {
12
+ udp: TransportResult;
13
+ tcp: TransportResult;
14
+ xtls: TransportResult;
15
+ };
16
+
17
+ export type ReachabilityMetrics = {
18
+ reachability_public_udp_success: number;
19
+ reachability_public_udp_failed: number;
20
+ reachability_public_tcp_success: number;
21
+ reachability_public_tcp_failed: number;
22
+ reachability_public_xtls_success: number;
23
+ reachability_public_xtls_failed: number;
24
+ reachability_vmn_udp_success: number;
25
+ reachability_vmn_udp_failed: number;
26
+ reachability_vmn_tcp_success: number;
27
+ reachability_vmn_tcp_failed: number;
28
+ reachability_vmn_xtls_success: number;
29
+ reachability_vmn_xtls_failed: number;
30
+ };
31
+
32
+ /**
33
+ * This is the type that matches what backend expects us to send to them. It is a bit weird, because
34
+ * it uses strings instead of booleans and numbers, but that's what they require.
35
+ */
36
+ export type TransportResultForBackend = {
37
+ reachable?: 'true' | 'false';
38
+ latencyInMilliseconds?: string;
39
+ clientMediaIPs?: string[];
40
+ untested?: 'true';
41
+ };
42
+
43
+ export type ReachabilityResultForBackend = {
44
+ udp: TransportResultForBackend;
45
+ tcp: TransportResultForBackend;
46
+ xtls: TransportResultForBackend;
47
+ };
48
+
49
+ // this is the type that is required by the backend when we send them reachability results
50
+ export type ReachabilityResultsForBackend = Record<string, ReachabilityResultForBackend>;
51
+
52
+ // this is the type used by Reachability class internally and stored in local storage
53
+ export type ReachabilityResults = Record<
54
+ string,
55
+ ClusterReachabilityResult & {
56
+ isVideoMesh?: boolean;
57
+ }
58
+ >;
59
+
60
+ export type ReachabilityReportV0 = ReachabilityResultsForBackend;
61
+
62
+ export type ReachabilityReportV1 = {
63
+ version: 1;
64
+ result: {
65
+ usedDiscoveryOptions: {
66
+ 'early-call-min-clusters': number;
67
+ // there are more options, but we don't support them yet
68
+ };
69
+ metrics: {
70
+ 'total-duration-ms': number;
71
+ // there are more metrics, but we don't support them yet
72
+ };
73
+ tests: Record<string, ReachabilityResultForBackend>;
74
+ };
75
+ };
76
+
77
+ export interface ClientMediaPreferences {
78
+ ipver: IP_VERSION;
79
+ joinCookie: any;
80
+ preferTranscoding: boolean;
81
+ reachability?: ReachabilityReportV1; // only present when using Orpheus API version 1
82
+ }
83
+
84
+ /* Orpheus API supports more triggers, but we don't use them yet */
85
+ export type GetClustersTrigger = 'startup' | 'early-call/no-min-reached';