1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-23 17:02:25 +03:00

Enable better tree shaking (#3356)

This commit is contained in:
Michael Telatynski
2023-05-15 09:10:44 +01:00
committed by GitHub
parent e6a3b0ebc0
commit 6ef9f6c55e
14 changed files with 69 additions and 70 deletions

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import * as utils from "./utils";
import { encodeParams } from "./utils";
/**
* Get the HTTP URL for an MXC URI.
@@ -74,6 +74,6 @@ export function getHttpUriForMxc(
serverAndMediaId = serverAndMediaId.slice(0, fragmentOffset);
}
const urlParams = Object.keys(params).length === 0 ? "" : "?" + utils.encodeParams(params);
const urlParams = Object.keys(params).length === 0 ? "" : "?" + encodeParams(params);
return baseUrl + prefix + serverAndMediaId + urlParams + fragment;
}

View File

@@ -15,7 +15,7 @@ limitations under the License.
*/
import { logger, PrefixedLogger } from "../../logger";
import * as utils from "../../utils";
import { deepCompare } from "../../utils";
import {
CryptoStore,
IDeviceData,
@@ -158,7 +158,7 @@ export class Backend implements CryptoStore {
const existing = cursor.value;
if (utils.deepCompare(existing.requestBody, requestBody)) {
if (deepCompare(existing.requestBody, requestBody)) {
// got a match
callback(existing);
return;

View File

@@ -15,7 +15,7 @@ limitations under the License.
*/
import { logger } from "../../logger";
import * as utils from "../../utils";
import { deepCompare, promiseTry } from "../../utils";
import {
CryptoStore,
IDeviceData,
@@ -90,7 +90,7 @@ export class MemoryCryptoStore implements CryptoStore {
public getOrAddOutgoingRoomKeyRequest(request: OutgoingRoomKeyRequest): Promise<OutgoingRoomKeyRequest> {
const requestBody = request.requestBody;
return utils.promiseTry(() => {
return promiseTry(() => {
// first see if we already have an entry for this request.
const existing = this._getOutgoingRoomKeyRequest(requestBody);
@@ -138,7 +138,7 @@ export class MemoryCryptoStore implements CryptoStore {
// eslint-disable-next-line @typescript-eslint/naming-convention
private _getOutgoingRoomKeyRequest(requestBody: IRoomKeyRequestBody): OutgoingRoomKeyRequest | null {
for (const existing of this.outgoingRoomKeyRequests) {
if (utils.deepCompare(existing.requestBody, requestBody)) {
if (deepCompare(existing.requestBody, requestBody)) {
return existing;
}
}

View File

@@ -18,7 +18,7 @@ limitations under the License.
* This is an internal module. See {@link MatrixHttpApi} for the public class.
*/
import * as utils from "../utils";
import { checkObjectHasKeys, encodeParams } from "../utils";
import { TypedEventEmitter } from "../models/typed-event-emitter";
import { Method } from "./method";
import { ConnectionError, MatrixError } from "./errors";
@@ -45,7 +45,7 @@ export class FetchHttpApi<O extends IHttpOpts> {
private eventEmitter: TypedEventEmitter<HttpApiEvent, HttpApiEventHandlerMap>,
public readonly opts: O,
) {
utils.checkObjectHasKeys(opts, ["baseUrl", "prefix"]);
checkObjectHasKeys(opts, ["baseUrl", "prefix"]);
opts.onlyData = !!opts.onlyData;
opts.useAuthorizationHeader = opts.useAuthorizationHeader ?? true;
}
@@ -304,7 +304,7 @@ export class FetchHttpApi<O extends IHttpOpts> {
public getUrl(path: string, queryParams?: QueryDict, prefix?: string, baseUrl?: string): URL {
const url = new URL((baseUrl ?? this.opts.baseUrl) + (prefix ?? this.opts.prefix) + path);
if (queryParams) {
utils.encodeParams(queryParams, url.searchParams);
encodeParams(queryParams, url.searchParams);
}
return url;
}

View File

@@ -17,7 +17,7 @@ limitations under the License.
import { FetchHttpApi } from "./fetch";
import { FileType, IContentUri, IHttpOpts, Upload, UploadOpts, UploadResponse } from "./interface";
import { MediaPrefix } from "./prefix";
import * as utils from "../utils";
import { defer, QueryDict, removeElement } from "../utils";
import * as callbacks from "../realtime-callbacks";
import { Method } from "./method";
import { ConnectionError } from "./errors";
@@ -58,14 +58,14 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
total: 0,
abortController,
} as Upload;
const defer = utils.defer<UploadResponse>();
const deferred = defer<UploadResponse>();
if (global.XMLHttpRequest) {
const xhr = new global.XMLHttpRequest();
const timeoutFn = function (): void {
xhr.abort();
defer.reject(new Error("Timeout"));
deferred.reject(new Error("Timeout"));
};
// set an initial timeout of 30s; we'll advance it each time we get a progress notification
@@ -84,16 +84,16 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
}
if (xhr.status >= 400) {
defer.reject(parseErrorResponse(xhr, xhr.responseText));
deferred.reject(parseErrorResponse(xhr, xhr.responseText));
} else {
defer.resolve(JSON.parse(xhr.responseText));
deferred.resolve(JSON.parse(xhr.responseText));
}
} catch (err) {
if ((<Error>err).name === "AbortError") {
defer.reject(err);
deferred.reject(err);
return;
}
defer.reject(new ConnectionError("request failed", <Error>err));
deferred.reject(new ConnectionError("request failed", <Error>err));
}
break;
}
@@ -131,7 +131,7 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
xhr.abort();
});
} else {
const queryParams: utils.QueryDict = {};
const queryParams: QueryDict = {};
if (includeFilename && fileName) {
queryParams.filename = fileName;
}
@@ -146,16 +146,16 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
.then((response) => {
return this.opts.onlyData ? <UploadResponse>response : response.json();
})
.then(defer.resolve, defer.reject);
.then(deferred.resolve, deferred.reject);
}
// remove the upload from the list on completion
upload.promise = defer.promise.finally(() => {
utils.removeElement(this.uploads, (elem) => elem === upload);
upload.promise = deferred.promise.finally(() => {
removeElement(this.uploads, (elem) => elem === upload);
});
abortController.signal.addEventListener("abort", () => {
utils.removeElement(this.uploads, (elem) => elem === upload);
defer.reject(new DOMException("Aborted", "AbortError"));
removeElement(this.uploads, (elem) => elem === upload);
deferred.reject(new DOMException("Aborted", "AbortError"));
});
this.uploads.push(upload);
return upload.promise;

View File

@@ -20,7 +20,7 @@ import {
WrappedReceipt,
} from "../@types/read_receipts";
import { ListenerMap, TypedEventEmitter } from "./typed-event-emitter";
import * as utils from "../utils";
import { isSupportedReceiptType } from "../utils";
import { MatrixEvent } from "./event";
import { EventType } from "../@types/event";
import { EventTimelineSet } from "./event-timeline-set";
@@ -267,7 +267,7 @@ export abstract class ReadReceipt<
public getUsersReadUpTo(event: MatrixEvent): string[] {
return this.getReceiptsForEvent(event)
.filter(function (receipt) {
return utils.isSupportedReceiptType(receipt.type);
return isSupportedReceiptType(receipt.type);
})
.map(function (receipt) {
return receipt.userId;

View File

@@ -15,7 +15,7 @@ limitations under the License.
*/
import { getHttpUriForMxc } from "../content-repo";
import * as utils from "../utils";
import { removeDirectionOverrideChars, removeHiddenChars } from "../utils";
import { User } from "./user";
import { MatrixEvent } from "./event";
import { RoomState } from "./room-state";
@@ -206,8 +206,8 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
// not quite raw: we strip direction override chars so it can safely be inserted into
// blocks of text without breaking the text direction
this.rawDisplayName = utils.removeDirectionOverrideChars(event.getDirectionalContent().displayname ?? "");
if (!this.rawDisplayName || !utils.removeHiddenChars(this.rawDisplayName)) {
this.rawDisplayName = removeDirectionOverrideChars(event.getDirectionalContent().displayname ?? "");
if (!this.rawDisplayName || !removeHiddenChars(this.rawDisplayName)) {
this.rawDisplayName = this.userId;
}
@@ -407,7 +407,7 @@ function shouldDisambiguate(selfUserId: string, displayName?: string, roomState?
// First check if the displayname is something we consider truthy
// after stripping it of zero width characters and padding spaces
if (!utils.removeHiddenChars(displayName)) return false;
if (!removeHiddenChars(displayName)) return false;
if (!roomState) return false;
@@ -432,11 +432,11 @@ function shouldDisambiguate(selfUserId: string, displayName?: string, roomState?
function calculateDisplayName(selfUserId: string, displayName: string | undefined, disambiguate: boolean): string {
if (!displayName || displayName === selfUserId) return selfUserId;
if (disambiguate) return utils.removeDirectionOverrideChars(displayName) + " (" + selfUserId + ")";
if (disambiguate) return removeDirectionOverrideChars(displayName) + " (" + selfUserId + ")";
// First check if the displayname is something we consider truthy
// after stripping it of zero width characters and padding spaces
if (!utils.removeHiddenChars(displayName)) return selfUserId;
if (!removeHiddenChars(displayName)) return selfUserId;
// We always strip the direction override characters (LRO and RLO).
// These override the text direction for all subsequent characters
@@ -449,5 +449,5 @@ function calculateDisplayName(selfUserId: string, displayName: string | undefine
// names should flip into the correct direction automatically based on
// the characters, and you can still embed rtl in ltr or vice versa
// with the embed chars or marker chars.
return utils.removeDirectionOverrideChars(displayName);
return removeDirectionOverrideChars(displayName);
}

View File

@@ -16,7 +16,7 @@ limitations under the License.
import { RoomMember } from "./room-member";
import { logger } from "../logger";
import * as utils from "../utils";
import { isNumber, removeHiddenChars } from "../utils";
import { EventType, UNSTABLE_MSC2716_MARKER } from "../@types/event";
import { IEvent, MatrixEvent, MatrixEventEvent } from "./event";
import { MatrixClient } from "../client";
@@ -759,7 +759,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
* @returns An array of user IDs or an empty array.
*/
public getUserIdsWithDisplayName(displayName: string): string[] {
return this.displayNameToUserIds.get(utils.removeHiddenChars(displayName)) ?? [];
return this.displayNameToUserIds.get(removeHiddenChars(displayName)) ?? [];
}
/**
@@ -798,7 +798,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
}
let requiredLevel = 50;
if (utils.isNumber(powerLevels[action])) {
if (isNumber(powerLevels[action])) {
requiredLevel = powerLevels[action]!;
}
@@ -928,7 +928,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
powerLevelsEvent &&
powerLevelsEvent.getContent() &&
powerLevelsEvent.getContent().notifications &&
utils.isNumber(powerLevelsEvent.getContent().notifications[notifLevelKey])
isNumber(powerLevelsEvent.getContent().notifications[notifLevelKey])
) {
notifLevel = powerLevelsEvent.getContent().notifications[notifLevelKey];
}
@@ -1058,7 +1058,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
// We clobber the user_id > name lookup but the name -> [user_id] lookup
// means we need to remove that user ID from that array rather than nuking
// the lot.
const strippedOldName = utils.removeHiddenChars(oldName);
const strippedOldName = removeHiddenChars(oldName);
const existingUserIds = this.displayNameToUserIds.get(strippedOldName);
if (existingUserIds) {
@@ -1070,7 +1070,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
this.userIdsToDisplayNames[userId] = displayName;
const strippedDisplayname = displayName && utils.removeHiddenChars(displayName);
const strippedDisplayname = displayName && removeHiddenChars(displayName);
// an empty stripped displayname (undefined/'') will be set to MXID in room-member.js
if (strippedDisplayname) {
const arr = this.displayNameToUserIds.get(strippedDisplayname) ?? [];

View File

@@ -24,7 +24,7 @@ import {
} from "./event-timeline-set";
import { Direction, EventTimeline } from "./event-timeline";
import { getHttpUriForMxc } from "../content-repo";
import * as utils from "../utils";
import { compare, removeElement } from "../utils";
import { normalize, noUnsafeEventProps } from "../utils";
import { IEvent, IThreadBundledRelationship, MatrixEvent, MatrixEventEvent, MatrixEventHandlerMap } from "./event";
import { EventStatus } from "./event-status";
@@ -733,7 +733,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
);
}
const removed = utils.removeElement(
const removed = removeElement(
this.pendingEventList,
function (ev) {
return ev.getId() == eventId;
@@ -3267,7 +3267,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
return true;
});
// make sure members have stable order
otherMembers.sort((a, b) => utils.compare(a.userId, b.userId));
otherMembers.sort((a, b) => compare(a.userId, b.userId));
// only 5 first members, immitate summaryHeroes
otherMembers = otherMembers.slice(0, 5);
otherNames = otherMembers.map((m) => m.name);

View File

@@ -18,11 +18,10 @@ limitations under the License.
* This is an internal module which manages queuing, scheduling and retrying
* of requests.
*/
import * as utils from "./utils";
import { logger } from "./logger";
import { MatrixEvent } from "./models/event";
import { EventType } from "./@types/event";
import { IDeferred } from "./utils";
import { defer, IDeferred, removeElement } from "./utils";
import { ConnectionError, MatrixError } from "./http-api";
import { ISendEventResponse } from "./@types/requests";
@@ -175,7 +174,7 @@ export class MatrixScheduler<T = ISendEventResponse> {
return false;
}
let removed = false;
utils.removeElement(this.queues[name], (element) => {
removeElement(this.queues[name], (element) => {
if (element.event.getId() === event.getId()) {
// XXX we should probably reject the promise?
// https://github.com/matrix-org/matrix-js-sdk/issues/496
@@ -214,15 +213,15 @@ export class MatrixScheduler<T = ISendEventResponse> {
if (!this.queues[queueName]) {
this.queues[queueName] = [];
}
const defer = utils.defer<T>();
const deferred = defer<T>();
this.queues[queueName].push({
event: event,
defer: defer,
defer: deferred,
attempts: 0,
});
debuglog("Queue algorithm dumped event %s into queue '%s'", event.getId(), queueName);
this.startProcessingQueues();
return defer.promise;
return deferred.promise;
}
private startProcessingQueues(): void {

View File

@@ -17,7 +17,7 @@ limitations under the License.
import type { SyncCryptoCallbacks } from "./common-crypto/CryptoBackend";
import { NotificationCountType, Room, RoomEvent } from "./models/room";
import { logger } from "./logger";
import * as utils from "./utils";
import { promiseMapSeries } from "./utils";
import { EventTimeline } from "./models/event-timeline";
import { ClientEvent, IStoredClientOpts, MatrixClient } from "./client";
import {
@@ -726,8 +726,8 @@ export class SlidingSyncSdk {
}
};
await utils.promiseMapSeries(stateEvents, processRoomEvent);
await utils.promiseMapSeries(timelineEvents, processRoomEvent);
await promiseMapSeries(stateEvents, processRoomEvent);
await promiseMapSeries(timelineEvents, processRoomEvent);
ephemeralEvents.forEach(function (e) {
client.emit(ClientEvent.Event, e);
});

View File

@@ -15,8 +15,8 @@ limitations under the License.
*/
import { IMinimalEvent, ISyncData, ISyncResponse, SyncAccumulator } from "../sync-accumulator";
import * as utils from "../utils";
import * as IndexedDBHelpers from "../indexeddb-helpers";
import { deepCopy, promiseTry } from "../utils";
import { exists as idbExists } from "../indexeddb-helpers";
import { logger } from "../logger";
import { IStateEventWithRoomId, IStoredClientOpts } from "../matrix";
import { ISavedSync } from "./index";
@@ -122,7 +122,7 @@ function reqAsCursorPromise<T>(req: IDBRequest<T>): Promise<T> {
export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
public static exists(indexedDB: IDBFactory, dbName: string): Promise<boolean> {
dbName = "matrix-js-sdk:" + (dbName || "default");
return IndexedDBHelpers.exists(indexedDB, dbName);
return idbExists(indexedDB, dbName);
}
private readonly dbName: string;
@@ -380,7 +380,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
if (copy) {
// We must deep copy the stored data so that the /sync processing code doesn't
// corrupt the internal state of the sync accumulator (it adds non-clonable keys)
return Promise.resolve(utils.deepCopy(data));
return Promise.resolve(deepCopy(data));
} else {
return Promise.resolve(data);
}
@@ -435,7 +435,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
*/
private persistSyncData(nextBatch: string, roomsData: ISyncResponse["rooms"]): Promise<void> {
logger.log("Persisting sync data up to", nextBatch);
return utils.promiseTry<void>(() => {
return promiseTry<void>(() => {
const txn = this.db!.transaction(["sync"], "readwrite");
const store = txn.objectStore("sync");
store.put({
@@ -456,7 +456,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
* @returns Promise which resolves if the events were persisted.
*/
private persistAccountData(accountData: IMinimalEvent[]): Promise<void> {
return utils.promiseTry<void>(() => {
return promiseTry<void>(() => {
const txn = this.db!.transaction(["accountData"], "readwrite");
const store = txn.objectStore("accountData");
for (const event of accountData) {
@@ -475,7 +475,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
* @returns Promise which resolves if the users were persisted.
*/
private persistUserPresenceEvents(tuples: UserTuple[]): Promise<void> {
return utils.promiseTry<void>(() => {
return promiseTry<void>(() => {
const txn = this.db!.transaction(["users"], "readwrite");
const store = txn.objectStore("users");
for (const tuple of tuples) {
@@ -495,7 +495,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
* @returns A list of presence events in their raw form.
*/
public getUserPresenceEvents(): Promise<UserTuple[]> {
return utils.promiseTry<UserTuple[]>(() => {
return promiseTry<UserTuple[]>(() => {
const txn = this.db!.transaction(["users"], "readonly");
const store = txn.objectStore("users");
return selectQuery(store, undefined, (cursor) => {
@@ -510,7 +510,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
*/
private loadAccountData(): Promise<IMinimalEvent[]> {
logger.log(`LocalIndexedDBStoreBackend: loading account data...`);
return utils.promiseTry<IMinimalEvent[]>(() => {
return promiseTry<IMinimalEvent[]>(() => {
const txn = this.db!.transaction(["accountData"], "readonly");
const store = txn.objectStore("accountData");
return selectQuery(store, undefined, (cursor) => {
@@ -528,7 +528,7 @@ export class LocalIndexedDBStoreBackend implements IIndexedDBBackend {
*/
private loadSyncData(): Promise<ISyncData> {
logger.log(`LocalIndexedDBStoreBackend: loading sync data...`);
return utils.promiseTry<ISyncData>(() => {
return promiseTry<ISyncData>(() => {
const txn = this.db!.transaction(["sync"], "readonly");
const store = txn.objectStore("sync");
return selectQuery(store, undefined, (cursor) => {

View File

@@ -28,7 +28,7 @@ import { Optional } from "matrix-events-sdk";
import type { SyncCryptoCallbacks } from "./common-crypto/CryptoBackend";
import { User, UserEvent } from "./models/user";
import { NotificationCountType, Room, RoomEvent } from "./models/room";
import * as utils from "./utils";
import { promiseMapSeries, defer, deepCopy } from "./utils";
import { IDeferred, noUnsafeEventProps, unsafeProp } from "./utils";
import { Filter } from "./filter";
import { EventTimeline } from "./models/event-timeline";
@@ -414,7 +414,7 @@ export class SyncApi {
// FIXME: Mostly duplicated from injectRoomEvents but not entirely
// because "state" in this API is at the BEGINNING of the chunk
const oldStateEvents = utils.deepCopy(response.state).map(client.getEventMapper());
const oldStateEvents = deepCopy(response.state).map(client.getEventMapper());
const stateEvents = response.state.map(client.getEventMapper());
const messages = response.messages.chunk.map(client.getEventMapper());
@@ -1247,7 +1247,7 @@ export class SyncApi {
this.notifEvents = [];
// Handle invites
await utils.promiseMapSeries(inviteRooms, async (inviteObj) => {
await promiseMapSeries(inviteRooms, async (inviteObj) => {
const room = inviteObj.room;
const stateEvents = this.mapSyncEventsFormat(inviteObj.invite_state, room);
@@ -1288,7 +1288,7 @@ export class SyncApi {
});
// Handle joins
await utils.promiseMapSeries(joinRooms, async (joinObj) => {
await promiseMapSeries(joinRooms, async (joinObj) => {
const room = joinObj.room;
const stateEvents = this.mapSyncEventsFormat(joinObj.state, room);
// Prevent events from being decrypted ahead of time
@@ -1471,7 +1471,7 @@ export class SyncApi {
});
// Handle leaves (e.g. kicked rooms)
await utils.promiseMapSeries(leaveRooms, async (leaveObj) => {
await promiseMapSeries(leaveRooms, async (leaveObj) => {
const room = leaveObj.room;
const stateEvents = this.mapSyncEventsFormat(leaveObj.state, room);
const events = this.mapSyncEventsFormat(leaveObj.timeline, room);
@@ -1552,7 +1552,7 @@ export class SyncApi {
this.pokeKeepAlive();
}
if (!this.connectionReturnedDefer) {
this.connectionReturnedDefer = utils.defer();
this.connectionReturnedDefer = defer();
}
return this.connectionReturnedDefer.promise;
}

View File

@@ -25,7 +25,7 @@ import { v4 as uuidv4 } from "uuid";
import { parse as parseSdp, write as writeSdp } from "sdp-transform";
import { logger } from "../logger";
import * as utils from "../utils";
import { checkObjectHasKeys, isNullOrUndefined, recursivelyAssign } from "../utils";
import { IContent, MatrixEvent } from "../models/event";
import { EventType, ToDeviceMessageId } from "../@types/event";
import { RoomMember } from "../models/room-member";
@@ -453,7 +453,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
});
}
for (const server of this.turnServers) {
utils.checkObjectHasKeys(server, ["urls"]);
checkObjectHasKeys(server, ["urls"]);
}
this.callId = genCallID();
// If the Client provides calls without audio and video we need a datachannel for a webrtc connection
@@ -1043,7 +1043,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
);
return false;
} else if (
!utils.isNullOrUndefined(wantedValue) &&
!isNullOrUndefined(wantedValue) &&
wantedValue !== valueOfTheOtherSide &&
!this.opponentSupportsSDPStreamMetadata()
) {
@@ -2030,7 +2030,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
}
private updateRemoteSDPStreamMetadata(metadata: SDPStreamMetadata): void {
this.remoteSDPStreamMetadata = utils.recursivelyAssign(this.remoteSDPStreamMetadata || {}, metadata, true);
this.remoteSDPStreamMetadata = recursivelyAssign(this.remoteSDPStreamMetadata || {}, metadata, true);
for (const feed of this.getRemoteFeeds()) {
const streamId = feed.stream.id;
const metadata = this.remoteSDPStreamMetadata![streamId];