@ai-matrx/meet 0.11.53 → 0.11.54

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/index.cjs CHANGED
@@ -3617,6 +3617,10 @@ function personOf(identity) {
3617
3617
  const cut = value.indexOf(CONNECTION_SEPARATOR);
3618
3618
  return cut === -1 ? value : value.slice(0, cut);
3619
3619
  }
3620
+ function userIdOfIdentity(identity) {
3621
+ const person = personOf(identity);
3622
+ return person.startsWith("user:") ? person.slice("user:".length) : null;
3623
+ }
3620
3624
  function isGuestIdentity(identity) {
3621
3625
  return personOf(identity).startsWith("guest:");
3622
3626
  }
@@ -4922,21 +4926,35 @@ function heartbeatIntervalMs(roomSize) {
4922
4926
  function staleAfterMs(roomSize) {
4923
4927
  return heartbeatIntervalMs(roomSize) * 3 + 1e3;
4924
4928
  }
4929
+ function firstBeatAllowanceMs(roomSize) {
4930
+ return staleAfterMs(roomSize) * 2;
4931
+ }
4925
4932
  function createLivenessTracker(now) {
4926
4933
  const lastHeard = /* @__PURE__ */ new Map();
4934
+ const firstSeen = /* @__PURE__ */ new Map();
4927
4935
  const beats = /* @__PURE__ */ new Map();
4928
4936
  return {
4929
4937
  heard(who, beat) {
4930
4938
  lastHeard.set(who, now());
4939
+ firstSeen.delete(who);
4931
4940
  if (beat !== null) beats.set(who, beat);
4932
4941
  },
4942
+ expect(who) {
4943
+ if (!lastHeard.has(who) && !firstSeen.has(who)) firstSeen.set(who, now());
4944
+ },
4933
4945
  stale(present, roomSize) {
4934
4946
  const limit = staleAfterMs(roomSize);
4947
+ const firstLimit = firstBeatAllowanceMs(roomSize);
4935
4948
  const at = now();
4936
4949
  const out = /* @__PURE__ */ new Set();
4937
4950
  for (const who of present) {
4938
4951
  const heard = lastHeard.get(who);
4939
- if (heard !== void 0 && at - heard > limit) out.add(who);
4952
+ if (heard !== void 0) {
4953
+ if (at - heard > limit) out.add(who);
4954
+ continue;
4955
+ }
4956
+ const seen = firstSeen.get(who);
4957
+ if (seen !== void 0 && at - seen > firstLimit) out.add(who);
4940
4958
  }
4941
4959
  return out;
4942
4960
  },
@@ -4944,13 +4962,16 @@ function createLivenessTracker(now) {
4944
4962
  restartClock() {
4945
4963
  const at = now();
4946
4964
  for (const who of lastHeard.keys()) lastHeard.set(who, at);
4965
+ for (const who of firstSeen.keys()) firstSeen.set(who, at);
4947
4966
  },
4948
4967
  forget(who) {
4949
4968
  lastHeard.delete(who);
4969
+ firstSeen.delete(who);
4950
4970
  beats.delete(who);
4951
4971
  },
4952
4972
  clear() {
4953
4973
  lastHeard.clear();
4974
+ firstSeen.clear();
4954
4975
  beats.clear();
4955
4976
  }
4956
4977
  };
@@ -7750,6 +7771,13 @@ function createRoomEngine(options) {
7750
7771
  const previous = new Map(liveRoster.map((p) => [p.identity, p]));
7751
7772
  const present = new Set(list.map((p) => p.identity));
7752
7773
  const graceMs = connectionPolicy.reconnectGraceSeconds * 1e3;
7774
+ if (store.snapshot().phase === "in_call") {
7775
+ for (const [who, last] of previous) {
7776
+ if (last.isLocal || present.has(who) || departures.has(who)) continue;
7777
+ departures.set(who, null);
7778
+ report("warn", `meet: ${who} vanished from the room's roster with no departure event; held as reconnecting`, "The media layer dropped a participant silently; the tile is kept for the reconnect grace.");
7779
+ }
7780
+ }
7753
7781
  for (const [who, reason] of departures) {
7754
7782
  const last = previous.get(who);
7755
7783
  const dropped = !saidBye.has(who) && (isUnannouncedDeparture(reason) || silent.has(who));
@@ -7765,6 +7793,9 @@ function createRoomEngine(options) {
7765
7793
  }
7766
7794
  departures.clear();
7767
7795
  liveRoster = list;
7796
+ for (const p of list) {
7797
+ if (!p.isLocal && (isGuestIdentity(p.identity) || userIdOfIdentity(p.identity) !== null)) liveness.expect(p.identity);
7798
+ }
7768
7799
  const localNow = list.find((p) => p.isLocal);
7769
7800
  if (localNow !== void 0 && !localNow.screenSharing && store.snapshot().share.state === "presenting") {
7770
7801
  store.patch({ share: NO_SHARE });
@@ -7785,7 +7816,7 @@ function createRoomEngine(options) {
7785
7816
  store.setParticipants(
7786
7817
  [...people.values()].map(({ entry }) => {
7787
7818
  const projected = projectParticipant(entry, joinedAt);
7788
- if (entry.reconnecting === true || !entry.isLocal && silent.has(entry.identity)) {
7819
+ if (entry.reconnecting === true || !entry.isLocal && silent.has(entry.identity) && !saidBye.has(entry.identity)) {
7789
7820
  return { ...projected, reconnecting: true, quality: "lost" };
7790
7821
  }
7791
7822
  const videoPaused = entry.isLocal ? store.snapshot().localNetwork.videoPaused : liveness.reported(entry.identity)?.vp === true;