@ai-matrx/meet 0.11.36 → 0.11.38

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.38
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/meet/v0.11.37..npm/meet/v0.11.38 -- apps/shared/meet`).
7
+ No source changes intended and no consumer action required.
8
+
9
+ ## 0.11.37
10
+
11
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
12
+ `git diff npm/meet/v0.11.36..npm/meet/v0.11.37 -- apps/shared/meet`).
13
+ No source changes intended and no consumer action required.
14
+
3
15
  ## 0.11.36
4
16
 
5
17
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/dist/core.cjs CHANGED
@@ -38,6 +38,7 @@ __export(core_exports, {
38
38
  DATA_TOPICS: () => DATA_TOPICS,
39
39
  DEFAULT_CONNECTION_POLICY: () => DEFAULT_CONNECTION_POLICY,
40
40
  DEFAULT_EFFECTS: () => DEFAULT_EFFECTS,
41
+ DEFAULT_LEAVE_POLICY: () => DEFAULT_LEAVE_POLICY,
41
42
  DEFAULT_PAGE_SIZE: () => DEFAULT_PAGE_SIZE,
42
43
  EMPTY_COLLAB: () => EMPTY_COLLAB,
43
44
  END_MEETING_NOT_SERVED: () => END_MEETING_NOT_SERVED,
@@ -72,6 +73,7 @@ __export(core_exports, {
72
73
  NO_SHARE: () => NO_SHARE,
73
74
  ORGANIZATION_HEADER: () => ORGANIZATION_HEADER,
74
75
  PARTICIPANT_CAN_RECORD_ATTRIBUTE: () => PARTICIPANT_CAN_RECORD_ATTRIBUTE,
76
+ PARTICIPANT_HAND_ATTRIBUTE: () => PARTICIPANT_HAND_ATTRIBUTE,
75
77
  PARTICIPANT_ROLE_ATTRIBUTE: () => PARTICIPANT_ROLE_ATTRIBUTE,
76
78
  PARTICIPANT_STANDING_ATTRIBUTE: () => PARTICIPANT_STANDING_ATTRIBUTE,
77
79
  REACTION_TTL_MS: () => REACTION_TTL_MS,
@@ -184,6 +186,8 @@ __export(core_exports, {
184
186
  isWaitingPhase: () => isWaitingPhase,
185
187
  learnName: () => learnName,
186
188
  learnNames: () => learnNames,
189
+ leaveChoices: () => leaveChoices,
190
+ leavePolicyFrom: () => leavePolicyFrom,
187
191
  listenOnlyNotice: () => listenOnlyNotice,
188
192
  loadFollowUpDraft: () => loadFollowUpDraft,
189
193
  loadGuestMeetingRecord: () => loadGuestMeetingRecord,
@@ -831,6 +835,30 @@ function mergeGhosts(live, ghosts, at) {
831
835
  return { roster: [...live, ...extra], kept };
832
836
  }
833
837
 
838
+ // src/core/leave.ts
839
+ var DEFAULT_LEAVE_POLICY = { hostLeavePrompt: "leave_or_end", endConfirm: false };
840
+ var PROMPTS = ["leave_or_end", "must_assign_or_end", "leave_only"];
841
+ function leavePolicyFrom(raw) {
842
+ if (typeof raw !== "object" || raw === null) return DEFAULT_LEAVE_POLICY;
843
+ const value = raw;
844
+ const prompt = value["host_leave_prompt"];
845
+ const confirm = value["end_confirm"];
846
+ return {
847
+ hostLeavePrompt: PROMPTS.includes(prompt) ? prompt : DEFAULT_LEAVE_POLICY.hostLeavePrompt,
848
+ endConfirm: typeof confirm === "boolean" ? confirm : DEFAULT_LEAVE_POLICY.endConfirm
849
+ };
850
+ }
851
+ function leaveChoices(args) {
852
+ if (args.role !== "host") return ["leave"];
853
+ switch (args.policy.hostLeavePrompt) {
854
+ case "must_assign_or_end":
855
+ return args.othersPresent ? ["assign_and_leave", "end_for_all"] : ["leave", "end_for_all"];
856
+ case "leave_only":
857
+ case "leave_or_end":
858
+ return ["leave", "end_for_all"];
859
+ }
860
+ }
861
+
834
862
  // src/core/tokens.ts
835
863
  function createWebRoomTokenStorage(onDiagnostic) {
836
864
  const store = globalThis.localStorage;
@@ -938,6 +966,12 @@ var MEET_ROUTES = {
938
966
  state: "/api/v1/meet/state",
939
967
  /** S4: `withdraw` (stop waiting) or `leave` (close this tab); the pass may ride in the body. */
940
968
  leave: "/api/v1/meet/leave",
969
+ /**
970
+ * S8: a host's browser just called an admission DOOR (`meet_admit` · `meet_deny` ·
971
+ * `meet_undeny` · `meet_admit_all`). Payload-free: the server republishes the room's
972
+ * replicated state (the People badge's waiting count) from the database truth.
973
+ */
974
+ admissionChanged: "/api/v1/meet/admission/changed",
941
975
  /** S4: a pass holder (guests included) saw the recording notice, for this run. */
942
976
  consent: "/api/v1/meet/consent"
943
977
  };
@@ -1022,7 +1056,8 @@ function parseRoomToken(body, roomName) {
1022
1056
  pollSeconds: typeof payload["poll_seconds"] === "number" ? payload["poll_seconds"] : void 0,
1023
1057
  breakoutRoomId: readString(payload, "breakout_room_id") ?? null,
1024
1058
  observersVisibleTo: readString(payload, "observers_visible_to") === "hosts" ? "hosts" : "everyone",
1025
- connectionPolicy: connectionPolicyFrom(payload["connection_policy"])
1059
+ connectionPolicy: connectionPolicyFrom(payload["connection_policy"]),
1060
+ leavePolicy: leavePolicyFrom(payload["leave_policy"])
1026
1061
  };
1027
1062
  }
1028
1063
  function createTokenClient(options) {
@@ -3721,6 +3756,10 @@ var EMPTY = {
3721
3756
  chatHistoryError: null,
3722
3757
  reactions: [],
3723
3758
  spotlight: null,
3759
+ actingHost: null,
3760
+ presenter: null,
3761
+ waitingCount: 0,
3762
+ leavePolicy: DEFAULT_LEAVE_POLICY,
3724
3763
  moderationNotice: null,
3725
3764
  actionNotice: null,
3726
3765
  privateChatRequest: null,
@@ -3782,8 +3821,6 @@ function createMeetStore(initial = {}) {
3782
3821
  },
3783
3822
  setParticipants(participants) {
3784
3823
  const names = learnNames(state.names, participants);
3785
- const hands = new Map(state.participants.map((p) => [p.identity, p.handRaised]));
3786
- const handTimes = new Map(state.participants.map((p) => [p.identity, p.handRaisedAt ?? null]));
3787
3824
  const quality = new Map(state.participants.map((p) => [p.identity, p.quality]));
3788
3825
  commit({
3789
3826
  ...state,
@@ -3796,8 +3833,6 @@ function createMeetStore(initial = {}) {
3796
3833
  // identity could reach a screen, and it is the place that asks the
3797
3834
  // name book. `roster-names.test.ts` fails if a token ever gets past it.
3798
3835
  displayName: displayNameFor(names, participant.identity, participant.displayName),
3799
- handRaised: hands.get(participant.identity) ?? participant.handRaised,
3800
- handRaisedAt: handTimes.get(participant.identity) ?? participant.handRaisedAt ?? null,
3801
3836
  quality: participant.quality === "unknown" ? quality.get(participant.identity) ?? "unknown" : participant.quality
3802
3837
  }))
3803
3838
  });
@@ -3820,20 +3855,6 @@ function createMeetStore(initial = {}) {
3820
3855
  )
3821
3856
  });
3822
3857
  },
3823
- setHand(identity, raised, at) {
3824
- commit({
3825
- ...state,
3826
- participants: state.participants.map(
3827
- (participant) => participant.identity === identity ? {
3828
- ...participant,
3829
- handRaised: raised,
3830
- // A hand that is ALREADY up keeps its place in the queue when
3831
- // it is re-announced (to a late joiner): the first time wins.
3832
- handRaisedAt: raised ? participant.handRaised && participant.handRaisedAt != null ? participant.handRaisedAt : at ?? Date.now() : null
3833
- } : participant
3834
- )
3835
- });
3836
- },
3837
3858
  addChat(message) {
3838
3859
  if (state.chat.some((existing) => existing.id === message.id)) return;
3839
3860
  const chat = [...state.chat, message];
@@ -3982,18 +4003,6 @@ var ROOM_EVENTS = {
3982
4003
  wrapUp: "matrx.meet.wrap_up",
3983
4004
  /** The meeting ended for everyone. Payload `{ meeting_id, ended_at, trigger }`. */
3984
4005
  ended: "matrx.meet.ended",
3985
- /**
3986
- * A `meet_recordings` row changed state. Payload
3987
- * `{ meeting_id, recording: { id, state, started_by } }`.
3988
- *
3989
- * 🚨 THIS IS THE ONLY WAY A GUEST LEARNS A RECORDING IS RUNNING. PreJoin
3990
- * promises every joiner an indicator, and `anon` holds no SELECT grant on
3991
- * `meet_recordings` (MRI-A10 settled that widening it is forbidden), so
3992
- * without this packet the promise was a sentence with nothing behind it: on
3993
- * production 2026-09-09 the guest lane showed no indicator at all while the
3994
- * host recorded (MRI-C8).
3995
- */
3996
- recording: "matrx.meet.recording",
3997
4006
  /**
3998
4007
  * A chat message to everyone was SAVED (Meet wave 2). Payload
3999
4008
  * `{ message: { id, meeting_id, sender_identity, sender_name, body, created_at } }`.
@@ -4046,8 +4055,6 @@ function applyRoomEvent(args) {
4046
4055
  return applyWrapUp(store, payload, now);
4047
4056
  case ROOM_EVENTS.ended:
4048
4057
  return applyEnded(store, payload);
4049
- case ROOM_EVENTS.recording:
4050
- return applyRecording(store, payload);
4051
4058
  case ROOM_EVENTS.chat:
4052
4059
  return applyChat(store, payload);
4053
4060
  case ROOM_EVENTS.moderation:
@@ -4127,9 +4134,9 @@ function applyWrapUp(store, payload, now) {
4127
4134
  store.announceWrapUp(announcement);
4128
4135
  return HANDLED;
4129
4136
  }
4130
- function applyRecording(store, payload) {
4137
+ function applyRecordingState(store, payload) {
4131
4138
  const row = object(payload["recording"]);
4132
- if (row === null) return ignored("a recording event with no `recording` row");
4139
+ if (row === null) return ignored("room state carries no recording");
4133
4140
  const meetingId = text2(payload["meeting_id"]);
4134
4141
  const meeting = store.snapshot().meeting;
4135
4142
  if (meeting !== null && meetingId !== null && meetingId !== meeting.id) {
@@ -4211,19 +4218,6 @@ function applyModeration(store, payload, now) {
4211
4218
  }
4212
4219
  const kind = text2(payload["kind"]);
4213
4220
  switch (kind) {
4214
- case "lower-hands": {
4215
- const raw = payload["identities"];
4216
- const everyone = raw === "*";
4217
- const named = new Set(
4218
- Array.isArray(raw) ? raw.filter((value) => typeof value === "string") : []
4219
- );
4220
- for (const participant of snapshot.participants) {
4221
- if (participant.handRaised && (everyone || named.has(participant.identity))) {
4222
- store.setHand(participant.identity, false);
4223
- }
4224
- }
4225
- return HANDLED;
4226
- }
4227
4221
  case "role": {
4228
4222
  const identity = text2(payload["identity"]);
4229
4223
  const role = text2(payload["role"]);
@@ -4615,7 +4609,6 @@ function gridColumns(count2) {
4615
4609
 
4616
4610
  // src/core/room-driver.ts
4617
4611
  var DATA_TOPICS = {
4618
- hand: "mx.hand",
4619
4612
  reaction: "mx.reaction",
4620
4613
  chat: "mx.chat"
4621
4614
  };
@@ -5249,7 +5242,7 @@ function createMeetingSession(options) {
5249
5242
  })();
5250
5243
  return reading;
5251
5244
  }
5252
- async function postLeave(intent) {
5245
+ async function postLeave(intent, extra = {}) {
5253
5246
  const meeting = requireMeeting(`meet.${intent}`);
5254
5247
  const pass = options.resolvePass?.() ?? null;
5255
5248
  const response = await options.api.request({
@@ -5257,7 +5250,7 @@ function createMeetingSession(options) {
5257
5250
  method: "POST",
5258
5251
  requireAuth: false,
5259
5252
  operation: `meet.${intent}`,
5260
- body: { meeting_id: meeting.id, intent },
5253
+ body: { meeting_id: meeting.id, intent, ...extra },
5261
5254
  ...pass !== null ? { headers: { [MEETING_PASS_HEADER]: pass } } : {}
5262
5255
  });
5263
5256
  if (!response.ok) {
@@ -5271,13 +5264,41 @@ function createMeetingSession(options) {
5271
5264
  throw new MeetError(
5272
5265
  "transport",
5273
5266
  refusal2?.reason ?? `meet.${intent}: the server answered ${response.status}`,
5274
- refusal2?.remedy ?? "You are still in the waiting room. Try again."
5267
+ refusal2?.remedy ?? (intent === "withdraw" ? "You are still in the waiting room. Try again." : "Nothing was changed. Try again.")
5275
5268
  );
5276
5269
  }
5277
5270
  }
5278
5271
  function hint() {
5279
5272
  channel?.send(MEET_EVENTS.stateChanged, { v: null });
5280
5273
  }
5274
+ async function tellServerAdmissionChanged(operation) {
5275
+ const meeting = store.snapshot().meeting;
5276
+ if (meeting === null) return;
5277
+ const pass = options.resolvePass?.() ?? null;
5278
+ try {
5279
+ const response = await options.api.request({
5280
+ path: MEET_ROUTES.admissionChanged,
5281
+ method: "POST",
5282
+ requireAuth: false,
5283
+ operation,
5284
+ body: { meeting_id: meeting.id },
5285
+ ...pass !== null ? { headers: { [MEETING_PASS_HEADER]: pass } } : {}
5286
+ });
5287
+ if (!response.ok) {
5288
+ report(
5289
+ "warn",
5290
+ `${operation}: the server answered ${response.status} when told about the admission change`,
5291
+ "The decision was saved. The waiting count in the room may lag until the next change."
5292
+ );
5293
+ }
5294
+ } catch (error) {
5295
+ report(
5296
+ "warn",
5297
+ `${operation}: ${String(error)}`,
5298
+ "The decision was saved. The waiting count in the room may lag until the next change."
5299
+ );
5300
+ }
5301
+ }
5281
5302
  async function refreshQueue() {
5282
5303
  const meeting = store.snapshot().meeting;
5283
5304
  if (meeting === null || isGuest(identity) || !isHostRole(effectiveRole(store.snapshot()))) return;
@@ -5433,6 +5454,7 @@ function createMeetingSession(options) {
5433
5454
  decidedAt: (/* @__PURE__ */ new Date()).toISOString(),
5434
5455
  decidedBy: by
5435
5456
  });
5457
+ await tellServerAdmissionChanged("meet.admit");
5436
5458
  hint();
5437
5459
  },
5438
5460
  async undeny(entry) {
@@ -5445,6 +5467,7 @@ function createMeetingSession(options) {
5445
5467
  byUserId: by
5446
5468
  });
5447
5469
  store.upsertLobby({ ...entry, state: decidedState(row.admissionState), decidedAt: (/* @__PURE__ */ new Date()).toISOString(), decidedBy: by });
5470
+ await tellServerAdmissionChanged("meet.undeny");
5448
5471
  hint();
5449
5472
  },
5450
5473
  async admitAll() {
@@ -5454,6 +5477,7 @@ function createMeetingSession(options) {
5454
5477
  for (const row of rows) {
5455
5478
  store.setAdmission(row.identity, row.admissionState, by);
5456
5479
  }
5480
+ await tellServerAdmissionChanged("meet.admitAll");
5457
5481
  hint();
5458
5482
  },
5459
5483
  startWaiting() {
@@ -5495,6 +5519,10 @@ function createMeetingSession(options) {
5495
5519
  store.dispatch({ type: "admission", admission: "withdrawn" });
5496
5520
  hint();
5497
5521
  },
5522
+ async hostLeave(intent) {
5523
+ if (intent === "end_for_all") await postLeave("end_for_all");
5524
+ else await postLeave("assign_and_leave", { assign_to: intent.assignTo });
5525
+ },
5498
5526
  async askAgain() {
5499
5527
  await options.rejoin?.();
5500
5528
  },
@@ -6456,6 +6484,11 @@ function SCREEN_SHARE_BLOCKED_REMEDY_FOR(remedy) {
6456
6484
  return /administrator|policy/i.test(remedy) ? remedy : SCREEN_SHARE_BLOCKED_REMEDY;
6457
6485
  }
6458
6486
  var PARTICIPANT_ROLE_ATTRIBUTE = "matrx.participant.role";
6487
+ var PARTICIPANT_HAND_ATTRIBUTE = "matrx.hand";
6488
+ function handFrom(value) {
6489
+ const at = value === void 0 || value.length === 0 ? Number.NaN : Number(value);
6490
+ return Number.isFinite(at) ? { handRaised: true, handRaisedAt: at } : { handRaised: false, handRaisedAt: null };
6491
+ }
6459
6492
  var PARTICIPANT_CAN_RECORD_ATTRIBUTE = "matrx.participant.can_record";
6460
6493
  var CONNECTION_KIND_ATTRIBUTE = "matrx.participant.connection_kind";
6461
6494
  var PARTICIPANT_STANDING_ATTRIBUTE = "matrx.participant.standing";
@@ -6509,7 +6542,10 @@ function projectParticipant(driver, joinedAt) {
6509
6542
  cameraEnabled: driver.cameraEnabled,
6510
6543
  screenSharing: driver.screenSharing,
6511
6544
  speaking: false,
6512
- handRaised: false,
6545
+ // S8: a hand is the SERVER's (`hand_raised_at` on the person row, `/moderate raise_hand`),
6546
+ // replicated as the `matrx.hand` attribute: epoch ms of the raise, "" when down. It is
6547
+ // therefore delivered to late joiners and survives refresh and reconnect.
6548
+ ...handFrom(driver.attributes[PARTICIPANT_HAND_ATTRIBUTE]),
6513
6549
  quality: "unknown",
6514
6550
  joinedAt
6515
6551
  };
@@ -6639,40 +6675,38 @@ function createRoomEngine(options) {
6639
6675
  },
6640
6676
  participants(list) {
6641
6677
  const joinedAt = new Date(now()).toISOString();
6642
- const before = new Set(store.snapshot().participants.map((p) => p.identity));
6643
6678
  projectRoster(list, joinedAt);
6644
- const snapshot = store.snapshot();
6645
- const newcomer = snapshot.participants.some(
6646
- (participant) => !participant.isLocal && !before.has(participant.identity)
6647
- );
6648
- const me = snapshot.participants.find((p) => p.identity === snapshot.localIdentity);
6649
- if (newcomer && before.size > 0 && me?.handRaised === true) {
6650
- void publish(DATA_TOPICS.hand, { raised: true, raisedAt: me.handRaisedAt ?? now() }).catch(
6651
- () => void 0
6652
- );
6653
- }
6654
6679
  },
6655
6680
  participantLeft(who, reason) {
6656
6681
  departures.set(who, reason);
6657
6682
  },
6658
6683
  roomMetadata(metadata) {
6659
- let spotlight = null;
6684
+ let parsed = {};
6660
6685
  if (metadata.length > 0) {
6661
6686
  try {
6662
- const parsed = JSON.parse(metadata);
6663
- if (typeof parsed === "object" && parsed !== null) {
6664
- const value = parsed.spotlight;
6665
- if (typeof value === "string" && value.length > 0) spotlight = asParticipantIdentity(value);
6666
- }
6687
+ const value = JSON.parse(metadata);
6688
+ if (typeof value === "object" && value !== null) parsed = value;
6667
6689
  } catch {
6668
6690
  report(
6669
6691
  "warn",
6670
- "meet: the room's metadata is not JSON, so no spotlight was read from it",
6671
- "Only aidream writes room metadata; check services/meet/moderation.py."
6692
+ "meet: the room's metadata is not JSON, so the room state was not read from it",
6693
+ "Only aidream writes room metadata; check services/meet/room_state.py."
6672
6694
  );
6673
6695
  }
6674
6696
  }
6675
- if (store.snapshot().spotlight !== spotlight) store.patch({ spotlight });
6697
+ const key = (name) => {
6698
+ const value = parsed[name];
6699
+ return typeof value === "string" && value.length > 0 ? asParticipantIdentity(personOf(value)) : null;
6700
+ };
6701
+ const waiting = typeof parsed["waiting_count"] === "number" ? parsed["waiting_count"] : 0;
6702
+ const before = store.snapshot();
6703
+ const next = { spotlight: key("spotlight"), actingHost: key("acting_host"), presenter: key("presenter"), waitingCount: waiting };
6704
+ if (before.spotlight !== next.spotlight || before.actingHost !== next.actingHost || before.presenter !== next.presenter || before.waitingCount !== next.waitingCount) {
6705
+ store.patch(next);
6706
+ }
6707
+ if (parsed["recording"] !== void 0 && parsed["recording"] !== null) {
6708
+ applyRecordingState(store, { meeting_id: parsed["meeting_id"], recording: parsed["recording"] });
6709
+ }
6676
6710
  },
6677
6711
  activeSpeakers(identities) {
6678
6712
  store.setSpeaking([...new Set(identities.map((who) => personOf(who)))]);
@@ -6774,13 +6808,6 @@ function createRoomEngine(options) {
6774
6808
  }
6775
6809
  const sender = personOf(from ?? "");
6776
6810
  switch (topic) {
6777
- case DATA_TOPICS.hand:
6778
- store.setHand(
6779
- sender,
6780
- envelope.raised === true,
6781
- typeof envelope.raisedAt === "number" ? envelope.raisedAt : now()
6782
- );
6783
- return;
6784
6811
  case DATA_TOPICS.reaction:
6785
6812
  if (typeof envelope.emoji === "string") {
6786
6813
  store.addReaction({
@@ -6879,6 +6906,7 @@ function createRoomEngine(options) {
6879
6906
  current = token;
6880
6907
  lastServerUrl = token.serverUrl;
6881
6908
  connectionPolicy = token.connectionPolicy ?? DEFAULT_CONNECTION_POLICY;
6909
+ if (token.leavePolicy !== void 0) store.patch({ leavePolicy: token.leavePolicy });
6882
6910
  store.patch({
6883
6911
  localIdentity: token.identity,
6884
6912
  breakoutRoomId: token.breakoutRoomId ?? null,
@@ -7245,11 +7273,6 @@ function createRoomEngine(options) {
7245
7273
  dismissShareNotice() {
7246
7274
  if (store.snapshot().share.state === "refused") store.patch({ share: NO_SHARE });
7247
7275
  },
7248
- async raiseHand(raised) {
7249
- const local = store.snapshot().localIdentity;
7250
- if (local !== null) store.setHand(local, raised);
7251
- await publish(DATA_TOPICS.hand, { raised, raisedAt: now() });
7252
- },
7253
7276
  async react(emoji) {
7254
7277
  const local = store.snapshot().localIdentity;
7255
7278
  const id = `${local ?? "local"}-${now()}`;
@@ -7378,6 +7401,8 @@ var MODERATION_ACTIONS = [
7378
7401
  "ask_unmute",
7379
7402
  "ask_all_unmute",
7380
7403
  "spotlight",
7404
+ "present",
7405
+ "raise_hand",
7381
7406
  "lower_hand",
7382
7407
  "lower_all_hands",
7383
7408
  "make_cohost",
@@ -7408,7 +7433,22 @@ function createInRoomClient(options) {
7408
7433
  function refusal2(response, operation, remedy) {
7409
7434
  return refusalFromResponse(response, operation, remedy);
7410
7435
  }
7411
- return {
7436
+ let toldPresenting = false;
7437
+ let tellChain = Promise.resolve();
7438
+ store.subscribe(() => {
7439
+ const local = store.snapshot().participants.find((p) => p.isLocal);
7440
+ const sharing = local?.screenSharing === true;
7441
+ if (sharing === toldPresenting || local === void 0) return;
7442
+ toldPresenting = sharing;
7443
+ const on = sharing;
7444
+ tellChain = tellChain.then(() => client.moderate({ action: "present", on })).then(
7445
+ () => void 0,
7446
+ (error) => {
7447
+ console.warn(`[meet] the server did not take presenter=${String(on)}: ${String(error)}`);
7448
+ }
7449
+ );
7450
+ });
7451
+ const client = {
7412
7452
  async moderate(request) {
7413
7453
  const operation = `meet.moderate(${request.action})`;
7414
7454
  const hdrs = headers();
@@ -7421,7 +7461,8 @@ function createInRoomClient(options) {
7421
7461
  action: request.action,
7422
7462
  ...request.identity != null ? { identity: request.identity } : {},
7423
7463
  ...request.name !== void 0 ? { name: request.name } : {},
7424
- ...request.reason !== void 0 ? { reason: request.reason } : {}
7464
+ ...request.reason !== void 0 ? { reason: request.reason } : {},
7465
+ ...request.on !== void 0 ? { on: request.on } : {}
7425
7466
  },
7426
7467
  ...hdrs !== void 0 ? { headers: hdrs } : {}
7427
7468
  });
@@ -7612,6 +7653,7 @@ function createInRoomClient(options) {
7612
7653
  });
7613
7654
  }
7614
7655
  };
7656
+ return client;
7615
7657
  }
7616
7658
 
7617
7659
  // src/core/record.ts