matrix-js-sdk 42.1.0 → 42.2.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 (154) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/lib/@types/beacon.d.ts +1 -1
  3. package/lib/@types/beacon.js +1 -1
  4. package/lib/@types/beacon.js.map +1 -1
  5. package/lib/@types/extensible_events.d.ts.map +1 -1
  6. package/lib/@types/extensible_events.js.map +1 -1
  7. package/lib/autodiscovery.js.map +1 -1
  8. package/lib/browser-index.js.map +1 -1
  9. package/lib/client.d.ts +12 -5
  10. package/lib/client.d.ts.map +1 -1
  11. package/lib/client.js +23 -26
  12. package/lib/client.js.map +1 -1
  13. package/lib/common-crypto/key-passphrase.js +1 -1
  14. package/lib/common-crypto/key-passphrase.js.map +1 -1
  15. package/lib/crypto/store/indexeddb-crypto-store-backend.js +2 -1
  16. package/lib/crypto/store/indexeddb-crypto-store-backend.js.map +1 -1
  17. package/lib/crypto/store/indexeddb-crypto-store.d.ts.map +1 -1
  18. package/lib/crypto/store/indexeddb-crypto-store.js +1 -1
  19. package/lib/crypto/store/indexeddb-crypto-store.js.map +1 -1
  20. package/lib/crypto/store/memory-crypto-store.js.map +1 -1
  21. package/lib/embedded.d.ts +16 -0
  22. package/lib/embedded.d.ts.map +1 -1
  23. package/lib/embedded.js +19 -6
  24. package/lib/embedded.js.map +1 -1
  25. package/lib/matrixrtc/MatrixRTCSession.js.map +1 -1
  26. package/lib/matrixrtc/MembershipManager.js.map +1 -1
  27. package/lib/matrixrtc/MembershipManagerActionScheduler.js.map +1 -1
  28. package/lib/matrixrtc/RTCEncryptionManager.js.map +1 -1
  29. package/lib/matrixrtc/ToDeviceKeyTransport.js.map +1 -1
  30. package/lib/matrixrtc/membershipData/rtc.js.map +1 -1
  31. package/lib/matrixrtc/utils.d.ts +0 -1
  32. package/lib/matrixrtc/utils.d.ts.map +1 -1
  33. package/lib/matrixrtc/utils.js +0 -1
  34. package/lib/matrixrtc/utils.js.map +1 -1
  35. package/lib/models/event-timeline-set.js +3 -3
  36. package/lib/models/event-timeline-set.js.map +1 -1
  37. package/lib/models/event.d.ts.map +1 -1
  38. package/lib/models/event.js.map +1 -1
  39. package/lib/models/invites-ignorer.js.map +1 -1
  40. package/lib/models/poll.js.map +1 -1
  41. package/lib/models/read-receipt.js.map +1 -1
  42. package/lib/models/relations-container.d.ts +10 -0
  43. package/lib/models/relations-container.d.ts.map +1 -1
  44. package/lib/models/relations-container.js +39 -17
  45. package/lib/models/relations-container.js.map +1 -1
  46. package/lib/models/relations.js +1 -1
  47. package/lib/models/relations.js.map +1 -1
  48. package/lib/models/room.js +3 -3
  49. package/lib/models/room.js.map +1 -1
  50. package/lib/models/thread.d.ts +3 -0
  51. package/lib/models/thread.d.ts.map +1 -1
  52. package/lib/models/thread.js +36 -3
  53. package/lib/models/thread.js.map +1 -1
  54. package/lib/oauth/authorize.js +1 -1
  55. package/lib/oauth/authorize.js.map +1 -1
  56. package/lib/oauth/index.js +4 -2
  57. package/lib/oauth/index.js.map +1 -1
  58. package/lib/pollingCachedValue.d.ts +77 -0
  59. package/lib/pollingCachedValue.d.ts.map +1 -0
  60. package/lib/pollingCachedValue.js +160 -0
  61. package/lib/pollingCachedValue.js.map +1 -0
  62. package/lib/pushprocessor.js.map +1 -1
  63. package/lib/receipt-accumulator.d.ts.map +1 -1
  64. package/lib/receipt-accumulator.js.map +1 -1
  65. package/lib/rendezvous/MSC4108SignInWithQR.d.ts.map +1 -1
  66. package/lib/rendezvous/MSC4108SignInWithQR.js +2 -3
  67. package/lib/rendezvous/MSC4108SignInWithQR.js.map +1 -1
  68. package/lib/rtcTransportsCachedValue.d.ts +9 -0
  69. package/lib/rtcTransportsCachedValue.d.ts.map +1 -0
  70. package/lib/rtcTransportsCachedValue.js +38 -0
  71. package/lib/rtcTransportsCachedValue.js.map +1 -0
  72. package/lib/rust-crypto/PerSessionKeyBackupDownloader.js.map +1 -1
  73. package/lib/rust-crypto/backup.d.ts +2 -3
  74. package/lib/rust-crypto/backup.d.ts.map +1 -1
  75. package/lib/rust-crypto/backup.js.map +1 -1
  76. package/lib/rust-crypto/index.d.ts +10 -4
  77. package/lib/rust-crypto/index.d.ts.map +1 -1
  78. package/lib/rust-crypto/index.js +20 -3
  79. package/lib/rust-crypto/index.js.map +1 -1
  80. package/lib/rust-crypto/libolm_migration.js.map +1 -1
  81. package/lib/rust-crypto/rust-crypto.js.map +1 -1
  82. package/lib/sliding-sync-sdk.js.map +1 -1
  83. package/lib/sliding-sync.js.map +1 -1
  84. package/lib/store/indexeddb-local-backend.js +1 -1
  85. package/lib/store/indexeddb-local-backend.js.map +1 -1
  86. package/lib/store/indexeddb-store-worker.d.ts.map +1 -1
  87. package/lib/store/indexeddb-store-worker.js +1 -0
  88. package/lib/store/indexeddb-store-worker.js.map +1 -1
  89. package/lib/sync.d.ts.map +1 -1
  90. package/lib/sync.js.map +1 -1
  91. package/lib/utils.d.ts +1 -1
  92. package/lib/utils.d.ts.map +1 -1
  93. package/lib/utils.js +1 -0
  94. package/lib/utils.js.map +1 -1
  95. package/lib/webrtc/call.js.map +1 -1
  96. package/lib/webrtc/groupCall.js.map +1 -1
  97. package/lib/webrtc/mediaHandler.js.map +1 -1
  98. package/lib/webrtc/stats/callStatsReportGatherer.js.map +1 -1
  99. package/lib/webrtc/stats/transportStatsBuilder.js.map +1 -1
  100. package/lib/wellKnownCachedValue.d.ts +8 -0
  101. package/lib/wellKnownCachedValue.d.ts.map +1 -0
  102. package/lib/wellKnownCachedValue.js +34 -0
  103. package/lib/wellKnownCachedValue.js.map +1 -0
  104. package/package.json +4 -4
  105. package/src/@types/beacon.ts +1 -1
  106. package/src/@types/extensible_events.ts +3 -4
  107. package/src/autodiscovery.ts +2 -2
  108. package/src/browser-index.ts +1 -1
  109. package/src/client.ts +48 -40
  110. package/src/common-crypto/key-passphrase.ts +1 -1
  111. package/src/crypto/store/indexeddb-crypto-store-backend.ts +2 -1
  112. package/src/crypto/store/indexeddb-crypto-store.ts +1 -3
  113. package/src/crypto/store/memory-crypto-store.ts +1 -1
  114. package/src/embedded.ts +34 -11
  115. package/src/matrixrtc/MatrixRTCSession.ts +3 -3
  116. package/src/matrixrtc/MembershipManager.ts +1 -1
  117. package/src/matrixrtc/MembershipManagerActionScheduler.ts +1 -1
  118. package/src/matrixrtc/RTCEncryptionManager.ts +2 -2
  119. package/src/matrixrtc/ToDeviceKeyTransport.ts +3 -3
  120. package/src/matrixrtc/membershipData/rtc.ts +1 -1
  121. package/src/matrixrtc/utils.ts +0 -2
  122. package/src/models/event-timeline-set.ts +3 -3
  123. package/src/models/event.ts +7 -10
  124. package/src/models/invites-ignorer.ts +1 -1
  125. package/src/models/poll.ts +1 -1
  126. package/src/models/read-receipt.ts +1 -1
  127. package/src/models/relations-container.ts +55 -19
  128. package/src/models/relations.ts +1 -1
  129. package/src/models/room.ts +9 -9
  130. package/src/models/thread.ts +49 -4
  131. package/src/oauth/authorize.ts +1 -1
  132. package/src/oauth/index.ts +2 -2
  133. package/src/pollingCachedValue.ts +184 -0
  134. package/src/pushprocessor.ts +3 -3
  135. package/src/receipt-accumulator.ts +1 -2
  136. package/src/rendezvous/MSC4108SignInWithQR.ts +3 -4
  137. package/src/rtcTransportsCachedValue.ts +40 -0
  138. package/src/rust-crypto/PerSessionKeyBackupDownloader.ts +1 -1
  139. package/src/rust-crypto/backup.ts +1 -5
  140. package/src/rust-crypto/index.ts +23 -25
  141. package/src/rust-crypto/libolm_migration.ts +1 -1
  142. package/src/rust-crypto/rust-crypto.ts +3 -3
  143. package/src/sliding-sync-sdk.ts +1 -1
  144. package/src/sliding-sync.ts +1 -1
  145. package/src/store/indexeddb-local-backend.ts +1 -1
  146. package/src/store/indexeddb-store-worker.ts +1 -0
  147. package/src/sync.ts +4 -3
  148. package/src/utils.ts +3 -2
  149. package/src/webrtc/call.ts +6 -6
  150. package/src/webrtc/groupCall.ts +7 -7
  151. package/src/webrtc/mediaHandler.ts +1 -1
  152. package/src/webrtc/stats/callStatsReportGatherer.ts +2 -2
  153. package/src/webrtc/stats/transportStatsBuilder.ts +1 -1
  154. package/src/wellKnownCachedValue.ts +34 -0
