@textrp/briij-js-sdk 41.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1104) hide show
  1. package/CHANGELOG.md +6464 -0
  2. package/LICENSE +177 -0
  3. package/README.md +477 -0
  4. package/lib/@types/AESEncryptedSecretStoragePayload.d.ts +14 -0
  5. package/lib/@types/AESEncryptedSecretStoragePayload.d.ts.map +1 -0
  6. package/lib/@types/AESEncryptedSecretStoragePayload.js +1 -0
  7. package/lib/@types/AESEncryptedSecretStoragePayload.js.map +1 -0
  8. package/lib/@types/IIdentityServerProvider.d.ts +9 -0
  9. package/lib/@types/IIdentityServerProvider.d.ts.map +1 -0
  10. package/lib/@types/IIdentityServerProvider.js +1 -0
  11. package/lib/@types/IIdentityServerProvider.js.map +1 -0
  12. package/lib/@types/PushRules.d.ts +140 -0
  13. package/lib/@types/PushRules.d.ts.map +1 -0
  14. package/lib/@types/PushRules.js +94 -0
  15. package/lib/@types/PushRules.js.map +1 -0
  16. package/lib/@types/another-json.d.js +0 -0
  17. package/lib/@types/another-json.d.js.map +1 -0
  18. package/lib/@types/auth.d.ts +213 -0
  19. package/lib/@types/auth.d.ts.map +1 -0
  20. package/lib/@types/auth.js +107 -0
  21. package/lib/@types/auth.js.map +1 -0
  22. package/lib/@types/beacon.d.ts +106 -0
  23. package/lib/@types/beacon.d.ts.map +1 -0
  24. package/lib/@types/beacon.js +119 -0
  25. package/lib/@types/beacon.js.map +1 -0
  26. package/lib/@types/common.d.ts +10 -0
  27. package/lib/@types/common.d.ts.map +1 -0
  28. package/lib/@types/common.js +1 -0
  29. package/lib/@types/common.js.map +1 -0
  30. package/lib/@types/crypto.d.ts +46 -0
  31. package/lib/@types/crypto.d.ts.map +1 -0
  32. package/lib/@types/crypto.js +1 -0
  33. package/lib/@types/crypto.js.map +1 -0
  34. package/lib/@types/event.d.ts +356 -0
  35. package/lib/@types/event.d.ts.map +1 -0
  36. package/lib/@types/event.js +280 -0
  37. package/lib/@types/event.js.map +1 -0
  38. package/lib/@types/events.d.ts +92 -0
  39. package/lib/@types/events.d.ts.map +1 -0
  40. package/lib/@types/events.js +1 -0
  41. package/lib/@types/events.js.map +1 -0
  42. package/lib/@types/extensible_events.d.ts +98 -0
  43. package/lib/@types/extensible_events.d.ts.map +1 -0
  44. package/lib/@types/extensible_events.js +116 -0
  45. package/lib/@types/extensible_events.js.map +1 -0
  46. package/lib/@types/global.d.js +18 -0
  47. package/lib/@types/global.d.js.map +1 -0
  48. package/lib/@types/local_notifications.d.ts +4 -0
  49. package/lib/@types/local_notifications.d.ts.map +1 -0
  50. package/lib/@types/local_notifications.js +1 -0
  51. package/lib/@types/local_notifications.js.map +1 -0
  52. package/lib/@types/location.d.ts +60 -0
  53. package/lib/@types/location.d.ts.map +1 -0
  54. package/lib/@types/location.js +66 -0
  55. package/lib/@types/location.js.map +1 -0
  56. package/lib/@types/matrix-sdk-crypto-wasm.d.js +1 -0
  57. package/lib/@types/matrix-sdk-crypto-wasm.d.js.map +1 -0
  58. package/lib/@types/media.d.ts +220 -0
  59. package/lib/@types/media.d.ts.map +1 -0
  60. package/lib/@types/media.js +1 -0
  61. package/lib/@types/media.js.map +1 -0
  62. package/lib/@types/membership.d.ts +41 -0
  63. package/lib/@types/membership.d.ts.map +1 -0
  64. package/lib/@types/membership.js +58 -0
  65. package/lib/@types/membership.js.map +1 -0
  66. package/lib/@types/partials.d.ts +72 -0
  67. package/lib/@types/partials.d.ts.map +1 -0
  68. package/lib/@types/partials.js +71 -0
  69. package/lib/@types/partials.js.map +1 -0
  70. package/lib/@types/polls.d.ts +89 -0
  71. package/lib/@types/polls.d.ts.map +1 -0
  72. package/lib/@types/polls.js +86 -0
  73. package/lib/@types/polls.js.map +1 -0
  74. package/lib/@types/read_receipts.d.ts +36 -0
  75. package/lib/@types/read_receipts.d.ts.map +1 -0
  76. package/lib/@types/read_receipts.js +27 -0
  77. package/lib/@types/read_receipts.js.map +1 -0
  78. package/lib/@types/registration.d.ts +85 -0
  79. package/lib/@types/registration.d.ts.map +1 -0
  80. package/lib/@types/registration.js +1 -0
  81. package/lib/@types/registration.js.map +1 -0
  82. package/lib/@types/requests.d.ts +267 -0
  83. package/lib/@types/requests.d.ts.map +1 -0
  84. package/lib/@types/requests.js +42 -0
  85. package/lib/@types/requests.js.map +1 -0
  86. package/lib/@types/search.d.ts +90 -0
  87. package/lib/@types/search.d.ts.map +1 -0
  88. package/lib/@types/search.js +30 -0
  89. package/lib/@types/search.js.map +1 -0
  90. package/lib/@types/signed.d.ts +9 -0
  91. package/lib/@types/signed.d.ts.map +1 -0
  92. package/lib/@types/signed.js +1 -0
  93. package/lib/@types/signed.js.map +1 -0
  94. package/lib/@types/spaces.d.ts +16 -0
  95. package/lib/@types/spaces.d.ts.map +1 -0
  96. package/lib/@types/spaces.js +1 -0
  97. package/lib/@types/spaces.js.map +1 -0
  98. package/lib/@types/state_events.d.ts +121 -0
  99. package/lib/@types/state_events.d.ts.map +1 -0
  100. package/lib/@types/state_events.js +1 -0
  101. package/lib/@types/state_events.js.map +1 -0
  102. package/lib/@types/synapse.d.ts +19 -0
  103. package/lib/@types/synapse.d.ts.map +1 -0
  104. package/lib/@types/synapse.js +1 -0
  105. package/lib/@types/synapse.js.map +1 -0
  106. package/lib/@types/sync.d.ts +8 -0
  107. package/lib/@types/sync.d.ts.map +1 -0
  108. package/lib/@types/sync.js +25 -0
  109. package/lib/@types/sync.js.map +1 -0
  110. package/lib/@types/threepids.d.ts +12 -0
  111. package/lib/@types/threepids.d.ts.map +1 -0
  112. package/lib/@types/threepids.js +24 -0
  113. package/lib/@types/threepids.js.map +1 -0
  114. package/lib/@types/topic.d.ts +55 -0
  115. package/lib/@types/topic.d.ts.map +1 -0
  116. package/lib/@types/topic.js +62 -0
  117. package/lib/@types/topic.js.map +1 -0
  118. package/lib/@types/uia.d.ts +8 -0
  119. package/lib/@types/uia.d.ts.map +1 -0
  120. package/lib/@types/uia.js +1 -0
  121. package/lib/@types/uia.js.map +1 -0
  122. package/lib/NamespacedValue.d.ts +32 -0
  123. package/lib/NamespacedValue.d.ts.map +1 -0
  124. package/lib/NamespacedValue.js +113 -0
  125. package/lib/NamespacedValue.js.map +1 -0
  126. package/lib/ReEmitter.d.ts +15 -0
  127. package/lib/ReEmitter.d.ts.map +1 -0
  128. package/lib/ReEmitter.js +87 -0
  129. package/lib/ReEmitter.js.map +1 -0
  130. package/lib/ToDeviceMessageQueue.d.ts +30 -0
  131. package/lib/ToDeviceMessageQueue.d.ts.map +1 -0
  132. package/lib/ToDeviceMessageQueue.js +135 -0
  133. package/lib/ToDeviceMessageQueue.js.map +1 -0
  134. package/lib/autodiscovery.d.ts +136 -0
  135. package/lib/autodiscovery.d.ts.map +1 -0
  136. package/lib/autodiscovery.js +464 -0
  137. package/lib/autodiscovery.js.map +1 -0
  138. package/lib/base64.d.ts +25 -0
  139. package/lib/base64.d.ts.map +1 -0
  140. package/lib/base64.js +95 -0
  141. package/lib/base64.js.map +1 -0
  142. package/lib/briij.d.ts +116 -0
  143. package/lib/briij.d.ts.map +1 -0
  144. package/lib/briij.js +145 -0
  145. package/lib/briij.js.map +1 -0
  146. package/lib/browser-index.d.ts +8 -0
  147. package/lib/browser-index.d.ts.map +1 -0
  148. package/lib/browser-index.js +35 -0
  149. package/lib/browser-index.js.map +1 -0
  150. package/lib/client.d.ts +3493 -0
  151. package/lib/client.d.ts.map +1 -0
  152. package/lib/client.js +7482 -0
  153. package/lib/client.js.map +1 -0
  154. package/lib/common-crypto/CryptoBackend.d.ts +234 -0
  155. package/lib/common-crypto/CryptoBackend.d.ts.map +1 -0
  156. package/lib/common-crypto/CryptoBackend.js +69 -0
  157. package/lib/common-crypto/CryptoBackend.js.map +1 -0
  158. package/lib/common-crypto/key-passphrase.d.ts +14 -0
  159. package/lib/common-crypto/key-passphrase.d.ts.map +1 -0
  160. package/lib/common-crypto/key-passphrase.js +33 -0
  161. package/lib/common-crypto/key-passphrase.js.map +1 -0
  162. package/lib/content-helpers.d.ts +90 -0
  163. package/lib/content-helpers.d.ts.map +1 -0
  164. package/lib/content-helpers.js +262 -0
  165. package/lib/content-helpers.js.map +1 -0
  166. package/lib/content-repo.d.ts +25 -0
  167. package/lib/content-repo.d.ts.map +1 -0
  168. package/lib/content-repo.js +109 -0
  169. package/lib/content-repo.js.map +1 -0
  170. package/lib/crypto/store/base.d.ts +301 -0
  171. package/lib/crypto/store/base.d.ts.map +1 -0
  172. package/lib/crypto/store/base.js +145 -0
  173. package/lib/crypto/store/base.js.map +1 -0
  174. package/lib/crypto/store/indexeddb-crypto-store-backend.d.ts +94 -0
  175. package/lib/crypto/store/indexeddb-crypto-store-backend.d.ts.map +1 -0
  176. package/lib/crypto/store/indexeddb-crypto-store-backend.js +604 -0
  177. package/lib/crypto/store/indexeddb-crypto-store-backend.js.map +1 -0
  178. package/lib/crypto/store/indexeddb-crypto-store.d.ts +251 -0
  179. package/lib/crypto/store/indexeddb-crypto-store.d.ts.map +1 -0
  180. package/lib/crypto/store/indexeddb-crypto-store.js +477 -0
  181. package/lib/crypto/store/indexeddb-crypto-store.js.map +1 -0
  182. package/lib/crypto/store/localStorage-crypto-store.d.ts +102 -0
  183. package/lib/crypto/store/localStorage-crypto-store.d.ts.map +1 -0
  184. package/lib/crypto/store/localStorage-crypto-store.js +374 -0
  185. package/lib/crypto/store/localStorage-crypto-store.js.map +1 -0
  186. package/lib/crypto/store/memory-crypto-store.d.ts +117 -0
  187. package/lib/crypto/store/memory-crypto-store.d.ts.map +1 -0
  188. package/lib/crypto/store/memory-crypto-store.js +311 -0
  189. package/lib/crypto/store/memory-crypto-store.js.map +1 -0
  190. package/lib/crypto-api/CryptoEvent.d.ts +120 -0
  191. package/lib/crypto-api/CryptoEvent.d.ts.map +1 -0
  192. package/lib/crypto-api/CryptoEvent.js +137 -0
  193. package/lib/crypto-api/CryptoEvent.js.map +1 -0
  194. package/lib/crypto-api/CryptoEventHandlerMap.d.ts +26 -0
  195. package/lib/crypto-api/CryptoEventHandlerMap.d.ts.map +1 -0
  196. package/lib/crypto-api/CryptoEventHandlerMap.js +1 -0
  197. package/lib/crypto-api/CryptoEventHandlerMap.js.map +1 -0
  198. package/lib/crypto-api/index.d.ts +1160 -0
  199. package/lib/crypto-api/index.d.ts.map +1 -0
  200. package/lib/crypto-api/index.js +410 -0
  201. package/lib/crypto-api/index.js.map +1 -0
  202. package/lib/crypto-api/key-passphrase.d.ts +11 -0
  203. package/lib/crypto-api/key-passphrase.d.ts.map +1 -0
  204. package/lib/crypto-api/key-passphrase.js +51 -0
  205. package/lib/crypto-api/key-passphrase.js.map +1 -0
  206. package/lib/crypto-api/keybackup.d.ts +87 -0
  207. package/lib/crypto-api/keybackup.d.ts.map +1 -0
  208. package/lib/crypto-api/keybackup.js +1 -0
  209. package/lib/crypto-api/keybackup.js.map +1 -0
  210. package/lib/crypto-api/recovery-key.d.ts +11 -0
  211. package/lib/crypto-api/recovery-key.d.ts.map +1 -0
  212. package/lib/crypto-api/recovery-key.js +65 -0
  213. package/lib/crypto-api/recovery-key.js.map +1 -0
  214. package/lib/crypto-api/verification.d.ts +315 -0
  215. package/lib/crypto-api/verification.d.ts.map +1 -0
  216. package/lib/crypto-api/verification.js +130 -0
  217. package/lib/crypto-api/verification.js.map +1 -0
  218. package/lib/digest.d.ts +10 -0
  219. package/lib/digest.d.ts.map +1 -0
  220. package/lib/digest.js +40 -0
  221. package/lib/digest.js.map +1 -0
  222. package/lib/embedded.d.ts +182 -0
  223. package/lib/embedded.d.ts.map +1 -0
  224. package/lib/embedded.js +746 -0
  225. package/lib/embedded.js.map +1 -0
  226. package/lib/errors.d.ts +38 -0
  227. package/lib/errors.d.ts.map +1 -0
  228. package/lib/errors.js +73 -0
  229. package/lib/errors.js.map +1 -0
  230. package/lib/event-mapper.d.ts +9 -0
  231. package/lib/event-mapper.d.ts.map +1 -0
  232. package/lib/event-mapper.js +74 -0
  233. package/lib/event-mapper.js.map +1 -0
  234. package/lib/extensible_events_v1/ExtensibleEvent.d.ts +38 -0
  235. package/lib/extensible_events_v1/ExtensibleEvent.d.ts.map +1 -0
  236. package/lib/extensible_events_v1/ExtensibleEvent.js +57 -0
  237. package/lib/extensible_events_v1/ExtensibleEvent.js.map +1 -0
  238. package/lib/extensible_events_v1/InvalidEventError.d.ts +7 -0
  239. package/lib/extensible_events_v1/InvalidEventError.d.ts.map +1 -0
  240. package/lib/extensible_events_v1/InvalidEventError.js +25 -0
  241. package/lib/extensible_events_v1/InvalidEventError.js.map +1 -0
  242. package/lib/extensible_events_v1/MessageEvent.d.ts +44 -0
  243. package/lib/extensible_events_v1/MessageEvent.d.ts.map +1 -0
  244. package/lib/extensible_events_v1/MessageEvent.js +134 -0
  245. package/lib/extensible_events_v1/MessageEvent.js.map +1 -0
  246. package/lib/extensible_events_v1/PollEndEvent.d.ts +33 -0
  247. package/lib/extensible_events_v1/PollEndEvent.d.ts.map +1 -0
  248. package/lib/extensible_events_v1/PollEndEvent.js +88 -0
  249. package/lib/extensible_events_v1/PollEndEvent.js.map +1 -0
  250. package/lib/extensible_events_v1/PollResponseEvent.d.ts +49 -0
  251. package/lib/extensible_events_v1/PollResponseEvent.d.ts.map +1 -0
  252. package/lib/extensible_events_v1/PollResponseEvent.js +135 -0
  253. package/lib/extensible_events_v1/PollResponseEvent.js.map +1 -0
  254. package/lib/extensible_events_v1/PollStartEvent.d.ts +71 -0
  255. package/lib/extensible_events_v1/PollStartEvent.d.ts.map +1 -0
  256. package/lib/extensible_events_v1/PollStartEvent.js +185 -0
  257. package/lib/extensible_events_v1/PollStartEvent.js.map +1 -0
  258. package/lib/extensible_events_v1/utilities.d.ts +14 -0
  259. package/lib/extensible_events_v1/utilities.d.ts.map +1 -0
  260. package/lib/extensible_events_v1/utilities.js +34 -0
  261. package/lib/extensible_events_v1/utilities.js.map +1 -0
  262. package/lib/feature.d.ts +20 -0
  263. package/lib/feature.d.ts.map +1 -0
  264. package/lib/feature.js +89 -0
  265. package/lib/feature.js.map +1 -0
  266. package/lib/filter-component.d.ts +64 -0
  267. package/lib/filter-component.d.ts.map +1 -0
  268. package/lib/filter-component.js +170 -0
  269. package/lib/filter-component.js.map +1 -0
  270. package/lib/filter.d.ts +97 -0
  271. package/lib/filter.d.ts.map +1 -0
  272. package/lib/filter.js +207 -0
  273. package/lib/filter.js.map +1 -0
  274. package/lib/http-api/errors.d.ts +117 -0
  275. package/lib/http-api/errors.d.ts.map +1 -0
  276. package/lib/http-api/errors.js +245 -0
  277. package/lib/http-api/errors.js.map +1 -0
  278. package/lib/http-api/fetch.d.ts +80 -0
  279. package/lib/http-api/fetch.d.ts.map +1 -0
  280. package/lib/http-api/fetch.js +332 -0
  281. package/lib/http-api/fetch.js.map +1 -0
  282. package/lib/http-api/index.d.ts +33 -0
  283. package/lib/http-api/index.d.ts.map +1 -0
  284. package/lib/http-api/index.js +178 -0
  285. package/lib/http-api/index.js.map +1 -0
  286. package/lib/http-api/interface.d.ts +186 -0
  287. package/lib/http-api/interface.d.ts.map +1 -0
  288. package/lib/http-api/interface.js +39 -0
  289. package/lib/http-api/interface.js.map +1 -0
  290. package/lib/http-api/method.d.ts +10 -0
  291. package/lib/http-api/method.d.ts.map +1 -0
  292. package/lib/http-api/method.js +27 -0
  293. package/lib/http-api/method.js.map +1 -0
  294. package/lib/http-api/prefix.d.ts +31 -0
  295. package/lib/http-api/prefix.d.ts.map +1 -0
  296. package/lib/http-api/prefix.js +50 -0
  297. package/lib/http-api/prefix.js.map +1 -0
  298. package/lib/http-api/refresh.d.ts +53 -0
  299. package/lib/http-api/refresh.d.ts.map +1 -0
  300. package/lib/http-api/refresh.js +174 -0
  301. package/lib/http-api/refresh.js.map +1 -0
  302. package/lib/http-api/utils.d.ts +37 -0
  303. package/lib/http-api/utils.d.ts.map +1 -0
  304. package/lib/http-api/utils.js +182 -0
  305. package/lib/http-api/utils.js.map +1 -0
  306. package/lib/index.d.ts +4 -0
  307. package/lib/index.d.ts.map +1 -0
  308. package/lib/index.js +24 -0
  309. package/lib/index.js.map +1 -0
  310. package/lib/indexeddb-helpers.d.ts +10 -0
  311. package/lib/indexeddb-helpers.d.ts.map +1 -0
  312. package/lib/indexeddb-helpers.js +51 -0
  313. package/lib/indexeddb-helpers.js.map +1 -0
  314. package/lib/indexeddb-worker.d.ts +7 -0
  315. package/lib/indexeddb-worker.d.ts.map +1 -0
  316. package/lib/indexeddb-worker.js +25 -0
  317. package/lib/indexeddb-worker.js.map +1 -0
  318. package/lib/interactive-auth.d.ts +341 -0
  319. package/lib/interactive-auth.d.ts.map +1 -0
  320. package/lib/interactive-auth.js +563 -0
  321. package/lib/interactive-auth.js.map +1 -0
  322. package/lib/logger.d.ts +124 -0
  323. package/lib/logger.d.ts.map +1 -0
  324. package/lib/logger.js +230 -0
  325. package/lib/logger.js.map +1 -0
  326. package/lib/matrixrtc/CallMembership.d.ts +154 -0
  327. package/lib/matrixrtc/CallMembership.d.ts.map +1 -0
  328. package/lib/matrixrtc/CallMembership.js +469 -0
  329. package/lib/matrixrtc/CallMembership.js.map +1 -0
  330. package/lib/matrixrtc/EncryptionManager.d.ts +44 -0
  331. package/lib/matrixrtc/EncryptionManager.d.ts.map +1 -0
  332. package/lib/matrixrtc/EncryptionManager.js +13 -0
  333. package/lib/matrixrtc/EncryptionManager.js.map +1 -0
  334. package/lib/matrixrtc/IKeyTransport.d.ts +37 -0
  335. package/lib/matrixrtc/IKeyTransport.d.ts.map +1 -0
  336. package/lib/matrixrtc/IKeyTransport.js +27 -0
  337. package/lib/matrixrtc/IKeyTransport.js.map +1 -0
  338. package/lib/matrixrtc/IMembershipManager.d.ts +94 -0
  339. package/lib/matrixrtc/IMembershipManager.d.ts.map +1 -0
  340. package/lib/matrixrtc/IMembershipManager.js +40 -0
  341. package/lib/matrixrtc/IMembershipManager.js.map +1 -0
  342. package/lib/matrixrtc/LivekitTransport.d.ts +23 -0
  343. package/lib/matrixrtc/LivekitTransport.d.ts.map +1 -0
  344. package/lib/matrixrtc/LivekitTransport.js +29 -0
  345. package/lib/matrixrtc/LivekitTransport.js.map +1 -0
  346. package/lib/matrixrtc/MatrixRTCSession.d.ts +343 -0
  347. package/lib/matrixrtc/MatrixRTCSession.d.ts.map +1 -0
  348. package/lib/matrixrtc/MatrixRTCSession.js +623 -0
  349. package/lib/matrixrtc/MatrixRTCSession.js.map +1 -0
  350. package/lib/matrixrtc/MatrixRTCSessionManager.d.ts +46 -0
  351. package/lib/matrixrtc/MatrixRTCSessionManager.d.ts.map +1 -0
  352. package/lib/matrixrtc/MatrixRTCSessionManager.js +149 -0
  353. package/lib/matrixrtc/MatrixRTCSessionManager.js.map +1 -0
  354. package/lib/matrixrtc/MembershipManager.d.ts +210 -0
  355. package/lib/matrixrtc/MembershipManager.d.ts.map +1 -0
  356. package/lib/matrixrtc/MembershipManager.js +977 -0
  357. package/lib/matrixrtc/MembershipManager.js.map +1 -0
  358. package/lib/matrixrtc/MembershipManagerActionScheduler.d.ts +59 -0
  359. package/lib/matrixrtc/MembershipManagerActionScheduler.d.ts.map +1 -0
  360. package/lib/matrixrtc/MembershipManagerActionScheduler.js +125 -0
  361. package/lib/matrixrtc/MembershipManagerActionScheduler.js.map +1 -0
  362. package/lib/matrixrtc/RTCEncryptionManager.d.ts +110 -0
  363. package/lib/matrixrtc/RTCEncryptionManager.d.ts.map +1 -0
  364. package/lib/matrixrtc/RTCEncryptionManager.js +376 -0
  365. package/lib/matrixrtc/RTCEncryptionManager.js.map +1 -0
  366. package/lib/matrixrtc/ToDeviceKeyTransport.d.ts +30 -0
  367. package/lib/matrixrtc/ToDeviceKeyTransport.d.ts.map +1 -0
  368. package/lib/matrixrtc/ToDeviceKeyTransport.js +164 -0
  369. package/lib/matrixrtc/ToDeviceKeyTransport.js.map +1 -0
  370. package/lib/matrixrtc/index.d.ts +9 -0
  371. package/lib/matrixrtc/index.d.ts.map +1 -0
  372. package/lib/matrixrtc/index.js +23 -0
  373. package/lib/matrixrtc/index.js.map +1 -0
  374. package/lib/matrixrtc/membershipData/common.d.ts +8 -0
  375. package/lib/matrixrtc/membershipData/common.d.ts.map +1 -0
  376. package/lib/matrixrtc/membershipData/common.js +26 -0
  377. package/lib/matrixrtc/membershipData/common.js.map +1 -0
  378. package/lib/matrixrtc/membershipData/index.d.ts +4 -0
  379. package/lib/matrixrtc/membershipData/index.d.ts.map +1 -0
  380. package/lib/matrixrtc/membershipData/index.js +20 -0
  381. package/lib/matrixrtc/membershipData/index.js.map +1 -0
  382. package/lib/matrixrtc/membershipData/rtc.d.ts +33 -0
  383. package/lib/matrixrtc/membershipData/rtc.d.ts.map +1 -0
  384. package/lib/matrixrtc/membershipData/rtc.js +137 -0
  385. package/lib/matrixrtc/membershipData/rtc.js.map +1 -0
  386. package/lib/matrixrtc/membershipData/session.d.ts +77 -0
  387. package/lib/matrixrtc/membershipData/session.d.ts.map +1 -0
  388. package/lib/matrixrtc/membershipData/session.js +62 -0
  389. package/lib/matrixrtc/membershipData/session.js.map +1 -0
  390. package/lib/matrixrtc/types.d.ts +169 -0
  391. package/lib/matrixrtc/types.d.ts.map +1 -0
  392. package/lib/matrixrtc/types.js +117 -0
  393. package/lib/matrixrtc/types.js.map +1 -0
  394. package/lib/matrixrtc/utils.d.ts +27 -0
  395. package/lib/matrixrtc/utils.d.ts.map +1 -0
  396. package/lib/matrixrtc/utils.js +72 -0
  397. package/lib/matrixrtc/utils.js.map +1 -0
  398. package/lib/models/MSC3089Branch.d.ts +98 -0
  399. package/lib/models/MSC3089Branch.d.ts.map +1 -0
  400. package/lib/models/MSC3089Branch.js +240 -0
  401. package/lib/models/MSC3089Branch.js.map +1 -0
  402. package/lib/models/MSC3089TreeSpace.d.ts +166 -0
  403. package/lib/models/MSC3089TreeSpace.d.ts.map +1 -0
  404. package/lib/models/MSC3089TreeSpace.js +521 -0
  405. package/lib/models/MSC3089TreeSpace.js.map +1 -0
  406. package/lib/models/ToDeviceMessage.d.ts +17 -0
  407. package/lib/models/ToDeviceMessage.d.ts.map +1 -0
  408. package/lib/models/ToDeviceMessage.js +1 -0
  409. package/lib/models/ToDeviceMessage.js.map +1 -0
  410. package/lib/models/beacon.d.ts +52 -0
  411. package/lib/models/beacon.d.ts.map +1 -0
  412. package/lib/models/beacon.js +174 -0
  413. package/lib/models/beacon.js.map +1 -0
  414. package/lib/models/compare-event-ordering.d.ts +24 -0
  415. package/lib/models/compare-event-ordering.d.ts.map +1 -0
  416. package/lib/models/compare-event-ordering.js +120 -0
  417. package/lib/models/compare-event-ordering.js.map +1 -0
  418. package/lib/models/device.d.ts +45 -0
  419. package/lib/models/device.d.ts.map +1 -0
  420. package/lib/models/device.js +77 -0
  421. package/lib/models/device.js.map +1 -0
  422. package/lib/models/event-context.d.ts +62 -0
  423. package/lib/models/event-context.d.ts.map +1 -0
  424. package/lib/models/event-context.js +113 -0
  425. package/lib/models/event-context.js.map +1 -0
  426. package/lib/models/event-status.d.ts +19 -0
  427. package/lib/models/event-status.d.ts.map +1 -0
  428. package/lib/models/event-status.js +36 -0
  429. package/lib/models/event-status.js.map +1 -0
  430. package/lib/models/event-timeline-set.d.ts +308 -0
  431. package/lib/models/event-timeline-set.d.ts.map +1 -0
  432. package/lib/models/event-timeline-set.js +805 -0
  433. package/lib/models/event-timeline-set.js.map +1 -0
  434. package/lib/models/event-timeline.d.ts +224 -0
  435. package/lib/models/event-timeline.d.ts.map +1 -0
  436. package/lib/models/event-timeline.js +434 -0
  437. package/lib/models/event-timeline.js.map +1 -0
  438. package/lib/models/event.d.ts +844 -0
  439. package/lib/models/event.d.ts.map +1 -0
  440. package/lib/models/event.js +1600 -0
  441. package/lib/models/event.js.map +1 -0
  442. package/lib/models/invites-ignorer-types.d.ts +27 -0
  443. package/lib/models/invites-ignorer-types.d.ts.map +1 -0
  444. package/lib/models/invites-ignorer-types.js +56 -0
  445. package/lib/models/invites-ignorer-types.js.map +1 -0
  446. package/lib/models/invites-ignorer.d.ts +112 -0
  447. package/lib/models/invites-ignorer.d.ts.map +1 -0
  448. package/lib/models/invites-ignorer.js +357 -0
  449. package/lib/models/invites-ignorer.js.map +1 -0
  450. package/lib/models/poll.d.ts +67 -0
  451. package/lib/models/poll.d.ts.map +1 -0
  452. package/lib/models/poll.js +241 -0
  453. package/lib/models/poll.js.map +1 -0
  454. package/lib/models/profile-keys.d.ts +17 -0
  455. package/lib/models/profile-keys.d.ts.map +1 -0
  456. package/lib/models/profile-keys.js +34 -0
  457. package/lib/models/profile-keys.js.map +1 -0
  458. package/lib/models/read-receipt.d.ts +115 -0
  459. package/lib/models/read-receipt.d.ts.map +1 -0
  460. package/lib/models/read-receipt.js +366 -0
  461. package/lib/models/read-receipt.js.map +1 -0
  462. package/lib/models/related-relations.d.ts +11 -0
  463. package/lib/models/related-relations.d.ts.map +1 -0
  464. package/lib/models/related-relations.js +33 -0
  465. package/lib/models/related-relations.js.map +1 -0
  466. package/lib/models/relations-container.d.ts +44 -0
  467. package/lib/models/relations-container.d.ts.map +1 -0
  468. package/lib/models/relations-container.js +132 -0
  469. package/lib/models/relations-container.js.map +1 -0
  470. package/lib/models/relations.d.ts +123 -0
  471. package/lib/models/relations.d.ts.map +1 -0
  472. package/lib/models/relations.js +378 -0
  473. package/lib/models/relations.js.map +1 -0
  474. package/lib/models/room-member.d.ts +221 -0
  475. package/lib/models/room-member.d.ts.map +1 -0
  476. package/lib/models/room-member.js +376 -0
  477. package/lib/models/room-member.js.map +1 -0
  478. package/lib/models/room-receipts.d.ts +39 -0
  479. package/lib/models/room-receipts.d.ts.map +1 -0
  480. package/lib/models/room-receipts.js +392 -0
  481. package/lib/models/room-receipts.js.map +1 -0
  482. package/lib/models/room-state.d.ts +463 -0
  483. package/lib/models/room-state.d.ts.map +1 -0
  484. package/lib/models/room-state.js +1066 -0
  485. package/lib/models/room-state.js.map +1 -0
  486. package/lib/models/room-sticky-events.d.ts +110 -0
  487. package/lib/models/room-sticky-events.d.ts.map +1 -0
  488. package/lib/models/room-sticky-events.js +353 -0
  489. package/lib/models/room-sticky-events.js.map +1 -0
  490. package/lib/models/room-summary.d.ts +59 -0
  491. package/lib/models/room-summary.d.ts.map +1 -0
  492. package/lib/models/room-summary.js +39 -0
  493. package/lib/models/room-summary.js.map +1 -0
  494. package/lib/models/room.d.ts +1285 -0
  495. package/lib/models/room.d.ts.map +1 -0
  496. package/lib/models/room.js +3548 -0
  497. package/lib/models/room.js.map +1 -0
  498. package/lib/models/search-result.d.ts +20 -0
  499. package/lib/models/search-result.d.ts.map +1 -0
  500. package/lib/models/search-result.js +52 -0
  501. package/lib/models/search-result.js.map +1 -0
  502. package/lib/models/thread.d.ts +245 -0
  503. package/lib/models/thread.d.ts.map +1 -0
  504. package/lib/models/thread.js +866 -0
  505. package/lib/models/thread.js.map +1 -0
  506. package/lib/models/typed-event-emitter.d.ts +157 -0
  507. package/lib/models/typed-event-emitter.d.ts.map +1 -0
  508. package/lib/models/typed-event-emitter.js +227 -0
  509. package/lib/models/typed-event-emitter.js.map +1 -0
  510. package/lib/models/user.d.ts +195 -0
  511. package/lib/models/user.d.ts.map +1 -0
  512. package/lib/models/user.js +218 -0
  513. package/lib/models/user.js.map +1 -0
  514. package/lib/oidc/authorize.d.ts +93 -0
  515. package/lib/oidc/authorize.d.ts.map +1 -0
  516. package/lib/oidc/authorize.js +282 -0
  517. package/lib/oidc/authorize.js.map +1 -0
  518. package/lib/oidc/discovery.d.ts +22 -0
  519. package/lib/oidc/discovery.d.ts.map +1 -0
  520. package/lib/oidc/discovery.js +78 -0
  521. package/lib/oidc/discovery.js.map +1 -0
  522. package/lib/oidc/error.d.ts +18 -0
  523. package/lib/oidc/error.d.ts.map +1 -0
  524. package/lib/oidc/error.js +35 -0
  525. package/lib/oidc/error.js.map +1 -0
  526. package/lib/oidc/index.d.ts +16 -0
  527. package/lib/oidc/index.d.ts.map +1 -0
  528. package/lib/oidc/index.js +29 -0
  529. package/lib/oidc/index.js.map +1 -0
  530. package/lib/oidc/register.d.ts +70 -0
  531. package/lib/oidc/register.d.ts.map +1 -0
  532. package/lib/oidc/register.js +135 -0
  533. package/lib/oidc/register.js.map +1 -0
  534. package/lib/oidc/tokenRefresher.d.ts +91 -0
  535. package/lib/oidc/tokenRefresher.d.ts.map +1 -0
  536. package/lib/oidc/tokenRefresher.js +187 -0
  537. package/lib/oidc/tokenRefresher.js.map +1 -0
  538. package/lib/oidc/validate.d.ts +78 -0
  539. package/lib/oidc/validate.d.ts.map +1 -0
  540. package/lib/oidc/validate.js +181 -0
  541. package/lib/oidc/validate.js.map +1 -0
  542. package/lib/pushprocessor.d.ts +140 -0
  543. package/lib/pushprocessor.d.ts.map +1 -0
  544. package/lib/pushprocessor.js +702 -0
  545. package/lib/pushprocessor.js.map +1 -0
  546. package/lib/randomstring.d.ts +32 -0
  547. package/lib/randomstring.d.ts.map +1 -0
  548. package/lib/randomstring.js +97 -0
  549. package/lib/randomstring.js.map +1 -0
  550. package/lib/realtime-callbacks.d.ts +18 -0
  551. package/lib/realtime-callbacks.d.ts.map +1 -0
  552. package/lib/realtime-callbacks.js +177 -0
  553. package/lib/realtime-callbacks.js.map +1 -0
  554. package/lib/receipt-accumulator.d.ts +51 -0
  555. package/lib/receipt-accumulator.d.ts.map +1 -0
  556. package/lib/receipt-accumulator.js +164 -0
  557. package/lib/receipt-accumulator.js.map +1 -0
  558. package/lib/rendezvous/MSC4108SignInWithQR.d.ts +112 -0
  559. package/lib/rendezvous/MSC4108SignInWithQR.d.ts.map +1 -0
  560. package/lib/rendezvous/MSC4108SignInWithQR.js +389 -0
  561. package/lib/rendezvous/MSC4108SignInWithQR.js.map +1 -0
  562. package/lib/rendezvous/RendezvousChannel.d.ts +27 -0
  563. package/lib/rendezvous/RendezvousChannel.d.ts.map +1 -0
  564. package/lib/rendezvous/RendezvousChannel.js +1 -0
  565. package/lib/rendezvous/RendezvousChannel.js.map +1 -0
  566. package/lib/rendezvous/RendezvousCode.d.ts +9 -0
  567. package/lib/rendezvous/RendezvousCode.d.ts.map +1 -0
  568. package/lib/rendezvous/RendezvousCode.js +1 -0
  569. package/lib/rendezvous/RendezvousCode.js.map +1 -0
  570. package/lib/rendezvous/RendezvousError.d.ts +6 -0
  571. package/lib/rendezvous/RendezvousError.d.ts.map +1 -0
  572. package/lib/rendezvous/RendezvousError.js +23 -0
  573. package/lib/rendezvous/RendezvousError.js.map +1 -0
  574. package/lib/rendezvous/RendezvousFailureReason.d.ts +31 -0
  575. package/lib/rendezvous/RendezvousFailureReason.d.ts.map +1 -0
  576. package/lib/rendezvous/RendezvousFailureReason.js +47 -0
  577. package/lib/rendezvous/RendezvousFailureReason.js.map +1 -0
  578. package/lib/rendezvous/RendezvousIntent.d.ts +5 -0
  579. package/lib/rendezvous/RendezvousIntent.d.ts.map +1 -0
  580. package/lib/rendezvous/RendezvousIntent.js +22 -0
  581. package/lib/rendezvous/RendezvousIntent.js.map +1 -0
  582. package/lib/rendezvous/RendezvousTransport.d.ts +36 -0
  583. package/lib/rendezvous/RendezvousTransport.d.ts.map +1 -0
  584. package/lib/rendezvous/RendezvousTransport.js +1 -0
  585. package/lib/rendezvous/RendezvousTransport.js.map +1 -0
  586. package/lib/rendezvous/channels/MSC4108SecureChannel.d.ts +58 -0
  587. package/lib/rendezvous/channels/MSC4108SecureChannel.d.ts.map +1 -0
  588. package/lib/rendezvous/channels/MSC4108SecureChannel.js +246 -0
  589. package/lib/rendezvous/channels/MSC4108SecureChannel.js.map +1 -0
  590. package/lib/rendezvous/channels/index.d.ts +2 -0
  591. package/lib/rendezvous/channels/index.d.ts.map +1 -0
  592. package/lib/rendezvous/channels/index.js +18 -0
  593. package/lib/rendezvous/channels/index.js.map +1 -0
  594. package/lib/rendezvous/index.d.ts +10 -0
  595. package/lib/rendezvous/index.d.ts.map +1 -0
  596. package/lib/rendezvous/index.js +23 -0
  597. package/lib/rendezvous/index.js.map +1 -0
  598. package/lib/rendezvous/transports/MSC4108RendezvousSession.d.ts +61 -0
  599. package/lib/rendezvous/transports/MSC4108RendezvousSession.d.ts.map +1 -0
  600. package/lib/rendezvous/transports/MSC4108RendezvousSession.js +254 -0
  601. package/lib/rendezvous/transports/MSC4108RendezvousSession.js.map +1 -0
  602. package/lib/rendezvous/transports/index.d.ts +2 -0
  603. package/lib/rendezvous/transports/index.d.ts.map +1 -0
  604. package/lib/rendezvous/transports/index.js +18 -0
  605. package/lib/rendezvous/transports/index.js.map +1 -0
  606. package/lib/room-hierarchy.d.ts +35 -0
  607. package/lib/room-hierarchy.d.ts.map +1 -0
  608. package/lib/room-hierarchy.js +136 -0
  609. package/lib/room-hierarchy.js.map +1 -0
  610. package/lib/rust-crypto/CrossSigningIdentity.d.ts +35 -0
  611. package/lib/rust-crypto/CrossSigningIdentity.d.ts.map +1 -0
  612. package/lib/rust-crypto/CrossSigningIdentity.js +163 -0
  613. package/lib/rust-crypto/CrossSigningIdentity.js.map +1 -0
  614. package/lib/rust-crypto/DehydratedDeviceManager.d.ts +118 -0
  615. package/lib/rust-crypto/DehydratedDeviceManager.d.ts.map +1 -0
  616. package/lib/rust-crypto/DehydratedDeviceManager.js +361 -0
  617. package/lib/rust-crypto/DehydratedDeviceManager.js.map +1 -0
  618. package/lib/rust-crypto/KeyClaimManager.d.ts +33 -0
  619. package/lib/rust-crypto/KeyClaimManager.d.ts.map +1 -0
  620. package/lib/rust-crypto/KeyClaimManager.js +82 -0
  621. package/lib/rust-crypto/KeyClaimManager.js.map +1 -0
  622. package/lib/rust-crypto/OutgoingRequestProcessor.d.ts +36 -0
  623. package/lib/rust-crypto/OutgoingRequestProcessor.d.ts.map +1 -0
  624. package/lib/rust-crypto/OutgoingRequestProcessor.js +194 -0
  625. package/lib/rust-crypto/OutgoingRequestProcessor.js.map +1 -0
  626. package/lib/rust-crypto/OutgoingRequestsManager.d.ts +47 -0
  627. package/lib/rust-crypto/OutgoingRequestsManager.d.ts.map +1 -0
  628. package/lib/rust-crypto/OutgoingRequestsManager.js +175 -0
  629. package/lib/rust-crypto/OutgoingRequestsManager.js.map +1 -0
  630. package/lib/rust-crypto/PerSessionKeyBackupDownloader.d.ts +120 -0
  631. package/lib/rust-crypto/PerSessionKeyBackupDownloader.d.ts.map +1 -0
  632. package/lib/rust-crypto/PerSessionKeyBackupDownloader.js +469 -0
  633. package/lib/rust-crypto/PerSessionKeyBackupDownloader.js.map +1 -0
  634. package/lib/rust-crypto/RoomEncryptor.d.ts +100 -0
  635. package/lib/rust-crypto/RoomEncryptor.d.ts.map +1 -0
  636. package/lib/rust-crypto/RoomEncryptor.js +308 -0
  637. package/lib/rust-crypto/RoomEncryptor.js.map +1 -0
  638. package/lib/rust-crypto/backup.d.ts +278 -0
  639. package/lib/rust-crypto/backup.d.ts.map +1 -0
  640. package/lib/rust-crypto/backup.js +898 -0
  641. package/lib/rust-crypto/backup.js.map +1 -0
  642. package/lib/rust-crypto/constants.d.ts +3 -0
  643. package/lib/rust-crypto/constants.d.ts.map +1 -0
  644. package/lib/rust-crypto/constants.js +19 -0
  645. package/lib/rust-crypto/constants.js.map +1 -0
  646. package/lib/rust-crypto/device-converter.d.ts +28 -0
  647. package/lib/rust-crypto/device-converter.d.ts.map +1 -0
  648. package/lib/rust-crypto/device-converter.js +123 -0
  649. package/lib/rust-crypto/device-converter.js.map +1 -0
  650. package/lib/rust-crypto/index.d.ts +65 -0
  651. package/lib/rust-crypto/index.d.ts.map +1 -0
  652. package/lib/rust-crypto/index.js +149 -0
  653. package/lib/rust-crypto/index.js.map +1 -0
  654. package/lib/rust-crypto/libolm_migration.d.ts +81 -0
  655. package/lib/rust-crypto/libolm_migration.d.ts.map +1 -0
  656. package/lib/rust-crypto/libolm_migration.js +456 -0
  657. package/lib/rust-crypto/libolm_migration.js.map +1 -0
  658. package/lib/rust-crypto/rust-crypto.d.ts +576 -0
  659. package/lib/rust-crypto/rust-crypto.d.ts.map +1 -0
  660. package/lib/rust-crypto/rust-crypto.js +2324 -0
  661. package/lib/rust-crypto/rust-crypto.js.map +1 -0
  662. package/lib/rust-crypto/secret-storage.d.ts +22 -0
  663. package/lib/rust-crypto/secret-storage.d.ts.map +1 -0
  664. package/lib/rust-crypto/secret-storage.js +63 -0
  665. package/lib/rust-crypto/secret-storage.js.map +1 -0
  666. package/lib/rust-crypto/verification.d.ts +321 -0
  667. package/lib/rust-crypto/verification.d.ts.map +1 -0
  668. package/lib/rust-crypto/verification.js +817 -0
  669. package/lib/rust-crypto/verification.js.map +1 -0
  670. package/lib/scheduler.d.ts +132 -0
  671. package/lib/scheduler.d.ts.map +1 -0
  672. package/lib/scheduler.js +259 -0
  673. package/lib/scheduler.js.map +1 -0
  674. package/lib/secret-storage.d.ts +383 -0
  675. package/lib/secret-storage.d.ts.map +1 -0
  676. package/lib/secret-storage.js +487 -0
  677. package/lib/secret-storage.js.map +1 -0
  678. package/lib/serverCapabilities.d.ts +78 -0
  679. package/lib/serverCapabilities.d.ts.map +1 -0
  680. package/lib/serverCapabilities.js +104 -0
  681. package/lib/serverCapabilities.js.map +1 -0
  682. package/lib/service-types.d.ts +5 -0
  683. package/lib/service-types.d.ts.map +1 -0
  684. package/lib/service-types.js +23 -0
  685. package/lib/service-types.js.map +1 -0
  686. package/lib/sliding-sync-sdk.d.ts +107 -0
  687. package/lib/sliding-sync-sdk.d.ts.map +1 -0
  688. package/lib/sliding-sync-sdk.js +892 -0
  689. package/lib/sliding-sync-sdk.js.map +1 -0
  690. package/lib/sliding-sync.d.ts +306 -0
  691. package/lib/sliding-sync.d.ts.map +1 -0
  692. package/lib/sliding-sync.js +585 -0
  693. package/lib/sliding-sync.js.map +1 -0
  694. package/lib/store/index.d.ts +201 -0
  695. package/lib/store/index.d.ts.map +1 -0
  696. package/lib/store/index.js +1 -0
  697. package/lib/store/index.js.map +1 -0
  698. package/lib/store/indexeddb-backend.d.ts +24 -0
  699. package/lib/store/indexeddb-backend.d.ts.map +1 -0
  700. package/lib/store/indexeddb-backend.js +1 -0
  701. package/lib/store/indexeddb-backend.js.map +1 -0
  702. package/lib/store/indexeddb-local-backend.d.ts +129 -0
  703. package/lib/store/indexeddb-local-backend.d.ts.map +1 -0
  704. package/lib/store/indexeddb-local-backend.js +599 -0
  705. package/lib/store/indexeddb-local-backend.js.map +1 -0
  706. package/lib/store/indexeddb-remote-backend.d.ts +79 -0
  707. package/lib/store/indexeddb-remote-backend.d.ts.map +1 -0
  708. package/lib/store/indexeddb-remote-backend.js +209 -0
  709. package/lib/store/indexeddb-remote-backend.js.map +1 -0
  710. package/lib/store/indexeddb-store-worker.d.ts +35 -0
  711. package/lib/store/indexeddb-store-worker.d.ts.map +1 -0
  712. package/lib/store/indexeddb-store-worker.js +146 -0
  713. package/lib/store/indexeddb-store-worker.js.map +1 -0
  714. package/lib/store/indexeddb.d.ts +142 -0
  715. package/lib/store/indexeddb.d.ts.map +1 -0
  716. package/lib/store/indexeddb.js +347 -0
  717. package/lib/store/indexeddb.js.map +1 -0
  718. package/lib/store/local-storage-events-emitter.d.ts +30 -0
  719. package/lib/store/local-storage-events-emitter.d.ts.map +1 -0
  720. package/lib/store/local-storage-events-emitter.js +37 -0
  721. package/lib/store/local-storage-events-emitter.js.map +1 -0
  722. package/lib/store/memory.d.ts +209 -0
  723. package/lib/store/memory.d.ts.map +1 -0
  724. package/lib/store/memory.js +432 -0
  725. package/lib/store/memory.js.map +1 -0
  726. package/lib/store/stub.d.ts +161 -0
  727. package/lib/store/stub.d.ts.map +1 -0
  728. package/lib/store/stub.js +268 -0
  729. package/lib/store/stub.js.map +1 -0
  730. package/lib/sync-accumulator.d.ts +207 -0
  731. package/lib/sync-accumulator.d.ts.map +1 -0
  732. package/lib/sync-accumulator.js +588 -0
  733. package/lib/sync-accumulator.js.map +1 -0
  734. package/lib/sync.d.ts +273 -0
  735. package/lib/sync.d.ts.map +1 -0
  736. package/lib/sync.js +1764 -0
  737. package/lib/sync.js.map +1 -0
  738. package/lib/testing.d.ts +98 -0
  739. package/lib/testing.d.ts.map +1 -0
  740. package/lib/testing.js +205 -0
  741. package/lib/testing.js.map +1 -0
  742. package/lib/thread-utils.d.ts +10 -0
  743. package/lib/thread-utils.d.ts.map +1 -0
  744. package/lib/thread-utils.js +31 -0
  745. package/lib/thread-utils.js.map +1 -0
  746. package/lib/timeline-window.d.ts +168 -0
  747. package/lib/timeline-window.d.ts.map +1 -0
  748. package/lib/timeline-window.js +494 -0
  749. package/lib/timeline-window.js.map +1 -0
  750. package/lib/types.d.ts +33 -0
  751. package/lib/types.d.ts.map +1 -0
  752. package/lib/types.js +52 -0
  753. package/lib/types.js.map +1 -0
  754. package/lib/utils/decryptAESSecretStorageItem.d.ts +12 -0
  755. package/lib/utils/decryptAESSecretStorageItem.d.ts.map +1 -0
  756. package/lib/utils/decryptAESSecretStorageItem.js +50 -0
  757. package/lib/utils/decryptAESSecretStorageItem.js.map +1 -0
  758. package/lib/utils/encryptAESSecretStorageItem.d.ts +16 -0
  759. package/lib/utils/encryptAESSecretStorageItem.d.ts.map +1 -0
  760. package/lib/utils/encryptAESSecretStorageItem.js +68 -0
  761. package/lib/utils/encryptAESSecretStorageItem.js.map +1 -0
  762. package/lib/utils/internal/deriveKeys.d.ts +10 -0
  763. package/lib/utils/internal/deriveKeys.d.ts.map +1 -0
  764. package/lib/utils/internal/deriveKeys.js +60 -0
  765. package/lib/utils/internal/deriveKeys.js.map +1 -0
  766. package/lib/utils/roomVersion.d.ts +13 -0
  767. package/lib/utils/roomVersion.d.ts.map +1 -0
  768. package/lib/utils/roomVersion.js +36 -0
  769. package/lib/utils/roomVersion.js.map +1 -0
  770. package/lib/utils.d.ts +270 -0
  771. package/lib/utils.d.ts.map +1 -0
  772. package/lib/utils.js +764 -0
  773. package/lib/utils.js.map +1 -0
  774. package/lib/version-support.d.ts +19 -0
  775. package/lib/version-support.d.ts.map +1 -0
  776. package/lib/version-support.js +37 -0
  777. package/lib/version-support.js.map +1 -0
  778. package/lib/webrtc/audioContext.d.ts +15 -0
  779. package/lib/webrtc/audioContext.d.ts.map +1 -0
  780. package/lib/webrtc/audioContext.js +46 -0
  781. package/lib/webrtc/audioContext.js.map +1 -0
  782. package/lib/webrtc/call.d.ts +560 -0
  783. package/lib/webrtc/call.d.ts.map +1 -0
  784. package/lib/webrtc/call.js +2596 -0
  785. package/lib/webrtc/call.js.map +1 -0
  786. package/lib/webrtc/callEventHandler.d.ts +37 -0
  787. package/lib/webrtc/callEventHandler.d.ts.map +1 -0
  788. package/lib/webrtc/callEventHandler.js +344 -0
  789. package/lib/webrtc/callEventHandler.js.map +1 -0
  790. package/lib/webrtc/callEventTypes.d.ts +79 -0
  791. package/lib/webrtc/callEventTypes.d.ts.map +1 -0
  792. package/lib/webrtc/callEventTypes.js +13 -0
  793. package/lib/webrtc/callEventTypes.js.map +1 -0
  794. package/lib/webrtc/callFeed.d.ts +128 -0
  795. package/lib/webrtc/callFeed.d.ts.map +1 -0
  796. package/lib/webrtc/callFeed.js +289 -0
  797. package/lib/webrtc/callFeed.js.map +1 -0
  798. package/lib/webrtc/groupCall.d.ts +319 -0
  799. package/lib/webrtc/groupCall.d.ts.map +1 -0
  800. package/lib/webrtc/groupCall.js +1334 -0
  801. package/lib/webrtc/groupCall.js.map +1 -0
  802. package/lib/webrtc/groupCallEventHandler.d.ts +31 -0
  803. package/lib/webrtc/groupCallEventHandler.d.ts.map +1 -0
  804. package/lib/webrtc/groupCallEventHandler.js +178 -0
  805. package/lib/webrtc/groupCallEventHandler.js.map +1 -0
  806. package/lib/webrtc/mediaHandler.d.ts +89 -0
  807. package/lib/webrtc/mediaHandler.d.ts.map +1 -0
  808. package/lib/webrtc/mediaHandler.js +454 -0
  809. package/lib/webrtc/mediaHandler.js.map +1 -0
  810. package/lib/webrtc/stats/callFeedStatsReporter.d.ts +8 -0
  811. package/lib/webrtc/stats/callFeedStatsReporter.d.ts.map +1 -0
  812. package/lib/webrtc/stats/callFeedStatsReporter.js +79 -0
  813. package/lib/webrtc/stats/callFeedStatsReporter.js.map +1 -0
  814. package/lib/webrtc/stats/callStatsReportGatherer.d.ts +25 -0
  815. package/lib/webrtc/stats/callStatsReportGatherer.d.ts.map +1 -0
  816. package/lib/webrtc/stats/callStatsReportGatherer.js +199 -0
  817. package/lib/webrtc/stats/callStatsReportGatherer.js.map +1 -0
  818. package/lib/webrtc/stats/callStatsReportSummary.d.ts +17 -0
  819. package/lib/webrtc/stats/callStatsReportSummary.d.ts.map +1 -0
  820. package/lib/webrtc/stats/callStatsReportSummary.js +1 -0
  821. package/lib/webrtc/stats/callStatsReportSummary.js.map +1 -0
  822. package/lib/webrtc/stats/connectionStats.d.ts +28 -0
  823. package/lib/webrtc/stats/connectionStats.d.ts.map +1 -0
  824. package/lib/webrtc/stats/connectionStats.js +26 -0
  825. package/lib/webrtc/stats/connectionStats.js.map +1 -0
  826. package/lib/webrtc/stats/connectionStatsBuilder.d.ts +5 -0
  827. package/lib/webrtc/stats/connectionStatsBuilder.d.ts.map +1 -0
  828. package/lib/webrtc/stats/connectionStatsBuilder.js +27 -0
  829. package/lib/webrtc/stats/connectionStatsBuilder.js.map +1 -0
  830. package/lib/webrtc/stats/connectionStatsReportBuilder.d.ts +7 -0
  831. package/lib/webrtc/stats/connectionStatsReportBuilder.d.ts.map +1 -0
  832. package/lib/webrtc/stats/connectionStatsReportBuilder.js +121 -0
  833. package/lib/webrtc/stats/connectionStatsReportBuilder.js.map +1 -0
  834. package/lib/webrtc/stats/groupCallStats.d.ts +22 -0
  835. package/lib/webrtc/stats/groupCallStats.d.ts.map +1 -0
  836. package/lib/webrtc/stats/groupCallStats.js +78 -0
  837. package/lib/webrtc/stats/groupCallStats.js.map +1 -0
  838. package/lib/webrtc/stats/media/mediaSsrcHandler.d.ts +10 -0
  839. package/lib/webrtc/stats/media/mediaSsrcHandler.d.ts.map +1 -0
  840. package/lib/webrtc/stats/media/mediaSsrcHandler.js +57 -0
  841. package/lib/webrtc/stats/media/mediaSsrcHandler.js.map +1 -0
  842. package/lib/webrtc/stats/media/mediaTrackHandler.d.ts +12 -0
  843. package/lib/webrtc/stats/media/mediaTrackHandler.d.ts.map +1 -0
  844. package/lib/webrtc/stats/media/mediaTrackHandler.js +58 -0
  845. package/lib/webrtc/stats/media/mediaTrackHandler.js.map +1 -0
  846. package/lib/webrtc/stats/media/mediaTrackStats.d.ts +86 -0
  847. package/lib/webrtc/stats/media/mediaTrackStats.d.ts.map +1 -0
  848. package/lib/webrtc/stats/media/mediaTrackStats.js +142 -0
  849. package/lib/webrtc/stats/media/mediaTrackStats.js.map +1 -0
  850. package/lib/webrtc/stats/media/mediaTrackStatsHandler.d.ts +22 -0
  851. package/lib/webrtc/stats/media/mediaTrackStatsHandler.d.ts.map +1 -0
  852. package/lib/webrtc/stats/media/mediaTrackStatsHandler.js +76 -0
  853. package/lib/webrtc/stats/media/mediaTrackStatsHandler.js.map +1 -0
  854. package/lib/webrtc/stats/statsReport.d.ts +99 -0
  855. package/lib/webrtc/stats/statsReport.d.ts.map +1 -0
  856. package/lib/webrtc/stats/statsReport.js +32 -0
  857. package/lib/webrtc/stats/statsReport.js.map +1 -0
  858. package/lib/webrtc/stats/statsReportEmitter.d.ts +15 -0
  859. package/lib/webrtc/stats/statsReportEmitter.d.ts.map +1 -0
  860. package/lib/webrtc/stats/statsReportEmitter.js +33 -0
  861. package/lib/webrtc/stats/statsReportEmitter.js.map +1 -0
  862. package/lib/webrtc/stats/summaryStatsReportGatherer.d.ts +16 -0
  863. package/lib/webrtc/stats/summaryStatsReportGatherer.d.ts.map +1 -0
  864. package/lib/webrtc/stats/summaryStatsReportGatherer.js +116 -0
  865. package/lib/webrtc/stats/summaryStatsReportGatherer.js.map +1 -0
  866. package/lib/webrtc/stats/trackStatsBuilder.d.ts +19 -0
  867. package/lib/webrtc/stats/trackStatsBuilder.d.ts.map +1 -0
  868. package/lib/webrtc/stats/trackStatsBuilder.js +168 -0
  869. package/lib/webrtc/stats/trackStatsBuilder.js.map +1 -0
  870. package/lib/webrtc/stats/transportStats.d.ts +11 -0
  871. package/lib/webrtc/stats/transportStats.d.ts.map +1 -0
  872. package/lib/webrtc/stats/transportStats.js +1 -0
  873. package/lib/webrtc/stats/transportStats.js.map +1 -0
  874. package/lib/webrtc/stats/transportStatsBuilder.d.ts +5 -0
  875. package/lib/webrtc/stats/transportStatsBuilder.d.ts.map +1 -0
  876. package/lib/webrtc/stats/transportStatsBuilder.js +34 -0
  877. package/lib/webrtc/stats/transportStatsBuilder.js.map +1 -0
  878. package/lib/webrtc/stats/valueFormatter.d.ts +4 -0
  879. package/lib/webrtc/stats/valueFormatter.d.ts.map +1 -0
  880. package/lib/webrtc/stats/valueFormatter.js +25 -0
  881. package/lib/webrtc/stats/valueFormatter.js.map +1 -0
  882. package/package.json +129 -0
  883. package/src/@types/AESEncryptedSecretStoragePayload.ts +29 -0
  884. package/src/@types/IIdentityServerProvider.ts +24 -0
  885. package/src/@types/PushRules.ts +208 -0
  886. package/src/@types/another-json.d.ts +19 -0
  887. package/src/@types/auth.ts +258 -0
  888. package/src/@types/beacon.ts +140 -0
  889. package/src/@types/common.ts +24 -0
  890. package/src/@types/crypto.ts +71 -0
  891. package/src/@types/event.ts +449 -0
  892. package/src/@types/events.ts +119 -0
  893. package/src/@types/extensible_events.ts +147 -0
  894. package/src/@types/global.d.ts +67 -0
  895. package/src/@types/local_notifications.ts +19 -0
  896. package/src/@types/location.ts +92 -0
  897. package/src/@types/matrix-sdk-crypto-wasm.d.ts +39 -0
  898. package/src/@types/media.ts +245 -0
  899. package/src/@types/membership.ts +57 -0
  900. package/src/@types/partials.ts +103 -0
  901. package/src/@types/polls.ts +120 -0
  902. package/src/@types/read_receipts.ts +61 -0
  903. package/src/@types/registration.ts +102 -0
  904. package/src/@types/requests.ts +346 -0
  905. package/src/@types/search.ts +119 -0
  906. package/src/@types/signed.ts +25 -0
  907. package/src/@types/spaces.ts +37 -0
  908. package/src/@types/state_events.ts +153 -0
  909. package/src/@types/synapse.ts +40 -0
  910. package/src/@types/sync.ts +27 -0
  911. package/src/@types/threepids.ts +29 -0
  912. package/src/@types/topic.ts +69 -0
  913. package/src/@types/uia.ts +24 -0
  914. package/src/NamespacedValue.ts +121 -0
  915. package/src/ReEmitter.ts +93 -0
  916. package/src/ToDeviceMessageQueue.ts +156 -0
  917. package/src/autodiscovery.ts +505 -0
  918. package/src/base64.ts +86 -0
  919. package/src/briij.ts +173 -0
  920. package/src/browser-index.ts +44 -0
  921. package/src/client.ts +9031 -0
  922. package/src/common-crypto/CryptoBackend.ts +295 -0
  923. package/src/common-crypto/README.md +4 -0
  924. package/src/common-crypto/key-passphrase.ts +43 -0
  925. package/src/content-helpers.ts +298 -0
  926. package/src/content-repo.ts +122 -0
  927. package/src/crypto/store/base.ts +388 -0
  928. package/src/crypto/store/indexeddb-crypto-store-backend.ts +655 -0
  929. package/src/crypto/store/indexeddb-crypto-store.ts +555 -0
  930. package/src/crypto/store/localStorage-crypto-store.ts +409 -0
  931. package/src/crypto/store/memory-crypto-store.ts +326 -0
  932. package/src/crypto-api/CryptoEvent.ts +152 -0
  933. package/src/crypto-api/CryptoEventHandlerMap.ts +42 -0
  934. package/src/crypto-api/index.ts +1362 -0
  935. package/src/crypto-api/key-passphrase.ts +58 -0
  936. package/src/crypto-api/keybackup.ts +114 -0
  937. package/src/crypto-api/recovery-key.ts +69 -0
  938. package/src/crypto-api/verification.ts +382 -0
  939. package/src/digest.ts +34 -0
  940. package/src/embedded.ts +865 -0
  941. package/src/errors.ts +87 -0
  942. package/src/event-mapper.ts +88 -0
  943. package/src/extensible_events_v1/ExtensibleEvent.ts +58 -0
  944. package/src/extensible_events_v1/InvalidEventError.ts +24 -0
  945. package/src/extensible_events_v1/MessageEvent.ts +143 -0
  946. package/src/extensible_events_v1/PollEndEvent.ts +97 -0
  947. package/src/extensible_events_v1/PollResponseEvent.ts +148 -0
  948. package/src/extensible_events_v1/PollStartEvent.ts +207 -0
  949. package/src/extensible_events_v1/utilities.ts +35 -0
  950. package/src/feature.ts +88 -0
  951. package/src/filter-component.ts +209 -0
  952. package/src/filter.ts +245 -0
  953. package/src/http-api/errors.ts +261 -0
  954. package/src/http-api/fetch.ts +377 -0
  955. package/src/http-api/index.ts +194 -0
  956. package/src/http-api/interface.ts +229 -0
  957. package/src/http-api/method.ts +25 -0
  958. package/src/http-api/prefix.ts +48 -0
  959. package/src/http-api/refresh.ts +167 -0
  960. package/src/http-api/utils.ts +217 -0
  961. package/src/index.ts +25 -0
  962. package/src/indexeddb-helpers.ts +50 -0
  963. package/src/indexeddb-worker.ts +24 -0
  964. package/src/interactive-auth.ts +700 -0
  965. package/src/logger.ts +279 -0
  966. package/src/matrixrtc/CallMembership.ts +438 -0
  967. package/src/matrixrtc/EncryptionManager.ts +54 -0
  968. package/src/matrixrtc/IKeyTransport.ts +63 -0
  969. package/src/matrixrtc/IMembershipManager.ts +120 -0
  970. package/src/matrixrtc/LivekitTransport.ts +46 -0
  971. package/src/matrixrtc/MatrixRTCSession.ts +934 -0
  972. package/src/matrixrtc/MatrixRTCSessionManager.ts +170 -0
  973. package/src/matrixrtc/MembershipManager.ts +1122 -0
  974. package/src/matrixrtc/MembershipManagerActionScheduler.ts +135 -0
  975. package/src/matrixrtc/RTCEncryptionManager.ts +459 -0
  976. package/src/matrixrtc/ToDeviceKeyTransport.ts +197 -0
  977. package/src/matrixrtc/index.ts +24 -0
  978. package/src/matrixrtc/membershipData/common.ts +27 -0
  979. package/src/matrixrtc/membershipData/index.ts +19 -0
  980. package/src/matrixrtc/membershipData/rtc.ts +156 -0
  981. package/src/matrixrtc/membershipData/session.ts +146 -0
  982. package/src/matrixrtc/types.ts +227 -0
  983. package/src/matrixrtc/utils.ts +71 -0
  984. package/src/models/MSC3089Branch.ts +272 -0
  985. package/src/models/MSC3089TreeSpace.ts +565 -0
  986. package/src/models/ToDeviceMessage.ts +38 -0
  987. package/src/models/beacon.ts +213 -0
  988. package/src/models/compare-event-ordering.ts +139 -0
  989. package/src/models/device.ts +85 -0
  990. package/src/models/event-context.ts +110 -0
  991. package/src/models/event-status.ts +39 -0
  992. package/src/models/event-timeline-set.ts +962 -0
  993. package/src/models/event-timeline.ts +461 -0
  994. package/src/models/event.ts +1819 -0
  995. package/src/models/invites-ignorer-types.ts +58 -0
  996. package/src/models/invites-ignorer.ts +341 -0
  997. package/src/models/poll.ts +285 -0
  998. package/src/models/profile-keys.ts +33 -0
  999. package/src/models/read-receipt.ts +422 -0
  1000. package/src/models/related-relations.ts +39 -0
  1001. package/src/models/relations-container.ts +149 -0
  1002. package/src/models/relations.ts +392 -0
  1003. package/src/models/room-member.ts +486 -0
  1004. package/src/models/room-receipts.ts +439 -0
  1005. package/src/models/room-state.ts +1230 -0
  1006. package/src/models/room-sticky-events.ts +383 -0
  1007. package/src/models/room-summary.ts +78 -0
  1008. package/src/models/room.ts +4067 -0
  1009. package/src/models/search-result.ts +57 -0
  1010. package/src/models/thread.ts +928 -0
  1011. package/src/models/typed-event-emitter.ts +246 -0
  1012. package/src/models/user.ts +302 -0
  1013. package/src/oidc/authorize.ts +279 -0
  1014. package/src/oidc/discovery.ts +67 -0
  1015. package/src/oidc/error.ts +33 -0
  1016. package/src/oidc/index.ts +33 -0
  1017. package/src/oidc/register.ts +163 -0
  1018. package/src/oidc/tokenRefresher.ts +184 -0
  1019. package/src/oidc/validate.ts +265 -0
  1020. package/src/pushprocessor.ts +856 -0
  1021. package/src/randomstring.ts +103 -0
  1022. package/src/realtime-callbacks.ts +191 -0
  1023. package/src/receipt-accumulator.ts +189 -0
  1024. package/src/rendezvous/MSC4108SignInWithQR.ts +443 -0
  1025. package/src/rendezvous/RendezvousChannel.ts +48 -0
  1026. package/src/rendezvous/RendezvousCode.ts +25 -0
  1027. package/src/rendezvous/RendezvousError.ts +26 -0
  1028. package/src/rendezvous/RendezvousFailureReason.ts +49 -0
  1029. package/src/rendezvous/RendezvousIntent.ts +20 -0
  1030. package/src/rendezvous/RendezvousTransport.ts +58 -0
  1031. package/src/rendezvous/channels/MSC4108SecureChannel.ts +270 -0
  1032. package/src/rendezvous/channels/index.ts +17 -0
  1033. package/src/rendezvous/index.ts +25 -0
  1034. package/src/rendezvous/transports/MSC4108RendezvousSession.ts +272 -0
  1035. package/src/rendezvous/transports/index.ts +17 -0
  1036. package/src/room-hierarchy.ts +152 -0
  1037. package/src/rust-crypto/CrossSigningIdentity.ts +195 -0
  1038. package/src/rust-crypto/DehydratedDeviceManager.ts +392 -0
  1039. package/src/rust-crypto/KeyClaimManager.ts +86 -0
  1040. package/src/rust-crypto/OutgoingRequestProcessor.ts +233 -0
  1041. package/src/rust-crypto/OutgoingRequestsManager.ts +170 -0
  1042. package/src/rust-crypto/PerSessionKeyBackupDownloader.ts +501 -0
  1043. package/src/rust-crypto/RoomEncryptor.ts +362 -0
  1044. package/src/rust-crypto/backup.ts +942 -0
  1045. package/src/rust-crypto/constants.ts +18 -0
  1046. package/src/rust-crypto/device-converter.ts +128 -0
  1047. package/src/rust-crypto/index.ts +251 -0
  1048. package/src/rust-crypto/libolm_migration.ts +532 -0
  1049. package/src/rust-crypto/rust-crypto.ts +2542 -0
  1050. package/src/rust-crypto/secret-storage.ts +60 -0
  1051. package/src/rust-crypto/verification.ts +833 -0
  1052. package/src/scheduler.ts +309 -0
  1053. package/src/secret-storage.ts +714 -0
  1054. package/src/serverCapabilities.ts +146 -0
  1055. package/src/service-types.ts +20 -0
  1056. package/src/sliding-sync-sdk.ts +1005 -0
  1057. package/src/sliding-sync.ts +674 -0
  1058. package/src/store/index.ts +261 -0
  1059. package/src/store/indexeddb-backend.ts +41 -0
  1060. package/src/store/indexeddb-local-backend.ts +610 -0
  1061. package/src/store/indexeddb-remote-backend.ts +212 -0
  1062. package/src/store/indexeddb-store-worker.ts +157 -0
  1063. package/src/store/indexeddb.ts +397 -0
  1064. package/src/store/local-storage-events-emitter.ts +46 -0
  1065. package/src/store/memory.ts +448 -0
  1066. package/src/store/stub.ts +280 -0
  1067. package/src/sync-accumulator.ts +779 -0
  1068. package/src/sync.ts +2020 -0
  1069. package/src/testing.ts +231 -0
  1070. package/src/thread-utils.ts +31 -0
  1071. package/src/timeline-window.ts +534 -0
  1072. package/src/types.ts +59 -0
  1073. package/src/utils/decryptAESSecretStorageItem.ts +54 -0
  1074. package/src/utils/encryptAESSecretStorageItem.ts +73 -0
  1075. package/src/utils/internal/deriveKeys.ts +63 -0
  1076. package/src/utils/roomVersion.ts +35 -0
  1077. package/src/utils.ts +775 -0
  1078. package/src/version-support.ts +50 -0
  1079. package/src/webrtc/audioContext.ts +44 -0
  1080. package/src/webrtc/call.ts +3061 -0
  1081. package/src/webrtc/callEventHandler.ts +425 -0
  1082. package/src/webrtc/callEventTypes.ts +101 -0
  1083. package/src/webrtc/callFeed.ts +364 -0
  1084. package/src/webrtc/groupCall.ts +1729 -0
  1085. package/src/webrtc/groupCallEventHandler.ts +234 -0
  1086. package/src/webrtc/mediaHandler.ts +501 -0
  1087. package/src/webrtc/stats/callFeedStatsReporter.ts +91 -0
  1088. package/src/webrtc/stats/callStatsReportGatherer.ts +219 -0
  1089. package/src/webrtc/stats/callStatsReportSummary.ts +30 -0
  1090. package/src/webrtc/stats/connectionStats.ts +47 -0
  1091. package/src/webrtc/stats/connectionStatsBuilder.ts +28 -0
  1092. package/src/webrtc/stats/connectionStatsReportBuilder.ts +140 -0
  1093. package/src/webrtc/stats/groupCallStats.ts +93 -0
  1094. package/src/webrtc/stats/media/mediaSsrcHandler.ts +57 -0
  1095. package/src/webrtc/stats/media/mediaTrackHandler.ts +70 -0
  1096. package/src/webrtc/stats/media/mediaTrackStats.ts +176 -0
  1097. package/src/webrtc/stats/media/mediaTrackStatsHandler.ts +90 -0
  1098. package/src/webrtc/stats/statsReport.ts +133 -0
  1099. package/src/webrtc/stats/statsReportEmitter.ts +49 -0
  1100. package/src/webrtc/stats/summaryStatsReportGatherer.ts +148 -0
  1101. package/src/webrtc/stats/trackStatsBuilder.ts +207 -0
  1102. package/src/webrtc/stats/transportStats.ts +26 -0
  1103. package/src/webrtc/stats/transportStatsBuilder.ts +48 -0
  1104. package/src/webrtc/stats/valueFormatter.ts +27 -0
