@textrp/briij-js-sdk 41.0.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 (1104) hide show
  1. package/CHANGELOG.md +6464 -0
  2. package/LICENSE +177 -0
  3. package/README.md +477 -0
  4. package/lib/@types/AESEncryptedSecretStoragePayload.d.ts +14 -0
  5. package/lib/@types/AESEncryptedSecretStoragePayload.d.ts.map +1 -0
  6. package/lib/@types/AESEncryptedSecretStoragePayload.js +1 -0
  7. package/lib/@types/AESEncryptedSecretStoragePayload.js.map +1 -0
  8. package/lib/@types/IIdentityServerProvider.d.ts +9 -0
  9. package/lib/@types/IIdentityServerProvider.d.ts.map +1 -0
  10. package/lib/@types/IIdentityServerProvider.js +1 -0
  11. package/lib/@types/IIdentityServerProvider.js.map +1 -0
  12. package/lib/@types/PushRules.d.ts +140 -0
  13. package/lib/@types/PushRules.d.ts.map +1 -0
  14. package/lib/@types/PushRules.js +94 -0
  15. package/lib/@types/PushRules.js.map +1 -0
  16. package/lib/@types/another-json.d.js +0 -0
  17. package/lib/@types/another-json.d.js.map +1 -0
  18. package/lib/@types/auth.d.ts +213 -0
  19. package/lib/@types/auth.d.ts.map +1 -0
  20. package/lib/@types/auth.js +107 -0
  21. package/lib/@types/auth.js.map +1 -0
  22. package/lib/@types/beacon.d.ts +106 -0
  23. package/lib/@types/beacon.d.ts.map +1 -0
  24. package/lib/@types/beacon.js +119 -0
  25. package/lib/@types/beacon.js.map +1 -0
  26. package/lib/@types/common.d.ts +10 -0
  27. package/lib/@types/common.d.ts.map +1 -0
  28. package/lib/@types/common.js +1 -0
  29. package/lib/@types/common.js.map +1 -0
  30. package/lib/@types/crypto.d.ts +46 -0
  31. package/lib/@types/crypto.d.ts.map +1 -0
  32. package/lib/@types/crypto.js +1 -0
  33. package/lib/@types/crypto.js.map +1 -0
  34. package/lib/@types/event.d.ts +356 -0
  35. package/lib/@types/event.d.ts.map +1 -0
  36. package/lib/@types/event.js +280 -0
  37. package/lib/@types/event.js.map +1 -0
  38. package/lib/@types/events.d.ts +92 -0
  39. package/lib/@types/events.d.ts.map +1 -0
  40. package/lib/@types/events.js +1 -0
  41. package/lib/@types/events.js.map +1 -0
  42. package/lib/@types/extensible_events.d.ts +98 -0
  43. package/lib/@types/extensible_events.d.ts.map +1 -0
  44. package/lib/@types/extensible_events.js +116 -0
  45. package/lib/@types/extensible_events.js.map +1 -0
  46. package/lib/@types/global.d.js +18 -0
  47. package/lib/@types/global.d.js.map +1 -0
  48. package/lib/@types/local_notifications.d.ts +4 -0
  49. package/lib/@types/local_notifications.d.ts.map +1 -0
  50. package/lib/@types/local_notifications.js +1 -0
  51. package/lib/@types/local_notifications.js.map +1 -0
  52. package/lib/@types/location.d.ts +60 -0
  53. package/lib/@types/location.d.ts.map +1 -0
  54. package/lib/@types/location.js +66 -0
  55. package/lib/@types/location.js.map +1 -0
  56. package/lib/@types/matrix-sdk-crypto-wasm.d.js +1 -0
  57. package/lib/@types/matrix-sdk-crypto-wasm.d.js.map +1 -0
  58. package/lib/@types/media.d.ts +220 -0
  59. package/lib/@types/media.d.ts.map +1 -0
  60. package/lib/@types/media.js +1 -0
  61. package/lib/@types/media.js.map +1 -0
  62. package/lib/@types/membership.d.ts +41 -0
  63. package/lib/@types/membership.d.ts.map +1 -0
  64. package/lib/@types/membership.js +58 -0
  65. package/lib/@types/membership.js.map +1 -0
  66. package/lib/@types/partials.d.ts +72 -0
  67. package/lib/@types/partials.d.ts.map +1 -0
  68. package/lib/@types/partials.js +71 -0
  69. package/lib/@types/partials.js.map +1 -0
  70. package/lib/@types/polls.d.ts +89 -0
  71. package/lib/@types/polls.d.ts.map +1 -0
  72. package/lib/@types/polls.js +86 -0
  73. package/lib/@types/polls.js.map +1 -0
  74. package/lib/@types/read_receipts.d.ts +36 -0
  75. package/lib/@types/read_receipts.d.ts.map +1 -0
  76. package/lib/@types/read_receipts.js +27 -0
  77. package/lib/@types/read_receipts.js.map +1 -0
  78. package/lib/@types/registration.d.ts +85 -0
  79. package/lib/@types/registration.d.ts.map +1 -0
  80. package/lib/@types/registration.js +1 -0
  81. package/lib/@types/registration.js.map +1 -0
  82. package/lib/@types/requests.d.ts +267 -0
  83. package/lib/@types/requests.d.ts.map +1 -0
  84. package/lib/@types/requests.js +42 -0
  85. package/lib/@types/requests.js.map +1 -0
  86. package/lib/@types/search.d.ts +90 -0
  87. package/lib/@types/search.d.ts.map +1 -0
  88. package/lib/@types/search.js +30 -0
  89. package/lib/@types/search.js.map +1 -0
  90. package/lib/@types/signed.d.ts +9 -0
  91. package/lib/@types/signed.d.ts.map +1 -0
  92. package/lib/@types/signed.js +1 -0
  93. package/lib/@types/signed.js.map +1 -0
  94. package/lib/@types/spaces.d.ts +16 -0
  95. package/lib/@types/spaces.d.ts.map +1 -0
  96. package/lib/@types/spaces.js +1 -0
  97. package/lib/@types/spaces.js.map +1 -0
  98. package/lib/@types/state_events.d.ts +121 -0
  99. package/lib/@types/state_events.d.ts.map +1 -0
  100. package/lib/@types/state_events.js +1 -0
  101. package/lib/@types/state_events.js.map +1 -0
  102. package/lib/@types/synapse.d.ts +19 -0
  103. package/lib/@types/synapse.d.ts.map +1 -0
  104. package/lib/@types/synapse.js +1 -0
  105. package/lib/@types/synapse.js.map +1 -0
  106. package/lib/@types/sync.d.ts +8 -0
  107. package/lib/@types/sync.d.ts.map +1 -0
  108. package/lib/@types/sync.js +25 -0
  109. package/lib/@types/sync.js.map +1 -0
  110. package/lib/@types/threepids.d.ts +12 -0
  111. package/lib/@types/threepids.d.ts.map +1 -0
  112. package/lib/@types/threepids.js +24 -0
  113. package/lib/@types/threepids.js.map +1 -0
  114. package/lib/@types/topic.d.ts +55 -0
  115. package/lib/@types/topic.d.ts.map +1 -0
  116. package/lib/@types/topic.js +62 -0
  117. package/lib/@types/topic.js.map +1 -0
  118. package/lib/@types/uia.d.ts +8 -0
  119. package/lib/@types/uia.d.ts.map +1 -0
  120. package/lib/@types/uia.js +1 -0
  121. package/lib/@types/uia.js.map +1 -0
  122. package/lib/NamespacedValue.d.ts +32 -0
  123. package/lib/NamespacedValue.d.ts.map +1 -0
  124. package/lib/NamespacedValue.js +113 -0
  125. package/lib/NamespacedValue.js.map +1 -0
  126. package/lib/ReEmitter.d.ts +15 -0
  127. package/lib/ReEmitter.d.ts.map +1 -0
  128. package/lib/ReEmitter.js +87 -0
  129. package/lib/ReEmitter.js.map +1 -0
  130. package/lib/ToDeviceMessageQueue.d.ts +30 -0
  131. package/lib/ToDeviceMessageQueue.d.ts.map +1 -0
  132. package/lib/ToDeviceMessageQueue.js +135 -0
  133. package/lib/ToDeviceMessageQueue.js.map +1 -0
  134. package/lib/autodiscovery.d.ts +136 -0
  135. package/lib/autodiscovery.d.ts.map +1 -0
  136. package/lib/autodiscovery.js +464 -0
  137. package/lib/autodiscovery.js.map +1 -0
  138. package/lib/base64.d.ts +25 -0
  139. package/lib/base64.d.ts.map +1 -0
  140. package/lib/base64.js +95 -0
  141. package/lib/base64.js.map +1 -0
  142. package/lib/briij.d.ts +116 -0
  143. package/lib/briij.d.ts.map +1 -0
  144. package/lib/briij.js +145 -0
  145. package/lib/briij.js.map +1 -0
  146. package/lib/browser-index.d.ts +8 -0
  147. package/lib/browser-index.d.ts.map +1 -0
  148. package/lib/browser-index.js +35 -0
  149. package/lib/browser-index.js.map +1 -0
  150. package/lib/client.d.ts +3493 -0
  151. package/lib/client.d.ts.map +1 -0
  152. package/lib/client.js +7482 -0
  153. package/lib/client.js.map +1 -0
  154. package/lib/common-crypto/CryptoBackend.d.ts +234 -0
  155. package/lib/common-crypto/CryptoBackend.d.ts.map +1 -0
  156. package/lib/common-crypto/CryptoBackend.js +69 -0
  157. package/lib/common-crypto/CryptoBackend.js.map +1 -0
  158. package/lib/common-crypto/key-passphrase.d.ts +14 -0
  159. package/lib/common-crypto/key-passphrase.d.ts.map +1 -0
  160. package/lib/common-crypto/key-passphrase.js +33 -0
  161. package/lib/common-crypto/key-passphrase.js.map +1 -0
  162. package/lib/content-helpers.d.ts +90 -0
  163. package/lib/content-helpers.d.ts.map +1 -0
  164. package/lib/content-helpers.js +262 -0
  165. package/lib/content-helpers.js.map +1 -0
  166. package/lib/content-repo.d.ts +25 -0
  167. package/lib/content-repo.d.ts.map +1 -0
  168. package/lib/content-repo.js +109 -0
  169. package/lib/content-repo.js.map +1 -0
  170. package/lib/crypto/store/base.d.ts +301 -0
  171. package/lib/crypto/store/base.d.ts.map +1 -0
  172. package/lib/crypto/store/base.js +145 -0
  173. package/lib/crypto/store/base.js.map +1 -0
  174. package/lib/crypto/store/indexeddb-crypto-store-backend.d.ts +94 -0
  175. package/lib/crypto/store/indexeddb-crypto-store-backend.d.ts.map +1 -0
  176. package/lib/crypto/store/indexeddb-crypto-store-backend.js +604 -0
  177. package/lib/crypto/store/indexeddb-crypto-store-backend.js.map +1 -0
  178. package/lib/crypto/store/indexeddb-crypto-store.d.ts +251 -0
  179. package/lib/crypto/store/indexeddb-crypto-store.d.ts.map +1 -0
  180. package/lib/crypto/store/indexeddb-crypto-store.js +477 -0
  181. package/lib/crypto/store/indexeddb-crypto-store.js.map +1 -0
  182. package/lib/crypto/store/localStorage-crypto-store.d.ts +102 -0
  183. package/lib/crypto/store/localStorage-crypto-store.d.ts.map +1 -0
  184. package/lib/crypto/store/localStorage-crypto-store.js +374 -0
  185. package/lib/crypto/store/localStorage-crypto-store.js.map +1 -0
  186. package/lib/crypto/store/memory-crypto-store.d.ts +117 -0
  187. package/lib/crypto/store/memory-crypto-store.d.ts.map +1 -0
  188. package/lib/crypto/store/memory-crypto-store.js +311 -0
  189. package/lib/crypto/store/memory-crypto-store.js.map +1 -0
  190. package/lib/crypto-api/CryptoEvent.d.ts +120 -0
  191. package/lib/crypto-api/CryptoEvent.d.ts.map +1 -0
  192. package/lib/crypto-api/CryptoEvent.js +137 -0
  193. package/lib/crypto-api/CryptoEvent.js.map +1 -0
  194. package/lib/crypto-api/CryptoEventHandlerMap.d.ts +26 -0
  195. package/lib/crypto-api/CryptoEventHandlerMap.d.ts.map +1 -0
  196. package/lib/crypto-api/CryptoEventHandlerMap.js +1 -0
  197. package/lib/crypto-api/CryptoEventHandlerMap.js.map +1 -0
  198. package/lib/crypto-api/index.d.ts +1160 -0
  199. package/lib/crypto-api/index.d.ts.map +1 -0
  200. package/lib/crypto-api/index.js +410 -0
  201. package/lib/crypto-api/index.js.map +1 -0
  202. package/lib/crypto-api/key-passphrase.d.ts +11 -0
  203. package/lib/crypto-api/key-passphrase.d.ts.map +1 -0
  204. package/lib/crypto-api/key-passphrase.js +51 -0
  205. package/lib/crypto-api/key-passphrase.js.map +1 -0
  206. package/lib/crypto-api/keybackup.d.ts +87 -0
  207. package/lib/crypto-api/keybackup.d.ts.map +1 -0
  208. package/lib/crypto-api/keybackup.js +1 -0
  209. package/lib/crypto-api/keybackup.js.map +1 -0
  210. package/lib/crypto-api/recovery-key.d.ts +11 -0
  211. package/lib/crypto-api/recovery-key.d.ts.map +1 -0
  212. package/lib/crypto-api/recovery-key.js +65 -0
  213. package/lib/crypto-api/recovery-key.js.map +1 -0
  214. package/lib/crypto-api/verification.d.ts +315 -0
  215. package/lib/crypto-api/verification.d.ts.map +1 -0
  216. package/lib/crypto-api/verification.js +130 -0
  217. package/lib/crypto-api/verification.js.map +1 -0
  218. package/lib/digest.d.ts +10 -0
  219. package/lib/digest.d.ts.map +1 -0
  220. package/lib/digest.js +40 -0
  221. package/lib/digest.js.map +1 -0
  222. package/lib/embedded.d.ts +182 -0
  223. package/lib/embedded.d.ts.map +1 -0
  224. package/lib/embedded.js +746 -0
  225. package/lib/embedded.js.map +1 -0
  226. package/lib/errors.d.ts +38 -0
  227. package/lib/errors.d.ts.map +1 -0
  228. package/lib/errors.js +73 -0
  229. package/lib/errors.js.map +1 -0
  230. package/lib/event-mapper.d.ts +9 -0
  231. package/lib/event-mapper.d.ts.map +1 -0
  232. package/lib/event-mapper.js +74 -0
  233. package/lib/event-mapper.js.map +1 -0
  234. package/lib/extensible_events_v1/ExtensibleEvent.d.ts +38 -0
  235. package/lib/extensible_events_v1/ExtensibleEvent.d.ts.map +1 -0
  236. package/lib/extensible_events_v1/ExtensibleEvent.js +57 -0
  237. package/lib/extensible_events_v1/ExtensibleEvent.js.map +1 -0
  238. package/lib/extensible_events_v1/InvalidEventError.d.ts +7 -0
  239. package/lib/extensible_events_v1/InvalidEventError.d.ts.map +1 -0
  240. package/lib/extensible_events_v1/InvalidEventError.js +25 -0
  241. package/lib/extensible_events_v1/InvalidEventError.js.map +1 -0
  242. package/lib/extensible_events_v1/MessageEvent.d.ts +44 -0
  243. package/lib/extensible_events_v1/MessageEvent.d.ts.map +1 -0
  244. package/lib/extensible_events_v1/MessageEvent.js +134 -0
  245. package/lib/extensible_events_v1/MessageEvent.js.map +1 -0
  246. package/lib/extensible_events_v1/PollEndEvent.d.ts +33 -0
  247. package/lib/extensible_events_v1/PollEndEvent.d.ts.map +1 -0
  248. package/lib/extensible_events_v1/PollEndEvent.js +88 -0
  249. package/lib/extensible_events_v1/PollEndEvent.js.map +1 -0
  250. package/lib/extensible_events_v1/PollResponseEvent.d.ts +49 -0
  251. package/lib/extensible_events_v1/PollResponseEvent.d.ts.map +1 -0
  252. package/lib/extensible_events_v1/PollResponseEvent.js +135 -0
  253. package/lib/extensible_events_v1/PollResponseEvent.js.map +1 -0
  254. package/lib/extensible_events_v1/PollStartEvent.d.ts +71 -0
  255. package/lib/extensible_events_v1/PollStartEvent.d.ts.map +1 -0
  256. package/lib/extensible_events_v1/PollStartEvent.js +185 -0
  257. package/lib/extensible_events_v1/PollStartEvent.js.map +1 -0
  258. package/lib/extensible_events_v1/utilities.d.ts +14 -0
  259. package/lib/extensible_events_v1/utilities.d.ts.map +1 -0
  260. package/lib/extensible_events_v1/utilities.js +34 -0
  261. package/lib/extensible_events_v1/utilities.js.map +1 -0
  262. package/lib/feature.d.ts +20 -0
  263. package/lib/feature.d.ts.map +1 -0
  264. package/lib/feature.js +89 -0
  265. package/lib/feature.js.map +1 -0
  266. package/lib/filter-component.d.ts +64 -0
  267. package/lib/filter-component.d.ts.map +1 -0
  268. package/lib/filter-component.js +170 -0
  269. package/lib/filter-component.js.map +1 -0
  270. package/lib/filter.d.ts +97 -0
  271. package/lib/filter.d.ts.map +1 -0
  272. package/lib/filter.js +207 -0
  273. package/lib/filter.js.map +1 -0
  274. package/lib/http-api/errors.d.ts +117 -0
  275. package/lib/http-api/errors.d.ts.map +1 -0
  276. package/lib/http-api/errors.js +245 -0
  277. package/lib/http-api/errors.js.map +1 -0
  278. package/lib/http-api/fetch.d.ts +80 -0
  279. package/lib/http-api/fetch.d.ts.map +1 -0
  280. package/lib/http-api/fetch.js +332 -0
  281. package/lib/http-api/fetch.js.map +1 -0
  282. package/lib/http-api/index.d.ts +33 -0
  283. package/lib/http-api/index.d.ts.map +1 -0
  284. package/lib/http-api/index.js +178 -0
  285. package/lib/http-api/index.js.map +1 -0
  286. package/lib/http-api/interface.d.ts +186 -0
  287. package/lib/http-api/interface.d.ts.map +1 -0
  288. package/lib/http-api/interface.js +39 -0
  289. package/lib/http-api/interface.js.map +1 -0
  290. package/lib/http-api/method.d.ts +10 -0
  291. package/lib/http-api/method.d.ts.map +1 -0
  292. package/lib/http-api/method.js +27 -0
  293. package/lib/http-api/method.js.map +1 -0
  294. package/lib/http-api/prefix.d.ts +31 -0
  295. package/lib/http-api/prefix.d.ts.map +1 -0
  296. package/lib/http-api/prefix.js +50 -0
  297. package/lib/http-api/prefix.js.map +1 -0
  298. package/lib/http-api/refresh.d.ts +53 -0
  299. package/lib/http-api/refresh.d.ts.map +1 -0
  300. package/lib/http-api/refresh.js +174 -0
  301. package/lib/http-api/refresh.js.map +1 -0
  302. package/lib/http-api/utils.d.ts +37 -0
  303. package/lib/http-api/utils.d.ts.map +1 -0
  304. package/lib/http-api/utils.js +182 -0
  305. package/lib/http-api/utils.js.map +1 -0
  306. package/lib/index.d.ts +4 -0
  307. package/lib/index.d.ts.map +1 -0
  308. package/lib/index.js +24 -0
  309. package/lib/index.js.map +1 -0
  310. package/lib/indexeddb-helpers.d.ts +10 -0
  311. package/lib/indexeddb-helpers.d.ts.map +1 -0
  312. package/lib/indexeddb-helpers.js +51 -0
  313. package/lib/indexeddb-helpers.js.map +1 -0
  314. package/lib/indexeddb-worker.d.ts +7 -0
  315. package/lib/indexeddb-worker.d.ts.map +1 -0
  316. package/lib/indexeddb-worker.js +25 -0
  317. package/lib/indexeddb-worker.js.map +1 -0
  318. package/lib/interactive-auth.d.ts +341 -0
  319. package/lib/interactive-auth.d.ts.map +1 -0
  320. package/lib/interactive-auth.js +563 -0
  321. package/lib/interactive-auth.js.map +1 -0
  322. package/lib/logger.d.ts +124 -0
  323. package/lib/logger.d.ts.map +1 -0
  324. package/lib/logger.js +230 -0
  325. package/lib/logger.js.map +1 -0
  326. package/lib/matrixrtc/CallMembership.d.ts +154 -0
  327. package/lib/matrixrtc/CallMembership.d.ts.map +1 -0
  328. package/lib/matrixrtc/CallMembership.js +469 -0
  329. package/lib/matrixrtc/CallMembership.js.map +1 -0
  330. package/lib/matrixrtc/EncryptionManager.d.ts +44 -0
  331. package/lib/matrixrtc/EncryptionManager.d.ts.map +1 -0
  332. package/lib/matrixrtc/EncryptionManager.js +13 -0
  333. package/lib/matrixrtc/EncryptionManager.js.map +1 -0
  334. package/lib/matrixrtc/IKeyTransport.d.ts +37 -0
  335. package/lib/matrixrtc/IKeyTransport.d.ts.map +1 -0
  336. package/lib/matrixrtc/IKeyTransport.js +27 -0
  337. package/lib/matrixrtc/IKeyTransport.js.map +1 -0
  338. package/lib/matrixrtc/IMembershipManager.d.ts +94 -0
  339. package/lib/matrixrtc/IMembershipManager.d.ts.map +1 -0
  340. package/lib/matrixrtc/IMembershipManager.js +40 -0
  341. package/lib/matrixrtc/IMembershipManager.js.map +1 -0
  342. package/lib/matrixrtc/LivekitTransport.d.ts +23 -0
  343. package/lib/matrixrtc/LivekitTransport.d.ts.map +1 -0
  344. package/lib/matrixrtc/LivekitTransport.js +29 -0
  345. package/lib/matrixrtc/LivekitTransport.js.map +1 -0
  346. package/lib/matrixrtc/MatrixRTCSession.d.ts +343 -0
  347. package/lib/matrixrtc/MatrixRTCSession.d.ts.map +1 -0
  348. package/lib/matrixrtc/MatrixRTCSession.js +623 -0
  349. package/lib/matrixrtc/MatrixRTCSession.js.map +1 -0
  350. package/lib/matrixrtc/MatrixRTCSessionManager.d.ts +46 -0
  351. package/lib/matrixrtc/MatrixRTCSessionManager.d.ts.map +1 -0
  352. package/lib/matrixrtc/MatrixRTCSessionManager.js +149 -0
  353. package/lib/matrixrtc/MatrixRTCSessionManager.js.map +1 -0
  354. package/lib/matrixrtc/MembershipManager.d.ts +210 -0
  355. package/lib/matrixrtc/MembershipManager.d.ts.map +1 -0
  356. package/lib/matrixrtc/MembershipManager.js +977 -0
  357. package/lib/matrixrtc/MembershipManager.js.map +1 -0
  358. package/lib/matrixrtc/MembershipManagerActionScheduler.d.ts +59 -0
  359. package/lib/matrixrtc/MembershipManagerActionScheduler.d.ts.map +1 -0
  360. package/lib/matrixrtc/MembershipManagerActionScheduler.js +125 -0
  361. package/lib/matrixrtc/MembershipManagerActionScheduler.js.map +1 -0
  362. package/lib/matrixrtc/RTCEncryptionManager.d.ts +110 -0
  363. package/lib/matrixrtc/RTCEncryptionManager.d.ts.map +1 -0
  364. package/lib/matrixrtc/RTCEncryptionManager.js +376 -0
  365. package/lib/matrixrtc/RTCEncryptionManager.js.map +1 -0
  366. package/lib/matrixrtc/ToDeviceKeyTransport.d.ts +30 -0
  367. package/lib/matrixrtc/ToDeviceKeyTransport.d.ts.map +1 -0
  368. package/lib/matrixrtc/ToDeviceKeyTransport.js +164 -0
  369. package/lib/matrixrtc/ToDeviceKeyTransport.js.map +1 -0
  370. package/lib/matrixrtc/index.d.ts +9 -0
  371. package/lib/matrixrtc/index.d.ts.map +1 -0
  372. package/lib/matrixrtc/index.js +23 -0
  373. package/lib/matrixrtc/index.js.map +1 -0
  374. package/lib/matrixrtc/membershipData/common.d.ts +8 -0
  375. package/lib/matrixrtc/membershipData/common.d.ts.map +1 -0
  376. package/lib/matrixrtc/membershipData/common.js +26 -0
  377. package/lib/matrixrtc/membershipData/common.js.map +1 -0
  378. package/lib/matrixrtc/membershipData/index.d.ts +4 -0
  379. package/lib/matrixrtc/membershipData/index.d.ts.map +1 -0
  380. package/lib/matrixrtc/membershipData/index.js +20 -0
  381. package/lib/matrixrtc/membershipData/index.js.map +1 -0
  382. package/lib/matrixrtc/membershipData/rtc.d.ts +33 -0
  383. package/lib/matrixrtc/membershipData/rtc.d.ts.map +1 -0
  384. package/lib/matrixrtc/membershipData/rtc.js +137 -0
  385. package/lib/matrixrtc/membershipData/rtc.js.map +1 -0
  386. package/lib/matrixrtc/membershipData/session.d.ts +77 -0
  387. package/lib/matrixrtc/membershipData/session.d.ts.map +1 -0
  388. package/lib/matrixrtc/membershipData/session.js +62 -0
  389. package/lib/matrixrtc/membershipData/session.js.map +1 -0
  390. package/lib/matrixrtc/types.d.ts +169 -0
  391. package/lib/matrixrtc/types.d.ts.map +1 -0
  392. package/lib/matrixrtc/types.js +117 -0
  393. package/lib/matrixrtc/types.js.map +1 -0
  394. package/lib/matrixrtc/utils.d.ts +27 -0
  395. package/lib/matrixrtc/utils.d.ts.map +1 -0
  396. package/lib/matrixrtc/utils.js +72 -0
  397. package/lib/matrixrtc/utils.js.map +1 -0
  398. package/lib/models/MSC3089Branch.d.ts +98 -0
  399. package/lib/models/MSC3089Branch.d.ts.map +1 -0
  400. package/lib/models/MSC3089Branch.js +240 -0
  401. package/lib/models/MSC3089Branch.js.map +1 -0
  402. package/lib/models/MSC3089TreeSpace.d.ts +166 -0
  403. package/lib/models/MSC3089TreeSpace.d.ts.map +1 -0
  404. package/lib/models/MSC3089TreeSpace.js +521 -0
  405. package/lib/models/MSC3089TreeSpace.js.map +1 -0
  406. package/lib/models/ToDeviceMessage.d.ts +17 -0
  407. package/lib/models/ToDeviceMessage.d.ts.map +1 -0
  408. package/lib/models/ToDeviceMessage.js +1 -0
  409. package/lib/models/ToDeviceMessage.js.map +1 -0
  410. package/lib/models/beacon.d.ts +52 -0
  411. package/lib/models/beacon.d.ts.map +1 -0
  412. package/lib/models/beacon.js +174 -0
  413. package/lib/models/beacon.js.map +1 -0
  414. package/lib/models/compare-event-ordering.d.ts +24 -0
  415. package/lib/models/compare-event-ordering.d.ts.map +1 -0
  416. package/lib/models/compare-event-ordering.js +120 -0
  417. package/lib/models/compare-event-ordering.js.map +1 -0
  418. package/lib/models/device.d.ts +45 -0
  419. package/lib/models/device.d.ts.map +1 -0
  420. package/lib/models/device.js +77 -0
  421. package/lib/models/device.js.map +1 -0
  422. package/lib/models/event-context.d.ts +62 -0
  423. package/lib/models/event-context.d.ts.map +1 -0
  424. package/lib/models/event-context.js +113 -0
  425. package/lib/models/event-context.js.map +1 -0
  426. package/lib/models/event-status.d.ts +19 -0
  427. package/lib/models/event-status.d.ts.map +1 -0
  428. package/lib/models/event-status.js +36 -0
  429. package/lib/models/event-status.js.map +1 -0
  430. package/lib/models/event-timeline-set.d.ts +308 -0
  431. package/lib/models/event-timeline-set.d.ts.map +1 -0
  432. package/lib/models/event-timeline-set.js +805 -0
  433. package/lib/models/event-timeline-set.js.map +1 -0
  434. package/lib/models/event-timeline.d.ts +224 -0
  435. package/lib/models/event-timeline.d.ts.map +1 -0
  436. package/lib/models/event-timeline.js +434 -0
  437. package/lib/models/event-timeline.js.map +1 -0
  438. package/lib/models/event.d.ts +844 -0
  439. package/lib/models/event.d.ts.map +1 -0
  440. package/lib/models/event.js +1600 -0
  441. package/lib/models/event.js.map +1 -0
  442. package/lib/models/invites-ignorer-types.d.ts +27 -0
  443. package/lib/models/invites-ignorer-types.d.ts.map +1 -0
  444. package/lib/models/invites-ignorer-types.js +56 -0
  445. package/lib/models/invites-ignorer-types.js.map +1 -0
  446. package/lib/models/invites-ignorer.d.ts +112 -0
  447. package/lib/models/invites-ignorer.d.ts.map +1 -0
  448. package/lib/models/invites-ignorer.js +357 -0
  449. package/lib/models/invites-ignorer.js.map +1 -0
  450. package/lib/models/poll.d.ts +67 -0
  451. package/lib/models/poll.d.ts.map +1 -0
  452. package/lib/models/poll.js +241 -0
  453. package/lib/models/poll.js.map +1 -0
  454. package/lib/models/profile-keys.d.ts +17 -0
  455. package/lib/models/profile-keys.d.ts.map +1 -0
  456. package/lib/models/profile-keys.js +34 -0
  457. package/lib/models/profile-keys.js.map +1 -0
  458. package/lib/models/read-receipt.d.ts +115 -0
  459. package/lib/models/read-receipt.d.ts.map +1 -0
  460. package/lib/models/read-receipt.js +366 -0
  461. package/lib/models/read-receipt.js.map +1 -0
  462. package/lib/models/related-relations.d.ts +11 -0
  463. package/lib/models/related-relations.d.ts.map +1 -0
  464. package/lib/models/related-relations.js +33 -0
  465. package/lib/models/related-relations.js.map +1 -0
  466. package/lib/models/relations-container.d.ts +44 -0
  467. package/lib/models/relations-container.d.ts.map +1 -0
  468. package/lib/models/relations-container.js +132 -0
  469. package/lib/models/relations-container.js.map +1 -0
  470. package/lib/models/relations.d.ts +123 -0
  471. package/lib/models/relations.d.ts.map +1 -0
  472. package/lib/models/relations.js +378 -0
  473. package/lib/models/relations.js.map +1 -0
  474. package/lib/models/room-member.d.ts +221 -0
  475. package/lib/models/room-member.d.ts.map +1 -0
  476. package/lib/models/room-member.js +376 -0
  477. package/lib/models/room-member.js.map +1 -0
  478. package/lib/models/room-receipts.d.ts +39 -0
  479. package/lib/models/room-receipts.d.ts.map +1 -0
  480. package/lib/models/room-receipts.js +392 -0
  481. package/lib/models/room-receipts.js.map +1 -0
  482. package/lib/models/room-state.d.ts +463 -0
  483. package/lib/models/room-state.d.ts.map +1 -0
  484. package/lib/models/room-state.js +1066 -0
  485. package/lib/models/room-state.js.map +1 -0
  486. package/lib/models/room-sticky-events.d.ts +110 -0
  487. package/lib/models/room-sticky-events.d.ts.map +1 -0
  488. package/lib/models/room-sticky-events.js +353 -0
  489. package/lib/models/room-sticky-events.js.map +1 -0
  490. package/lib/models/room-summary.d.ts +59 -0
  491. package/lib/models/room-summary.d.ts.map +1 -0
  492. package/lib/models/room-summary.js +39 -0
  493. package/lib/models/room-summary.js.map +1 -0
  494. package/lib/models/room.d.ts +1285 -0
  495. package/lib/models/room.d.ts.map +1 -0
  496. package/lib/models/room.js +3548 -0
  497. package/lib/models/room.js.map +1 -0
  498. package/lib/models/search-result.d.ts +20 -0
  499. package/lib/models/search-result.d.ts.map +1 -0
  500. package/lib/models/search-result.js +52 -0
  501. package/lib/models/search-result.js.map +1 -0
  502. package/lib/models/thread.d.ts +245 -0
  503. package/lib/models/thread.d.ts.map +1 -0
  504. package/lib/models/thread.js +866 -0
  505. package/lib/models/thread.js.map +1 -0
  506. package/lib/models/typed-event-emitter.d.ts +157 -0
  507. package/lib/models/typed-event-emitter.d.ts.map +1 -0
  508. package/lib/models/typed-event-emitter.js +227 -0
  509. package/lib/models/typed-event-emitter.js.map +1 -0
  510. package/lib/models/user.d.ts +195 -0
  511. package/lib/models/user.d.ts.map +1 -0
  512. package/lib/models/user.js +218 -0
  513. package/lib/models/user.js.map +1 -0
  514. package/lib/oidc/authorize.d.ts +93 -0
  515. package/lib/oidc/authorize.d.ts.map +1 -0
  516. package/lib/oidc/authorize.js +282 -0
  517. package/lib/oidc/authorize.js.map +1 -0
  518. package/lib/oidc/discovery.d.ts +22 -0
  519. package/lib/oidc/discovery.d.ts.map +1 -0
  520. package/lib/oidc/discovery.js +78 -0
  521. package/lib/oidc/discovery.js.map +1 -0
  522. package/lib/oidc/error.d.ts +18 -0
  523. package/lib/oidc/error.d.ts.map +1 -0
  524. package/lib/oidc/error.js +35 -0
  525. package/lib/oidc/error.js.map +1 -0
  526. package/lib/oidc/index.d.ts +16 -0
  527. package/lib/oidc/index.d.ts.map +1 -0
  528. package/lib/oidc/index.js +29 -0
  529. package/lib/oidc/index.js.map +1 -0
  530. package/lib/oidc/register.d.ts +70 -0
  531. package/lib/oidc/register.d.ts.map +1 -0
  532. package/lib/oidc/register.js +135 -0
  533. package/lib/oidc/register.js.map +1 -0
  534. package/lib/oidc/tokenRefresher.d.ts +91 -0
  535. package/lib/oidc/tokenRefresher.d.ts.map +1 -0
  536. package/lib/oidc/tokenRefresher.js +187 -0
  537. package/lib/oidc/tokenRefresher.js.map +1 -0
  538. package/lib/oidc/validate.d.ts +78 -0
  539. package/lib/oidc/validate.d.ts.map +1 -0
  540. package/lib/oidc/validate.js +181 -0
  541. package/lib/oidc/validate.js.map +1 -0
  542. package/lib/pushprocessor.d.ts +140 -0
  543. package/lib/pushprocessor.d.ts.map +1 -0
  544. package/lib/pushprocessor.js +702 -0
  545. package/lib/pushprocessor.js.map +1 -0
  546. package/lib/randomstring.d.ts +32 -0
  547. package/lib/randomstring.d.ts.map +1 -0
  548. package/lib/randomstring.js +97 -0
  549. package/lib/randomstring.js.map +1 -0
  550. package/lib/realtime-callbacks.d.ts +18 -0
  551. package/lib/realtime-callbacks.d.ts.map +1 -0
  552. package/lib/realtime-callbacks.js +177 -0
  553. package/lib/realtime-callbacks.js.map +1 -0
  554. package/lib/receipt-accumulator.d.ts +51 -0
  555. package/lib/receipt-accumulator.d.ts.map +1 -0
  556. package/lib/receipt-accumulator.js +164 -0
  557. package/lib/receipt-accumulator.js.map +1 -0
  558. package/lib/rendezvous/MSC4108SignInWithQR.d.ts +112 -0
  559. package/lib/rendezvous/MSC4108SignInWithQR.d.ts.map +1 -0
  560. package/lib/rendezvous/MSC4108SignInWithQR.js +389 -0
  561. package/lib/rendezvous/MSC4108SignInWithQR.js.map +1 -0
  562. package/lib/rendezvous/RendezvousChannel.d.ts +27 -0
  563. package/lib/rendezvous/RendezvousChannel.d.ts.map +1 -0
  564. package/lib/rendezvous/RendezvousChannel.js +1 -0
  565. package/lib/rendezvous/RendezvousChannel.js.map +1 -0
  566. package/lib/rendezvous/RendezvousCode.d.ts +9 -0
  567. package/lib/rendezvous/RendezvousCode.d.ts.map +1 -0
  568. package/lib/rendezvous/RendezvousCode.js +1 -0
  569. package/lib/rendezvous/RendezvousCode.js.map +1 -0
  570. package/lib/rendezvous/RendezvousError.d.ts +6 -0
  571. package/lib/rendezvous/RendezvousError.d.ts.map +1 -0
  572. package/lib/rendezvous/RendezvousError.js +23 -0
  573. package/lib/rendezvous/RendezvousError.js.map +1 -0
  574. package/lib/rendezvous/RendezvousFailureReason.d.ts +31 -0
  575. package/lib/rendezvous/RendezvousFailureReason.d.ts.map +1 -0
  576. package/lib/rendezvous/RendezvousFailureReason.js +47 -0
  577. package/lib/rendezvous/RendezvousFailureReason.js.map +1 -0
  578. package/lib/rendezvous/RendezvousIntent.d.ts +5 -0
  579. package/lib/rendezvous/RendezvousIntent.d.ts.map +1 -0
  580. package/lib/rendezvous/RendezvousIntent.js +22 -0
  581. package/lib/rendezvous/RendezvousIntent.js.map +1 -0
  582. package/lib/rendezvous/RendezvousTransport.d.ts +36 -0
  583. package/lib/rendezvous/RendezvousTransport.d.ts.map +1 -0
  584. package/lib/rendezvous/RendezvousTransport.js +1 -0
  585. package/lib/rendezvous/RendezvousTransport.js.map +1 -0
  586. package/lib/rendezvous/channels/MSC4108SecureChannel.d.ts +58 -0
  587. package/lib/rendezvous/channels/MSC4108SecureChannel.d.ts.map +1 -0
  588. package/lib/rendezvous/channels/MSC4108SecureChannel.js +246 -0
  589. package/lib/rendezvous/channels/MSC4108SecureChannel.js.map +1 -0
  590. package/lib/rendezvous/channels/index.d.ts +2 -0
  591. package/lib/rendezvous/channels/index.d.ts.map +1 -0
  592. package/lib/rendezvous/channels/index.js +18 -0
  593. package/lib/rendezvous/channels/index.js.map +1 -0
  594. package/lib/rendezvous/index.d.ts +10 -0
  595. package/lib/rendezvous/index.d.ts.map +1 -0
  596. package/lib/rendezvous/index.js +23 -0
  597. package/lib/rendezvous/index.js.map +1 -0
  598. package/lib/rendezvous/transports/MSC4108RendezvousSession.d.ts +61 -0
  599. package/lib/rendezvous/transports/MSC4108RendezvousSession.d.ts.map +1 -0
  600. package/lib/rendezvous/transports/MSC4108RendezvousSession.js +254 -0
  601. package/lib/rendezvous/transports/MSC4108RendezvousSession.js.map +1 -0
  602. package/lib/rendezvous/transports/index.d.ts +2 -0
  603. package/lib/rendezvous/transports/index.d.ts.map +1 -0
  604. package/lib/rendezvous/transports/index.js +18 -0
  605. package/lib/rendezvous/transports/index.js.map +1 -0
  606. package/lib/room-hierarchy.d.ts +35 -0
  607. package/lib/room-hierarchy.d.ts.map +1 -0
  608. package/lib/room-hierarchy.js +136 -0
  609. package/lib/room-hierarchy.js.map +1 -0
  610. package/lib/rust-crypto/CrossSigningIdentity.d.ts +35 -0
  611. package/lib/rust-crypto/CrossSigningIdentity.d.ts.map +1 -0
  612. package/lib/rust-crypto/CrossSigningIdentity.js +163 -0
  613. package/lib/rust-crypto/CrossSigningIdentity.js.map +1 -0
  614. package/lib/rust-crypto/DehydratedDeviceManager.d.ts +118 -0
  615. package/lib/rust-crypto/DehydratedDeviceManager.d.ts.map +1 -0
  616. package/lib/rust-crypto/DehydratedDeviceManager.js +361 -0
  617. package/lib/rust-crypto/DehydratedDeviceManager.js.map +1 -0
  618. package/lib/rust-crypto/KeyClaimManager.d.ts +33 -0
  619. package/lib/rust-crypto/KeyClaimManager.d.ts.map +1 -0
  620. package/lib/rust-crypto/KeyClaimManager.js +82 -0
  621. package/lib/rust-crypto/KeyClaimManager.js.map +1 -0
  622. package/lib/rust-crypto/OutgoingRequestProcessor.d.ts +36 -0
  623. package/lib/rust-crypto/OutgoingRequestProcessor.d.ts.map +1 -0
  624. package/lib/rust-crypto/OutgoingRequestProcessor.js +194 -0
  625. package/lib/rust-crypto/OutgoingRequestProcessor.js.map +1 -0
  626. package/lib/rust-crypto/OutgoingRequestsManager.d.ts +47 -0
  627. package/lib/rust-crypto/OutgoingRequestsManager.d.ts.map +1 -0
  628. package/lib/rust-crypto/OutgoingRequestsManager.js +175 -0
  629. package/lib/rust-crypto/OutgoingRequestsManager.js.map +1 -0
  630. package/lib/rust-crypto/PerSessionKeyBackupDownloader.d.ts +120 -0
  631. package/lib/rust-crypto/PerSessionKeyBackupDownloader.d.ts.map +1 -0
  632. package/lib/rust-crypto/PerSessionKeyBackupDownloader.js +469 -0
  633. package/lib/rust-crypto/PerSessionKeyBackupDownloader.js.map +1 -0
  634. package/lib/rust-crypto/RoomEncryptor.d.ts +100 -0
  635. package/lib/rust-crypto/RoomEncryptor.d.ts.map +1 -0
  636. package/lib/rust-crypto/RoomEncryptor.js +308 -0
  637. package/lib/rust-crypto/RoomEncryptor.js.map +1 -0
  638. package/lib/rust-crypto/backup.d.ts +278 -0
  639. package/lib/rust-crypto/backup.d.ts.map +1 -0
  640. package/lib/rust-crypto/backup.js +898 -0
  641. package/lib/rust-crypto/backup.js.map +1 -0
  642. package/lib/rust-crypto/constants.d.ts +3 -0
  643. package/lib/rust-crypto/constants.d.ts.map +1 -0
  644. package/lib/rust-crypto/constants.js +19 -0
  645. package/lib/rust-crypto/constants.js.map +1 -0
  646. package/lib/rust-crypto/device-converter.d.ts +28 -0
  647. package/lib/rust-crypto/device-converter.d.ts.map +1 -0
  648. package/lib/rust-crypto/device-converter.js +123 -0
  649. package/lib/rust-crypto/device-converter.js.map +1 -0
  650. package/lib/rust-crypto/index.d.ts +65 -0
  651. package/lib/rust-crypto/index.d.ts.map +1 -0
  652. package/lib/rust-crypto/index.js +149 -0
  653. package/lib/rust-crypto/index.js.map +1 -0
  654. package/lib/rust-crypto/libolm_migration.d.ts +81 -0
  655. package/lib/rust-crypto/libolm_migration.d.ts.map +1 -0
  656. package/lib/rust-crypto/libolm_migration.js +456 -0
  657. package/lib/rust-crypto/libolm_migration.js.map +1 -0
  658. package/lib/rust-crypto/rust-crypto.d.ts +576 -0
  659. package/lib/rust-crypto/rust-crypto.d.ts.map +1 -0
  660. package/lib/rust-crypto/rust-crypto.js +2324 -0
  661. package/lib/rust-crypto/rust-crypto.js.map +1 -0
  662. package/lib/rust-crypto/secret-storage.d.ts +22 -0
  663. package/lib/rust-crypto/secret-storage.d.ts.map +1 -0
  664. package/lib/rust-crypto/secret-storage.js +63 -0
  665. package/lib/rust-crypto/secret-storage.js.map +1 -0
  666. package/lib/rust-crypto/verification.d.ts +321 -0
  667. package/lib/rust-crypto/verification.d.ts.map +1 -0
  668. package/lib/rust-crypto/verification.js +817 -0
  669. package/lib/rust-crypto/verification.js.map +1 -0
  670. package/lib/scheduler.d.ts +132 -0
  671. package/lib/scheduler.d.ts.map +1 -0
  672. package/lib/scheduler.js +259 -0
  673. package/lib/scheduler.js.map +1 -0
  674. package/lib/secret-storage.d.ts +383 -0
  675. package/lib/secret-storage.d.ts.map +1 -0
  676. package/lib/secret-storage.js +487 -0
  677. package/lib/secret-storage.js.map +1 -0
  678. package/lib/serverCapabilities.d.ts +78 -0
  679. package/lib/serverCapabilities.d.ts.map +1 -0
  680. package/lib/serverCapabilities.js +104 -0
  681. package/lib/serverCapabilities.js.map +1 -0
  682. package/lib/service-types.d.ts +5 -0
  683. package/lib/service-types.d.ts.map +1 -0
  684. package/lib/service-types.js +23 -0
  685. package/lib/service-types.js.map +1 -0
  686. package/lib/sliding-sync-sdk.d.ts +107 -0
  687. package/lib/sliding-sync-sdk.d.ts.map +1 -0
  688. package/lib/sliding-sync-sdk.js +892 -0
  689. package/lib/sliding-sync-sdk.js.map +1 -0
  690. package/lib/sliding-sync.d.ts +306 -0
  691. package/lib/sliding-sync.d.ts.map +1 -0
  692. package/lib/sliding-sync.js +585 -0
  693. package/lib/sliding-sync.js.map +1 -0
  694. package/lib/store/index.d.ts +201 -0
  695. package/lib/store/index.d.ts.map +1 -0
  696. package/lib/store/index.js +1 -0
  697. package/lib/store/index.js.map +1 -0
  698. package/lib/store/indexeddb-backend.d.ts +24 -0
  699. package/lib/store/indexeddb-backend.d.ts.map +1 -0
  700. package/lib/store/indexeddb-backend.js +1 -0
  701. package/lib/store/indexeddb-backend.js.map +1 -0
  702. package/lib/store/indexeddb-local-backend.d.ts +129 -0
  703. package/lib/store/indexeddb-local-backend.d.ts.map +1 -0
  704. package/lib/store/indexeddb-local-backend.js +599 -0
  705. package/lib/store/indexeddb-local-backend.js.map +1 -0
  706. package/lib/store/indexeddb-remote-backend.d.ts +79 -0
  707. package/lib/store/indexeddb-remote-backend.d.ts.map +1 -0
  708. package/lib/store/indexeddb-remote-backend.js +209 -0
  709. package/lib/store/indexeddb-remote-backend.js.map +1 -0
  710. package/lib/store/indexeddb-store-worker.d.ts +35 -0
  711. package/lib/store/indexeddb-store-worker.d.ts.map +1 -0
  712. package/lib/store/indexeddb-store-worker.js +146 -0
  713. package/lib/store/indexeddb-store-worker.js.map +1 -0
  714. package/lib/store/indexeddb.d.ts +142 -0
  715. package/lib/store/indexeddb.d.ts.map +1 -0
  716. package/lib/store/indexeddb.js +347 -0
  717. package/lib/store/indexeddb.js.map +1 -0
  718. package/lib/store/local-storage-events-emitter.d.ts +30 -0
  719. package/lib/store/local-storage-events-emitter.d.ts.map +1 -0
  720. package/lib/store/local-storage-events-emitter.js +37 -0
  721. package/lib/store/local-storage-events-emitter.js.map +1 -0
  722. package/lib/store/memory.d.ts +209 -0
  723. package/lib/store/memory.d.ts.map +1 -0
  724. package/lib/store/memory.js +432 -0
  725. package/lib/store/memory.js.map +1 -0
  726. package/lib/store/stub.d.ts +161 -0
  727. package/lib/store/stub.d.ts.map +1 -0
  728. package/lib/store/stub.js +268 -0
  729. package/lib/store/stub.js.map +1 -0
  730. package/lib/sync-accumulator.d.ts +207 -0
  731. package/lib/sync-accumulator.d.ts.map +1 -0
  732. package/lib/sync-accumulator.js +588 -0
  733. package/lib/sync-accumulator.js.map +1 -0
  734. package/lib/sync.d.ts +273 -0
  735. package/lib/sync.d.ts.map +1 -0
  736. package/lib/sync.js +1764 -0
  737. package/lib/sync.js.map +1 -0
  738. package/lib/testing.d.ts +98 -0
  739. package/lib/testing.d.ts.map +1 -0
  740. package/lib/testing.js +205 -0
  741. package/lib/testing.js.map +1 -0
  742. package/lib/thread-utils.d.ts +10 -0
  743. package/lib/thread-utils.d.ts.map +1 -0
  744. package/lib/thread-utils.js +31 -0
  745. package/lib/thread-utils.js.map +1 -0
  746. package/lib/timeline-window.d.ts +168 -0
  747. package/lib/timeline-window.d.ts.map +1 -0
  748. package/lib/timeline-window.js +494 -0
  749. package/lib/timeline-window.js.map +1 -0
  750. package/lib/types.d.ts +33 -0
  751. package/lib/types.d.ts.map +1 -0
  752. package/lib/types.js +52 -0
  753. package/lib/types.js.map +1 -0
  754. package/lib/utils/decryptAESSecretStorageItem.d.ts +12 -0
  755. package/lib/utils/decryptAESSecretStorageItem.d.ts.map +1 -0
  756. package/lib/utils/decryptAESSecretStorageItem.js +50 -0
  757. package/lib/utils/decryptAESSecretStorageItem.js.map +1 -0
  758. package/lib/utils/encryptAESSecretStorageItem.d.ts +16 -0
  759. package/lib/utils/encryptAESSecretStorageItem.d.ts.map +1 -0
  760. package/lib/utils/encryptAESSecretStorageItem.js +68 -0
  761. package/lib/utils/encryptAESSecretStorageItem.js.map +1 -0
  762. package/lib/utils/internal/deriveKeys.d.ts +10 -0
  763. package/lib/utils/internal/deriveKeys.d.ts.map +1 -0
  764. package/lib/utils/internal/deriveKeys.js +60 -0
  765. package/lib/utils/internal/deriveKeys.js.map +1 -0
  766. package/lib/utils/roomVersion.d.ts +13 -0
  767. package/lib/utils/roomVersion.d.ts.map +1 -0
  768. package/lib/utils/roomVersion.js +36 -0
  769. package/lib/utils/roomVersion.js.map +1 -0
  770. package/lib/utils.d.ts +270 -0
  771. package/lib/utils.d.ts.map +1 -0
  772. package/lib/utils.js +764 -0
  773. package/lib/utils.js.map +1 -0
  774. package/lib/version-support.d.ts +19 -0
  775. package/lib/version-support.d.ts.map +1 -0
  776. package/lib/version-support.js +37 -0
  777. package/lib/version-support.js.map +1 -0
  778. package/lib/webrtc/audioContext.d.ts +15 -0
  779. package/lib/webrtc/audioContext.d.ts.map +1 -0
  780. package/lib/webrtc/audioContext.js +46 -0
  781. package/lib/webrtc/audioContext.js.map +1 -0
  782. package/lib/webrtc/call.d.ts +560 -0
  783. package/lib/webrtc/call.d.ts.map +1 -0
  784. package/lib/webrtc/call.js +2596 -0
  785. package/lib/webrtc/call.js.map +1 -0
  786. package/lib/webrtc/callEventHandler.d.ts +37 -0
  787. package/lib/webrtc/callEventHandler.d.ts.map +1 -0
  788. package/lib/webrtc/callEventHandler.js +344 -0
  789. package/lib/webrtc/callEventHandler.js.map +1 -0
  790. package/lib/webrtc/callEventTypes.d.ts +79 -0
  791. package/lib/webrtc/callEventTypes.d.ts.map +1 -0
  792. package/lib/webrtc/callEventTypes.js +13 -0
  793. package/lib/webrtc/callEventTypes.js.map +1 -0
  794. package/lib/webrtc/callFeed.d.ts +128 -0
  795. package/lib/webrtc/callFeed.d.ts.map +1 -0
  796. package/lib/webrtc/callFeed.js +289 -0
  797. package/lib/webrtc/callFeed.js.map +1 -0
  798. package/lib/webrtc/groupCall.d.ts +319 -0
  799. package/lib/webrtc/groupCall.d.ts.map +1 -0
  800. package/lib/webrtc/groupCall.js +1334 -0
  801. package/lib/webrtc/groupCall.js.map +1 -0
  802. package/lib/webrtc/groupCallEventHandler.d.ts +31 -0
  803. package/lib/webrtc/groupCallEventHandler.d.ts.map +1 -0
  804. package/lib/webrtc/groupCallEventHandler.js +178 -0
  805. package/lib/webrtc/groupCallEventHandler.js.map +1 -0
  806. package/lib/webrtc/mediaHandler.d.ts +89 -0
  807. package/lib/webrtc/mediaHandler.d.ts.map +1 -0
  808. package/lib/webrtc/mediaHandler.js +454 -0
  809. package/lib/webrtc/mediaHandler.js.map +1 -0
  810. package/lib/webrtc/stats/callFeedStatsReporter.d.ts +8 -0
  811. package/lib/webrtc/stats/callFeedStatsReporter.d.ts.map +1 -0
  812. package/lib/webrtc/stats/callFeedStatsReporter.js +79 -0
  813. package/lib/webrtc/stats/callFeedStatsReporter.js.map +1 -0
  814. package/lib/webrtc/stats/callStatsReportGatherer.d.ts +25 -0
  815. package/lib/webrtc/stats/callStatsReportGatherer.d.ts.map +1 -0
  816. package/lib/webrtc/stats/callStatsReportGatherer.js +199 -0
  817. package/lib/webrtc/stats/callStatsReportGatherer.js.map +1 -0
  818. package/lib/webrtc/stats/callStatsReportSummary.d.ts +17 -0
  819. package/lib/webrtc/stats/callStatsReportSummary.d.ts.map +1 -0
  820. package/lib/webrtc/stats/callStatsReportSummary.js +1 -0
  821. package/lib/webrtc/stats/callStatsReportSummary.js.map +1 -0
  822. package/lib/webrtc/stats/connectionStats.d.ts +28 -0
  823. package/lib/webrtc/stats/connectionStats.d.ts.map +1 -0
  824. package/lib/webrtc/stats/connectionStats.js +26 -0
  825. package/lib/webrtc/stats/connectionStats.js.map +1 -0
  826. package/lib/webrtc/stats/connectionStatsBuilder.d.ts +5 -0
  827. package/lib/webrtc/stats/connectionStatsBuilder.d.ts.map +1 -0
  828. package/lib/webrtc/stats/connectionStatsBuilder.js +27 -0
  829. package/lib/webrtc/stats/connectionStatsBuilder.js.map +1 -0
  830. package/lib/webrtc/stats/connectionStatsReportBuilder.d.ts +7 -0
  831. package/lib/webrtc/stats/connectionStatsReportBuilder.d.ts.map +1 -0
  832. package/lib/webrtc/stats/connectionStatsReportBuilder.js +121 -0
  833. package/lib/webrtc/stats/connectionStatsReportBuilder.js.map +1 -0
  834. package/lib/webrtc/stats/groupCallStats.d.ts +22 -0
  835. package/lib/webrtc/stats/groupCallStats.d.ts.map +1 -0
  836. package/lib/webrtc/stats/groupCallStats.js +78 -0
  837. package/lib/webrtc/stats/groupCallStats.js.map +1 -0
  838. package/lib/webrtc/stats/media/mediaSsrcHandler.d.ts +10 -0
  839. package/lib/webrtc/stats/media/mediaSsrcHandler.d.ts.map +1 -0
  840. package/lib/webrtc/stats/media/mediaSsrcHandler.js +57 -0
  841. package/lib/webrtc/stats/media/mediaSsrcHandler.js.map +1 -0
  842. package/lib/webrtc/stats/media/mediaTrackHandler.d.ts +12 -0
  843. package/lib/webrtc/stats/media/mediaTrackHandler.d.ts.map +1 -0
  844. package/lib/webrtc/stats/media/mediaTrackHandler.js +58 -0
  845. package/lib/webrtc/stats/media/mediaTrackHandler.js.map +1 -0
  846. package/lib/webrtc/stats/media/mediaTrackStats.d.ts +86 -0
  847. package/lib/webrtc/stats/media/mediaTrackStats.d.ts.map +1 -0
  848. package/lib/webrtc/stats/media/mediaTrackStats.js +142 -0
  849. package/lib/webrtc/stats/media/mediaTrackStats.js.map +1 -0
  850. package/lib/webrtc/stats/media/mediaTrackStatsHandler.d.ts +22 -0
  851. package/lib/webrtc/stats/media/mediaTrackStatsHandler.d.ts.map +1 -0
  852. package/lib/webrtc/stats/media/mediaTrackStatsHandler.js +76 -0
  853. package/lib/webrtc/stats/media/mediaTrackStatsHandler.js.map +1 -0
  854. package/lib/webrtc/stats/statsReport.d.ts +99 -0
  855. package/lib/webrtc/stats/statsReport.d.ts.map +1 -0
  856. package/lib/webrtc/stats/statsReport.js +32 -0
  857. package/lib/webrtc/stats/statsReport.js.map +1 -0
  858. package/lib/webrtc/stats/statsReportEmitter.d.ts +15 -0
  859. package/lib/webrtc/stats/statsReportEmitter.d.ts.map +1 -0
  860. package/lib/webrtc/stats/statsReportEmitter.js +33 -0
  861. package/lib/webrtc/stats/statsReportEmitter.js.map +1 -0
  862. package/lib/webrtc/stats/summaryStatsReportGatherer.d.ts +16 -0
  863. package/lib/webrtc/stats/summaryStatsReportGatherer.d.ts.map +1 -0
  864. package/lib/webrtc/stats/summaryStatsReportGatherer.js +116 -0
  865. package/lib/webrtc/stats/summaryStatsReportGatherer.js.map +1 -0
  866. package/lib/webrtc/stats/trackStatsBuilder.d.ts +19 -0
  867. package/lib/webrtc/stats/trackStatsBuilder.d.ts.map +1 -0
  868. package/lib/webrtc/stats/trackStatsBuilder.js +168 -0
  869. package/lib/webrtc/stats/trackStatsBuilder.js.map +1 -0
  870. package/lib/webrtc/stats/transportStats.d.ts +11 -0
  871. package/lib/webrtc/stats/transportStats.d.ts.map +1 -0
  872. package/lib/webrtc/stats/transportStats.js +1 -0
  873. package/lib/webrtc/stats/transportStats.js.map +1 -0
  874. package/lib/webrtc/stats/transportStatsBuilder.d.ts +5 -0
  875. package/lib/webrtc/stats/transportStatsBuilder.d.ts.map +1 -0
  876. package/lib/webrtc/stats/transportStatsBuilder.js +34 -0
  877. package/lib/webrtc/stats/transportStatsBuilder.js.map +1 -0
  878. package/lib/webrtc/stats/valueFormatter.d.ts +4 -0
  879. package/lib/webrtc/stats/valueFormatter.d.ts.map +1 -0
  880. package/lib/webrtc/stats/valueFormatter.js +25 -0
  881. package/lib/webrtc/stats/valueFormatter.js.map +1 -0
  882. package/package.json +129 -0
  883. package/src/@types/AESEncryptedSecretStoragePayload.ts +29 -0
  884. package/src/@types/IIdentityServerProvider.ts +24 -0
  885. package/src/@types/PushRules.ts +208 -0
  886. package/src/@types/another-json.d.ts +19 -0
  887. package/src/@types/auth.ts +258 -0
  888. package/src/@types/beacon.ts +140 -0
  889. package/src/@types/common.ts +24 -0
  890. package/src/@types/crypto.ts +71 -0
  891. package/src/@types/event.ts +449 -0
  892. package/src/@types/events.ts +119 -0
  893. package/src/@types/extensible_events.ts +147 -0
  894. package/src/@types/global.d.ts +67 -0
  895. package/src/@types/local_notifications.ts +19 -0
  896. package/src/@types/location.ts +92 -0
  897. package/src/@types/matrix-sdk-crypto-wasm.d.ts +39 -0
  898. package/src/@types/media.ts +245 -0
  899. package/src/@types/membership.ts +57 -0
  900. package/src/@types/partials.ts +103 -0
  901. package/src/@types/polls.ts +120 -0
  902. package/src/@types/read_receipts.ts +61 -0
  903. package/src/@types/registration.ts +102 -0
  904. package/src/@types/requests.ts +346 -0
  905. package/src/@types/search.ts +119 -0
  906. package/src/@types/signed.ts +25 -0
  907. package/src/@types/spaces.ts +37 -0
  908. package/src/@types/state_events.ts +153 -0
  909. package/src/@types/synapse.ts +40 -0
  910. package/src/@types/sync.ts +27 -0
  911. package/src/@types/threepids.ts +29 -0
  912. package/src/@types/topic.ts +69 -0
  913. package/src/@types/uia.ts +24 -0
  914. package/src/NamespacedValue.ts +121 -0
  915. package/src/ReEmitter.ts +93 -0
  916. package/src/ToDeviceMessageQueue.ts +156 -0
  917. package/src/autodiscovery.ts +505 -0
  918. package/src/base64.ts +86 -0
  919. package/src/briij.ts +173 -0
  920. package/src/browser-index.ts +44 -0
  921. package/src/client.ts +9031 -0
  922. package/src/common-crypto/CryptoBackend.ts +295 -0
  923. package/src/common-crypto/README.md +4 -0
  924. package/src/common-crypto/key-passphrase.ts +43 -0
  925. package/src/content-helpers.ts +298 -0
  926. package/src/content-repo.ts +122 -0
  927. package/src/crypto/store/base.ts +388 -0
  928. package/src/crypto/store/indexeddb-crypto-store-backend.ts +655 -0
  929. package/src/crypto/store/indexeddb-crypto-store.ts +555 -0
  930. package/src/crypto/store/localStorage-crypto-store.ts +409 -0
  931. package/src/crypto/store/memory-crypto-store.ts +326 -0
  932. package/src/crypto-api/CryptoEvent.ts +152 -0
  933. package/src/crypto-api/CryptoEventHandlerMap.ts +42 -0
  934. package/src/crypto-api/index.ts +1362 -0
  935. package/src/crypto-api/key-passphrase.ts +58 -0
  936. package/src/crypto-api/keybackup.ts +114 -0
  937. package/src/crypto-api/recovery-key.ts +69 -0
  938. package/src/crypto-api/verification.ts +382 -0
  939. package/src/digest.ts +34 -0
  940. package/src/embedded.ts +865 -0
  941. package/src/errors.ts +87 -0
  942. package/src/event-mapper.ts +88 -0
  943. package/src/extensible_events_v1/ExtensibleEvent.ts +58 -0
  944. package/src/extensible_events_v1/InvalidEventError.ts +24 -0
  945. package/src/extensible_events_v1/MessageEvent.ts +143 -0
  946. package/src/extensible_events_v1/PollEndEvent.ts +97 -0
  947. package/src/extensible_events_v1/PollResponseEvent.ts +148 -0
  948. package/src/extensible_events_v1/PollStartEvent.ts +207 -0
  949. package/src/extensible_events_v1/utilities.ts +35 -0
  950. package/src/feature.ts +88 -0
  951. package/src/filter-component.ts +209 -0
  952. package/src/filter.ts +245 -0
  953. package/src/http-api/errors.ts +261 -0
  954. package/src/http-api/fetch.ts +377 -0
  955. package/src/http-api/index.ts +194 -0
  956. package/src/http-api/interface.ts +229 -0
  957. package/src/http-api/method.ts +25 -0
  958. package/src/http-api/prefix.ts +48 -0
  959. package/src/http-api/refresh.ts +167 -0
  960. package/src/http-api/utils.ts +217 -0
  961. package/src/index.ts +25 -0
  962. package/src/indexeddb-helpers.ts +50 -0
  963. package/src/indexeddb-worker.ts +24 -0
  964. package/src/interactive-auth.ts +700 -0
  965. package/src/logger.ts +279 -0
  966. package/src/matrixrtc/CallMembership.ts +438 -0
  967. package/src/matrixrtc/EncryptionManager.ts +54 -0
  968. package/src/matrixrtc/IKeyTransport.ts +63 -0
  969. package/src/matrixrtc/IMembershipManager.ts +120 -0
  970. package/src/matrixrtc/LivekitTransport.ts +46 -0
  971. package/src/matrixrtc/MatrixRTCSession.ts +934 -0
  972. package/src/matrixrtc/MatrixRTCSessionManager.ts +170 -0
  973. package/src/matrixrtc/MembershipManager.ts +1122 -0
  974. package/src/matrixrtc/MembershipManagerActionScheduler.ts +135 -0
  975. package/src/matrixrtc/RTCEncryptionManager.ts +459 -0
  976. package/src/matrixrtc/ToDeviceKeyTransport.ts +197 -0
  977. package/src/matrixrtc/index.ts +24 -0
  978. package/src/matrixrtc/membershipData/common.ts +27 -0
  979. package/src/matrixrtc/membershipData/index.ts +19 -0
  980. package/src/matrixrtc/membershipData/rtc.ts +156 -0
  981. package/src/matrixrtc/membershipData/session.ts +146 -0
  982. package/src/matrixrtc/types.ts +227 -0
  983. package/src/matrixrtc/utils.ts +71 -0
  984. package/src/models/MSC3089Branch.ts +272 -0
  985. package/src/models/MSC3089TreeSpace.ts +565 -0
  986. package/src/models/ToDeviceMessage.ts +38 -0
  987. package/src/models/beacon.ts +213 -0
  988. package/src/models/compare-event-ordering.ts +139 -0
  989. package/src/models/device.ts +85 -0
  990. package/src/models/event-context.ts +110 -0
  991. package/src/models/event-status.ts +39 -0
  992. package/src/models/event-timeline-set.ts +962 -0
  993. package/src/models/event-timeline.ts +461 -0
  994. package/src/models/event.ts +1819 -0
  995. package/src/models/invites-ignorer-types.ts +58 -0
  996. package/src/models/invites-ignorer.ts +341 -0
  997. package/src/models/poll.ts +285 -0
  998. package/src/models/profile-keys.ts +33 -0
  999. package/src/models/read-receipt.ts +422 -0
  1000. package/src/models/related-relations.ts +39 -0
  1001. package/src/models/relations-container.ts +149 -0
  1002. package/src/models/relations.ts +392 -0
  1003. package/src/models/room-member.ts +486 -0
  1004. package/src/models/room-receipts.ts +439 -0
  1005. package/src/models/room-state.ts +1230 -0
  1006. package/src/models/room-sticky-events.ts +383 -0
  1007. package/src/models/room-summary.ts +78 -0
  1008. package/src/models/room.ts +4067 -0
  1009. package/src/models/search-result.ts +57 -0
  1010. package/src/models/thread.ts +928 -0
  1011. package/src/models/typed-event-emitter.ts +246 -0
  1012. package/src/models/user.ts +302 -0
  1013. package/src/oidc/authorize.ts +279 -0
  1014. package/src/oidc/discovery.ts +67 -0
  1015. package/src/oidc/error.ts +33 -0
  1016. package/src/oidc/index.ts +33 -0
  1017. package/src/oidc/register.ts +163 -0
  1018. package/src/oidc/tokenRefresher.ts +184 -0
  1019. package/src/oidc/validate.ts +265 -0
  1020. package/src/pushprocessor.ts +856 -0
  1021. package/src/randomstring.ts +103 -0
  1022. package/src/realtime-callbacks.ts +191 -0
  1023. package/src/receipt-accumulator.ts +189 -0
  1024. package/src/rendezvous/MSC4108SignInWithQR.ts +443 -0
  1025. package/src/rendezvous/RendezvousChannel.ts +48 -0
  1026. package/src/rendezvous/RendezvousCode.ts +25 -0
  1027. package/src/rendezvous/RendezvousError.ts +26 -0
  1028. package/src/rendezvous/RendezvousFailureReason.ts +49 -0
  1029. package/src/rendezvous/RendezvousIntent.ts +20 -0
  1030. package/src/rendezvous/RendezvousTransport.ts +58 -0
  1031. package/src/rendezvous/channels/MSC4108SecureChannel.ts +270 -0
  1032. package/src/rendezvous/channels/index.ts +17 -0
  1033. package/src/rendezvous/index.ts +25 -0
  1034. package/src/rendezvous/transports/MSC4108RendezvousSession.ts +272 -0
  1035. package/src/rendezvous/transports/index.ts +17 -0
  1036. package/src/room-hierarchy.ts +152 -0
  1037. package/src/rust-crypto/CrossSigningIdentity.ts +195 -0
  1038. package/src/rust-crypto/DehydratedDeviceManager.ts +392 -0
  1039. package/src/rust-crypto/KeyClaimManager.ts +86 -0
  1040. package/src/rust-crypto/OutgoingRequestProcessor.ts +233 -0
  1041. package/src/rust-crypto/OutgoingRequestsManager.ts +170 -0
  1042. package/src/rust-crypto/PerSessionKeyBackupDownloader.ts +501 -0
  1043. package/src/rust-crypto/RoomEncryptor.ts +362 -0
  1044. package/src/rust-crypto/backup.ts +942 -0
  1045. package/src/rust-crypto/constants.ts +18 -0
  1046. package/src/rust-crypto/device-converter.ts +128 -0
  1047. package/src/rust-crypto/index.ts +251 -0
  1048. package/src/rust-crypto/libolm_migration.ts +532 -0
  1049. package/src/rust-crypto/rust-crypto.ts +2542 -0
  1050. package/src/rust-crypto/secret-storage.ts +60 -0
  1051. package/src/rust-crypto/verification.ts +833 -0
  1052. package/src/scheduler.ts +309 -0
  1053. package/src/secret-storage.ts +714 -0
  1054. package/src/serverCapabilities.ts +146 -0
  1055. package/src/service-types.ts +20 -0
  1056. package/src/sliding-sync-sdk.ts +1005 -0
  1057. package/src/sliding-sync.ts +674 -0
  1058. package/src/store/index.ts +261 -0
  1059. package/src/store/indexeddb-backend.ts +41 -0
  1060. package/src/store/indexeddb-local-backend.ts +610 -0
  1061. package/src/store/indexeddb-remote-backend.ts +212 -0
  1062. package/src/store/indexeddb-store-worker.ts +157 -0
  1063. package/src/store/indexeddb.ts +397 -0
  1064. package/src/store/local-storage-events-emitter.ts +46 -0
  1065. package/src/store/memory.ts +448 -0
  1066. package/src/store/stub.ts +280 -0
  1067. package/src/sync-accumulator.ts +779 -0
  1068. package/src/sync.ts +2020 -0
  1069. package/src/testing.ts +231 -0
  1070. package/src/thread-utils.ts +31 -0
  1071. package/src/timeline-window.ts +534 -0
  1072. package/src/types.ts +59 -0
  1073. package/src/utils/decryptAESSecretStorageItem.ts +54 -0
  1074. package/src/utils/encryptAESSecretStorageItem.ts +73 -0
  1075. package/src/utils/internal/deriveKeys.ts +63 -0
  1076. package/src/utils/roomVersion.ts +35 -0
  1077. package/src/utils.ts +775 -0
  1078. package/src/version-support.ts +50 -0
  1079. package/src/webrtc/audioContext.ts +44 -0
  1080. package/src/webrtc/call.ts +3061 -0
  1081. package/src/webrtc/callEventHandler.ts +425 -0
  1082. package/src/webrtc/callEventTypes.ts +101 -0
  1083. package/src/webrtc/callFeed.ts +364 -0
  1084. package/src/webrtc/groupCall.ts +1729 -0
  1085. package/src/webrtc/groupCallEventHandler.ts +234 -0
  1086. package/src/webrtc/mediaHandler.ts +501 -0
  1087. package/src/webrtc/stats/callFeedStatsReporter.ts +91 -0
  1088. package/src/webrtc/stats/callStatsReportGatherer.ts +219 -0
  1089. package/src/webrtc/stats/callStatsReportSummary.ts +30 -0
  1090. package/src/webrtc/stats/connectionStats.ts +47 -0
  1091. package/src/webrtc/stats/connectionStatsBuilder.ts +28 -0
  1092. package/src/webrtc/stats/connectionStatsReportBuilder.ts +140 -0
  1093. package/src/webrtc/stats/groupCallStats.ts +93 -0
  1094. package/src/webrtc/stats/media/mediaSsrcHandler.ts +57 -0
  1095. package/src/webrtc/stats/media/mediaTrackHandler.ts +70 -0
  1096. package/src/webrtc/stats/media/mediaTrackStats.ts +176 -0
  1097. package/src/webrtc/stats/media/mediaTrackStatsHandler.ts +90 -0
  1098. package/src/webrtc/stats/statsReport.ts +133 -0
  1099. package/src/webrtc/stats/statsReportEmitter.ts +49 -0
  1100. package/src/webrtc/stats/summaryStatsReportGatherer.ts +148 -0
  1101. package/src/webrtc/stats/trackStatsBuilder.ts +207 -0
  1102. package/src/webrtc/stats/transportStats.ts +26 -0
  1103. package/src/webrtc/stats/transportStatsBuilder.ts +48 -0
  1104. package/src/webrtc/stats/valueFormatter.ts +27 -0
