@ai-matrx/meet 0.11.53 → 0.11.55

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog — `@ai-matrx/meet`
2
2
 
3
+ ## 0.11.55
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/meet/v0.11.54..npm/meet/v0.11.55 -- apps/shared/meet`).
7
+ No source changes intended and no consumer action required.
8
+
9
+ ## 0.11.54
10
+
11
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
12
+ `git diff npm/meet/v0.11.53..npm/meet/v0.11.54 -- apps/shared/meet`).
13
+ No source changes intended and no consumer action required.
14
+
3
15
  ## 0.11.53
4
16
 
5
17
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/dist/core.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
  };
@@ -5173,14 +5194,22 @@ function createLiveKitDriver(handlers, options = {}) {
5173
5194
  ...options.roomOptions
5174
5195
  });
5175
5196
  const reasonName = (reason) => reason === void 0 || reason === null ? null : module2.DisconnectReason?.[reason] ?? String(reason);
5176
- const roster = () => {
5197
+ const emitRoster = () => {
5198
+ rosterQueued = false;
5199
+ if (room !== created) return;
5177
5200
  const local = snapshotParticipant(created.localParticipant, true);
5178
5201
  const remotes = [...created.remoteParticipants.values()].map(
5179
5202
  (participant) => snapshotParticipant(participant, false)
5180
5203
  );
5181
5204
  handlers.participants([local, ...remotes]);
5182
5205
  };
5183
- projectRoster = roster;
5206
+ let rosterQueued = false;
5207
+ const roster = () => {
5208
+ if (rosterQueued) return;
5209
+ rosterQueued = true;
5210
+ queueMicrotask(emitRoster);
5211
+ };
5212
+ projectRoster = emitRoster;
5184
5213
  created.on(RoomEvent.TrackSubscribed, (track) => {
5185
5214
  if (track.kind !== Track.Kind.Audio || typeof document === "undefined") return;
5186
5215
  if (!remoteAudioPlayback) return;
@@ -7750,6 +7779,13 @@ function createRoomEngine(options) {
7750
7779
  const previous = new Map(liveRoster.map((p) => [p.identity, p]));
7751
7780
  const present = new Set(list.map((p) => p.identity));
7752
7781
  const graceMs = connectionPolicy.reconnectGraceSeconds * 1e3;
7782
+ if (store.snapshot().phase === "in_call") {
7783
+ for (const [who, last] of previous) {
7784
+ if (last.isLocal || present.has(who) || departures.has(who)) continue;
7785
+ departures.set(who, null);
7786
+ 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.");
7787
+ }
7788
+ }
7753
7789
  for (const [who, reason] of departures) {
7754
7790
  const last = previous.get(who);
7755
7791
  const dropped = !saidBye.has(who) && (isUnannouncedDeparture(reason) || silent.has(who));
@@ -7765,6 +7801,9 @@ function createRoomEngine(options) {
7765
7801
  }
7766
7802
  departures.clear();
7767
7803
  liveRoster = list;
7804
+ for (const p of list) {
7805
+ if (!p.isLocal && (isGuestIdentity(p.identity) || userIdOfIdentity(p.identity) !== null)) liveness.expect(p.identity);
7806
+ }
7768
7807
  const localNow = list.find((p) => p.isLocal);
7769
7808
  if (localNow !== void 0 && !localNow.screenSharing && store.snapshot().share.state === "presenting") {
7770
7809
  store.patch({ share: NO_SHARE });
@@ -7785,7 +7824,7 @@ function createRoomEngine(options) {
7785
7824
  store.setParticipants(
7786
7825
  [...people.values()].map(({ entry }) => {
7787
7826
  const projected = projectParticipant(entry, joinedAt);
7788
- if (entry.reconnecting === true || !entry.isLocal && silent.has(entry.identity)) {
7827
+ if (entry.reconnecting === true || !entry.isLocal && silent.has(entry.identity) && !saidBye.has(entry.identity)) {
7789
7828
  return { ...projected, reconnecting: true, quality: "lost" };
7790
7829
  }
7791
7830
  const videoPaused = entry.isLocal ? store.snapshot().localNetwork.videoPaused : liveness.reported(entry.identity)?.vp === true;