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

Split membership manager into legacy variant to improve readability

This commit is contained in:
Half-Shot
2025-11-03 12:07:33 +00:00
parent 4ca30bed25
commit 3e5c1ee6f5
3 changed files with 795 additions and 769 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,7 @@ import { KnownMembership } from "../@types/membership.ts";
import { type ISendEventResponse } from "../@types/requests.ts"; import { type ISendEventResponse } from "../@types/requests.ts";
import { CallMembership } from "./CallMembership.ts"; import { CallMembership } from "./CallMembership.ts";
import { RoomStateEvent } from "../models/room-state.ts"; import { RoomStateEvent } from "../models/room-state.ts";
import { MembershipManager, StickyEventMembershipManager } from "./MembershipManager.ts"; import { LegacyMembershipManager, StickyEventMembershipManager } from "./MembershipManager.ts";
import { EncryptionManager, type IEncryptionManager } from "./EncryptionManager.ts"; import { EncryptionManager, type IEncryptionManager } from "./EncryptionManager.ts";
import { deepCompare, logDurationSync } from "../utils.ts"; import { deepCompare, logDurationSync } from "../utils.ts";
import { import {
@@ -618,7 +618,7 @@ export class MatrixRTCSession extends TypedEventEmitter<
this.slotDescription, this.slotDescription,
this.logger, this.logger,
) )
: new MembershipManager(joinConfig, this.roomSubset, this.client, this.slotDescription, this.logger); : new LegacyMembershipManager(joinConfig, this.roomSubset, this.client, this.slotDescription, this.logger);
this.reEmitter.reEmit(this.membershipManager!, [ this.reEmitter.reEmit(this.membershipManager!, [
MembershipManagerEvent.ProbablyLeft, MembershipManagerEvent.ProbablyLeft,

View File

@@ -29,9 +29,13 @@ import { type Room } from "../models/room.ts";
import { import {
type CallMembership, type CallMembership,
DEFAULT_EXPIRE_DURATION, DEFAULT_EXPIRE_DURATION,
type RtcMembershipData,
type SessionMembershipData,
} from "./CallMembership.ts"; } from "./CallMembership.ts";
import type {
RtcMembershipData,
} from "./membership/rtc.ts"
import type {
SessionMembershipData,
} from "./membership/legacy.ts"
import { type Transport, isMyMembership, type RTCCallIntent, Status, SlotDescription } from "./types.ts"; import { type Transport, isMyMembership, type RTCCallIntent, Status, SlotDescription } from "./types.ts";
import { type MembershipConfig, type SessionConfig } from "./MatrixRTCSession.ts"; import { type MembershipConfig, type SessionConfig } from "./MatrixRTCSession.ts";
import { ActionScheduler, type ActionUpdate } from "./MembershipManagerActionScheduler.ts"; import { ActionScheduler, type ActionUpdate } from "./MembershipManagerActionScheduler.ts";
@@ -181,7 +185,7 @@ type MembershipManagerClient = Pick<
* - Stop the timer for the delay refresh * - Stop the timer for the delay refresh
* - Stop the timer for updating the state event * - Stop the timer for updating the state event
*/ */
export class MembershipManager export abstract class MembershipManager<MembershipData extends SessionMembershipData|RtcMembershipData>
extends TypedEventEmitter<MembershipManagerEvent, MembershipManagerEventHandlerMap> extends TypedEventEmitter<MembershipManagerEvent, MembershipManagerEventHandlerMap>
implements IMembershipManager implements IMembershipManager
{ {
@@ -382,7 +386,7 @@ export class MembershipManager
protected memberId: string; protected memberId: string;
protected rtcTransport?: Transport; protected rtcTransport?: Transport;
/** @deprecated This will be removed in favor or rtcTransport becoming a list of actively used transports */ /** @deprecated This will be removed in favor or rtcTransport becoming a list of actively used transports */
private fociPreferred?: Transport[]; protected fociPreferred?: Transport[];
// Config: // Config:
private delayedLeaveEventDelayMsOverride?: number; private delayedLeaveEventDelayMsOverride?: number;
@@ -473,15 +477,7 @@ export class MembershipManager
} }
} }
// an abstraction to switch between sending state or a sticky event protected abstract clientSendDelayedDisconnectMembership: () => Promise<SendDelayedEventResponse>;
protected clientSendDelayedDisconnectMembership: () => Promise<SendDelayedEventResponse> = () =>
this.client._unstable_sendDelayedStateEvent(
this.room.roomId,
{ delay: this.delayedLeaveEventDelayMs },
EventType.GroupCallMemberPrefix,
{},
this.memberId,
);
// HANDLERS (used in the membershipLoopHandler) // HANDLERS (used in the membershipLoopHandler)
private async sendOrResendDelayedLeaveEvent(): Promise<ActionUpdate> { private async sendOrResendDelayedLeaveEvent(): Promise<ActionUpdate> {
@@ -669,16 +665,9 @@ export class MembershipManager
}); });
} }
protected clientSendMembership: ( protected abstract clientSendMembership: (
myMembership: RtcMembershipData | SessionMembershipData | EmptyObject, myMembership: MembershipData | EmptyObject,
) => Promise<ISendEventResponse> = (myMembership) => { ) => Promise<ISendEventResponse>;
return this.client.sendStateEvent(
this.room.roomId,
EventType.GroupCallMemberPrefix,
myMembership as EmptyObject | SessionMembershipData,
this.memberId,
);
};
private async sendJoinEvent(): Promise<ActionUpdate> { private async sendJoinEvent(): Promise<ActionUpdate> {
return await this.clientSendMembership(this.makeMyMembership(this.membershipEventExpiryMs)) return await this.clientSendMembership(this.makeMyMembership(this.membershipEventExpiryMs))
@@ -771,30 +760,7 @@ export class MembershipManager
/** /**
* Constructs our own membership * Constructs our own membership
*/ */
protected makeMyMembership(expires: number): SessionMembershipData | RtcMembershipData { protected abstract makeMyMembership(expires: number): MembershipData;
const ownMembership = this.ownMembership;
const focusObjects =
this.rtcTransport === undefined
? {
focus_active: { type: "livekit", focus_selection: "oldest_membership" } as const,
foci_preferred: this.fociPreferred ?? [],
}
: {
focus_active: { type: "livekit", focus_selection: "multi_sfu" } as const,
foci_preferred: [this.rtcTransport, ...(this.fociPreferred ?? [])],
};
return {
"application": this.slotDescription.application,
"call_id": this.slotDescription.id,
"scope": "m.room",
"device_id": this.deviceId,
expires,
"m.call.intent": this.callIntent,
...focusObjects,
...(ownMembership !== undefined ? { created_ts: ownMembership.createdTs() } : undefined),
};
}
// Error checks and handlers // Error checks and handlers
@@ -1020,11 +986,65 @@ export class MembershipManager
} }
} }
/**
* Handles sending membership for MSC3401 RTC events.
*/
export class LegacyMembershipManager extends MembershipManager<SessionMembershipData> {
protected clientSendDelayedDisconnectMembership: () => Promise<SendDelayedEventResponse> = () =>
this.client._unstable_sendDelayedStateEvent(
this.room.roomId,
{ delay: this.delayedLeaveEventDelayMs },
EventType.GroupCallMemberPrefix,
{},
this.memberId,
);
protected makeMyMembership(expires: number): SessionMembershipData {
const ownMembership = this.ownMembership;
const focusObjects =
this.rtcTransport === undefined
? {
focus_active: { type: "livekit", focus_selection: "oldest_membership" } as const,
foci_preferred: this.fociPreferred ?? [],
}
: {
focus_active: { type: "livekit", focus_selection: "multi_sfu" } as const,
foci_preferred: [this.rtcTransport, ...(this.fociPreferred ?? [])],
};
return {
"application": this.slotDescription.application,
"call_id": this.slotDescription.id ?? "",
"scope": "m.room",
"device_id": this.deviceId,
expires,
"m.call.intent": this.callIntent,
...focusObjects,
...(ownMembership !== undefined ? { created_ts: ownMembership.createdTs() } : undefined),
};
}
protected clientSendMembership: (
myMembership: SessionMembershipData | EmptyObject,
) => Promise<ISendEventResponse> = (myMembership) => {
return this.client.sendStateEvent(
this.room.roomId,
EventType.GroupCallMemberPrefix,
myMembership,
this.memberId,
);
};
}
/** /**
* Implementation of the Membership manager that uses sticky events * Implementation of the Membership manager that uses sticky events
* rather than state events. * rather than state events.
*
* This exclusively sends RTCMembershipData
*/ */
export class StickyEventMembershipManager extends MembershipManager { export class StickyEventMembershipManager extends MembershipManager<RtcMembershipData> {
public constructor( public constructor(
joinConfig: (SessionConfig & MembershipConfig) | undefined, joinConfig: (SessionConfig & MembershipConfig) | undefined,
room: Pick<Room, "getLiveTimeline" | "roomId" | "getVersion">, room: Pick<Room, "getLiveTimeline" | "roomId" | "getVersion">,
@@ -1036,6 +1056,8 @@ export class StickyEventMembershipManager extends MembershipManager {
super(joinConfig, room, clientWithSticky, sessionDescription, parentLogger); super(joinConfig, room, clientWithSticky, sessionDescription, parentLogger);
} }
protected readonly eventType = EventType.RTCMembership;
protected clientSendDelayedDisconnectMembership: () => Promise<SendDelayedEventResponse> = () => protected clientSendDelayedDisconnectMembership: () => Promise<SendDelayedEventResponse> = () =>
this.clientWithSticky._unstable_sendStickyDelayedEvent( this.clientWithSticky._unstable_sendStickyDelayedEvent(
this.room.roomId, this.room.roomId,
@@ -1047,7 +1069,7 @@ export class StickyEventMembershipManager extends MembershipManager {
); );
protected clientSendMembership: ( protected clientSendMembership: (
myMembership: RtcMembershipData | SessionMembershipData | EmptyObject, myMembership: RtcMembershipData | EmptyObject,
) => Promise<ISendEventResponse> = (myMembership) => { ) => Promise<ISendEventResponse> = (myMembership) => {
return this.clientWithSticky._unstable_sendStickyEvent( return this.clientWithSticky._unstable_sendStickyEvent(
this.room.roomId, this.room.roomId,
@@ -1066,7 +1088,7 @@ export class StickyEventMembershipManager extends MembershipManager {
return super.actionUpdateFromErrors(e, t, StickyEventMembershipManager.nameMap.get(m) ?? "unknown"); return super.actionUpdateFromErrors(e, t, StickyEventMembershipManager.nameMap.get(m) ?? "unknown");
} }
protected makeMyMembership(expires: number): SessionMembershipData | RtcMembershipData { protected makeMyMembership(_expires: number): RtcMembershipData {
const ownMembership = this.ownMembership; const ownMembership = this.ownMembership;
const relationObject = ownMembership?.eventId const relationObject = ownMembership?.eventId
@@ -1079,7 +1101,7 @@ export class StickyEventMembershipManager extends MembershipManager {
}, },
slot_id: slotDescriptionToId(this.slotDescription), slot_id: slotDescriptionToId(this.slotDescription),
rtc_transports: this.rtcTransport ? [this.rtcTransport] : [], rtc_transports: this.rtcTransport ? [this.rtcTransport] : [],
member: { device_id: this.deviceId, user_id: this.client.getUserId()!, id: this.memberId }, member: { claimed_device_id: this.deviceId, claimed_user_id: this.client.getUserId()!, id: this.memberId },
versions: [], versions: [],
...relationObject, ...relationObject,
}; };