@ai-matrx/meet 0.7.82 → 0.7.84

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,25 @@
1
1
  # Changelog — `@ai-matrx/meet`
2
2
 
3
+ ## 0.7.84
4
+ ### Unreleased
5
+
6
+ - **Observation contract (Meet duplicates CORE-DESIGN step S0).** Every screen `<MeetingRoom>`
7
+ renders now sits inside ONE `[data-meet-root]` carrying the HARNESS-CONTRACT values derived from
8
+ today's store (phase, role, connection, lobby count, recording, camera/microphone). Tiles carry
9
+ `[data-meet-participant]`, lobby rows `[data-meet-lobby-entry]`, the listen-only notice its
10
+ `data-meet-notice` code. New `<MeetRoot>` / `useCoreRootProps()` / `useCoreObservation()` for a
11
+ consumer's own screens around the room, pure `observeMeeting()` / `rootAttributes()` in the core,
12
+ and `window.__matrxMeet` diagnostics. The wrapper is `display: contents` — no layout change.
13
+
14
+ **Consumer action:** wrap any meeting screen you draw yourself (link resolution, a guest-name step,
15
+ a custom in-call layout) in `<MeetRoot>`, passing `phase` when no store exists yet.
16
+
17
+ ## 0.7.83
18
+
19
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
20
+ `git diff npm/meet/v0.7.82..npm/meet/v0.7.83 -- apps/shared/meet`).
21
+ No source changes intended and no consumer action required.
22
+
3
23
  ## 0.7.82
4
24
 
