matrix-js-sdk 43.0.0 → 44.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/lib/matrixrtc/CallMembership.d.ts +30 -25
- package/lib/matrixrtc/CallMembership.d.ts.map +1 -1
- package/lib/matrixrtc/CallMembership.js +91 -100
- package/lib/matrixrtc/CallMembership.js.map +1 -1
- package/lib/matrixrtc/EncryptionManager.d.ts +6 -4
- package/lib/matrixrtc/EncryptionManager.d.ts.map +1 -1
- package/lib/matrixrtc/EncryptionManager.js.map +1 -1
- package/lib/matrixrtc/IMembershipManager.d.ts +2 -15
- package/lib/matrixrtc/IMembershipManager.d.ts.map +1 -1
- package/lib/matrixrtc/IMembershipManager.js.map +1 -1
- package/lib/matrixrtc/LivekitTransport.d.ts +36 -7
- package/lib/matrixrtc/LivekitTransport.d.ts.map +1 -1
- package/lib/matrixrtc/LivekitTransport.js +29 -2
- package/lib/matrixrtc/LivekitTransport.js.map +1 -1
- package/lib/matrixrtc/MatrixRTCSession.d.ts +12 -51
- package/lib/matrixrtc/MatrixRTCSession.d.ts.map +1 -1
- package/lib/matrixrtc/MatrixRTCSession.js +10 -66
- package/lib/matrixrtc/MatrixRTCSession.js.map +1 -1
- package/lib/matrixrtc/MembershipManager.d.ts +5 -10
- package/lib/matrixrtc/MembershipManager.d.ts.map +1 -1
- package/lib/matrixrtc/MembershipManager.js +25 -44
- package/lib/matrixrtc/MembershipManager.js.map +1 -1
- package/lib/matrixrtc/RTCEncryptionManager.d.ts +8 -8
- package/lib/matrixrtc/RTCEncryptionManager.d.ts.map +1 -1
- package/lib/matrixrtc/RTCEncryptionManager.js +30 -22
- package/lib/matrixrtc/RTCEncryptionManager.js.map +1 -1
- package/lib/matrixrtc/ToDeviceKeyTransport.js +7 -8
- package/lib/matrixrtc/ToDeviceKeyTransport.js.map +1 -1
- package/lib/matrixrtc/membershipData/rtc.d.ts +8 -13
- package/lib/matrixrtc/membershipData/rtc.d.ts.map +1 -1
- package/lib/matrixrtc/membershipData/rtc.js +2 -11
- package/lib/matrixrtc/membershipData/rtc.js.map +1 -1
- package/lib/matrixrtc/membershipData/session.d.ts +6 -2
- package/lib/matrixrtc/membershipData/session.d.ts.map +1 -1
- package/lib/matrixrtc/membershipData/session.js +3 -0
- package/lib/matrixrtc/membershipData/session.js.map +1 -1
- package/lib/matrixrtc/types.d.ts +5 -0
- package/lib/matrixrtc/types.d.ts.map +1 -1
- package/lib/matrixrtc/types.js +5 -0
- package/lib/matrixrtc/types.js.map +1 -1
- package/lib/models/event-timeline-set.d.ts +9 -2
- package/lib/models/event-timeline-set.d.ts.map +1 -1
- package/lib/models/event-timeline-set.js +8 -5
- package/lib/models/event-timeline-set.js.map +1 -1
- package/lib/models/room-sticky-events.d.ts +17 -2
- package/lib/models/room-sticky-events.d.ts.map +1 -1
- package/lib/models/room-sticky-events.js +88 -47
- package/lib/models/room-sticky-events.js.map +1 -1
- package/lib/models/room.d.ts +1 -1
- package/lib/models/room.d.ts.map +1 -1
- package/lib/models/room.js +8 -2
- package/lib/models/room.js.map +1 -1
- package/lib/models/thread.d.ts.map +1 -1
- package/lib/models/thread.js +23 -2
- package/lib/models/thread.js.map +1 -1
- package/lib/rendezvous/MSC4108SignInWithQR.d.ts +3 -3
- package/lib/rendezvous/MSC4108SignInWithQR.d.ts.map +1 -1
- package/lib/rendezvous/MSC4108SignInWithQR.js.map +1 -1
- package/lib/rendezvous/SignInWithQRFlow.d.ts +95 -0
- package/lib/rendezvous/SignInWithQRFlow.d.ts.map +1 -0
- package/lib/rendezvous/SignInWithQRFlow.js +3 -0
- package/lib/rendezvous/SignInWithQRFlow.js.map +1 -0
- package/lib/rendezvous/index.d.ts +1 -0
- package/lib/rendezvous/index.d.ts.map +1 -1
- package/lib/rendezvous/index.js.map +1 -1
- package/lib/rust-crypto/index.js +5 -1
- package/lib/rust-crypto/index.js.map +1 -1
- package/package.json +3 -3
- package/src/matrixrtc/CallMembership.ts +85 -95
- package/src/matrixrtc/EncryptionManager.ts +6 -4
- package/src/matrixrtc/IMembershipManager.ts +2 -15
- package/src/matrixrtc/LivekitTransport.ts +58 -9
- package/src/matrixrtc/MatrixRTCSession.ts +21 -80
- package/src/matrixrtc/MembershipManager.ts +23 -40
- package/src/matrixrtc/RTCEncryptionManager.ts +51 -39
- package/src/matrixrtc/ToDeviceKeyTransport.ts +7 -7
- package/src/matrixrtc/membershipData/rtc.ts +9 -23
- package/src/matrixrtc/membershipData/session.ts +14 -2
- package/src/matrixrtc/types.ts +6 -0
- package/src/models/event-timeline-set.ts +19 -4
- package/src/models/room-sticky-events.ts +92 -58
- package/src/models/room.ts +8 -2
- package/src/models/thread.ts +25 -3
- package/src/rendezvous/MSC4108SignInWithQR.ts +3 -3
- package/src/rendezvous/SignInWithQRFlow.ts +117 -0
- package/src/rendezvous/index.ts +1 -0
- package/src/rust-crypto/index.ts +5 -1
|
@@ -50,15 +50,6 @@ export interface IMembershipManager extends TypedEventEmitter<
|
|
|
50
50
|
MembershipManagerEvent,
|
|
51
51
|
MembershipManagerEventHandlerMap
|
|
52
52
|
> {
|
|
53
|
-
/**
|
|
54
|
-
* If we are trying to join, or have successfully joined the session.
|
|
55
|
-
* It does not reflect if the room state is already configured to represent us being joined.
|
|
56
|
-
* It only means that the Manager should be trying to connect or to disconnect running.
|
|
57
|
-
* The Manager is still running right after isJoined becomes false to send the disconnect events.
|
|
58
|
-
* @returns true if we intend to be participating in the MatrixRTC session
|
|
59
|
-
* @deprecated This name is confusing and replaced by `isActivated()`. (Returns the same as `isActivated()`)
|
|
60
|
-
*/
|
|
61
|
-
isJoined(): boolean;
|
|
62
53
|
/**
|
|
63
54
|
* If the manager is activated. This means it tries to do its job to join the call, resend state events...
|
|
64
55
|
* It does not imply that the room state is already configured to represent being joined.
|
|
@@ -92,14 +83,10 @@ export interface IMembershipManager extends TypedEventEmitter<
|
|
|
92
83
|
|
|
93
84
|
/**
|
|
94
85
|
* Start sending all necessary events to make this user participate in the RTC session.
|
|
95
|
-
* @param
|
|
96
|
-
* If multiSfuFocus is set, this is only needed if this client wants to publish to multiple transports simultaneously.
|
|
97
|
-
* @param multiSfuFocus the active focus to use in the joined RTC membership event. Setting this implies the
|
|
98
|
-
* membership manager will operate in a multi-SFU connection mode. If `undefined`, an `oldest_membership`
|
|
99
|
-
* transport selection will be used instead.
|
|
86
|
+
* @param publishedTransports the list of transports on which the member is publishing.
|
|
100
87
|
* @throws can throw if it exceeds a configured maximum retry.
|
|
101
88
|
*/
|
|
102
|
-
join(
|
|
89
|
+
join(publishedTransports: Transport[], onError?: (error: unknown) => void): void;
|
|
103
90
|
/**
|
|
104
91
|
* Send all necessary events to make this user leave the RTC session.
|
|
105
92
|
* @param timeout the maximum duration in ms until the promise is forced to resolve.
|
|
@@ -16,20 +16,69 @@ limitations under the License.
|
|
|
16
16
|
|
|
17
17
|
import { type Transport } from "./types.ts";
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* @deprecated Use {@link UnstableLivekitTransport} instead, which has multiple
|
|
21
|
+
* variants to support the migration to newer versions of MSC4195.
|
|
22
|
+
*/
|
|
23
|
+
export interface LivekitTransport extends Transport {
|
|
20
24
|
type: "livekit";
|
|
21
25
|
livekit_service_url: string;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
/**
|
|
29
|
+
* @deprecated Use {@link isUnstableLivekitTransport} instead.
|
|
30
|
+
*/
|
|
31
|
+
export const isLivekitTransport = (object: unknown): object is LivekitTransport => {
|
|
32
|
+
if (typeof object !== "object" || object === null) return false;
|
|
33
|
+
const transport = object as Transport;
|
|
26
34
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
return transport.type === "livekit" && typeof transport.livekit_service_url === "string";
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type WebsocketUrl = {
|
|
39
|
+
/**
|
|
40
|
+
* WebSocket URL of the LiveKit server.
|
|
41
|
+
*/
|
|
42
|
+
url: string;
|
|
43
|
+
};
|
|
30
44
|
|
|
31
|
-
|
|
32
|
-
|
|
45
|
+
type ServiceUrl = {
|
|
46
|
+
/**
|
|
47
|
+
* Base URL of the LiveKit JWT service.
|
|
48
|
+
*/
|
|
49
|
+
livekit_service_url: string;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Any LiveKit transport that can be advertised by a homeserver or published by
|
|
54
|
+
* a session member in unstable MSC4195 implementations: `url` only,
|
|
55
|
+
* `livekit_service_url` only, or both during the migration.
|
|
56
|
+
*/
|
|
57
|
+
export type UnstableLivekitTransport =
|
|
58
|
+
// Latest MSC4195 variant, with `url`. Indicates that both publishers and
|
|
59
|
+
// subscribers will use the /_matrix/client/v1/rtc/livekit/get_token
|
|
60
|
+
// endpoint.
|
|
61
|
+
| ({ type: "livekit" } & WebsocketUrl)
|
|
62
|
+
// Legacy variant, with `livekit_service_url`. Indicates that both
|
|
63
|
+
// publishers and subscribers will use the endpoints of the provided LiveKit
|
|
64
|
+
// JWT service.
|
|
65
|
+
| ({ type: "livekit" } & ServiceUrl)
|
|
66
|
+
// Transitional variant, with both `url` and `livekit_service_url`.
|
|
67
|
+
// Indicates that both publishers and subscribers may use either the
|
|
68
|
+
// /_matrix/client/v1/rtc/livekit/get_token endpoint or the provided LiveKit
|
|
69
|
+
// JWT service.
|
|
70
|
+
| ({ type: "livekit" } & WebsocketUrl & ServiceUrl);
|
|
71
|
+
|
|
72
|
+
export const isUnstableLivekitTransport = (object: unknown): object is UnstableLivekitTransport => {
|
|
73
|
+
if (typeof object !== "object" || object === null) return false;
|
|
74
|
+
const transport = object as Transport;
|
|
75
|
+
|
|
76
|
+
if (transport.type !== "livekit") return false;
|
|
77
|
+
if (!("url" in transport || "livekit_service_url" in transport)) return false;
|
|
78
|
+
if ("url" in transport && typeof transport.url !== "string") return false;
|
|
79
|
+
if ("livekit_service_url" in transport && typeof transport.livekit_service_url !== "string") return false;
|
|
80
|
+
return true;
|
|
81
|
+
};
|
|
33
82
|
|
|
34
83
|
/**
|
|
35
84
|
* @deprecated this is just needed for the old focus active / focus fields of a call membership.
|
|
@@ -37,7 +86,7 @@ export const isLivekitTransport = (object: any): object is LivekitTransport =>
|
|
|
37
86
|
*/
|
|
38
87
|
export interface LivekitFocusSelection extends Transport {
|
|
39
88
|
type: "livekit";
|
|
40
|
-
focus_selection: "
|
|
89
|
+
focus_selection: "multi_sfu";
|
|
41
90
|
}
|
|
42
91
|
/**
|
|
43
92
|
* @deprecated see LivekitFocusSelection
|
|
@@ -33,6 +33,7 @@ import type {
|
|
|
33
33
|
Status,
|
|
34
34
|
IRTCNotificationContent,
|
|
35
35
|
RTCCallIntent,
|
|
36
|
+
RTCCallCapability,
|
|
36
37
|
Transport,
|
|
37
38
|
SlotDescription,
|
|
38
39
|
RtcSlotEventContent,
|
|
@@ -83,7 +84,7 @@ export type MatrixRTCSessionEventHandlerMap = {
|
|
|
83
84
|
key: Uint8Array<ArrayBuffer>,
|
|
84
85
|
encryptionKeyIndex: number,
|
|
85
86
|
membership: CallMembershipIdentityParts,
|
|
86
|
-
|
|
87
|
+
backendIdentity: string,
|
|
87
88
|
) => void;
|
|
88
89
|
[MatrixRTCSessionEvent.MembershipManagerError]: (error: unknown) => void;
|
|
89
90
|
[MatrixRTCSessionEvent.DidSendCallNotification]: (
|
|
@@ -104,11 +105,16 @@ export interface SessionConfig {
|
|
|
104
105
|
*/
|
|
105
106
|
callIntent?: RTCCallIntent;
|
|
106
107
|
|
|
108
|
+
/**
|
|
109
|
+
* What kinds of media this device is capable of handling for the call.
|
|
110
|
+
*/
|
|
111
|
+
callCapabilities?: RTCCallCapability[];
|
|
112
|
+
|
|
107
113
|
/**
|
|
108
114
|
* Application-specific data to publish in our membership alongside the
|
|
109
|
-
* application `type
|
|
110
|
-
* an `m.rtc.member` event, or at the top level of a legacy
|
|
111
|
-
* one. Keys should be namespaced. Read back through
|
|
115
|
+
* application `type`, `m.call.intent` and `capabilities`: in the `application`
|
|
116
|
+
* object of an `m.rtc.member` event, or at the top level of a legacy
|
|
117
|
+
* `m.call.member` one. Keys should be namespaced. Read back through
|
|
112
118
|
* {@link CallMembership.applicationData}.
|
|
113
119
|
*/
|
|
114
120
|
applicationData?: Record<string, unknown>;
|
|
@@ -202,12 +208,6 @@ export interface EncryptionConfig {
|
|
|
202
208
|
* media keys for other participants become available.
|
|
203
209
|
*/
|
|
204
210
|
manageMediaKeys?: boolean;
|
|
205
|
-
/**
|
|
206
|
-
* The minimum time (in milliseconds) between each attempt to send encryption key(s).
|
|
207
|
-
* e.g. if this is set to 1000, then we will send at most one key event every second.
|
|
208
|
-
* @deprecated - Not used by the new encryption manager.
|
|
209
|
-
*/
|
|
210
|
-
updateEncryptionKeyThrottle?: number;
|
|
211
211
|
|
|
212
212
|
/**
|
|
213
213
|
* Sometimes it is necessary to rotate the encryption key after a membership update.
|
|
@@ -331,16 +331,6 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|
|
331
331
|
return this.encryptionManager?.isKeyRotationSuppressed ?? false;
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
-
/**
|
|
335
|
-
* The callId (sessionId) of the call.
|
|
336
|
-
*
|
|
337
|
-
* It can be undefined since the callId is only known once the first membership joins.
|
|
338
|
-
* The callId is the property that, per definition, groups memberships into one call.
|
|
339
|
-
* @deprecated use `slotId` instead.
|
|
340
|
-
*/
|
|
341
|
-
public get callId(): string | undefined {
|
|
342
|
-
return this.slotDescription?.id;
|
|
343
|
-
}
|
|
344
334
|
/**
|
|
345
335
|
* The slotId of the call.
|
|
346
336
|
* `{application}#{appSpecificId}`
|
|
@@ -550,12 +540,12 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|
|
550
540
|
this.initialMembershipCalculated = this.ensureRecalculateSessionMembers();
|
|
551
541
|
this.setExpiryTimer();
|
|
552
542
|
}
|
|
543
|
+
|
|
553
544
|
/*
|
|
554
545
|
* Returns true if we intend to be participating in the MatrixRTC session.
|
|
555
|
-
* This is determined by checking if the relativeExpiry has been set.
|
|
556
546
|
*/
|
|
557
547
|
public isJoined(): boolean {
|
|
558
|
-
return this.membershipManager?.
|
|
548
|
+
return this.membershipManager?.isActivated() ?? false;
|
|
559
549
|
}
|
|
560
550
|
|
|
561
551
|
/**
|
|
@@ -582,22 +572,15 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|
|
582
572
|
* Announces this user and device as joined to the MatrixRTC session,
|
|
583
573
|
* and continues to update the membership event to keep it valid until
|
|
584
574
|
* leaveRoomSession() is called
|
|
585
|
-
* This will not subscribe to updates: remember to call subscribe() separately if
|
|
586
|
-
* desired.
|
|
587
575
|
* This method will return immediately and the session will be joined in the background.
|
|
588
576
|
* @param ownMembershipIdentity the identity of the user and device joining the session.
|
|
589
577
|
* This will be put into the content.member.
|
|
590
|
-
* @param
|
|
591
|
-
* If multiSfuFocus is set, this is only needed if this client wants to publish to multiple transports simultaneously.
|
|
592
|
-
* @param multiSfuFocus the active focus to use in the joined RTC membership event. Setting this implies the
|
|
593
|
-
* membership manager will operate in a multi-SFU connection mode. If `undefined`, an `oldest_membership`
|
|
594
|
-
* transport selection will be used instead.
|
|
578
|
+
* @param publishedTransports the list of transports on which the member is publishing.
|
|
595
579
|
* @param joinConfig - Additional configuration for the joined session.
|
|
596
580
|
*/
|
|
597
|
-
public
|
|
581
|
+
public join(
|
|
598
582
|
ownMembershipIdentity: CallMembershipIdentityParts,
|
|
599
|
-
|
|
600
|
-
multiSfuFocus?: Transport,
|
|
583
|
+
publishedTransports: Transport[],
|
|
601
584
|
joinConfig?: JoinSessionConfig,
|
|
602
585
|
): void {
|
|
603
586
|
if (this.isJoined()) {
|
|
@@ -632,14 +615,14 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|
|
632
615
|
keyBin: Uint8Array<ArrayBuffer>,
|
|
633
616
|
encryptionKeyIndex: number,
|
|
634
617
|
membership: CallMembershipIdentityParts,
|
|
635
|
-
|
|
618
|
+
backendIdentity: string,
|
|
636
619
|
) => {
|
|
637
620
|
this.emit(
|
|
638
621
|
MatrixRTCSessionEvent.EncryptionKeyChanged,
|
|
639
622
|
keyBin,
|
|
640
623
|
encryptionKeyIndex,
|
|
641
624
|
membership,
|
|
642
|
-
|
|
625
|
+
backendIdentity,
|
|
643
626
|
);
|
|
644
627
|
},
|
|
645
628
|
this.logger,
|
|
@@ -650,45 +633,25 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|
|
650
633
|
this.pendingNotificationToSend = this.joinConfig?.notificationType;
|
|
651
634
|
|
|
652
635
|
// Join!
|
|
653
|
-
this.membershipManager.join(
|
|
636
|
+
this.membershipManager.join(publishedTransports, (e) => {
|
|
654
637
|
this.logger.error("MembershipManager encountered an unrecoverable error: ", e);
|
|
655
638
|
this.emit(MatrixRTCSessionEvent.MembershipManagerError, e);
|
|
656
639
|
this.emit(MatrixRTCSessionEvent.JoinStateChanged, this.isJoined());
|
|
657
640
|
});
|
|
658
|
-
this.encryptionManager.join(joinConfig);
|
|
641
|
+
this.encryptionManager.join(joinConfig, publishedTransports);
|
|
659
642
|
|
|
660
643
|
this.emit(MatrixRTCSessionEvent.JoinStateChanged, true);
|
|
661
644
|
}
|
|
662
645
|
|
|
663
|
-
/**
|
|
664
|
-
*
|
|
665
|
-
* @param fociPreferred
|
|
666
|
-
* @param multiSfuFocus
|
|
667
|
-
* @param joinConfig
|
|
668
|
-
* @deprecated use the joinRTCSession method instead
|
|
669
|
-
*/
|
|
670
|
-
public joinRoomSession(
|
|
671
|
-
fociPreferred: Transport[],
|
|
672
|
-
multiSfuFocus?: Transport,
|
|
673
|
-
joinConfig?: JoinSessionConfig,
|
|
674
|
-
): void {
|
|
675
|
-
const [userId, deviceId] = [this.client.getUserId()!, this.client.getDeviceId()!];
|
|
676
|
-
// TODO this wants to become a UUID
|
|
677
|
-
const memberId = `${userId}:${deviceId}`;
|
|
678
|
-
this.joinRTCSession({ userId, deviceId, memberId }, fociPreferred, multiSfuFocus, joinConfig);
|
|
679
|
-
}
|
|
680
|
-
|
|
681
646
|
/**
|
|
682
647
|
* Announces this user and device as having left the MatrixRTC session
|
|
683
648
|
* and stops scheduled updates.
|
|
684
|
-
* This will not unsubscribe from updates: remember to call unsubscribe() separately if
|
|
685
|
-
* desired.
|
|
686
649
|
* The membership update required to leave the session will retry if it fails.
|
|
687
650
|
* Without network connection the promise will never resolve.
|
|
688
651
|
* A timeout can be provided so that there is a guarantee for the promise to resolve.
|
|
689
652
|
* @returns Whether the membership update was attempted and did not time out.
|
|
690
653
|
*/
|
|
691
|
-
public async
|
|
654
|
+
public async leave(timeout?: number): Promise<boolean> {
|
|
692
655
|
if (!this.isJoined()) {
|
|
693
656
|
this.logger.info(`Not joined to session in room ${this.roomSubset.roomId}: ignoring leave call`);
|
|
694
657
|
return false;
|
|
@@ -703,19 +666,6 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|
|
703
666
|
|
|
704
667
|
return await leavePromise;
|
|
705
668
|
}
|
|
706
|
-
/**
|
|
707
|
-
* This returns the focus in use by the oldest membership.
|
|
708
|
-
* Do not use since this might be just the focus for the oldest membership. others might use a different focus.
|
|
709
|
-
* @deprecated use `member.getTransport(session.getOldestMembership())` instead for the specific member you want to get the focus for.
|
|
710
|
-
*/
|
|
711
|
-
public getFocusInUse(): Transport | undefined {
|
|
712
|
-
const oldestMembership = this.getOldestMembership();
|
|
713
|
-
return oldestMembership?.getTransport(oldestMembership);
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
public getOldestMembership(): CallMembership | undefined {
|
|
717
|
-
return this.memberships[0];
|
|
718
|
-
}
|
|
719
669
|
|
|
720
670
|
/**
|
|
721
671
|
* Get the call intent for the current call, based on what members are advertising. If one or more
|
|
@@ -767,7 +717,7 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|
|
767
717
|
keyInfo.key,
|
|
768
718
|
keyInfo.keyIndex,
|
|
769
719
|
keyInfo.membership,
|
|
770
|
-
keyInfo.
|
|
720
|
+
keyInfo.backendIdentity,
|
|
771
721
|
);
|
|
772
722
|
});
|
|
773
723
|
});
|
|
@@ -898,15 +848,6 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|
|
898
848
|
}
|
|
899
849
|
};
|
|
900
850
|
|
|
901
|
-
/**
|
|
902
|
-
* Call this when something changed that may impacts the current MatrixRTC members in this session.
|
|
903
|
-
*
|
|
904
|
-
* @deprecated use {@link ensureRecalculateSessionMembers} instead.
|
|
905
|
-
*/
|
|
906
|
-
public _onRTCSessionMemberUpdate = async (): Promise<void> => {
|
|
907
|
-
await this.ensureRecalculateSessionMembers();
|
|
908
|
-
};
|
|
909
|
-
|
|
910
851
|
// Recalculations are chained onto this promise, so they never run in parallel.
|
|
911
852
|
private recalculateSessionMembersPromise: Promise<void> = Promise.resolve();
|
|
912
853
|
|
|
@@ -15,7 +15,7 @@ limitations under the License.
|
|
|
15
15
|
*/
|
|
16
16
|
import { AbortError } from "p-retry";
|
|
17
17
|
|
|
18
|
-
import { EventType
|
|
18
|
+
import { EventType } from "../@types/event.ts";
|
|
19
19
|
import { type ISendEventResponse, type SendDelayedEventResponse } from "../@types/requests.ts";
|
|
20
20
|
import { type EmptyObject } from "../@types/common.ts";
|
|
21
21
|
import type { MatrixClient } from "../client.ts";
|
|
@@ -23,7 +23,14 @@ import { ConnectionError, HTTPError, MatrixError } from "../http-api/errors.ts";
|
|
|
23
23
|
import { type Logger, logger as rootLogger } from "../logger.ts";
|
|
24
24
|
import { type Room } from "../models/room.ts";
|
|
25
25
|
import { type CallMembership, DEFAULT_EXPIRE_DURATION } from "./CallMembership.ts";
|
|
26
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
type Transport,
|
|
28
|
+
isMyMembership,
|
|
29
|
+
type RTCCallCapability,
|
|
30
|
+
type RTCCallIntent,
|
|
31
|
+
Status,
|
|
32
|
+
type SlotDescription,
|
|
33
|
+
} from "./types.ts";
|
|
27
34
|
import { type MembershipConfig, type SessionConfig } from "./MatrixRTCSession.ts";
|
|
28
35
|
import { type Action, ActionScheduler, type ActionUpdate } from "./MembershipManagerActionScheduler.ts";
|
|
29
36
|
import { TypedEventEmitter } from "../models/typed-event-emitter.ts";
|
|
@@ -36,7 +43,6 @@ import {
|
|
|
36
43
|
import { type RtcMembershipData, type SessionMembershipData } from "./membershipData/index.ts";
|
|
37
44
|
import { computeSlotId } from "./utils.ts";
|
|
38
45
|
import { deepCompare } from "../utils.ts";
|
|
39
|
-
import { isLivekitTransportConfig } from "./LivekitTransport.ts";
|
|
40
46
|
|
|
41
47
|
/* MembershipActionTypes:
|
|
42
48
|
On Join: ───────────────────┐ ┌───────────────(1)───────────┐
|
|
@@ -209,6 +215,7 @@ export class MembershipManager
|
|
|
209
215
|
private activated = false;
|
|
210
216
|
private readonly logger: Logger;
|
|
211
217
|
protected callIntent: RTCCallIntent | undefined;
|
|
218
|
+
protected callCapabilities: RTCCallCapability[] | undefined;
|
|
212
219
|
protected applicationData: Record<string, unknown> | undefined;
|
|
213
220
|
|
|
214
221
|
public isActivated(): boolean {
|
|
@@ -222,23 +229,18 @@ export class MembershipManager
|
|
|
222
229
|
/**
|
|
223
230
|
* Puts the MembershipManager in a state where it tries to be joined.
|
|
224
231
|
* It will send delayed events and membership events
|
|
225
|
-
* @param
|
|
226
|
-
* If multiSfuFocus is set, this is only needed if this client wants to publish to multiple transports simultaneously.
|
|
227
|
-
* @param multiSfuFocus the active focus to use in the joined RTC membership event. Setting this implies the
|
|
228
|
-
* membership manager will operate in a multi-SFU connection mode. If `undefined`, an `oldest_membership`
|
|
229
|
-
* transport selection will be used instead.
|
|
232
|
+
* @param publishedTransports the list of transports on which the member is publishing.
|
|
230
233
|
* @param onError This will be called once the membership manager encounters an unrecoverable error.
|
|
231
234
|
* This should bubble up the the frontend to communicate that the call does not work in the current environment.
|
|
232
235
|
* The original underlying error is preserved as `error.cause`, so consumers can `instanceof`-check the typed
|
|
233
236
|
* cause.
|
|
234
237
|
*/
|
|
235
|
-
public join(
|
|
238
|
+
public join(publishedTransports: Transport[], onError?: (error: unknown) => void): void {
|
|
236
239
|
if (this.scheduler.running) {
|
|
237
240
|
this.logger.error("MembershipManager is already running. Ignoring join request.");
|
|
238
241
|
return;
|
|
239
242
|
}
|
|
240
|
-
this.
|
|
241
|
-
this.rtcTransport = multiSfuFocus;
|
|
243
|
+
this.publishedTransports = publishedTransports;
|
|
242
244
|
this.leavePromiseResolvers = undefined;
|
|
243
245
|
this.activated = true;
|
|
244
246
|
this.oldStatus = this.status;
|
|
@@ -367,6 +369,7 @@ export class MembershipManager
|
|
|
367
369
|
this.stateKey = this.makeMembershipStateKey(userId, deviceId);
|
|
368
370
|
this.state = MembershipManager.defaultState;
|
|
369
371
|
this.callIntent = joinConfig?.callIntent;
|
|
372
|
+
this.callCapabilities = joinConfig?.callCapabilities;
|
|
370
373
|
this.applicationData = joinConfig?.applicationData;
|
|
371
374
|
this.scheduler = new ActionScheduler((type): Promise<ActionUpdate> => {
|
|
372
375
|
if (this.oldStatus) {
|
|
@@ -414,9 +417,7 @@ export class MembershipManager
|
|
|
414
417
|
protected deviceId: string;
|
|
415
418
|
protected userId: string;
|
|
416
419
|
protected stateKey: string;
|
|
417
|
-
protected
|
|
418
|
-
/** @deprecated This will be removed in favor or rtcTransport becoming a list of actively used transports */
|
|
419
|
-
private fociPreferred?: Transport[];
|
|
420
|
+
protected publishedTransports: Transport[] = [];
|
|
420
421
|
|
|
421
422
|
// Config:
|
|
422
423
|
private delayedLeaveEventDelayMsOverride?: number;
|
|
@@ -753,6 +754,9 @@ export class MembershipManager
|
|
|
753
754
|
this.state.expireUpdateIterations = 1;
|
|
754
755
|
this.state.hasMemberStateEvent = true;
|
|
755
756
|
this.resetRateLimitCounter(MembershipActionType.SendJoinEvent);
|
|
757
|
+
// A successful (re-)join is a fresh membership: failures accumulated by the previous one
|
|
758
|
+
// (e.g. delayed event restarts that timed out before the server sent our leave) must not carry over.
|
|
759
|
+
this.state.networkErrorRetries.clear();
|
|
756
760
|
// An UpdateExpiry action might be left over from a previous join event.
|
|
757
761
|
// We can reach sendJoinEvent when the delayed leave event gets send by the HS.
|
|
758
762
|
// The branch where we might have a leftover UpdateExpiry action is:
|
|
@@ -1003,16 +1007,6 @@ export class MembershipManager
|
|
|
1003
1007
|
const needsEmptyStringRoomFix =
|
|
1004
1008
|
this.slotDescription.application === "m.call" && this.slotDescription.id === "ROOM";
|
|
1005
1009
|
|
|
1006
|
-
const focusObjects: Pick<SessionMembershipData, "foci_preferred" | "focus_active"> =
|
|
1007
|
-
this.rtcTransport === undefined
|
|
1008
|
-
? {
|
|
1009
|
-
focus_active: { type: "livekit", focus_selection: "oldest_membership" } as const,
|
|
1010
|
-
foci_preferred: this.fociPreferred ?? [],
|
|
1011
|
-
}
|
|
1012
|
-
: {
|
|
1013
|
-
focus_active: { type: "livekit", focus_selection: "multi_sfu" } as const,
|
|
1014
|
-
foci_preferred: [this.rtcTransport, ...(this.fociPreferred ?? [])],
|
|
1015
|
-
};
|
|
1016
1010
|
return {
|
|
1017
1011
|
// Legacy memberships have no application object, so the
|
|
1018
1012
|
// application's data sits at the top level, under the fields
|
|
@@ -1030,7 +1024,9 @@ export class MembershipManager
|
|
|
1030
1024
|
"membershipID": `${this.userId}:${this.deviceId}`,
|
|
1031
1025
|
expires,
|
|
1032
1026
|
"m.call.intent": this.callIntent,
|
|
1033
|
-
...
|
|
1027
|
+
...(this.callCapabilities !== undefined ? { capabilities: this.callCapabilities } : {}),
|
|
1028
|
+
"focus_active": { type: "livekit", focus_selection: "multi_sfu" } as const,
|
|
1029
|
+
"foci_preferred": this.publishedTransports,
|
|
1034
1030
|
...(ownMembership !== undefined ? { created_ts: ownMembership.createdTs() } : undefined),
|
|
1035
1031
|
};
|
|
1036
1032
|
}
|
|
@@ -1321,30 +1317,17 @@ export class StickyEventMembershipManager extends MembershipManager {
|
|
|
1321
1317
|
* @returns Only returns `RtcMembershipData`
|
|
1322
1318
|
*/
|
|
1323
1319
|
protected makeMyMembership(): RtcMembershipData {
|
|
1324
|
-
const ownMembership = this.ownMembership;
|
|
1325
|
-
|
|
1326
|
-
const livekitTransport = isLivekitTransportConfig(this.rtcTransport) ? this.rtcTransport : undefined;
|
|
1327
|
-
const relationObject = ownMembership?.eventId
|
|
1328
|
-
? { "m.relation": { rel_type: RelationType.Reference, event_id: ownMembership?.eventId } }
|
|
1329
|
-
: {};
|
|
1330
1320
|
return {
|
|
1331
1321
|
application: {
|
|
1332
1322
|
...this.applicationData,
|
|
1333
1323
|
type: this.slotDescription.application,
|
|
1334
1324
|
...(this.callIntent ? { "m.call.intent": this.callIntent } : {}),
|
|
1325
|
+
...(this.callCapabilities !== undefined ? { capabilities: this.callCapabilities } : {}),
|
|
1335
1326
|
},
|
|
1336
1327
|
slot_id: computeSlotId(this.slotDescription),
|
|
1337
|
-
transports: {
|
|
1338
|
-
// Make sure we do not add the alias to the transport.
|
|
1339
|
-
// It is not needed in matrix2.0. The additional session information will be used to find the right alias on the sfu.
|
|
1340
|
-
published: livekitTransport
|
|
1341
|
-
? [{ type: livekitTransport.type, livekit_service_url: livekitTransport.livekit_service_url }]
|
|
1342
|
-
: [],
|
|
1343
|
-
can_subscribe: ["livekit"],
|
|
1344
|
-
},
|
|
1328
|
+
transports: { published: this.publishedTransports, can_subscribe: ["livekit"] },
|
|
1345
1329
|
member: { device_id: this.deviceId, user_id: this.userId, id: this.memberId },
|
|
1346
1330
|
versions: [],
|
|
1347
|
-
...relationObject,
|
|
1348
1331
|
};
|
|
1349
1332
|
}
|
|
1350
1333
|
}
|