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