@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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog — `@ai-matrx/meet`
|
|
2
2
|
|
|
3
|
+
## 0.11.45
|
|
4
|
+
|
|
5
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
6
|
+
`git diff npm/meet/v0.11.44..npm/meet/v0.11.45 -- apps/shared/meet`).
|
|
7
|
+
No source changes intended and no consumer action required.
|
|
8
|
+
|
|
3
9
|
## 0.11.44
|
|
4
10
|
|
|
5
11
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
@@ -107,6 +107,11 @@ interface LobbyEntry {
|
|
|
107
107
|
readonly knockExpiresAt?: string | null | undefined;
|
|
108
108
|
readonly decidedAt: string | null;
|
|
109
109
|
readonly decidedBy: UserId | null;
|
|
110
|
+
/**
|
|
111
|
+
* The server's flag on this knock (`mod-removed-bypass`): `previously_removed` when its coarse
|
|
112
|
+
* signals match someone a host removed from this meeting. Advice for the host, never a block.
|
|
113
|
+
*/
|
|
114
|
+
readonly flag?: string | null | undefined;
|
|
110
115
|
}
|
|
111
116
|
type ConnectionQuality = "excellent" | "good" | "poor" | "lost" | "unknown";
|
|
112
117
|
/** One person in the room, as the UI needs them. Media state is a FACT here. */
|
|
@@ -403,6 +408,8 @@ interface MeetingAttendee {
|
|
|
403
408
|
/** When this person knocked, and when an unanswered knock lapses (null = never). */
|
|
404
409
|
readonly knockedAt?: string | null | undefined;
|
|
405
410
|
readonly knockExpiresAt?: string | null | undefined;
|
|
411
|
+
/** The server's flag on a knock (`metadata.knock_flag`), e.g. `previously_removed`. */
|
|
412
|
+
readonly knockFlag?: string | null | undefined;
|
|
406
413
|
readonly isAgent: boolean;
|
|
407
414
|
/** FIRST arrival in the room — a rejoin never moves it. */
|
|
408
415
|
readonly joinedAt: string | null;
|
|
@@ -107,6 +107,11 @@ interface LobbyEntry {
|
|
|
107
107
|
readonly knockExpiresAt?: string | null | undefined;
|
|
108
108
|
readonly decidedAt: string | null;
|
|
109
109
|
readonly decidedBy: UserId | null;
|
|
110
|
+
/**
|
|
111
|
+
* The server's flag on this knock (`mod-removed-bypass`): `previously_removed` when its coarse
|
|
112
|
+
* signals match someone a host removed from this meeting. Advice for the host, never a block.
|
|
113
|
+
*/
|
|
114
|
+
readonly flag?: string | null | undefined;
|
|
110
115
|
}
|
|
111
116
|
type ConnectionQuality = "excellent" | "good" | "poor" | "lost" | "unknown";
|
|
112
117
|
/** One person in the room, as the UI needs them. Media state is a FACT here. */
|
|
@@ -403,6 +408,8 @@ interface MeetingAttendee {
|
|
|
403
408
|
/** When this person knocked, and when an unanswered knock lapses (null = never). */
|
|
404
409
|
readonly knockedAt?: string | null | undefined;
|
|
405
410
|
readonly knockExpiresAt?: string | null | undefined;
|
|
411
|
+
/** The server's flag on a knock (`metadata.knock_flag`), e.g. `previously_removed`. */
|
|
412
|
+
readonly knockFlag?: string | null | undefined;
|
|
406
413
|
readonly isAgent: boolean;
|
|
407
414
|
/** FIRST arrival in the room — a rejoin never moves it. */
|
|
408
415
|
readonly joinedAt: string | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { M as MeetingRecord, P as ParticipantIdentity, R as RoomName, a as MeetParticipant } from './collab-
|
|
2
|
+
import { M as MeetingRecord, P as ParticipantIdentity, R as RoomName, a as MeetParticipant } from './collab-D1TX5uf9.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* THE PRODUCT UI (R6/R7). Not a headless kernel with a note telling the host to
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { M as MeetingRecord, P as ParticipantIdentity, R as RoomName, a as MeetParticipant } from './collab-
|
|
2
|
+
import { M as MeetingRecord, P as ParticipantIdentity, R as RoomName, a as MeetParticipant } from './collab-D1TX5uf9.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* THE PRODUCT UI (R6/R7). Not a headless kernel with a note telling the host to
|
package/dist/core.cjs
CHANGED
|
@@ -607,7 +607,8 @@ function createWebResumeStorage() {
|
|
|
607
607
|
}
|
|
608
608
|
};
|
|
609
609
|
}
|
|
610
|
-
var CLEARS_RESUME = (phase) => phase === "left" || phase === "removed" || phase === "superseded" || phase === "inactive" || phase === "ended" || phase === "record" || phase === "prejoin" || phase
|
|
610
|
+
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:");
|
|
611
|
+
var WAITING_RESUMES = (phase) => phase.startsWith("waiting:");
|
|
611
612
|
function autoRejoinDelayMs(attempt, random = Math.random) {
|
|
612
613
|
const base = Math.min(15e3, 1e3 * 2 ** Math.max(0, attempt));
|
|
613
614
|
return Math.round(base * (0.5 + random()));
|
|
@@ -739,6 +740,10 @@ function createConnectionSupervisor(options) {
|
|
|
739
740
|
rejoinAttempts = 0;
|
|
740
741
|
stopRejoin();
|
|
741
742
|
saveMarker(true);
|
|
743
|
+
} else if (WAITING_RESUMES(phase)) {
|
|
744
|
+
stopRejoin();
|
|
745
|
+
driverRegion = null;
|
|
746
|
+
saveMarker(true);
|
|
742
747
|
} else if (phase === "disconnected") {
|
|
743
748
|
driverRegion = null;
|
|
744
749
|
saveMarker(true);
|
|
@@ -1042,6 +1047,7 @@ function parseRoomToken(body, roomName) {
|
|
|
1042
1047
|
connectionIdentity: readString(payload, "connection_identity") ?? personKey,
|
|
1043
1048
|
connectionKind: readString(payload, "connection_kind") === "companion" ? "companion" : "main",
|
|
1044
1049
|
secondDeviceChoice,
|
|
1050
|
+
secondDeviceRule: readString(payload, "second_device_rule"),
|
|
1045
1051
|
displayName: readString(payload, "display_name") ?? readString(payload, "displayName") ?? identity,
|
|
1046
1052
|
expiresAt,
|
|
1047
1053
|
canPublish: readBoolean(payload, "can_publish", true),
|
|
@@ -1780,6 +1786,12 @@ var JOINABLE_FROM = /* @__PURE__ */ new Set([
|
|
|
1780
1786
|
// allows the press; the server's gate decides whether it knocks or is refused again.
|
|
1781
1787
|
"refused:lobby_rejects"
|
|
1782
1788
|
]);
|
|
1789
|
+
var RETRYABLE_REFUSALS = /* @__PURE__ */ new Set([
|
|
1790
|
+
"refused:locked",
|
|
1791
|
+
"refused:too_early",
|
|
1792
|
+
"refused:meeting_full",
|
|
1793
|
+
"refused:platform_capacity"
|
|
1794
|
+
]);
|
|
1783
1795
|
var NOT_ENDABLE = /* @__PURE__ */ new Set([
|
|
1784
1796
|
"ended",
|
|
1785
1797
|
"record",
|
|
@@ -1845,7 +1857,7 @@ function nextPhase(from, event) {
|
|
|
1845
1857
|
case "link_state":
|
|
1846
1858
|
return from === "resolving" && event.reason !== null && isJoinRefusalReason(event.reason) ? refusalPhase(event.reason) : null;
|
|
1847
1859
|
case "join":
|
|
1848
|
-
return JOINABLE_FROM.has(from) ? "joining" : null;
|
|
1860
|
+
return JOINABLE_FROM.has(from) || RETRYABLE_REFUSALS.has(from) ? "joining" : null;
|
|
1849
1861
|
case "auto_rejoin":
|
|
1850
1862
|
return from === "disconnected" ? "joining" : null;
|
|
1851
1863
|
case "resumed":
|
|
@@ -2270,6 +2282,10 @@ var RPCS = {
|
|
|
2270
2282
|
admitAll: "meet_admit_all",
|
|
2271
2283
|
setLock: "meet_set_lock",
|
|
2272
2284
|
recordConsent: "meet_record_consent",
|
|
2285
|
+
/** One meeting rule as the gate obeys it (the knob ladder, this meeting's rung included). */
|
|
2286
|
+
meetingRule: "meet_policy",
|
|
2287
|
+
/** A host sets one rule for THIS meeting (the `meet_meeting` rung); refusals come back as `{ok:false}`. */
|
|
2288
|
+
setMeetingRule: "meet_policy_set",
|
|
2273
2289
|
/*
|
|
2274
2290
|
* ── MEET WAVE 1 — management (0.8). Every write is a SECURITY DEFINER door
|
|
2275
2291
|
* authorized by the meeting's host or a real iam grant (editor to change,
|
|
@@ -2316,7 +2332,7 @@ var INVITEE_COLUMNS = "id,meeting_id,invitee_user_id,email,display_name,role,rsv
|
|
|
2316
2332
|
var RECORDING_COLUMNS = "id,meeting_id,state,started_at,ended_at,started_by,file_id,failure_reason";
|
|
2317
2333
|
var SEGMENT_COLUMNS = "id,meeting_id,identity,speaker,text,started_at,is_final,metadata";
|
|
2318
2334
|
var NOTE_COLUMNS = "id,meeting_id,text,kind,assignee_user_id,created_at,metadata";
|
|
2319
|
-
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";
|
|
2335
|
+
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";
|
|
2320
2336
|
function projectStays(value) {
|
|
2321
2337
|
if (!Array.isArray(value)) return [];
|
|
2322
2338
|
const stays = [];
|
|
@@ -2716,6 +2732,8 @@ function createMeetRepository(options) {
|
|
|
2716
2732
|
admissionState: states.includes(admission) ? admission : "admitted",
|
|
2717
2733
|
knockedAt: text(row, "knocked_at"),
|
|
2718
2734
|
knockExpiresAt: text(row, "knock_expires_at"),
|
|
2735
|
+
// The list read selects `metadata->>knock_flag`; a Postgres Changes row carries `metadata`.
|
|
2736
|
+
knockFlag: text(row, "knock_flag") ?? (typeof row["metadata"] === "object" && row["metadata"] !== null ? text(row["metadata"], "knock_flag") : null),
|
|
2719
2737
|
isAgent: bool(row, "is_agent", false),
|
|
2720
2738
|
joinedAt: text(row, "joined_at"),
|
|
2721
2739
|
leftAt: text(row, "left_at"),
|
|
@@ -3039,6 +3057,25 @@ function createMeetRepository(options) {
|
|
|
3039
3057
|
);
|
|
3040
3058
|
return projectMeeting(row);
|
|
3041
3059
|
},
|
|
3060
|
+
async meetingRule(meetingId, key) {
|
|
3061
|
+
const response = await db.rpc(RPCS.meetingRule, { p_meeting_id: meetingId, p_key: key });
|
|
3062
|
+
if (response.error !== null) throw normalizeMeetError(response.error, "meet.meetingRule");
|
|
3063
|
+
return response.data;
|
|
3064
|
+
},
|
|
3065
|
+
async setMeetingRule(meetingId, key, value) {
|
|
3066
|
+
const response = await db.rpc(RPCS.setMeetingRule, { p_meeting_id: meetingId, p_key: key, p_value: value });
|
|
3067
|
+
if (response.error !== null) throw normalizeMeetError(response.error, "meet.setMeetingRule");
|
|
3068
|
+
const answer = response.data ?? {};
|
|
3069
|
+
if (answer["ok"] !== true) {
|
|
3070
|
+
throw new MeetError(
|
|
3071
|
+
"forbidden",
|
|
3072
|
+
typeof answer["detail"] === "string" ? answer["detail"] : "This meeting's rule was not changed.",
|
|
3073
|
+
"Only the meeting's host or a co-host sets its rules; an organization can lock a rule for everyone.",
|
|
3074
|
+
answer
|
|
3075
|
+
);
|
|
3076
|
+
}
|
|
3077
|
+
return answer["effective_value"];
|
|
3078
|
+
},
|
|
3042
3079
|
async transcript(meetingId, limit = 1e3) {
|
|
3043
3080
|
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);
|
|
3044
3081
|
if (response.error !== null) throw normalizeMeetError(response.error, "meet.transcript");
|
|
@@ -5204,7 +5241,8 @@ function lobbyEntryFrom(attendee, now = Date.now()) {
|
|
|
5204
5241
|
knockedAt: attendee.knockedAt ?? attendee.joinedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
5205
5242
|
knockExpiresAt: attendee.knockExpiresAt ?? null,
|
|
5206
5243
|
decidedAt: null,
|
|
5207
|
-
decidedBy: null
|
|
5244
|
+
decidedBy: null,
|
|
5245
|
+
flag: attendee.knockFlag ?? null
|
|
5208
5246
|
};
|
|
5209
5247
|
}
|
|
5210
5248
|
function deniedEntryFrom(attendee) {
|
|
@@ -5736,6 +5774,17 @@ function createMeetingSession(options) {
|
|
|
5736
5774
|
async askAgain() {
|
|
5737
5775
|
await options.rejoin?.();
|
|
5738
5776
|
},
|
|
5777
|
+
async meetingRule(key) {
|
|
5778
|
+
const meeting = requireMeeting("meet.meetingRule");
|
|
5779
|
+
return repository.meetingRule(meeting.id, key);
|
|
5780
|
+
},
|
|
5781
|
+
async setMeetingRule(key, value) {
|
|
5782
|
+
requireHostUser("meet.setMeetingRule");
|
|
5783
|
+
const meeting = requireMeeting("meet.setMeetingRule");
|
|
5784
|
+
const effective = await repository.setMeetingRule(meeting.id, key, value);
|
|
5785
|
+
hint();
|
|
5786
|
+
return effective;
|
|
5787
|
+
},
|
|
5739
5788
|
async setLock(locked) {
|
|
5740
5789
|
const by = requireHostUser("meet.setLock");
|
|
5741
5790
|
const meeting = requireMeeting("meet.setLock");
|
|
@@ -7127,7 +7176,7 @@ function createRoomEngine(options) {
|
|
|
7127
7176
|
const { secondDevice: _answered, ...rest } = lastRequest;
|
|
7128
7177
|
lastRequest = rest;
|
|
7129
7178
|
}
|
|
7130
|
-
options.tabClaim?.inRoom(String(request.roomName), String(token.identity));
|
|
7179
|
+
options.tabClaim?.inRoom(String(request.roomName), String(token.identity), token.secondDeviceRule ?? null);
|
|
7131
7180
|
current = token;
|
|
7132
7181
|
lastServerUrl = token.serverUrl;
|
|
7133
7182
|
connectionPolicy = token.connectionPolicy ?? DEFAULT_CONNECTION_POLICY;
|
|
@@ -7439,10 +7488,12 @@ function createRoomEngine(options) {
|
|
|
7439
7488
|
if (claim === void 0 || userId === null) return false;
|
|
7440
7489
|
const before = store.snapshot();
|
|
7441
7490
|
if (before.phase !== "prejoin" || before.secondDevice !== null) return false;
|
|
7442
|
-
|
|
7491
|
+
const person = `user:${String(userId)}`;
|
|
7492
|
+
const found = claim.presenceElsewhere !== void 0 ? await claim.presenceElsewhere(String(roomName), person) : await claim.presentElsewhere(String(roomName), person) ? { rule: null } : null;
|
|
7493
|
+
if (found === null || found.rule === "allow_both") return false;
|
|
7443
7494
|
const now2 = store.snapshot();
|
|
7444
7495
|
if (now2.phase !== "prejoin" || now2.secondDevice !== null) return false;
|
|
7445
|
-
store.patch({ secondDevice: { rule: "ask_switch_or_join" } });
|
|
7496
|
+
store.patch({ secondDevice: { rule: found.rule ?? "ask_switch_or_join" } });
|
|
7446
7497
|
report("info", "meet: this browser already has you in this meeting \u2014 offering the choice before Join");
|
|
7447
7498
|
return true;
|
|
7448
7499
|
},
|