5
25
  - Screen share: a SYSTEM or POLICY block (Chrome/Edge "Permission denied by system", a
package/dist/index.cjs CHANGED
@@ -162,6 +162,7 @@ __export(src_exports, {
162
162
  meetingWhen: () => meetingWhen,
163
163
  mergeCaption: () => mergeCaption,
164
164
  mergeRecord: () => mergeRecord,
165
+ microphoneNoticeCode: () => microphoneNoticeCode,
165
166
  normalizeDeviceError: () => normalizeDeviceError,
166
167
  normalizeMeetError: () => normalizeMeetError,
167
168
  normalizeSpoken: () => normalizeSpoken,
@@ -170,8 +171,13 @@ __export(src_exports, {
170
171
  noteTakerParticipant: () => noteTakerParticipant,
171
172
  noteTakerStatus: () => noteTakerStatus,
172
173
  notesDocument: () => notesDocument,
174
+ observeMeeting: () => observe,
175
+ observedDevice: () => observedDevice,
176
+ observedPhase: () => observedPhase,
177
+ observedQuality: () => observedQuality,
173
178
  orderParticipants: () => orderParticipants,
174
179
  parseRoomToken: () => parseRoomToken,
180
+ participantAttributes: () => participantAttributes,
175
181
  participantSummary: () => participantSummary,
176
182
  playableRecordingFileId: () => playableRecordingFileId,
177
183
  projectInvitee: () => projectInvitee,
@@ -192,12 +198,14 @@ __export(src_exports, {
192
198
  recordingOffsetMs: () => recordingOffsetMs,
193
199
  roleOf: () => roleOf,
194
200
  roomTopic: () => roomTopic,
201
+ rootAttributes: () => rootAttributes,
195
202
  searchTranscript: () => searchTranscript,
196
203
  sendFollowUp: () => sendFollowUp,
197
204
  setGuestRecordAccess: () => setGuestRecordAccess,
198
205
  settingsPatch: () => settingsPatch,
199
206
  snapshotParticipant: () => snapshotParticipant,
200
207
  snippetRuns: () => snippetRuns,
208
+ staticObservation: () => staticObservation,
201
209
  summarizeMeetingRecordRestrictions: () => summarizeMeetingRecordRestrictions,
202
210
  transcriptDocument: () => transcriptDocument,
203
211
  unavailableFrom: () => unavailableFrom,
@@ -6515,4 +6523,136 @@ function createMeetingRecordCache(options = {}) {
6515
6523
  }
6516
6524
  };
6517
6525
  }
6526
+
6527
+ // src/core/observation.ts
6528
+ function observedDevice(track) {
6529
+ if (track.enabled) return "on";
6530
+ const refused = track.unavailable;
6531
+ if (refused === null) return "muted_by_me";
6532
+ switch (refused.code) {
6533
+ case "permission-denied":
6534
+ return "unavailable:denied";
6535
+ case "device-not-found":
6536
+ return "unavailable:none";
6537
+ case "device-in-use":
6538
+ return "unavailable:busy";
6539
+ case "insecure-context":
6540
+ return "unavailable:blocked_site";
6541
+ default:
6542
+ return "unavailable:failed";
6543
+ }
6544
+ }
6545
+ function endedRecord(snapshot, given) {
6546
+ const record = snapshot?.meeting ?? given;
6547
+ return record !== null && record.endedAt !== null;
6548
+ }
6549
+ function observedPhase(input) {
6550
+ const { snapshot } = input;
6551
+ if (snapshot === null) return "resolving";
6552
+ const raw = snapshot.phase;
6553
+ const live = raw === "connected" || raw === "reconnecting";
6554
+ if (endedRecord(snapshot, input.meeting ?? null) && !live) return "ended";
6555
+ switch (raw) {
6556
+ case "idle":
6557
+ case "failed":
6558
+ case "left":
6559
+ return "prejoin";
6560
+ case "lobby":
6561
+ return "waiting:knocking";
6562
+ case "requesting-token":
6563
+ case "connecting":
6564
+ return "joining";
6565
+ case "connected":
6566
+ case "reconnecting":
6567
+ return "in_call";
6568
+ }
6569
+ }
6570
+ var ADMITTER_ROLES = /* @__PURE__ */ new Set(["host", "cohost"]);
6571
+ function observe(input) {
6572
+ const { snapshot } = input;
6573
+ const phase = observedPhase(input);
6574
+ const inCall = phase === "in_call";
6575
+ const role = inCall && snapshot !== null ? effectiveRole(snapshot) : "none";
6576
+ const canAdmit = role !== "none" && ADMITTER_ROLES.has(role);
6577
+ const deviceInPlay = phase === "joining" || inCall;
6578
+ return {
6579
+ phase,
6580
+ reason: null,
6581
+ role,
6582
+ connection: snapshot?.phase === "reconnecting" ? "reconnecting" : "stable",
6583
+ hostPresent: inCall && snapshot !== null ? snapshot.participants.some((p) => ADMITTER_ROLES.has(p.role)) : null,
6584
+ lobbyCount: canAdmit && snapshot !== null ? snapshot.lobby.filter((entry) => entry.state === "knocking").length : 0,
6585
+ recording: snapshot?.recording === "recording" || snapshot?.recording === "stopping",
6586
+ audioBlocked: null,
6587
+ camera: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.camera) : null,
6588
+ microphone: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.microphone) : null
6589
+ };
6590
+ }
6591
+ function staticObservation(phase, reason = null) {
6592
+ return {
6593
+ phase,
6594
+ reason,
6595
+ role: "none",
6596
+ connection: phase === "disconnected" ? "server_unreachable" : "stable",
6597
+ hostPresent: null,
6598
+ lobbyCount: 0,
6599
+ recording: false,
6600
+ audioBlocked: null,
6601
+ camera: null,
6602
+ microphone: null
6603
+ };
6604
+ }
6605
+ function rootAttributes(o) {
6606
+ const attrs = {
6607
+ "data-meet-root": "",
6608
+ "data-meet-phase": o.phase,
6609
+ "data-meet-role": o.role,
6610
+ "data-meet-connection": o.connection,
6611
+ "data-meet-lobby-count": String(o.lobbyCount),
6612
+ "data-meet-recording": String(o.recording)
6613
+ };
6614
+ if (o.reason !== null) attrs["data-meet-reason"] = o.reason;
6615
+ if (o.hostPresent !== null) attrs["data-meet-host-present"] = String(o.hostPresent);
6616
+ if (o.audioBlocked !== null) attrs["data-meet-audio-blocked"] = String(o.audioBlocked);
6617
+ if (o.camera !== null) attrs["data-meet-camera"] = o.camera;
6618
+ if (o.microphone !== null) attrs["data-meet-microphone"] = o.microphone;
6619
+ attrs["data-meet-regions"] = JSON.stringify({
6620
+ connection: o.connection,
6621
+ camera: o.camera,
6622
+ mic: o.microphone,
6623
+ audio_output: o.audioBlocked === null ? null : o.audioBlocked ? "blocked" : "playing",
6624
+ recording: o.recording
6625
+ });
6626
+ return attrs;
6627
+ }
6628
+ function observedQuality(quality) {
6629
+ switch (quality) {
6630
+ case "excellent":
6631
+ case "good":
6632
+ return "good";
6633
+ case "poor":
6634
+ return "poor";
6635
+ case "lost":
6636
+ return "lost";
6637
+ default:
6638
+ return null;
6639
+ }
6640
+ }
6641
+ function participantAttributes(p) {
6642
+ const attrs = {
6643
+ "data-meet-participant": "",
6644
+ "data-meet-participant-identity": p.identity,
6645
+ "data-meet-participant-name": p.displayName,
6646
+ "data-meet-participant-role": p.role,
6647
+ "data-meet-participant-self": String(p.isLocal)
6648
+ };
6649
+ const quality = observedQuality(p.quality);
6650
+ if (quality !== null) attrs["data-meet-participant-connection"] = quality;
6651
+ return attrs;
6652
+ }
6653
+ function microphoneNoticeCode(track) {
6654
+ const refused = track.unavailable;
6655
+ if (refused === null) return null;
6656
+ return refused.code === "permission-denied" || refused.code === "insecure-context" ? "mic-blocked" : "device-lost";
6657
+ }
6518
6658
  //# sourceMappingURL=index.cjs.map