@ai-matrx/meet 0.11.49 → 0.11.51

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.51
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/meet/v0.11.50..npm/meet/v0.11.51 -- apps/shared/meet`).
7
+ No source changes intended and no consumer action required.
8
+
9
+ ## 0.11.50
10
+
11
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
12
+ `git diff npm/meet/v0.11.49..npm/meet/v0.11.50 -- apps/shared/meet`).
13
+ No source changes intended and no consumer action required.
14
+
3
15
  ## 0.11.49
4
16
 
5
17
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/dist/core.cjs CHANGED
@@ -500,7 +500,8 @@ var DEFAULT_CONNECTION_POLICY = {
500
500
  autoRejoin: true,
501
501
  autoRejoinMaxAttempts: 5,
502
502
  reconnectGraceSeconds: 30,
503
- videoAutoOffAfterPoorSeconds: 20
503
+ videoAutoOffAfterPoorSeconds: 20,
504
+ captionsStartTimeoutSeconds: 20
504
505
  };
505
506
  function clampInt(value, min, max, fallback) {
506
507
  if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
@@ -515,7 +516,8 @@ function connectionPolicyFrom(raw) {
515
516
  autoRejoin: typeof row["auto_rejoin"] === "boolean" ? row["auto_rejoin"] : d.autoRejoin,
516
517
  autoRejoinMaxAttempts: clampInt(row["auto_rejoin_max_attempts"], 0, 20, d.autoRejoinMaxAttempts),
517
518
  reconnectGraceSeconds: clampInt(row["reconnect_grace_seconds"], 0, 600, d.reconnectGraceSeconds),
518
- videoAutoOffAfterPoorSeconds: clampInt(row["video_auto_off_after_poor_seconds"], 0, 600, d.videoAutoOffAfterPoorSeconds)
519
+ videoAutoOffAfterPoorSeconds: clampInt(row["video_auto_off_after_poor_seconds"], 0, 600, d.videoAutoOffAfterPoorSeconds),
520
+ captionsStartTimeoutSeconds: clampInt(row["captions_start_timeout_seconds"], 1, 600, d.captionsStartTimeoutSeconds)
519
521
  };
520
522
  }
521
523
  var LIVEKIT_BASE_DELAYS_MS = [0, 300, 1200, 2700, 4800, 7e3];
@@ -3927,6 +3929,7 @@ var EMPTY = {
3927
3929
  noteTakerRefusal: null,
3928
3930
  captionsOn: false,
3929
3931
  captionsRefusal: null,
3932
+ captionsStartTimeoutSeconds: 20,
3930
3933
  media: IDLE_MEDIA,
3931
3934
  mediaRegion: IDLE_MEDIA_REGION,
3932
3935
  failure: null,
@@ -4362,11 +4365,10 @@ function moderationText(kind, payload) {
4362
4365
  switch (kind) {
4363
4366
  case "muted": {
4364
4367
  const source = text2(payload["source"]) ?? "microphone";
4365
- const who = payload["by_role"] === "host" || payload["by_role"] === "cohost" ? "the host" : by;
4366
- return source === "microphone" ? `You've been muted by ${who}.` : source === "camera" ? `Your camera was turned off by ${who}.` : `Your screen share was stopped by ${who}.`;
4368
+ return source === "microphone" ? `${by} muted you.` : source === "camera" ? `${by} turned off your camera.` : `${by} stopped your screen share.`;
4367
4369
  }
4368
4370
  case "ask-unmute":
4369
- return `${by === "The host" ? "The host" : by} asked you to unmute.`;
4371
+ return `${by} is asking you to unmute.`;
4370
4372
  case "removed":
4371
4373
  return `${by} removed you from this meeting.`;
4372
4374
  default:
@@ -4392,7 +4394,7 @@ function applyModeration(store, payload, now) {
4392
4394
  grants: { ...snapshot.grants, role },
4393
4395
  moderationNotice: {
4394
4396
  kind: "role",
4395
- text: role === "host" ? "You are now the host." : role === "cohost" ? "You're now a co-host." : role === "presenter" ? "You're now a presenter." : snapshot.grants.role === "presenter" ? "You're now a participant: you can no longer present." : "You're now a participant: you are no longer a co-host.",
4397
+ text: role === "host" ? "You are now the host." : role === "cohost" ? "You are now a co-host." : role === "presenter" ? "You are now a presenter." : snapshot.grants.role === "presenter" ? "You are now a participant: you can no longer present." : "You are no longer a co-host.",
4396
4398
  at: now()
4397
4399
  }
4398
4400
  });