@@ -0,0 +1,1729 @@
1
+ import { TypedEventEmitter } from "../models/typed-event-emitter.ts";
2
+ import { CallFeed, SPEAKING_THRESHOLD } from "./callFeed.ts";
3
+ import { type BriijClient, type IMyDevice } from "../client.ts";
4
+ import {
5
+ CallErrorCode,
6
+ CallEvent,
7
+ type CallEventHandlerMap,
8
+ CallState,
9
+ genCallID,
10
+ type BriijCall,
11
+ setTracksEnabled,
12
+ createNewBriijCall,
13
+ CallError,
14
+ } from "./call.ts";
15
+ import { type RoomMember } from "../models/room-member.ts";
16
+ import { type Room } from "../models/room.ts";
17
+ import { RoomStateEvent } from "../models/room-state.ts";
18
+ import { logger } from "../logger.ts";
19
+ import { ReEmitter } from "../ReEmitter.ts";
20
+ import { SDPStreamMetadataPurpose } from "./callEventTypes.ts";
21
+ import { type BriijEvent } from "../models/event.ts";
22
+ import { EventType } from "../@types/event.ts";
23
+ import { CallEventHandlerEvent } from "./callEventHandler.ts";
24
+ import { GroupCallEventHandlerEvent } from "./groupCallEventHandler.ts";
25
+ import { type IScreensharingOpts } from "./mediaHandler.ts";
26
+ import { mapsEqual } from "../utils.ts";
27
+ import { GroupCallStats } from "./stats/groupCallStats.ts";
28
+ import {
29
+ type ByteSentStatsReport,
30
+ type CallFeedReport,
31
+ type ConnectionStatsReport,
32
+ StatsReport,
33
+ type SummaryStatsReport,
34
+ } from "./stats/statsReport.ts";
35
+ import { SummaryStatsReportGatherer } from "./stats/summaryStatsReportGatherer.ts";
36
+ import { CallFeedStatsReporter } from "./stats/callFeedStatsReporter.ts";
37
+ import { KnownMembership } from "../@types/membership.ts";
38
+
39
+ export enum GroupCallIntent {
40
+ Ring = "m.ring",
41
+ Prompt = "m.prompt",
42
+ Room = "m.room",
43
+ }
44
+
45
+ export enum GroupCallType {
46
+ Video = "m.video",
47
+ Voice = "m.voice",
48
+ }
49
+
50
+ export enum GroupCallTerminationReason {
51
+ CallEnded = "call_ended",
52
+ }
53
+
54
+ export type CallsByUserAndDevice = Map<string, Map<string, BriijCall>>;
55
+
56
+ /**
57
+ * Because event names are just strings, they do need
58
+ * to be unique over all event types of event emitter.
59
+ * Some objects could emit more then one set of events.
60
+ */
61
+ export enum GroupCallEvent {
62
+ GroupCallStateChanged = "group_call_state_changed",
63
+ ActiveSpeakerChanged = "active_speaker_changed",
64
+ CallsChanged = "calls_changed",
65
+ UserMediaFeedsChanged = "user_media_feeds_changed",
66
+ ScreenshareFeedsChanged = "screenshare_feeds_changed",
67
+ LocalScreenshareStateChanged = "local_screenshare_state_changed",
68
+ LocalMuteStateChanged = "local_mute_state_changed",
69
+ ParticipantsChanged = "participants_changed",
70
+ Error = "group_call_error",
71
+ }
72
+
73
+ export type GroupCallEventHandlerMap = {
74
+ [GroupCallEvent.GroupCallStateChanged]: (newState: GroupCallState, oldState: GroupCallState) => void;
75
+ [GroupCallEvent.ActiveSpeakerChanged]: (activeSpeaker: CallFeed | undefined) => void;
76
+ [GroupCallEvent.CallsChanged]: (calls: CallsByUserAndDevice) => void;
77
+ [GroupCallEvent.UserMediaFeedsChanged]: (feeds: CallFeed[]) => void;
78
+ [GroupCallEvent.ScreenshareFeedsChanged]: (feeds: CallFeed[]) => void;
79
+ [GroupCallEvent.LocalScreenshareStateChanged]: (
80
+ isScreensharing: boolean,
81
+ feed?: CallFeed,
82
+ sourceId?: string,
83
+ ) => void;
84
+ [GroupCallEvent.LocalMuteStateChanged]: (audioMuted: boolean, videoMuted: boolean) => void;
85
+ [GroupCallEvent.ParticipantsChanged]: (participants: Map<RoomMember, Map<string, ParticipantState>>) => void;
86
+ /**
87
+ * Fires whenever an error occurs when call.js encounters an issue with setting up the call.
88
+ * <p>
89
+ * The error given will have a code equal to either `BriijCall.ERR_LOCAL_OFFER_FAILED` or
90
+ * `BriijCall.ERR_NO_USER_MEDIA`. `ERR_LOCAL_OFFER_FAILED` is emitted when the local client
91
+ * fails to create an offer. `ERR_NO_USER_MEDIA` is emitted when the user has denied access
92
+ * to their audio/video hardware.
93
+ * @param error - The error raised by BriijCall.
94
+ * @example
95
+ * ```
96
+ * matrixCall.on("error", function(err){
97
+ * console.error(err.code, err);
98
+ * });
99
+ * ```
100
+ */
101
+ [GroupCallEvent.Error]: (error: GroupCallError) => void;
102
+ };
103
+
104
+ export enum GroupCallStatsReportEvent {
105
+ ConnectionStats = "GroupCall.connection_stats",
106
+ ByteSentStats = "GroupCall.byte_sent_stats",
107
+ SummaryStats = "GroupCall.summary_stats",
108
+ CallFeedStats = "GroupCall.call_feed_stats",
109
+ }
110
+
111
+ /**
112
+ * The final report-events that get consumed by client.
113
+ */
114
+ export type GroupCallStatsReportEventHandlerMap = {
115
+ [GroupCallStatsReportEvent.ConnectionStats]: (report: GroupCallStatsReport<ConnectionStatsReport>) => void;
116
+ [GroupCallStatsReportEvent.ByteSentStats]: (report: GroupCallStatsReport<ByteSentStatsReport>) => void;
117
+ [GroupCallStatsReportEvent.SummaryStats]: (report: GroupCallStatsReport<SummaryStatsReport>) => void;
118
+ [GroupCallStatsReportEvent.CallFeedStats]: (report: GroupCallStatsReport<CallFeedReport>) => void;
119
+ };
120
+
121
+ export enum GroupCallErrorCode {
122
+ NoUserMedia = "no_user_media",
123
+ UnknownDevice = "unknown_device",
124
+ PlaceCallFailed = "place_call_failed",
125
+ }
126
+
127
+ export interface GroupCallStatsReport<
128
+ T extends ConnectionStatsReport | ByteSentStatsReport | SummaryStatsReport | CallFeedReport,
129
+ > {
130
+ report: T;
131
+ }
132
+
133
+ export class GroupCallError extends Error {
134
+ public code: string;
135
+
136
+ public constructor(code: GroupCallErrorCode, msg: string, err?: Error) {
137
+ // Still don't think there's any way to have proper nested errors
138
+ if (err) {
139
+ super(msg + ": " + err);
140
+ } else {
141
+ super(msg);
142
+ }
143
+
144
+ this.code = code;
145
+ }
146
+ }
147
+
148
+ export class GroupCallUnknownDeviceError extends GroupCallError {
149
+ public constructor(public userId: string) {
150
+ super(GroupCallErrorCode.UnknownDevice, "No device found for " + userId);
151
+ }
152
+ }
153
+
154
+ export class OtherUserSpeakingError extends Error {
155
+ public constructor() {
156
+ super("Cannot unmute: another user is speaking");
157
+ }
158
+ }
159
+
160
+ export interface IGroupCallDataChannelOptions {
161
+ ordered: boolean;
162
+ maxPacketLifeTime: number;
163
+ maxRetransmits: number;
164
+ protocol: string;
165
+ }
166
+
167
+ export interface IGroupCallRoomState {
168
+ "m.intent": GroupCallIntent;
169
+ "m.type": GroupCallType;
170
+ "m.terminated"?: GroupCallTerminationReason;
171
+ "io.element.ptt"?: boolean;
172
+ // TODO: Specify data-channels
173
+ "dataChannelsEnabled"?: boolean;
174
+ "dataChannelOptions"?: IGroupCallDataChannelOptions;
175
+
176
+ "io.element.livekit_service_url"?: string;
177
+ }
178
+
179
+ export interface IGroupCallRoomMemberFeed {
180
+ purpose: SDPStreamMetadataPurpose;
181
+ }
182
+
183
+ export interface IGroupCallRoomMemberDevice {
184
+ device_id: string;
185
+ session_id: string;
186
+ expires_ts: number;
187
+ feeds: IGroupCallRoomMemberFeed[];
188
+ }
189
+
190
+ export interface IGroupCallRoomMemberCallState {
191
+ "m.call_id": string;
192
+ "m.foci"?: string[];
193
+ "m.devices": IGroupCallRoomMemberDevice[];
194
+ }
195
+
196
+ export interface IGroupCallRoomMemberState {
197
+ "m.calls": IGroupCallRoomMemberCallState[];
198
+ }
199
+
200
+ export enum GroupCallState {
201
+ LocalCallFeedUninitialized = "local_call_feed_uninitialized",
202
+ InitializingLocalCallFeed = "initializing_local_call_feed",
203
+ LocalCallFeedInitialized = "local_call_feed_initialized",
204
+ Entered = "entered",
205
+ Ended = "ended",
206
+ }
207
+
208
+ export interface ParticipantState {
209
+ sessionId: string;
210
+ screensharing: boolean;
211
+ }
212
+
213
+ interface ICallHandlers {
214
+ onCallFeedsChanged: (feeds: CallFeed[]) => void;
215
+ onCallStateChanged: (state: CallState, oldState: CallState | undefined) => void;
216
+ onCallHangup: (call: BriijCall) => void;
217
+ onCallReplaced: (newCall: BriijCall) => void;
218
+ }
219
+
220
+ const DEVICE_TIMEOUT = 1000 * 60 * 60; // 1 hour
221
+
222
+ function getCallUserId(call: BriijCall): string | null {
223
+ return call.getOpponentMember()?.userId || call.invitee || null;
224
+ }
225
+
226
+ export class GroupCall extends TypedEventEmitter<
227
+ GroupCallEvent | CallEvent | GroupCallStatsReportEvent,
228
+ GroupCallEventHandlerMap & CallEventHandlerMap & GroupCallStatsReportEventHandlerMap
229
+ > {
230
+ // Config
231
+ public activeSpeakerInterval = 1000;
232
+ public retryCallInterval = 5000;
233
+ public participantTimeout = 1000 * 15;
234
+ public pttMaxTransmitTime = 1000 * 20;
235
+
236
+ public activeSpeaker?: CallFeed;
237
+ public localCallFeed?: CallFeed;
238
+ public localScreenshareFeed?: CallFeed;
239
+ public localDesktopCapturerSourceId?: string;
240
+ public readonly userMediaFeeds: CallFeed[] = [];
241
+ public readonly screenshareFeeds: CallFeed[] = [];
242
+ public groupCallId: string;
243
+ public readonly allowCallWithoutVideoAndAudio: boolean;
244
+
245
+ private readonly calls = new Map<string, Map<string, BriijCall>>(); // user_id -> device_id -> BriijCall
246
+ private callHandlers = new Map<string, Map<string, ICallHandlers>>(); // user_id -> device_id -> ICallHandlers
247
+ private activeSpeakerLoopInterval?: ReturnType<typeof setTimeout>;
248
+ private retryCallLoopInterval?: ReturnType<typeof setTimeout>;
249
+ private retryCallCounts: Map<string, Map<string, number>> = new Map(); // user_id -> device_id -> count
250
+ private reEmitter: ReEmitter;
251
+ private transmitTimer: ReturnType<typeof setTimeout> | null = null;
252
+ private participantsExpirationTimer: ReturnType<typeof setTimeout> | null = null;
253
+ private resendMemberStateTimer: ReturnType<typeof setInterval> | null = null;
254
+ private initWithAudioMuted = false;
255
+ private initWithVideoMuted = false;
256
+ private initCallFeedPromise?: Promise<void>;
257
+ private _livekitServiceURL?: string;
258
+
259
+ private stats: GroupCallStats | undefined;
260
+ /**
261
+ * Configure default webrtc stats collection interval in ms
262
+ * Disable collecting webrtc stats by setting interval to 0
263
+ */
264
+ private statsCollectIntervalTime = 0;
265
+
266
+ public constructor(
267
+ private client: BriijClient,
268
+ public room: Room,
269
+ public type: GroupCallType,
270
+ public isPtt: boolean,
271
+ public intent: GroupCallIntent,
272
+ groupCallId?: string,
273
+ private dataChannelsEnabled?: boolean,
274
+ private dataChannelOptions?: IGroupCallDataChannelOptions,
275
+ isCallWithoutVideoAndAudio?: boolean,
276
+ // this tells the js-sdk not to actually establish any calls to exchange media and just to
277
+ // create the group call signaling events, with the intention that the actual media will be
278
+ // handled using livekit. The js-sdk doesn't contain any code to do the actual livekit call though.
279
+ private useLivekit = false,
280
+ livekitServiceURL?: string,
281
+ ) {
282
+ super();
283
+ this.reEmitter = new ReEmitter(this);
284
+ this.groupCallId = groupCallId ?? genCallID();
285
+ this._livekitServiceURL = livekitServiceURL;
286
+ this.creationTs =
287
+ room.currentState.getStateEvents(EventType.GroupCallPrefix, this.groupCallId)?.getTs() ?? null;
288
+ this.updateParticipants();
289
+
290
+ room.on(RoomStateEvent.Update, this.onRoomState);
291
+ this.on(GroupCallEvent.ParticipantsChanged, this.onParticipantsChanged);
292
+ this.on(GroupCallEvent.GroupCallStateChanged, this.onStateChanged);
293
+ this.on(GroupCallEvent.LocalScreenshareStateChanged, this.onLocalFeedsChanged);
294
+ this.allowCallWithoutVideoAndAudio = !!isCallWithoutVideoAndAudio;
295
+ }
296
+
297
+ private onConnectionStats = (report: ConnectionStatsReport): void => {
298
+ // Final emit of the summary event, to be consumed by the client
299
+ this.emit(GroupCallStatsReportEvent.ConnectionStats, { report });
300
+ };
301
+
302
+ private onByteSentStats = (report: ByteSentStatsReport): void => {
303
+ // Final emit of the summary event, to be consumed by the client
304
+ this.emit(GroupCallStatsReportEvent.ByteSentStats, { report });
305
+ };
306
+
307
+ private onSummaryStats = (report: SummaryStatsReport): void => {
308
+ SummaryStatsReportGatherer.extendSummaryReport(report, this.participants);
309
+ // Final emit of the summary event, to be consumed by the client
310
+ this.emit(GroupCallStatsReportEvent.SummaryStats, { report });
311
+ };
312
+
313
+ private onCallFeedReport = (report: CallFeedReport): void => {
314
+ if (this.localCallFeed) {
315
+ report = CallFeedStatsReporter.expandCallFeedReport(report, [this.localCallFeed], "from-local-feed");
316
+ }
317
+
318
+ const callFeeds: CallFeed[] = [];
319
+ this.forEachCall((call) => {
320
+ if (call.callId === report.callId) {
321
+ call.getFeeds().forEach((f) => callFeeds.push(f));
322
+ }
323
+ });
324
+
325
+ report = CallFeedStatsReporter.expandCallFeedReport(report, callFeeds, "from-call-feed");
326
+ this.emit(GroupCallStatsReportEvent.CallFeedStats, { report });
327
+ };
328
+
329
+ public async create(): Promise<GroupCall> {
330
+ this.creationTs = Date.now();
331
+ this.client.groupCallEventHandler!.groupCalls.set(this.room.roomId, this);
332
+ this.client.emit(GroupCallEventHandlerEvent.Outgoing, this);
333
+
334
+ await this.sendCallStateEvent();
335
+
336
+ return this;
337
+ }
338
+
339
+ private async sendCallStateEvent(): Promise<void> {
340
+ const groupCallState: IGroupCallRoomState = {
341
+ "m.intent": this.intent,
342
+ "m.type": this.type,
343
+ "io.element.ptt": this.isPtt,
344
+ // TODO: Specify data-channels better
345
+ "dataChannelsEnabled": this.dataChannelsEnabled,
346
+ "dataChannelOptions": this.dataChannelsEnabled ? this.dataChannelOptions : undefined,
347
+ };
348
+ if (this.livekitServiceURL) {
349
+ groupCallState["io.element.livekit_service_url"] = this.livekitServiceURL;
350
+ }
351
+
352
+ await this.client.sendStateEvent(this.room.roomId, EventType.GroupCallPrefix, groupCallState, this.groupCallId);
353
+ }
354
+
355
+ public get livekitServiceURL(): string | undefined {
356
+ return this._livekitServiceURL;
357
+ }
358
+
359
+ public updateLivekitServiceURL(newURL: string): Promise<void> {
360
+ this._livekitServiceURL = newURL;
361
+ return this.sendCallStateEvent();
362
+ }
363
+
364
+ private _state = GroupCallState.LocalCallFeedUninitialized;
365
+
366
+ /**
367
+ * The group call's state.
368
+ */
369
+ public get state(): GroupCallState {
370
+ return this._state;
371
+ }
372
+
373
+ private set state(value: GroupCallState) {
374
+ const prevValue = this._state;
375
+ if (value !== prevValue) {
376
+ this._state = value;
377
+ this.emit(GroupCallEvent.GroupCallStateChanged, value, prevValue);
378
+ }
379
+ }
380
+
381
+ private _participants = new Map<RoomMember, Map<string, ParticipantState>>();
382
+
383
+ /**
384
+ * The current participants in the call, as a map from members to device IDs
385
+ * to participant info.
386
+ */
387
+ public get participants(): Map<RoomMember, Map<string, ParticipantState>> {
388
+ return this._participants;
389
+ }
390
+
391
+ private set participants(value: Map<RoomMember, Map<string, ParticipantState>>) {
392
+ const prevValue = this._participants;
393
+ const participantStateEqual = (x: ParticipantState, y: ParticipantState): boolean =>
394
+ x.sessionId === y.sessionId && x.screensharing === y.screensharing;
395
+ const deviceMapsEqual = (x: Map<string, ParticipantState>, y: Map<string, ParticipantState>): boolean =>
396
+ mapsEqual(x, y, participantStateEqual);
397
+
398
+ // Only update if the map actually changed
399
+ if (!mapsEqual(value, prevValue, deviceMapsEqual)) {
400
+ this._participants = value;
401
+ this.emit(GroupCallEvent.ParticipantsChanged, value);
402
+ }
403
+ }
404
+
405
+ private _creationTs: number | null = null;
406
+
407
+ /**
408
+ * The timestamp at which the call was created, or null if it has not yet
409
+ * been created.
410
+ */
411
+ public get creationTs(): number | null {
412
+ return this._creationTs;
413
+ }
414
+
415
+ private set creationTs(value: number | null) {
416
+ this._creationTs = value;
417
+ }
418
+
419
+ private _enteredViaAnotherSession = false;
420
+
421
+ /**
422
+ * Whether the local device has entered this call via another session, such
423
+ * as a widget.
424
+ */
425
+ public get enteredViaAnotherSession(): boolean {
426
+ return this._enteredViaAnotherSession;
427
+ }
428
+
429
+ public set enteredViaAnotherSession(value: boolean) {
430
+ this._enteredViaAnotherSession = value;
431
+ this.updateParticipants();
432
+ }
433
+
434
+ /**
435
+ * Executes the given callback on all calls in this group call.
436
+ * @param f - The callback.
437
+ */
438
+ public forEachCall(f: (call: BriijCall) => void): void {
439
+ for (const deviceMap of this.calls.values()) {
440
+ for (const call of deviceMap.values()) f(call);
441
+ }
442
+ }
443
+
444
+ public getLocalFeeds(): CallFeed[] {
445
+ const feeds: CallFeed[] = [];
446
+
447
+ if (this.localCallFeed) feeds.push(this.localCallFeed);
448
+ if (this.localScreenshareFeed) feeds.push(this.localScreenshareFeed);
449
+
450
+ return feeds;
451
+ }
452
+
453
+ public hasLocalParticipant(): boolean {
454
+ return (
455
+ this.participants.get(this.room.getMember(this.client.getUserId()!)!)?.has(this.client.getDeviceId()!) ??
456
+ false
457
+ );
458
+ }
459
+
460
+ /**
461
+ * Determines whether the given call is one that we were expecting to exist
462
+ * given our knowledge of who is participating in the group call.
463
+ */
464
+ private callExpected(call: BriijCall): boolean {
465
+ const userId = getCallUserId(call);
466
+ const member = userId === null ? null : this.room.getMember(userId);
467
+ const deviceId = call.getOpponentDeviceId();
468
+ return member !== null && deviceId !== undefined && this.participants.get(member)?.get(deviceId) !== undefined;
469
+ }
470
+
471
+ public async initLocalCallFeed(): Promise<void> {
472
+ if (this.useLivekit) {
473
+ logger.info("Livekit group call: not starting local call feed.");
474
+ return;
475
+ }
476
+
477
+ if (this.state !== GroupCallState.LocalCallFeedUninitialized) {
478
+ throw new Error(`Cannot initialize local call feed in the "${this.state}" state.`);
479
+ }
480
+ this.state = GroupCallState.InitializingLocalCallFeed;
481
+
482
+ // wraps the real method to serialise calls, because we don't want to try starting
483
+ // multiple call feeds at once
484
+ if (this.initCallFeedPromise) return this.initCallFeedPromise;
485
+
486
+ try {
487
+ this.initCallFeedPromise = this.initLocalCallFeedInternal();
488
+ await this.initCallFeedPromise;
489
+ } finally {
490
+ this.initCallFeedPromise = undefined;
491
+ }
492
+ }
493
+
494
+ private async initLocalCallFeedInternal(): Promise<void> {
495
+ logger.log(`GroupCall ${this.groupCallId} initLocalCallFeedInternal() running`);
496
+
497
+ let stream: MediaStream;
498
+
499
+ try {
500
+ stream = await this.client.getMediaHandler().getUserMediaStream(true, this.type === GroupCallType.Video);
501
+ } catch (error) {
502
+ // If is allowed to join a call without a media stream, then we
503
+ // don't throw an error here. But we need an empty Local Feed to establish
504
+ // a connection later.
505
+ if (this.allowCallWithoutVideoAndAudio) {
506
+ stream = new MediaStream();
507
+ } else {
508
+ this.state = GroupCallState.LocalCallFeedUninitialized;
509
+ throw error;
510
+ }
511
+ }
512
+
513
+ // The call could've been disposed while we were waiting, and could
514
+ // also have been started back up again (hello, React 18) so if we're
515
+ // still in this 'initializing' state, carry on, otherwise bail.
516
+ if (this._state !== GroupCallState.InitializingLocalCallFeed) {
517
+ this.client.getMediaHandler().stopUserMediaStream(stream);
518
+ throw new Error("Group call disposed while gathering media stream");
519
+ }
520
+
521
+ const callFeed = new CallFeed({
522
+ client: this.client,
523
+ roomId: this.room.roomId,
524
+ userId: this.client.getUserId()!,
525
+ deviceId: this.client.getDeviceId()!,
526
+ stream,
527
+ purpose: SDPStreamMetadataPurpose.Usermedia,
528
+ audioMuted: this.initWithAudioMuted || stream.getAudioTracks().length === 0 || this.isPtt,
529
+ videoMuted: this.initWithVideoMuted || stream.getVideoTracks().length === 0,
530
+ });
531
+
532
+ setTracksEnabled(stream.getAudioTracks(), !callFeed.isAudioMuted());
533
+ setTracksEnabled(stream.getVideoTracks(), !callFeed.isVideoMuted());
534
+
535
+ this.localCallFeed = callFeed;
536
+ this.addUserMediaFeed(callFeed);
537
+
538
+ this.state = GroupCallState.LocalCallFeedInitialized;
539
+ }
540
+
541
+ public async updateLocalUsermediaStream(stream: MediaStream): Promise<void> {
542
+ if (this.localCallFeed) {
543
+ const oldStream = this.localCallFeed.stream;
544
+ this.localCallFeed.setNewStream(stream);
545
+ const micShouldBeMuted = this.localCallFeed.isAudioMuted();
546
+ const vidShouldBeMuted = this.localCallFeed.isVideoMuted();
547
+ logger.log(
548
+ `GroupCall ${this.groupCallId} updateLocalUsermediaStream() (oldStreamId=${oldStream.id}, newStreamId=${stream.id}, micShouldBeMuted=${micShouldBeMuted}, vidShouldBeMuted=${vidShouldBeMuted})`,
549
+ );
550
+ setTracksEnabled(stream.getAudioTracks(), !micShouldBeMuted);
551
+ setTracksEnabled(stream.getVideoTracks(), !vidShouldBeMuted);
552
+ this.client.getMediaHandler().stopUserMediaStream(oldStream);
553
+ }
554
+ }
555
+
556
+ public async enter(): Promise<void> {
557
+ if (this.state === GroupCallState.LocalCallFeedUninitialized) {
558
+ await this.initLocalCallFeed();
559
+ } else if (this.state !== GroupCallState.LocalCallFeedInitialized) {
560
+ throw new Error(`Cannot enter call in the "${this.state}" state`);
561
+ }
562
+
563
+ logger.log(`GroupCall ${this.groupCallId} enter() running`);
564
+ this.state = GroupCallState.Entered;
565
+
566
+ this.client.on(CallEventHandlerEvent.Incoming, this.onIncomingCall);
567
+
568
+ for (const call of this.client.callEventHandler!.calls.values()) {
569
+ this.onIncomingCall(call);
570
+ }
571
+
572
+ if (!this.useLivekit) {
573
+ this.retryCallLoopInterval = setInterval(this.onRetryCallLoop, this.retryCallInterval);
574
+
575
+ this.activeSpeaker = undefined;
576
+ this.onActiveSpeakerLoop();
577
+ this.activeSpeakerLoopInterval = setInterval(this.onActiveSpeakerLoop, this.activeSpeakerInterval);
578
+ }
579
+ }
580
+
581
+ private dispose(): void {
582
+ if (this.localCallFeed) {
583
+ this.removeUserMediaFeed(this.localCallFeed);
584
+ this.localCallFeed = undefined;
585
+ }
586
+
587
+ if (this.localScreenshareFeed) {
588
+ this.client.getMediaHandler().stopScreensharingStream(this.localScreenshareFeed.stream);
589
+ this.removeScreenshareFeed(this.localScreenshareFeed);
590
+ this.localScreenshareFeed = undefined;
591
+ this.localDesktopCapturerSourceId = undefined;
592
+ }
593
+
594
+ this.client.getMediaHandler().stopAllStreams();
595
+
596
+ if (this.transmitTimer !== null) {
597
+ clearTimeout(this.transmitTimer);
598
+ this.transmitTimer = null;
599
+ }
600
+
601
+ if (this.retryCallLoopInterval !== undefined) {
602
+ clearInterval(this.retryCallLoopInterval);
603
+ this.retryCallLoopInterval = undefined;
604
+ }
605
+
606
+ if (this.participantsExpirationTimer !== null) {
607
+ clearTimeout(this.participantsExpirationTimer);
608
+ this.participantsExpirationTimer = null;
609
+ }
610
+
611
+ if (this.state !== GroupCallState.Entered) {
612
+ return;
613
+ }
614
+
615
+ this.forEachCall((call) => call.hangup(CallErrorCode.UserHangup, false));
616
+
617
+ this.activeSpeaker = undefined;
618
+ clearInterval(this.activeSpeakerLoopInterval);
619
+
620
+ this.retryCallCounts.clear();
621
+ clearInterval(this.retryCallLoopInterval);
622
+
623
+ this.client.removeListener(CallEventHandlerEvent.Incoming, this.onIncomingCall);
624
+ this.stats?.stop();
625
+ }
626
+
627
+ public leave(): void {
628
+ this.dispose();
629
+ this.state = GroupCallState.LocalCallFeedUninitialized;
630
+ }
631
+
632
+ public async terminate(emitStateEvent = true): Promise<void> {
633
+ this.dispose();
634
+
635
+ this.room.off(RoomStateEvent.Update, this.onRoomState);
636
+ this.client.groupCallEventHandler!.groupCalls.delete(this.room.roomId);
637
+ this.client.emit(GroupCallEventHandlerEvent.Ended, this);
638
+ this.state = GroupCallState.Ended;
639
+
640
+ if (emitStateEvent) {
641
+ const existingStateEvent = this.room.currentState.getStateEvents(
642
+ EventType.GroupCallPrefix,
643
+ this.groupCallId,
644
+ )!;
645
+
646
+ await this.client.sendStateEvent(
647
+ this.room.roomId,
648
+ EventType.GroupCallPrefix,
649
+ {
650
+ ...existingStateEvent.getContent(),
651
+ "m.terminated": GroupCallTerminationReason.CallEnded,
652
+ },
653
+ this.groupCallId,
654
+ );
655
+ }
656
+ }
657
+
658
+ /*
659
+ * Local Usermedia
660
+ */
661
+
662
+ public isLocalVideoMuted(): boolean {
663
+ if (this.localCallFeed) {
664
+ return this.localCallFeed.isVideoMuted();
665
+ }
666
+
667
+ return true;
668
+ }
669
+
670
+ public isMicrophoneMuted(): boolean {
671
+ if (this.localCallFeed) {
672
+ return this.localCallFeed.isAudioMuted();
673
+ }
674
+
675
+ return true;
676
+ }
677
+
678
+ /**
679
+ * Sets the mute state of the local participants's microphone.
680
+ * @param muted - Whether to mute the microphone
681
+ * @returns Whether muting/unmuting was successful
682
+ */
683
+ public async setMicrophoneMuted(muted: boolean): Promise<boolean> {
684
+ // hasAudioDevice can block indefinitely if the window has lost focus,
685
+ // and it doesn't make much sense to keep a device from being muted, so
686
+ // we always allow muted = true changes to go through
687
+ if (!muted && !(await this.client.getMediaHandler().hasAudioDevice())) {
688
+ return false;
689
+ }
690
+
691
+ const sendUpdatesBefore = !muted && this.isPtt;
692
+
693
+ // set a timer for the maximum transmit time on PTT calls
694
+ if (this.isPtt) {
695
+ // Set or clear the max transmit timer
696
+ if (!muted && this.isMicrophoneMuted()) {
697
+ this.transmitTimer = setTimeout(() => {
698
+ this.setMicrophoneMuted(true);
699
+ }, this.pttMaxTransmitTime);
700
+ } else if (muted && !this.isMicrophoneMuted()) {
701
+ if (this.transmitTimer !== null) clearTimeout(this.transmitTimer);
702
+ this.transmitTimer = null;
703
+ }
704
+ }
705
+
706
+ this.forEachCall((call) => call.localUsermediaFeed?.setAudioVideoMuted(muted, null));
707
+
708
+ const sendUpdates = async (): Promise<void> => {
709
+ const updates: Promise<void>[] = [];
710
+ this.forEachCall((call) => updates.push(call.sendMetadataUpdate()));
711
+
712
+ await Promise.all(updates).catch((e) =>
713
+ logger.info(
714
+ `GroupCall ${this.groupCallId} setMicrophoneMuted() failed to send some metadata updates`,
715
+ e,
716
+ ),
717
+ );
718
+ };
719
+
720
+ if (sendUpdatesBefore) await sendUpdates();
721
+
722
+ if (this.localCallFeed) {
723
+ logger.log(
724
+ `GroupCall ${this.groupCallId} setMicrophoneMuted() (streamId=${this.localCallFeed.stream.id}, muted=${muted})`,
725
+ );
726
+
727
+ const hasPermission = await this.checkAudioPermissionIfNecessary(muted);
728
+
729
+ if (!hasPermission) {
730
+ return false;
731
+ }
732
+
733
+ this.localCallFeed.setAudioVideoMuted(muted, null);
734
+ // I don't believe its actually necessary to enable these tracks: they
735
+ // are the one on the GroupCall's own CallFeed and are cloned before being
736
+ // given to any of the actual calls, so these tracks don't actually go
737
+ // anywhere. Let's do it anyway to avoid confusion.
738
+ setTracksEnabled(this.localCallFeed.stream.getAudioTracks(), !muted);
739
+ } else {
740
+ logger.log(`GroupCall ${this.groupCallId} setMicrophoneMuted() no stream muted (muted=${muted})`);
741
+ this.initWithAudioMuted = muted;
742
+ }
743
+
744
+ this.forEachCall((call) =>
745
+ setTracksEnabled(call.localUsermediaFeed!.stream.getAudioTracks(), !muted && this.callExpected(call)),
746
+ );
747
+ this.emit(GroupCallEvent.LocalMuteStateChanged, muted, this.isLocalVideoMuted());
748
+
749
+ if (!sendUpdatesBefore) await sendUpdates();
750
+
751
+ return true;
752
+ }
753
+
754
+ /**
755
+ * If we allow entering a call without a camera and without video, it can happen that the access rights to the
756
+ * devices have not yet been queried. If a stream does not yet have an audio track, we assume that the rights have
757
+ * not yet been checked.
758
+ *
759
+ * `this.client.getMediaHandler().getUserMediaStream` clones the current stream, so it only wanted to be called when
760
+ * not Audio Track exists.
761
+ * As such, this is a compromise, because, the access rights should always be queried before the call.
762
+ */
763
+ private async checkAudioPermissionIfNecessary(muted: boolean): Promise<boolean> {
764
+ // We needed this here to avoid an error in case user join a call without a device.
765
+ try {
766
+ if (!muted && this.localCallFeed && !this.localCallFeed.hasAudioTrack) {
767
+ const stream = await this.client
768
+ .getMediaHandler()
769
+ .getUserMediaStream(true, !this.localCallFeed.isVideoMuted());
770
+ if (stream?.getTracks().length === 0) {
771
+ // if case permission denied to get a stream stop this here
772
+ /* istanbul ignore next */
773
+ logger.log(
774
+ `GroupCall ${this.groupCallId} setMicrophoneMuted() no device to receive local stream, muted=${muted}`,
775
+ );
776
+ return false;
777
+ }
778
+ }
779
+ } catch {
780
+ /* istanbul ignore next */
781
+ logger.log(
782
+ `GroupCall ${this.groupCallId} setMicrophoneMuted() no device or permission to receive local stream, muted=${muted}`,
783
+ );
784
+ return false;
785
+ }
786
+
787
+ return true;
788
+ }
789
+
790
+ /**
791
+ * Sets the mute state of the local participants's video.
792
+ * @param muted - Whether to mute the video
793
+ * @returns Whether muting/unmuting was successful
794
+ */
795
+ public async setLocalVideoMuted(muted: boolean): Promise<boolean> {
796
+ // hasAudioDevice can block indefinitely if the window has lost focus,
797
+ // and it doesn't make much sense to keep a device from being muted, so
798
+ // we always allow muted = true changes to go through
799
+ if (!muted && !(await this.client.getMediaHandler().hasVideoDevice())) {
800
+ return false;
801
+ }
802
+
803
+ if (this.localCallFeed) {
804
+ /* istanbul ignore next */
805
+ logger.log(
806
+ `GroupCall ${this.groupCallId} setLocalVideoMuted() (stream=${this.localCallFeed.stream.id}, muted=${muted})`,
807
+ );
808
+
809
+ try {
810
+ const stream = await this.client.getMediaHandler().getUserMediaStream(true, !muted);
811
+ await this.updateLocalUsermediaStream(stream);
812
+ this.localCallFeed.setAudioVideoMuted(null, muted);
813
+ setTracksEnabled(this.localCallFeed.stream.getVideoTracks(), !muted);
814
+ } catch {
815
+ // No permission to video device
816
+ /* istanbul ignore next */
817
+ logger.log(
818
+ `GroupCall ${this.groupCallId} setLocalVideoMuted() no device or permission to receive local stream, muted=${muted}`,
819
+ );
820
+ return false;
821
+ }
822
+ } else {
823
+ logger.log(`GroupCall ${this.groupCallId} setLocalVideoMuted() no stream muted (muted=${muted})`);
824
+ this.initWithVideoMuted = muted;
825
+ }
826
+
827
+ const updates: Promise<unknown>[] = [];
828
+ this.forEachCall((call) => updates.push(call.setLocalVideoMuted(muted)));
829
+ await Promise.all(updates);
830
+
831
+ // We setTracksEnabled again, independently from the call doing it
832
+ // internally, since we might not be expecting the call
833
+ this.forEachCall((call) =>
834
+ setTracksEnabled(call.localUsermediaFeed!.stream.getVideoTracks(), !muted && this.callExpected(call)),
835
+ );
836
+
837
+ this.emit(GroupCallEvent.LocalMuteStateChanged, this.isMicrophoneMuted(), muted);
838
+
839
+ return true;
840
+ }
841
+
842
+ public async setScreensharingEnabled(enabled: boolean, opts: IScreensharingOpts = {}): Promise<boolean> {
843
+ if (enabled === this.isScreensharing()) {
844
+ return enabled;
845
+ }
846
+
847
+ if (enabled) {
848
+ try {
849
+ logger.log(
850
+ `GroupCall ${this.groupCallId} setScreensharingEnabled() is asking for screensharing permissions`,
851
+ );
852
+ const stream = await this.client.getMediaHandler().getScreensharingStream(opts);
853
+
854
+ for (const track of stream.getTracks()) {
855
+ const onTrackEnded = (): void => {
856
+ this.setScreensharingEnabled(false);
857
+ track.removeEventListener("ended", onTrackEnded);
858
+ };
859
+
860
+ track.addEventListener("ended", onTrackEnded);
861
+ }
862
+
863
+ logger.log(
864
+ `GroupCall ${this.groupCallId} setScreensharingEnabled() granted screensharing permissions. Setting screensharing enabled on all calls`,
865
+ );
866
+
867
+ this.localDesktopCapturerSourceId = opts.desktopCapturerSourceId;
868
+ this.localScreenshareFeed = new CallFeed({
869
+ client: this.client,
870
+ roomId: this.room.roomId,
871
+ userId: this.client.getUserId()!,
872
+ deviceId: this.client.getDeviceId()!,
873
+ stream,
874
+ purpose: SDPStreamMetadataPurpose.Screenshare,
875
+ audioMuted: false,
876
+ videoMuted: false,
877
+ });
878
+ this.addScreenshareFeed(this.localScreenshareFeed);
879
+
880
+ this.emit(
881
+ GroupCallEvent.LocalScreenshareStateChanged,
882
+ true,
883
+ this.localScreenshareFeed,
884
+ this.localDesktopCapturerSourceId,
885
+ );
886
+
887
+ // TODO: handle errors
888
+ this.forEachCall((call) => call.pushLocalFeed(this.localScreenshareFeed!.clone()));
889
+
890
+ return true;
891
+ } catch (error) {
892
+ if (opts.throwOnFail) throw error;
893
+ logger.error(
894
+ `GroupCall ${this.groupCallId} setScreensharingEnabled() enabling screensharing error`,
895
+ error,
896
+ );
897
+ this.emit(
898
+ GroupCallEvent.Error,
899
+ new GroupCallError(
900
+ GroupCallErrorCode.NoUserMedia,
901
+ "Failed to get screen-sharing stream: ",
902
+ error as Error,
903
+ ),
904
+ );
905
+ return false;
906
+ }
907
+ } else {
908
+ this.forEachCall((call) => {
909
+ if (call.localScreensharingFeed) call.removeLocalFeed(call.localScreensharingFeed);
910
+ });
911
+ this.client.getMediaHandler().stopScreensharingStream(this.localScreenshareFeed!.stream);
912
+ this.removeScreenshareFeed(this.localScreenshareFeed!);
913
+ this.localScreenshareFeed = undefined;
914
+ this.localDesktopCapturerSourceId = undefined;
915
+ this.emit(GroupCallEvent.LocalScreenshareStateChanged, false, undefined, undefined);
916
+ return false;
917
+ }
918
+ }
919
+
920
+ public isScreensharing(): boolean {
921
+ return !!this.localScreenshareFeed;
922
+ }
923
+
924
+ /*
925
+ * Call Setup
926
+ *
927
+ * There are two different paths for calls to be created:
928
+ * 1. Incoming calls triggered by the Call.incoming event.
929
+ * 2. Outgoing calls to the initial members of a room or new members
930
+ * as they are observed by the RoomState.members event.
931
+ */
932
+
933
+ private onIncomingCall = (newCall: BriijCall): void => {
934
+ // The incoming calls may be for another room, which we will ignore.
935
+ if (newCall.roomId !== this.room.roomId) {
936
+ return;
937
+ }
938
+
939
+ if (newCall.state !== CallState.Ringing) {
940
+ logger.warn(
941
+ `GroupCall ${this.groupCallId} onIncomingCall() incoming call no longer in ringing state - ignoring`,
942
+ );
943
+ return;
944
+ }
945
+
946
+ if (!newCall.groupCallId || newCall.groupCallId !== this.groupCallId) {
947
+ logger.log(
948
+ `GroupCall ${this.groupCallId} onIncomingCall() ignored because it doesn't match the current group call`,
949
+ );
950
+ newCall.reject();
951
+ return;
952
+ }
953
+
954
+ const opponentUserId = newCall.getOpponentMember()?.userId;
955
+ if (opponentUserId === undefined) {
956
+ logger.warn(`GroupCall ${this.groupCallId} onIncomingCall() incoming call with no member - ignoring`);
957
+ return;
958
+ }
959
+
960
+ if (this.useLivekit) {
961
+ logger.info("Received incoming call whilst in signaling-only mode! Ignoring.");
962
+ return;
963
+ }
964
+
965
+ const deviceMap = this.calls.get(opponentUserId) ?? new Map<string, BriijCall>();
966
+ const prevCall = deviceMap.get(newCall.getOpponentDeviceId()!);
967
+
968
+ if (prevCall?.callId === newCall.callId) return;
969
+
970
+ logger.log(
971
+ `GroupCall ${this.groupCallId} onIncomingCall() incoming call (userId=${opponentUserId}, callId=${newCall.callId})`,
972
+ );
973
+
974
+ if (prevCall) prevCall.hangup(CallErrorCode.Replaced, false);
975
+ // We must do this before we start initialising / answering the call as we
976
+ // need to know it is the active call for this user+deviceId and to not ignore
977
+ // events from it.
978
+ deviceMap.set(newCall.getOpponentDeviceId()!, newCall);
979
+ this.calls.set(opponentUserId, deviceMap);
980
+
981
+ this.initCall(newCall);
982
+
983
+ const feeds = this.getLocalFeeds().map((feed) => feed.clone());
984
+ if (!this.callExpected(newCall)) {
985
+ // Disable our tracks for users not explicitly participating in the
986
+ // call but trying to receive the feeds
987
+ for (const feed of feeds) {
988
+ setTracksEnabled(feed.stream.getAudioTracks(), false);
989
+ setTracksEnabled(feed.stream.getVideoTracks(), false);
990
+ }
991
+ }
992
+ newCall.answerWithCallFeeds(feeds);
993
+
994
+ this.emit(GroupCallEvent.CallsChanged, this.calls);
995
+ };
996
+
997
+ /**
998
+ * Determines whether a given participant expects us to call them (versus
999
+ * them calling us).
1000
+ * @param userId - The participant's user ID.
1001
+ * @param deviceId - The participant's device ID.
1002
+ * @returns Whether we need to place an outgoing call to the participant.
1003
+ */
1004
+ private wantsOutgoingCall(userId: string, deviceId: string): boolean {
1005
+ const localUserId = this.client.getUserId()!;
1006
+ const localDeviceId = this.client.getDeviceId()!;
1007
+ return (
1008
+ // If a user's ID is less than our own, they'll call us
1009
+ userId >= localUserId &&
1010
+ // If this is another one of our devices, compare device IDs to tell whether it'll call us
1011
+ (userId !== localUserId || deviceId > localDeviceId)
1012
+ );
1013
+ }
1014
+
1015
+ /**
1016
+ * Places calls to all participants that we're responsible for calling.
1017
+ */
1018
+ private placeOutgoingCalls(): void {
1019
+ let callsChanged = false;
1020
+
1021
+ for (const [{ userId }, participantMap] of this.participants) {
1022
+ const callMap = this.calls.get(userId) ?? new Map<string, BriijCall>();
1023
+
1024
+ for (const [deviceId, participant] of participantMap) {
1025
+ const prevCall = callMap.get(deviceId);
1026
+
1027
+ if (
1028
+ prevCall?.getOpponentSessionId() !== participant.sessionId &&
1029
+ this.wantsOutgoingCall(userId, deviceId)
1030
+ ) {
1031
+ callsChanged = true;
1032
+
1033
+ if (prevCall !== undefined) {
1034
+ logger.debug(
1035
+ `GroupCall ${this.groupCallId} placeOutgoingCalls() replacing call (userId=${userId}, deviceId=${deviceId}, callId=${prevCall.callId})`,
1036
+ );
1037
+ prevCall.hangup(CallErrorCode.NewSession, false);
1038
+ }
1039
+
1040
+ const newCall = createNewBriijCall(this.client, this.room.roomId, {
1041
+ invitee: userId,
1042
+ opponentDeviceId: deviceId,
1043
+ opponentSessionId: participant.sessionId,
1044
+ groupCallId: this.groupCallId,
1045
+ });
1046
+
1047
+ if (newCall === null) {
1048
+ logger.error(
1049
+ `GroupCall ${this.groupCallId} placeOutgoingCalls() failed to create call (userId=${userId}, device=${deviceId})`,
1050
+ );
1051
+ callMap.delete(deviceId);
1052
+ } else {
1053
+ this.initCall(newCall);
1054
+ callMap.set(deviceId, newCall);
1055
+
1056
+ logger.debug(
1057
+ `GroupCall ${this.groupCallId} placeOutgoingCalls() placing call (userId=${userId}, deviceId=${deviceId}, sessionId=${participant.sessionId})`,
1058
+ );
1059
+
1060
+ newCall
1061
+ .placeCallWithCallFeeds(
1062
+ this.getLocalFeeds().map((feed) => feed.clone()),
1063
+ participant.screensharing,
1064
+ )
1065
+ .then(() => {
1066
+ if (this.dataChannelsEnabled) {
1067
+ newCall.createDataChannel("datachannel", this.dataChannelOptions);
1068
+ }
1069
+ })
1070
+ .catch((e) => {
1071
+ logger.warn(
1072
+ `GroupCall ${this.groupCallId} placeOutgoingCalls() failed to place call (userId=${userId})`,
1073
+ e,
1074
+ );
1075
+
1076
+ if (e instanceof CallError && e.code === GroupCallErrorCode.UnknownDevice) {
1077
+ this.emit(GroupCallEvent.Error, e);
1078
+ } else {
1079
+ this.emit(
1080
+ GroupCallEvent.Error,
1081
+ new GroupCallError(
1082
+ GroupCallErrorCode.PlaceCallFailed,
1083
+ `Failed to place call to ${userId}`,
1084
+ ),
1085
+ );
1086
+ }
1087
+
1088
+ newCall.hangup(CallErrorCode.SignallingFailed, false);
1089
+ if (callMap.get(deviceId) === newCall) callMap.delete(deviceId);
1090
+ });
1091
+ }
1092
+ }
1093
+ }
1094
+
1095
+ if (callMap.size > 0) {
1096
+ this.calls.set(userId, callMap);
1097
+ } else {
1098
+ this.calls.delete(userId);
1099
+ }
1100
+ }
1101
+
1102
+ if (callsChanged) this.emit(GroupCallEvent.CallsChanged, this.calls);
1103
+ }
1104
+
1105
+ /*
1106
+ * Room Member State
1107
+ */
1108
+
1109
+ private getMemberStateEvents(): BriijEvent[];
1110
+ private getMemberStateEvents(userId: string): BriijEvent | null;
1111
+ private getMemberStateEvents(userId?: string): BriijEvent[] | BriijEvent | null {
1112
+ return userId === undefined
1113
+ ? this.room.currentState.getStateEvents(EventType.GroupCallMemberPrefix)
1114
+ : this.room.currentState.getStateEvents(EventType.GroupCallMemberPrefix, userId);
1115
+ }
1116
+
1117
+ private onRetryCallLoop = (): void => {
1118
+ let needsRetry = false;
1119
+
1120
+ for (const [{ userId }, participantMap] of this.participants) {
1121
+ const callMap = this.calls.get(userId);
1122
+ let retriesMap = this.retryCallCounts.get(userId);
1123
+
1124
+ for (const [deviceId, participant] of participantMap) {
1125
+ const call = callMap?.get(deviceId);
1126
+ const retries = retriesMap?.get(deviceId) ?? 0;
1127
+
1128
+ if (
1129
+ call?.getOpponentSessionId() !== participant.sessionId &&
1130
+ this.wantsOutgoingCall(userId, deviceId) &&
1131
+ retries < 3
1132
+ ) {
1133
+ if (retriesMap === undefined) {
1134
+ retriesMap = new Map();
1135
+ this.retryCallCounts.set(userId, retriesMap);
1136
+ }
1137
+ retriesMap.set(deviceId, retries + 1);
1138
+ needsRetry = true;
1139
+ }
1140
+ }
1141
+ }
1142
+
1143
+ if (needsRetry) this.placeOutgoingCalls();
1144
+ };
1145
+
1146
+ private initCall(call: BriijCall): void {
1147
+ const opponentMemberId = getCallUserId(call);
1148
+
1149
+ if (!opponentMemberId) {
1150
+ throw new Error("Cannot init call without user id");
1151
+ }
1152
+
1153
+ const onCallFeedsChanged = (): void => this.onCallFeedsChanged(call);
1154
+ const onCallStateChanged = (state: CallState, oldState?: CallState): void =>
1155
+ this.onCallStateChanged(call, state, oldState);
1156
+ const onCallHangup = this.onCallHangup;
1157
+ const onCallReplaced = (newCall: BriijCall): void => this.onCallReplaced(call, newCall);
1158
+
1159
+ let deviceMap = this.callHandlers.get(opponentMemberId);
1160
+ if (deviceMap === undefined) {
1161
+ deviceMap = new Map();
1162
+ this.callHandlers.set(opponentMemberId, deviceMap);
1163
+ }
1164
+
1165
+ deviceMap.set(call.getOpponentDeviceId()!, {
1166
+ onCallFeedsChanged,
1167
+ onCallStateChanged,
1168
+ onCallHangup,
1169
+ onCallReplaced,
1170
+ });
1171
+
1172
+ call.on(CallEvent.FeedsChanged, onCallFeedsChanged);
1173
+ call.on(CallEvent.State, onCallStateChanged);
1174
+ call.on(CallEvent.Hangup, onCallHangup);
1175
+ call.on(CallEvent.Replaced, onCallReplaced);
1176
+
1177
+ call.isPtt = this.isPtt;
1178
+
1179
+ this.reEmitter.reEmit(call, Object.values(CallEvent));
1180
+
1181
+ call.initStats(this.getGroupCallStats());
1182
+
1183
+ onCallFeedsChanged();
1184
+ }
1185
+
1186
+ private disposeCall(call: BriijCall, hangupReason: CallErrorCode): void {
1187
+ const opponentMemberId = getCallUserId(call);
1188
+ const opponentDeviceId = call.getOpponentDeviceId()!;
1189
+
1190
+ if (!opponentMemberId) {
1191
+ throw new Error("Cannot dispose call without user id");
1192
+ }
1193
+
1194
+ const deviceMap = this.callHandlers.get(opponentMemberId)!;
1195
+ const { onCallFeedsChanged, onCallStateChanged, onCallHangup, onCallReplaced } =
1196
+ deviceMap.get(opponentDeviceId)!;
1197
+
1198
+ call.removeListener(CallEvent.FeedsChanged, onCallFeedsChanged);
1199
+ call.removeListener(CallEvent.State, onCallStateChanged);
1200
+ call.removeListener(CallEvent.Hangup, onCallHangup);
1201
+ call.removeListener(CallEvent.Replaced, onCallReplaced);
1202
+
1203
+ deviceMap.delete(opponentMemberId);
1204
+ if (deviceMap.size === 0) this.callHandlers.delete(opponentMemberId);
1205
+
1206
+ if (call.hangupReason === CallErrorCode.Replaced) {
1207
+ return;
1208
+ }
1209
+
1210
+ const usermediaFeed = this.getUserMediaFeed(opponentMemberId, opponentDeviceId);
1211
+
1212
+ if (usermediaFeed) {
1213
+ this.removeUserMediaFeed(usermediaFeed);
1214
+ }
1215
+
1216
+ const screenshareFeed = this.getScreenshareFeed(opponentMemberId, opponentDeviceId);
1217
+
1218
+ if (screenshareFeed) {
1219
+ this.removeScreenshareFeed(screenshareFeed);
1220
+ }
1221
+ }
1222
+
1223
+ private onCallFeedsChanged = (call: BriijCall): void => {
1224
+ const opponentMemberId = getCallUserId(call);
1225
+ const opponentDeviceId = call.getOpponentDeviceId()!;
1226
+
1227
+ if (!opponentMemberId) {
1228
+ throw new Error("Cannot change call feeds without user id");
1229
+ }
1230
+
1231
+ const currentUserMediaFeed = this.getUserMediaFeed(opponentMemberId, opponentDeviceId);
1232
+ const remoteUsermediaFeed = call.remoteUsermediaFeed;
1233
+ const remoteFeedChanged = remoteUsermediaFeed !== currentUserMediaFeed;
1234
+
1235
+ const deviceMap = this.calls.get(opponentMemberId);
1236
+ const currentCallForUserDevice = deviceMap?.get(opponentDeviceId);
1237
+ if (currentCallForUserDevice?.callId !== call.callId) {
1238
+ // the call in question is not the current call for this user/deviceId
1239
+ // so ignore feed events from it otherwise we'll remove our real feeds
1240
+ return;
1241
+ }
1242
+
1243
+ if (remoteFeedChanged) {
1244
+ if (!currentUserMediaFeed && remoteUsermediaFeed) {
1245
+ this.addUserMediaFeed(remoteUsermediaFeed);
1246
+ } else if (currentUserMediaFeed && remoteUsermediaFeed) {
1247
+ this.replaceUserMediaFeed(currentUserMediaFeed, remoteUsermediaFeed);
1248
+ } else if (currentUserMediaFeed && !remoteUsermediaFeed) {
1249
+ this.removeUserMediaFeed(currentUserMediaFeed);
1250
+ }
1251
+ }
1252
+
1253
+ const currentScreenshareFeed = this.getScreenshareFeed(opponentMemberId, opponentDeviceId);
1254
+ const remoteScreensharingFeed = call.remoteScreensharingFeed;
1255
+ const remoteScreenshareFeedChanged = remoteScreensharingFeed !== currentScreenshareFeed;
1256
+
1257
+ if (remoteScreenshareFeedChanged) {
1258
+ if (!currentScreenshareFeed && remoteScreensharingFeed) {
1259
+ this.addScreenshareFeed(remoteScreensharingFeed);
1260
+ } else if (currentScreenshareFeed && remoteScreensharingFeed) {
1261
+ this.replaceScreenshareFeed(currentScreenshareFeed, remoteScreensharingFeed);
1262
+ } else if (currentScreenshareFeed && !remoteScreensharingFeed) {
1263
+ this.removeScreenshareFeed(currentScreenshareFeed);
1264
+ }
1265
+ }
1266
+ };
1267
+
1268
+ private onCallStateChanged = (call: BriijCall, state: CallState, _oldState: CallState | undefined): void => {
1269
+ if (state === CallState.Ended) return;
1270
+
1271
+ const audioMuted = this.localCallFeed!.isAudioMuted();
1272
+
1273
+ if (call.localUsermediaStream && call.isMicrophoneMuted() !== audioMuted) {
1274
+ call.setMicrophoneMuted(audioMuted);
1275
+ }
1276
+
1277
+ const videoMuted = this.localCallFeed!.isVideoMuted();
1278
+
1279
+ if (call.localUsermediaStream && call.isLocalVideoMuted() !== videoMuted) {
1280
+ call.setLocalVideoMuted(videoMuted);
1281
+ }
1282
+
1283
+ const opponentUserId = call.getOpponentMember()?.userId;
1284
+ if (state === CallState.Connected && opponentUserId) {
1285
+ const retriesMap = this.retryCallCounts.get(opponentUserId);
1286
+ retriesMap?.delete(call.getOpponentDeviceId()!);
1287
+ if (retriesMap?.size === 0) this.retryCallCounts.delete(opponentUserId);
1288
+ }
1289
+ };
1290
+
1291
+ private onCallHangup = (call: BriijCall): void => {
1292
+ if (call.hangupReason === CallErrorCode.Replaced) return;
1293
+
1294
+ const opponentUserId = call.getOpponentMember()?.userId ?? this.room.getMember(call.invitee!)!.userId;
1295
+ const deviceMap = this.calls.get(opponentUserId);
1296
+
1297
+ // Sanity check that this call is in fact in the map
1298
+ if (deviceMap?.get(call.getOpponentDeviceId()!) === call) {
1299
+ this.disposeCall(call, call.hangupReason as CallErrorCode);
1300
+ deviceMap.delete(call.getOpponentDeviceId()!);
1301
+ if (deviceMap.size === 0) this.calls.delete(opponentUserId);
1302
+ this.emit(GroupCallEvent.CallsChanged, this.calls);
1303
+ }
1304
+ };
1305
+
1306
+ private onCallReplaced = (prevCall: BriijCall, newCall: BriijCall): void => {
1307
+ const opponentUserId = prevCall.getOpponentMember()!.userId;
1308
+
1309
+ let deviceMap = this.calls.get(opponentUserId);
1310
+ if (deviceMap === undefined) {
1311
+ deviceMap = new Map();
1312
+ this.calls.set(opponentUserId, deviceMap);
1313
+ }
1314
+
1315
+ prevCall.hangup(CallErrorCode.Replaced, false);
1316
+ this.initCall(newCall);
1317
+ deviceMap.set(prevCall.getOpponentDeviceId()!, newCall);
1318
+ this.emit(GroupCallEvent.CallsChanged, this.calls);
1319
+ };
1320
+
1321
+ /*
1322
+ * UserMedia CallFeed Event Handlers
1323
+ */
1324
+
1325
+ public getUserMediaFeed(userId: string, deviceId: string): CallFeed | undefined {
1326
+ return this.userMediaFeeds.find((f) => f.userId === userId && f.deviceId! === deviceId);
1327
+ }
1328
+
1329
+ private addUserMediaFeed(callFeed: CallFeed): void {
1330
+ this.userMediaFeeds.push(callFeed);
1331
+ callFeed.measureVolumeActivity(true);
1332
+ this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds);
1333
+ }
1334
+
1335
+ private replaceUserMediaFeed(existingFeed: CallFeed, replacementFeed: CallFeed): void {
1336
+ const feedIndex = this.userMediaFeeds.findIndex(
1337
+ (f) => f.userId === existingFeed.userId && f.deviceId! === existingFeed.deviceId,
1338
+ );
1339
+
1340
+ if (feedIndex === -1) {
1341
+ throw new Error("Couldn't find user media feed to replace");
1342
+ }
1343
+
1344
+ this.userMediaFeeds.splice(feedIndex, 1, replacementFeed);
1345
+
1346
+ existingFeed.dispose();
1347
+ replacementFeed.measureVolumeActivity(true);
1348
+ this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds);
1349
+ }
1350
+
1351
+ private removeUserMediaFeed(callFeed: CallFeed): void {
1352
+ const feedIndex = this.userMediaFeeds.findIndex(
1353
+ (f) => f.userId === callFeed.userId && f.deviceId! === callFeed.deviceId,
1354
+ );
1355
+
1356
+ if (feedIndex === -1) {
1357
+ throw new Error("Couldn't find user media feed to remove");
1358
+ }
1359
+
1360
+ this.userMediaFeeds.splice(feedIndex, 1);
1361
+
1362
+ callFeed.dispose();
1363
+ this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds);
1364
+
1365
+ if (this.activeSpeaker === callFeed) {
1366
+ this.activeSpeaker = this.userMediaFeeds[0];
1367
+ this.emit(GroupCallEvent.ActiveSpeakerChanged, this.activeSpeaker);
1368
+ }
1369
+ }
1370
+
1371
+ private onActiveSpeakerLoop = (): void => {
1372
+ let topAvg: number | undefined = undefined;
1373
+ let nextActiveSpeaker: CallFeed | undefined = undefined;
1374
+
1375
+ for (const callFeed of this.userMediaFeeds) {
1376
+ if (callFeed.isLocal() && this.userMediaFeeds.length > 1) continue;
1377
+
1378
+ const total = callFeed.speakingVolumeSamples.reduce(
1379
+ (acc, volume) => acc + Math.max(volume, SPEAKING_THRESHOLD),
1380
+ );
1381
+ const avg = total / callFeed.speakingVolumeSamples.length;
1382
+
1383
+ if (!topAvg || avg > topAvg) {
1384
+ topAvg = avg;
1385
+ nextActiveSpeaker = callFeed;
1386
+ }
1387
+ }
1388
+
1389
+ if (nextActiveSpeaker && this.activeSpeaker !== nextActiveSpeaker && topAvg && topAvg > SPEAKING_THRESHOLD) {
1390
+ this.activeSpeaker = nextActiveSpeaker;
1391
+ this.emit(GroupCallEvent.ActiveSpeakerChanged, this.activeSpeaker);
1392
+ }
1393
+ };
1394
+
1395
+ /*
1396
+ * Screenshare Call Feed Event Handlers
1397
+ */
1398
+
1399
+ public getScreenshareFeed(userId: string, deviceId: string): CallFeed | undefined {
1400
+ return this.screenshareFeeds.find((f) => f.userId === userId && f.deviceId! === deviceId);
1401
+ }
1402
+
1403
+ private addScreenshareFeed(callFeed: CallFeed): void {
1404
+ this.screenshareFeeds.push(callFeed);
1405
+ this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds);
1406
+ }
1407
+
1408
+ private replaceScreenshareFeed(existingFeed: CallFeed, replacementFeed: CallFeed): void {
1409
+ const feedIndex = this.screenshareFeeds.findIndex(
1410
+ (f) => f.userId === existingFeed.userId && f.deviceId! === existingFeed.deviceId,
1411
+ );
1412
+
1413
+ if (feedIndex === -1) {
1414
+ throw new Error("Couldn't find screenshare feed to replace");
1415
+ }
1416
+
1417
+ this.screenshareFeeds.splice(feedIndex, 1, replacementFeed);
1418
+
1419
+ existingFeed.dispose();
1420
+ this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds);
1421
+ }
1422
+
1423
+ private removeScreenshareFeed(callFeed: CallFeed): void {
1424
+ const feedIndex = this.screenshareFeeds.findIndex(
1425
+ (f) => f.userId === callFeed.userId && f.deviceId! === callFeed.deviceId,
1426
+ );
1427
+
1428
+ if (feedIndex === -1) {
1429
+ throw new Error("Couldn't find screenshare feed to remove");
1430
+ }
1431
+
1432
+ this.screenshareFeeds.splice(feedIndex, 1);
1433
+
1434
+ callFeed.dispose();
1435
+ this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds);
1436
+ }
1437
+
1438
+ /**
1439
+ * Recalculates and updates the participant map to match the room state.
1440
+ */
1441
+ private updateParticipants(): void {
1442
+ const localMember = this.room.getMember(this.client.getSafeUserId());
1443
+ if (!localMember) {
1444
+ // The client hasn't fetched enough of the room state to get our own member
1445
+ // event. This probably shouldn't happen, but sanity check & exit for now.
1446
+ logger.warn(
1447
+ `GroupCall ${this.groupCallId} updateParticipants() tried to update participants before local room member is available`,
1448
+ );
1449
+ return;
1450
+ }
1451
+
1452
+ if (this.participantsExpirationTimer !== null) {
1453
+ clearTimeout(this.participantsExpirationTimer);
1454
+ this.participantsExpirationTimer = null;
1455
+ }
1456
+
1457
+ if (this.state === GroupCallState.Ended) {
1458
+ this.participants = new Map();
1459
+ return;
1460
+ }
1461
+
1462
+ const participants = new Map<RoomMember, Map<string, ParticipantState>>();
1463
+ const now = Date.now();
1464
+ const entered = this.state === GroupCallState.Entered || this.enteredViaAnotherSession;
1465
+ let nextExpiration = Infinity;
1466
+
1467
+ for (const e of this.getMemberStateEvents()) {
1468
+ const member = this.room.getMember(e.getStateKey()!);
1469
+ const content = e.getContent<Record<any, unknown>>();
1470
+ const calls: Record<any, unknown>[] = Array.isArray(content["m.calls"]) ? content["m.calls"] : [];
1471
+ const call = calls.find((call) => call["m.call_id"] === this.groupCallId);
1472
+ const devices: Record<any, unknown>[] = Array.isArray(call?.["m.devices"]) ? call!["m.devices"] : [];
1473
+
1474
+ // Filter out invalid and expired devices
1475
+ let validDevices = devices.filter(
1476
+ (d) =>
1477
+ typeof d.device_id === "string" &&
1478
+ typeof d.session_id === "string" &&
1479
+ typeof d.expires_ts === "number" &&
1480
+ d.expires_ts > now &&
1481
+ Array.isArray(d.feeds),
1482
+ ) as unknown as IGroupCallRoomMemberDevice[];
1483
+
1484
+ // Apply local echo for the unentered case
1485
+ if (!entered && member?.userId === this.client.getUserId()!) {
1486
+ validDevices = validDevices.filter((d) => d.device_id !== this.client.getDeviceId()!);
1487
+ }
1488
+
1489
+ // Must have a connected device and be joined to the room
1490
+ if (validDevices.length > 0 && member?.membership === KnownMembership.Join) {
1491
+ const deviceMap = new Map<string, ParticipantState>();
1492
+ participants.set(member, deviceMap);
1493
+
1494
+ for (const d of validDevices) {
1495
+ deviceMap.set(d.device_id, {
1496
+ sessionId: d.session_id,
1497
+ screensharing: d.feeds.some((f) => f.purpose === SDPStreamMetadataPurpose.Screenshare),
1498
+ });
1499
+ if (d.expires_ts < nextExpiration) nextExpiration = d.expires_ts;
1500
+ }
1501
+ }
1502
+ }
1503
+
1504
+ // Apply local echo for the entered case
1505
+ if (entered) {
1506
+ let deviceMap = participants.get(localMember);
1507
+ if (deviceMap === undefined) {
1508
+ deviceMap = new Map();
1509
+ participants.set(localMember, deviceMap);
1510
+ }
1511
+
1512
+ if (!deviceMap.has(this.client.getDeviceId()!)) {
1513
+ deviceMap.set(this.client.getDeviceId()!, {
1514
+ sessionId: this.client.getSessionId(),
1515
+ screensharing: this.getLocalFeeds().some((f) => f.purpose === SDPStreamMetadataPurpose.Screenshare),
1516
+ });
1517
+ }
1518
+ }
1519
+
1520
+ this.participants = participants;
1521
+ if (nextExpiration < Infinity) {
1522
+ this.participantsExpirationTimer = setTimeout(() => this.updateParticipants(), nextExpiration - now);
1523
+ }
1524
+ }
1525
+
1526
+ /**
1527
+ * Updates the local user's member state with the devices returned by the given function.
1528
+ * @param fn - A function from the current devices to the new devices. If it
1529
+ * returns null, the update will be skipped.
1530
+ * @param keepAlive - Whether the request should outlive the window.
1531
+ */
1532
+ private async updateDevices(
1533
+ fn: (devices: IGroupCallRoomMemberDevice[]) => IGroupCallRoomMemberDevice[] | null,
1534
+ keepAlive = false,
1535
+ ): Promise<void> {
1536
+ const now = Date.now();
1537
+ const localUserId = this.client.getUserId()!;
1538
+
1539
+ const event = this.getMemberStateEvents(localUserId);
1540
+ const content = event?.getContent<Record<any, unknown>>() ?? {};
1541
+ const calls: Record<any, unknown>[] = Array.isArray(content["m.calls"]) ? content["m.calls"] : [];
1542
+
1543
+ let call: Record<any, unknown> | null = null;
1544
+ const otherCalls: Record<any, unknown>[] = [];
1545
+ for (const c of calls) {
1546
+ if (c["m.call_id"] === this.groupCallId) {
1547
+ call = c;
1548
+ } else {
1549
+ otherCalls.push(c);
1550
+ }
1551
+ }
1552
+ if (call === null) call = {};
1553
+
1554
+ const devices: Record<any, unknown>[] = Array.isArray(call["m.devices"]) ? call["m.devices"] : [];
1555
+
1556
+ // Filter out invalid and expired devices
1557
+ const validDevices = devices.filter(
1558
+ (d) =>
1559
+ typeof d.device_id === "string" &&
1560
+ typeof d.session_id === "string" &&
1561
+ typeof d.expires_ts === "number" &&
1562
+ d.expires_ts > now &&
1563
+ Array.isArray(d.feeds),
1564
+ ) as unknown as IGroupCallRoomMemberDevice[];
1565
+
1566
+ const newDevices = fn(validDevices);
1567
+ if (newDevices === null) return;
1568
+
1569
+ const newCalls = [...(otherCalls as unknown as IGroupCallRoomMemberCallState[])];
1570
+ if (newDevices.length > 0) {
1571
+ newCalls.push({
1572
+ ...call,
1573
+ "m.call_id": this.groupCallId,
1574
+ "m.devices": newDevices,
1575
+ });
1576
+ }
1577
+
1578
+ const newContent: IGroupCallRoomMemberState = { "m.calls": newCalls };
1579
+
1580
+ await this.client.sendStateEvent(this.room.roomId, EventType.GroupCallMemberPrefix, newContent, localUserId, {
1581
+ keepAlive,
1582
+ });
1583
+ }
1584
+
1585
+ private async addDeviceToMemberState(): Promise<void> {
1586
+ await this.updateDevices((devices) => [
1587
+ ...devices.filter((d) => d.device_id !== this.client.getDeviceId()!),
1588
+ {
1589
+ device_id: this.client.getDeviceId()!,
1590
+ session_id: this.client.getSessionId(),
1591
+ expires_ts: Date.now() + DEVICE_TIMEOUT,
1592
+ feeds: this.getLocalFeeds().map((feed) => ({ purpose: feed.purpose })),
1593
+ // TODO: Add data channels
1594
+ },
1595
+ ]);
1596
+ }
1597
+
1598
+ private async updateMemberState(): Promise<void> {
1599
+ // Clear the old update interval before proceeding
1600
+ if (this.resendMemberStateTimer !== null) {
1601
+ clearInterval(this.resendMemberStateTimer);
1602
+ this.resendMemberStateTimer = null;
1603
+ }
1604
+
1605
+ if (this.state === GroupCallState.Entered) {
1606
+ // Add the local device
1607
+ await this.addDeviceToMemberState();
1608
+
1609
+ // Resend the state event every so often so it doesn't become stale
1610
+ this.resendMemberStateTimer = setInterval(
1611
+ async () => {
1612
+ logger.log(`GroupCall ${this.groupCallId} updateMemberState() resending call member state"`);
1613
+ try {
1614
+ await this.addDeviceToMemberState();
1615
+ } catch (e) {
1616
+ logger.error(
1617
+ `GroupCall ${this.groupCallId} updateMemberState() failed to resend call member state`,
1618
+ e,
1619
+ );
1620
+ }
1621
+ },
1622
+ (DEVICE_TIMEOUT * 3) / 4,
1623
+ );
1624
+ } else {
1625
+ // Remove the local device
1626
+ await this.updateDevices(
1627
+ (devices) => devices.filter((d) => d.device_id !== this.client.getDeviceId()!),
1628
+ true,
1629
+ );
1630
+ }
1631
+ }
1632
+
1633
+ /**
1634
+ * Cleans up our member state by filtering out logged out devices, inactive
1635
+ * devices, and our own device (if we know we haven't entered).
1636
+ */
1637
+ public async cleanMemberState(): Promise<void> {
1638
+ const { devices: myDevices } = await this.client.getDevices();
1639
+ const deviceMap = new Map<string, IMyDevice>(myDevices.map((d) => [d.device_id, d]));
1640
+
1641
+ // updateDevices takes care of filtering out inactive devices for us
1642
+ await this.updateDevices((devices) => {
1643
+ const newDevices = devices.filter((d) => {
1644
+ const device = deviceMap.get(d.device_id);
1645
+ return (
1646
+ device?.last_seen_ts !== undefined &&
1647
+ !(
1648
+ d.device_id === this.client.getDeviceId()! &&
1649
+ this.state !== GroupCallState.Entered &&
1650
+ !this.enteredViaAnotherSession
1651
+ )
1652
+ );
1653
+ });
1654
+
1655
+ // Skip the update if the devices are unchanged
1656
+ return newDevices.length === devices.length ? null : newDevices;
1657
+ });
1658
+ }
1659
+
1660
+ private onRoomState = (): void => this.updateParticipants();
1661
+
1662
+ private onParticipantsChanged = (): void => {
1663
+ // Re-run setTracksEnabled on all calls, so that participants that just
1664
+ // left get denied access to our media, and participants that just
1665
+ // joined get granted access
1666
+ this.forEachCall((call) => {
1667
+ const expected = this.callExpected(call);
1668
+ for (const feed of call.getLocalFeeds()) {
1669
+ setTracksEnabled(feed.stream.getAudioTracks(), !feed.isAudioMuted() && expected);
1670
+ setTracksEnabled(feed.stream.getVideoTracks(), !feed.isVideoMuted() && expected);
1671
+ }
1672
+ });
1673
+
1674
+ if (this.state === GroupCallState.Entered && !this.useLivekit) this.placeOutgoingCalls();
1675
+
1676
+ // Update the participants stored in the stats object
1677
+ };
1678
+
1679
+ private onStateChanged = (newState: GroupCallState, oldState: GroupCallState): void => {
1680
+ if (
1681
+ newState === GroupCallState.Entered ||
1682
+ oldState === GroupCallState.Entered ||
1683
+ newState === GroupCallState.Ended
1684
+ ) {
1685
+ // We either entered, left, or ended the call
1686
+ this.updateParticipants();
1687
+ this.updateMemberState().catch((e) =>
1688
+ logger.error(
1689
+ `GroupCall ${this.groupCallId} onStateChanged() failed to update member state devices"`,
1690
+ e,
1691
+ ),
1692
+ );
1693
+ }
1694
+ };
1695
+
1696
+ private onLocalFeedsChanged = (): void => {
1697
+ if (this.state === GroupCallState.Entered) {
1698
+ this.updateMemberState().catch((e) =>
1699
+ logger.error(
1700
+ `GroupCall ${this.groupCallId} onLocalFeedsChanged() failed to update member state feeds`,
1701
+ e,
1702
+ ),
1703
+ );
1704
+ }
1705
+ };
1706
+
1707
+ public getGroupCallStats(): GroupCallStats {
1708
+ if (this.stats === undefined) {
1709
+ const userID = this.client.getUserId() || "unknown";
1710
+ this.stats = new GroupCallStats(this.groupCallId, userID, this.statsCollectIntervalTime);
1711
+ this.stats.reports.on(StatsReport.CONNECTION_STATS, this.onConnectionStats);
1712
+ this.stats.reports.on(StatsReport.BYTE_SENT_STATS, this.onByteSentStats);
1713
+ this.stats.reports.on(StatsReport.SUMMARY_STATS, this.onSummaryStats);
1714
+ this.stats.reports.on(StatsReport.CALL_FEED_REPORT, this.onCallFeedReport);
1715
+ }
1716
+ return this.stats;
1717
+ }
1718
+
1719
+ public setGroupCallStatsInterval(interval: number): void {
1720
+ this.statsCollectIntervalTime = interval;
1721
+ if (this.stats !== undefined) {
1722
+ this.stats.stop();
1723
+ this.stats.setInterval(interval);
1724
+ if (interval > 0) {
1725
+ this.stats.start();
1726
+ }
1727
+ }
1728
+ }
1729
+ }