matrix-js-sdk 37.1.0 → 37.2.0-rc.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 (72) hide show
  1. package/git-revision.txt +1 -1
  2. package/lib/client.d.ts +11 -1
  3. package/lib/client.d.ts.map +1 -1
  4. package/lib/client.js +24 -5
  5. package/lib/client.js.map +1 -1
  6. package/lib/content-helpers.d.ts.map +1 -1
  7. package/lib/crypto-api/index.d.ts +9 -0
  8. package/lib/crypto-api/index.d.ts.map +1 -1
  9. package/lib/crypto-api/index.js.map +1 -1
  10. package/lib/embedded.d.ts.map +1 -1
  11. package/lib/embedded.js +27 -14
  12. package/lib/embedded.js.map +1 -1
  13. package/lib/errors.d.ts +7 -0
  14. package/lib/errors.d.ts.map +1 -1
  15. package/lib/errors.js +11 -0
  16. package/lib/errors.js.map +1 -1
  17. package/lib/http-api/fetch.d.ts +4 -2
  18. package/lib/http-api/fetch.d.ts.map +1 -1
  19. package/lib/http-api/fetch.js.map +1 -1
  20. package/lib/matrixrtc/EncryptionManager.d.ts.map +1 -1
  21. package/lib/matrixrtc/{MembershipManager.d.ts → LegacyMembershipManager.d.ts} +4 -40
  22. package/lib/matrixrtc/LegacyMembershipManager.d.ts.map +1 -0
  23. package/lib/matrixrtc/{MembershipManager.js → LegacyMembershipManager.js} +19 -11
  24. package/lib/matrixrtc/LegacyMembershipManager.js.map +1 -0
  25. package/lib/matrixrtc/LivekitFocus.d.ts.map +1 -1
  26. package/lib/matrixrtc/MatrixRTCSession.d.ts +28 -1
  27. package/lib/matrixrtc/MatrixRTCSession.d.ts.map +1 -1
  28. package/lib/matrixrtc/MatrixRTCSession.js +19 -5
  29. package/lib/matrixrtc/MatrixRTCSession.js.map +1 -1
  30. package/lib/matrixrtc/NewMembershipManager.d.ts +210 -0
  31. package/lib/matrixrtc/NewMembershipManager.d.ts.map +1 -0
  32. package/lib/matrixrtc/NewMembershipManager.js +784 -0
  33. package/lib/matrixrtc/NewMembershipManager.js.map +1 -0
  34. package/lib/matrixrtc/NewMembershipManagerActionScheduler.d.ts +57 -0
  35. package/lib/matrixrtc/NewMembershipManagerActionScheduler.d.ts.map +1 -0
  36. package/lib/matrixrtc/NewMembershipManagerActionScheduler.js +124 -0
  37. package/lib/matrixrtc/NewMembershipManagerActionScheduler.js.map +1 -0
  38. package/lib/models/beacon.d.ts.map +1 -1
  39. package/lib/models/poll.d.ts.map +1 -1
  40. package/lib/oidc/authorize.d.ts.map +1 -1
  41. package/lib/oidc/discovery.d.ts.map +1 -1
  42. package/lib/oidc/register.d.ts +2 -1
  43. package/lib/oidc/register.d.ts.map +1 -1
  44. package/lib/oidc/register.js +15 -4
  45. package/lib/oidc/register.js.map +1 -1
  46. package/lib/oidc/validate.d.ts.map +1 -1
  47. package/lib/rust-crypto/rust-crypto.d.ts +9 -0
  48. package/lib/rust-crypto/rust-crypto.d.ts.map +1 -1
  49. package/lib/rust-crypto/rust-crypto.js +136 -106
  50. package/lib/rust-crypto/rust-crypto.js.map +1 -1
  51. package/lib/store/indexeddb-store-worker.d.ts.map +1 -1
  52. package/lib/testing.d.ts.map +1 -1
  53. package/lib/utils.d.ts +8 -0
  54. package/lib/utils.d.ts.map +1 -1
  55. package/lib/utils.js +20 -3
  56. package/lib/utils.js.map +1 -1
  57. package/lib/webrtc/call.d.ts.map +1 -1
  58. package/package.json +4 -4
  59. package/src/client.ts +35 -5
  60. package/src/crypto-api/index.ts +10 -0
  61. package/src/embedded.ts +62 -27
  62. package/src/errors.ts +13 -0
  63. package/src/http-api/fetch.ts +4 -4
  64. package/src/matrixrtc/{MembershipManager.ts → LegacyMembershipManager.ts} +19 -39
  65. package/src/matrixrtc/MatrixRTCSession.ts +52 -7
  66. package/src/matrixrtc/NewMembershipManager.ts +943 -0
  67. package/src/matrixrtc/NewMembershipManagerActionScheduler.ts +133 -0
  68. package/src/oidc/register.ts +17 -4
  69. package/src/rust-crypto/rust-crypto.ts +37 -11
  70. package/src/utils.ts +17 -0
  71. package/lib/matrixrtc/MembershipManager.d.ts.map +0 -1
  72. package/lib/matrixrtc/MembershipManager.js.map +0 -1
@@ -1,5 +1,21 @@
1
1
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ /*
4
+ Copyright 2025 The Matrix.org Foundation C.I.C.
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ */
18
+
3
19
  import { EventType } from "../@types/event.js";
4
20
  import { UpdateDelayedEventAction } from "../@types/requests.js";
5
21
  import { HTTPError, MatrixError } from "../http-api/errors.js";
@@ -8,15 +24,6 @@ import { EventTimeline } from "../models/event-timeline.js";
8
24
  import { sleep } from "../utils.js";
9
25
  import { DEFAULT_EXPIRE_DURATION } from "./CallMembership.js";
10
26
  import { isLivekitFocusActive } from "./LivekitFocus.js";
11
-
12
- /**
13
- * This interface defines what a MembershipManager uses and exposes.
14
- * This interface is what we use to write tests and allows to change the actual implementation
15
- * Without breaking tests because of some internal method renaming.
16
- *
17
- * @internal
18
- */
19
-
20
27
  /**
21
28
  * This internal class is used by the MatrixRTCSession to manage the local user's own membership of the session.
22
29
  *
@@ -31,7 +38,8 @@ import { isLivekitFocusActive } from "./LivekitFocus.js";
31
38
  *
32
39
  * It is recommended to only use this interface for testing to allow replacing this class.
33
40
  *
34
- * @internal
41
+ * @internal
42
+ * @deprecated Use {@link MembershipManager} instead
35
43
  */
36
44
  export class LegacyMembershipManager {
37
45
  get callMemberEventRetryDelayMinimum() {
@@ -331,4 +339,4 @@ function _resendIfRateLimited() {
331
339
  });
332
340
  return _resendIfRateLimited.apply(this, arguments);
333
341
  }