package/src/sync.ts ADDED
@@ -0,0 +1,2020 @@
1
+ /*
2
+ Copyright 2015 - 2023 The Matrix.org Foundation C.I.C.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ /*
18
+ * TODO:
19
+ * This class mainly serves to take all the syncing logic out of client.js and
20
+ * into a separate file. It's all very fluid, and this class gut wrenches a lot
21
+ * of BriijClient props (e.g. http). Given we want to support WebSockets as
22
+ * an alternative syncing API, we may want to have a proper syncing interface
23
+ * for HTTP and WS at some point.
24
+ */
25
+
26
+ import type { SyncCryptoCallbacks } from "./common-crypto/CryptoBackend.ts";
27
+ import { User } from "./models/user.ts";
28
+ import { NotificationCountType, Room, RoomEvent } from "./models/room.ts";
29
+ import { deepCopy, noUnsafeEventProps, unsafeProp } from "./utils.ts";
30
+ import { Filter } from "./filter.ts";
31
+ import { EventTimeline } from "./models/event-timeline.ts";
32
+ import { type Logger } from "./logger.ts";
33
+ import {
34
+ ClientEvent,
35
+ type IStoredClientOpts,
36
+ type BriijClient,
37
+ PendingEventOrdering,
38
+ type ResetTimelineCallback,
39
+ } from "./client.ts";
40
+ import {
41
+ type IEphemeral,
42
+ type IInvitedRoom,
43
+ type IInviteState,
44
+ type IJoinedRoom,
45
+ type IKnockedRoom,
46
+ type ILeftRoom,
47
+ type IMinimalEvent,
48
+ type IRoomEvent,
49
+ type IStateEvent,
50
+ type IStrippedState,
51
+ type ISyncResponse,
52
+ type ITimeline,
53
+ type IToDeviceEvent,
54
+ type ReceivedToDeviceMessage,
55
+ } from "./sync-accumulator.ts";
56
+ import { BriijEvent } from "./models/event.ts";
57
+ import { type BriijError, Method } from "./http-api/index.ts";
58
+ import { type ISavedSync } from "./store/index.ts";
59
+ import { EventType } from "./@types/event.ts";
60
+ import { type IPushRules } from "./@types/PushRules.ts";
61
+ import { type IMarkerFoundOptions, RoomStateEvent } from "./models/room-state.ts";
62
+ import { RoomMemberEvent } from "./models/room-member.ts";
63
+ import { BeaconEvent } from "./models/beacon.ts";
64
+ import { type IEventsResponse } from "./@types/requests.ts";
65
+ import { UNREAD_THREAD_NOTIFICATIONS } from "./@types/sync.ts";
66
+ import { Feature, ServerSupport } from "./feature.ts";
67
+ import { KnownMembership } from "./@types/membership.ts";
68
+
69
+ // /sync requests allow you to set a timeout= but the request may continue
70
+ // beyond that and wedge forever, so we need to track how long we are willing
71
+ // to keep open the connection. This constant is *ADDED* to the timeout= value
72
+ // to determine the max time we're willing to wait.
73
+ const BUFFER_PERIOD_MS = 80 * 1000;
74
+
75
+ // Number of consecutive failed syncs that will lead to a syncState of ERROR as opposed
76
+ // to RECONNECTING. This is needed to inform the client of server issues when the
77
+ // keepAlive is successful but the server /sync fails.
78
+ const FAILED_SYNC_ERROR_THRESHOLD = 3;
79
+
80
+ export enum SyncState {
81
+ /** Emitted after we try to sync more than `FAILED_SYNC_ERROR_THRESHOLD`
82
+ * times and are still failing. Or when we enounter a hard error like the
83
+ * token being invalid. */
84
+ Error = "ERROR",
85
+ /** Emitted after the first sync events are ready (this could even be sync
86
+ * events from the cache) */
87
+ Prepared = "PREPARED",
88
+ /** Emitted when the sync loop is no longer running */
89
+ Stopped = "STOPPED",
90
+ /** Emitted after each sync request happens */
91
+ Syncing = "SYNCING",
92
+ /** Emitted after a connectivity error and we're ready to start syncing again */
93
+ Catchup = "CATCHUP",
94
+ /** Emitted for each time we try reconnecting. Will switch to `Error` after
95
+ * we reach the `FAILED_SYNC_ERROR_THRESHOLD`
96
+ */
97
+ Reconnecting = "RECONNECTING",
98
+ }
99
+
100
+ // Room versions where "insertion", "batch", and "marker" events are controlled
101
+ // by power-levels. MSC2716 is supported in existing room versions but they
102
+ // should only have special meaning when the room creator sends them.
103
+ const MSC2716_ROOM_VERSIONS = ["org.matrix.msc2716v3"];
104
+
105
+ function getFilterName(userId: string, suffix?: string): string {
106
+ // scope this on the user ID because people may login on many accounts
107
+ // and they all need to be stored!
108
+ return `FILTER_SYNC_${userId}` + (suffix ? "_" + suffix : "");
109
+ }
110
+
111
+ /**
112
+ * Options passed into the constructor of SyncApi by BriijClient
113
+ */
114
+ export interface SyncApiOptions {
115
+ /**
116
+ * If crypto is enabled on our client, callbacks into the crypto module
117
+ */
118
+ cryptoCallbacks?: SyncCryptoCallbacks;
119
+
120
+ /**
121
+ * A function which is called
122
+ * with a room ID and returns a boolean. It should return 'true' if the SDK can
123
+ * SAFELY remove events from this room. It may not be safe to remove events if
124
+ * there are other references to the timelines for this room.
125
+ */
126
+ canResetEntireTimeline?: ResetTimelineCallback;
127
+
128
+ /** Logger instance to use for writing debug logs. */
129
+ logger: Logger;
130
+ }
131
+
132
+ interface ISyncOptions {
133
+ filter?: string;
134
+ hasSyncedBefore?: boolean;
135
+ }
136
+
137
+ export interface ISyncStateData {
138
+ /**
139
+ * The matrix error if `state=ERROR`.
140
+ */
141
+ error?: Error;
142
+ /**
143
+ * The 'since' token passed to /sync.
144
+ * `null` for the first successful sync since this client was
145
+ * started. Only present if `state=PREPARED` or
146
+ * `state=SYNCING`.
147
+ */
148
+ oldSyncToken?: string;
149
+ /**
150
+ * The 'next_batch' result from /sync, which
151
+ * will become the 'since' token for the next call to /sync. Only present if
152
+ * `state=PREPARED</code> or <code>state=SYNCING`.
153
+ */
154
+ nextSyncToken?: string;
155
+ /**
156
+ * True if we are working our way through a
157
+ * backlog of events after connecting. Only present if `state=SYNCING`.
158
+ */
159
+ catchingUp?: boolean;
160
+ fromCache?: boolean;
161
+ }
162
+
163
+ export enum SetPresence {
164
+ Offline = "offline",
165
+ Online = "online",
166
+ Unavailable = "unavailable",
167
+ }
168
+
169
+ interface ISyncParams {
170
+ "filter"?: string;
171
+ "timeout": number;
172
+ "since"?: string;
173
+ // eslint-disable-next-line camelcase
174
+ "full_state"?: boolean;
175
+ // eslint-disable-next-line camelcase
176
+ "set_presence"?: SetPresence;
177
+ "_cacheBuster"?: string | number; // not part of the API itself
178
+ "org.matrix.msc4222.use_state_after"?: boolean; // https://github.com/matrix-org/matrix-spec-proposals/pull/4222
179
+ }
180
+
181
+ type WrappedRoom<T> = T & {
182
+ room: Room;
183
+ isBrandNewRoom: boolean;
184
+ };
185
+
186
+ /** add default settings to an IStoredClientOpts */
187
+ export function defaultClientOpts(opts?: IStoredClientOpts): IStoredClientOpts {
188
+ return {
189
+ initialSyncLimit: 8,
190
+ resolveInvitesToProfiles: false,
191
+ pollTimeout: 30 * 1000,
192
+ pendingEventOrdering: PendingEventOrdering.Chronological,
193
+ threadSupport: false,
194
+ ...opts,
195
+ };
196
+ }
197
+
198
+ export function defaultSyncApiOpts(syncOpts: SyncApiOptions): SyncApiOptions {
199
+ return {
200
+ canResetEntireTimeline: (_roomId): boolean => false,
201
+ ...syncOpts,
202
+ };
203
+ }
204
+
205
+ export class SyncApi {
206
+ private readonly opts: IStoredClientOpts;
207
+ private readonly syncOpts: SyncApiOptions;
208
+
209
+ private _peekRoom: Room | null = null;
210
+ private currentSyncRequest?: Promise<ISyncResponse>;
211
+ private abortController?: AbortController;
212
+ private syncState: SyncState | null = null;
213
+ private syncStateData?: ISyncStateData; // additional data (eg. error object for failed sync)
214
+ private catchingUp = false;
215
+ private running = false;
216
+ private keepAliveTimer?: ReturnType<typeof setTimeout>;
217
+ private connectionReturnedResolvers?: PromiseWithResolvers<boolean>;
218
+ private notifEvents: BriijEvent[] = []; // accumulator of sync events in the current sync response
219
+ private failedSyncCount = 0; // Number of consecutive failed /sync requests
220
+ private storeIsInvalid = false; // flag set if the store needs to be cleared before we can start
221
+ private presence?: SetPresence;
222
+
223
+ /**
224
+ * Construct an entity which is able to sync with a homeserver.
225
+ * @param client - The matrix client instance to use.
226
+ * @param opts - client config options
227
+ * @param syncOpts - sync-specific options passed by the client
228
+ * @internal
229
+ */
230
+ public constructor(
231
+ private readonly client: BriijClient,
232
+ opts: IStoredClientOpts | undefined,
233
+ syncOpts: SyncApiOptions,
234
+ ) {
235
+ this.opts = defaultClientOpts(opts);
236
+ this.syncOpts = defaultSyncApiOpts(syncOpts);
237
+
238
+ if (client.getNotifTimelineSet()) {
239
+ client.reEmitter.reEmit(client.getNotifTimelineSet()!, [RoomEvent.Timeline, RoomEvent.TimelineReset]);
240
+ }
241
+ }
242
+
243
+ public createRoom(roomId: string): Room {
244
+ const room = _createAndReEmitRoom(this.client, roomId, this.opts);
245
+
246
+ room.on(RoomStateEvent.Marker, (markerEvent, markerFoundOptions) => {
247
+ this.onMarkerStateEvent(room, markerEvent, markerFoundOptions);
248
+ });
249
+
250
+ return room;
251
+ }
252
+
253
+ /** When we see the marker state change in the room, we know there is some
254
+ * new historical messages imported by MSC2716 `/batch_send` somewhere in
255
+ * the room and we need to throw away the timeline to make sure the
256
+ * historical messages are shown when we paginate `/messages` again.
257
+ * @param room - The room where the marker event was sent
258
+ * @param markerEvent - The new marker event
259
+ * @param setStateOptions - When `timelineWasEmpty` is set
260
+ * as `true`, the given marker event will be ignored
261
+ */
262
+ private onMarkerStateEvent(
263
+ room: Room,
264
+ markerEvent: BriijEvent,
265
+ { timelineWasEmpty }: IMarkerFoundOptions = {},
266
+ ): void {
267
+ // We don't need to refresh the timeline if it was empty before the
268
+ // marker arrived. This could be happen in a variety of cases:
269
+ // 1. From the initial sync
270
+ // 2. If it's from the first state we're seeing after joining the room
271
+ // 3. Or whether it's coming from `syncFromCache`
272
+ if (timelineWasEmpty) {
273
+ this.syncOpts.logger.debug(
274
+ `MarkerState: Ignoring markerEventId=${markerEvent.getId()} in roomId=${room.roomId} ` +
275
+ `because the timeline was empty before the marker arrived which means there is nothing to refresh.`,
276
+ );
277
+ return;
278
+ }
279
+
280
+ const isValidMsc2716Event =
281
+ // Check whether the room version directly supports MSC2716, in
282
+ // which case, "marker" events are already auth'ed by
283
+ // power_levels
284
+ MSC2716_ROOM_VERSIONS.includes(room.getVersion()) ||
285
+ // MSC2716 is also supported in all existing room versions but
286
+ // special meaning should only be given to "insertion", "batch",
287
+ // and "marker" events when they come from the room creator
288
+ markerEvent.getSender() === room.getCreator();
289
+
290
+ // It would be nice if we could also specifically tell whether the
291
+ // historical messages actually affected the locally cached client
292
+ // timeline or not. The problem is we can't see the prev_events of
293
+ // the base insertion event that the marker was pointing to because
294
+ // prev_events aren't available in the client API's. In most cases,
295
+ // the history won't be in people's locally cached timelines in the
296
+ // client, so we don't need to bother everyone about refreshing
297
+ // their timeline. This works for a v1 though and there are use
298
+ // cases like initially bootstrapping your bridged room where people
299
+ // are likely to encounter the historical messages affecting their
300
+ // current timeline (think someone signing up for Beeper and
301
+ // importing their Whatsapp history).
302
+ if (isValidMsc2716Event) {
303
+ // Saw new marker event, let's let the clients know they should
304
+ // refresh the timeline.
305
+ this.syncOpts.logger.debug(
306
+ `MarkerState: Timeline needs to be refreshed because ` +
307
+ `a new markerEventId=${markerEvent.getId()} was sent in roomId=${room.roomId}`,
308
+ );
309
+ room.setTimelineNeedsRefresh(true);
310
+ room.emit(RoomEvent.HistoryImportedWithinTimeline, markerEvent, room);
311
+ } else {
312
+ this.syncOpts.logger.debug(
313
+ `MarkerState: Ignoring markerEventId=${markerEvent.getId()} in roomId=${room.roomId} because ` +
314
+ `MSC2716 is not supported in the room version or for any room version, the marker wasn't sent ` +
315
+ `by the room creator.`,
316
+ );
317
+ }
318
+ }
319
+
320
+ /**
321
+ * Sync rooms the user has left.
322
+ * @returns Resolved when they've been added to the store.
323
+ */
324
+ public async syncLeftRooms(): Promise<Room[]> {
325
+ const client = this.client;
326
+
327
+ // grab a filter with limit=1 and include_leave=true
328
+ const filter = new Filter(this.client.credentials.userId);
329
+ filter.setTimelineLimit(1);
330
+ filter.setIncludeLeaveRooms(true);
331
+
332
+ const localTimeoutMs = this.opts.pollTimeout! + BUFFER_PERIOD_MS;
333
+
334
+ const filterId = await client.getOrCreateFilter(
335
+ getFilterName(client.credentials.userId!, "LEFT_ROOMS"),
336
+ filter,
337
+ );
338
+
339
+ const qps: ISyncParams = {
340
+ "timeout": 0, // don't want to block since this is a single isolated req
341
+ "filter": filterId,
342
+ "org.matrix.msc4222.use_state_after": true,
343
+ };
344
+
345
+ const data = await client.http.authedRequest<ISyncResponse>(Method.Get, "/sync", qps as any, undefined, {
346
+ localTimeoutMs,
347
+ });
348
+
349
+ let leaveRooms: WrappedRoom<ILeftRoom>[] = [];
350
+ if (data.rooms?.leave) {
351
+ leaveRooms = this.mapSyncResponseToRoomArray(data.rooms.leave);
352
+ }
353
+
354
+ const rooms = await Promise.all(
355
+ leaveRooms.map(async (leaveObj) => {
356
+ const room = leaveObj.room;
357
+ if (!leaveObj.isBrandNewRoom) {
358
+ // the intention behind syncLeftRooms is to add in rooms which were
359
+ // *omitted* from the initial /sync. Rooms the user were joined to
360
+ // but then left whilst the app is running will appear in this list
361
+ // and we do not want to bother with them since they will have the
362
+ // current state already (and may get dupe messages if we add
363
+ // yet more timeline events!), so skip them.
364
+ // NB: When we persist rooms to localStorage this will be more
365
+ // complicated...
366
+ return;
367
+ }
368
+ leaveObj.timeline = leaveObj.timeline || {
369
+ prev_batch: null,
370
+ events: [],
371
+ };
372
+
373
+ // set the back-pagination token. Do this *before* adding any
374
+ // events so that clients can start back-paginating.
375
+ room.getLiveTimeline().setPaginationToken(leaveObj.timeline.prev_batch, EventTimeline.BACKWARDS);
376
+
377
+ const { timelineEvents } = await this.mapAndInjectRoomEvents(leaveObj);
378
+
379
+ room.recalculate();
380
+ client.store.storeRoom(room);
381
+ client.emit(ClientEvent.Room, room);
382
+
383
+ this.processEventsForNotifs(room, timelineEvents);
384
+ return room;
385
+ }),
386
+ );
387
+
388
+ return rooms.filter(Boolean) as Room[];
389
+ }
390
+
391
+ /**
392
+ * Peek into a room. This will result in the room in question being synced so it
393
+ * is accessible via getRooms(). Live updates for the room will be provided.
394
+ * @param roomId - The room ID to peek into.
395
+ * @param limit - The number of timeline events to initially retrieve.
396
+ * @returns A promise which resolves once the room has been added to the
397
+ * store.
398
+ */
399
+ public peek(roomId: string, limit: number = 20): Promise<Room> {
400
+ if (this._peekRoom?.roomId === roomId) {
401
+ return Promise.resolve(this._peekRoom);
402
+ }
403
+
404
+ const client = this.client;
405
+ this._peekRoom = this.createRoom(roomId);
406
+ return this.client.roomInitialSync(roomId, limit).then((response) => {
407
+ if (this._peekRoom?.roomId !== roomId) {
408
+ throw new Error("Peeking aborted");
409
+ }
410
+
411
+ // make sure things are init'd
412
+ response.messages = response.messages || { chunk: [] };
413
+ response.messages.chunk = response.messages.chunk || [];
414
+ response.state = response.state || [];
415
+
416
+ // FIXME: Mostly duplicated from injectRoomEvents but not entirely
417
+ // because "state" in this API is at the BEGINNING of the chunk
418
+ const oldStateEvents = deepCopy(response.state).map(client.getEventMapper());
419
+ const stateEvents = response.state.map(client.getEventMapper());
420
+ const messages = response.messages.chunk.map(client.getEventMapper());
421
+
422
+ // XXX: copypasted from /sync until we kill off this minging v1 API stuff)
423
+ // handle presence events (User objects)
424
+ if (Array.isArray(response.presence)) {
425
+ response.presence.map(client.getEventMapper()).forEach(function (presenceEvent) {
426
+ let user = client.store.getUser(presenceEvent.getContent().user_id);
427
+ if (user) {
428
+ user.setPresenceEvent(presenceEvent);
429
+ } else {
430
+ user = User.createUser(presenceEvent.getContent().user_id, client);
431
+ user.setPresenceEvent(presenceEvent);
432
+ client.store.storeUser(user);
433
+ }
434
+ client.emit(ClientEvent.Event, presenceEvent);
435
+ });
436
+ }
437
+
438
+ // set the pagination token before adding the events in case people
439
+ // fire off pagination requests in response to the Room.timeline
440
+ // events.
441
+ if (response.messages.start) {
442
+ this._peekRoom.oldState.paginationToken = response.messages.start;
443
+ }
444
+
445
+ // set the state of the room to as it was after the timeline executes
446
+ this._peekRoom.oldState.setStateEvents(oldStateEvents);
447
+ this._peekRoom.currentState.setStateEvents(stateEvents);
448
+
449
+ this.resolveInvites(this._peekRoom);
450
+ this._peekRoom.recalculate();
451
+
452
+ // roll backwards to diverge old state. addEventsToTimeline
453
+ // will overwrite the pagination token, so make sure it overwrites
454
+ // it with the right thing.
455
+ this._peekRoom.addEventsToTimeline(
456
+ messages.reverse(),
457
+ true,
458
+ true,
459
+ this._peekRoom.getLiveTimeline(),
460
+ response.messages.start,
461
+ );
462
+
463
+ client.store.storeRoom(this._peekRoom);
464
+ client.emit(ClientEvent.Room, this._peekRoom);
465
+
466
+ this.peekPoll(this._peekRoom);
467
+ return this._peekRoom;
468
+ });
469
+ }
470
+
471
+ /**
472
+ * Stop polling for updates in the peeked room. NOPs if there is no room being
473
+ * peeked.
474
+ */
475
+ public stopPeeking(): void {
476
+ this._peekRoom = null;
477
+ }
478
+
479
+ /**
480
+ * Do a peek room poll.
481
+ * @param token - from= token
482
+ */
483
+ private peekPoll(peekRoom: Room, token?: string): void {
484
+ if (this._peekRoom !== peekRoom) {
485
+ this.syncOpts.logger.debug("Stopped peeking in room %s", peekRoom.roomId);
486
+ return;
487
+ }
488
+
489
+ // FIXME: gut wrenching; hard-coded timeout values
490
+ this.client.http
491
+ .authedRequest<IEventsResponse>(
492
+ Method.Get,
493
+ "/events",
494
+ {
495
+ room_id: peekRoom.roomId,
496
+ timeout: String(30 * 1000),
497
+ from: token,
498
+ },
499
+ undefined,
500
+ {
501
+ localTimeoutMs: 50 * 1000,
502
+ abortSignal: this.abortController?.signal,
503
+ },
504
+ )
505
+ .then(
506
+ async (res) => {
507
+ if (this._peekRoom !== peekRoom) {
508
+ this.syncOpts.logger.debug("Stopped peeking in room %s", peekRoom.roomId);
509
+ return;
510
+ }
511
+ // We have a problem that we get presence both from /events and /sync
512
+ // however, /sync only returns presence for users in rooms
513
+ // you're actually joined to.
514
+ // in order to be sure to get presence for all of the users in the
515
+ // peeked room, we handle presence explicitly here. This may result
516
+ // in duplicate presence events firing for some users, which is a
517
+ // performance drain, but such is life.
518
+ // XXX: copypasted from /sync until we can kill this minging v1 stuff.
519
+
520
+ res.chunk
521
+ .filter(function (e) {
522
+ return e.type === "m.presence";
523
+ })
524
+ .map(this.client.getEventMapper())
525
+ .forEach((presenceEvent) => {
526
+ let user = this.client.store.getUser(presenceEvent.getContent().user_id);
527
+ if (user) {
528
+ user.setPresenceEvent(presenceEvent);
529
+ } else {
530
+ user = User.createUser(presenceEvent.getContent().user_id, this.client);
531
+ user.setPresenceEvent(presenceEvent);
532
+ this.client.store.storeUser(user);
533
+ }
534
+ this.client.emit(ClientEvent.Event, presenceEvent);
535
+ });
536
+
537
+ // strip out events which aren't for the given room_id (e.g presence)
538
+ // and also ephemeral events (which we're assuming is anything without
539
+ // and event ID because the /events API doesn't separate them).
540
+ const events = res.chunk
541
+ .filter(function (e) {
542
+ return e.room_id === peekRoom.roomId && e.event_id;
543
+ })
544
+ .map(this.client.getEventMapper());
545
+
546
+ await peekRoom.addLiveEvents(events, { addToState: true });
547
+ this.peekPoll(peekRoom, res.end);
548
+ },
549
+ (err) => {
550
+ this.syncOpts.logger.error("[%s] Peek poll failed: %s", peekRoom.roomId, err);
551
+ setTimeout(() => {
552
+ this.peekPoll(peekRoom, token);
553
+ }, 30 * 1000);
554
+ },
555
+ );
556
+ }
557
+
558
+ /**
559
+ * Returns the current state of this sync object
560
+ * @see BriijClient#event:"sync"
561
+ */
562
+ public getSyncState(): SyncState | null {
563
+ return this.syncState;
564
+ }
565
+
566
+ /**
567
+ * Returns the additional data object associated with
568
+ * the current sync state, or null if there is no
569
+ * such data.
570
+ * Sync errors, if available, are put in the 'error' key of
571
+ * this object.
572
+ */
573
+ public getSyncStateData(): ISyncStateData | null {
574
+ return this.syncStateData ?? null;
575
+ }
576
+
577
+ public async recoverFromSyncStartupError(savedSyncPromise: Promise<void> | undefined, error: Error): Promise<void> {
578
+ // Wait for the saved sync to complete - we send the pushrules and filter requests
579
+ // before the saved sync has finished so they can run in parallel, but only process
580
+ // the results after the saved sync is done. Equivalently, we wait for it to finish
581
+ // before reporting failures from these functions.
582
+ await savedSyncPromise;
583
+ const keepaliveProm = this.startKeepAlives();
584
+ this.updateSyncState(SyncState.Error, { error });
585
+ await keepaliveProm;
586
+ }
587
+
588
+ private shouldAbortSync(error: BriijError): boolean {
589
+ if (error.errcode === "M_UNKNOWN_TOKEN") {
590
+ // The logout already happened, we just need to stop.
591
+ this.syncOpts.logger.warn("Token no longer valid - assuming logout");
592
+ this.stop();
593
+ this.updateSyncState(SyncState.Error, { error });
594
+ return true;
595
+ }
596
+ return false;
597
+ }
598
+
599
+ private getPushRules = async (): Promise<void> => {
600
+ try {
601
+ this.syncOpts.logger.debug("Getting push rules...");
602
+ const result = await this.client.getPushRules();
603
+ this.syncOpts.logger.debug("Got push rules");
604
+
605
+ this.client.pushRules = result;
606
+ } catch (err) {
607
+ this.syncOpts.logger.error("Getting push rules failed", err);
608
+ if (this.shouldAbortSync(<BriijError>err)) return;
609
+ // wait for saved sync to complete before doing anything else,
610
+ // otherwise the sync state will end up being incorrect
611
+ this.syncOpts.logger.debug("Waiting for saved sync before retrying push rules...");
612
+ await this.recoverFromSyncStartupError(this.savedSyncPromise, <Error>err);
613
+ return this.getPushRules(); // try again
614
+ }
615
+ };
616
+
617
+ private buildDefaultFilter = (): Filter => {
618
+ const filter = new Filter(this.client.credentials.userId);
619
+ if (this.client.canSupport.get(Feature.ThreadUnreadNotifications) !== ServerSupport.Unsupported) {
620
+ filter.setUnreadThreadNotifications(true);
621
+ }
622
+ return filter;
623
+ };
624
+
625
+ private prepareLazyLoadingForSync = async (): Promise<void> => {
626
+ this.syncOpts.logger.debug("Prepare lazy loading for sync...");
627
+ if (this.client.isGuest()) {
628
+ this.opts.lazyLoadMembers = false;
629
+ }
630
+ if (this.opts.lazyLoadMembers) {
631
+ this.syncOpts.logger.debug("Enabling lazy load on sync filter...");
632
+ if (!this.opts.filter) {
633
+ this.opts.filter = this.buildDefaultFilter();
634
+ }
635
+ this.opts.filter.setLazyLoadMembers(true);
636
+ }
637
+ };
638
+
639
+ private storeClientOptions = async (): Promise<void> => {
640
+ try {
641
+ this.syncOpts.logger.debug("Storing client options...");
642
+ await this.client.storeClientOptions();
643
+ this.syncOpts.logger.debug("Stored client options");
644
+ } catch (err) {
645
+ this.syncOpts.logger.error("Storing client options failed", err);
646
+ throw err;
647
+ }
648
+ };
649
+
650
+ private getFilter = async (): Promise<{
651
+ filterId?: string;
652
+ filter?: Filter;
653
+ }> => {
654
+ this.syncOpts.logger.debug("Getting filter...");
655
+ let filter: Filter;
656
+ if (this.opts.filter) {
657
+ filter = this.opts.filter;
658
+ } else {
659
+ filter = this.buildDefaultFilter();
660
+ }
661
+
662
+ let filterId: string;
663
+ try {
664
+ filterId = await this.client.getOrCreateFilter(getFilterName(this.client.credentials.userId!), filter);
665
+ } catch (err) {
666
+ this.syncOpts.logger.error("Getting filter failed", err);
667
+ if (this.shouldAbortSync(<BriijError>err)) return {};
668
+ // wait for saved sync to complete before doing anything else,
669
+ // otherwise the sync state will end up being incorrect
670
+ this.syncOpts.logger.debug("Waiting for saved sync before retrying filter...");
671
+ await this.recoverFromSyncStartupError(this.savedSyncPromise, <Error>err);
672
+ return this.getFilter(); // try again
673
+ }
674
+ return { filter, filterId };
675
+ };
676
+
677
+ private savedSyncPromise?: Promise<void>;
678
+
679
+ /**
680
+ * Main entry point
681
+ */
682
+ public async sync(): Promise<void> {
683
+ this.running = true;
684
+ this.abortController = new AbortController();
685
+
686
+ globalThis.window?.addEventListener?.("online", this.onOnline, false);
687
+
688
+ if (this.client.isGuest()) {
689
+ // no push rules for guests, no access to POST filter for guests.
690
+ return this.doSync({});
691
+ }
692
+
693
+ // Pull the saved sync token out first, before the worker starts sending
694
+ // all the sync data which could take a while. This will let us send our
695
+ // first incremental sync request before we've processed our saved data.
696
+ this.syncOpts.logger.debug("Getting saved sync token...");
697
+ const savedSyncTokenPromise = this.client.store.getSavedSyncToken().then((tok) => {
698
+ this.syncOpts.logger.debug("Got saved sync token");
699
+ return tok;
700
+ });
701
+
702
+ this.savedSyncPromise = this.client.store
703
+ .getSavedSync()
704
+ .then((savedSync) => {
705
+ this.syncOpts.logger.debug(`Got reply from saved sync, exists? ${!!savedSync}`);
706
+ if (savedSync) {
707
+ return this.syncFromCache(savedSync);
708
+ }
709
+ })
710
+ .catch((err) => {
711
+ this.syncOpts.logger.error("Getting saved sync failed", err);
712
+ });
713
+
714
+ // We need to do one-off checks before we can begin the /sync loop.
715
+ // These are:
716
+ // 1) We need to get push rules so we can check if events should bing as we get
717
+ // them from /sync.
718
+ // 2) We need to get/create a filter which we can use for /sync.
719
+ // 3) We need to prepare lazy loading for sync
720
+ // 4) We need to store the client options
721
+
722
+ // Now start the first incremental sync request: this can also
723
+ // take a while so if we set it going now, we can wait for it
724
+ // to finish while we process our saved sync data.
725
+ await this.getPushRules();
726
+ await this.prepareLazyLoadingForSync();
727
+ await this.storeClientOptions();
728
+
729
+ const { filterId, filter } = await this.getFilter();
730
+ if (!filter) return; // bail, getFilter failed
731
+
732
+ // reset the notifications timeline to prepare it to paginate from
733
+ // the current point in time.
734
+ // The right solution would be to tie /sync pagination tokens into
735
+ // /notifications API somehow.
736
+ this.client.resetNotifTimelineSet();
737
+
738
+ if (!this.currentSyncRequest) {
739
+ let firstSyncFilter = filterId;
740
+ const savedSyncToken = await savedSyncTokenPromise;
741
+
742
+ if (savedSyncToken) {
743
+ this.syncOpts.logger.debug("Sending first sync request...");
744
+ } else {
745
+ this.syncOpts.logger.debug("Sending initial sync request...");
746
+ const initialFilter = this.buildDefaultFilter();
747
+ initialFilter.setDefinition(filter.getDefinition());
748
+ initialFilter.setTimelineLimit(this.opts.initialSyncLimit!);
749
+ // Use an inline filter, no point uploading it for a single usage
750
+ firstSyncFilter = JSON.stringify(initialFilter.getDefinition());
751
+ }
752
+
753
+ // Send this first sync request here so we can then wait for the saved
754
+ // sync data to finish processing before we process the results of this one.
755
+ this.currentSyncRequest = this.doSyncRequest({ filter: firstSyncFilter }, savedSyncToken);
756
+ }
757
+
758
+ // Now wait for the saved sync to finish...
759
+ this.syncOpts.logger.debug("Waiting for saved sync before starting sync processing...");
760
+ await this.savedSyncPromise;
761
+ // process the first sync request and continue syncing with the normal filterId
762
+ return this.doSync({ filter: filterId });
763
+ }
764
+
765
+ /**
766
+ * Stops the sync object from syncing.
767
+ */
768
+ public stop(): void {
769
+ this.syncOpts.logger.debug("SyncApi.stop");
770
+ // It is necessary to check for the existance of
771
+ // globalThis.window AND globalThis.window.removeEventListener.
772
+ // Some platforms (e.g. React Native) register globalThis.window,
773
+ // but do not have globalThis.window.removeEventListener.
774
+ globalThis.window?.removeEventListener?.("online", this.onOnline, false);
775
+ this.running = false;
776
+ this.abortController?.abort();
777
+ if (this.keepAliveTimer) {
778
+ clearTimeout(this.keepAliveTimer);
779
+ this.keepAliveTimer = undefined;
780
+ }
781
+ }
782
+
783
+ /**
784
+ * Retry a backed off syncing request immediately. This should only be used when
785
+ * the user <b>explicitly</b> attempts to retry their lost connection.
786
+ * @returns True if this resulted in a request being retried.
787
+ */
788
+ public retryImmediately(): boolean {
789
+ if (!this.connectionReturnedResolvers) {
790
+ return false;
791
+ }
792
+ this.startKeepAlives(0);
793
+ return true;
794
+ }
795
+ /**
796
+ * Process a single set of cached sync data.
797
+ * @param savedSync - a saved sync that was persisted by a store. This
798
+ * should have been acquired via client.store.getSavedSync().
799
+ */
800
+ private async syncFromCache(savedSync: ISavedSync): Promise<void> {
801
+ this.syncOpts.logger.debug("sync(): not doing HTTP hit, instead returning stored /sync data");
802
+
803
+ const nextSyncToken = savedSync.nextBatch;
804
+
805
+ // Set sync token for future incremental syncing
806
+ this.client.store.setSyncToken(nextSyncToken);
807
+
808
+ // No previous sync, set old token to null
809
+ const syncEventData: ISyncStateData = {
810
+ nextSyncToken,
811
+ catchingUp: false,
812
+ fromCache: true,
813
+ };
814
+
815
+ const data: ISyncResponse = {
816
+ next_batch: nextSyncToken,
817
+ rooms: savedSync.roomsData,
818
+ account_data: {
819
+ events: savedSync.accountData,
820
+ },
821
+ };
822
+
823
+ try {
824
+ await this.processSyncResponse(syncEventData, data);
825
+ } catch (e) {
826
+ this.syncOpts.logger.error("Error processing cached sync", e);
827
+ }
828
+
829
+ // Don't emit a prepared if we've bailed because the store is invalid:
830
+ // in this case the client will not be usable until stopped & restarted
831
+ // so this would be useless and misleading.
832
+ if (!this.storeIsInvalid) {
833
+ this.updateSyncState(SyncState.Prepared, syncEventData);
834
+ }
835
+ }
836
+
837
+ /**
838
+ * Invoke me to do /sync calls
839
+ */
840
+ private async doSync(syncOptions: ISyncOptions): Promise<void> {
841
+ while (this.running) {
842
+ const syncToken = this.client.store.getSyncToken();
843
+
844
+ let data: ISyncResponse;
845
+ try {
846
+ if (!this.currentSyncRequest) {
847
+ this.currentSyncRequest = this.doSyncRequest(syncOptions, syncToken);
848
+ }
849
+ data = await this.currentSyncRequest;
850
+ } catch (e) {
851
+ const abort = await this.onSyncError(<BriijError>e);
852
+ if (abort) return;
853
+ continue;
854
+ } finally {
855
+ this.currentSyncRequest = undefined;
856
+ }
857
+
858
+ // set the sync token NOW *before* processing the events. We do this so
859
+ // if something barfs on an event we can skip it rather than constantly
860
+ // polling with the same token.
861
+ this.client.store.setSyncToken(data.next_batch);
862
+
863
+ // Reset after a successful sync
864
+ this.failedSyncCount = 0;
865
+
866
+ const syncEventData = {
867
+ oldSyncToken: syncToken ?? undefined,
868
+ nextSyncToken: data.next_batch,
869
+ catchingUp: this.catchingUp,
870
+ };
871
+
872
+ try {
873
+ await this.processSyncResponse(syncEventData, data);
874
+ } catch (e) {
875
+ // log the exception with stack if we have it, else fall back
876
+ // to the plain description
877
+ this.syncOpts.logger.error("Caught /sync error", e);
878
+
879
+ // Emit the exception for client handling
880
+ this.client.emit(ClientEvent.SyncUnexpectedError, <Error>e);
881
+ }
882
+
883
+ // Persist after processing as `unsigned` may get mutated
884
+ // with an `org.matrix.msc4023.thread_id`
885
+ await this.client.store.setSyncData(data);
886
+
887
+ // update this as it may have changed
888
+ syncEventData.catchingUp = this.catchingUp;
889
+
890
+ // emit synced events
891
+ if (!syncOptions.hasSyncedBefore) {
892
+ this.updateSyncState(SyncState.Prepared, syncEventData);
893
+ syncOptions.hasSyncedBefore = true;
894
+ }
895
+
896
+ // tell the crypto module to do its processing. It may block (to do a
897
+ // /keys/changes request).
898
+ if (this.syncOpts.cryptoCallbacks) {
899
+ await this.syncOpts.cryptoCallbacks.onSyncCompleted(syncEventData);
900
+ }
901
+
902
+ // keep emitting SYNCING -> SYNCING for clients who want to do bulk updates
903
+ this.updateSyncState(SyncState.Syncing, syncEventData);
904
+
905
+ if (this.client.store.wantsSave()) {
906
+ // tell databases that everything is now in a consistent state and can be saved.
907
+ await this.client.store.save();
908
+ }
909
+ }
910
+
911
+ if (!this.running) {
912
+ this.syncOpts.logger.debug("Sync no longer running: exiting.");
913
+ if (this.connectionReturnedResolvers) {
914
+ this.connectionReturnedResolvers.reject();
915
+ this.connectionReturnedResolvers = undefined;
916
+ }
917
+ this.updateSyncState(SyncState.Stopped);
918
+ }
919
+ }
920
+
921
+ private doSyncRequest(syncOptions: ISyncOptions, syncToken: string | null): Promise<ISyncResponse> {
922
+ const qps = this.getSyncParams(syncOptions, syncToken);
923
+ return this.client.http.authedRequest<ISyncResponse>(Method.Get, "/sync", qps as any, undefined, {
924
+ localTimeoutMs: qps.timeout + BUFFER_PERIOD_MS,
925
+ abortSignal: this.abortController?.signal,
926
+ });
927
+ }
928
+
929
+ private getSyncParams(syncOptions: ISyncOptions, syncToken: string | null): ISyncParams {
930
+ let timeout = this.opts.pollTimeout!;
931
+
932
+ if (this.getSyncState() !== SyncState.Syncing || this.catchingUp) {
933
+ // unless we are happily syncing already, we want the server to return
934
+ // as quickly as possible, even if there are no events queued. This
935
+ // serves two purposes:
936
+ //
937
+ // * When the connection dies, we want to know asap when it comes back,
938
+ // so that we can hide the error from the user. (We don't want to
939
+ // have to wait for an event or a timeout).
940
+ //
941
+ // * We want to know if the server has any to_device messages queued up
942
+ // for us. We do that by calling it with a zero timeout until it
943
+ // doesn't give us any more to_device messages.
944
+ this.catchingUp = true;
945
+ timeout = 0;
946
+ }
947
+
948
+ let filter = syncOptions.filter;
949
+ if (this.client.isGuest() && !filter) {
950
+ filter = this.getGuestFilter();
951
+ }
952
+
953
+ const qps: ISyncParams = {
954
+ filter,
955
+ timeout,
956
+ "org.matrix.msc4222.use_state_after": true,
957
+ };
958
+
959
+ if (this.opts.disablePresence) {
960
+ qps.set_presence = SetPresence.Offline;
961
+ } else if (this.presence !== undefined) {
962
+ qps.set_presence = this.presence;
963
+ }
964
+
965
+ if (syncToken) {
966
+ qps.since = syncToken;
967
+ } else {
968
+ // use a cachebuster for initialsyncs, to make sure that
969
+ // we don't get a stale sync
970
+ // (https://github.com/vector-im/vector-web/issues/1354)
971
+ qps._cacheBuster = Date.now();
972
+ }
973
+
974
+ if ([SyncState.Reconnecting, SyncState.Error].includes(this.getSyncState()!)) {
975
+ // we think the connection is dead. If it comes back up, we won't know
976
+ // about it till /sync returns. If the timeout= is high, this could
977
+ // be a long time. Set it to 0 when doing retries so we don't have to wait
978
+ // for an event or a timeout before emiting the SYNCING event.
979
+ qps.timeout = 0;
980
+ }
981
+
982
+ return qps;
983
+ }
984
+
985
+ /**
986
+ * Specify the set_presence value to be used for subsequent calls to the Sync API.
987
+ * @param presence - the presence to specify to set_presence of sync calls
988
+ */
989
+ public setPresence(presence?: SetPresence): void {
990
+ this.presence = presence;
991
+ }
992
+
993
+ private async onSyncError(err: BriijError): Promise<boolean> {
994
+ if (!this.running) {
995
+ this.syncOpts.logger.debug("Sync no longer running: exiting");
996
+ if (this.connectionReturnedResolvers) {
997
+ this.connectionReturnedResolvers.reject();
998
+ this.connectionReturnedResolvers = undefined;
999
+ }
1000
+ this.updateSyncState(SyncState.Stopped);
1001
+ return true; // abort
1002
+ }
1003
+
1004
+ this.syncOpts.logger.error("/sync error %s", err);
1005
+
1006
+ if (this.shouldAbortSync(err)) {
1007
+ return true; // abort
1008
+ }
1009
+
1010
+ this.failedSyncCount++;
1011
+ this.syncOpts.logger.debug("Number of consecutive failed sync requests:", this.failedSyncCount);
1012
+
1013
+ this.syncOpts.logger.debug("Starting keep-alive");
1014
+ // Note that we do *not* mark the sync connection as
1015
+ // lost yet: we only do this if a keepalive poke
1016
+ // fails, since long lived HTTP connections will
1017
+ // go away sometimes and we shouldn't treat this as
1018
+ // erroneous. We set the state to 'reconnecting'
1019
+ // instead, so that clients can observe this state
1020
+ // if they wish.
1021
+ const keepAlivePromise = this.startKeepAlives();
1022
+
1023
+ this.currentSyncRequest = undefined;
1024
+ // Transition from RECONNECTING to ERROR after a given number of failed syncs
1025
+ this.updateSyncState(
1026
+ this.failedSyncCount >= FAILED_SYNC_ERROR_THRESHOLD ? SyncState.Error : SyncState.Reconnecting,
1027
+ { error: err },
1028
+ );
1029
+
1030
+ const connDidFail = await keepAlivePromise;
1031
+
1032
+ // Only emit CATCHUP if we detected a connectivity error: if we didn't,
1033
+ // it's quite likely the sync will fail again for the same reason and we
1034
+ // want to stay in ERROR rather than keep flip-flopping between ERROR
1035
+ // and CATCHUP.
1036
+ if (connDidFail && this.getSyncState() === SyncState.Error) {
1037
+ this.updateSyncState(SyncState.Catchup, {
1038
+ catchingUp: true,
1039
+ });
1040
+ }
1041
+ return false;
1042
+ }
1043
+
1044
+ /**
1045
+ * Process data returned from a sync response and propagate it
1046
+ * into the model objects
1047
+ *
1048
+ * @param syncEventData - Object containing sync tokens associated with this sync
1049
+ * @param data - The response from /sync
1050
+ */
1051
+ private async processSyncResponse(syncEventData: ISyncStateData, data: ISyncResponse): Promise<void> {
1052
+ const client = this.client;
1053
+
1054
+ // data looks like:
1055
+ // {
1056
+ // next_batch: $token,
1057
+ // presence: { events: [] },
1058
+ // account_data: { events: [] },
1059
+ // device_lists: { changed: ["@user:server", ... ]},
1060
+ // to_device: { events: [] },
1061
+ // device_one_time_keys_count: { signed_curve25519: 42 },
1062
+ // rooms: {
1063
+ // invite: {
1064
+ // $roomid: {
1065
+ // invite_state: { events: [] }
1066
+ // }
1067
+ // },
1068
+ // join: {
1069
+ // $roomid: {
1070
+ // state: { events: [] },
1071
+ // timeline: { events: [], prev_batch: $token, limited: true },
1072
+ // ephemeral: { events: [] },
1073
+ // summary: {
1074
+ // m.heroes: [ $user_id ],
1075
+ // m.joined_member_count: $count,
1076
+ // m.invited_member_count: $count
1077
+ // },
1078
+ // account_data: { events: [] },
1079
+ // unread_notifications: {
1080
+ // highlight_count: 0,
1081
+ // notification_count: 0,
1082
+ // }
1083
+ // "org.matrix.msc4222.state_after": { events: [] }, // only if "org.matrix.msc4222.use_state_after" is true
1084
+ // msc4354_sticky: { events: [] }, // only if "org.matrix.msc4354.sticky" is true
1085
+ // }
1086
+ // },
1087
+ // leave: {
1088
+ // $roomid: {
1089
+ // state: { events: [] },
1090
+ // timeline: { events: [], prev_batch: $token }
1091
+ // }
1092
+ // }
1093
+ // }
1094
+ // }
1095
+
1096
+ // TODO-arch:
1097
+ // - Each event we pass through needs to be emitted via 'event', can we
1098
+ // do this in one place?
1099
+ // - The isBrandNewRoom boilerplate is boilerplatey.
1100
+
1101
+ // handle presence events (User objects)
1102
+ if (Array.isArray(data.presence?.events)) {
1103
+ data.presence!.events.filter(noUnsafeEventProps)
1104
+ .map(client.getEventMapper())
1105
+ .forEach(function (presenceEvent) {
1106
+ let user = client.store.getUser(presenceEvent.getSender()!);
1107
+ if (user) {
1108
+ user.setPresenceEvent(presenceEvent);
1109
+ } else {
1110
+ user = User.createUser(presenceEvent.getSender()!, client);
1111
+ user.setPresenceEvent(presenceEvent);
1112
+ client.store.storeUser(user);
1113
+ }
1114
+ client.emit(ClientEvent.Event, presenceEvent);
1115
+ });
1116
+ }
1117
+
1118
+ // handle non-room account_data
1119
+ if (Array.isArray(data.account_data?.events)) {
1120
+ const events = data.account_data.events.filter(noUnsafeEventProps).map(client.getEventMapper());
1121
+ const prevEventsMap = events.reduce<Record<string, BriijEvent | undefined>>((m, c) => {
1122
+ m[c.getType()!] = client.store.getAccountData(c.getType());
1123
+ return m;
1124
+ }, {});
1125
+ client.store.storeAccountDataEvents(events);
1126
+ events.forEach(function (accountDataEvent) {
1127
+ // Honour push rules that come down the sync stream but also
1128
+ // honour push rules that were previously cached. Base rules
1129
+ // will be updated when we receive push rules via getPushRules
1130
+ // (see sync) before syncing over the network.
1131
+ if (accountDataEvent.getType() === EventType.PushRules) {
1132
+ const rules = accountDataEvent.getContent<IPushRules>();
1133
+ client.setPushRules(rules);
1134
+ }
1135
+ const prevEvent = prevEventsMap[accountDataEvent.getType()!];
1136
+ client.emit(ClientEvent.AccountData, accountDataEvent, prevEvent);
1137
+ return accountDataEvent;
1138
+ });
1139
+ }
1140
+
1141
+ // handle to-device events
1142
+ if (data.to_device && Array.isArray(data.to_device.events) && data.to_device.events.length > 0) {
1143
+ const toDeviceMessages: IToDeviceEvent[] = data.to_device.events.filter(noUnsafeEventProps);
1144
+
1145
+ let receivedToDeviceMessages: ReceivedToDeviceMessage[];
1146
+ if (this.syncOpts.cryptoCallbacks) {
1147
+ receivedToDeviceMessages =
1148
+ await this.syncOpts.cryptoCallbacks.preprocessToDeviceMessages(toDeviceMessages);
1149
+ } else {
1150
+ receivedToDeviceMessages = toDeviceMessages.map((rawEvent) =>
1151
+ // Crypto is not enabled, so we just return the events.
1152
+ ({
1153
+ message: rawEvent,
1154
+ encryptionInfo: null,
1155
+ }),
1156
+ );
1157
+ }
1158
+
1159
+ processToDeviceMessages(receivedToDeviceMessages, client);
1160
+ } else {
1161
+ // no more to-device events: we can stop polling with a short timeout.
1162
+ this.catchingUp = false;
1163
+ }
1164
+
1165
+ // the returned json structure is a bit crap, so make it into a
1166
+ // nicer form (array) after applying sanity to make sure we don't fail
1167
+ // on missing keys (on the off chance)
1168
+ let inviteRooms: WrappedRoom<IInvitedRoom>[] = [];
1169
+ let joinRooms: WrappedRoom<IJoinedRoom>[] = [];
1170
+ let leaveRooms: WrappedRoom<ILeftRoom>[] = [];
1171
+ let knockRooms: WrappedRoom<IKnockedRoom>[] = [];
1172
+
1173
+ if (data.rooms) {
1174
+ if (data.rooms.invite) {
1175
+ inviteRooms = this.mapSyncResponseToRoomArray(data.rooms.invite);
1176
+ }
1177
+ if (data.rooms.join) {
1178
+ joinRooms = this.mapSyncResponseToRoomArray(data.rooms.join);
1179
+ }
1180
+ if (data.rooms.leave) {
1181
+ leaveRooms = this.mapSyncResponseToRoomArray(data.rooms.leave);
1182
+ }
1183
+ if (data.rooms.knock) {
1184
+ knockRooms = this.mapSyncResponseToRoomArray(data.rooms.knock);
1185
+ }
1186
+ }
1187
+
1188
+ this.notifEvents = [];
1189
+
1190
+ // Handle invites
1191
+ await Promise.all(
1192
+ inviteRooms.map(async (inviteObj) => {
1193
+ const room = inviteObj.room;
1194
+ const stateEvents = this.mapSyncEventsFormat(inviteObj.invite_state, room);
1195
+
1196
+ await this.injectRoomEvents(room, stateEvents, undefined);
1197
+
1198
+ if (inviteObj.isBrandNewRoom) {
1199
+ room.recalculate();
1200
+ client.store.storeRoom(room);
1201
+ client.emit(ClientEvent.Room, room);
1202
+ } else {
1203
+ // Update room state for invite->reject->invite cycles
1204
+ room.recalculate();
1205
+ }
1206
+ stateEvents.forEach(function (e) {
1207
+ client.emit(ClientEvent.Event, e);
1208
+ });
1209
+ }),
1210
+ );
1211
+
1212
+ // Handle joins
1213
+ await Promise.all(
1214
+ joinRooms.map(async (joinObj) => {
1215
+ const room = joinObj.room;
1216
+ const stateEvents = this.mapSyncEventsFormat(joinObj.state, room);
1217
+ const stateAfterEvents = this.mapSyncEventsFormat(joinObj["org.matrix.msc4222.state_after"], room);
1218
+ // Prevent events from being decrypted ahead of time
1219
+ // this helps large account to speed up faster
1220
+ // room::decryptCriticalEvent is in charge of decrypting all the events
1221
+ // required for a client to function properly
1222
+ const timelineEvents = this.mapSyncEventsFormat(joinObj.timeline, room, false);
1223
+ const ephemeralEvents = this.mapSyncEventsFormat(joinObj.ephemeral);
1224
+ const accountDataEvents = this.mapSyncEventsFormat(joinObj.account_data);
1225
+ const stickyEvents = this.mapSyncEventsFormat(joinObj.msc4354_sticky);
1226
+
1227
+ // If state_after is present, this is the events that form the state at the end of the timeline block and
1228
+ // regular timeline events do *not* count towards state. If it's not present, then the state is formed by
1229
+ // the state events plus the timeline events. Note mapSyncEventsFormat returns an empty array if the field
1230
+ // is absent so we explicitly check the field on the original object.
1231
+ const eventsFormingFinalState = joinObj["org.matrix.msc4222.state_after"]
1232
+ ? stateAfterEvents
1233
+ : stateEvents.concat(timelineEvents);
1234
+
1235
+ const encrypted = this.isRoomEncrypted(room, eventsFormingFinalState);
1236
+ // We store the server-provided value first so it's correct when any of the events fire.
1237
+ if (joinObj.unread_notifications) {
1238
+ /**
1239
+ * We track unread notifications ourselves in encrypted rooms, so don't
1240
+ * bother setting it here. We trust our calculations better than the
1241
+ * server's for this case, and therefore will assume that our non-zero
1242
+ * count is accurate.
1243
+ * XXX: this is known faulty as the push rule for `.m.room.encrypted` may be disabled so server
1244
+ * may issue notification counts of 0 which we wrongly trust.
1245
+ * https://github.com/matrix-org/matrix-spec-proposals/pull/2654 would fix this
1246
+ *
1247
+ * @see import("./client").fixNotificationCountOnDecryption
1248
+ */
1249
+ if (!encrypted || joinObj.unread_notifications.notification_count === 0) {
1250
+ // In an encrypted room, if the room has notifications enabled then it's typical for
1251
+ // the server to flag all new messages as notifying. However, some push rules calculate
1252
+ // events as ignored based on their event contents (e.g. ignoring msgtype=m.notice messages)
1253
+ // so we want to calculate this figure on the client in all cases.
1254
+ room.setUnreadNotificationCount(
1255
+ NotificationCountType.Total,
1256
+ joinObj.unread_notifications.notification_count ?? 0,
1257
+ );
1258
+ }
1259
+
1260
+ if (!encrypted || room.getUnreadNotificationCount(NotificationCountType.Highlight) <= 0) {
1261
+ // If the locally stored highlight count is zero, use the server provided value.
1262
+ room.setUnreadNotificationCount(
1263
+ NotificationCountType.Highlight,
1264
+ joinObj.unread_notifications.highlight_count ?? 0,
1265
+ );
1266
+ }
1267
+ }
1268
+
1269
+ const unreadThreadNotifications =
1270
+ joinObj[UNREAD_THREAD_NOTIFICATIONS.name] ?? joinObj[UNREAD_THREAD_NOTIFICATIONS.altName!];
1271
+ if (unreadThreadNotifications) {
1272
+ // This mirrors the logic above for rooms: take the *total* notification count from
1273
+ // the server for unencrypted rooms or is it's zero. Any threads not present in this
1274
+ // object implicitly have zero notifications, so start by clearing the total counts
1275
+ // for all such threads.
1276
+ room.resetThreadUnreadNotificationCountFromSync(Object.keys(unreadThreadNotifications));
1277
+ for (const [threadId, unreadNotification] of Object.entries(unreadThreadNotifications)) {
1278
+ if (!encrypted || unreadNotification.notification_count === 0) {
1279
+ room.setThreadUnreadNotificationCount(
1280
+ threadId,
1281
+ NotificationCountType.Total,
1282
+ unreadNotification.notification_count ?? 0,
1283
+ );
1284
+ }
1285
+
1286
+ const hasNoNotifications =
1287
+ room.getThreadUnreadNotificationCount(threadId, NotificationCountType.Highlight) <= 0;
1288
+ if (!encrypted || (encrypted && hasNoNotifications)) {
1289
+ room.setThreadUnreadNotificationCount(
1290
+ threadId,
1291
+ NotificationCountType.Highlight,
1292
+ unreadNotification.highlight_count ?? 0,
1293
+ );
1294
+ }
1295
+ }
1296
+ } else {
1297
+ room.resetThreadUnreadNotificationCountFromSync();
1298
+ }
1299
+
1300
+ joinObj.timeline = joinObj.timeline || ({} as ITimeline);
1301
+
1302
+ if (joinObj.isBrandNewRoom) {
1303
+ // set the back-pagination token. Do this *before* adding any
1304
+ // events so that clients can start back-paginating.
1305
+ if (joinObj.timeline.prev_batch !== null) {
1306
+ room.getLiveTimeline().setPaginationToken(joinObj.timeline.prev_batch, EventTimeline.BACKWARDS);
1307
+ }
1308
+ } else if (joinObj.timeline.limited) {
1309
+ let limited = true;
1310
+
1311
+ // we've got a limited sync, so we *probably* have a gap in the
1312
+ // timeline, so should reset. But we might have been peeking or
1313
+ // paginating and already have some of the events, in which
1314
+ // case we just want to append any subsequent events to the end
1315
+ // of the existing timeline.
1316
+ //
1317
+ // This is particularly important in the case that we already have
1318
+ // *all* of the events in the timeline - in that case, if we reset
1319
+ // the timeline, we'll end up with an entirely empty timeline,
1320
+ // which we'll try to paginate but not get any new events (which
1321
+ // will stop us linking the empty timeline into the chain).
1322
+ //
1323
+ for (let i = timelineEvents.length - 1; i >= 0; i--) {
1324
+ const eventId = timelineEvents[i].getId()!;
1325
+ if (room.getTimelineForEvent(eventId)) {
1326
+ this.syncOpts.logger.debug(`Already have event ${eventId} in limited sync - not resetting`);
1327
+ limited = false;
1328
+
1329
+ // we might still be missing some of the events before i;
1330
+ // we don't want to be adding them to the end of the
1331
+ // timeline because that would put them out of order.
1332
+ timelineEvents.splice(0, i);
1333
+
1334
+ // XXX: there's a problem here if the skipped part of the
1335
+ // timeline modifies the state set in stateEvents, because
1336
+ // we'll end up using the state from stateEvents rather
1337
+ // than the later state from timelineEvents. We probably
1338
+ // need to wind stateEvents forward over the events we're
1339
+ // skipping.
1340
+
1341
+ break;
1342
+ }
1343
+ }
1344
+
1345
+ if (limited) {
1346
+ room.resetLiveTimeline(
1347
+ joinObj.timeline.prev_batch,
1348
+ this.syncOpts.canResetEntireTimeline!(room.roomId)
1349
+ ? null
1350
+ : (syncEventData.oldSyncToken ?? null),
1351
+ );
1352
+
1353
+ // We have to assume any gap in any timeline is
1354
+ // reason to stop incrementally tracking notifications and
1355
+ // reset the timeline.
1356
+ client.resetNotifTimelineSet();
1357
+ }
1358
+ }
1359
+
1360
+ // process any crypto events *before* emitting the RoomStateEvent events. This
1361
+ // avoids a race condition if the application tries to send a message after the
1362
+ // state event is processed, but before crypto is enabled, which then causes the
1363
+ // crypto layer to complain.
1364
+
1365
+ if (this.syncOpts.cryptoCallbacks) {
1366
+ for (const e of eventsFormingFinalState) {
1367
+ if (e.isState() && e.getType() === EventType.RoomEncryption && e.getStateKey() === "") {
1368
+ await this.syncOpts.cryptoCallbacks.onCryptoEvent(room, e);
1369
+ }
1370
+ }
1371
+ }
1372
+
1373
+ // Proactively decrypt state events: normally we decrypt on demand, but for state
1374
+ // events we need them immediately, so we handle them here. Specifically, consumers
1375
+ // (e.g. Element Web) expect state events to be unencrypted upon receipt.
1376
+ for (const ev of timelineEvents.filter((ev) => ev.isState())) {
1377
+ await this.client.decryptEventIfNeeded(ev);
1378
+ }
1379
+
1380
+ try {
1381
+ if ("org.matrix.msc4222.state_after" in joinObj) {
1382
+ await this.injectRoomEvents(
1383
+ room,
1384
+ undefined,
1385
+ stateAfterEvents,
1386
+ timelineEvents,
1387
+ syncEventData.fromCache,
1388
+ );
1389
+ } else {
1390
+ await this.injectRoomEvents(
1391
+ room,
1392
+ stateEvents,
1393
+ undefined,
1394
+ timelineEvents,
1395
+ syncEventData.fromCache,
1396
+ );
1397
+ }
1398
+ } catch (e) {
1399
+ this.syncOpts.logger.error(`Failed to process events on room ${room.roomId}:`, e);
1400
+ }
1401
+
1402
+ // set summary after processing events,
1403
+ // because it will trigger a name calculation
1404
+ // which needs the room state to be up to date
1405
+ if (joinObj.summary) {
1406
+ room.setSummary(joinObj.summary);
1407
+ }
1408
+
1409
+ // we deliberately don't add ephemeral events to the timeline
1410
+ room.addEphemeralEvents(ephemeralEvents);
1411
+
1412
+ // we deliberately don't add accountData to the timeline
1413
+ room.addAccountData(accountDataEvents);
1414
+
1415
+ // Sticky events primarily come via the `timeline` field, with the
1416
+ // sticky info field marking them as sticky.
1417
+ // If the sync is "gappy" (meaning it is skipping events to catch up) then
1418
+ // sticky events will instead come down the sticky section.
1419
+ // This ensures we collect sticky events from both places.
1420
+ const stickyEventsAndStickyEventsFromTheTimeline = stickyEvents.concat(
1421
+ timelineEvents.filter((e) => e.unstableStickyInfo !== undefined),
1422
+ );
1423
+ // Note: We calculate sticky events before emitting `.Room` as it's nice to have
1424
+ // sticky events calculated and ready to go.
1425
+ room._unstable_addStickyEvents(stickyEventsAndStickyEventsFromTheTimeline);
1426
+
1427
+ room.recalculate();
1428
+ if (joinObj.isBrandNewRoom) {
1429
+ client.store.storeRoom(room);
1430
+ client.emit(ClientEvent.Room, room);
1431
+ }
1432
+
1433
+ this.processEventsForNotifs(room, timelineEvents);
1434
+
1435
+ const emitEvent = (e: BriijEvent): boolean => client.emit(ClientEvent.Event, e);
1436
+ // this fires a couple of times for some events. (eg state events are in the timeline and the state)
1437
+ // should this get a sync section as an additional event emission param (e, syncSection))?
1438
+ stateEvents.forEach(emitEvent);
1439
+ timelineEvents.forEach(emitEvent);
1440
+ ephemeralEvents.forEach(emitEvent);
1441
+ accountDataEvents.forEach(emitEvent);
1442
+ stickyEvents
1443
+ .filter(
1444
+ (stickyEvent) =>
1445
+ // This is highly unlikey, but in the case where a sticky event
1446
+ // has appeared in the timeline AND the sticky section, we only
1447
+ // want to emit the event once.
1448
+ !timelineEvents.some((timelineEvent) => timelineEvent.getId() === stickyEvent.getId()),
1449
+ )
1450
+ .forEach(emitEvent);
1451
+ // Decrypt only the last message in all rooms to make sure we can generate a preview
1452
+ // And decrypt all events after the recorded read receipt to ensure an accurate
1453
+ // notification count
1454
+ room.decryptCriticalEvents();
1455
+ }),
1456
+ );
1457
+
1458
+ // Handle leaves (e.g. kicked rooms)
1459
+ await Promise.all(
1460
+ leaveRooms.map(async (leaveObj) => {
1461
+ const room = leaveObj.room;
1462
+ const { timelineEvents, stateEvents, stateAfterEvents } = await this.mapAndInjectRoomEvents(leaveObj);
1463
+ const accountDataEvents = this.mapSyncEventsFormat(leaveObj.account_data);
1464
+
1465
+ room.addAccountData(accountDataEvents);
1466
+
1467
+ room.recalculate();
1468
+ if (leaveObj.isBrandNewRoom) {
1469
+ client.store.storeRoom(room);
1470
+ client.emit(ClientEvent.Room, room);
1471
+ }
1472
+
1473
+ this.processEventsForNotifs(room, timelineEvents);
1474
+
1475
+ stateEvents?.forEach(function (e) {
1476
+ client.emit(ClientEvent.Event, e);
1477
+ });
1478
+ stateAfterEvents?.forEach(function (e) {
1479
+ client.emit(ClientEvent.Event, e);
1480
+ });
1481
+ timelineEvents.forEach(function (e) {
1482
+ client.emit(ClientEvent.Event, e);
1483
+ });
1484
+ accountDataEvents.forEach(function (e) {
1485
+ client.emit(ClientEvent.Event, e);
1486
+ });
1487
+ }),
1488
+ );
1489
+
1490
+ // Handle knocks
1491
+ await Promise.all(
1492
+ knockRooms.map(async (knockObj) => {
1493
+ const room = knockObj.room;
1494
+ const stateEvents = this.mapSyncEventsFormat(knockObj.knock_state, room);
1495
+
1496
+ await this.injectRoomEvents(room, stateEvents, undefined);
1497
+
1498
+ if (knockObj.isBrandNewRoom) {
1499
+ room.recalculate();
1500
+ client.store.storeRoom(room);
1501
+ client.emit(ClientEvent.Room, room);
1502
+ } else {
1503
+ // Update room state for knock->leave->knock cycles
1504
+ room.recalculate();
1505
+ }
1506
+ stateEvents.forEach(function (e) {
1507
+ client.emit(ClientEvent.Event, e);
1508
+ });
1509
+ }),
1510
+ );
1511
+
1512
+ // update the notification timeline, if appropriate.
1513
+ // we only do this for live events, as otherwise we can't order them sanely
1514
+ // in the timeline relative to ones paginated in by /notifications.
1515
+ // XXX: we could fix this by making EventTimeline support chronological
1516
+ // ordering... but it doesn't, right now.
1517
+ if (syncEventData.oldSyncToken && this.notifEvents.length) {
1518
+ this.notifEvents.sort(function (a, b) {
1519
+ return a.getTs() - b.getTs();
1520
+ });
1521
+ this.notifEvents.forEach(function (event) {
1522
+ client.getNotifTimelineSet()?.addLiveEvent(event, { addToState: true });
1523
+ });
1524
+ }
1525
+
1526
+ // Handle device list updates
1527
+ if (data.device_lists) {
1528
+ if (this.syncOpts.cryptoCallbacks) {
1529
+ await this.syncOpts.cryptoCallbacks.processDeviceLists(data.device_lists);
1530
+ } else {
1531
+ // FIXME if we *don't* have a crypto module, we still need to
1532
+ // invalidate the device lists. But that would require a
1533
+ // substantial bit of rework :/.
1534
+ }
1535
+ }
1536
+
1537
+ // Handle one_time_keys_count and unused fallback keys
1538
+ await this.syncOpts.cryptoCallbacks?.processKeyCounts(
1539
+ data.device_one_time_keys_count,
1540
+ data.device_unused_fallback_key_types ?? data["org.matrix.msc2732.device_unused_fallback_key_types"],
1541
+ );
1542
+ }
1543
+
1544
+ /**
1545
+ * Starts polling the connectivity check endpoint
1546
+ * @param delay - How long to delay until the first poll.
1547
+ * defaults to a short, randomised interval (to prevent
1548
+ * tight-looping if /versions succeeds but /sync etc. fail).
1549
+ * @returns which resolves once the connection returns
1550
+ */
1551
+ private startKeepAlives(delay?: number): Promise<boolean> {
1552
+ if (delay === undefined) {
1553
+ delay = 2000 + Math.floor(Math.random() * 5000);
1554
+ }
1555
+
1556
+ if (this.keepAliveTimer !== null) {
1557
+ clearTimeout(this.keepAliveTimer);
1558
+ }
1559
+ if (delay > 0) {
1560
+ this.keepAliveTimer = setTimeout(this.pokeKeepAlive.bind(this), delay);
1561
+ } else {
1562
+ this.pokeKeepAlive();
1563
+ }
1564
+ if (!this.connectionReturnedResolvers) {
1565
+ this.connectionReturnedResolvers = Promise.withResolvers();
1566
+ }
1567
+ return this.connectionReturnedResolvers.promise;
1568
+ }
1569
+
1570
+ /**
1571
+ * Make a dummy call to /_matrix/client/versions, to see if the HS is
1572
+ * reachable.
1573
+ *
1574
+ * On failure, schedules a call back to itself. On success, resolves
1575
+ * this.connectionReturnedResolvers.
1576
+ *
1577
+ * @param connDidFail - True if a connectivity failure has been detected. Optional.
1578
+ */
1579
+ private pokeKeepAlive(connDidFail = false): void {
1580
+ if (!this.running) {
1581
+ // we are in a keepAlive, retrying to connect, but the syncronization
1582
+ // was stopped, so we are stopping the retry.
1583
+ clearTimeout(this.keepAliveTimer);
1584
+ if (this.connectionReturnedResolvers) {
1585
+ this.connectionReturnedResolvers.reject("SyncApi.stop() was called");
1586
+ this.connectionReturnedResolvers = undefined;
1587
+ }
1588
+ return;
1589
+ }
1590
+
1591
+ const success = (): void => {
1592
+ clearTimeout(this.keepAliveTimer);
1593
+ if (this.connectionReturnedResolvers) {
1594
+ this.connectionReturnedResolvers.resolve(connDidFail);
1595
+ this.connectionReturnedResolvers = undefined;
1596
+ }
1597
+ };
1598
+
1599
+ this.client.http
1600
+ .request(
1601
+ Method.Get,
1602
+ "/_matrix/client/versions",
1603
+ undefined, // queryParams
1604
+ undefined, // data
1605
+ {
1606
+ prefix: "",
1607
+ localTimeoutMs: 15 * 1000,
1608
+ abortSignal: this.abortController?.signal,
1609
+ },
1610
+ )
1611
+ .then(
1612
+ () => {
1613
+ success();
1614
+ },
1615
+ (err) => {
1616
+ if (err.httpStatus == 400 || err.httpStatus == 404) {
1617
+ // treat this as a success because the server probably just doesn't
1618
+ // support /versions: point is, we're getting a response.
1619
+ // We wait a short time though, just in case somehow the server
1620
+ // is in a mode where it 400s /versions responses and sync etc.
1621
+ // responses fail, this will mean we don't hammer in a loop.
1622
+ this.keepAliveTimer = setTimeout(success, 2000);
1623
+ } else {
1624
+ connDidFail = true;
1625
+ this.keepAliveTimer = setTimeout(
1626
+ this.pokeKeepAlive.bind(this, connDidFail),
1627
+ 5000 + Math.floor(Math.random() * 5000),
1628
+ );
1629
+ // A keepalive has failed, so we emit the
1630
+ // error state (whether or not this is the
1631
+ // first failure).
1632
+ // Note we do this after setting the timer:
1633
+ // this lets the unit tests advance the mock
1634
+ // clock when they get the error.
1635
+ this.updateSyncState(SyncState.Error, { error: err });
1636
+ }
1637
+ },
1638
+ );
1639
+ }
1640
+
1641
+ private mapSyncResponseToRoomArray<T extends ILeftRoom | IJoinedRoom | IInvitedRoom | IKnockedRoom>(
1642
+ obj: Record<string, T>,
1643
+ ): Array<WrappedRoom<T>> {
1644
+ // Maps { roomid: {stuff}, roomid: {stuff} }
1645
+ // to
1646
+ // [{stuff+Room+isBrandNewRoom}, {stuff+Room+isBrandNewRoom}]
1647
+ const client = this.client;
1648
+ return Object.keys(obj)
1649
+ .filter((k) => !unsafeProp(k))
1650
+ .map((roomId) => {
1651
+ let room = client.store.getRoom(roomId);
1652
+ let isBrandNewRoom = false;
1653
+ if (!room) {
1654
+ room = this.createRoom(roomId);
1655
+ isBrandNewRoom = true;
1656
+ }
1657
+ return {
1658
+ ...obj[roomId],
1659
+ room,
1660
+ isBrandNewRoom,
1661
+ };
1662
+ });
1663
+ }
1664
+
1665
+ private mapSyncEventsFormat(
1666
+ obj: IInviteState | ITimeline | IEphemeral | undefined,
1667
+ room?: Room,
1668
+ decrypt = true,
1669
+ ): BriijEvent[] {
1670
+ if (!obj || !Array.isArray(obj.events)) {
1671
+ return [];
1672
+ }
1673
+ const mapper = this.client.getEventMapper({ decrypt });
1674
+ type TaggedEvent = (IStrippedState | IRoomEvent | IStateEvent | IMinimalEvent) & { room_id?: string };
1675
+ return (obj.events as TaggedEvent[]).filter(noUnsafeEventProps).map(function (e) {
1676
+ if (room) {
1677
+ e.room_id = room.roomId;
1678
+ }
1679
+ return mapper(e);
1680
+ });
1681
+ }
1682
+
1683
+ /**
1684
+ */
1685
+ private resolveInvites(room: Room): void {
1686
+ if (!room || !this.opts.resolveInvitesToProfiles) {
1687
+ return;
1688
+ }
1689
+ const client = this.client;
1690
+ // For each invited room member we want to give them a displayname/avatar url
1691
+ // if they have one (the m.room.member invites don't contain this).
1692
+ room.getMembersWithMembership(KnownMembership.Invite).forEach(function (member) {
1693
+ if (member.requestedProfileInfo) return;
1694
+ member.requestedProfileInfo = true;
1695
+ // try to get a cached copy first.
1696
+ const user = client.getUser(member.userId);
1697
+ let promise;
1698
+ if (user) {
1699
+ promise = Promise.resolve({
1700
+ avatar_url: user.avatarUrl,
1701
+ displayname: user.displayName,
1702
+ });
1703
+ } else {
1704
+ promise = client.getProfileInfo(member.userId);
1705
+ }
1706
+ promise.then(
1707
+ function (info) {
1708
+ // slightly naughty by doctoring the invite event but this means all
1709
+ // the code paths remain the same between invite/join display name stuff
1710
+ // which is a worthy trade-off for some minor pollution.
1711
+ const inviteEvent = member.events.member;
1712
+ if (inviteEvent?.getContent().membership !== KnownMembership.Invite) {
1713
+ // between resolving and now they have since joined, so don't clobber
1714
+ return;
1715
+ }
1716
+ inviteEvent.getContent().avatar_url = info.avatar_url;
1717
+ inviteEvent.getContent().displayname = info.displayname;
1718
+ // fire listeners
1719
+ member.setMembershipEvent(inviteEvent, room.currentState);
1720
+ },
1721
+ function (err) {
1722
+ // OH WELL.
1723
+ },
1724
+ );
1725
+ });
1726
+ }
1727
+
1728
+ private findEncryptionEvent(events?: BriijEvent[]): BriijEvent | undefined {
1729
+ return events?.find((e) => e.getType() === EventType.RoomEncryption && e.getStateKey() === "");
1730
+ }
1731
+
1732
+ // When processing the sync response we cannot rely on Room.hasEncryptionStateEvent we actually
1733
+ // inject the events into the room object, so we have to inspect the events themselves.
1734
+ private isRoomEncrypted(room: Room, eventsFormingFinalState: BriijEvent[]): boolean {
1735
+ return room.hasEncryptionStateEvent() || !!this.findEncryptionEvent(eventsFormingFinalState);
1736
+ }
1737
+
1738
+ private async mapAndInjectRoomEvents(wrappedRoom: WrappedRoom<ILeftRoom>): Promise<{
1739
+ timelineEvents: BriijEvent[];
1740
+ stateEvents?: BriijEvent[];
1741
+ stateAfterEvents?: BriijEvent[];
1742
+ }> {
1743
+ const stateEvents = this.mapSyncEventsFormat(wrappedRoom.state, wrappedRoom.room);
1744
+ const stateAfterEvents = this.mapSyncEventsFormat(
1745
+ wrappedRoom["org.matrix.msc4222.state_after"],
1746
+ wrappedRoom.room,
1747
+ );
1748
+ const timelineEvents = this.mapSyncEventsFormat(wrappedRoom.timeline, wrappedRoom.room);
1749
+
1750
+ if ("org.matrix.msc4222.state_after" in wrappedRoom) {
1751
+ await this.injectRoomEvents(wrappedRoom.room, undefined, stateAfterEvents, timelineEvents);
1752
+ } else {
1753
+ await this.injectRoomEvents(wrappedRoom.room, stateEvents, undefined, timelineEvents);
1754
+ }
1755
+
1756
+ return { timelineEvents, stateEvents, stateAfterEvents };
1757
+ }
1758
+
1759
+ /**
1760
+ * Injects events into a room's model.
1761
+ * @param stateEventList - A list of state events. This is the state
1762
+ * at the *START* of the timeline list if it is supplied.
1763
+ * @param stateAfterEventList - A list of state events. This is the state
1764
+ * at the *END* of the timeline list if it is supplied.
1765
+ * @param timelineEventList - A list of timeline events, including threaded. Lower index
1766
+ * is earlier in time. Higher index is later.
1767
+ * @param fromCache - whether the sync response came from cache
1768
+ *
1769
+ * No more than one of stateEventList and stateAfterEventList must be supplied. If
1770
+ * stateEventList is supplied, the events in timelineEventList are added to the state
1771
+ * after stateEventList. If stateAfterEventList is supplied, the events in timelineEventList
1772
+ * are not added to the state.
1773
+ */
1774
+ public async injectRoomEvents(
1775
+ room: Room,
1776
+ stateEventList: BriijEvent[],
1777
+ stateAfterEventList: undefined,
1778
+ timelineEventList?: BriijEvent[],
1779
+ fromCache?: boolean,
1780
+ ): Promise<void>;
1781
+ public async injectRoomEvents(
1782
+ room: Room,
1783
+ stateEventList: undefined,
1784
+ stateAfterEventList: BriijEvent[],
1785
+ timelineEventList?: BriijEvent[],
1786
+ fromCache?: boolean,
1787
+ ): Promise<void>;
1788
+ public async injectRoomEvents(
1789
+ room: Room,
1790
+ stateEventList: BriijEvent[] | undefined,
1791
+ stateAfterEventList: BriijEvent[] | undefined,
1792
+ timelineEventList?: BriijEvent[],
1793
+ fromCache = false,
1794
+ ): Promise<void> {
1795
+ const eitherStateEventList = stateAfterEventList ?? stateEventList!;
1796
+
1797
+ // If there are no events in the timeline yet, initialise it with
1798
+ // the given state events
1799
+ const liveTimeline = room.getLiveTimeline();
1800
+ const timelineWasEmpty = liveTimeline.getEvents().length == 0;
1801
+ if (timelineWasEmpty) {
1802
+ // Passing these events into initialiseState will freeze them, so we need
1803
+ // to compute and cache the push actions for them now, otherwise sync dies
1804
+ // with an attempt to assign to read only property.
1805
+ // XXX: This is pretty horrible and is assuming all sorts of behaviour from
1806
+ // these functions that it shouldn't be. We should probably either store the
1807
+ // push actions cache elsewhere so we can freeze BriijEvents, or otherwise
1808
+ // find some solution where BriijEvents are immutable but allow for a cache
1809
+ // field.
1810
+
1811
+ for (const ev of eitherStateEventList) {
1812
+ this.client.getPushActionsForEvent(ev);
1813
+ }
1814
+ liveTimeline.initialiseState(eitherStateEventList, {
1815
+ timelineWasEmpty,
1816
+ });
1817
+ }
1818
+
1819
+ this.resolveInvites(room);
1820
+
1821
+ // recalculate the room name at this point as adding events to the timeline
1822
+ // may make notifications appear which should have the right name.
1823
+ // XXX: This looks suspect: we'll end up recalculating the room once here
1824
+ // and then again after adding events (processSyncResponse calls it after
1825
+ // calling us) even if no state events were added. It also means that if
1826
+ // one of the room events in timelineEventList is something that needs
1827
+ // a recalculation (like m.room.name) we won't recalculate until we've
1828
+ // finished adding all the events, which will cause the notification to have
1829
+ // the old room name rather than the new one.
1830
+ room.recalculate();
1831
+
1832
+ // If the timeline wasn't empty, we process the state events here: they're
1833
+ // defined as updates to the state before the start of the timeline, so this
1834
+ // starts to roll the state forward.
1835
+ // XXX: That's what we *should* do, but this can happen if we were previously
1836
+ // peeking in a room, in which case we obviously do *not* want to add the
1837
+ // state events here onto the end of the timeline. Historically, the js-sdk
1838
+ // has just set these new state events on the old and new state. This seems
1839
+ // very wrong because there could be events in the timeline that diverge the
1840
+ // state, in which case this is going to leave things out of sync. However,
1841
+ // for now I think it;s best to behave the same as the code has done previously.
1842
+ if (!timelineWasEmpty) {
1843
+ // XXX: As above, don't do this...
1844
+ //room.addLiveEvents(stateEventList || []);
1845
+ // Do this instead...
1846
+ room.oldState.setStateEvents(eitherStateEventList);
1847
+ room.currentState.setStateEvents(eitherStateEventList);
1848
+ }
1849
+
1850
+ // Execute the timeline events. If addToState is true the timeline has any state
1851
+ // events in it, this will continue to diverge the current state.
1852
+ // This also needs to be done before running push rules on the events as they need
1853
+ // to be decorated with sender etc.
1854
+ await room.addLiveEvents(timelineEventList || [], {
1855
+ fromCache,
1856
+ timelineWasEmpty,
1857
+ addToState: stateAfterEventList === undefined,
1858
+ });
1859
+ this.client.processBeaconEvents(room, timelineEventList);
1860
+ }
1861
+
1862
+ /**
1863
+ * Takes a list of timelineEvents and adds and adds to notifEvents
1864
+ * as appropriate.
1865
+ * This must be called after the room the events belong to has been stored.
1866
+ *
1867
+ * @param timelineEventList - A list of timeline events. Lower index
1868
+ * is earlier in time. Higher index is later.
1869
+ */
1870
+ private processEventsForNotifs(room: Room, timelineEventList: BriijEvent[]): void {
1871
+ // gather our notifications into this.notifEvents
1872
+ if (this.client.getNotifTimelineSet()) {
1873
+ for (const event of timelineEventList) {
1874
+ const pushActions = this.client.getPushActionsForEvent(event);
1875
+ if (pushActions?.notify && pushActions.tweaks?.highlight) {
1876
+ this.notifEvents.push(event);
1877
+ }
1878
+ }
1879
+ }
1880
+ }
1881
+
1882
+ private getGuestFilter(): string {
1883
+ // Dev note: This used to be conditional to return a filter of 20 events maximum, but
1884
+ // the condition never went to the other branch. This is now hardcoded.
1885
+ return "{}";
1886
+ }
1887
+
1888
+ /**
1889
+ * Sets the sync state and emits an event to say so
1890
+ * @param newState - The new state string
1891
+ * @param data - Object of additional data to emit in the event
1892
+ */
1893
+ private updateSyncState(newState: SyncState, data?: ISyncStateData): void {
1894
+ const old = this.syncState;
1895
+ this.syncState = newState;
1896
+ this.syncStateData = data;
1897
+ this.client.emit(ClientEvent.Sync, this.syncState, old, data);
1898
+ }
1899
+
1900
+ /**
1901
+ * Event handler for the 'online' event
1902
+ * This event is generally unreliable and precise behaviour
1903
+ * varies between browsers, so we poll for connectivity too,
1904
+ * but this might help us reconnect a little faster.
1905
+ */
1906
+ private onOnline = (): void => {
1907
+ this.syncOpts.logger.debug("Browser thinks we are back online");
1908
+ this.startKeepAlives(0);
1909
+ };
1910
+ }
1911
+
1912
+ // /!\ This function is not intended for public use! It's only exported from
1913
+ // here in order to share some common logic with sliding-sync-sdk.ts.
1914
+ export function _createAndReEmitRoom(client: BriijClient, roomId: string, opts: Partial<IStoredClientOpts>): Room {
1915
+ const { timelineSupport } = client;
1916
+
1917
+ const room = new Room(roomId, client, client.getUserId()!, {
1918
+ lazyLoadMembers: opts.lazyLoadMembers,
1919
+ pendingEventOrdering: opts.pendingEventOrdering,
1920
+ timelineSupport,
1921
+ });
1922
+
1923
+ client.reEmitter.reEmit(room, [
1924
+ RoomEvent.Name,
1925
+ RoomEvent.Redaction,
1926
+ RoomEvent.RedactionCancelled,
1927
+ RoomEvent.Receipt,
1928
+ RoomEvent.Tags,
1929
+ RoomEvent.LocalEchoUpdated,
1930
+ RoomEvent.AccountData,
1931
+ RoomEvent.MyMembership,
1932
+ RoomEvent.Timeline,
1933
+ RoomEvent.TimelineReset,
1934
+ RoomStateEvent.Events,
1935
+ RoomStateEvent.Members,
1936
+ RoomStateEvent.NewMember,
1937
+ RoomStateEvent.Update,
1938
+ BeaconEvent.New,
1939
+ BeaconEvent.Update,
1940
+ BeaconEvent.Destroy,
1941
+ BeaconEvent.LivenessChange,
1942
+ ]);
1943
+
1944
+ // We need to add a listener for RoomState.members in order to hook them
1945
+ // correctly.
1946
+ room.on(RoomStateEvent.NewMember, (event, state, member) => {
1947
+ member.user = client.getUser(member.userId) ?? undefined;
1948
+ client.reEmitter.reEmit(member, [
1949
+ RoomMemberEvent.Name,
1950
+ RoomMemberEvent.Typing,
1951
+ RoomMemberEvent.PowerLevel,
1952
+ RoomMemberEvent.Membership,
1953
+ ]);
1954
+ });
1955
+
1956
+ return room;
1957
+ }
1958
+
1959
+ /**
1960
+ * Process a list of (decrypted, where possible) received to-device events.
1961
+ *
1962
+ * Emits the appropriate {@link ClientEvent.ReceivedToDeviceMessage} event.
1963
+ * Also converts the events into `BriijEvent`s, and emits the now deprecated {@link ClientEvent.ToDeviceEvent} events for compatibility.
1964
+ * */
1965
+ export function processToDeviceMessages(toDeviceMessages: ReceivedToDeviceMessage[], client: BriijClient): void {
1966
+ const cancelledKeyVerificationTxns: string[] = [];
1967
+ toDeviceMessages
1968
+ .map((processedMessage) => {
1969
+ // map is a cheap inline forEach
1970
+ // We want to flag m.key.verification.start events as cancelled
1971
+ // if there's an accompanying m.key.verification.cancel event, so
1972
+ // we pull out the transaction IDs from the cancellation events
1973
+ // so we can flag the verification events as cancelled in the loop
1974
+ // below.
1975
+ if (processedMessage.message.type === "m.key.verification.cancel") {
1976
+ const txnId: string = processedMessage.message.content["transaction_id"];
1977
+ if (txnId) {
1978
+ cancelledKeyVerificationTxns.push(txnId);
1979
+ }
1980
+ }
1981
+
1982
+ // as mentioned above, .map is a cheap inline forEach, so return
1983
+ // the unmodified event.
1984
+ return processedMessage;
1985
+ })
1986
+ .forEach(function (processedEvent) {
1987
+ // For backwards compatibility, we also emit the event as a `BriijEvent` using `ClientEvent.ToDeviceEvent`.
1988
+ {
1989
+ const toDeviceEvent = processedEvent.message;
1990
+ const content = toDeviceEvent.content;
1991
+ // The message is cloned before being passed to the BriijEvent constructor, because
1992
+ // the `makeEncrypted` method will mutate the type and content properties of the original message and will interfere
1993
+ // with the emitted event for `ReceivedToDeviceMessage`.
1994
+ const deprecatedCompatibilityEvent = new BriijEvent(Object.assign({}, toDeviceEvent));
1995
+ if (
1996
+ toDeviceEvent.type === "m.key.verification.start" ||
1997
+ toDeviceEvent.type === "m.key.verification.request"
1998
+ ) {
1999
+ const txnId = content["transaction_id"];
2000
+ if (cancelledKeyVerificationTxns.includes(txnId)) {
2001
+ deprecatedCompatibilityEvent.flagCancelled();
2002
+ }
2003
+ }
2004
+ if (processedEvent.encryptionInfo) {
2005
+ // Restore partially the legacy behavior to detect encrypted messages.
2006
+ // Now `event.isEncrypted()` will return true.
2007
+ deprecatedCompatibilityEvent.makeEncrypted(
2008
+ EventType.RoomMessageEncrypted,
2009
+ { ciphertext: "" },
2010
+ processedEvent.encryptionInfo.senderCurve25519KeyBase64,
2011
+ "",
2012
+ );
2013
+ }
2014
+
2015
+ client.emit(ClientEvent.ToDeviceEvent, deprecatedCompatibilityEvent);
2016
+ }
2017
+
2018
+ client.emit(ClientEvent.ReceivedToDeviceMessage, processedEvent);
2019
+ });
2020
+ }