review: count as publishing even if not yet connected to LK
This commit is contained in:
@@ -35,6 +35,7 @@ import type {
|
|||||||
import {
|
import {
|
||||||
type ConnectionOpts,
|
type ConnectionOpts,
|
||||||
type FocusConnectionState,
|
type FocusConnectionState,
|
||||||
|
type PublishingParticipant,
|
||||||
RemoteConnection,
|
RemoteConnection,
|
||||||
} from "./Connection.ts";
|
} from "./Connection.ts";
|
||||||
import { ObservableScope } from "./ObservableScope.ts";
|
import { ObservableScope } from "./ObservableScope.ts";
|
||||||
@@ -454,22 +455,19 @@ describe("Publishing participants observations", () => {
|
|||||||
|
|
||||||
const bobIsAPublisher = Promise.withResolvers<void>();
|
const bobIsAPublisher = Promise.withResolvers<void>();
|
||||||
const danIsAPublisher = Promise.withResolvers<void>();
|
const danIsAPublisher = Promise.withResolvers<void>();
|
||||||
const observedPublishers: {
|
const observedPublishers: PublishingParticipant[][] = [];
|
||||||
participant: RemoteParticipant;
|
|
||||||
membership: CallMembership;
|
|
||||||
}[][] = [];
|
|
||||||
const s = connection.publishingParticipants$.subscribe((publishers) => {
|
const s = connection.publishingParticipants$.subscribe((publishers) => {
|
||||||
observedPublishers.push(publishers);
|
observedPublishers.push(publishers);
|
||||||
if (
|
if (
|
||||||
publishers.some(
|
publishers.some(
|
||||||
(p) => p.participant.identity === "@bob:example.org:DEV111",
|
(p) => p.participant?.identity === "@bob:example.org:DEV111",
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
bobIsAPublisher.resolve();
|
bobIsAPublisher.resolve();
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
publishers.some(
|
publishers.some(
|
||||||
(p) => p.participant.identity === "@dan:example.org:DEV333",
|
(p) => p.participant?.identity === "@dan:example.org:DEV333",
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
danIsAPublisher.resolve();
|
danIsAPublisher.resolve();
|
||||||
@@ -529,7 +527,7 @@ describe("Publishing participants observations", () => {
|
|||||||
await bobIsAPublisher.promise;
|
await bobIsAPublisher.promise;
|
||||||
const publishers = observedPublishers.pop();
|
const publishers = observedPublishers.pop();
|
||||||
expect(publishers?.length).toEqual(1);
|
expect(publishers?.length).toEqual(1);
|
||||||
expect(publishers?.[0].participant.identity).toEqual(
|
expect(publishers?.[0].participant?.identity).toEqual(
|
||||||
"@bob:example.org:DEV111",
|
"@bob:example.org:DEV111",
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -546,12 +544,12 @@ describe("Publishing participants observations", () => {
|
|||||||
expect(twoPublishers?.length).toEqual(2);
|
expect(twoPublishers?.length).toEqual(2);
|
||||||
expect(
|
expect(
|
||||||
twoPublishers?.some(
|
twoPublishers?.some(
|
||||||
(p) => p.participant.identity === "@bob:example.org:DEV111",
|
(p) => p.participant?.identity === "@bob:example.org:DEV111",
|
||||||
),
|
),
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
expect(
|
expect(
|
||||||
twoPublishers?.some(
|
twoPublishers?.some(
|
||||||
(p) => p.participant.identity === "@dan:example.org:DEV333",
|
(p) => p.participant?.identity === "@dan:example.org:DEV333",
|
||||||
),
|
),
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
|
|
||||||
@@ -568,12 +566,25 @@ describe("Publishing participants observations", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const updatedPublishers = observedPublishers.pop();
|
const updatedPublishers = observedPublishers.pop();
|
||||||
expect(updatedPublishers?.length).toEqual(1);
|
// Bob is not connected to the room but he is still in the rtc memberships declaring that
|
||||||
|
// he is using that focus to publish, so he should still appear as a publisher
|
||||||
|
expect(updatedPublishers?.length).toEqual(2);
|
||||||
|
const pp = updatedPublishers?.find(
|
||||||
|
(p) => p.membership.sender == "@bob:example.org",
|
||||||
|
);
|
||||||
|
expect(pp).toBeDefined();
|
||||||
|
expect(pp!.participant).not.toBeDefined();
|
||||||
expect(
|
expect(
|
||||||
updatedPublishers?.some(
|
updatedPublishers?.some(
|
||||||
(p) => p.participant.identity === "@dan:example.org:DEV333",
|
(p) => p.participant?.identity === "@dan:example.org:DEV333",
|
||||||
),
|
),
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
|
// Now if bob is not in the rtc memberships, he should disappear
|
||||||
|
const noBob = rtcMemberships.filter(
|
||||||
|
({ membership }) => membership.sender !== "@bob:example.org",
|
||||||
|
);
|
||||||
|
fakeMembershipsFocusMap$.next(noBob);
|
||||||
|
expect(observedPublishers.pop()?.length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be scoped to parent scope", (): void => {
|
it("should be scoped to parent scope", (): void => {
|
||||||
@@ -581,10 +592,7 @@ describe("Publishing participants observations", () => {
|
|||||||
|
|
||||||
const connection = setupRemoteConnection();
|
const connection = setupRemoteConnection();
|
||||||
|
|
||||||
let observedPublishers: {
|
let observedPublishers: PublishingParticipant[][] = [];
|
||||||
participant: RemoteParticipant;
|
|
||||||
membership: CallMembership;
|
|
||||||
}[][] = [];
|
|
||||||
const s = connection.publishingParticipants$.subscribe((publishers) => {
|
const s = connection.publishingParticipants$.subscribe((publishers) => {
|
||||||
observedPublishers.push(publishers);
|
observedPublishers.push(publishers);
|
||||||
});
|
});
|
||||||
@@ -619,7 +627,7 @@ describe("Publishing participants observations", () => {
|
|||||||
// We should have bob has a publisher now
|
// We should have bob has a publisher now
|
||||||
const publishers = observedPublishers.pop();
|
const publishers = observedPublishers.pop();
|
||||||
expect(publishers?.length).toEqual(1);
|
expect(publishers?.length).toEqual(1);
|
||||||
expect(publishers?.[0].participant.identity).toEqual(
|
expect(publishers?.[0].participant?.identity).toEqual(
|
||||||
"@bob:example.org:DEV111",
|
"@bob:example.org:DEV111",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
ConnectionError,
|
ConnectionError,
|
||||||
type ConnectionState,
|
type ConnectionState,
|
||||||
type E2EEOptions,
|
type E2EEOptions,
|
||||||
|
type RemoteParticipant,
|
||||||
Room as LivekitRoom,
|
Room as LivekitRoom,
|
||||||
type RoomOptions,
|
type RoomOptions,
|
||||||
} from "livekit-client";
|
} from "livekit-client";
|
||||||
@@ -64,6 +65,21 @@ export type FocusConnectionState =
|
|||||||
}
|
}
|
||||||
| { state: "Stopped"; focus: LivekitTransport };
|
| { state: "Stopped"; focus: LivekitTransport };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents participant publishing or expected to publish on the connection.
|
||||||
|
* It is paired with its associated rtc membership.
|
||||||
|
*/
|
||||||
|
export type PublishingParticipant = {
|
||||||
|
/**
|
||||||
|
* The LiveKit participant publishing on this connection, or undefined if the participant is not currently (yet) connected to the livekit room.
|
||||||
|
*/
|
||||||
|
participant: RemoteParticipant | undefined;
|
||||||
|
/**
|
||||||
|
* The rtc call membership associated with this participant.
|
||||||
|
*/
|
||||||
|
membership: CallMembership;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A connection to a Matrix RTC LiveKit backend.
|
* A connection to a Matrix RTC LiveKit backend.
|
||||||
*
|
*
|
||||||
@@ -183,7 +199,7 @@ export class Connection {
|
|||||||
* This is derived from `participantsIncludingSubscribers$` and `remoteTransports$`.
|
* This is derived from `participantsIncludingSubscribers$` and `remoteTransports$`.
|
||||||
* It filters the participants to only those that are associated with a membership that claims to publish on this connection.
|
* It filters the participants to only those that are associated with a membership that claims to publish on this connection.
|
||||||
*/
|
*/
|
||||||
public readonly publishingParticipants$;
|
public readonly publishingParticipants$: Behavior<PublishingParticipant[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The focus server to connect to.
|
* The focus server to connect to.
|
||||||
@@ -226,10 +242,10 @@ export class Connection {
|
|||||||
)
|
)
|
||||||
// Pair with their associated LiveKit participant (if any)
|
// Pair with their associated LiveKit participant (if any)
|
||||||
// Uses flatMap to filter out memberships with no associated rtc participant ([])
|
// Uses flatMap to filter out memberships with no associated rtc participant ([])
|
||||||
.flatMap((membership) => {
|
.map((membership) => {
|
||||||
const id = `${membership.sender}:${membership.deviceId}`;
|
const id = `${membership.sender}:${membership.deviceId}`;
|
||||||
const participant = participants.find((p) => p.identity === id);
|
const participant = participants.find((p) => p.identity === id);
|
||||||
return participant ? [{ participant, membership }] : [];
|
return { participant, membership };
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
[],
|
[],
|
||||||
|
|||||||
Reference in New Issue
Block a user