@ai-matrx/meet 0.11.44 → 0.11.45
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 +6 -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 +58 -7
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +25 -3
- package/dist/core.d.ts +25 -3
- package/dist/core.js +58 -7
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +58 -7
- 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 +58 -7
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +169 -25
- 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 +169 -25
- package/dist/react.js.map +1 -1
- package/dist/skins/meet.cjs +112 -24
- 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 +112 -24
- package/dist/skins/meet.js.map +1 -1
- package/dist/styles.css +16 -0
- package/package.json +4 -4
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';
|
|
@@ -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). */
|
|
@@ -2308,6 +2316,10 @@ interface MeetingSession {
|
|
|
2308
2316
|
readonly assignTo: string;
|
|
2309
2317
|
}): Promise<void>;
|
|
2310
2318
|
setLock(locked: boolean): Promise<MeetingRecord>;
|
|
2319
|
+
/** `wr-policy-who-waits`: one rule of the meeting on screen (null when unreadable). */
|
|
2320
|
+
meetingRule(key: string): Promise<unknown>;
|
|
2321
|
+
/** A host changes one rule for this meeting; waiting people are told to read again. */
|
|
2322
|
+
setMeetingRule(key: string, value: string | number | boolean): Promise<unknown>;
|
|
2311
2323
|
/** End it for everyone, through the server (MRI-A6). */
|
|
2312
2324
|
endForEveryone(): Promise<EndMeetingResult>;
|
|
2313
2325
|
dispose(): void;
|
|
@@ -2498,10 +2510,18 @@ interface TabClaim {
|
|
|
2498
2510
|
/** This page's claimed tab id (resolves once the claim settles). */
|
|
2499
2511
|
readonly tabId: Promise<string>;
|
|
2500
2512
|
/** Announce that this tab is in `room` as `person` (until `left`); answers presence questions. */
|
|
2501
|
-
inRoom(room: string, person: string): void;
|
|
2513
|
+
inRoom(room: string, person: string, rule?: string | null): void;
|
|
2502
2514
|
left(): void;
|
|
2503
2515
|
/** Is `person` in `room` on ANOTHER tab of this browser? Answers within `TAB_ANSWER_MS`. */
|
|
2504
2516
|
presentElsewhere(room: string, person: string): Promise<boolean>;
|
|
2517
|
+
/**
|
|
2518
|
+
* The same question, with the meeting's `second_device` rule the live tab holds — so the second
|
|
2519
|
+
* tab offers the PROFILE's choice (Meet: Switch here / Join here too; Teams: Transfer here / Add
|
|
2520
|
+
* this device) before anybody presses Join. Null when no other tab has the person live.
|
|
2521
|
+
*/
|
|
2522
|
+
presenceElsewhere?(room: string, person: string): Promise<{
|
|
2523
|
+
readonly rule: string | null;
|
|
2524
|
+
} | null>;
|
|
2505
2525
|
dispose(): void;
|
|
2506
2526
|
}
|
|
2507
2527
|
|
|
@@ -2907,6 +2927,8 @@ interface RoomToken {
|
|
|
2907
2927
|
* LiveKit token was issued (`token` is empty); the pre-join offers the choice.
|
|
2908
2928
|
*/
|
|
2909
2929
|
readonly secondDeviceChoice?: string | null | undefined;
|
|
2930
|
+
/** S7: the meeting's `second_device` rule, always — told to a second tab of this browser. */
|
|
2931
|
+
readonly secondDeviceRule?: string | null | undefined;
|
|
2910
2932
|
readonly displayName: string;
|
|
2911
2933
|
/** ISO. The package refreshes at 80% of the remaining life. */
|
|
2912
2934
|
readonly expiresAt: string;
|
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';
|
|
@@ -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). */
|
|
@@ -2308,6 +2316,10 @@ interface MeetingSession {
|
|
|
2308
2316
|
readonly assignTo: string;
|
|
2309
2317
|
}): Promise<void>;
|
|
2310
2318
|
setLock(locked: boolean): Promise<MeetingRecord>;
|
|
2319
|
+
/** `wr-policy-who-waits`: one rule of the meeting on screen (null when unreadable). */
|
|
2320
|
+
meetingRule(key: string): Promise<unknown>;
|
|
2321
|
+
/** A host changes one rule for this meeting; waiting people are told to read again. */
|
|
2322
|
+
setMeetingRule(key: string, value: string | number | boolean): Promise<unknown>;
|
|
2311
2323
|
/** End it for everyone, through the server (MRI-A6). */
|
|
2312
2324
|
endForEveryone(): Promise<EndMeetingResult>;
|
|
2313
2325
|
dispose(): void;
|
|
@@ -2498,10 +2510,18 @@ interface TabClaim {
|
|
|
2498
2510
|
/** This page's claimed tab id (resolves once the claim settles). */
|
|
2499
2511
|
readonly tabId: Promise<string>;
|
|
2500
2512
|
/** Announce that this tab is in `room` as `person` (until `left`); answers presence questions. */
|
|
2501
|
-
inRoom(room: string, person: string): void;
|
|
2513
|
+
inRoom(room: string, person: string, rule?: string | null): void;
|
|
2502
2514
|
left(): void;
|
|
2503
2515
|
/** Is `person` in `room` on ANOTHER tab of this browser? Answers within `TAB_ANSWER_MS`. */
|
|
2504
2516
|
presentElsewhere(room: string, person: string): Promise<boolean>;
|
|
2517
|
+
/**
|
|
2518
|
+
* The same question, with the meeting's `second_device` rule the live tab holds — so the second
|
|
2519
|
+
* tab offers the PROFILE's choice (Meet: Switch here / Join here too; Teams: Transfer here / Add
|
|
2520
|
+
* this device) before anybody presses Join. Null when no other tab has the person live.
|
|
2521
|
+
*/
|
|
2522
|
+
presenceElsewhere?(room: string, person: string): Promise<{
|
|
2523
|
+
readonly rule: string | null;
|
|
2524
|
+
} | null>;
|
|
2505
2525
|
dispose(): void;
|
|
2506
2526
|
}
|
|
2507
2527
|
|
|
@@ -2907,6 +2927,8 @@ interface RoomToken {
|
|
|
2907
2927
|
* LiveKit token was issued (`token` is empty); the pre-join offers the choice.
|
|
2908
2928
|
*/
|
|
2909
2929
|
readonly secondDeviceChoice?: string | null | undefined;
|
|
2930
|
+
/** S7: the meeting's `second_device` rule, always — told to a second tab of this browser. */
|
|
2931
|
+
readonly secondDeviceRule?: string | null | undefined;
|
|
2910
2932
|
readonly displayName: string;
|
|
2911
2933
|
/** ISO. The package refreshes at 80% of the remaining life. */
|
|
2912
2934
|
readonly expiresAt: string;
|
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);
|
|
@@ -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),
|
|
@@ -1496,6 +1502,12 @@ var JOINABLE_FROM = /* @__PURE__ */ new Set([
|
|
|
1496
1502
|
// allows the press; the server's gate decides whether it knocks or is refused again.
|
|
1497
1503
|
"refused:lobby_rejects"
|
|
1498
1504
|
]);
|
|
1505
|
+
var RETRYABLE_REFUSALS = /* @__PURE__ */ new Set([
|
|
1506
|
+
"refused:locked",
|
|
1507
|
+
"refused:too_early",
|
|
1508
|
+
"refused:meeting_full",
|
|
1509
|
+
"refused:platform_capacity"
|
|
1510
|
+
]);
|
|
1499
1511
|
var NOT_ENDABLE = /* @__PURE__ */ new Set([
|
|
1500
1512
|
"ended",
|
|
1501
1513
|
"record",
|
|
@@ -1561,7 +1573,7 @@ function nextPhase(from, event) {
|
|
|
1561
1573
|
case "link_state":
|
|
1562
1574
|
return from === "resolving" && event.reason !== null && isJoinRefusalReason(event.reason) ? refusalPhase(event.reason) : null;
|
|
1563
1575
|
case "join":
|
|
1564
|
-
return JOINABLE_FROM.has(from) ? "joining" : null;
|
|
1576
|
+
return JOINABLE_FROM.has(from) || RETRYABLE_REFUSALS.has(from) ? "joining" : null;
|
|
1565
1577
|
case "auto_rejoin":
|
|
1566
1578
|
return from === "disconnected" ? "joining" : null;
|
|
1567
1579
|
case "resumed":
|
|
@@ -1986,6 +1998,10 @@ var RPCS = {
|
|
|
1986
1998
|
admitAll: "meet_admit_all",
|
|
1987
1999
|
setLock: "meet_set_lock",
|
|
1988
2000
|
recordConsent: "meet_record_consent",
|
|
2001
|
+
/** One meeting rule as the gate obeys it (the knob ladder, this meeting's rung included). */
|
|
2002
|
+
meetingRule: "meet_policy",
|
|
2003
|
+
/** A host sets one rule for THIS meeting (the `meet_meeting` rung); refusals come back as `{ok:false}`. */
|
|
2004
|
+
setMeetingRule: "meet_policy_set",
|
|
1989
2005
|
/*
|
|
1990
2006
|
* ── MEET WAVE 1 — management (0.8). Every write is a SECURITY DEFINER door
|
|
1991
2007
|
* authorized by the meeting's host or a real iam grant (editor to change,
|
|
@@ -2032,7 +2048,7 @@ var INVITEE_COLUMNS = "id,meeting_id,invitee_user_id,email,display_name,role,rsv
|
|
|
2032
2048
|
var RECORDING_COLUMNS = "id,meeting_id,state,started_at,ended_at,started_by,file_id,failure_reason";
|
|
2033
2049
|
var SEGMENT_COLUMNS = "id,meeting_id,identity,speaker,text,started_at,is_final,metadata";
|
|
2034
2050
|
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";
|
|
2051
|
+
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
2052
|
function projectStays(value) {
|
|
2037
2053
|
if (!Array.isArray(value)) return [];
|
|
2038
2054
|
const stays = [];
|
|
@@ -2432,6 +2448,8 @@ function createMeetRepository(options) {
|
|
|
2432
2448
|
admissionState: states.includes(admission) ? admission : "admitted",
|
|
2433
2449
|
knockedAt: text(row, "knocked_at"),
|
|
2434
2450
|
knockExpiresAt: text(row, "knock_expires_at"),
|
|
2451
|
+
// The list read selects `metadata->>knock_flag`; a Postgres Changes row carries `metadata`.
|
|
2452
|
+
knockFlag: text(row, "knock_flag") ?? (typeof row["metadata"] === "object" && row["metadata"] !== null ? text(row["metadata"], "knock_flag") : null),
|
|
2435
2453
|
isAgent: bool(row, "is_agent", false),
|
|
2436
2454
|
joinedAt: text(row, "joined_at"),
|
|
2437
2455
|
leftAt: text(row, "left_at"),
|
|
@@ -2755,6 +2773,25 @@ function createMeetRepository(options) {
|
|
|
2755
2773
|
);
|
|
2756
2774
|
return projectMeeting(row);
|
|
2757
2775
|
},
|
|
2776
|
+
async meetingRule(meetingId, key) {
|
|
2777
|
+
const response = await db.rpc(RPCS.meetingRule, { p_meeting_id: meetingId, p_key: key });
|
|
2778
|
+
if (response.error !== null) throw normalizeMeetError(response.error, "meet.meetingRule");
|
|
2779
|
+
return response.data;
|
|
2780
|
+
},
|
|
2781
|
+
async setMeetingRule(meetingId, key, value) {
|
|
2782
|
+
const response = await db.rpc(RPCS.setMeetingRule, { p_meeting_id: meetingId, p_key: key, p_value: value });
|
|
2783
|
+
if (response.error !== null) throw normalizeMeetError(response.error, "meet.setMeetingRule");
|
|
2784
|
+
const answer = response.data ?? {};
|
|
2785
|
+
if (answer["ok"] !== true) {
|
|
2786
|
+
throw new MeetError(
|
|
2787
|
+
"forbidden",
|
|
2788
|
+
typeof answer["detail"] === "string" ? answer["detail"] : "This meeting's rule was not changed.",
|
|
2789
|
+
"Only the meeting's host or a co-host sets its rules; an organization can lock a rule for everyone.",
|
|
2790
|
+
answer
|
|
2791
|
+
);
|
|
2792
|
+
}
|
|
2793
|
+
return answer["effective_value"];
|
|
2794
|
+
},
|
|
2758
2795
|
async transcript(meetingId, limit = 1e3) {
|
|
2759
2796
|
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
2797
|
if (response.error !== null) throw normalizeMeetError(response.error, "meet.transcript");
|
|
@@ -4920,7 +4957,8 @@ function lobbyEntryFrom(attendee, now = Date.now()) {
|
|
|
4920
4957
|
knockedAt: attendee.knockedAt ?? attendee.joinedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
4921
4958
|
knockExpiresAt: attendee.knockExpiresAt ?? null,
|
|
4922
4959
|
decidedAt: null,
|
|
4923
|
-
decidedBy: null
|
|
4960
|
+
decidedBy: null,
|
|
4961
|
+
flag: attendee.knockFlag ?? null
|
|
4924
4962
|
};
|
|
4925
4963
|
}
|
|
4926
4964
|
function deniedEntryFrom(attendee) {
|
|
@@ -5452,6 +5490,17 @@ function createMeetingSession(options) {
|
|
|
5452
5490
|
async askAgain() {
|
|
5453
5491
|
await options.rejoin?.();
|
|
5454
5492
|
},
|
|
5493
|
+
async meetingRule(key) {
|
|
5494
|
+
const meeting = requireMeeting("meet.meetingRule");
|
|
5495
|
+
return repository.meetingRule(meeting.id, key);
|
|
5496
|
+
},
|
|
5497
|
+
async setMeetingRule(key, value) {
|
|
5498
|
+
requireHostUser("meet.setMeetingRule");
|
|
5499
|
+
const meeting = requireMeeting("meet.setMeetingRule");
|
|
5500
|
+
const effective = await repository.setMeetingRule(meeting.id, key, value);
|
|
5501
|
+
hint();
|
|
5502
|
+
return effective;
|
|
5503
|
+
},
|
|
5455
5504
|
async setLock(locked) {
|
|
5456
5505
|
const by = requireHostUser("meet.setLock");
|
|
5457
5506
|
const meeting = requireMeeting("meet.setLock");
|
|
@@ -6843,7 +6892,7 @@ function createRoomEngine(options) {
|
|
|
6843
6892
|
const { secondDevice: _answered, ...rest } = lastRequest;
|
|
6844
6893
|
lastRequest = rest;
|
|
6845
6894
|
}
|
|
6846
|
-
options.tabClaim?.inRoom(String(request.roomName), String(token.identity));
|
|
6895
|
+
options.tabClaim?.inRoom(String(request.roomName), String(token.identity), token.secondDeviceRule ?? null);
|
|
6847
6896
|
current = token;
|
|
6848
6897
|
lastServerUrl = token.serverUrl;
|
|
6849
6898
|
connectionPolicy = token.connectionPolicy ?? DEFAULT_CONNECTION_POLICY;
|
|
@@ -7155,10 +7204,12 @@ function createRoomEngine(options) {
|
|
|
7155
7204
|
if (claim === void 0 || userId === null) return false;
|
|
7156
7205
|
const before = store.snapshot();
|
|
7157
7206
|
if (before.phase !== "prejoin" || before.secondDevice !== null) return false;
|
|
7158
|
-
|
|
7207
|
+
const person = `user:${String(userId)}`;
|
|
7208
|
+
const found = claim.presenceElsewhere !== void 0 ? await claim.presenceElsewhere(String(roomName), person) : await claim.presentElsewhere(String(roomName), person) ? { rule: null } : null;
|
|
7209
|
+
if (found === null || found.rule === "allow_both") return false;
|
|
7159
7210
|
const now2 = store.snapshot();
|
|
7160
7211
|
if (now2.phase !== "prejoin" || now2.secondDevice !== null) return false;
|
|
7161
|
-
store.patch({ secondDevice: { rule: "ask_switch_or_join" } });
|
|
7212
|
+
store.patch({ secondDevice: { rule: found.rule ?? "ask_switch_or_join" } });
|
|
7162
7213
|
report("info", "meet: this browser already has you in this meeting \u2014 offering the choice before Join");
|
|
7163
7214
|
return true;
|
|
7164
7215
|
},
|