334
- //# sourceMappingURL=MembershipManager.js.map
342
+ //# sourceMappingURL=LegacyMembershipManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LegacyMembershipManager.js","names":["EventType","UpdateDelayedEventAction","HTTPError","MatrixError","logger","EventTimeline","sleep","DEFAULT_EXPIRE_DURATION","isLivekitFocusActive","LegacyMembershipManager","callMemberEventRetryDelayMinimum","_this$joinConfig$call","_this$joinConfig","joinConfig","membershipExpiryTimeout","_this$joinConfig$memb","_this$joinConfig2","membershipServerSideExpiryTimeout","_ref","_this$membershipServe","_this$joinConfig3","membershipServerSideExpiryTimeoutOverride","membershipKeepAlivePeriod","_this$joinConfig$memb2","_this$joinConfig4","callMemberEventRetryJitter","_this$joinConfig$call2","_this$joinConfig5","constructor","room","client","getOldestMembership","_this","_defineProperty","_asyncToGenerator","updateCallMembershipRunning","needCallMembershipUpdate","updateCallMembershipEvent","knownDisconnectDelayId","disconnectDelayId","resendIfRateLimited","_unstable_updateDelayedEvent","Restart","scheduleDelayDisconnection","e","error","isJoined","relativeExpiry","undefined","join","fociPreferred","fociActive","ownFocusActive","ownFociPreferred","triggerCallMembershipEventUpdate","leave","_arguments","arguments","_this2","timeout","length","memberEventTimeout","clearTimeout","raceResult","Promise","race","onRTCSessionMemberUpdate","memberships","_this3","isMyMembership","m","sender","getUserId","deviceId","getDeviceId","some","warn","getActiveFocus","focus_selection","oldestMembership","getPreferredFoci","makeNewMembership","makeMyMembership","_this$ownFociPreferre","call_id","scope","application","device_id","expires","focus_active","type","foci_preferred","_this4","roomState","getLiveTimeline","getState","FORWARDS","Error","roomId","localUserId","localDeviceId","newContent","stateKey","makeMembershipStateKey","prepareDelayedDisconnection","_ref4","res","_unstable_sendDelayedStateEvent","delay","GroupCallMemberPrefix","delay_id","errcode","data","maxDelayAllowed","apply","sendStateEvent","sentDelayedDisconnect","Send","info","resendDelay","Math","random","concat","setTimeout","delayDisconnection","exec","getVersion","_x","_resendIfRateLimited","func","numRetriesAllowed","isRateLimitError","defaultMs","_e$getRetryAfterMs","getRetryAfterMs"],"sources":["../../src/matrixrtc/LegacyMembershipManager.ts"],"sourcesContent":["/*\nCopyright 2025 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { EventType } from \"../@types/event.ts\";\nimport { UpdateDelayedEventAction } from \"../@types/requests.ts\";\nimport type { MatrixClient } from \"../client.ts\";\nimport { HTTPError, MatrixError } from \"../http-api/errors.ts\";\nimport { logger } from \"../logger.ts\";\nimport { EventTimeline } from \"../models/event-timeline.ts\";\nimport { type Room } from \"../models/room.ts\";\nimport { sleep } from \"../utils.ts\";\nimport { type CallMembership, DEFAULT_EXPIRE_DURATION, type SessionMembershipData } from \"./CallMembership.ts\";\nimport { type Focus } from \"./focus.ts\";\nimport { isLivekitFocusActive } from \"./LivekitFocus.ts\";\nimport { type MembershipConfig } from \"./MatrixRTCSession.ts\";\nimport { type EmptyObject } from \"../@types/common.ts\";\nimport { type IMembershipManager } from \"./NewMembershipManager.ts\";\n\n/**\n * This internal class is used by the MatrixRTCSession to manage the local user's own membership of the session.\n *\n * Its responsibitiy is to manage the locals user membership:\n * - send that sate event\n * - send the delayed leave event\n * - update the delayed leave event while connected\n * - update the state event when it times out (for calls longer than membershipExpiryTimeout ~ 4h)\n *\n * It is possible to test this class on its own. The api surface (to use for tests) is\n * defined in `MembershipManagerInterface`.\n *\n * It is recommended to only use this interface for testing to allow replacing this class.\n *\n * @internal\n * @deprecated Use {@link MembershipManager} instead\n */\nexport class LegacyMembershipManager implements IMembershipManager {\n private relativeExpiry: number | undefined;\n\n private memberEventTimeout?: ReturnType<typeof setTimeout>;\n\n /**\n * This is a Foci array that contains the Focus objects this user is aware of and proposes to use.\n */\n private ownFociPreferred?: Focus[];\n /**\n * This is a Focus with the specified fields for an ActiveFocus (e.g. LivekitFocusActive for type=\"livekit\")\n */\n private ownFocusActive?: Focus;\n\n private updateCallMembershipRunning = false;\n private needCallMembershipUpdate = false;\n /**\n * If the server disallows the configured {@link membershipServerSideExpiryTimeout},\n * this stores a delay that the server does allow.\n */\n private membershipServerSideExpiryTimeoutOverride?: number;\n private disconnectDelayId: string | undefined;\n\n private get callMemberEventRetryDelayMinimum(): number {\n return this.joinConfig?.callMemberEventRetryDelayMinimum ?? 3_000;\n }\n private get membershipExpiryTimeout(): number {\n return this.joinConfig?.membershipExpiryTimeout ?? DEFAULT_EXPIRE_DURATION;\n }\n private get membershipServerSideExpiryTimeout(): number {\n return (\n this.membershipServerSideExpiryTimeoutOverride ??\n this.joinConfig?.membershipServerSideExpiryTimeout ??\n 8_000\n );\n }\n private get membershipKeepAlivePeriod(): number {\n return this.joinConfig?.membershipKeepAlivePeriod ?? 5_000;\n }\n private get callMemberEventRetryJitter(): number {\n return this.joinConfig?.callMemberEventRetryJitter ?? 2_000;\n }\n\n public constructor(\n private joinConfig: MembershipConfig | undefined,\n private room: Pick<Room, \"getLiveTimeline\" | \"roomId\" | \"getVersion\">,\n private client: Pick<\n MatrixClient,\n | \"getUserId\"\n | \"getDeviceId\"\n | \"sendStateEvent\"\n | \"_unstable_sendDelayedStateEvent\"\n | \"_unstable_updateDelayedEvent\"\n >,\n private getOldestMembership: () => CallMembership | undefined,\n ) {}\n\n public isJoined(): boolean {\n return this.relativeExpiry !== undefined;\n }\n\n public join(fociPreferred: Focus[], fociActive?: Focus): void {\n this.ownFocusActive = fociActive;\n this.ownFociPreferred = fociPreferred;\n this.relativeExpiry = this.membershipExpiryTimeout;\n // We don't wait for this, mostly because it may fail and schedule a retry, so this\n // function returning doesn't really mean anything at all.\n void this.triggerCallMembershipEventUpdate();\n }\n\n public async leave(timeout: number | undefined = undefined): Promise<boolean> {\n this.relativeExpiry = undefined;\n this.ownFocusActive = undefined;\n\n if (this.memberEventTimeout) {\n clearTimeout(this.memberEventTimeout);\n this.memberEventTimeout = undefined;\n }\n if (timeout) {\n // The sleep promise returns the string 'timeout' and the membership update void\n // A success implies that the membership update was quicker then the timeout.\n const raceResult = await Promise.race([this.triggerCallMembershipEventUpdate(), sleep(timeout, \"timeout\")]);\n return raceResult !== \"timeout\";\n } else {\n await this.triggerCallMembershipEventUpdate();\n return true;\n }\n }\n\n public async onRTCSessionMemberUpdate(memberships: CallMembership[]): Promise<void> {\n const isMyMembership = (m: CallMembership): boolean =>\n m.sender === this.client.getUserId() && m.deviceId === this.client.getDeviceId();\n\n if (this.isJoined() && !memberships.some(isMyMembership)) {\n logger.warn(\"Missing own membership: force re-join\");\n // TODO: Should this be awaited? And is there anything to tell the focus?\n return this.triggerCallMembershipEventUpdate();\n }\n }\n\n public getActiveFocus(): Focus | undefined {\n if (this.ownFocusActive) {\n // A livekit active focus\n if (isLivekitFocusActive(this.ownFocusActive)) {\n if (this.ownFocusActive.focus_selection === \"oldest_membership\") {\n const oldestMembership = this.getOldestMembership();\n return oldestMembership?.getPreferredFoci()[0];\n }\n } else {\n logger.warn(\"Unknown own ActiveFocus type. This makes it impossible to connect to an SFU.\");\n }\n } else {\n // We do not understand the membership format (could be legacy). We default to oldestMembership\n // Once there are other methods this is a hard error!\n const oldestMembership = this.getOldestMembership();\n return oldestMembership?.getPreferredFoci()[0];\n }\n }\n\n private triggerCallMembershipEventUpdate = async (): Promise<void> => {\n // TODO: Should this await on a shared promise?\n if (this.updateCallMembershipRunning) {\n this.needCallMembershipUpdate = true;\n return;\n }\n\n this.updateCallMembershipRunning = true;\n try {\n // if anything triggers an update while the update is running, do another update afterwards\n do {\n this.needCallMembershipUpdate = false;\n await this.updateCallMembershipEvent();\n } while (this.needCallMembershipUpdate);\n } finally {\n this.updateCallMembershipRunning = false;\n }\n };\n private makeNewMembership(deviceId: string): SessionMembershipData | EmptyObject {\n // If we're joined, add our own\n if (this.isJoined()) {\n return this.makeMyMembership(deviceId);\n }\n return {};\n }\n\n /**\n * Constructs our own membership\n */\n private makeMyMembership(deviceId: string): SessionMembershipData {\n return {\n call_id: \"\",\n scope: \"m.room\",\n application: \"m.call\",\n device_id: deviceId,\n expires: this.relativeExpiry,\n focus_active: { type: \"livekit\", focus_selection: \"oldest_membership\" },\n foci_preferred: this.ownFociPreferred ?? [],\n };\n }\n\n private async updateCallMembershipEvent(): Promise<void> {\n if (this.memberEventTimeout) {\n clearTimeout(this.memberEventTimeout);\n this.memberEventTimeout = undefined;\n }\n\n const roomState = this.room.getLiveTimeline().getState(EventTimeline.FORWARDS);\n if (!roomState) throw new Error(\"Couldn't get room state for room \" + this.room.roomId);\n\n const localUserId = this.client.getUserId();\n const localDeviceId = this.client.getDeviceId();\n if (!localUserId || !localDeviceId) throw new Error(\"User ID or device ID was null!\");\n\n let newContent: EmptyObject | SessionMembershipData = {};\n // TODO: add back expiary logic to non-legacy events\n // previously we checked here if the event is timed out and scheduled a check if not.\n // maybe there is a better way.\n newContent = this.makeNewMembership(localDeviceId);\n\n try {\n if (this.isJoined()) {\n const stateKey = this.makeMembershipStateKey(localUserId, localDeviceId);\n const prepareDelayedDisconnection = async (): Promise<void> => {\n try {\n const res = await resendIfRateLimited(() =>\n this.client._unstable_sendDelayedStateEvent(\n this.room.roomId,\n {\n delay: this.membershipServerSideExpiryTimeout,\n },\n EventType.GroupCallMemberPrefix,\n {}, // leave event\n stateKey,\n ),\n );\n this.disconnectDelayId = res.delay_id;\n } catch (e) {\n if (\n e instanceof MatrixError &&\n e.errcode === \"M_UNKNOWN\" &&\n e.data[\"org.matrix.msc4140.errcode\"] === \"M_MAX_DELAY_EXCEEDED\"\n ) {\n const maxDelayAllowed = e.data[\"org.matrix.msc4140.max_delay\"];\n if (\n typeof maxDelayAllowed === \"number\" &&\n this.membershipServerSideExpiryTimeout > maxDelayAllowed\n ) {\n this.membershipServerSideExpiryTimeoutOverride = maxDelayAllowed;\n return prepareDelayedDisconnection();\n }\n }\n logger.error(\"Failed to prepare delayed disconnection event:\", e);\n }\n };\n\n await prepareDelayedDisconnection();\n // Send join event _after_ preparing the delayed disconnection event\n await resendIfRateLimited(() =>\n this.client.sendStateEvent(this.room.roomId, EventType.GroupCallMemberPrefix, newContent, stateKey),\n );\n // If sending state cancels your own delayed state, prepare another delayed state\n // TODO: Remove this once MSC4140 is stable & doesn't cancel own delayed state\n if (this.disconnectDelayId !== undefined) {\n try {\n const knownDisconnectDelayId = this.disconnectDelayId;\n await resendIfRateLimited(() =>\n this.client._unstable_updateDelayedEvent(\n knownDisconnectDelayId,\n UpdateDelayedEventAction.Restart,\n ),\n );\n } catch (e) {\n if (e instanceof MatrixError && e.errcode === \"M_NOT_FOUND\") {\n // If we get a M_NOT_FOUND we prepare a new delayed event.\n // In other error cases we do not want to prepare anything since we do not have the guarantee, that the\n // future is not still running.\n logger.warn(\"Failed to update delayed disconnection event, prepare it again:\", e);\n this.disconnectDelayId = undefined;\n await prepareDelayedDisconnection();\n }\n }\n }\n if (this.disconnectDelayId !== undefined) {\n this.scheduleDelayDisconnection();\n }\n // TODO throw or log an error if this.disconnectDelayId === undefined\n } else {\n // Not joined\n let sentDelayedDisconnect = false;\n if (this.disconnectDelayId !== undefined) {\n try {\n const knownDisconnectDelayId = this.disconnectDelayId;\n await resendIfRateLimited(() =>\n this.client._unstable_updateDelayedEvent(\n knownDisconnectDelayId,\n UpdateDelayedEventAction.Send,\n ),\n );\n sentDelayedDisconnect = true;\n } catch (e) {\n logger.error(\"Failed to send our delayed disconnection event:\", e);\n }\n this.disconnectDelayId = undefined;\n }\n if (!sentDelayedDisconnect) {\n await resendIfRateLimited(() =>\n this.client.sendStateEvent(\n this.room.roomId,\n EventType.GroupCallMemberPrefix,\n {},\n this.makeMembershipStateKey(localUserId, localDeviceId),\n ),\n );\n }\n }\n logger.info(\"Sent updated call member event.\");\n } catch (e) {\n const resendDelay = this.callMemberEventRetryDelayMinimum + Math.random() * this.callMemberEventRetryJitter;\n logger.warn(`Failed to send call member event (retrying in ${resendDelay}): ${e}`);\n await sleep(resendDelay);\n await this.triggerCallMembershipEventUpdate();\n }\n }\n\n private scheduleDelayDisconnection(): void {\n this.memberEventTimeout = setTimeout(() => void this.delayDisconnection(), this.membershipKeepAlivePeriod);\n }\n\n private readonly delayDisconnection = async (): Promise<void> => {\n try {\n const knownDisconnectDelayId = this.disconnectDelayId!;\n await resendIfRateLimited(() =>\n this.client._unstable_updateDelayedEvent(knownDisconnectDelayId, UpdateDelayedEventAction.Restart),\n );\n this.scheduleDelayDisconnection();\n } catch (e) {\n logger.error(\"Failed to delay our disconnection event:\", e);\n }\n };\n\n private makeMembershipStateKey(localUserId: string, localDeviceId: string): string {\n const stateKey = `${localUserId}_${localDeviceId}`;\n if (/^org\\.matrix\\.msc(3757|3779)\\b/.exec(this.room.getVersion())) {\n return stateKey;\n } else {\n return `_${stateKey}`;\n }\n }\n}\n\nasync function resendIfRateLimited<T>(func: () => Promise<T>, numRetriesAllowed: number = 1): Promise<T> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n try {\n return await func();\n } catch (e) {\n if (numRetriesAllowed > 0 && e instanceof HTTPError && e.isRateLimitError()) {\n numRetriesAllowed--;\n let resendDelay: number;\n const defaultMs = 5000;\n try {\n resendDelay = e.getRetryAfterMs() ?? defaultMs;\n logger.info(`Rate limited by server, retrying in ${resendDelay}ms`);\n } catch (e) {\n logger.warn(\n `Error while retrieving a rate-limit retry delay, retrying after default delay of ${defaultMs}`,\n e,\n );\n resendDelay = defaultMs;\n }\n await sleep(resendDelay);\n } else {\n throw e;\n }\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"LivekitFocus.d.ts","sourceRoot":"","sources":["../../src/matrixrtc/LivekitFocus.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,WAAW,kBAAmB,SAAQ,KAAK;IAC7C,IAAI,EAAE,SAAS,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,oBAAoB,WAAY,GAAG,KAAG,MAAM,IAAI,kBACG,CAAC;AAEjE,MAAM,WAAW,YAAa,SAAQ,kBAAkB;IACpD,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,cAAc,WAAY,GAAG,KAAG,MAAM,IAAI,YACM,CAAC;AAE9D,MAAM,WAAW,kBAAmB,SAAQ,KAAK;IAC7C,IAAI,EAAE,SAAS,CAAC;IAChB,eAAe,EAAE,mBAAmB,CAAC;CACxC;AACD,eAAO,MAAM,oBAAoB,WAAY,GAAG,KAAG,MAAM,IAAI,kBACD,CAAC"}
1
+ {"version":3,"file":"LivekitFocus.d.ts","sourceRoot":"","sources":["../../src/matrixrtc/LivekitFocus.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,WAAW,kBAAmB,SAAQ,KAAK;IAC7C,IAAI,EAAE,SAAS,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,oBAAoB,GAAI,QAAQ,GAAG,KAAG,MAAM,IAAI,kBACG,CAAC;AAEjE,MAAM,WAAW,YAAa,SAAQ,kBAAkB;IACpD,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,cAAc,GAAI,QAAQ,GAAG,KAAG,MAAM,IAAI,YACM,CAAC;AAE9D,MAAM,WAAW,kBAAmB,SAAQ,KAAK;IAC7C,IAAI,EAAE,SAAS,CAAC;IAChB,eAAe,EAAE,mBAAmB,CAAC;CACxC;AACD,eAAO,MAAM,oBAAoB,GAAI,QAAQ,GAAG,KAAG,MAAM,IAAI,kBACD,CAAC"}
@@ -8,14 +8,23 @@ import { type Statistics } from "./EncryptionManager.ts";
8
8
  export declare enum MatrixRTCSessionEvent {
9
9
  MembershipsChanged = "memberships_changed",
10
10
  JoinStateChanged = "join_state_changed",
11
- EncryptionKeyChanged = "encryption_key_changed"
11
+ EncryptionKeyChanged = "encryption_key_changed",
12
+ /** The membership manager had to shut down caused by an unrecoverable error */
13
+ MembershipManagerError = "membership_manager_error"
12
14
  }
13
15
  export type MatrixRTCSessionEventHandlerMap = {
14
16
  [MatrixRTCSessionEvent.MembershipsChanged]: (oldMemberships: CallMembership[], newMemberships: CallMembership[]) => void;
15
17
  [MatrixRTCSessionEvent.JoinStateChanged]: (isJoined: boolean) => void;
16
18
  [MatrixRTCSessionEvent.EncryptionKeyChanged]: (key: Uint8Array, encryptionKeyIndex: number, participantId: string) => void;
19
+ [MatrixRTCSessionEvent.MembershipManagerError]: (error: unknown) => void;
17
20
  };
18
21
  export interface MembershipConfig {
22
+ /**
23
+ * Use the new Manager.
24
+ *
25
+ * Default: `false`.
26
+ */
27
+ useNewMembershipManager?: boolean;
19
28
  /**
20
29
  * The timeout (in milliseconds) after we joined the call, that our membership should expire
21
30
  * unless we have explicitly updated it.
@@ -23,6 +32,16 @@ export interface MembershipConfig {
23
32
  * This is what goes into the m.rtc.member event expiry field and is typically set to a number of hours.
24
33
  */
25
34
  membershipExpiryTimeout?: number;
35
+ /**
36
+ * The time in (in milliseconds) which the manager will prematurely send the updated state event before the membership `expires` time to make sure it
37
+ * sends the updated state event early enough.
38
+ *
39
+ * A headroom of 1000ms and a `membershipExpiryTimeout` of 10000ms would result in the first membership event update after 9s and
40
+ * a membership event that would be considered expired after 10s.
41
+ *
42
+ * This value does not have an effect on the value of `SessionMembershipData.expires`.
43
+ */
44
+ membershipExpiryTimeoutHeadroom?: number;
26
45
  /**
27
46
  * The period (in milliseconds) with which we check that our membership event still exists on the
28
47
  * server. If it is not found we create it again.
@@ -46,6 +65,14 @@ export interface MembershipConfig {
46
65
  * @deprecated It should be possible to make it stable without this.
47
66
  */
48
67
  callMemberEventRetryJitter?: number;
68
+ /**
69
+ * The maximum number of retries that the manager will do for delayed event sending/updating and state event sending when a server rate limit has been hit.
70
+ */
71
+ maximumRateLimitRetryCount?: number;
72
+ /**
73
+ * The maximum number of retries that the manager will do for delayed event sending/updating and state event sending when a network error occurs.
74
+ */
75
+ maximumNetworkErrorRetryCount?: number;
49
76
  }
50
77
  export interface EncryptionConfig {
51
78
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"MatrixRTCSession.d.ts","sourceRoot":"","sources":["../../src/matrixrtc/MatrixRTCSession.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MatrixRTCSession.d.ts","sourceRoot":"","sources":["../../src/matrixrtc/MatrixRTCSession.ts"],"names":[],"mappings":"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"}
@@ -23,13 +23,16 @@ import { EventType } from "../@types/event.js";
23
23
  import { CallMembership } from "./CallMembership.js";
24
24
  import { RoomStateEvent } from "../models/room-state.js";
25
25
  import { KnownMembership } from "../@types/membership.js";
26
- import { LegacyMembershipManager } from "./MembershipManager.js";
26
+ import { MembershipManager } from "./NewMembershipManager.js";
27
27
  import { EncryptionManager } from "./EncryptionManager.js";
28
+ import { LegacyMembershipManager } from "./LegacyMembershipManager.js";
29
+ import { logDurationSync } from "../utils.js";
28
30
  var logger = rootLogger.getChild("MatrixRTCSession");
29
31
  export var MatrixRTCSessionEvent = /*#__PURE__*/function (MatrixRTCSessionEvent) {
30
32
  MatrixRTCSessionEvent["MembershipsChanged"] = "memberships_changed";
31
33
  MatrixRTCSessionEvent["JoinStateChanged"] = "join_state_changed";
32
34
  MatrixRTCSessionEvent["EncryptionKeyChanged"] = "encryption_key_changed";
35
+ MatrixRTCSessionEvent["MembershipManagerError"] = "membership_manager_error";
33
36
  return MatrixRTCSessionEvent;
34
37
  }({});
35
38
  /**
@@ -201,7 +204,9 @@ export class MatrixRTCSession extends TypedEventEmitter {
201
204
  if (changed) {
202
205
  var _this$membershipManag;
203
206
  logger.info("Memberships for call in room ".concat(this.roomSubset.roomId, " have changed: emitting"));
204
- this.emit(MatrixRTCSessionEvent.MembershipsChanged, oldMemberships, this.memberships);
207
+ logDurationSync(logger, "emit MatrixRTCSessionEvent.MembershipsChanged", () => {
208
+ this.emit(MatrixRTCSessionEvent.MembershipsChanged, oldMemberships, this.memberships);
209
+ });
205
210
  void ((_this$membershipManag = this.membershipManager) === null || _this$membershipManag === void 0 ? void 0 : _this$membershipManag.onRTCSessionMemberUpdate(this.memberships));
206
211
  }
207
212
  // This also needs to be done if `changed` = false
@@ -260,16 +265,25 @@ export class MatrixRTCSession extends TypedEventEmitter {
260
265
  * @param joinConfig - Additional configuration for the joined session.
261
266
  */
262
267
  joinRoomSession(fociPreferred, fociActive, joinConfig) {
263
- // create MembershipManager
264
268
  if (this.isJoined()) {
265
269
  logger.info("Already joined to session in room ".concat(this.roomSubset.roomId, ": ignoring join call"));
266
270
  return;
267
271
  } else {
268
- this.membershipManager = new LegacyMembershipManager(joinConfig, this.roomSubset, this.client, () => this.getOldestMembership());
272
+ var _joinConfig$useNewMem;
273
+ // Create MembershipManager
274
+ if ((_joinConfig$useNewMem = joinConfig === null || joinConfig === void 0 ? void 0 : joinConfig.useNewMembershipManager) !== null && _joinConfig$useNewMem !== void 0 ? _joinConfig$useNewMem : false) {
275
+ this.membershipManager = new MembershipManager(joinConfig, this.roomSubset, this.client, () => this.getOldestMembership());
276
+ } else {
277
+ this.membershipManager = new LegacyMembershipManager(joinConfig, this.roomSubset, this.client, () => this.getOldestMembership());
278
+ }
269
279
  }
270
280
 
271
281
  // Join!
272
- this.membershipManager.join(fociPreferred, fociActive);
282
+ this.membershipManager.join(fociPreferred, fociActive, e => {
283
+ logger.error("MembershipManager encountered an unrecoverable error: ", e);
284
+ this.emit(MatrixRTCSessionEvent.MembershipManagerError, e);
285
+ this.emit(MatrixRTCSessionEvent.JoinStateChanged, this.isJoined());
286
+ });
273
287
  this.encryptionManager.join(joinConfig);
274
288
  this.emit(MatrixRTCSessionEvent.JoinStateChanged, true);
275
289
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MatrixRTCSession.js","names":["logger","rootLogger","TypedEventEmitter","EventTimeline","EventType","CallMembership","RoomStateEvent","KnownMembership","LegacyMembershipManager","EncryptionManager","getChild","MatrixRTCSessionEvent","MatrixRTCSession","statistics","encryptionManager","callId","_callId","callMembershipsForRoom","room","roomState","getLiveTimeline","getState","FORWARDS","warn","roomId","Error","callMemberEvents","getStateEvents","GroupCallMemberPrefix","callMemberships","memberEvent","content","getContent","eventKeysCount","Object","keys","length","membershipContents","push","membershipData","_membership$sender","membership","scope","info","isExpired","concat","sender","deviceId","hasMembershipState","Join","e","sort","a","b","createdTs","debug","map","m","roomSessionForRoom","client","roomSubset","constructor","memberships","_memberships$","_defineProperty","event","onCallEncryptionEventReceived","recalculateSessionMembers","_this$_callId","_this$memberships$","oldMemberships","changed","some","i","equal","_this$membershipManag","emit","MembershipsChanged","membershipManager","onRTCSessionMemberUpdate","onMembershipsUpdate","setExpiryTimer","on","Members","onRoomMemberUpdate","keyBin","encryptionKeyIndex","participantId","EncryptionKeyChanged","isJoined","_this$membershipManag2","_this$membershipManag3","stop","_this","_asyncToGenerator","_this$membershipManag4","leave","expiryTimeout","clearTimeout","undefined","off","joinRoomSession","fociPreferred","fociActive","joinConfig","getOldestMembership","join","JoinStateChanged","leaveRoomSession","_arguments","arguments","_this2","timeout","leavePromise","getActiveFocus","_this$membershipManag5","getFocusInUse","oldestMembership","getFocusSelection","getPreferredFoci","reemitEncryptionKeys","getEncryptionKeys","forEach","key","index","_this$encryptionManag","Map","Array","from","entries","_ref","k","values","soonestExpiry","thisExpiry","getMsUntilExpiry","setTimeout"],"sources":["../../src/matrixrtc/MatrixRTCSession.ts"],"sourcesContent":["/*\nCopyright 2023 - 2024 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { logger as rootLogger } from \"../logger.ts\";\nimport { TypedEventEmitter } from \"../models/typed-event-emitter.ts\";\nimport { EventTimeline } from \"../models/event-timeline.ts\";\nimport { type Room } from \"../models/room.ts\";\nimport { type MatrixClient } from \"../client.ts\";\nimport { EventType } from \"../@types/event.ts\";\nimport { CallMembership } from \"./CallMembership.ts\";\nimport { RoomStateEvent } from \"../models/room-state.ts\";\nimport { type Focus } from \"./focus.ts\";\nimport { KnownMembership } from \"../@types/membership.ts\";\nimport { type MatrixEvent } from \"../models/event.ts\";\nimport { LegacyMembershipManager, type IMembershipManager } from \"./MembershipManager.ts\";\nimport { EncryptionManager, type IEncryptionManager, type Statistics } from \"./EncryptionManager.ts\";\n\nconst logger = rootLogger.getChild(\"MatrixRTCSession\");\n\nexport enum MatrixRTCSessionEvent {\n // A member joined, left, or updated a property of their membership.\n MembershipsChanged = \"memberships_changed\",\n // We joined or left the session: our own local idea of whether we are joined,\n // separate from MembershipsChanged, ie. independent of whether our member event\n // has successfully gone through.\n JoinStateChanged = \"join_state_changed\",\n // The key used to encrypt media has changed\n EncryptionKeyChanged = \"encryption_key_changed\",\n}\n\nexport type MatrixRTCSessionEventHandlerMap = {\n [MatrixRTCSessionEvent.MembershipsChanged]: (\n oldMemberships: CallMembership[],\n newMemberships: CallMembership[],\n ) => void;\n [MatrixRTCSessionEvent.JoinStateChanged]: (isJoined: boolean) => void;\n [MatrixRTCSessionEvent.EncryptionKeyChanged]: (\n key: Uint8Array,\n encryptionKeyIndex: number,\n participantId: string,\n ) => void;\n};\n\nexport interface MembershipConfig {\n /**\n * The timeout (in milliseconds) after we joined the call, that our membership should expire\n * unless we have explicitly updated it.\n *\n * This is what goes into the m.rtc.member event expiry field and is typically set to a number of hours.\n */\n membershipExpiryTimeout?: number;\n\n /**\n * The period (in milliseconds) with which we check that our membership event still exists on the\n * server. If it is not found we create it again.\n */\n memberEventCheckPeriod?: number;\n\n /**\n * The minimum delay (in milliseconds) after which we will retry sending the membership event if it\n * failed to send.\n */\n callMemberEventRetryDelayMinimum?: number;\n\n /**\n * The timeout (in milliseconds) with which the deleayed leave event on the server is configured.\n * After this time the server will set the event to the disconnected stat if it has not received a keep-alive from the client.\n */\n membershipServerSideExpiryTimeout?: number;\n\n /**\n * The interval (in milliseconds) in which the client will send membership keep-alives to the server.\n */\n membershipKeepAlivePeriod?: number;\n\n /**\n * @deprecated It should be possible to make it stable without this.\n */\n callMemberEventRetryJitter?: number;\n}\n\nexport interface EncryptionConfig {\n /**\n * If true, generate and share a media key for this participant,\n * and emit MatrixRTCSessionEvent.EncryptionKeyChanged when\n * media keys for other participants become available.\n */\n manageMediaKeys?: boolean;\n /**\n * The minimum time (in milliseconds) between each attempt to send encryption key(s).\n * e.g. if this is set to 1000, then we will send at most one key event every second.\n */\n updateEncryptionKeyThrottle?: number;\n /**\n * The delay (in milliseconds) after a member leaves before we create and publish a new key, because people\n * tend to leave calls at the same time.\n */\n makeKeyDelay?: number;\n /**\n * The delay (in milliseconds) between creating and sending a new key and starting to encrypt with it. This\n * gives other a chance to receive the new key to minimise the chance they don't get media they can't decrypt.\n * The total time between a member leaving and the call switching to new keys is therefore:\n * makeKeyDelay + useKeyDelay\n */\n useKeyDelay?: number;\n}\nexport type JoinSessionConfig = MembershipConfig & EncryptionConfig;\n\n/**\n * A MatrixRTCSession manages the membership & properties of a MatrixRTC session.\n * This class doesn't deal with media at all, just membership & properties of a session.\n */\nexport class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSessionEvent, MatrixRTCSessionEventHandlerMap> {\n private membershipManager?: IMembershipManager;\n private encryptionManager: IEncryptionManager;\n // The session Id of the call, this is the call_id of the call Member event.\n private _callId: string | undefined;\n\n /**\n * This timeout is responsible to track any expiration. We need to know when we have to start\n * to ignore other call members. There is no callback for this. This timeout will always be configured to\n * emit when the next membership expires.\n */\n private expiryTimeout?: ReturnType<typeof setTimeout>;\n\n /**\n * The statistics for this session.\n */\n public get statistics(): Statistics {\n return this.encryptionManager.statistics;\n }\n\n /**\n * The callId (sessionId) of the call.\n *\n * It can be undefined since the callId is only known once the first membership joins.\n * The callId is the property that, per definition, groups memberships into one call.\n */\n public get callId(): string | undefined {\n return this._callId;\n }\n\n /**\n * Returns all the call memberships for a room, oldest first\n */\n public static callMembershipsForRoom(\n room: Pick<Room, \"getLiveTimeline\" | \"roomId\" | \"hasMembershipState\">,\n ): CallMembership[] {\n const roomState = room.getLiveTimeline().getState(EventTimeline.FORWARDS);\n if (!roomState) {\n logger.warn(\"Couldn't get state for room \" + room.roomId);\n throw new Error(\"Could't get state for room \" + room.roomId);\n }\n const callMemberEvents = roomState.getStateEvents(EventType.GroupCallMemberPrefix);\n\n const callMemberships: CallMembership[] = [];\n for (const memberEvent of callMemberEvents) {\n const content = memberEvent.getContent();\n const eventKeysCount = Object.keys(content).length;\n // Dont even bother about empty events (saves us from costly type/\"key in\" checks in bigger rooms)\n if (eventKeysCount === 0) continue;\n\n const membershipContents: any[] = [];\n\n // We first decide if its a MSC4143 event (per device state key)\n if (eventKeysCount > 1 && \"focus_active\" in content) {\n // We have a MSC4143 event membership event\n membershipContents.push(content);\n } else if (eventKeysCount === 1 && \"memberships\" in content) {\n logger.warn(`Legacy event found. Those are ignored, they do not contribute to the MatrixRTC session`);\n }\n\n if (membershipContents.length === 0) continue;\n\n for (const membershipData of membershipContents) {\n try {\n const membership = new CallMembership(memberEvent, membershipData);\n\n if (membership.callId !== \"\" || membership.scope !== \"m.room\") {\n // for now, just ignore anything that isn't a room scope call\n logger.info(`Ignoring user-scoped call`);\n continue;\n }\n\n if (membership.isExpired()) {\n logger.info(`Ignoring expired device membership ${membership.sender}/${membership.deviceId}`);\n continue;\n }\n if (!room.hasMembershipState(membership.sender ?? \"\", KnownMembership.Join)) {\n logger.info(`Ignoring membership of user ${membership.sender} who is not in the room.`);\n continue;\n }\n callMemberships.push(membership);\n } catch (e) {\n logger.warn(\"Couldn't construct call membership: \", e);\n }\n }\n }\n\n callMemberships.sort((a, b) => a.createdTs() - b.createdTs());\n if (callMemberships.length > 1) {\n logger.debug(\n `Call memberships in room ${room.roomId}, in order: `,\n callMemberships.map((m) => [m.createdTs(), m.sender]),\n );\n }\n\n return callMemberships;\n }\n\n /**\n * Return the MatrixRTC session for the room, whether there are currently active members or not\n */\n public static roomSessionForRoom(client: MatrixClient, room: Room): MatrixRTCSession {\n const callMemberships = MatrixRTCSession.callMembershipsForRoom(room);\n\n return new MatrixRTCSession(client, room, callMemberships);\n }\n\n /**\n * WARN: this can in theory only be a subset of the room with the properties required by\n * this class.\n * Outside of tests this most likely will be a full room, however.\n * @deprecated Relying on a full Room object being available here is an anti-pattern. You should be tracking\n * the room object in your own code and passing it in when needed.\n */\n public get room(): Room {\n return this.roomSubset as Room;\n }\n\n /**\n * This constructs a room session. When using MatrixRTC inside the js-sdk this is expected\n * to be used with the MatrixRTCSessionManager exclusively.\n *\n * In cases where you don't use the js-sdk but build on top of another Matrix stack this class can be used standalone\n * to manage a joined MatrixRTC session.\n *\n * @param client A subset of the {@link MatrixClient} that lets the session interact with the Matrix room.\n * @param roomSubset The room this session is attached to. A subset of a js-sdk Room that the session needs.\n * @param memberships The list of memberships this session currently has.\n */\n public constructor(\n private readonly client: Pick<\n MatrixClient,\n | \"getUserId\"\n | \"getDeviceId\"\n | \"sendStateEvent\"\n | \"_unstable_sendDelayedStateEvent\"\n | \"_unstable_updateDelayedEvent\"\n | \"sendEvent\"\n | \"cancelPendingEvent\"\n >,\n private roomSubset: Pick<Room, \"getLiveTimeline\" | \"roomId\" | \"getVersion\" | \"hasMembershipState\">,\n public memberships: CallMembership[],\n ) {\n super();\n this._callId = memberships[0]?.callId;\n const roomState = this.roomSubset.getLiveTimeline().getState(EventTimeline.FORWARDS);\n // TODO: double check if this is actually needed. Should be covered by refreshRoom in MatrixRTCSessionManager\n roomState?.on(RoomStateEvent.Members, this.onRoomMemberUpdate);\n this.setExpiryTimer();\n this.encryptionManager = new EncryptionManager(\n this.client,\n this.roomSubset,\n () => this.memberships,\n (keyBin: Uint8Array<ArrayBufferLike>, encryptionKeyIndex: number, participantId: string) => {\n this.emit(MatrixRTCSessionEvent.EncryptionKeyChanged, keyBin, encryptionKeyIndex, participantId);\n },\n );\n }\n\n /*\n * Returns true if we intend to be participating in the MatrixRTC session.\n * This is determined by checking if the relativeExpiry has been set.\n */\n public isJoined(): boolean {\n return this.membershipManager?.isJoined() ?? false;\n }\n\n /**\n * Performs cleanup & removes timers for client shutdown\n */\n public async stop(): Promise<void> {\n await this.membershipManager?.leave(1000);\n if (this.expiryTimeout) {\n clearTimeout(this.expiryTimeout);\n this.expiryTimeout = undefined;\n }\n const roomState = this.roomSubset.getLiveTimeline().getState(EventTimeline.FORWARDS);\n roomState?.off(RoomStateEvent.Members, this.onRoomMemberUpdate);\n }\n\n /**\n * Announces this user and device as joined to the MatrixRTC session,\n * and continues to update the membership event to keep it valid until\n * leaveRoomSession() is called\n * This will not subscribe to updates: remember to call subscribe() separately if\n * desired.\n * This method will return immediately and the session will be joined in the background.\n *\n * @param fociActive - The object representing the active focus. (This depends on the focus type.)\n * @param fociPreferred - The list of preferred foci this member proposes to use/knows/has access to.\n * For the livekit case this is a list of foci generated from the homeserver well-known, the current rtc session,\n * or optionally other room members homeserver well known.\n * @param joinConfig - Additional configuration for the joined session.\n */\n public joinRoomSession(fociPreferred: Focus[], fociActive?: Focus, joinConfig?: JoinSessionConfig): void {\n // create MembershipManager\n if (this.isJoined()) {\n logger.info(`Already joined to session in room ${this.roomSubset.roomId}: ignoring join call`);\n return;\n } else {\n this.membershipManager = new LegacyMembershipManager(joinConfig, this.roomSubset, this.client, () =>\n this.getOldestMembership(),\n );\n }\n\n // Join!\n this.membershipManager!.join(fociPreferred, fociActive);\n this.encryptionManager!.join(joinConfig);\n\n this.emit(MatrixRTCSessionEvent.JoinStateChanged, true);\n }\n\n /**\n * Announces this user and device as having left the MatrixRTC session\n * and stops scheduled updates.\n * This will not unsubscribe from updates: remember to call unsubscribe() separately if\n * desired.\n * The membership update required to leave the session will retry if it fails.\n * Without network connection the promise will never resolve.\n * A timeout can be provided so that there is a guarantee for the promise to resolve.\n * @returns Whether the membership update was attempted and did not time out.\n */\n public async leaveRoomSession(timeout: number | undefined = undefined): Promise<boolean> {\n if (!this.isJoined()) {\n logger.info(`Not joined to session in room ${this.roomSubset.roomId}: ignoring leave call`);\n return false;\n }\n\n logger.info(`Leaving call session in room ${this.roomSubset.roomId}`);\n\n this.encryptionManager.leave();\n\n const leavePromise = this.membershipManager!.leave(timeout);\n this.emit(MatrixRTCSessionEvent.JoinStateChanged, false);\n\n return await leavePromise;\n }\n\n /**\n * Get the active focus from the current CallMemberState event\n * @returns The focus that is currently in use to connect to this session. This is undefined\n * if the client is not connected to this session.\n */\n public getActiveFocus(): Focus | undefined {\n return this.membershipManager?.getActiveFocus();\n }\n\n public getOldestMembership(): CallMembership | undefined {\n return this.memberships[0];\n }\n\n /**\n * This method is used when the user is not yet connected to the Session but wants to know what focus\n * the users in the session are using to make a decision how it wants/should connect.\n *\n * See also `getActiveFocus`\n * @returns The focus which should be used when joining this session.\n */\n public getFocusInUse(): Focus | undefined {\n const oldestMembership = this.getOldestMembership();\n if (oldestMembership?.getFocusSelection() === \"oldest_membership\") {\n return oldestMembership.getPreferredFoci()[0];\n }\n }\n\n /**\n * Re-emit an EncryptionKeyChanged event for each tracked encryption key. This can be used to export\n * the keys.\n */\n public reemitEncryptionKeys(): void {\n this.encryptionManager.getEncryptionKeys().forEach((keys, participantId) => {\n keys.forEach((key, index) => {\n this.emit(MatrixRTCSessionEvent.EncryptionKeyChanged, key.key, index, participantId);\n });\n });\n }\n\n /**\n * A map of keys used to encrypt and decrypt (we are using a symmetric\n * cipher) given participant's media. This also includes our own key\n *\n * @deprecated This will be made private in a future release.\n */\n public getEncryptionKeys(): IterableIterator<[string, Array<Uint8Array>]> {\n const keys =\n this.encryptionManager.getEncryptionKeys() ??\n new Map<string, Array<{ key: Uint8Array; timestamp: number }>>();\n // the returned array doesn't contain the timestamps\n return Array.from(keys.entries())\n .map(([participantId, keys]): [string, Uint8Array[]] => [participantId, keys.map((k) => k.key)])\n .values();\n }\n\n /**\n * Sets a timer for the soonest membership expiry\n */\n private setExpiryTimer(): void {\n if (this.expiryTimeout) {\n clearTimeout(this.expiryTimeout);\n this.expiryTimeout = undefined;\n }\n\n let soonestExpiry;\n for (const membership of this.memberships) {\n const thisExpiry = membership.getMsUntilExpiry();\n // If getMsUntilExpiry is undefined we have a MSC4143 (MatrixRTC) compliant event - it never expires\n // but will be reliably resent on disconnect.\n if (thisExpiry !== undefined && (soonestExpiry === undefined || thisExpiry < soonestExpiry)) {\n soonestExpiry = thisExpiry;\n }\n }\n\n if (soonestExpiry != undefined) {\n this.expiryTimeout = setTimeout(this.onRTCSessionMemberUpdate, soonestExpiry);\n }\n }\n\n /**\n * Process `m.call.encryption_keys` events to track the encryption keys for call participants.\n * This should be called each time the relevant event is received from a room timeline.\n * If the event is malformed then it will be logged and ignored.\n *\n * @param event the event to process\n */\n public onCallEncryption = (event: MatrixEvent): void => {\n this.encryptionManager.onCallEncryptionEventReceived(event);\n };\n\n /**\n * @deprecated use onRoomMemberUpdate or onRTCSessionMemberUpdate instead. this should be called when any membership in the call is updated\n * the old name might have implied to only need to call this when your own membership changes.\n */\n public onMembershipUpdate = (): void => {\n this.recalculateSessionMembers();\n };\n\n /**\n * Call this when the Matrix room members have changed.\n */\n public onRoomMemberUpdate = (): void => {\n this.recalculateSessionMembers();\n };\n\n /**\n * Call this when something changed that may impacts the current MatrixRTC members in this session.\n */\n public onRTCSessionMemberUpdate = (): void => {\n this.recalculateSessionMembers();\n };\n\n /**\n * Call this when anything that could impact rtc memberships has changed: Room Members or RTC members.\n *\n * Examines the latest call memberships and handles any encryption key sending or rotation that is needed.\n *\n * This function should be called when the room members or call memberships might have changed.\n */\n private recalculateSessionMembers = (): void => {\n const oldMemberships = this.memberships;\n this.memberships = MatrixRTCSession.callMembershipsForRoom(this.room);\n\n this._callId = this._callId ?? this.memberships[0]?.callId;\n\n const changed =\n oldMemberships.length != this.memberships.length ||\n oldMemberships.some((m, i) => !CallMembership.equal(m, this.memberships[i]));\n\n if (changed) {\n logger.info(`Memberships for call in room ${this.roomSubset.roomId} have changed: emitting`);\n this.emit(MatrixRTCSessionEvent.MembershipsChanged, oldMemberships, this.memberships);\n\n void this.membershipManager?.onRTCSessionMemberUpdate(this.memberships);\n }\n // This also needs to be done if `changed` = false\n // A member might have updated their fingerprint (created_ts)\n void this.encryptionManager.onMembershipsUpdate(oldMemberships);\n\n this.setExpiryTimer();\n };\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"MatrixRTCSession.js","names":["logger","rootLogger","TypedEventEmitter","EventTimeline","EventType","CallMembership","RoomStateEvent","KnownMembership","MembershipManager","EncryptionManager","LegacyMembershipManager","logDurationSync","getChild","MatrixRTCSessionEvent","MatrixRTCSession","statistics","encryptionManager","callId","_callId","callMembershipsForRoom","room","roomState","getLiveTimeline","getState","FORWARDS","warn","roomId","Error","callMemberEvents","getStateEvents","GroupCallMemberPrefix","callMemberships","memberEvent","content","getContent","eventKeysCount","Object","keys","length","membershipContents","push","membershipData","_membership$sender","membership","scope","info","isExpired","concat","sender","deviceId","hasMembershipState","Join","e","sort","a","b","createdTs","debug","map","m","roomSessionForRoom","client","roomSubset","constructor","memberships","_memberships$","_defineProperty","event","onCallEncryptionEventReceived","recalculateSessionMembers","_this$_callId","_this$memberships$","oldMemberships","changed","some","i","equal","_this$membershipManag","emit","MembershipsChanged","membershipManager","onRTCSessionMemberUpdate","onMembershipsUpdate","setExpiryTimer","on","Members","onRoomMemberUpdate","keyBin","encryptionKeyIndex","participantId","EncryptionKeyChanged","isJoined","_this$membershipManag2","_this$membershipManag3","stop","_this","_asyncToGenerator","_this$membershipManag4","leave","expiryTimeout","clearTimeout","undefined","off","joinRoomSession","fociPreferred","fociActive","joinConfig","_joinConfig$useNewMem","useNewMembershipManager","getOldestMembership","join","error","MembershipManagerError","JoinStateChanged","leaveRoomSession","_arguments","arguments","_this2","timeout","leavePromise","getActiveFocus","_this$membershipManag5","getFocusInUse","oldestMembership","getFocusSelection","getPreferredFoci","reemitEncryptionKeys","getEncryptionKeys","forEach","key","index","_this$encryptionManag","Map","Array","from","entries","_ref","k","values","soonestExpiry","thisExpiry","getMsUntilExpiry","setTimeout"],"sources":["../../src/matrixrtc/MatrixRTCSession.ts"],"sourcesContent":["/*\nCopyright 2023 - 2024 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { logger as rootLogger } from \"../logger.ts\";\nimport { TypedEventEmitter } from \"../models/typed-event-emitter.ts\";\nimport { EventTimeline } from \"../models/event-timeline.ts\";\nimport { type Room } from \"../models/room.ts\";\nimport { type MatrixClient } from \"../client.ts\";\nimport { EventType } from \"../@types/event.ts\";\nimport { CallMembership } from \"./CallMembership.ts\";\nimport { RoomStateEvent } from \"../models/room-state.ts\";\nimport { type Focus } from \"./focus.ts\";\nimport { KnownMembership } from \"../@types/membership.ts\";\nimport { type MatrixEvent } from \"../models/event.ts\";\nimport { MembershipManager, type IMembershipManager } from \"./NewMembershipManager.ts\";\nimport { EncryptionManager, type IEncryptionManager, type Statistics } from \"./EncryptionManager.ts\";\nimport { LegacyMembershipManager } from \"./LegacyMembershipManager.ts\";\nimport { logDurationSync } from \"../utils.ts\";\n\nconst logger = rootLogger.getChild(\"MatrixRTCSession\");\n\nexport enum MatrixRTCSessionEvent {\n // A member joined, left, or updated a property of their membership.\n MembershipsChanged = \"memberships_changed\",\n // We joined or left the session: our own local idea of whether we are joined,\n // separate from MembershipsChanged, ie. independent of whether our member event\n // has successfully gone through.\n JoinStateChanged = \"join_state_changed\",\n // The key used to encrypt media has changed\n EncryptionKeyChanged = \"encryption_key_changed\",\n /** The membership manager had to shut down caused by an unrecoverable error */\n MembershipManagerError = \"membership_manager_error\",\n}\n\nexport type MatrixRTCSessionEventHandlerMap = {\n [MatrixRTCSessionEvent.MembershipsChanged]: (\n oldMemberships: CallMembership[],\n newMemberships: CallMembership[],\n ) => void;\n [MatrixRTCSessionEvent.JoinStateChanged]: (isJoined: boolean) => void;\n [MatrixRTCSessionEvent.EncryptionKeyChanged]: (\n key: Uint8Array,\n encryptionKeyIndex: number,\n participantId: string,\n ) => void;\n [MatrixRTCSessionEvent.MembershipManagerError]: (error: unknown) => void;\n};\n\nexport interface MembershipConfig {\n /**\n * Use the new Manager.\n *\n * Default: `false`.\n */\n useNewMembershipManager?: boolean;\n\n /**\n * The timeout (in milliseconds) after we joined the call, that our membership should expire\n * unless we have explicitly updated it.\n *\n * This is what goes into the m.rtc.member event expiry field and is typically set to a number of hours.\n */\n membershipExpiryTimeout?: number;\n\n /**\n * The time in (in milliseconds) which the manager will prematurely send the updated state event before the membership `expires` time to make sure it\n * sends the updated state event early enough.\n *\n * A headroom of 1000ms and a `membershipExpiryTimeout` of 10000ms would result in the first membership event update after 9s and\n * a membership event that would be considered expired after 10s.\n *\n * This value does not have an effect on the value of `SessionMembershipData.expires`.\n */\n membershipExpiryTimeoutHeadroom?: number;\n\n /**\n * The period (in milliseconds) with which we check that our membership event still exists on the\n * server. If it is not found we create it again.\n */\n memberEventCheckPeriod?: number;\n\n /**\n * The minimum delay (in milliseconds) after which we will retry sending the membership event if it\n * failed to send.\n */\n callMemberEventRetryDelayMinimum?: number;\n\n /**\n * The timeout (in milliseconds) with which the deleayed leave event on the server is configured.\n * After this time the server will set the event to the disconnected stat if it has not received a keep-alive from the client.\n */\n membershipServerSideExpiryTimeout?: number;\n\n /**\n * The interval (in milliseconds) in which the client will send membership keep-alives to the server.\n */\n membershipKeepAlivePeriod?: number;\n\n /**\n * @deprecated It should be possible to make it stable without this.\n */\n callMemberEventRetryJitter?: number;\n\n /**\n * The maximum number of retries that the manager will do for delayed event sending/updating and state event sending when a server rate limit has been hit.\n */\n maximumRateLimitRetryCount?: number;\n\n /**\n * The maximum number of retries that the manager will do for delayed event sending/updating and state event sending when a network error occurs.\n */\n maximumNetworkErrorRetryCount?: number;\n}\n\nexport interface EncryptionConfig {\n /**\n * If true, generate and share a media key for this participant,\n * and emit MatrixRTCSessionEvent.EncryptionKeyChanged when\n * media keys for other participants become available.\n */\n manageMediaKeys?: boolean;\n /**\n * The minimum time (in milliseconds) between each attempt to send encryption key(s).\n * e.g. if this is set to 1000, then we will send at most one key event every second.\n */\n updateEncryptionKeyThrottle?: number;\n /**\n * The delay (in milliseconds) after a member leaves before we create and publish a new key, because people\n * tend to leave calls at the same time.\n */\n makeKeyDelay?: number;\n /**\n * The delay (in milliseconds) between creating and sending a new key and starting to encrypt with it. This\n * gives other a chance to receive the new key to minimise the chance they don't get media they can't decrypt.\n * The total time between a member leaving and the call switching to new keys is therefore:\n * makeKeyDelay + useKeyDelay\n */\n useKeyDelay?: number;\n}\nexport type JoinSessionConfig = MembershipConfig & EncryptionConfig;\n\n/**\n * A MatrixRTCSession manages the membership & properties of a MatrixRTC session.\n * This class doesn't deal with media at all, just membership & properties of a session.\n */\nexport class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSessionEvent, MatrixRTCSessionEventHandlerMap> {\n private membershipManager?: IMembershipManager;\n private encryptionManager: IEncryptionManager;\n // The session Id of the call, this is the call_id of the call Member event.\n private _callId: string | undefined;\n\n /**\n * This timeout is responsible to track any expiration. We need to know when we have to start\n * to ignore other call members. There is no callback for this. This timeout will always be configured to\n * emit when the next membership expires.\n */\n private expiryTimeout?: ReturnType<typeof setTimeout>;\n\n /**\n * The statistics for this session.\n */\n public get statistics(): Statistics {\n return this.encryptionManager.statistics;\n }\n\n /**\n * The callId (sessionId) of the call.\n *\n * It can be undefined since the callId is only known once the first membership joins.\n * The callId is the property that, per definition, groups memberships into one call.\n */\n public get callId(): string | undefined {\n return this._callId;\n }\n\n /**\n * Returns all the call memberships for a room, oldest first\n */\n public static callMembershipsForRoom(\n room: Pick<Room, \"getLiveTimeline\" | \"roomId\" | \"hasMembershipState\">,\n ): CallMembership[] {\n const roomState = room.getLiveTimeline().getState(EventTimeline.FORWARDS);\n if (!roomState) {\n logger.warn(\"Couldn't get state for room \" + room.roomId);\n throw new Error(\"Could't get state for room \" + room.roomId);\n }\n const callMemberEvents = roomState.getStateEvents(EventType.GroupCallMemberPrefix);\n\n const callMemberships: CallMembership[] = [];\n for (const memberEvent of callMemberEvents) {\n const content = memberEvent.getContent();\n const eventKeysCount = Object.keys(content).length;\n // Dont even bother about empty events (saves us from costly type/\"key in\" checks in bigger rooms)\n if (eventKeysCount === 0) continue;\n\n const membershipContents: any[] = [];\n\n // We first decide if its a MSC4143 event (per device state key)\n if (eventKeysCount > 1 && \"focus_active\" in content) {\n // We have a MSC4143 event membership event\n membershipContents.push(content);\n } else if (eventKeysCount === 1 && \"memberships\" in content) {\n logger.warn(`Legacy event found. Those are ignored, they do not contribute to the MatrixRTC session`);\n }\n\n if (membershipContents.length === 0) continue;\n\n for (const membershipData of membershipContents) {\n try {\n const membership = new CallMembership(memberEvent, membershipData);\n\n if (membership.callId !== \"\" || membership.scope !== \"m.room\") {\n // for now, just ignore anything that isn't a room scope call\n logger.info(`Ignoring user-scoped call`);\n continue;\n }\n\n if (membership.isExpired()) {\n logger.info(`Ignoring expired device membership ${membership.sender}/${membership.deviceId}`);\n continue;\n }\n if (!room.hasMembershipState(membership.sender ?? \"\", KnownMembership.Join)) {\n logger.info(`Ignoring membership of user ${membership.sender} who is not in the room.`);\n continue;\n }\n callMemberships.push(membership);\n } catch (e) {\n logger.warn(\"Couldn't construct call membership: \", e);\n }\n }\n }\n\n callMemberships.sort((a, b) => a.createdTs() - b.createdTs());\n if (callMemberships.length > 1) {\n logger.debug(\n `Call memberships in room ${room.roomId}, in order: `,\n callMemberships.map((m) => [m.createdTs(), m.sender]),\n );\n }\n\n return callMemberships;\n }\n\n /**\n * Return the MatrixRTC session for the room, whether there are currently active members or not\n */\n public static roomSessionForRoom(client: MatrixClient, room: Room): MatrixRTCSession {\n const callMemberships = MatrixRTCSession.callMembershipsForRoom(room);\n\n return new MatrixRTCSession(client, room, callMemberships);\n }\n\n /**\n * WARN: this can in theory only be a subset of the room with the properties required by\n * this class.\n * Outside of tests this most likely will be a full room, however.\n * @deprecated Relying on a full Room object being available here is an anti-pattern. You should be tracking\n * the room object in your own code and passing it in when needed.\n */\n public get room(): Room {\n return this.roomSubset as Room;\n }\n\n /**\n * This constructs a room session. When using MatrixRTC inside the js-sdk this is expected\n * to be used with the MatrixRTCSessionManager exclusively.\n *\n * In cases where you don't use the js-sdk but build on top of another Matrix stack this class can be used standalone\n * to manage a joined MatrixRTC session.\n *\n * @param client A subset of the {@link MatrixClient} that lets the session interact with the Matrix room.\n * @param roomSubset The room this session is attached to. A subset of a js-sdk Room that the session needs.\n * @param memberships The list of memberships this session currently has.\n */\n public constructor(\n private readonly client: Pick<\n MatrixClient,\n | \"getUserId\"\n | \"getDeviceId\"\n | \"sendStateEvent\"\n | \"_unstable_sendDelayedStateEvent\"\n | \"_unstable_updateDelayedEvent\"\n | \"sendEvent\"\n | \"cancelPendingEvent\"\n >,\n private roomSubset: Pick<Room, \"getLiveTimeline\" | \"roomId\" | \"getVersion\" | \"hasMembershipState\">,\n public memberships: CallMembership[],\n ) {\n super();\n this._callId = memberships[0]?.callId;\n const roomState = this.roomSubset.getLiveTimeline().getState(EventTimeline.FORWARDS);\n // TODO: double check if this is actually needed. Should be covered by refreshRoom in MatrixRTCSessionManager\n roomState?.on(RoomStateEvent.Members, this.onRoomMemberUpdate);\n this.setExpiryTimer();\n this.encryptionManager = new EncryptionManager(\n this.client,\n this.roomSubset,\n () => this.memberships,\n (keyBin: Uint8Array<ArrayBufferLike>, encryptionKeyIndex: number, participantId: string) => {\n this.emit(MatrixRTCSessionEvent.EncryptionKeyChanged, keyBin, encryptionKeyIndex, participantId);\n },\n );\n }\n\n /*\n * Returns true if we intend to be participating in the MatrixRTC session.\n * This is determined by checking if the relativeExpiry has been set.\n */\n public isJoined(): boolean {\n return this.membershipManager?.isJoined() ?? false;\n }\n\n /**\n * Performs cleanup & removes timers for client shutdown\n */\n public async stop(): Promise<void> {\n await this.membershipManager?.leave(1000);\n if (this.expiryTimeout) {\n clearTimeout(this.expiryTimeout);\n this.expiryTimeout = undefined;\n }\n const roomState = this.roomSubset.getLiveTimeline().getState(EventTimeline.FORWARDS);\n roomState?.off(RoomStateEvent.Members, this.onRoomMemberUpdate);\n }\n\n /**\n * Announces this user and device as joined to the MatrixRTC session,\n * and continues to update the membership event to keep it valid until\n * leaveRoomSession() is called\n * This will not subscribe to updates: remember to call subscribe() separately if\n * desired.\n * This method will return immediately and the session will be joined in the background.\n *\n * @param fociActive - The object representing the active focus. (This depends on the focus type.)\n * @param fociPreferred - The list of preferred foci this member proposes to use/knows/has access to.\n * For the livekit case this is a list of foci generated from the homeserver well-known, the current rtc session,\n * or optionally other room members homeserver well known.\n * @param joinConfig - Additional configuration for the joined session.\n */\n public joinRoomSession(fociPreferred: Focus[], fociActive?: Focus, joinConfig?: JoinSessionConfig): void {\n if (this.isJoined()) {\n logger.info(`Already joined to session in room ${this.roomSubset.roomId}: ignoring join call`);\n return;\n } else {\n // Create MembershipManager\n if (joinConfig?.useNewMembershipManager ?? false) {\n this.membershipManager = new MembershipManager(joinConfig, this.roomSubset, this.client, () =>\n this.getOldestMembership(),\n );\n } else {\n this.membershipManager = new LegacyMembershipManager(joinConfig, this.roomSubset, this.client, () =>\n this.getOldestMembership(),\n );\n }\n }\n\n // Join!\n this.membershipManager!.join(fociPreferred, fociActive, (e) => {\n logger.error(\"MembershipManager encountered an unrecoverable error: \", e);\n this.emit(MatrixRTCSessionEvent.MembershipManagerError, e);\n this.emit(MatrixRTCSessionEvent.JoinStateChanged, this.isJoined());\n });\n this.encryptionManager!.join(joinConfig);\n\n this.emit(MatrixRTCSessionEvent.JoinStateChanged, true);\n }\n\n /**\n * Announces this user and device as having left the MatrixRTC session\n * and stops scheduled updates.\n * This will not unsubscribe from updates: remember to call unsubscribe() separately if\n * desired.\n * The membership update required to leave the session will retry if it fails.\n * Without network connection the promise will never resolve.\n * A timeout can be provided so that there is a guarantee for the promise to resolve.\n * @returns Whether the membership update was attempted and did not time out.\n */\n public async leaveRoomSession(timeout: number | undefined = undefined): Promise<boolean> {\n if (!this.isJoined()) {\n logger.info(`Not joined to session in room ${this.roomSubset.roomId}: ignoring leave call`);\n return false;\n }\n\n logger.info(`Leaving call session in room ${this.roomSubset.roomId}`);\n\n this.encryptionManager.leave();\n\n const leavePromise = this.membershipManager!.leave(timeout);\n this.emit(MatrixRTCSessionEvent.JoinStateChanged, false);\n\n return await leavePromise;\n }\n\n /**\n * Get the active focus from the current CallMemberState event\n * @returns The focus that is currently in use to connect to this session. This is undefined\n * if the client is not connected to this session.\n */\n public getActiveFocus(): Focus | undefined {\n return this.membershipManager?.getActiveFocus();\n }\n\n public getOldestMembership(): CallMembership | undefined {\n return this.memberships[0];\n }\n\n /**\n * This method is used when the user is not yet connected to the Session but wants to know what focus\n * the users in the session are using to make a decision how it wants/should connect.\n *\n * See also `getActiveFocus`\n * @returns The focus which should be used when joining this session.\n */\n public getFocusInUse(): Focus | undefined {\n const oldestMembership = this.getOldestMembership();\n if (oldestMembership?.getFocusSelection() === \"oldest_membership\") {\n return oldestMembership.getPreferredFoci()[0];\n }\n }\n\n /**\n * Re-emit an EncryptionKeyChanged event for each tracked encryption key. This can be used to export\n * the keys.\n */\n public reemitEncryptionKeys(): void {\n this.encryptionManager.getEncryptionKeys().forEach((keys, participantId) => {\n keys.forEach((key, index) => {\n this.emit(MatrixRTCSessionEvent.EncryptionKeyChanged, key.key, index, participantId);\n });\n });\n }\n\n /**\n * A map of keys used to encrypt and decrypt (we are using a symmetric\n * cipher) given participant's media. This also includes our own key\n *\n * @deprecated This will be made private in a future release.\n */\n public getEncryptionKeys(): IterableIterator<[string, Array<Uint8Array>]> {\n const keys =\n this.encryptionManager.getEncryptionKeys() ??\n new Map<string, Array<{ key: Uint8Array; timestamp: number }>>();\n // the returned array doesn't contain the timestamps\n return Array.from(keys.entries())\n .map(([participantId, keys]): [string, Uint8Array[]] => [participantId, keys.map((k) => k.key)])\n .values();\n }\n\n /**\n * Sets a timer for the soonest membership expiry\n */\n private setExpiryTimer(): void {\n if (this.expiryTimeout) {\n clearTimeout(this.expiryTimeout);\n this.expiryTimeout = undefined;\n }\n\n let soonestExpiry;\n for (const membership of this.memberships) {\n const thisExpiry = membership.getMsUntilExpiry();\n // If getMsUntilExpiry is undefined we have a MSC4143 (MatrixRTC) compliant event - it never expires\n // but will be reliably resent on disconnect.\n if (thisExpiry !== undefined && (soonestExpiry === undefined || thisExpiry < soonestExpiry)) {\n soonestExpiry = thisExpiry;\n }\n }\n\n if (soonestExpiry != undefined) {\n this.expiryTimeout = setTimeout(this.onRTCSessionMemberUpdate, soonestExpiry);\n }\n }\n\n /**\n * Process `m.call.encryption_keys` events to track the encryption keys for call participants.\n * This should be called each time the relevant event is received from a room timeline.\n * If the event is malformed then it will be logged and ignored.\n *\n * @param event the event to process\n */\n public onCallEncryption = (event: MatrixEvent): void => {\n this.encryptionManager.onCallEncryptionEventReceived(event);\n };\n\n /**\n * @deprecated use onRoomMemberUpdate or onRTCSessionMemberUpdate instead. this should be called when any membership in the call is updated\n * the old name might have implied to only need to call this when your own membership changes.\n */\n public onMembershipUpdate = (): void => {\n this.recalculateSessionMembers();\n };\n\n /**\n * Call this when the Matrix room members have changed.\n */\n public onRoomMemberUpdate = (): void => {\n this.recalculateSessionMembers();\n };\n\n /**\n * Call this when something changed that may impacts the current MatrixRTC members in this session.\n */\n public onRTCSessionMemberUpdate = (): void => {\n this.recalculateSessionMembers();\n };\n\n /**\n * Call this when anything that could impact rtc memberships has changed: Room Members or RTC members.\n *\n * Examines the latest call memberships and handles any encryption key sending or rotation that is needed.\n *\n * This function should be called when the room members or call memberships might have changed.\n */\n private recalculateSessionMembers = (): void => {\n const oldMemberships = this.memberships;\n this.memberships = MatrixRTCSession.callMembershipsForRoom(this.room);\n\n this._callId = this._callId ?? this.memberships[0]?.callId;\n\n const changed =\n oldMemberships.length != this.memberships.length ||\n oldMemberships.some((m, i) => !CallMembership.equal(m, this.memberships[i]));\n\n if (changed) {\n logger.info(`Memberships for call in room ${this.roomSubset.roomId} have changed: emitting`);\n logDurationSync(logger, \"emit MatrixRTCSessionEvent.MembershipsChanged\", () => {\n this.emit(MatrixRTCSessionEvent.MembershipsChanged, oldMemberships, this.memberships);\n });\n\n void this.membershipManager?.onRTCSessionMemberUpdate(this.memberships);\n }\n // This also needs to be done if `changed` = false\n // A member might have updated their fingerprint (created_ts)\n void this.encryptionManager.onMembershipsUpdate(oldMemberships);\n\n this.setExpiryTimer();\n };\n}\n"],"mappings":"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","ignoreList":[]}