@ai-matrx/meet 0.11.44 → 0.11.46
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 +12 -0
- package/dist/{collab-BNJNgXFB.d.cts → collab-D1TX5uf9.d.cts} +7 -0
- package/dist/{collab-BNJNgXFB.d.ts → collab-D1TX5uf9.d.ts} +7 -0
- package/dist/{components-BDtGzHf4.d.ts → components-CNwBgmYU.d.ts} +1 -1
- package/dist/{components-BxK993iW.d.cts → components-CkyDos0f.d.cts} +1 -1
- package/dist/core.cjs +70 -10
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +33 -9
- package/dist/core.d.ts +33 -9
- package/dist/core.js +70 -10
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +70 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +70 -10
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +197 -30
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +3 -3
- package/dist/react.d.ts +3 -3
- package/dist/react.js +197 -30
- package/dist/react.js.map +1 -1
- package/dist/skins/meet.cjs +131 -28
- package/dist/skins/meet.cjs.map +1 -1
- package/dist/skins/meet.d.cts +2 -2
- package/dist/skins/meet.d.ts +2 -2
- package/dist/skins/meet.js +131 -28
- package/dist/skins/meet.js.map +1 -1
- package/dist/styles.css +16 -0
- package/package.json +5 -5
package/dist/core.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as ParticipantIdentity, e as ParticipantRole, k as AdmissionState, a1 as NoteTakerState, a as MeetParticipant, M as MeetingRecord, R as RoomName, d as CallInvite, a6 as ParticipantStanding, a3 as ObserversVisibleTo, S as StageLayout, L as LobbyEntry, aa as RecordingState, U as UserId, aF as RecordingSource, ae as TranscriptSegment, g as MeetingNote, W as WrapUpAnnouncement, j as CollabSnapshot, p as ConnectionQuality, h as MeetingId, b as MeetApi, f as CallMode, O as OrganizationId, m as CallId, n as CallState, Z as MeetingKind, a8 as RecordingPolicy, V as MeetingAttendee, a9 as RecordingRecord, a0 as MeetingSettings, X as MeetingChanges, a4 as OccurrenceOverride, $ as MeetingOccurrence, af as UpcomingOccurrence, Y as MeetingInvitee, I as InviteeInput, q as InviteeRole, ab as RsvpAnswer, ac as RsvpInvitation, c as MeetIdentity, C as CollabPanel } from './collab-
|
|
2
|
-
export { A as AccessTokenSource, l as CAPTION_LANGUAGES, o as CallablePerson, E as EMPTY_COLLAB, F as FILE_SESSION_PATH, J as JsonObject, r as JsonValue, s as MeetApiOptions, t as MeetApiRequest, u as MeetAppFocus, v as MeetBreakoutBroadcast, w as MeetBreakoutPlan, x as MeetBreakoutRoom, y as MeetCollabSettings, z as MeetFileMedia, B as MeetPoll, D as MeetPollOption, G as MeetPollState, H as MeetQuestion, K as MeetQuestionState, N as MeetStroke, Q as MeetingActivities, i as MeetingAppPanel, _ as MeetingNoteKind, a2 as ORGANIZATION_HEADER, a5 as OccurrenceState, a7 as ROLE_RANK, ad as RsvpState, T as TranscriptSource, ag as appPanelOf, ah as applyCollabPacket, ai as asCallId, aj as asMeetingId, ak as asOrganizationId, al as asParticipantIdentity, am as asRoomName, an as asUserId, ao as assignedRoom, ap as autoAssign, aq as breakoutClosingMs, ar as breakoutRemainingMs, as as captureHeldOf, at as collabFromState, au as createMeetApi, av as defaultCaptionLanguage, aw as fileDownloadPath, ax as focusFromRow, ay as isGuest, az as isHostRole, aA as isLinkFollower, aB as isObserverRole, aC as loadMeetingActivities, aD as scheduleSettingsPatch, aE as withItem } from './collab-
|
|
1
|
+
import { P as ParticipantIdentity, e as ParticipantRole, k as AdmissionState, a1 as NoteTakerState, a as MeetParticipant, M as MeetingRecord, R as RoomName, d as CallInvite, a6 as ParticipantStanding, a3 as ObserversVisibleTo, S as StageLayout, L as LobbyEntry, aa as RecordingState, U as UserId, aF as RecordingSource, ae as TranscriptSegment, g as MeetingNote, W as WrapUpAnnouncement, j as CollabSnapshot, p as ConnectionQuality, h as MeetingId, b as MeetApi, f as CallMode, O as OrganizationId, m as CallId, n as CallState, Z as MeetingKind, a8 as RecordingPolicy, V as MeetingAttendee, a9 as RecordingRecord, a0 as MeetingSettings, X as MeetingChanges, a4 as OccurrenceOverride, $ as MeetingOccurrence, af as UpcomingOccurrence, Y as MeetingInvitee, I as InviteeInput, q as InviteeRole, ab as RsvpAnswer, ac as RsvpInvitation, c as MeetIdentity, C as CollabPanel } from './collab-D1TX5uf9.cjs';
|
|
2
|
+
export { A as AccessTokenSource, l as CAPTION_LANGUAGES, o as CallablePerson, E as EMPTY_COLLAB, F as FILE_SESSION_PATH, J as JsonObject, r as JsonValue, s as MeetApiOptions, t as MeetApiRequest, u as MeetAppFocus, v as MeetBreakoutBroadcast, w as MeetBreakoutPlan, x as MeetBreakoutRoom, y as MeetCollabSettings, z as MeetFileMedia, B as MeetPoll, D as MeetPollOption, G as MeetPollState, H as MeetQuestion, K as MeetQuestionState, N as MeetStroke, Q as MeetingActivities, i as MeetingAppPanel, _ as MeetingNoteKind, a2 as ORGANIZATION_HEADER, a5 as OccurrenceState, a7 as ROLE_RANK, ad as RsvpState, T as TranscriptSource, ag as appPanelOf, ah as applyCollabPacket, ai as asCallId, aj as asMeetingId, ak as asOrganizationId, al as asParticipantIdentity, am as asRoomName, an as asUserId, ao as assignedRoom, ap as autoAssign, aq as breakoutClosingMs, ar as breakoutRemainingMs, as as captureHeldOf, at as collabFromState, au as createMeetApi, av as defaultCaptionLanguage, aw as fileDownloadPath, ax as focusFromRow, ay as isGuest, az as isHostRole, aA as isLinkFollower, aB as isObserverRole, aC as loadMeetingActivities, aD as scheduleSettingsPatch, aE as withItem } from './collab-D1TX5uf9.cjs';
|
|
3
3
|
import { RealtimeManager } from '@ai-matrx/realtime';
|
|
4
4
|
import { MessagingSupabaseClient, ActionHandler } from '@ai-matrx/messaging';
|
|
5
5
|
import { RoomOptions, ConnectionQuality as ConnectionQuality$1, Participant } from 'livekit-client';
|
|
@@ -859,6 +859,10 @@ interface MeetSnapshot {
|
|
|
859
859
|
* Rendered verbatim; never replaced by a spinner or a house sentence.
|
|
860
860
|
*/
|
|
861
861
|
readonly noteTakerRefusal: NoteTakerRefusal | null;
|
|
862
|
+
/** `captions-toggle`: THIS viewer wants captions. Local to the viewer; never sent to the room. */
|
|
863
|
+
readonly captionsOn: boolean;
|
|
864
|
+
/** Why asking for captions failed, in the server's words (`captions-unavailable`). */
|
|
865
|
+
readonly captionsRefusal: NoteTakerRefusal | null;
|
|
862
866
|
/**
|
|
863
867
|
* What the LOCAL participant is actually publishing, and why not when it is
|
|
864
868
|
* not. Attendance never depends on it (see `attendance.ts`): a refused
|
|
@@ -870,10 +874,6 @@ interface MeetSnapshot {
|
|
|
870
874
|
* last device change and an offered new device. Written only by `media-supervisor.ts`.
|
|
871
875
|
*/
|
|
872
876
|
readonly mediaRegion: MediaRegionState;
|
|
873
|
-
/** `captions-toggle`: THIS viewer wants captions. Local to the viewer; never sent to the room. */
|
|
874
|
-
readonly captionsOn: boolean;
|
|
875
|
-
/** Why asking for captions failed, in the server's words (`captions-unavailable`). */
|
|
876
|
-
readonly captionsRefusal: NoteTakerRefusal | null;
|
|
877
877
|
/** The last failure, with its remedy. Never null-and-hoping. */
|
|
878
878
|
readonly failure: {
|
|
879
879
|
readonly message: string;
|
|
@@ -1206,6 +1206,10 @@ declare const RPCS: {
|
|
|
1206
1206
|
readonly admitAll: "meet_admit_all";
|
|
1207
1207
|
readonly setLock: "meet_set_lock";
|
|
1208
1208
|
readonly recordConsent: "meet_record_consent";
|
|
1209
|
+
/** One meeting rule as the gate obeys it (the knob ladder, this meeting's rung included). */
|
|
1210
|
+
readonly meetingRule: "meet_policy";
|
|
1211
|
+
/** A host sets one rule for THIS meeting (the `meet_meeting` rung); refusals come back as `{ok:false}`. */
|
|
1212
|
+
readonly setMeetingRule: "meet_policy_set";
|
|
1209
1213
|
/** Schedule with every setting at create; unset settings come from the knobs. */
|
|
1210
1214
|
readonly scheduleMeeting: "meet_schedule_meeting";
|
|
1211
1215
|
/** Edit / reschedule — a JSON patch with a version compare-and-swap. */
|
|
@@ -1297,6 +1301,10 @@ interface MeetRepository {
|
|
|
1297
1301
|
/** S4: admit everyone still waiting (not expired); returns the admitted rows. */
|
|
1298
1302
|
admitAll(meetingId: MeetingId, byUserId: UserId): Promise<readonly MeetingAttendee[]>;
|
|
1299
1303
|
setLock(meetingId: MeetingId, locked: boolean, byUserId: UserId): Promise<MeetingRecord>;
|
|
1304
|
+
/** `wr-policy-who-waits`: read one rule of this meeting (`lobby_bypass`, `access_type`…). */
|
|
1305
|
+
meetingRule(meetingId: MeetingId, key: string): Promise<unknown>;
|
|
1306
|
+
/** A host sets one rule for this meeting; a refusal throws with the server's sentence. */
|
|
1307
|
+
setMeetingRule(meetingId: MeetingId, key: string, value: string | number | boolean): Promise<unknown>;
|
|
1300
1308
|
projectSegment(row: Row): TranscriptSegment;
|
|
1301
1309
|
projectNote(row: Row): MeetingNote;
|
|
1302
1310
|
/** One `meet_recordings` row, however it arrived (row or room packet). */
|
|
@@ -2290,6 +2298,8 @@ interface MeetingSession {
|
|
|
2290
2298
|
stopWaiting(): void;
|
|
2291
2299
|
/** One state read now (idempotent while one is in flight). */
|
|
2292
2300
|
readState(): Promise<void>;
|
|
2301
|
+
/** One read of the meeting's rules now (chat mode, attendee lock, time limit); resolves once they are on the store. */
|
|
2302
|
+
readLivePolicy(): Promise<void>;
|
|
2293
2303
|
/**
|
|
2294
2304
|
* §3.4 ER: what the server recorded for THIS connection's exit, and the run's phase. null =
|
|
2295
2305
|
* the read failed (offline / unreachable); undefined = no meeting or no pass to ask with.
|
|
@@ -2308,6 +2318,10 @@ interface MeetingSession {
|
|
|
2308
2318
|
readonly assignTo: string;
|
|
2309
2319
|
}): Promise<void>;
|
|
2310
2320
|
setLock(locked: boolean): Promise<MeetingRecord>;
|
|
2321
|
+
/** `wr-policy-who-waits`: one rule of the meeting on screen (null when unreadable). */
|
|
2322
|
+
meetingRule(key: string): Promise<unknown>;
|
|
2323
|
+
/** A host changes one rule for this meeting; waiting people are told to read again. */
|
|
2324
|
+
setMeetingRule(key: string, value: string | number | boolean): Promise<unknown>;
|
|
2311
2325
|
/** End it for everyone, through the server (MRI-A6). */
|
|
2312
2326
|
endForEveryone(): Promise<EndMeetingResult>;
|
|
2313
2327
|
dispose(): void;
|
|
@@ -2498,10 +2512,18 @@ interface TabClaim {
|
|
|
2498
2512
|
/** This page's claimed tab id (resolves once the claim settles). */
|
|
2499
2513
|
readonly tabId: Promise<string>;
|
|
2500
2514
|
/** Announce that this tab is in `room` as `person` (until `left`); answers presence questions. */
|
|
2501
|
-
inRoom(room: string, person: string): void;
|
|
2515
|
+
inRoom(room: string, person: string, rule?: string | null): void;
|
|
2502
2516
|
left(): void;
|
|
2503
2517
|
/** Is `person` in `room` on ANOTHER tab of this browser? Answers within `TAB_ANSWER_MS`. */
|
|
2504
2518
|
presentElsewhere(room: string, person: string): Promise<boolean>;
|
|
2519
|
+
/**
|
|
2520
|
+
* The same question, with the meeting's `second_device` rule the live tab holds — so the second
|
|
2521
|
+
* tab offers the PROFILE's choice (Meet: Switch here / Join here too; Teams: Transfer here / Add
|
|
2522
|
+
* this device) before anybody presses Join. Null when no other tab has the person live.
|
|
2523
|
+
*/
|
|
2524
|
+
presenceElsewhere?(room: string, person: string): Promise<{
|
|
2525
|
+
readonly rule: string | null;
|
|
2526
|
+
} | null>;
|
|
2505
2527
|
dispose(): void;
|
|
2506
2528
|
}
|
|
2507
2529
|
|
|
@@ -2907,6 +2929,8 @@ interface RoomToken {
|
|
|
2907
2929
|
* LiveKit token was issued (`token` is empty); the pre-join offers the choice.
|
|
2908
2930
|
*/
|
|
2909
2931
|
readonly secondDeviceChoice?: string | null | undefined;
|
|
2932
|
+
/** S7: the meeting's `second_device` rule, always — told to a second tab of this browser. */
|
|
2933
|
+
readonly secondDeviceRule?: string | null | undefined;
|
|
2910
2934
|
readonly displayName: string;
|
|
2911
2935
|
/** ISO. The package refreshes at 80% of the remaining life. */
|
|
2912
2936
|
readonly expiresAt: string;
|
|
@@ -3056,10 +3080,10 @@ declare const MEET_ROUTES: {
|
|
|
3056
3080
|
readonly recordingStop: "/api/v1/meet/recording/stop";
|
|
3057
3081
|
readonly noteTakerStart: "/api/v1/meet/agent/start";
|
|
3058
3082
|
readonly noteTakerStop: "/api/v1/meet/agent/stop";
|
|
3059
|
-
/** In-meeting Q&A. Streams NDJSON; body is `{meeting_id, question}` only. */
|
|
3060
|
-
readonly intelligenceAsk: "/api/v1/meet/intelligence/ask";
|
|
3061
3083
|
/** Anyone in the meeting (guests with the room pass included) asks for captions for themselves. */
|
|
3062
3084
|
readonly noteTakerCaptions: "/api/v1/meet/agent/captions";
|
|
3085
|
+
/** In-meeting Q&A. Streams NDJSON; body is `{meeting_id, question}` only. */
|
|
3086
|
+
readonly intelligenceAsk: "/api/v1/meet/intelligence/ask";
|
|
3063
3087
|
/** A host ends the meeting for everyone. Served by MRI-A6. */
|
|
3064
3088
|
readonly meetingEnd: "/api/v1/meet/end";
|
|
3065
3089
|
/**
|
package/dist/core.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as ParticipantIdentity, e as ParticipantRole, k as AdmissionState, a1 as NoteTakerState, a as MeetParticipant, M as MeetingRecord, R as RoomName, d as CallInvite, a6 as ParticipantStanding, a3 as ObserversVisibleTo, S as StageLayout, L as LobbyEntry, aa as RecordingState, U as UserId, aF as RecordingSource, ae as TranscriptSegment, g as MeetingNote, W as WrapUpAnnouncement, j as CollabSnapshot, p as ConnectionQuality, h as MeetingId, b as MeetApi, f as CallMode, O as OrganizationId, m as CallId, n as CallState, Z as MeetingKind, a8 as RecordingPolicy, V as MeetingAttendee, a9 as RecordingRecord, a0 as MeetingSettings, X as MeetingChanges, a4 as OccurrenceOverride, $ as MeetingOccurrence, af as UpcomingOccurrence, Y as MeetingInvitee, I as InviteeInput, q as InviteeRole, ab as RsvpAnswer, ac as RsvpInvitation, c as MeetIdentity, C as CollabPanel } from './collab-
|
|
2
|
-
export { A as AccessTokenSource, l as CAPTION_LANGUAGES, o as CallablePerson, E as EMPTY_COLLAB, F as FILE_SESSION_PATH, J as JsonObject, r as JsonValue, s as MeetApiOptions, t as MeetApiRequest, u as MeetAppFocus, v as MeetBreakoutBroadcast, w as MeetBreakoutPlan, x as MeetBreakoutRoom, y as MeetCollabSettings, z as MeetFileMedia, B as MeetPoll, D as MeetPollOption, G as MeetPollState, H as MeetQuestion, K as MeetQuestionState, N as MeetStroke, Q as MeetingActivities, i as MeetingAppPanel, _ as MeetingNoteKind, a2 as ORGANIZATION_HEADER, a5 as OccurrenceState, a7 as ROLE_RANK, ad as RsvpState, T as TranscriptSource, ag as appPanelOf, ah as applyCollabPacket, ai as asCallId, aj as asMeetingId, ak as asOrganizationId, al as asParticipantIdentity, am as asRoomName, an as asUserId, ao as assignedRoom, ap as autoAssign, aq as breakoutClosingMs, ar as breakoutRemainingMs, as as captureHeldOf, at as collabFromState, au as createMeetApi, av as defaultCaptionLanguage, aw as fileDownloadPath, ax as focusFromRow, ay as isGuest, az as isHostRole, aA as isLinkFollower, aB as isObserverRole, aC as loadMeetingActivities, aD as scheduleSettingsPatch, aE as withItem } from './collab-
|
|
1
|
+
import { P as ParticipantIdentity, e as ParticipantRole, k as AdmissionState, a1 as NoteTakerState, a as MeetParticipant, M as MeetingRecord, R as RoomName, d as CallInvite, a6 as ParticipantStanding, a3 as ObserversVisibleTo, S as StageLayout, L as LobbyEntry, aa as RecordingState, U as UserId, aF as RecordingSource, ae as TranscriptSegment, g as MeetingNote, W as WrapUpAnnouncement, j as CollabSnapshot, p as ConnectionQuality, h as MeetingId, b as MeetApi, f as CallMode, O as OrganizationId, m as CallId, n as CallState, Z as MeetingKind, a8 as RecordingPolicy, V as MeetingAttendee, a9 as RecordingRecord, a0 as MeetingSettings, X as MeetingChanges, a4 as OccurrenceOverride, $ as MeetingOccurrence, af as UpcomingOccurrence, Y as MeetingInvitee, I as InviteeInput, q as InviteeRole, ab as RsvpAnswer, ac as RsvpInvitation, c as MeetIdentity, C as CollabPanel } from './collab-D1TX5uf9.js';
|
|
2
|
+
export { A as AccessTokenSource, l as CAPTION_LANGUAGES, o as CallablePerson, E as EMPTY_COLLAB, F as FILE_SESSION_PATH, J as JsonObject, r as JsonValue, s as MeetApiOptions, t as MeetApiRequest, u as MeetAppFocus, v as MeetBreakoutBroadcast, w as MeetBreakoutPlan, x as MeetBreakoutRoom, y as MeetCollabSettings, z as MeetFileMedia, B as MeetPoll, D as MeetPollOption, G as MeetPollState, H as MeetQuestion, K as MeetQuestionState, N as MeetStroke, Q as MeetingActivities, i as MeetingAppPanel, _ as MeetingNoteKind, a2 as ORGANIZATION_HEADER, a5 as OccurrenceState, a7 as ROLE_RANK, ad as RsvpState, T as TranscriptSource, ag as appPanelOf, ah as applyCollabPacket, ai as asCallId, aj as asMeetingId, ak as asOrganizationId, al as asParticipantIdentity, am as asRoomName, an as asUserId, ao as assignedRoom, ap as autoAssign, aq as breakoutClosingMs, ar as breakoutRemainingMs, as as captureHeldOf, at as collabFromState, au as createMeetApi, av as defaultCaptionLanguage, aw as fileDownloadPath, ax as focusFromRow, ay as isGuest, az as isHostRole, aA as isLinkFollower, aB as isObserverRole, aC as loadMeetingActivities, aD as scheduleSettingsPatch, aE as withItem } from './collab-D1TX5uf9.js';
|
|
3
3
|
import { RealtimeManager } from '@ai-matrx/realtime';
|
|
4
4
|
import { MessagingSupabaseClient, ActionHandler } from '@ai-matrx/messaging';
|
|
5
5
|
import { RoomOptions, ConnectionQuality as ConnectionQuality$1, Participant } from 'livekit-client';
|
|
@@ -859,6 +859,10 @@ interface MeetSnapshot {
|
|
|
859
859
|
* Rendered verbatim; never replaced by a spinner or a house sentence.
|
|
860
860
|
*/
|
|
861
861
|
readonly noteTakerRefusal: NoteTakerRefusal | null;
|
|
862
|
+
/** `captions-toggle`: THIS viewer wants captions. Local to the viewer; never sent to the room. */
|
|
863
|
+
readonly captionsOn: boolean;
|
|
864
|
+
/** Why asking for captions failed, in the server's words (`captions-unavailable`). */
|
|
865
|
+
readonly captionsRefusal: NoteTakerRefusal | null;
|
|
862
866
|
/**
|
|
863
867
|
* What the LOCAL participant is actually publishing, and why not when it is
|
|
864
868
|
* not. Attendance never depends on it (see `attendance.ts`): a refused
|
|
@@ -870,10 +874,6 @@ interface MeetSnapshot {
|
|
|
870
874
|
* last device change and an offered new device. Written only by `media-supervisor.ts`.
|
|
871
875
|
*/
|
|
872
876
|
readonly mediaRegion: MediaRegionState;
|
|
873
|
-
/** `captions-toggle`: THIS viewer wants captions. Local to the viewer; never sent to the room. */
|
|
874
|
-
readonly captionsOn: boolean;
|
|
875
|
-
/** Why asking for captions failed, in the server's words (`captions-unavailable`). */
|
|
876
|
-
readonly captionsRefusal: NoteTakerRefusal | null;
|
|
877
877
|
/** The last failure, with its remedy. Never null-and-hoping. */
|
|
878
878
|
readonly failure: {
|
|
879
879
|
readonly message: string;
|
|
@@ -1206,6 +1206,10 @@ declare const RPCS: {
|
|
|
1206
1206
|
readonly admitAll: "meet_admit_all";
|
|
1207
1207
|
readonly setLock: "meet_set_lock";
|
|
1208
1208
|
readonly recordConsent: "meet_record_consent";
|
|
1209
|
+
/** One meeting rule as the gate obeys it (the knob ladder, this meeting's rung included). */
|
|
1210
|
+
readonly meetingRule: "meet_policy";
|
|
1211
|
+
/** A host sets one rule for THIS meeting (the `meet_meeting` rung); refusals come back as `{ok:false}`. */
|
|
1212
|
+
readonly setMeetingRule: "meet_policy_set";
|
|
1209
1213
|
/** Schedule with every setting at create; unset settings come from the knobs. */
|
|
1210
1214
|
readonly scheduleMeeting: "meet_schedule_meeting";
|
|
1211
1215
|
/** Edit / reschedule — a JSON patch with a version compare-and-swap. */
|
|
@@ -1297,6 +1301,10 @@ interface MeetRepository {
|
|
|
1297
1301
|
/** S4: admit everyone still waiting (not expired); returns the admitted rows. */
|
|
1298
1302
|
admitAll(meetingId: MeetingId, byUserId: UserId): Promise<readonly MeetingAttendee[]>;
|
|
1299
1303
|
setLock(meetingId: MeetingId, locked: boolean, byUserId: UserId): Promise<MeetingRecord>;
|
|
1304
|
+
/** `wr-policy-who-waits`: read one rule of this meeting (`lobby_bypass`, `access_type`…). */
|
|
1305
|
+
meetingRule(meetingId: MeetingId, key: string): Promise<unknown>;
|
|
1306
|
+
/** A host sets one rule for this meeting; a refusal throws with the server's sentence. */
|
|
1307
|
+
setMeetingRule(meetingId: MeetingId, key: string, value: string | number | boolean): Promise<unknown>;
|
|
1300
1308
|
projectSegment(row: Row): TranscriptSegment;
|
|
1301
1309
|
projectNote(row: Row): MeetingNote;
|
|
1302
1310
|
/** One `meet_recordings` row, however it arrived (row or room packet). */
|
|
@@ -2290,6 +2298,8 @@ interface MeetingSession {
|
|
|
2290
2298
|
stopWaiting(): void;
|
|
2291
2299
|
/** One state read now (idempotent while one is in flight). */
|
|
2292
2300
|
readState(): Promise<void>;
|
|
2301
|
+
/** One read of the meeting's rules now (chat mode, attendee lock, time limit); resolves once they are on the store. */
|
|
2302
|
+
readLivePolicy(): Promise<void>;
|
|
2293
2303
|
/**
|
|
2294
2304
|
* §3.4 ER: what the server recorded for THIS connection's exit, and the run's phase. null =
|
|
2295
2305
|
* the read failed (offline / unreachable); undefined = no meeting or no pass to ask with.
|
|
@@ -2308,6 +2318,10 @@ interface MeetingSession {
|
|
|
2308
2318
|
readonly assignTo: string;
|
|
2309
2319
|
}): Promise<void>;
|
|
2310
2320
|
setLock(locked: boolean): Promise<MeetingRecord>;
|
|
2321
|
+
/** `wr-policy-who-waits`: one rule of the meeting on screen (null when unreadable). */
|
|
2322
|
+
meetingRule(key: string): Promise<unknown>;
|
|
2323
|
+
/** A host changes one rule for this meeting; waiting people are told to read again. */
|
|
2324
|
+
setMeetingRule(key: string, value: string | number | boolean): Promise<unknown>;
|
|
2311
2325
|
/** End it for everyone, through the server (MRI-A6). */
|
|
2312
2326
|
endForEveryone(): Promise<EndMeetingResult>;
|
|
2313
2327
|
dispose(): void;
|
|
@@ -2498,10 +2512,18 @@ interface TabClaim {
|
|
|
2498
2512
|
/** This page's claimed tab id (resolves once the claim settles). */
|
|
2499
2513
|
readonly tabId: Promise<string>;
|
|
2500
2514
|
/** Announce that this tab is in `room` as `person` (until `left`); answers presence questions. */
|
|
2501
|
-
inRoom(room: string, person: string): void;
|
|
2515
|
+
inRoom(room: string, person: string, rule?: string | null): void;
|
|
2502
2516
|
left(): void;
|
|
2503
2517
|
/** Is `person` in `room` on ANOTHER tab of this browser? Answers within `TAB_ANSWER_MS`. */
|
|
2504
2518
|
presentElsewhere(room: string, person: string): Promise<boolean>;
|
|
2519
|
+
/**
|
|
2520
|
+
* The same question, with the meeting's `second_device` rule the live tab holds — so the second
|
|
2521
|
+
* tab offers the PROFILE's choice (Meet: Switch here / Join here too; Teams: Transfer here / Add
|
|
2522
|
+
* this device) before anybody presses Join. Null when no other tab has the person live.
|
|
2523
|
+
*/
|
|
2524
|
+
presenceElsewhere?(room: string, person: string): Promise<{
|
|
2525
|
+
readonly rule: string | null;
|
|
2526
|
+
} | null>;
|
|
2505
2527
|
dispose(): void;
|
|
2506
2528
|
}
|
|
2507
2529
|
|
|
@@ -2907,6 +2929,8 @@ interface RoomToken {
|
|
|
2907
2929
|
* LiveKit token was issued (`token` is empty); the pre-join offers the choice.
|
|
2908
2930
|
*/
|
|
2909
2931
|
readonly secondDeviceChoice?: string | null | undefined;
|
|
2932
|
+
/** S7: the meeting's `second_device` rule, always — told to a second tab of this browser. */
|
|
2933
|
+
readonly secondDeviceRule?: string | null | undefined;
|
|
2910
2934
|
readonly displayName: string;
|
|
2911
2935
|
/** ISO. The package refreshes at 80% of the remaining life. */
|
|
2912
2936
|
readonly expiresAt: string;
|
|
@@ -3056,10 +3080,10 @@ declare const MEET_ROUTES: {
|
|
|
3056
3080
|
readonly recordingStop: "/api/v1/meet/recording/stop";
|
|
3057
3081
|
readonly noteTakerStart: "/api/v1/meet/agent/start";
|
|
3058
3082
|
readonly noteTakerStop: "/api/v1/meet/agent/stop";
|
|
3059
|
-
/** In-meeting Q&A. Streams NDJSON; body is `{meeting_id, question}` only. */
|
|
3060
|
-
readonly intelligenceAsk: "/api/v1/meet/intelligence/ask";
|
|
3061
3083
|
/** Anyone in the meeting (guests with the room pass included) asks for captions for themselves. */
|
|
3062
3084
|
readonly noteTakerCaptions: "/api/v1/meet/agent/captions";
|
|
3085
|
+
/** In-meeting Q&A. Streams NDJSON; body is `{meeting_id, question}` only. */
|
|
3086
|
+
readonly intelligenceAsk: "/api/v1/meet/intelligence/ask";
|
|
3063
3087
|
/** A host ends the meeting for everyone. Served by MRI-A6. */
|
|
3064
3088
|
readonly meetingEnd: "/api/v1/meet/end";
|
|
3065
3089
|
/**
|
package/dist/core.js
CHANGED
|
@@ -323,7 +323,8 @@ function createWebResumeStorage() {
|
|
|
323
323
|
}
|
|
324
324
|
};
|
|
325
325
|
}
|
|
326
|
-
var CLEARS_RESUME = (phase) => phase === "left" || phase === "removed" || phase === "superseded" || phase === "inactive" || phase === "ended" || phase === "record" || phase === "prejoin" || phase
|
|
326
|
+
var CLEARS_RESUME = (phase) => phase === "left" || phase === "removed" || phase === "superseded" || phase === "inactive" || phase === "ended" || phase === "record" || phase === "prejoin" || phase === "denied" || phase === "knock_expired" || phase.startsWith("refused:");
|
|
327
|
+
var WAITING_RESUMES = (phase) => phase.startsWith("waiting:");
|
|
327
328
|
function autoRejoinDelayMs(attempt, random = Math.random) {
|
|
328
329
|
const base = Math.min(15e3, 1e3 * 2 ** Math.max(0, attempt));
|
|
329
330
|
return Math.round(base * (0.5 + random()));
|
|
@@ -455,6 +456,10 @@ function createConnectionSupervisor(options) {
|
|
|
455
456
|
rejoinAttempts = 0;
|
|
456
457
|
stopRejoin();
|
|
457
458
|
saveMarker(true);
|
|
459
|
+
} else if (WAITING_RESUMES(phase)) {
|
|
460
|
+
stopRejoin();
|
|
461
|
+
driverRegion = null;
|
|
462
|
+
saveMarker(true);
|
|
458
463
|
} else if (phase === "disconnected") {
|
|
459
464
|
driverRegion = null;
|
|
460
465
|
saveMarker(true);
|
|
@@ -630,10 +635,10 @@ var MEET_ROUTES = {
|
|
|
630
635
|
recordingStop: "/api/v1/meet/recording/stop",
|
|
631
636
|
noteTakerStart: "/api/v1/meet/agent/start",
|
|
632
637
|
noteTakerStop: "/api/v1/meet/agent/stop",
|
|
633
|
-
/** In-meeting Q&A. Streams NDJSON; body is `{meeting_id, question}` only. */
|
|
634
|
-
intelligenceAsk: "/api/v1/meet/intelligence/ask",
|
|
635
638
|
/** Anyone in the meeting (guests with the room pass included) asks for captions for themselves. */
|
|
636
639
|
noteTakerCaptions: "/api/v1/meet/agent/captions",
|
|
640
|
+
/** In-meeting Q&A. Streams NDJSON; body is `{meeting_id, question}` only. */
|
|
641
|
+
intelligenceAsk: "/api/v1/meet/intelligence/ask",
|
|
637
642
|
/** A host ends the meeting for everyone. Served by MRI-A6. */
|
|
638
643
|
meetingEnd: "/api/v1/meet/end",
|
|
639
644
|
/**
|
|
@@ -758,6 +763,7 @@ function parseRoomToken(body, roomName) {
|
|
|
758
763
|
connectionIdentity: readString(payload, "connection_identity") ?? personKey,
|
|
759
764
|
connectionKind: readString(payload, "connection_kind") === "companion" ? "companion" : "main",
|
|
760
765
|
secondDeviceChoice,
|
|
766
|
+
secondDeviceRule: readString(payload, "second_device_rule"),
|
|
761
767
|
displayName: readString(payload, "display_name") ?? readString(payload, "displayName") ?? identity,
|
|
762
768
|
expiresAt,
|
|
763
769
|
canPublish: readBoolean(payload, "can_publish", true),
|
|
@@ -1302,6 +1308,7 @@ var STATES = [
|
|
|
1302
1308
|
"ended"
|
|
1303
1309
|
];
|
|
1304
1310
|
function readState(value) {
|
|
1311
|
+
if (value === "dispatching") return "joining";
|
|
1305
1312
|
return typeof value === "string" && STATES.includes(value) ? value : null;
|
|
1306
1313
|
}
|
|
1307
1314
|
function isNoteTaker(participant) {
|
|
@@ -1496,6 +1503,12 @@ var JOINABLE_FROM = /* @__PURE__ */ new Set([
|
|
|
1496
1503
|
// allows the press; the server's gate decides whether it knocks or is refused again.
|
|
1497
1504
|
"refused:lobby_rejects"
|
|
1498
1505
|
]);
|
|
1506
|
+
var RETRYABLE_REFUSALS = /* @__PURE__ */ new Set([
|
|
1507
|
+
"refused:locked",
|
|
1508
|
+
"refused:too_early",
|
|
1509
|
+
"refused:meeting_full",
|
|
1510
|
+
"refused:platform_capacity"
|
|
1511
|
+
]);
|
|
1499
1512
|
var NOT_ENDABLE = /* @__PURE__ */ new Set([
|
|
1500
1513
|
"ended",
|
|
1501
1514
|
"record",
|
|
@@ -1561,7 +1574,7 @@ function nextPhase(from, event) {
|
|
|
1561
1574
|
case "link_state":
|
|
1562
1575
|
return from === "resolving" && event.reason !== null && isJoinRefusalReason(event.reason) ? refusalPhase(event.reason) : null;
|
|
1563
1576
|
case "join":
|
|
1564
|
-
return JOINABLE_FROM.has(from) ? "joining" : null;
|
|
1577
|
+
return JOINABLE_FROM.has(from) || RETRYABLE_REFUSALS.has(from) ? "joining" : null;
|
|
1565
1578
|
case "auto_rejoin":
|
|
1566
1579
|
return from === "disconnected" ? "joining" : null;
|
|
1567
1580
|
case "resumed":
|
|
@@ -1986,6 +1999,10 @@ var RPCS = {
|
|
|
1986
1999
|
admitAll: "meet_admit_all",
|
|
1987
2000
|
setLock: "meet_set_lock",
|
|
1988
2001
|
recordConsent: "meet_record_consent",
|
|
2002
|
+
/** One meeting rule as the gate obeys it (the knob ladder, this meeting's rung included). */
|
|
2003
|
+
meetingRule: "meet_policy",
|
|
2004
|
+
/** A host sets one rule for THIS meeting (the `meet_meeting` rung); refusals come back as `{ok:false}`. */
|
|
2005
|
+
setMeetingRule: "meet_policy_set",
|
|
1989
2006
|
/*
|
|
1990
2007
|
* ── MEET WAVE 1 — management (0.8). Every write is a SECURITY DEFINER door
|
|
1991
2008
|
* authorized by the meeting's host or a real iam grant (editor to change,
|
|
@@ -2032,7 +2049,7 @@ var INVITEE_COLUMNS = "id,meeting_id,invitee_user_id,email,display_name,role,rsv
|
|
|
2032
2049
|
var RECORDING_COLUMNS = "id,meeting_id,state,started_at,ended_at,started_by,file_id,failure_reason";
|
|
2033
2050
|
var SEGMENT_COLUMNS = "id,meeting_id,identity,speaker,text,started_at,is_final,metadata";
|
|
2034
2051
|
var NOTE_COLUMNS = "id,meeting_id,text,kind,assignee_user_id,created_at,metadata";
|
|
2035
|
-
var ATTENDEE_COLUMNS = "id,meeting_id,identity,participant_user_id,display_name,avatar_url,role,admission_state,knocked_at,knock_expires_at,is_agent,joined_at,left_at,sessions:metadata->sessions";
|
|
2052
|
+
var ATTENDEE_COLUMNS = "id,meeting_id,identity,participant_user_id,display_name,avatar_url,role,admission_state,knocked_at,knock_expires_at,is_agent,joined_at,left_at,sessions:metadata->sessions,knock_flag:metadata->>knock_flag";
|
|
2036
2053
|
function projectStays(value) {
|
|
2037
2054
|
if (!Array.isArray(value)) return [];
|
|
2038
2055
|
const stays = [];
|
|
@@ -2432,6 +2449,8 @@ function createMeetRepository(options) {
|
|
|
2432
2449
|
admissionState: states.includes(admission) ? admission : "admitted",
|
|
2433
2450
|
knockedAt: text(row, "knocked_at"),
|
|
2434
2451
|
knockExpiresAt: text(row, "knock_expires_at"),
|
|
2452
|
+
// The list read selects `metadata->>knock_flag`; a Postgres Changes row carries `metadata`.
|
|
2453
|
+
knockFlag: text(row, "knock_flag") ?? (typeof row["metadata"] === "object" && row["metadata"] !== null ? text(row["metadata"], "knock_flag") : null),
|
|
2435
2454
|
isAgent: bool(row, "is_agent", false),
|
|
2436
2455
|
joinedAt: text(row, "joined_at"),
|
|
2437
2456
|
leftAt: text(row, "left_at"),
|
|
@@ -2755,6 +2774,25 @@ function createMeetRepository(options) {
|
|
|
2755
2774
|
);
|
|
2756
2775
|
return projectMeeting(row);
|
|
2757
2776
|
},
|
|
2777
|
+
async meetingRule(meetingId, key) {
|
|
2778
|
+
const response = await db.rpc(RPCS.meetingRule, { p_meeting_id: meetingId, p_key: key });
|
|
2779
|
+
if (response.error !== null) throw normalizeMeetError(response.error, "meet.meetingRule");
|
|
2780
|
+
return response.data;
|
|
2781
|
+
},
|
|
2782
|
+
async setMeetingRule(meetingId, key, value) {
|
|
2783
|
+
const response = await db.rpc(RPCS.setMeetingRule, { p_meeting_id: meetingId, p_key: key, p_value: value });
|
|
2784
|
+
if (response.error !== null) throw normalizeMeetError(response.error, "meet.setMeetingRule");
|
|
2785
|
+
const answer = response.data ?? {};
|
|
2786
|
+
if (answer["ok"] !== true) {
|
|
2787
|
+
throw new MeetError(
|
|
2788
|
+
"forbidden",
|
|
2789
|
+
typeof answer["detail"] === "string" ? answer["detail"] : "This meeting's rule was not changed.",
|
|
2790
|
+
"Only the meeting's host or a co-host sets its rules; an organization can lock a rule for everyone.",
|
|
2791
|
+
answer
|
|
2792
|
+
);
|
|
2793
|
+
}
|
|
2794
|
+
return answer["effective_value"];
|
|
2795
|
+
},
|
|
2758
2796
|
async transcript(meetingId, limit = 1e3) {
|
|
2759
2797
|
const response = await db.from(TABLES.transcripts).select(SEGMENT_COLUMNS).eq("meeting_id", meetingId).order("started_at", { ascending: true }).order("id", { ascending: true }).limit(limit);
|
|
2760
2798
|
if (response.error !== null) throw normalizeMeetError(response.error, "meet.transcript");
|
|
@@ -4920,7 +4958,8 @@ function lobbyEntryFrom(attendee, now = Date.now()) {
|
|
|
4920
4958
|
knockedAt: attendee.knockedAt ?? attendee.joinedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
4921
4959
|
knockExpiresAt: attendee.knockExpiresAt ?? null,
|
|
4922
4960
|
decidedAt: null,
|
|
4923
|
-
decidedBy: null
|
|
4961
|
+
decidedBy: null,
|
|
4962
|
+
flag: attendee.knockFlag ?? null
|
|
4924
4963
|
};
|
|
4925
4964
|
}
|
|
4926
4965
|
function deniedEntryFrom(attendee) {
|
|
@@ -5092,11 +5131,15 @@ function createMeetingSession(options) {
|
|
|
5092
5131
|
}
|
|
5093
5132
|
let policyTimer = null;
|
|
5094
5133
|
let policyReading = false;
|
|
5134
|
+
let policyInFlight = null;
|
|
5095
5135
|
async function readLivePolicy() {
|
|
5096
5136
|
const meeting = store.snapshot().meeting;
|
|
5097
5137
|
const pass = options.resolvePass?.() ?? null;
|
|
5098
|
-
if (meeting === null || pass === null
|
|
5138
|
+
if (meeting === null || pass === null) return;
|
|
5139
|
+
if (policyReading) return policyInFlight ?? void 0;
|
|
5099
5140
|
policyReading = true;
|
|
5141
|
+
let done = () => void 0;
|
|
5142
|
+
policyInFlight = new Promise((resolve) => done = resolve);
|
|
5100
5143
|
try {
|
|
5101
5144
|
const response = await options.api.request({
|
|
5102
5145
|
path: `${MEET_ROUTES.state}?meeting_id=${encodeURIComponent(meeting.id)}`,
|
|
@@ -5117,6 +5160,8 @@ function createMeetingSession(options) {
|
|
|
5117
5160
|
} catch {
|
|
5118
5161
|
} finally {
|
|
5119
5162
|
policyReading = false;
|
|
5163
|
+
policyInFlight = null;
|
|
5164
|
+
done();
|
|
5120
5165
|
}
|
|
5121
5166
|
}
|
|
5122
5167
|
function syncLivePolicyTimer() {
|
|
@@ -5415,6 +5460,7 @@ function createMeetingSession(options) {
|
|
|
5415
5460
|
},
|
|
5416
5461
|
stopWaiting,
|
|
5417
5462
|
readState: readState2,
|
|
5463
|
+
readLivePolicy,
|
|
5418
5464
|
async readExit(connection, held) {
|
|
5419
5465
|
const meeting = store.snapshot().meeting;
|
|
5420
5466
|
const pass = held ?? options.resolvePass?.() ?? null;
|
|
@@ -5452,6 +5498,17 @@ function createMeetingSession(options) {
|
|
|
5452
5498
|
async askAgain() {
|
|
5453
5499
|
await options.rejoin?.();
|
|
5454
5500
|
},
|
|
5501
|
+
async meetingRule(key) {
|
|
5502
|
+
const meeting = requireMeeting("meet.meetingRule");
|
|
5503
|
+
return repository.meetingRule(meeting.id, key);
|
|
5504
|
+
},
|
|
5505
|
+
async setMeetingRule(key, value) {
|
|
5506
|
+
requireHostUser("meet.setMeetingRule");
|
|
5507
|
+
const meeting = requireMeeting("meet.setMeetingRule");
|
|
5508
|
+
const effective = await repository.setMeetingRule(meeting.id, key, value);
|
|
5509
|
+
hint();
|
|
5510
|
+
return effective;
|
|
5511
|
+
},
|
|
5455
5512
|
async setLock(locked) {
|
|
5456
5513
|
const by = requireHostUser("meet.setLock");
|
|
5457
5514
|
const meeting = requireMeeting("meet.setLock");
|
|
@@ -6843,7 +6900,7 @@ function createRoomEngine(options) {
|
|
|
6843
6900
|
const { secondDevice: _answered, ...rest } = lastRequest;
|
|
6844
6901
|
lastRequest = rest;
|
|
6845
6902
|
}
|
|
6846
|
-
options.tabClaim?.inRoom(String(request.roomName), String(token.identity));
|
|
6903
|
+
options.tabClaim?.inRoom(String(request.roomName), String(token.identity), token.secondDeviceRule ?? null);
|
|
6847
6904
|
current = token;
|
|
6848
6905
|
lastServerUrl = token.serverUrl;
|
|
6849
6906
|
connectionPolicy = token.connectionPolicy ?? DEFAULT_CONNECTION_POLICY;
|
|
@@ -7155,10 +7212,12 @@ function createRoomEngine(options) {
|
|
|
7155
7212
|
if (claim === void 0 || userId === null) return false;
|
|
7156
7213
|
const before = store.snapshot();
|
|
7157
7214
|
if (before.phase !== "prejoin" || before.secondDevice !== null) return false;
|
|
7158
|
-
|
|
7215
|
+
const person = `user:${String(userId)}`;
|
|
7216
|
+
const found = claim.presenceElsewhere !== void 0 ? await claim.presenceElsewhere(String(roomName), person) : await claim.presentElsewhere(String(roomName), person) ? { rule: null } : null;
|
|
7217
|
+
if (found === null || found.rule === "allow_both") return false;
|
|
7159
7218
|
const now2 = store.snapshot();
|
|
7160
7219
|
if (now2.phase !== "prejoin" || now2.secondDevice !== null) return false;
|
|
7161
|
-
store.patch({ secondDevice: { rule: "ask_switch_or_join" } });
|
|
7220
|
+
store.patch({ secondDevice: { rule: found.rule ?? "ask_switch_or_join" } });
|
|
7162
7221
|
report("info", "meet: this browser already has you in this meeting \u2014 offering the choice before Join");
|
|
7163
7222
|
return true;
|
|
7164
7223
|
},
|
|
@@ -7414,6 +7473,7 @@ function createInRoomClient(options) {
|
|
|
7414
7473
|
action: request.action,
|
|
7415
7474
|
...request.identity != null ? { identity: request.identity } : {},
|
|
7416
7475
|
...request.name !== void 0 ? { name: request.name } : {},
|
|
7476
|
+
...request.value !== void 0 ? { value: request.value } : {},
|
|
7417
7477
|
...request.reason !== void 0 ? { reason: request.reason } : {}
|
|
7418
7478
|
},
|
|
7419
7479
|
...hdrs !== void 0 ? { headers: hdrs } : {}
|