@@ -5652,7 +5654,10 @@ function createMeetingSession(options) {
5652
5654
  const meeting = store.snapshot().meeting;
5653
5655
  const pass = options.resolvePass?.() ?? null;
5654
5656
  if (meeting === null || pass === null) return;
5655
- if (policyReading) return policyInFlight ?? void 0;
5657
+ if (policyReading) {
5658
+ await (policyInFlight ?? void 0);
5659
+ return readLivePolicy();
5660
+ }
5656
5661
  policyReading = true;
5657
5662
  let done = () => void 0;
5658
5663
  policyInFlight = new Promise((resolve) => done = resolve);
@@ -5673,6 +5678,9 @@ function createMeetingSession(options) {
5673
5678
  if (!samePolicy(snapshot.livePolicy, next) || startedAt !== snapshot.sessionStartedAt) {
5674
5679
  store.patch({ livePolicy: next, sessionStartedAt: startedAt });
5675
5680
  }
5681
+ if (read.consent_given === true && !store.snapshot().recordingConsentGiven) {
5682
+ store.patch({ recordingConsentGiven: true });
5683
+ }
5676
5684
  } catch {
5677
5685
  } finally {
5678
5686
  policyReading = false;
@@ -5977,6 +5985,21 @@ function createMeetingSession(options) {
5977
5985
  stopWaiting,
5978
5986
  readState: readState2,
5979
5987
  readLivePolicy,
5988
+ async acknowledgeConsent() {
5989
+ const meeting = requireMeeting("meet.consent");
5990
+ const pass = options.resolvePass?.() ?? null;
5991
+ const response = await options.api.request({
5992
+ path: MEET_ROUTES.consent,
5993
+ method: "POST",
5994
+ requireAuth: false,
5995
+ operation: "meet.consent",
5996
+ body: { meeting_id: meeting.id },
5997
+ ...pass !== null ? { headers: { [MEETING_PASS_HEADER]: pass } } : {}
5998
+ });
5999
+ if (!response.ok) {
6000
+ throw new MeetError("transport", `meet.consent: the server answered ${response.status}`, "Your agreement was not saved. Try again.");
6001
+ }
6002
+ },
5980
6003
  async readExit(connection, held) {
5981
6004
  const meeting = store.snapshot().meeting;
5982
6005
  const pass = held ?? options.resolvePass?.() ?? null;
@@ -6848,7 +6871,9 @@ function createMediaSupervisor(options) {
6848
6871
  const deviceKind = INPUT_KIND[kind];
6849
6872
  const previous = inUse[deviceKind];
6850
6873
  const track = store.snapshot().media[kind];
6851
- const gone = previous !== null && !isAlias(previous) && before[deviceKind].has(previous) && !now[deviceKind].has(previous);
6874
+ const aliasLabel = previous !== null && isAlias(previous) ? before[deviceKind].get(previous) : void 0;
6875
+ const aliasGone = previous !== null && aliasLabel !== void 0 && aliasLabel !== "" && (!now[deviceKind].has(previous) || now[deviceKind].get(previous) !== aliasLabel);
6876
+ const gone = aliasGone || previous !== null && !isAlias(previous) && before[deviceKind].has(previous) && !now[deviceKind].has(previous);
6852
6877
  if (gone) {
6853
6878
  const from = before[deviceKind].get(previous) ?? "";
6854
6879
  const remaining = [...now[deviceKind].entries()].filter(([id]) => !isAlias(id));
@@ -6873,7 +6898,7 @@ function createMediaSupervisor(options) {
6873
6898
  await driver.setCameraEnabled(true);
6874
6899
  store.setLocalTrack("camera", { enabled: true, unavailable: null });
6875
6900
  }
6876
- setRegion({ notice: { id: ++noticeId, kind, outcome: "switched", from, to: nextLabel } });
6901
+ setRegion({ notice: { id: ++noticeId, kind, outcome: "switched", from, fromId: previous, to: nextLabel } });
6877
6902
  } catch (error) {
6878
6903
  const refused = await unavailable(error, "camera", "meet.camera(fallback)");
6879
6904
  store.setLocalTrack("camera", { enabled: false, unavailable: refused });
@@ -6881,8 +6906,24 @@ function createMediaSupervisor(options) {
6881
6906
  }
6882
6907
  } else {
6883
6908
  const active = driver.activeDevices().audioinput;
6884
- const to = (active !== null ? now.audioinput.get(active) : void 0) ?? now.audioinput.get("default") ?? remaining[0][1];
6885
- setRegion({ notice: { id: ++noticeId, kind, outcome: "switched", from, to } });
6909
+ let to = (active !== null && !aliasGone ? now.audioinput.get(active) : void 0) ?? now.audioinput.get("default");
6910
+ if (to === void 0 || aliasGone) {
6911
+ const [nextId, nextLabel] = remaining[0];
6912
+ try {
6913
+ await driver.switchDevice("audioinput", nextId);
6914
+ if (track.enabled || track.unavailable !== null) {
6915
+ await driver.setMicrophoneEnabled(true);
6916
+ store.setLocalTrack("microphone", { enabled: true, unavailable: null });
6917
+ }
6918
+ to = nextLabel;
6919
+ } catch (error) {
6920
+ const refused = await unavailable(error, "microphone", "meet.microphone(fallback)");
6921
+ store.setLocalTrack("microphone", { enabled: false, unavailable: refused });
6922
+ setRegion({ notice: { id: ++noticeId, kind, outcome: "lost", from, to: null } });
6923
+ continue;
6924
+ }
6925
+ }
6926
+ setRegion({ notice: { id: ++noticeId, kind, outcome: "switched", from, fromId: previous, to } });
6886
6927
  }
6887
6928
  continue;
6888
6929
  }
@@ -6987,6 +7028,21 @@ function createMediaSupervisor(options) {
6987
7028
  },
6988
7029
  dismissNotice() {
6989
7030
  setRegion({ notice: null });
7031
+ },
7032
+ async undoNotice() {
7033
+ const notice = region().notice;
7034
+ setRegion({ notice: null });
7035
+ const driver = options.driver();
7036
+ if (notice === null || notice.outcome !== "switched" || notice.fromId === void 0 || driver === null) return;
7037
+ const list = await snapshotDevices();
7038
+ if (!list[INPUT_KIND[notice.kind]].has(notice.fromId)) return;
7039
+ try {
7040
+ await driver.switchDevice(INPUT_KIND[notice.kind], notice.fromId);
7041
+ readInUse();
7042
+ } catch (error) {
7043
+ const refused = await unavailable(error, notice.kind, "meet.undoDeviceSwitch");
7044
+ store.setLocalTrack(notice.kind, { enabled: false, unavailable: refused });
7045
+ }
6990
7046
  }
6991
7047
  };
6992
7048
  return api;
@@ -7201,7 +7257,14 @@ function createRoomEngine(options) {
7201
7257
  const latest = store.snapshot().meeting;
7202
7258
  if (latest === null) return;
7203
7259
  store.patch({ meeting: { ...latest, endedAt: verified.endedAt } });
7204
- store.dispatch({ type: "ended" }, { reason: "ended" });
7260
+ const connection = current?.connectionIdentity ?? current?.identity ?? store.snapshot().localIdentity ?? null;
7261
+ let why;
7262
+ try {
7263
+ why = options.readExit !== void 0 && connection !== null ? await options.readExit(connection, current?.meetingPass ?? null) : void 0;
7264
+ } catch {
7265
+ why = null;
7266
+ }
7267
+ store.dispatch({ type: "ended" }, { reason: why?.exitReason === "time_limit" ? "time_limit" : "ended" });
7205
7268
  await dropRoom();
7206
7269
  options.onLeft?.("ended");
7207
7270
  } catch (error) {
@@ -7529,6 +7592,7 @@ function createRoomEngine(options) {
7529
7592
  current = token;
7530
7593
  lastServerUrl = token.serverUrl;
7531
7594
  connectionPolicy = token.connectionPolicy ?? DEFAULT_CONNECTION_POLICY;
7595
+ store.patch({ captionsStartTimeoutSeconds: connectionPolicy.captionsStartTimeoutSeconds });
7532
7596
  if (token.leavePolicy !== void 0) store.patch({ leavePolicy: token.leavePolicy });
7533
7597
  store.patch({ canReclaim: token.canReclaim === true });
7534
7598
  store.patch({
@@ -7973,6 +8037,7 @@ function createRoomEngine(options) {
7973
8037
  acceptDeviceOffer: () => media.acceptOffer(),
7974
8038
  dismissDeviceOffer: () => media.dismissOffer(),
7975
8039
  dismissDeviceNotice: () => media.dismissNotice(),
8040
+ undoDeviceNotice: () => media.undoNotice(),
7976
8041
  pin(who) {
7977
8042
  store.patch({ pinned: who, layout: who === null ? "grid" : "speaker" });
7978
8043
  },