@ai-matrx/meet 0.11.51 → 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/dist/core.js CHANGED
@@ -4612,6 +4612,16 @@ var ALIVE_TOPIC = "mx.alive";
4612
4612
  function encodeBeat(beat) {
4613
4613
  return JSON.stringify({ q: beat.q, vp: beat.vp });
4614
4614
  }
4615
+ function encodeBye() {
4616
+ return JSON.stringify({ bye: true });
4617
+ }
4618
+ function isBye(payload) {
4619
+ try {
4620
+ return JSON.parse(payload).bye === true;
4621
+ } catch {
4622
+ return false;
4623
+ }
4624
+ }
4615
4625
  function decodeBeat(payload) {
4616
4626
  try {
4617
4627
  const raw = JSON.parse(payload);
@@ -6861,6 +6871,7 @@ function createRoomEngine(options) {
6861
6871
  const autoOff = createVideoAutoOff(() => connectionPolicy.videoAutoOffAfterPoorSeconds * 1e3, now);
6862
6872
  const lkQuality = /* @__PURE__ */ new Map();
6863
6873
  let silent = /* @__PURE__ */ new Set();
6874
+ const saidBye = /* @__PURE__ */ new Set();
6864
6875
  let healthTimer = null;
6865
6876
  let lastBeatAt = 0;
6866
6877
  let wasUnstable = false;
@@ -6891,6 +6902,7 @@ function createRoomEngine(options) {
6891
6902
  assessor.reset();
6892
6903
  autoOff.reset();
6893
6904
  silent = /* @__PURE__ */ new Set();
6905
+ saidBye.clear();
6894
6906
  lkQuality.clear();
6895
6907
  lastBeatAt = 0;
6896
6908
  wasUnstable = false;
@@ -6948,6 +6960,13 @@ function createRoomEngine(options) {
6948
6960
  await target?.disconnect();
6949
6961
  }
6950
6962
  async function leaveRoom() {
6963
+ const target = driver;
6964
+ if (target !== null && store.snapshot().phase === "in_call") {
6965
+ await Promise.race([
6966
+ target.publishData(ALIVE_TOPIC, encodeBye()).catch(() => void 0),
6967
+ new Promise((resolve) => setTimeout(resolve, 300))
6968
+ ]);
6969
+ }
6951
6970
  store.dispatch({ type: "leave" });
6952
6971
  await dropRoom();
6953
6972
  options.onLeft?.(null);
@@ -7043,8 +7062,6 @@ function createRoomEngine(options) {
7043
7062
  },
7044
7063
  participantLeft(who, reason) {
7045
7064
  departures.set(who, reason);
7046
- liveness.forget(who);
7047
- silent.delete(who);
7048
7065
  },
7049
7066
  roomMetadata(metadata) {
7050
7067
  let parsed = {};
@@ -7087,8 +7104,12 @@ function createRoomEngine(options) {
7087
7104
  const snap = store.snapshot();
7088
7105
  if (snap.phase !== "in_call" || snap.connection !== "stable") return;
7089
7106
  startHealth();
7107
+ const before = assessor.current();
7090
7108
  const quality = assessor.push(reading);
7091
7109
  const path = pathOf(reading);
7110
+ if (quality !== before) {
7111
+ report("info", `meet: this connection reads ${quality} (round trip ${reading.rttMs ?? "?"} ms, path ${path})`, "Diagnostic only.");
7112
+ }
7092
7113
  patchLocalNetwork({ quality, ...path !== "unknown" ? { path } : {} });
7093
7114
  refreshQualities();
7094
7115
  const cameraOn = snap.media.camera.enabled;
@@ -7103,6 +7124,11 @@ function createRoomEngine(options) {
7103
7124
  connectionState(state) {
7104
7125
  supervisor.driverState(state);
7105
7126
  if (state === "connected" && store.snapshot().phase === "joining") store.dispatch({ type: "connected" });
7127
+ if (state === "connected") {
7128
+ startHealth();
7129
+ lastBeatAt = 0;
7130
+ healthTick();
7131
+ }
7106
7132
  },
7107
7133
  transcription(event) {
7108
7134
  const snapshot = store.snapshot();
@@ -7194,6 +7220,10 @@ function createRoomEngine(options) {
7194
7220
  }
7195
7221
  const sender = personOf(from ?? "");
7196
7222
  if (from !== null) {
7223
+ if (topic === ALIVE_TOPIC && isBye(payload)) {
7224
+ saidBye.add(from);
7225
+ return;
7226
+ }
7197
7227
  const beat = topic === ALIVE_TOPIC ? decodeBeat(payload) : null;
7198
7228
  const before = liveness.reported(from);
7199
7229
  liveness.heard(from, beat);
@@ -7426,10 +7456,17 @@ function createRoomEngine(options) {
7426
7456
  const graceMs = connectionPolicy.reconnectGraceSeconds * 1e3;
7427
7457
  for (const [who, reason] of departures) {
7428
7458
  const last = previous.get(who);
7429
- if (last !== void 0 && !last.isLocal && !present.has(who) && graceMs > 0 && isUnannouncedDeparture(reason)) {
7459
+ const dropped = !saidBye.has(who) && (isUnannouncedDeparture(reason) || silent.has(who));
7460
+ report("info", `meet: ${who} left the room (${reason ?? "no reason"}${dropped ? ", held as reconnecting" : ""})`, "Diagnostic only.");
7461
+ if (last !== void 0 && !last.isLocal && !present.has(who) && graceMs > 0 && dropped) {
7430
7462
  ghosts.set(who, { participant: last, until: at + graceMs });
7431
7463
  }
7432
7464
  }
7465
+ for (const who of departures.keys()) {
7466
+ liveness.forget(who);
7467
+ silent.delete(who);
7468
+ saidBye.delete(who);
7469
+ }
7433
7470
  departures.clear();
7434
7471
  liveRoster = list;
7435
7472
  const localNow = list.find((p) => p.isLocal);