@@ -30,12 +30,11 @@ import {
30
30
  import { type CryptoCallbacks } from "../crypto-api/index.ts";
31
31
 
32
32
  /**
33
- * Create a new `RustCrypto` implementation
33
+ * The arguments used to initialise RustCrypto, passed in to initRustCrypto.
34
34
  *
35
- * @param args - Parameter object
36
35
  * @internal
37
36
  */
38
- export async function initRustCrypto(args: {
37
+ export interface InitRustCryptoArgs {
39
38
  /** A `Logger` instance that will be used for debug output. */
40
39
  logger: Logger;
41
40
 
@@ -104,7 +103,15 @@ export async function initRustCrypto(args: {
104
103
  * considered verified, without any manual verification taking place.
105
104
  */
106
105
  caCertsPem?: string;
107
- }): Promise<RustCrypto> {
106
+ }
107
+
108
+ /**
109
+ * Create a new `RustCrypto` implementation
110
+ *
111
+ * @param args - InitRustCryptoArgs
112
+ * @internal
113
+ */
114
+ export async function initRustCrypto(args: InitRustCryptoArgs): Promise<RustCrypto> {
108
115
  const { logger } = args;
109
116
 
110
117
  // initialise the rust matrix-sdk-crypto-wasm, if it hasn't already been done
@@ -132,18 +139,7 @@ export async function initRustCrypto(args: {
132
139
  });
133
140
  }
134
141
 
135
- const rustCrypto = await initOlmMachine(
136
- logger,
137
- args.http,
138
- args.userId,
139
- args.deviceId,
140
- args.secretStorage,
141
- args.cryptoCallbacks,
142
- storeHandle,
143
- args.legacyCryptoStore,
144
- args.enableEncryptedStateEvents,
145
- args.caCertsPem,
146
- );
142
+ const rustCrypto = await initOlmMachine(args, storeHandle);
147
143
 
148
144
  storeHandle.free();
149
145
 
@@ -152,16 +148,18 @@ export async function initRustCrypto(args: {
152
148
  }
153
149
 
154
150
  async function initOlmMachine(
155
- logger: Logger,
156
- http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,
157
- userId: string,
158
- deviceId: string,
159
- secretStorage: ServerSideSecretStorage,
160
- cryptoCallbacks: CryptoCallbacks,
151
+ {
152
+ logger,
153
+ http,
154
+ userId,
155
+ deviceId,
156
+ secretStorage,
157
+ cryptoCallbacks,
158
+ legacyCryptoStore,
159
+ enableEncryptedStateEvents,
160
+ caCertsPem,
161
+ }: InitRustCryptoArgs,
161
162
  storeHandle: StoreHandle,
162
- legacyCryptoStore?: CryptoStore,
163
- enableEncryptedStateEvents?: boolean,
164
- caCertsPem?: string,
165
163
  ): Promise<RustCrypto> {
166
164
  logger.debug("Init OlmMachine");
167
165
 
@@ -487,7 +487,7 @@ export async function migrateLegacyLocalTrustIfNeeded(args: {
487
487
  if (rustSeenMSK && rustSeenMSK == legacyLocallyTrustedMSK) {
488
488
  logger.info(`Post Migration: Migrating legacy trusted MSK: ${legacyLocallyTrustedMSK} to locally verified.`);
489
489
  // Let's mark the user identity as locally verified as part of the migration.
490
- await rustOwnIdentity!.verify();
490
+ await rustOwnIdentity.verify();
491
491
  // As well as marking the MSK as trusted, `OlmMachine.verify` returns a
492
492
  // `SignatureUploadRequest` which will publish a signature of the MSK using
493
493
  // this device. In this case, we ignore the request: since the user hasn't
@@ -2329,11 +2329,11 @@ class EventDecryptor {
2329
2329
  }
2330
2330
 
2331
2331
  try {
2332
- const res = (await this.olmMachine.decryptRoomEvent(
2332
+ const res = await this.olmMachine.decryptRoomEvent(
2333
2333
  stringifyEvent(event),
2334
2334
  new RustSdkCryptoJs.RoomId(event.getRoomId()!),
2335
2335
  new RustSdkCryptoJs.DecryptionSettings(trustRequirement),
2336
- )) as RustSdkCryptoJs.DecryptedRoomEvent;
2336
+ );
2337
2337
 
2338
2338
  // Success. We can remove the event from the pending list, if
2339
2339
  // that hasn't already happened.
@@ -2377,7 +2377,7 @@ class EventDecryptor {
2377
2377
  err.code === RustSdkCryptoJs.DecryptionErrorCode.MissingRoomKey ||
2378
2378
  err.code === RustSdkCryptoJs.DecryptionErrorCode.UnknownMessageIndex
2379
2379
  ) {
2380
- this.perSessionBackupDownloader.onDecryptionKeyMissingError(event.getRoomId()!, content.session_id!);
2380
+ this.perSessionBackupDownloader.onDecryptionKeyMissingError(event.getRoomId()!, content.session_id);
2381
2381
 
2382
2382
  // If the server is telling us our membership at the time the event
2383
2383
  // was sent, and it isn't "join", we use a different error code.
@@ -366,7 +366,7 @@ export class SlidingSyncSdk {
366
366
  }
367
367
  room = _createAndReEmitRoom(this.client, roomId, this.opts);
368
368
  }
369
- await this.processRoomData(this.client, room!, roomData);
369
+ await this.processRoomData(this.client, room, roomData);
370
370
  }
371
371
 
372
372
  private onLifecycle(state: SlidingSyncState, resp: MSC3575SlidingSyncResponse | null, err?: Error): void {
@@ -658,7 +658,7 @@ export class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, SlidingSync
658
658
 
659
659
  // oxlint-disable-next-line guard-for-in
660
660
  for (const roomId in resp.rooms) {
661
- await this.invokeRoomDataListeners(roomId, resp!.rooms[roomId]);
661
+ await this.invokeRoomDataListeners(roomId, resp.rooms[roomId]);
662
662
  }
663
663
 
664
664
  this.invokeLifecycleListeners(SlidingSyncState.Complete, resp);
@@ -289,7 +289,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
289
289
  * @param membershipEvents - the membership events to store
290
290
  */
291
291
  public async setOutOfBandMembers(roomId: string, membershipEvents: IStateEventWithRoomId[]): Promise<void> {
292
- logger.log(`LL: backend about to store ${membershipEvents.length}` + ` members for ${roomId}`);
292
+ logger.log(`LL: backend about to store ${membershipEvents.length} members for ${roomId}`);
293
293
  const tx = this.db!.transaction(["oob_membership_events"], "readwrite");
294
294
  const store = tx.objectStore("oob_membership_events");
295
295
  membershipEvents.forEach((e) => {
@@ -137,6 +137,7 @@ export class IndexedDBStoreWorker {
137
137
  seq: msg.seq,
138
138
  // Can't be an Error because they're not structured cloneable
139
139
  error: "Unrecognised command",
140
+ // oxlint-disable-next-line unicorn/require-post-message-target-origin
140
141
  });
141
142
  return;
142
143
  }
package/src/sync.ts CHANGED
@@ -1119,7 +1119,8 @@ export class SyncApi {
1119
1119
 
1120
1120
  // handle presence events (User objects)
1121
1121
  if (Array.isArray(data.presence?.events)) {
1122
- data.presence!.events.filter(noUnsafeEventProps)
1122
+ data.presence.events
1123
+ .filter(noUnsafeEventProps)
1123
1124
  .map(client.getEventMapper())
1124
1125
  .forEach(function (presenceEvent) {
1125
1126
  let user = client.store.getUser(presenceEvent.getSender()!);
@@ -1138,7 +1139,7 @@ export class SyncApi {
1138
1139
  if (Array.isArray(data.account_data?.events)) {
1139
1140
  const events = data.account_data.events.filter(noUnsafeEventProps).map(client.getEventMapper());
1140
1141
  const prevEventsMap = events.reduce<Record<string, MatrixEvent | undefined>>((m, c) => {
1141
- m[c.getType()!] = client.store.getAccountData(c.getType());
1142
+ m[c.getType()] = client.store.getAccountData(c.getType());
1142
1143
  return m;
1143
1144
  }, {});
1144
1145
  client.store.storeAccountDataEvents(events);
@@ -1151,7 +1152,7 @@ export class SyncApi {
1151
1152
  const rules = accountDataEvent.getContent<IPushRules>();
1152
1153
  client.setPushRules(rules);
1153
1154
  }
1154
- const prevEvent = prevEventsMap[accountDataEvent.getType()!];
1155
+ const prevEvent = prevEventsMap[accountDataEvent.getType()];
1155
1156
  client.emit(ClientEvent.AccountData, accountDataEvent, prevEvent);
1156
1157
  return accountDataEvent;
1157
1158
  });
package/src/utils.ts CHANGED
@@ -37,6 +37,7 @@ const interns = new Map<string, string>();
37
37
  export function internaliseString(str: string): string {
38
38
  // Unwrap strings before entering the map, if we somehow got a wrapped
39
39
  // string as our input. This should only happen from tests.
40
+ // oxlint-disable-next-line unicorn/no-instanceof-builtins
40
41
  if ((str as unknown) instanceof String) {
41
42
  str = str.toString();
42
43
  }
@@ -682,7 +683,7 @@ export function recursivelyAssign<T1 extends T2, T2 extends Record<string, any>>
682
683
  continue;
683
684
  }
684
685
  }
685
- return target as T1 & T2;
686
+ return target;
686
687
  }
687
688
 
688
689
  function getContentTimestampWithFallback(event: MatrixEvent): number {
@@ -740,7 +741,7 @@ export function recursiveMapToObject(map: Map<any, any>): Record<any, any> {
740
741
  return Object.fromEntries(targetMap.entries());
741
742
  }
742
743
 
743
- export function unsafeProp<K extends keyof any | undefined>(prop: K): boolean {
744
+ export function unsafeProp(prop: keyof any | undefined): boolean {
744
745
  return prop === "__proto__" || prop === "prototype" || prop === "constructor";
745
746
  }
746
747
 
@@ -1054,9 +1054,9 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
1054
1054
  logger.warn(
1055
1055
  `Call ${this.callId} shouldAnswerWithMediaType() unable to answer with ${type}=${wantedValue} because the other side doesn't support it. Answering with ${type}=${valueOfTheOtherSide}.`,
1056
1056
  );
1057
- return valueOfTheOtherSide!;
1057
+ return valueOfTheOtherSide;
1058
1058
  }
1059
- return wantedValue ?? valueOfTheOtherSide!;
1059
+ return wantedValue ?? valueOfTheOtherSide;
1060
1060
  }
1061
1061
 
1062
1062
  /**
@@ -2038,10 +2038,10 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
2038
2038
  this.remoteSDPStreamMetadata = recursivelyAssign(this.remoteSDPStreamMetadata || {}, metadata, true);
2039
2039
  for (const feed of this.getRemoteFeeds()) {
2040
2040
  const streamId = feed.stream.id;
2041
- const metadata = this.remoteSDPStreamMetadata![streamId];
2041
+ const metadata = this.remoteSDPStreamMetadata[streamId];
2042
2042
 
2043
2043
  feed.setAudioVideoMuted(metadata?.audio_muted, metadata?.video_muted);
2044
- feed.purpose = this.remoteSDPStreamMetadata![streamId]?.purpose;
2044
+ feed.purpose = this.remoteSDPStreamMetadata[streamId]?.purpose;
2045
2045
  }
2046
2046
  }
2047
2047
 
@@ -2286,7 +2286,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
2286
2286
  logger.debug(
2287
2287
  `Call ${this.callId} onIceConnectionStateChanged() ice restart (state=${this.peerConn?.iceConnectionState})`,
2288
2288
  );
2289
- this.peerConn!.restartIce();
2289
+ this.peerConn.restartIce();
2290
2290
  } else {
2291
2291
  logger.info(
2292
2292
  `Call ${this.callId} onIceConnectionStateChanged() hanging up call (ICE failed and no ICE restart method)`,
@@ -2533,7 +2533,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
2533
2533
  this,
2534
2534
  );
2535
2535
 
2536
- await this.client.sendEvent(this.roomId!, eventType, realContent);
2536
+ await this.client.sendEvent(this.roomId, eventType, realContent);
2537
2537
  }
2538
2538
  }
2539
2539
 
@@ -1323,7 +1323,7 @@ export class GroupCall extends TypedEventEmitter<
1323
1323
  */
1324
1324
 
1325
1325
  public getUserMediaFeed(userId: string, deviceId: string): CallFeed | undefined {
1326
- return this.userMediaFeeds.find((f) => f.userId === userId && f.deviceId! === deviceId);
1326
+ return this.userMediaFeeds.find((f) => f.userId === userId && f.deviceId === deviceId);
1327
1327
  }
1328
1328
 
1329
1329
  private addUserMediaFeed(callFeed: CallFeed): void {
@@ -1334,7 +1334,7 @@ export class GroupCall extends TypedEventEmitter<
1334
1334
 
1335
1335
  private replaceUserMediaFeed(existingFeed: CallFeed, replacementFeed: CallFeed): void {
1336
1336
  const feedIndex = this.userMediaFeeds.findIndex(
1337
- (f) => f.userId === existingFeed.userId && f.deviceId! === existingFeed.deviceId,
1337
+ (f) => f.userId === existingFeed.userId && f.deviceId === existingFeed.deviceId,
1338
1338
  );
1339
1339
 
1340
1340
  if (feedIndex === -1) {
@@ -1350,7 +1350,7 @@ export class GroupCall extends TypedEventEmitter<
1350
1350
 
1351
1351
  private removeUserMediaFeed(callFeed: CallFeed): void {
1352
1352
  const feedIndex = this.userMediaFeeds.findIndex(
1353
- (f) => f.userId === callFeed.userId && f.deviceId! === callFeed.deviceId,
1353
+ (f) => f.userId === callFeed.userId && f.deviceId === callFeed.deviceId,
1354
1354
  );
1355
1355
 
1356
1356
  if (feedIndex === -1) {
@@ -1397,7 +1397,7 @@ export class GroupCall extends TypedEventEmitter<
1397
1397
  */
1398
1398
 
1399
1399
  public getScreenshareFeed(userId: string, deviceId: string): CallFeed | undefined {
1400
- return this.screenshareFeeds.find((f) => f.userId === userId && f.deviceId! === deviceId);
1400
+ return this.screenshareFeeds.find((f) => f.userId === userId && f.deviceId === deviceId);
1401
1401
  }
1402
1402
 
1403
1403
  private addScreenshareFeed(callFeed: CallFeed): void {
@@ -1407,7 +1407,7 @@ export class GroupCall extends TypedEventEmitter<
1407
1407
 
1408
1408
  private replaceScreenshareFeed(existingFeed: CallFeed, replacementFeed: CallFeed): void {
1409
1409
  const feedIndex = this.screenshareFeeds.findIndex(
1410
- (f) => f.userId === existingFeed.userId && f.deviceId! === existingFeed.deviceId,
1410
+ (f) => f.userId === existingFeed.userId && f.deviceId === existingFeed.deviceId,
1411
1411
  );
1412
1412
 
1413
1413
  if (feedIndex === -1) {
@@ -1422,7 +1422,7 @@ export class GroupCall extends TypedEventEmitter<
1422
1422
 
1423
1423
  private removeScreenshareFeed(callFeed: CallFeed): void {
1424
1424
  const feedIndex = this.screenshareFeeds.findIndex(
1425
- (f) => f.userId === callFeed.userId && f.deviceId! === callFeed.deviceId,
1425
+ (f) => f.userId === callFeed.userId && f.deviceId === callFeed.deviceId,
1426
1426
  );
1427
1427
 
1428
1428
  if (feedIndex === -1) {
@@ -1469,7 +1469,7 @@ export class GroupCall extends TypedEventEmitter<
1469
1469
  const content = e.getContent<Record<any, unknown>>();
1470
1470
  const calls: Record<any, unknown>[] = Array.isArray(content["m.calls"]) ? content["m.calls"] : [];
1471
1471
  const call = calls.find((call) => call["m.call_id"] === this.groupCallId);
1472
- const devices: Record<any, unknown>[] = Array.isArray(call?.["m.devices"]) ? call!["m.devices"] : [];
1472
+ const devices: Record<any, unknown>[] = Array.isArray(call?.["m.devices"]) ? call["m.devices"] : [];
1473
1473
 
1474
1474
  // Filter out invalid and expired devices
1475
1475
  let validDevices = devices.filter(
@@ -93,7 +93,7 @@ export class MediaHandler extends TypedEventEmitter<
93
93
  public async setAudioSettings(opts: AudioSettings): Promise<void> {
94
94
  logger.info(`MediaHandler setAudioSettings() running (opts=${JSON.stringify(opts)})`);
95
95
 
96
- this.audioSettings = Object.assign({}, opts) as AudioSettings;
96
+ this.audioSettings = Object.assign({}, opts);
97
97
  await this.updateLocalUsermediaStreams();
98
98
  }
99
99
 
@@ -56,7 +56,7 @@ export class CallStatsReportGatherer {
56
56
  receivedVideoMedia: 0,
57
57
  audioTrackSummary: { count: 0, muted: 0, maxPacketLoss: 0, maxJitter: 0, concealedAudio: 0, totalAudio: 0 },
58
58
  videoTrackSummary: { count: 0, muted: 0, maxPacketLoss: 0, maxJitter: 0, concealedAudio: 0, totalAudio: 0 },
59
- } as CallStatsReportSummary;
59
+ } satisfies CallStatsReportSummary;
60
60
  if (this.isActive) {
61
61
  const statsPromise = this.pc.getStats();
62
62
  if (typeof statsPromise?.then === "function") {
@@ -96,7 +96,7 @@ export class CallStatsReportGatherer {
96
96
  }
97
97
 
98
98
  private processStatsReport(groupCallId: string, localUserId: string): void {
99
- const byteSentStatsReport: ByteSentStatsReport = new Map<TrackID, ByteSend>() as ByteSentStatsReport;
99
+ const byteSentStatsReport: ByteSentStatsReport = new Map<TrackID, ByteSend>();
100
100
  byteSentStatsReport.callId = this.callId;
101
101
  byteSentStatsReport.opponentMemberId = this.opponentMemberId;
102
102
 
@@ -40,7 +40,7 @@ export class TransportStatsBuilder {
40
40
  remoteCandidateType: remoteUsedCandidate.candidateType,
41
41
  networkType: localUsedCandidate.networkType,
42
42
  rtt: now.currentRoundTripTime ? now.currentRoundTripTime * 1000 : NaN,
43
- } as TransportStats);
43
+ });
44
44
  }
45
45
  }
46
46
  return conferenceStatsTransport;
@@ -0,0 +1,34 @@
1
+ /*
2
+ Copyright 2026 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
+ import { PollingCachedValue } from "./pollingCachedValue.ts";
18
+ import { ClientEvent, type IClientWellKnown, type MatrixClient } from "./client.ts";
19
+ import { type Logger } from "./logger.ts";
20
+ import { AutoDiscovery } from "./autodiscovery.ts";
21
+
22
+ /**
23
+ * Builds a cache for the well-known configuration of the given client.
24
+ */
25
+ export function createWellKnownCachedValue(client: MatrixClient, logger: Logger): PollingCachedValue<IClientWellKnown> {
26
+ return new PollingCachedValue({
27
+ name: "WellKnown",
28
+ logger,
29
+ // No expiration by default
30
+ ttlMillis: undefined,
31
+ fetch: () => AutoDiscovery.getRawClientConfig(client.getDomain() ?? undefined),
32
+ onValueCached: (wellKnown) => client.emit(ClientEvent.ClientWellKnown, wellKnown),
33
+ });
34
+ }