@ai-matrx/meet 0.11.32 → 0.11.34
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 +35 -0
- package/dist/core.cjs +137 -48
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +75 -6
- package/dist/core.d.ts +75 -6
- package/dist/core.js +137 -48
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +137 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +137 -48
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +481 -79
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +6 -0
- package/dist/react.d.ts +6 -0
- package/dist/react.js +481 -79
- package/dist/react.js.map +1 -1
- package/dist/skins/meet.cjs +217 -33
- package/dist/skins/meet.cjs.map +1 -1
- package/dist/skins/meet.js +217 -33
- package/dist/skins/meet.js.map +1 -1
- package/dist/styles.css +19 -0
- package/package.json +2 -2
package/dist/core.d.cts
CHANGED
|
@@ -35,7 +35,12 @@ declare class MeetError extends Error {
|
|
|
35
35
|
* renders `refused:<reason>` (or `ended`) from it — never from the HTTP status.
|
|
36
36
|
*/
|
|
37
37
|
readonly reason: string | null;
|
|
38
|
-
|
|
38
|
+
/**
|
|
39
|
+
* A refusal that lifts by itself says when: whole seconds from the moment the server answered
|
|
40
|
+
* (a denial's cooldown, `reknock_cooldown_seconds`). Null for every refusal that does not.
|
|
41
|
+
*/
|
|
42
|
+
readonly retryAfterSeconds: number | null;
|
|
43
|
+
constructor(code: MeetErrorCode, message: string, remedy: string, cause?: unknown, reason?: string | null, retryAfterSeconds?: number | null);
|
|
39
44
|
/** True when retrying after the host re-establishes a session is the fix. */
|
|
40
45
|
get isRetryable(): boolean;
|
|
41
46
|
/** True when the user, not the code, must act — the UI shows `remedy`. */
|
|
@@ -342,6 +347,13 @@ type PhaseEvent =
|
|
|
342
347
|
| {
|
|
343
348
|
readonly type: "connected";
|
|
344
349
|
}
|
|
350
|
+
/**
|
|
351
|
+
* S7: the server answered the join with a QUESTION — this person is already in the meeting on
|
|
352
|
+
* another tab or device — so `joining` goes back to `prejoin`, which offers the choice.
|
|
353
|
+
*/
|
|
354
|
+
| {
|
|
355
|
+
readonly type: "second_device";
|
|
356
|
+
}
|
|
345
357
|
/** The join itself failed: a gate reason (→ `refused:*` / `ended`) or none (→ `disconnected`). */
|
|
346
358
|
| {
|
|
347
359
|
readonly type: "join_failed";
|
|
@@ -375,9 +387,15 @@ type PhaseEvent =
|
|
|
375
387
|
readonly type: "call_outcome";
|
|
376
388
|
readonly outcome: CallOutcomePhase;
|
|
377
389
|
}
|
|
378
|
-
/**
|
|
390
|
+
/**
|
|
391
|
+
* Back to the start: a different meeting mounted or the call surface was dismissed (refused
|
|
392
|
+
* from a live phase — leave first). `teardown: true` is the engine's own dispose: it has
|
|
393
|
+
* already closed the connection, so nothing live remains to protect and the reset applies from
|
|
394
|
+
* any phase.
|
|
395
|
+
*/
|
|
379
396
|
| {
|
|
380
397
|
readonly type: "reset";
|
|
398
|
+
readonly teardown?: true;
|
|
381
399
|
};
|
|
382
400
|
type PhaseEventType = PhaseEvent["type"];
|
|
383
401
|
/** Phases in which this tab holds (or is getting) a live media connection. */
|
|
@@ -582,8 +600,8 @@ interface MeetGrants {
|
|
|
582
600
|
declare const NO_GRANTS: MeetGrants;
|
|
583
601
|
/**
|
|
584
602
|
* S4 — THIS PERSON'S WAIT, as the server's state read (`GET /v1/meet/state`) last said it
|
|
585
|
-
* (CORE-DESIGN §2.6). Set while
|
|
586
|
-
* broadcast. `admission` is the row's own word: `waiting_host` · `knocking` · `denied` ·
|
|
603
|
+
* (CORE-DESIGN §2.6). Set while the phase is a waiting one (`waiting:*`, `denied`,
|
|
604
|
+
* `knock_expired`); the waiting screens read it, never a broadcast. `admission` is the row's own word: `waiting_host` · `knocking` · `denied` ·
|
|
587
605
|
* `expired` · `withdrawn` · `ended` (`admitted` is never held here — it is a join).
|
|
588
606
|
*/
|
|
589
607
|
interface MeetWaiting {
|
|
@@ -593,6 +611,8 @@ interface MeetWaiting {
|
|
|
593
611
|
/** May a denied person ask again (`reknock_after_deny`)? */
|
|
594
612
|
readonly reknockAllowed: boolean;
|
|
595
613
|
readonly knockExpiresAt: string | null;
|
|
614
|
+
/** While a denial's cooldown runs: the epoch-ms moment the person may ask again; else null. */
|
|
615
|
+
readonly reknockAt?: number | null;
|
|
596
616
|
/** How often the core reads while waiting (`waiting_poll_seconds`). */
|
|
597
617
|
readonly pollSeconds: number;
|
|
598
618
|
/** The run's `live_version` at the last read. */
|
|
@@ -647,6 +667,14 @@ interface MeetSnapshot {
|
|
|
647
667
|
readonly waiting: MeetWaiting | null;
|
|
648
668
|
readonly meeting: MeetingRecord | null;
|
|
649
669
|
readonly localIdentity: ParticipantIdentity | null;
|
|
670
|
+
/**
|
|
671
|
+
* S7: this person is already in this meeting on another tab or device, and the pre-join offers
|
|
672
|
+
* the meeting's choice — `rule` is the `second_device` knob (`ask_switch_or_join` · Meet: Switch
|
|
673
|
+
* here / Join here too; `ask_transfer_or_add` · Teams: Transfer / Add). Null otherwise.
|
|
674
|
+
*/
|
|
675
|
+
readonly secondDevice: {
|
|
676
|
+
readonly rule: string;
|
|
677
|
+
} | null;
|
|
650
678
|
/** The server's word on what THIS joiner may do. See `MeetGrants`. */
|
|
651
679
|
readonly grants: MeetGrants;
|
|
652
680
|
readonly participants: readonly MeetParticipant[];
|
|
@@ -756,6 +784,11 @@ interface MeetSnapshot {
|
|
|
756
784
|
readonly remedy: string;
|
|
757
785
|
/** The join gate's reason code, when the server named one (CORE-DESIGN §2.5). */
|
|
758
786
|
readonly reason?: string | null;
|
|
787
|
+
/**
|
|
788
|
+
* When a refusal lifts by itself (a denial's cooldown): the epoch-ms moment the person may
|
|
789
|
+
* ask again. Absent for every refusal that does not lift (CORE-DESIGN §11 `wr-denied-reknock`).
|
|
790
|
+
*/
|
|
791
|
+
readonly retryAt?: number | null;
|
|
759
792
|
} | null;
|
|
760
793
|
/**
|
|
761
794
|
* Meet wave 5: polls, Q&A, the shared whiteboard and the breakout plan — what the
|
|
@@ -2163,7 +2196,7 @@ interface MeetingSession {
|
|
|
2163
2196
|
* §3.4 ER: what the server recorded for THIS connection's exit, and the run's phase. null =
|
|
2164
2197
|
* the read failed (offline / unreachable); undefined = no meeting or no pass to ask with.
|
|
2165
2198
|
*/
|
|
2166
|
-
readExit(connection: string): Promise<ExitServerWord | null | undefined>;
|
|
2199
|
+
readExit(connection: string, pass?: string | null): Promise<ExitServerWord | null | undefined>;
|
|
2167
2200
|
/** Stop waiting: the row becomes `withdrawn` (`POST /v1/meet/leave {intent: "withdraw"}`). */
|
|
2168
2201
|
withdraw(): Promise<void>;
|
|
2169
2202
|
/** Ask again after a denial or an expired knock (only offered when allowed). */
|
|
@@ -2347,6 +2380,17 @@ interface MediaSupervisor {
|
|
|
2347
2380
|
}
|
|
2348
2381
|
declare function createMediaSupervisor(options: MediaSupervisorOptions): MediaSupervisor;
|
|
2349
2382
|
|
|
2383
|
+
interface TabClaim {
|
|
2384
|
+
/** This page's claimed tab id (resolves once the claim settles). */
|
|
2385
|
+
readonly tabId: Promise<string>;
|
|
2386
|
+
/** Announce that this tab is in `room` as `person` (until `left`); answers presence questions. */
|
|
2387
|
+
inRoom(room: string, person: string): void;
|
|
2388
|
+
left(): void;
|
|
2389
|
+
/** Is `person` in `room` on ANOTHER tab of this browser? Answers within `TAB_ANSWER_MS`. */
|
|
2390
|
+
presentElsewhere(room: string, person: string): Promise<boolean>;
|
|
2391
|
+
dispose(): void;
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2350
2394
|
/**
|
|
2351
2395
|
* THE ROOM ENGINE — the object a host mounts once and never reasons about.
|
|
2352
2396
|
*
|
|
@@ -2387,12 +2431,20 @@ interface JoinRequest {
|
|
|
2387
2431
|
readonly breakoutRoomId?: string | null | undefined;
|
|
2388
2432
|
/** HR-360 wave 2 (MD-16): ask to join as a silent observer. The server decides. */
|
|
2389
2433
|
readonly observe?: boolean | undefined;
|
|
2434
|
+
/**
|
|
2435
|
+
* S7: the person's answer when they are already in this meeting on another tab or device
|
|
2436
|
+
* (`snapshot.secondDevice`): `switch_here` moves the call here, `join_too` adds this tab as a
|
|
2437
|
+
* companion (no microphone, speaker off).
|
|
2438
|
+
*/
|
|
2439
|
+
readonly secondDevice?: SecondDeviceAnswer | undefined;
|
|
2390
2440
|
}
|
|
2391
2441
|
interface RoomEngineOptions {
|
|
2392
2442
|
store: MeetStore;
|
|
2393
2443
|
tokens: TokenClient;
|
|
2394
2444
|
identity: MeetIdentity;
|
|
2395
2445
|
driverFactory: RoomDriverFactory;
|
|
2446
|
+
/** S7: this page's tab claim (`core/tab-claim.ts`); absent = one connection per person. */
|
|
2447
|
+
tabClaim?: TabClaim | undefined;
|
|
2396
2448
|
/** Canonical public metadata read; room packets alone never authorize teardown. */
|
|
2397
2449
|
resolveMeeting?: ((slug: string) => Promise<MeetingRecord>) | undefined;
|
|
2398
2450
|
onDiagnostic?: ((event: {
|
|
@@ -2417,7 +2469,7 @@ interface RoomEngineOptions {
|
|
|
2417
2469
|
* read what happened to THIS connection (`GET /v1/meet/state?connection=`). Resolves null when
|
|
2418
2470
|
* the read failed (offline / unreachable), undefined when this room has no state read (a call).
|
|
2419
2471
|
*/
|
|
2420
|
-
readExit?: ((connection: string) => Promise<ExitServerWord | null | undefined>) | undefined;
|
|
2472
|
+
readExit?: ((connection: string, pass?: string | null) => Promise<ExitServerWord | null | undefined>) | undefined;
|
|
2421
2473
|
/** Was the page frozen when the connection dropped (Page Lifecycle)? → `inactive`. */
|
|
2422
2474
|
wasFrozen?: (() => boolean) | undefined;
|
|
2423
2475
|
/**
|
|
@@ -2717,7 +2769,18 @@ interface RoomToken {
|
|
|
2717
2769
|
readonly token: string;
|
|
2718
2770
|
readonly serverUrl: string;
|
|
2719
2771
|
readonly roomName: RoomName;
|
|
2772
|
+
/** S7: the PERSON key (`user:<id>` · `guest:<device>`) — what every roster tile and row uses. */
|
|
2720
2773
|
readonly identity: ParticipantIdentity;
|
|
2774
|
+
/** S7: this tab's LiveKit identity, `<person>~<tab>` (the person key from an older server). */
|
|
2775
|
+
readonly connectionIdentity?: string | undefined;
|
|
2776
|
+
/** S7: `companion` for a "join here too" connection (no audio publish, speaker off). */
|
|
2777
|
+
readonly connectionKind?: "main" | "companion" | undefined;
|
|
2778
|
+
/**
|
|
2779
|
+
* S7: set when the person is ALREADY in the room on another tab or device and has not chosen
|
|
2780
|
+
* yet — the meeting's `second_device` rule (`ask_switch_or_join` · `ask_transfer_or_add`). No
|
|
2781
|
+
* LiveKit token was issued (`token` is empty); the pre-join offers the choice.
|
|
2782
|
+
*/
|
|
2783
|
+
readonly secondDeviceChoice?: string | null | undefined;
|
|
2721
2784
|
readonly displayName: string;
|
|
2722
2785
|
/** ISO. The package refreshes at 80% of the remaining life. */
|
|
2723
2786
|
readonly expiresAt: string;
|
|
@@ -2818,7 +2881,13 @@ interface TokenRequest {
|
|
|
2818
2881
|
readonly breakoutRoomId?: string | null | undefined;
|
|
2819
2882
|
/** HR-360 wave 2 (MD-16): ask to join as a silent observer. The server decides. */
|
|
2820
2883
|
readonly observe?: boolean | undefined;
|
|
2884
|
+
/** S7: this tab's claimed id (`core/tab-claim.ts`) — the LiveKit identity is `<person>~<tab>`. */
|
|
2885
|
+
readonly tabId?: string | undefined;
|
|
2886
|
+
/** S7: the person's answer when they are already in this meeting on another tab or device. */
|
|
2887
|
+
readonly secondDevice?: SecondDeviceAnswer | undefined;
|
|
2821
2888
|
}
|
|
2889
|
+
/** S7: what a person already in the meeting elsewhere chose (CORE-DESIGN §2.1). */
|
|
2890
|
+
type SecondDeviceAnswer = "switch_here" | "join_too";
|
|
2822
2891
|
interface TokenClient {
|
|
2823
2892
|
/** A currently-valid token, minting or refreshing only when it must. */
|
|
2824
2893
|
get(request: TokenRequest): Promise<RoomToken>;
|
package/dist/core.d.ts
CHANGED
|
@@ -35,7 +35,12 @@ declare class MeetError extends Error {
|
|
|
35
35
|
* renders `refused:<reason>` (or `ended`) from it — never from the HTTP status.
|
|
36
36
|
*/
|
|
37
37
|
readonly reason: string | null;
|
|
38
|
-
|
|
38
|
+
/**
|
|
39
|
+
* A refusal that lifts by itself says when: whole seconds from the moment the server answered
|
|
40
|
+
* (a denial's cooldown, `reknock_cooldown_seconds`). Null for every refusal that does not.
|
|
41
|
+
*/
|
|
42
|
+
readonly retryAfterSeconds: number | null;
|
|
43
|
+
constructor(code: MeetErrorCode, message: string, remedy: string, cause?: unknown, reason?: string | null, retryAfterSeconds?: number | null);
|
|
39
44
|
/** True when retrying after the host re-establishes a session is the fix. */
|
|
40
45
|
get isRetryable(): boolean;
|
|
41
46
|
/** True when the user, not the code, must act — the UI shows `remedy`. */
|
|
@@ -342,6 +347,13 @@ type PhaseEvent =
|
|
|
342
347
|
| {
|
|
343
348
|
readonly type: "connected";
|
|
344
349
|
}
|
|
350
|
+
/**
|
|
351
|
+
* S7: the server answered the join with a QUESTION — this person is already in the meeting on
|
|
352
|
+
* another tab or device — so `joining` goes back to `prejoin`, which offers the choice.
|
|
353
|
+
*/
|
|
354
|
+
| {
|
|
355
|
+
readonly type: "second_device";
|
|
356
|
+
}
|
|
345
357
|
/** The join itself failed: a gate reason (→ `refused:*` / `ended`) or none (→ `disconnected`). */
|
|
346
358
|
| {
|
|
347
359
|
readonly type: "join_failed";
|
|
@@ -375,9 +387,15 @@ type PhaseEvent =
|
|
|
375
387
|
readonly type: "call_outcome";
|
|
376
388
|
readonly outcome: CallOutcomePhase;
|
|
377
389
|
}
|
|
378
|
-
/**
|
|
390
|
+
/**
|
|
391
|
+
* Back to the start: a different meeting mounted or the call surface was dismissed (refused
|
|
392
|
+
* from a live phase — leave first). `teardown: true` is the engine's own dispose: it has
|
|
393
|
+
* already closed the connection, so nothing live remains to protect and the reset applies from
|
|
394
|
+
* any phase.
|
|
395
|
+
*/
|
|
379
396
|
| {
|
|
380
397
|
readonly type: "reset";
|
|
398
|
+
readonly teardown?: true;
|
|
381
399
|
};
|
|
382
400
|
type PhaseEventType = PhaseEvent["type"];
|
|
383
401
|
/** Phases in which this tab holds (or is getting) a live media connection. */
|
|
@@ -582,8 +600,8 @@ interface MeetGrants {
|
|
|
582
600
|
declare const NO_GRANTS: MeetGrants;
|
|
583
601
|
/**
|
|
584
602
|
* S4 — THIS PERSON'S WAIT, as the server's state read (`GET /v1/meet/state`) last said it
|
|
585
|
-
* (CORE-DESIGN §2.6). Set while
|
|
586
|
-
* broadcast. `admission` is the row's own word: `waiting_host` · `knocking` · `denied` ·
|
|
603
|
+
* (CORE-DESIGN §2.6). Set while the phase is a waiting one (`waiting:*`, `denied`,
|
|
604
|
+
* `knock_expired`); the waiting screens read it, never a broadcast. `admission` is the row's own word: `waiting_host` · `knocking` · `denied` ·
|
|
587
605
|
* `expired` · `withdrawn` · `ended` (`admitted` is never held here — it is a join).
|
|
588
606
|
*/
|
|
589
607
|
interface MeetWaiting {
|
|
@@ -593,6 +611,8 @@ interface MeetWaiting {
|
|
|
593
611
|
/** May a denied person ask again (`reknock_after_deny`)? */
|
|
594
612
|
readonly reknockAllowed: boolean;
|
|
595
613
|
readonly knockExpiresAt: string | null;
|
|
614
|
+
/** While a denial's cooldown runs: the epoch-ms moment the person may ask again; else null. */
|
|
615
|
+
readonly reknockAt?: number | null;
|
|
596
616
|
/** How often the core reads while waiting (`waiting_poll_seconds`). */
|
|
597
617
|
readonly pollSeconds: number;
|
|
598
618
|
/** The run's `live_version` at the last read. */
|
|
@@ -647,6 +667,14 @@ interface MeetSnapshot {
|
|
|
647
667
|
readonly waiting: MeetWaiting | null;
|
|
648
668
|
readonly meeting: MeetingRecord | null;
|
|
649
669
|
readonly localIdentity: ParticipantIdentity | null;
|
|
670
|
+
/**
|
|
671
|
+
* S7: this person is already in this meeting on another tab or device, and the pre-join offers
|
|
672
|
+
* the meeting's choice — `rule` is the `second_device` knob (`ask_switch_or_join` · Meet: Switch
|
|
673
|
+
* here / Join here too; `ask_transfer_or_add` · Teams: Transfer / Add). Null otherwise.
|
|
674
|
+
*/
|
|
675
|
+
readonly secondDevice: {
|
|
676
|
+
readonly rule: string;
|
|
677
|
+
} | null;
|
|
650
678
|
/** The server's word on what THIS joiner may do. See `MeetGrants`. */
|
|
651
679
|
readonly grants: MeetGrants;
|
|
652
680
|
readonly participants: readonly MeetParticipant[];
|
|
@@ -756,6 +784,11 @@ interface MeetSnapshot {
|
|
|
756
784
|
readonly remedy: string;
|
|
757
785
|
/** The join gate's reason code, when the server named one (CORE-DESIGN §2.5). */
|
|
758
786
|
readonly reason?: string | null;
|
|
787
|
+
/**
|
|
788
|
+
* When a refusal lifts by itself (a denial's cooldown): the epoch-ms moment the person may
|
|
789
|
+
* ask again. Absent for every refusal that does not lift (CORE-DESIGN §11 `wr-denied-reknock`).
|
|
790
|
+
*/
|
|
791
|
+
readonly retryAt?: number | null;
|
|
759
792
|
} | null;
|
|
760
793
|
/**
|
|
761
794
|
* Meet wave 5: polls, Q&A, the shared whiteboard and the breakout plan — what the
|
|
@@ -2163,7 +2196,7 @@ interface MeetingSession {
|
|
|
2163
2196
|
* §3.4 ER: what the server recorded for THIS connection's exit, and the run's phase. null =
|
|
2164
2197
|
* the read failed (offline / unreachable); undefined = no meeting or no pass to ask with.
|
|
2165
2198
|
*/
|
|
2166
|
-
readExit(connection: string): Promise<ExitServerWord | null | undefined>;
|
|
2199
|
+
readExit(connection: string, pass?: string | null): Promise<ExitServerWord | null | undefined>;
|
|
2167
2200
|
/** Stop waiting: the row becomes `withdrawn` (`POST /v1/meet/leave {intent: "withdraw"}`). */
|
|
2168
2201
|
withdraw(): Promise<void>;
|
|
2169
2202
|
/** Ask again after a denial or an expired knock (only offered when allowed). */
|
|
@@ -2347,6 +2380,17 @@ interface MediaSupervisor {
|
|
|
2347
2380
|
}
|
|
2348
2381
|
declare function createMediaSupervisor(options: MediaSupervisorOptions): MediaSupervisor;
|
|
2349
2382
|
|
|
2383
|
+
interface TabClaim {
|
|
2384
|
+
/** This page's claimed tab id (resolves once the claim settles). */
|
|
2385
|
+
readonly tabId: Promise<string>;
|
|
2386
|
+
/** Announce that this tab is in `room` as `person` (until `left`); answers presence questions. */
|
|
2387
|
+
inRoom(room: string, person: string): void;
|
|
2388
|
+
left(): void;
|
|
2389
|
+
/** Is `person` in `room` on ANOTHER tab of this browser? Answers within `TAB_ANSWER_MS`. */
|
|
2390
|
+
presentElsewhere(room: string, person: string): Promise<boolean>;
|
|
2391
|
+
dispose(): void;
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2350
2394
|
/**
|
|
2351
2395
|
* THE ROOM ENGINE — the object a host mounts once and never reasons about.
|
|
2352
2396
|
*
|
|
@@ -2387,12 +2431,20 @@ interface JoinRequest {
|
|
|
2387
2431
|
readonly breakoutRoomId?: string | null | undefined;
|
|
2388
2432
|
/** HR-360 wave 2 (MD-16): ask to join as a silent observer. The server decides. */
|
|
2389
2433
|
readonly observe?: boolean | undefined;
|
|
2434
|
+
/**
|
|
2435
|
+
* S7: the person's answer when they are already in this meeting on another tab or device
|
|
2436
|
+
* (`snapshot.secondDevice`): `switch_here` moves the call here, `join_too` adds this tab as a
|
|
2437
|
+
* companion (no microphone, speaker off).
|
|
2438
|
+
*/
|
|
2439
|
+
readonly secondDevice?: SecondDeviceAnswer | undefined;
|
|
2390
2440
|
}
|
|
2391
2441
|
interface RoomEngineOptions {
|
|
2392
2442
|
store: MeetStore;
|
|
2393
2443
|
tokens: TokenClient;
|
|
2394
2444
|
identity: MeetIdentity;
|
|
2395
2445
|
driverFactory: RoomDriverFactory;
|
|
2446
|
+
/** S7: this page's tab claim (`core/tab-claim.ts`); absent = one connection per person. */
|
|
2447
|
+
tabClaim?: TabClaim | undefined;
|
|
2396
2448
|
/** Canonical public metadata read; room packets alone never authorize teardown. */
|
|
2397
2449
|
resolveMeeting?: ((slug: string) => Promise<MeetingRecord>) | undefined;
|
|
2398
2450
|
onDiagnostic?: ((event: {
|
|
@@ -2417,7 +2469,7 @@ interface RoomEngineOptions {
|
|
|
2417
2469
|
* read what happened to THIS connection (`GET /v1/meet/state?connection=`). Resolves null when
|
|
2418
2470
|
* the read failed (offline / unreachable), undefined when this room has no state read (a call).
|
|
2419
2471
|
*/
|
|
2420
|
-
readExit?: ((connection: string) => Promise<ExitServerWord | null | undefined>) | undefined;
|
|
2472
|
+
readExit?: ((connection: string, pass?: string | null) => Promise<ExitServerWord | null | undefined>) | undefined;
|
|
2421
2473
|
/** Was the page frozen when the connection dropped (Page Lifecycle)? → `inactive`. */
|
|
2422
2474
|
wasFrozen?: (() => boolean) | undefined;
|
|
2423
2475
|
/**
|
|
@@ -2717,7 +2769,18 @@ interface RoomToken {
|
|
|
2717
2769
|
readonly token: string;
|
|
2718
2770
|
readonly serverUrl: string;
|
|
2719
2771
|
readonly roomName: RoomName;
|
|
2772
|
+
/** S7: the PERSON key (`user:<id>` · `guest:<device>`) — what every roster tile and row uses. */
|
|
2720
2773
|
readonly identity: ParticipantIdentity;
|
|
2774
|
+
/** S7: this tab's LiveKit identity, `<person>~<tab>` (the person key from an older server). */
|
|
2775
|
+
readonly connectionIdentity?: string | undefined;
|
|
2776
|
+
/** S7: `companion` for a "join here too" connection (no audio publish, speaker off). */
|
|
2777
|
+
readonly connectionKind?: "main" | "companion" | undefined;
|
|
2778
|
+
/**
|
|
2779
|
+
* S7: set when the person is ALREADY in the room on another tab or device and has not chosen
|
|
2780
|
+
* yet — the meeting's `second_device` rule (`ask_switch_or_join` · `ask_transfer_or_add`). No
|
|
2781
|
+
* LiveKit token was issued (`token` is empty); the pre-join offers the choice.
|
|
2782
|
+
*/
|
|
2783
|
+
readonly secondDeviceChoice?: string | null | undefined;
|
|
2721
2784
|
readonly displayName: string;
|
|
2722
2785
|
/** ISO. The package refreshes at 80% of the remaining life. */
|
|
2723
2786
|
readonly expiresAt: string;
|
|
@@ -2818,7 +2881,13 @@ interface TokenRequest {
|
|
|
2818
2881
|
readonly breakoutRoomId?: string | null | undefined;
|
|
2819
2882
|
/** HR-360 wave 2 (MD-16): ask to join as a silent observer. The server decides. */
|
|
2820
2883
|
readonly observe?: boolean | undefined;
|
|
2884
|
+
/** S7: this tab's claimed id (`core/tab-claim.ts`) — the LiveKit identity is `<person>~<tab>`. */
|
|
2885
|
+
readonly tabId?: string | undefined;
|
|
2886
|
+
/** S7: the person's answer when they are already in this meeting on another tab or device. */
|
|
2887
|
+
readonly secondDevice?: SecondDeviceAnswer | undefined;
|
|
2821
2888
|
}
|
|
2889
|
+
/** S7: what a person already in the meeting elsewhere chose (CORE-DESIGN §2.1). */
|
|
2890
|
+
type SecondDeviceAnswer = "switch_here" | "join_too";
|
|
2822
2891
|
interface TokenClient {
|
|
2823
2892
|
/** A currently-valid token, minting or refreshing only when it must. */
|
|
2824
2893
|
get(request: TokenRequest): Promise<RoomToken>;
|