@ai-matrx/meet 0.11.50 → 0.11.52
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/core.cjs +46 -5
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +7 -0
- package/dist/core.d.ts +7 -0
- package/dist/core.js +46 -5
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +46 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +46 -5
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +97 -31
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -0
- package/dist/react.d.ts +2 -0
- package/dist/react.js +97 -31
- package/dist/react.js.map +1 -1
- package/dist/skins/meet.cjs +51 -26
- package/dist/skins/meet.cjs.map +1 -1
- package/dist/skins/meet.js +51 -26
- package/dist/skins/meet.js.map +1 -1
- package/package.json +2 -2
package/dist/react.cjs
CHANGED
|
@@ -491,7 +491,8 @@ var DEFAULT_CONNECTION_POLICY = {
|
|
|
491
491
|
autoRejoin: true,
|
|
492
492
|
autoRejoinMaxAttempts: 5,
|
|
493
493
|
reconnectGraceSeconds: 30,
|
|
494
|
-
videoAutoOffAfterPoorSeconds: 20
|
|
494
|
+
videoAutoOffAfterPoorSeconds: 20,
|
|
495
|
+
captionsStartTimeoutSeconds: 20
|
|
495
496
|
};
|
|
496
497
|
function clampInt(value, min, max, fallback) {
|
|
497
498
|
if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
|
|
@@ -506,7 +507,8 @@ function connectionPolicyFrom(raw) {
|
|
|
506
507
|
autoRejoin: typeof row["auto_rejoin"] === "boolean" ? row["auto_rejoin"] : d.autoRejoin,
|
|
507
508
|
autoRejoinMaxAttempts: clampInt(row["auto_rejoin_max_attempts"], 0, 20, d.autoRejoinMaxAttempts),
|
|
508
509
|
reconnectGraceSeconds: clampInt(row["reconnect_grace_seconds"], 0, 600, d.reconnectGraceSeconds),
|
|
509
|
-
videoAutoOffAfterPoorSeconds: clampInt(row["video_auto_off_after_poor_seconds"], 0, 600, d.videoAutoOffAfterPoorSeconds)
|
|
510
|
+
videoAutoOffAfterPoorSeconds: clampInt(row["video_auto_off_after_poor_seconds"], 0, 600, d.videoAutoOffAfterPoorSeconds),
|
|
511
|
+
captionsStartTimeoutSeconds: clampInt(row["captions_start_timeout_seconds"], 1, 600, d.captionsStartTimeoutSeconds)
|
|
510
512
|
};
|
|
511
513
|
}
|
|
512
514
|
var LIVEKIT_BASE_DELAYS_MS = [0, 300, 1200, 2700, 4800, 7e3];
|
|
@@ -4357,6 +4359,7 @@ var EMPTY = {
|
|
|
4357
4359
|
noteTakerRefusal: null,
|
|
4358
4360
|
captionsOn: false,
|
|
4359
4361
|
captionsRefusal: null,
|
|
4362
|
+
captionsStartTimeoutSeconds: 20,
|
|
4360
4363
|
media: IDLE_MEDIA,
|
|
4361
4364
|
mediaRegion: IDLE_MEDIA_REGION,
|
|
4362
4365
|
failure: null,
|
|
@@ -6106,6 +6109,16 @@ var ALIVE_TOPIC = "mx.alive";
|
|
|
6106
6109
|
function encodeBeat(beat) {
|
|
6107
6110
|
return JSON.stringify({ q: beat.q, vp: beat.vp });
|
|
6108
6111
|
}
|
|
6112
|
+
function encodeBye() {
|
|
6113
|
+
return JSON.stringify({ bye: true });
|
|
6114
|
+
}
|
|
6115
|
+
function isBye(payload) {
|
|
6116
|
+
try {
|
|
6117
|
+
return JSON.parse(payload).bye === true;
|
|
6118
|
+
} catch {
|
|
6119
|
+
return false;
|
|
6120
|
+
}
|
|
6121
|
+
}
|
|
6109
6122
|
function decodeBeat(payload) {
|
|
6110
6123
|
try {
|
|
6111
6124
|
const raw = JSON.parse(payload);
|
|
@@ -6332,6 +6345,7 @@ function createRoomEngine(options) {
|
|
|
6332
6345
|
const autoOff = createVideoAutoOff(() => connectionPolicy.videoAutoOffAfterPoorSeconds * 1e3, now);
|
|
6333
6346
|
const lkQuality = /* @__PURE__ */ new Map();
|
|
6334
6347
|
let silent = /* @__PURE__ */ new Set();
|
|
6348
|
+
const saidBye = /* @__PURE__ */ new Set();
|
|
6335
6349
|
let healthTimer = null;
|
|
6336
6350
|
let lastBeatAt = 0;
|
|
6337
6351
|
let wasUnstable = false;
|
|
@@ -6362,6 +6376,7 @@ function createRoomEngine(options) {
|
|
|
6362
6376
|
assessor.reset();
|
|
6363
6377
|
autoOff.reset();
|
|
6364
6378
|
silent = /* @__PURE__ */ new Set();
|
|
6379
|
+
saidBye.clear();
|
|
6365
6380
|
lkQuality.clear();
|
|
6366
6381
|
lastBeatAt = 0;
|
|
6367
6382
|
wasUnstable = false;
|
|
@@ -6419,6 +6434,13 @@ function createRoomEngine(options) {
|
|
|
6419
6434
|
await target?.disconnect();
|
|
6420
6435
|
}
|
|
6421
6436
|
async function leaveRoom() {
|
|
6437
|
+
const target = driver;
|
|
6438
|
+
if (target !== null && store.snapshot().phase === "in_call") {
|
|
6439
|
+
await Promise.race([
|
|
6440
|
+
target.publishData(ALIVE_TOPIC, encodeBye()).catch(() => void 0),
|
|
6441
|
+
new Promise((resolve) => setTimeout(resolve, 300))
|
|
6442
|
+
]);
|
|
6443
|
+
}
|
|
6422
6444
|
store.dispatch({ type: "leave" });
|
|
6423
6445
|
await dropRoom();
|
|
6424
6446
|
options.onLeft?.(null);
|
|
@@ -6514,8 +6536,6 @@ function createRoomEngine(options) {
|
|
|
6514
6536
|
},
|
|
6515
6537
|
participantLeft(who, reason) {
|
|
6516
6538
|
departures.set(who, reason);
|
|
6517
|
-
liveness.forget(who);
|
|
6518
|
-
silent.delete(who);
|
|
6519
6539
|
},
|
|
6520
6540
|
roomMetadata(metadata) {
|
|
6521
6541
|
let parsed = {};
|
|
@@ -6558,8 +6578,12 @@ function createRoomEngine(options) {
|
|
|
6558
6578
|
const snap = store.snapshot();
|
|
6559
6579
|
if (snap.phase !== "in_call" || snap.connection !== "stable") return;
|
|
6560
6580
|
startHealth();
|
|
6581
|
+
const before = assessor.current();
|
|
6561
6582
|
const quality = assessor.push(reading);
|
|
6562
6583
|
const path = pathOf(reading);
|
|
6584
|
+
if (quality !== before) {
|
|
6585
|
+
report("info", `meet: this connection reads ${quality} (round trip ${reading.rttMs ?? "?"} ms, path ${path})`, "Diagnostic only.");
|
|
6586
|
+
}
|
|
6563
6587
|
patchLocalNetwork({ quality, ...path !== "unknown" ? { path } : {} });
|
|
6564
6588
|
refreshQualities();
|
|
6565
6589
|
const cameraOn = snap.media.camera.enabled;
|
|
@@ -6574,6 +6598,11 @@ function createRoomEngine(options) {
|
|
|
6574
6598
|
connectionState(state) {
|
|
6575
6599
|
supervisor.driverState(state);
|
|
6576
6600
|
if (state === "connected" && store.snapshot().phase === "joining") store.dispatch({ type: "connected" });
|
|
6601
|
+
if (state === "connected") {
|
|
6602
|
+
startHealth();
|
|
6603
|
+
lastBeatAt = 0;
|
|
6604
|
+
healthTick();
|
|
6605
|
+
}
|
|
6577
6606
|
},
|
|
6578
6607
|
transcription(event) {
|
|
6579
6608
|
const snapshot = store.snapshot();
|
|
@@ -6665,6 +6694,10 @@ function createRoomEngine(options) {
|
|
|
6665
6694
|
}
|
|
6666
6695
|
const sender = personOf(from ?? "");
|
|
6667
6696
|
if (from !== null) {
|
|
6697
|
+
if (topic === ALIVE_TOPIC && isBye(payload)) {
|
|
6698
|
+
saidBye.add(from);
|
|
6699
|
+
return;
|
|
6700
|
+
}
|
|
6668
6701
|
const beat = topic === ALIVE_TOPIC ? decodeBeat(payload) : null;
|
|
6669
6702
|
const before = liveness.reported(from);
|
|
6670
6703
|
liveness.heard(from, beat);
|
|
@@ -6779,6 +6812,7 @@ function createRoomEngine(options) {
|
|
|
6779
6812
|
current = token;
|
|
6780
6813
|
lastServerUrl = token.serverUrl;
|
|
6781
6814
|
connectionPolicy = token.connectionPolicy ?? DEFAULT_CONNECTION_POLICY;
|
|
6815
|
+
store.patch({ captionsStartTimeoutSeconds: connectionPolicy.captionsStartTimeoutSeconds });
|
|
6782
6816
|
if (token.leavePolicy !== void 0) store.patch({ leavePolicy: token.leavePolicy });
|
|
6783
6817
|
store.patch({ canReclaim: token.canReclaim === true });
|
|
6784
6818
|
store.patch({
|
|
@@ -6896,10 +6930,17 @@ function createRoomEngine(options) {
|
|
|
6896
6930
|
const graceMs = connectionPolicy.reconnectGraceSeconds * 1e3;
|
|
6897
6931
|
for (const [who, reason] of departures) {
|
|
6898
6932
|
const last = previous.get(who);
|
|
6899
|
-
|
|
6933
|
+
const dropped = !saidBye.has(who) && (isUnannouncedDeparture(reason) || silent.has(who));
|
|
6934
|
+
report("info", `meet: ${who} left the room (${reason ?? "no reason"}${dropped ? ", held as reconnecting" : ""})`, "Diagnostic only.");
|
|
6935
|
+
if (last !== void 0 && !last.isLocal && !present.has(who) && graceMs > 0 && dropped) {
|
|
6900
6936
|
ghosts.set(who, { participant: last, until: at + graceMs });
|
|
6901
6937
|
}
|
|
6902
6938
|
}
|
|
6939
|
+
for (const who of departures.keys()) {
|
|
6940
|
+
liveness.forget(who);
|
|
6941
|
+
silent.delete(who);
|
|
6942
|
+
saidBye.delete(who);
|
|
6943
|
+
}
|
|
6903
6944
|
departures.clear();
|
|
6904
6945
|
liveRoster = list;
|
|
6905
6946
|
const localNow = list.find((p) => p.isLocal);
|
|
@@ -9226,6 +9267,22 @@ function createMeetingRecordCache(options = {}) {
|
|
|
9226
9267
|
};
|
|
9227
9268
|
}
|
|
9228
9269
|
|
|
9270
|
+
// src/core/captions-state.ts
|
|
9271
|
+
var CAPTIONS_TIMEOUT_REASON = "Captions are unavailable right now.";
|
|
9272
|
+
function resolveCaptionsState(i) {
|
|
9273
|
+
if (!i.on) return { state: "off", reason: null, remedy: null };
|
|
9274
|
+
if (i.takerState === "transcribing" && i.takerPresent) return { state: "live", reason: null, remedy: null };
|
|
9275
|
+
if (i.takerState === "joining" && !i.timedOut) return { state: "starting", reason: null, remedy: null };
|
|
9276
|
+
if (i.refusal !== null && i.refusal.reason.length > 0) {
|
|
9277
|
+
return { state: "unavailable", reason: i.refusal.reason, remedy: i.refusal.remedy.length > 0 ? i.refusal.remedy : null };
|
|
9278
|
+
}
|
|
9279
|
+
if (i.takerState === "ended" || i.takerState === "handoff_pending") {
|
|
9280
|
+
return { state: "unavailable", reason: i.takerLabel, remedy: null };
|
|
9281
|
+
}
|
|
9282
|
+
if (i.timedOut) return { state: "unavailable", reason: CAPTIONS_TIMEOUT_REASON, remedy: null };
|
|
9283
|
+
return { state: "starting", reason: null, remedy: null };
|
|
9284
|
+
}
|
|
9285
|
+
|
|
9229
9286
|
// src/core/layout.ts
|
|
9230
9287
|
var DEFAULT_PAGE_SIZE = 12;
|
|
9231
9288
|
function orderParticipants(participants, activeSpeakers) {
|
|
@@ -9316,7 +9373,8 @@ function useRoom() {
|
|
|
9316
9373
|
local,
|
|
9317
9374
|
// An observer (role `viewer`) publishes nothing: no Share screen to press and be refused (MD-16).
|
|
9318
9375
|
sharingAllowed: snapshot === null || canShareUnder(snapshot.livePolicy, effectiveRole(snapshot), effectiveStanding(snapshot)),
|
|
9319
|
-
canShareScreen: (engine?.supportsScreenShare() ?? true) && !isObserverRole(snapshot?.grants.role ?? null) &&
|
|
9376
|
+
canShareScreen: (engine?.supportsScreenShare() ?? true) && !isObserverRole(snapshot?.grants.role ?? null) && // The server's word that sharing was taken away arrives before the rules refresh does: the control goes at once.
|
|
9377
|
+
!(snapshot?.share.state === "ended" && snapshot.share.reason === "not_allowed") && (snapshot === null || canShareUnder(snapshot.livePolicy, effectiveRole(snapshot), effectiveStanding(snapshot))),
|
|
9320
9378
|
otherPresenter: otherPresenterOf(snapshot),
|
|
9321
9379
|
join: (0, import_react4.useCallback)(
|
|
9322
9380
|
async (request) => requireEngine(engine, "join").join(request),
|
|
@@ -9713,32 +9771,37 @@ function useCaptions() {
|
|
|
9713
9771
|
if (host === null || meeting === null) return;
|
|
9714
9772
|
void host.ai.requestCaptions({ meetingId: meeting.id });
|
|
9715
9773
|
}, [host, meeting]);
|
|
9774
|
+
const [timedOut, setTimedOut] = (0, import_react4.useState)(false);
|
|
9775
|
+
const timeoutSeconds = snapshot?.captionsStartTimeoutSeconds ?? 20;
|
|
9776
|
+
const live = taker.state === "transcribing" && taker.present;
|
|
9777
|
+
const [attempt, setAttempt] = (0, import_react4.useState)(0);
|
|
9778
|
+
(0, import_react4.useEffect)(() => {
|
|
9779
|
+
setTimedOut(false);
|
|
9780
|
+
if (!on || live) return void 0;
|
|
9781
|
+
const id = setTimeout(() => setTimedOut(true), timeoutSeconds * 1e3);
|
|
9782
|
+
return () => clearTimeout(id);
|
|
9783
|
+
}, [on, live, timeoutSeconds, attempt]);
|
|
9716
9784
|
const toggle = (0, import_react4.useCallback)(() => {
|
|
9717
9785
|
if (host === null) return;
|
|
9718
9786
|
const next = !on;
|
|
9719
9787
|
host.store.patch({ captionsOn: next, captionsRefusal: null });
|
|
9720
9788
|
if (next && taker.state !== "joining" && taker.state !== "transcribing") request();
|
|
9721
9789
|
}, [host, on, taker.state, request]);
|
|
9722
|
-
|
|
9723
|
-
|
|
9724
|
-
|
|
9725
|
-
|
|
9726
|
-
|
|
9727
|
-
|
|
9728
|
-
|
|
9729
|
-
|
|
9730
|
-
|
|
9731
|
-
|
|
9732
|
-
|
|
9733
|
-
|
|
9734
|
-
|
|
9735
|
-
|
|
9736
|
-
|
|
9737
|
-
} else {
|
|
9738
|
-
state = "starting";
|
|
9739
|
-
}
|
|
9740
|
-
}
|
|
9741
|
-
return { on, state, reason, remedy, toggle };
|
|
9790
|
+
const retry = (0, import_react4.useCallback)(() => {
|
|
9791
|
+
if (host === null) return;
|
|
9792
|
+
host.store.patch({ captionsOn: true, captionsRefusal: null });
|
|
9793
|
+
setAttempt((n) => n + 1);
|
|
9794
|
+
request();
|
|
9795
|
+
}, [host, request]);
|
|
9796
|
+
const view = resolveCaptionsState({
|
|
9797
|
+
on,
|
|
9798
|
+
takerState: taker.state,
|
|
9799
|
+
takerPresent: taker.present,
|
|
9800
|
+
refusal: refusal2,
|
|
9801
|
+
takerLabel: on ? noteTakerLabel(taker) : "",
|
|
9802
|
+
timedOut
|
|
9803
|
+
});
|
|
9804
|
+
return { on, state: view.state, reason: view.reason, remedy: view.remedy, toggle, retry };
|
|
9742
9805
|
}
|
|
9743
9806
|
function useEndMeeting() {
|
|
9744
9807
|
const host = useMeetHost();
|
|
@@ -14257,11 +14320,14 @@ function Captions({ lines = 3 }) {
|
|
|
14257
14320
|
const captions = useCaptions();
|
|
14258
14321
|
if (!captions.on) return null;
|
|
14259
14322
|
if (captions.state === "unavailable") {
|
|
14260
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.
|
|
14261
|
-
|
|
14262
|
-
|
|
14263
|
-
|
|
14264
|
-
|
|
14323
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mx-meet__captions", role: "status", "data-meet-notice": "captions-unavailable", children: [
|
|
14324
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "mx-meet__caption", children: [
|
|
14325
|
+
(captions.reason ?? "").startsWith("Captions are unavailable") ? "" : "Captions are unavailable. ",
|
|
14326
|
+
captions.reason,
|
|
14327
|
+
captions.remedy !== null ? ` ${captions.remedy}` : ""
|
|
14328
|
+
] }),
|
|
14329
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__caption-retry", onClick: captions.retry, children: "Try again" })
|
|
14330
|
+
] });
|
|
14265
14331
|
}
|
|
14266
14332
|
if (visible.length === 0) {
|
|
14267
14333
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", "data-meet-caption": captions.state, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mx-meet__caption mx-meet__caption--interim", children: captions.state === "starting" ? "Starting captions. They appear as people speak." : "Captions are on. They appear as people speak." }) });
|