@ai-matrx/meet 0.11.46 → 0.11.48

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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { ATTENDANCE_CSV_HEADER, AnnounceResult, ApplyRoomEventArgs, AskArgs, AttendanceKind, AttendanceRow, AudioProcessing, BrowserFamily, CALL_INVITE_KIND, CALL_INVITE_VERSION, CONSENT_NOTICE_ATTRIBUTE, CallCenter, CallCenterOptions, CallInviteHandlerOptions, CallInvitePayload, CallOutcomePhase, CollabAction, CollabRequest, CollabResult, CollabRuntime, CollabStoreLike, ConnectionPolicy, ConnectionRegion, ConnectionSupervisor, ConnectionSupervisorOptions, CreateCallInviteInput, CreateMeetingInput, DATA_TOPICS, DEFAULT_CONNECTION_POLICY, DEFAULT_EFFECTS, DEFAULT_LEAVE_POLICY, DEFAULT_PAGE_SIZE, DataTopic, DeviceKind, DeviceManager, DeviceManagerOptions, DeviceNotice, DeviceOffer, DeviceSnapshot, DeviceStorage, DeviceUnavailableReason, DriverConnectionState, DriverParticipant, DriverTrackKind, DriverTranscription, END_MEETING_NOT_SERVED, EffectsStorage, EndMeetingResult, ExitInput, ExitPhase, ExitResolution, ExitServerWord, FollowUpDraft, FollowUpRecipient, FollowUpSendResult, GUEST_RECORD_ACCESS_CHOICES, GUEST_RECORD_ACCESS_LEVELS, GUEST_RECORD_ACCESS_METADATA_KEY, GUEST_RECORD_NOT_SHARED, Ghost, GuestRecordAccess, GuestRecordAccessResolution, GuestRecordAccessSetting, HostLeavePrompt, IDLE_MEDIA, IDLE_MEDIA_REGION, IDLE_PHASES, IDLE_TRACK, InRoomClient, InRoomClientOptions, JOIN_REFUSAL_REASONS, JoinRefusalReason, JoinRequest, LISTEN_ONLY_NOTICE, LIVEKIT_BASE_DELAYS_MS, LIVE_PHASES, LeaveChoice, LeavePolicy, LibraryRecording, LiveKitDriverOptions, LocalMediaState, LocalTrackState, MEETING_INVITE_KIND, MEETING_INVITE_VERSION, MEETING_PASS_HEADER, MEETING_RECORD_GRACE_MS, MEET_ANSWER_CONTEXT_EVENT, MEET_ANSWER_EVENTS, MEET_EVENTS, MEET_REACTIONS, MEET_ROUTES, MEET_SCHEMA, MODERATION_ACTIONS, MediaDevicesLike, MediaEffects, MediaKind, MediaPlatform, MediaRegionState, MediaSupervisor, MediaSupervisorOptions, MediaUnavailable, MeetAi, MeetAiAnswer, MeetAiOptions, MeetAnswerCoverage, MeetCapabilities, MeetDevice, MeetError, MeetErrorCode, MeetEvent, MeetGrants, MeetObservation, MeetPatch, MeetPhase, MeetRepository, MeetRoomDriver, MeetSnapshot, MeetStore, MeetingChatHistory, MeetingInviteHandlerOptions, MeetingInvitePayload, MeetingRecordAnswer, MeetingRecordBundle, MeetingRecordCache, MeetingRecordChange, MeetingRecordFailure, MeetingRecordParts, MeetingRecordRestriction, MeetingRecordRestrictionNotice, MeetingRecordState, MeetingSearchHit, MeetingSearchSource, MeetingSession, MeetingSessionOptions, ModerationAction, ModerationNotice, ModerationRequest, ModerationResult, NOTE_TAKER_IDENTITY_PREFIX, NOTE_TAKER_METADATA_KEY, NO_GRANTS, NO_SHARE, NameBook, NetworkPort, NoteTakerDispatch, NoteTakerRefusal, NoteTakerStatus, ObserveInput, ObservedConnection, ObservedPhase, OsFamily, PARTICIPANT_CAN_RECORD_ATTRIBUTE, PARTICIPANT_HAND_ATTRIBUTE, PARTICIPANT_ROLE_ATTRIBUTE, PARTICIPANT_STANDING_ATTRIBUTE, PermissionReading, PhaseEvent, PhaseEventType, PlatformDevice, REACTION_TTL_MS, REFUSED_ABSENCE, RESUME_WINDOW_MS, ROOM_EVENTS, ROOM_EVENT_PREFIX, RPCS, ReconnectPolicyLike, ReconnectPolicyOptions, RecordingController, RecordingControllerOptions, RepositoryOptions, ResumeMarker, ResumeStorage, RoomChatMessage, RoomDriverFactory, RoomDriverHandlers, RoomEngine, RoomEngineOptions, RoomEventOutcome, RoomEventTopic, RoomReaction, RoomToken, RoomTokenStorage, ScheduleMeetingInput, ShareRegion, SpeakingWhileMutedDetector, SpeakingWhileMutedOptions, Stage, StageArgs, TABLES, TRANSCRIPTION_ATTRIBUTES, TRANSCRIPTION_TOPIC, TokenClient, TokenClientOptions, TokenRequest, TranscriptBlock, TranscriptFormat, TranscriptMatch, UnsupportedReason, VideoEffect, WAITING_PHASES, WrapUpStatus, absenceSentence, activeWrapUpSummary, activityAttention, admissionPhase, announceMeeting, applyRoomEvent, assembleMeetingRecord, attendanceCsv, attendanceReport, attendanceTotals, attendeeKey, autoRejoinDelayMs, availableActivities, callInviteAction, callInviteText, callStateLabel, canModerate, canModerateParticipant, canTransition, captionSegment, changesPatch, classifyDeviceFailure, clockPosition, computeStage, connectionPolicyFrom, countLabel, createCallCenter, createCallInviteHandler, createConnectionSupervisor, createDeviceManager, createInRoomClient, createLiveKitDriver, createMediaSupervisor, createMeetAi, createMeetRepository, createMeetStore, createMeetingInviteHandler, createMeetingRecordCache, createMeetingSession, createMemoryDeviceStorage, createReachabilityProbe, createReconnectPolicy, createRecordingController, createRoomEngine, createSpeakingWhileMutedDetector, createTokenClient, createWebDeviceStorage, createWebEffectsStorage, createWebNetworkPort, createWebResumeStorage, createWebRoomTokenStorage, detectBrowser, detectCapabilities, detectOs, deviceChipLabel, deviceFixSteps, deviceNoticeCode, deviceUnavailableReason, displayNameFor, gridColumns, groupTranscript, guestRecordAccessExplanation, guestRecordAccessLabel, guestRecordAccessSetting, hasEnded, hostUserIds, httpUrlOf, invalidResponse, isGuestIdentity, isJoinRefusalReason, isListenOnly, isLivePhase, isMobileUserAgent, isNoteTaker, isRealName, isRefusedPhase, isRoomEventTopic, isUnannouncedDeparture, isWaitingPhase, learnName, learnNames, leaveChoices, leavePolicyFrom, listenOnlyNotice, loadFollowUpDraft, loadGuestMeetingRecord, loadMeetingChat, loadMeetingRecord, loadMeetingRecordParts, mapConnectionState, mapQuality, meetingInviteAction, meetingLength, meetingLink, meetingPassHeaders, meetingPath, meetingSlug, meetingTopic, meetingWhen, mergeCaption, mergeGhosts, mergeRecord, microphoneNoticeCode, moveToRoom, nextPhase, nextTranslationBatch, normalizeDeviceError, normalizeMeetError, normalizeSpoken, noteTakerIdentity, noteTakerLabel, noteTakerParticipant, noteTakerStatus, notesDocument, observeMeeting, observedDevice, observedPhase, observedQuality, orderParticipants, parseRoomToken, participantAttributes, participantSummary, performCollab, playableRecordingFileId, projectInvitee, projectLibraryRecording, projectNote, projectOccurrence, projectOverride, projectParticipant, projectRsvpInvitation, projectSearchHit, projectSegment, projectUpcoming, pushMeetingToGoogleCalendar, readServerRefusal, readableTranscript, reasonOf, recordingLabel, recordingNotice, recordingOffsetMs, refusalPhase, rememberedMeetingPass, resolveExit, roleOf, roomTopic, rootAttributes, searchTranscript, sendFollowUp, setCaptionLanguage, setGuestRecordAccess, settingsPatch, snapshotParticipant, snippetRuns, staticObservation, summarizeMeetingRecordRestrictions, takeMoveRequest, takePanelRequest, transcriptDocument, unavailableFrom, uniqueAttendees, unsupportedWords, untranslatedLines, userTopic, wasRefused, webMediaPlatform, wrapUpStatus } from './core.cjs';
2
- export { A as AccessTokenSource, k as AdmissionState, l as CAPTION_LANGUAGES, m as CallId, d as CallInvite, f as CallMode, n as CallState, o as CallablePerson, C as CollabPanel, j as CollabSnapshot, p as ConnectionQuality, E as EMPTY_COLLAB, F as FILE_SESSION_PATH, I as InviteeInput, q as InviteeRole, J as JsonObject, r as JsonValue, L as LobbyEntry, b as MeetApi, s as MeetApiOptions, t as MeetApiRequest, u as MeetAppFocus, v as MeetBreakoutBroadcast, w as MeetBreakoutPlan, x as MeetBreakoutRoom, y as MeetCollabSettings, z as MeetFileMedia, c as MeetIdentity, a as MeetParticipant, B as MeetPoll, D as MeetPollOption, G as MeetPollState, H as MeetQuestion, K as MeetQuestionState, N as MeetStroke, Q as MeetingActivities, i as MeetingAppPanel, V as MeetingAttendee, X as MeetingChanges, h as MeetingId, Y as MeetingInvitee, Z as MeetingKind, g as MeetingNote, _ as MeetingNoteKind, $ as MeetingOccurrence, M as MeetingRecord, a0 as MeetingSettings, a1 as NoteTakerState, a2 as ORGANIZATION_HEADER, a3 as ObserversVisibleTo, a4 as OccurrenceOverride, a5 as OccurrenceState, O as OrganizationId, P as ParticipantIdentity, e as ParticipantRole, a6 as ParticipantStanding, a7 as ROLE_RANK, a8 as RecordingPolicy, a9 as RecordingRecord, aa as RecordingState, R as RoomName, ab as RsvpAnswer, ac as RsvpInvitation, ad as RsvpState, S as StageLayout, ae as TranscriptSegment, T as TranscriptSource, af as UpcomingOccurrence, U as UserId, W as WrapUpAnnouncement, ag as appPanelOf, ah as applyCollabPacket, ai as asCallId, aj as asMeetingId, ak as asOrganizationId, al as asParticipantIdentity, am as asRoomName, an as asUserId, ao as assignedRoom, ap as autoAssign, aq as breakoutClosingMs, ar as breakoutRemainingMs, as as captureHeldOf, at as collabFromState, au as createMeetApi, av as defaultCaptionLanguage, aw as fileDownloadPath, ax as focusFromRow, ay as isGuest, az as isHostRole, aA as isLinkFollower, aB as isObserverRole, aC as loadMeetingActivities, aD as scheduleSettingsPatch, aE as withItem } from './collab-D1TX5uf9.cjs';
2
+ export { A as AccessTokenSource, k as AdmissionState, l as CAPTION_LANGUAGES, m as CallId, d as CallInvite, f as CallMode, n as CallState, o as CallablePerson, C as CollabPanel, j as CollabSnapshot, p as ConnectionQuality, E as EMPTY_COLLAB, F as FILE_SESSION_PATH, I as InviteeInput, q as InviteeRole, J as JsonObject, r as JsonValue, L as LobbyEntry, b as MeetApi, s as MeetApiOptions, t as MeetApiRequest, u as MeetAppFocus, v as MeetBreakoutBroadcast, w as MeetBreakoutPlan, x as MeetBreakoutRoom, y as MeetCollabSettings, z as MeetFileMedia, c as MeetIdentity, a as MeetParticipant, B as MeetPoll, D as MeetPollOption, G as MeetPollState, H as MeetQuestion, K as MeetQuestionState, N as MeetStroke, Q as MeetingActivities, i as MeetingAppPanel, V as MeetingAttendee, X as MeetingChanges, h as MeetingId, Y as MeetingInvitee, Z as MeetingKind, g as MeetingNote, _ as MeetingNoteKind, $ as MeetingOccurrence, M as MeetingRecord, a0 as MeetingSettings, a1 as NoteTakerState, a2 as ORGANIZATION_HEADER, a3 as ObserversVisibleTo, a4 as OccurrenceOverride, a5 as OccurrenceState, O as OrganizationId, P as ParticipantIdentity, e as ParticipantRole, a6 as ParticipantStanding, a7 as ROLE_RANK, a8 as RecordingPolicy, a9 as RecordingRecord, aa as RecordingState, R as RoomName, ab as RsvpAnswer, ac as RsvpInvitation, ad as RsvpState, S as StageLayout, ae as TranscriptSegment, T as TranscriptSource, af as UpcomingOccurrence, U as UserId, W as WrapUpAnnouncement, ag as appPanelOf, ah as applyCollabPacket, ai as asCallId, aj as asMeetingId, ak as asOrganizationId, al as asParticipantIdentity, am as asRoomName, an as asUserId, ao as assignedRoom, ap as autoAssign, aq as breakoutClosingMs, ar as breakoutRemainingMs, as as captureHeldOf, at as collabFromState, au as createMeetApi, av as defaultCaptionLanguage, aw as fileDownloadPath, ax as focusFromRow, ay as isGuest, az as isHostRole, aA as isLinkFollower, aB as isObserverRole, aC as loadMeetingActivities, aD as scheduleSettingsPatch, aE as withItem } from './collab-Dk3r37MW.cjs';
3
3
  import '@ai-matrx/realtime';
4
4
  import '@ai-matrx/messaging';
5
5
  import 'livekit-client';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { ATTENDANCE_CSV_HEADER, AnnounceResult, ApplyRoomEventArgs, AskArgs, AttendanceKind, AttendanceRow, AudioProcessing, BrowserFamily, CALL_INVITE_KIND, CALL_INVITE_VERSION, CONSENT_NOTICE_ATTRIBUTE, CallCenter, CallCenterOptions, CallInviteHandlerOptions, CallInvitePayload, CallOutcomePhase, CollabAction, CollabRequest, CollabResult, CollabRuntime, CollabStoreLike, ConnectionPolicy, ConnectionRegion, ConnectionSupervisor, ConnectionSupervisorOptions, CreateCallInviteInput, CreateMeetingInput, DATA_TOPICS, DEFAULT_CONNECTION_POLICY, DEFAULT_EFFECTS, DEFAULT_LEAVE_POLICY, DEFAULT_PAGE_SIZE, DataTopic, DeviceKind, DeviceManager, DeviceManagerOptions, DeviceNotice, DeviceOffer, DeviceSnapshot, DeviceStorage, DeviceUnavailableReason, DriverConnectionState, DriverParticipant, DriverTrackKind, DriverTranscription, END_MEETING_NOT_SERVED, EffectsStorage, EndMeetingResult, ExitInput, ExitPhase, ExitResolution, ExitServerWord, FollowUpDraft, FollowUpRecipient, FollowUpSendResult, GUEST_RECORD_ACCESS_CHOICES, GUEST_RECORD_ACCESS_LEVELS, GUEST_RECORD_ACCESS_METADATA_KEY, GUEST_RECORD_NOT_SHARED, Ghost, GuestRecordAccess, GuestRecordAccessResolution, GuestRecordAccessSetting, HostLeavePrompt, IDLE_MEDIA, IDLE_MEDIA_REGION, IDLE_PHASES, IDLE_TRACK, InRoomClient, InRoomClientOptions, JOIN_REFUSAL_REASONS, JoinRefusalReason, JoinRequest, LISTEN_ONLY_NOTICE, LIVEKIT_BASE_DELAYS_MS, LIVE_PHASES, LeaveChoice, LeavePolicy, LibraryRecording, LiveKitDriverOptions, LocalMediaState, LocalTrackState, MEETING_INVITE_KIND, MEETING_INVITE_VERSION, MEETING_PASS_HEADER, MEETING_RECORD_GRACE_MS, MEET_ANSWER_CONTEXT_EVENT, MEET_ANSWER_EVENTS, MEET_EVENTS, MEET_REACTIONS, MEET_ROUTES, MEET_SCHEMA, MODERATION_ACTIONS, MediaDevicesLike, MediaEffects, MediaKind, MediaPlatform, MediaRegionState, MediaSupervisor, MediaSupervisorOptions, MediaUnavailable, MeetAi, MeetAiAnswer, MeetAiOptions, MeetAnswerCoverage, MeetCapabilities, MeetDevice, MeetError, MeetErrorCode, MeetEvent, MeetGrants, MeetObservation, MeetPatch, MeetPhase, MeetRepository, MeetRoomDriver, MeetSnapshot, MeetStore, MeetingChatHistory, MeetingInviteHandlerOptions, MeetingInvitePayload, MeetingRecordAnswer, MeetingRecordBundle, MeetingRecordCache, MeetingRecordChange, MeetingRecordFailure, MeetingRecordParts, MeetingRecordRestriction, MeetingRecordRestrictionNotice, MeetingRecordState, MeetingSearchHit, MeetingSearchSource, MeetingSession, MeetingSessionOptions, ModerationAction, ModerationNotice, ModerationRequest, ModerationResult, NOTE_TAKER_IDENTITY_PREFIX, NOTE_TAKER_METADATA_KEY, NO_GRANTS, NO_SHARE, NameBook, NetworkPort, NoteTakerDispatch, NoteTakerRefusal, NoteTakerStatus, ObserveInput, ObservedConnection, ObservedPhase, OsFamily, PARTICIPANT_CAN_RECORD_ATTRIBUTE, PARTICIPANT_HAND_ATTRIBUTE, PARTICIPANT_ROLE_ATTRIBUTE, PARTICIPANT_STANDING_ATTRIBUTE, PermissionReading, PhaseEvent, PhaseEventType, PlatformDevice, REACTION_TTL_MS, REFUSED_ABSENCE, RESUME_WINDOW_MS, ROOM_EVENTS, ROOM_EVENT_PREFIX, RPCS, ReconnectPolicyLike, ReconnectPolicyOptions, RecordingController, RecordingControllerOptions, RepositoryOptions, ResumeMarker, ResumeStorage, RoomChatMessage, RoomDriverFactory, RoomDriverHandlers, RoomEngine, RoomEngineOptions, RoomEventOutcome, RoomEventTopic, RoomReaction, RoomToken, RoomTokenStorage, ScheduleMeetingInput, ShareRegion, SpeakingWhileMutedDetector, SpeakingWhileMutedOptions, Stage, StageArgs, TABLES, TRANSCRIPTION_ATTRIBUTES, TRANSCRIPTION_TOPIC, TokenClient, TokenClientOptions, TokenRequest, TranscriptBlock, TranscriptFormat, TranscriptMatch, UnsupportedReason, VideoEffect, WAITING_PHASES, WrapUpStatus, absenceSentence, activeWrapUpSummary, activityAttention, admissionPhase, announceMeeting, applyRoomEvent, assembleMeetingRecord, attendanceCsv, attendanceReport, attendanceTotals, attendeeKey, autoRejoinDelayMs, availableActivities, callInviteAction, callInviteText, callStateLabel, canModerate, canModerateParticipant, canTransition, captionSegment, changesPatch, classifyDeviceFailure, clockPosition, computeStage, connectionPolicyFrom, countLabel, createCallCenter, createCallInviteHandler, createConnectionSupervisor, createDeviceManager, createInRoomClient, createLiveKitDriver, createMediaSupervisor, createMeetAi, createMeetRepository, createMeetStore, createMeetingInviteHandler, createMeetingRecordCache, createMeetingSession, createMemoryDeviceStorage, createReachabilityProbe, createReconnectPolicy, createRecordingController, createRoomEngine, createSpeakingWhileMutedDetector, createTokenClient, createWebDeviceStorage, createWebEffectsStorage, createWebNetworkPort, createWebResumeStorage, createWebRoomTokenStorage, detectBrowser, detectCapabilities, detectOs, deviceChipLabel, deviceFixSteps, deviceNoticeCode, deviceUnavailableReason, displayNameFor, gridColumns, groupTranscript, guestRecordAccessExplanation, guestRecordAccessLabel, guestRecordAccessSetting, hasEnded, hostUserIds, httpUrlOf, invalidResponse, isGuestIdentity, isJoinRefusalReason, isListenOnly, isLivePhase, isMobileUserAgent, isNoteTaker, isRealName, isRefusedPhase, isRoomEventTopic, isUnannouncedDeparture, isWaitingPhase, learnName, learnNames, leaveChoices, leavePolicyFrom, listenOnlyNotice, loadFollowUpDraft, loadGuestMeetingRecord, loadMeetingChat, loadMeetingRecord, loadMeetingRecordParts, mapConnectionState, mapQuality, meetingInviteAction, meetingLength, meetingLink, meetingPassHeaders, meetingPath, meetingSlug, meetingTopic, meetingWhen, mergeCaption, mergeGhosts, mergeRecord, microphoneNoticeCode, moveToRoom, nextPhase, nextTranslationBatch, normalizeDeviceError, normalizeMeetError, normalizeSpoken, noteTakerIdentity, noteTakerLabel, noteTakerParticipant, noteTakerStatus, notesDocument, observeMeeting, observedDevice, observedPhase, observedQuality, orderParticipants, parseRoomToken, participantAttributes, participantSummary, performCollab, playableRecordingFileId, projectInvitee, projectLibraryRecording, projectNote, projectOccurrence, projectOverride, projectParticipant, projectRsvpInvitation, projectSearchHit, projectSegment, projectUpcoming, pushMeetingToGoogleCalendar, readServerRefusal, readableTranscript, reasonOf, recordingLabel, recordingNotice, recordingOffsetMs, refusalPhase, rememberedMeetingPass, resolveExit, roleOf, roomTopic, rootAttributes, searchTranscript, sendFollowUp, setCaptionLanguage, setGuestRecordAccess, settingsPatch, snapshotParticipant, snippetRuns, staticObservation, summarizeMeetingRecordRestrictions, takeMoveRequest, takePanelRequest, transcriptDocument, unavailableFrom, uniqueAttendees, unsupportedWords, untranslatedLines, userTopic, wasRefused, webMediaPlatform, wrapUpStatus } from './core.js';
2
- export { A as AccessTokenSource, k as AdmissionState, l as CAPTION_LANGUAGES, m as CallId, d as CallInvite, f as CallMode, n as CallState, o as CallablePerson, C as CollabPanel, j as CollabSnapshot, p as ConnectionQuality, E as EMPTY_COLLAB, F as FILE_SESSION_PATH, I as InviteeInput, q as InviteeRole, J as JsonObject, r as JsonValue, L as LobbyEntry, b as MeetApi, s as MeetApiOptions, t as MeetApiRequest, u as MeetAppFocus, v as MeetBreakoutBroadcast, w as MeetBreakoutPlan, x as MeetBreakoutRoom, y as MeetCollabSettings, z as MeetFileMedia, c as MeetIdentity, a as MeetParticipant, B as MeetPoll, D as MeetPollOption, G as MeetPollState, H as MeetQuestion, K as MeetQuestionState, N as MeetStroke, Q as MeetingActivities, i as MeetingAppPanel, V as MeetingAttendee, X as MeetingChanges, h as MeetingId, Y as MeetingInvitee, Z as MeetingKind, g as MeetingNote, _ as MeetingNoteKind, $ as MeetingOccurrence, M as MeetingRecord, a0 as MeetingSettings, a1 as NoteTakerState, a2 as ORGANIZATION_HEADER, a3 as ObserversVisibleTo, a4 as OccurrenceOverride, a5 as OccurrenceState, O as OrganizationId, P as ParticipantIdentity, e as ParticipantRole, a6 as ParticipantStanding, a7 as ROLE_RANK, a8 as RecordingPolicy, a9 as RecordingRecord, aa as RecordingState, R as RoomName, ab as RsvpAnswer, ac as RsvpInvitation, ad as RsvpState, S as StageLayout, ae as TranscriptSegment, T as TranscriptSource, af as UpcomingOccurrence, U as UserId, W as WrapUpAnnouncement, ag as appPanelOf, ah as applyCollabPacket, ai as asCallId, aj as asMeetingId, ak as asOrganizationId, al as asParticipantIdentity, am as asRoomName, an as asUserId, ao as assignedRoom, ap as autoAssign, aq as breakoutClosingMs, ar as breakoutRemainingMs, as as captureHeldOf, at as collabFromState, au as createMeetApi, av as defaultCaptionLanguage, aw as fileDownloadPath, ax as focusFromRow, ay as isGuest, az as isHostRole, aA as isLinkFollower, aB as isObserverRole, aC as loadMeetingActivities, aD as scheduleSettingsPatch, aE as withItem } from './collab-D1TX5uf9.js';
2
+ export { A as AccessTokenSource, k as AdmissionState, l as CAPTION_LANGUAGES, m as CallId, d as CallInvite, f as CallMode, n as CallState, o as CallablePerson, C as CollabPanel, j as CollabSnapshot, p as ConnectionQuality, E as EMPTY_COLLAB, F as FILE_SESSION_PATH, I as InviteeInput, q as InviteeRole, J as JsonObject, r as JsonValue, L as LobbyEntry, b as MeetApi, s as MeetApiOptions, t as MeetApiRequest, u as MeetAppFocus, v as MeetBreakoutBroadcast, w as MeetBreakoutPlan, x as MeetBreakoutRoom, y as MeetCollabSettings, z as MeetFileMedia, c as MeetIdentity, a as MeetParticipant, B as MeetPoll, D as MeetPollOption, G as MeetPollState, H as MeetQuestion, K as MeetQuestionState, N as MeetStroke, Q as MeetingActivities, i as MeetingAppPanel, V as MeetingAttendee, X as MeetingChanges, h as MeetingId, Y as MeetingInvitee, Z as MeetingKind, g as MeetingNote, _ as MeetingNoteKind, $ as MeetingOccurrence, M as MeetingRecord, a0 as MeetingSettings, a1 as NoteTakerState, a2 as ORGANIZATION_HEADER, a3 as ObserversVisibleTo, a4 as OccurrenceOverride, a5 as OccurrenceState, O as OrganizationId, P as ParticipantIdentity, e as ParticipantRole, a6 as ParticipantStanding, a7 as ROLE_RANK, a8 as RecordingPolicy, a9 as RecordingRecord, aa as RecordingState, R as RoomName, ab as RsvpAnswer, ac as RsvpInvitation, ad as RsvpState, S as StageLayout, ae as TranscriptSegment, T as TranscriptSource, af as UpcomingOccurrence, U as UserId, W as WrapUpAnnouncement, ag as appPanelOf, ah as applyCollabPacket, ai as asCallId, aj as asMeetingId, ak as asOrganizationId, al as asParticipantIdentity, am as asRoomName, an as asUserId, ao as assignedRoom, ap as autoAssign, aq as breakoutClosingMs, ar as breakoutRemainingMs, as as captureHeldOf, at as collabFromState, au as createMeetApi, av as defaultCaptionLanguage, aw as fileDownloadPath, ax as focusFromRow, ay as isGuest, az as isHostRole, aA as isLinkFollower, aB as isObserverRole, aC as loadMeetingActivities, aD as scheduleSettingsPatch, aE as withItem } from './collab-Dk3r37MW.js';
3
3
  import '@ai-matrx/realtime';
4
4
  import '@ai-matrx/messaging';
5
5
  import 'livekit-client';
package/dist/index.js CHANGED
@@ -212,10 +212,11 @@ function invalidResponse(operation, detail) {
212
212
 
213
213
  // src/core/connection-supervisor.ts
214
214
  var DEFAULT_CONNECTION_POLICY = {
215
- bannerDelayMs: 2e3,
215
+ bannerDelayMs: 5e3,
216
216
  autoRejoin: true,
217
217
  autoRejoinMaxAttempts: 5,
218
- reconnectGraceSeconds: 30
218
+ reconnectGraceSeconds: 30,
219
+ videoAutoOffAfterPoorSeconds: 20
219
220
  };
220
221
  function clampInt(value, min, max, fallback) {
221
222
  if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
@@ -229,7 +230,8 @@ function connectionPolicyFrom(raw) {
229
230
  bannerDelayMs: clampInt(row["reconnect_banner_delay_ms"], 0, 1e4, d.bannerDelayMs),
230
231
  autoRejoin: typeof row["auto_rejoin"] === "boolean" ? row["auto_rejoin"] : d.autoRejoin,
231
232
  autoRejoinMaxAttempts: clampInt(row["auto_rejoin_max_attempts"], 0, 20, d.autoRejoinMaxAttempts),
232
- reconnectGraceSeconds: clampInt(row["reconnect_grace_seconds"], 0, 600, d.reconnectGraceSeconds)
233
+ reconnectGraceSeconds: clampInt(row["reconnect_grace_seconds"], 0, 600, d.reconnectGraceSeconds),
234
+ videoAutoOffAfterPoorSeconds: clampInt(row["video_auto_off_after_poor_seconds"], 0, 600, d.videoAutoOffAfterPoorSeconds)
233
235
  };
234
236
  }
235
237
  var LIVEKIT_BASE_DELAYS_MS = [0, 300, 1200, 2700, 4800, 7e3];
@@ -3500,11 +3502,14 @@ function recordingLabel(state) {
3500
3502
 
3501
3503
  // src/core/live-policy.ts
3502
3504
  var DEFAULT_LIVE_POLICY = {
3505
+ headlessPowers: "members_admit",
3503
3506
  chatMode: "everyone",
3504
3507
  avLock: "off",
3505
3508
  timeLimitMinutes: 0,
3506
3509
  timeLimitWarningMinutes: 5,
3507
- recordingConsent: "notice"
3510
+ recordingConsent: "notice",
3511
+ shareWhoCan: "everyone",
3512
+ shareConcurrency: "one_takeover"
3508
3513
  };
3509
3514
  function oneOf(value, allowed, fallback) {
3510
3515
  return typeof value === "string" && allowed.includes(value) ? value : fallback;
@@ -3516,6 +3521,7 @@ function whole(value, fallback) {
3516
3521
  function livePolicyFrom(raw) {
3517
3522
  const o = typeof raw === "object" && raw !== null ? raw : {};
3518
3523
  return {
3524
+ headlessPowers: oneOf(o["headless_powers"], ["members_admit", "none", "cohosts_only"], DEFAULT_LIVE_POLICY.headlessPowers),
3519
3525
  chatMode: oneOf(o["chat_mode"], ["everyone", "hosts_only", "off"], DEFAULT_LIVE_POLICY.chatMode),
3520
3526
  avLock: oneOf(o["attendee_av_lock"], ["off", "mic", "camera", "both"], DEFAULT_LIVE_POLICY.avLock),
3521
3527
  timeLimitMinutes: whole(o["time_limit_minutes"], 0),
@@ -3524,11 +3530,13 @@ function livePolicyFrom(raw) {
3524
3530
  o["recording_consent"],
3525
3531
  ["notice", "ok_or_leave", "view_only_until_agree"],
3526
3532
  DEFAULT_LIVE_POLICY.recordingConsent
3527
- )
3533
+ ),
3534
+ shareWhoCan: oneOf(o["share_who_can"], ["everyone", "host_only", "org", "presenters"], DEFAULT_LIVE_POLICY.shareWhoCan),
3535
+ shareConcurrency: oneOf(o["share_concurrency"], ["one_takeover", "one_replace", "multiple"], DEFAULT_LIVE_POLICY.shareConcurrency)
3528
3536
  };
3529
3537
  }
3530
3538
  function samePolicy(a, b) {
3531
- return a.chatMode === b.chatMode && a.avLock === b.avLock && a.timeLimitMinutes === b.timeLimitMinutes && a.timeLimitWarningMinutes === b.timeLimitWarningMinutes && a.recordingConsent === b.recordingConsent;
3539
+ return a.headlessPowers === b.headlessPowers && a.chatMode === b.chatMode && a.avLock === b.avLock && a.timeLimitMinutes === b.timeLimitMinutes && a.timeLimitWarningMinutes === b.timeLimitWarningMinutes && a.recordingConsent === b.recordingConsent && a.shareWhoCan === b.shareWhoCan && a.shareConcurrency === b.shareConcurrency;
3532
3540
  }
3533
3541
  var MODERATORS = /* @__PURE__ */ new Set(["host", "cohost"]);
3534
3542
  function isLockedFor(policy, role, kind) {
@@ -3538,6 +3546,12 @@ function isLockedFor(policy, role, kind) {
3538
3546
  function consentPending(policy, role, recordingOn, given) {
3539
3547
  return recordingOn && !given && policy.recordingConsent !== "notice" && !MODERATORS.has(role);
3540
3548
  }
3549
+ function mayAdmitNow(role, participants, policy) {
3550
+ if (role === "none") return false;
3551
+ if (role === "host" || role === "cohost") return true;
3552
+ const hostIn = participants.some((p) => p.role === "host" || p.role === "cohost");
3553
+ return !hostIn && policy.headlessPowers === "members_admit";
3554
+ }
3541
3555
 
3542
3556
  // src/core/attendance.ts
3543
3557
  var IDLE_PREVIEW = { state: "idle", unavailable: null };
@@ -3577,6 +3591,7 @@ var NO_GRANTS = {
3577
3591
  canPublish: false,
3578
3592
  canSubscribe: false
3579
3593
  };
3594
+ var UNKNOWN_LOCAL_NETWORK = { path: "unknown", quality: "unknown", videoPaused: false };
3580
3595
  var NO_SHARE = { state: "none", reason: null, remedy: null, at: 0 };
3581
3596
  var EMPTY = {
3582
3597
  phase: "resolving",
@@ -3585,6 +3600,7 @@ var EMPTY = {
3585
3600
  roomName: null,
3586
3601
  connection: "stable",
3587
3602
  connectionBanner: false,
3603
+ localNetwork: UNKNOWN_LOCAL_NETWORK,
3588
3604
  share: NO_SHARE,
3589
3605
  call: null,
3590
3606
  waiting: null,
@@ -4099,6 +4115,14 @@ function applyModeration(store, payload, now) {
4099
4115
  }
4100
4116
  return HANDLED;
4101
4117
  }
4118
+ case "share-ended": {
4119
+ const reason = text2(payload["reason"]) === "not_allowed" ? "not_allowed" : "replaced";
4120
+ const by = text2(payload["by"]);
4121
+ store.patch({
4122
+ share: { state: "ended", reason, remedy: null, at: now(), ...by !== null ? { by } : {} }
4123
+ });
4124
+ return HANDLED;
4125
+ }
4102
4126
  case "muted":
4103
4127
  case "ask-unmute":
4104
4128
  case "removed": {
@@ -4511,7 +4535,7 @@ function unsupportedWords(capabilities) {
4511
4535
  body: "Open this link in Chrome, Safari, Edge or Firefox"
4512
4536
  };
4513
4537
  }
4514
- return { title: "This browser can't join calls", body: "Open this link in Chrome, Safari, Edge or Firefox" };
4538
+ return { title: "Meet is not compatible with your browser yet", body: "Open this link in Chrome, Safari, Edge or Firefox" };
4515
4539
  }
4516
4540
 
4517
4541
  // src/core/room-driver.ts
@@ -4534,6 +4558,187 @@ var TRANSCRIPTION_ATTRIBUTES = {
4534
4558
  speakerIdentity: "lk.transcribed_participant_identity"
4535
4559
  };
4536
4560
 
4561
+ // src/core/network-health.ts
4562
+ function pathOf(reading) {
4563
+ if (reading.relayed === null && reading.tcp === null) return "unknown";
4564
+ return reading.relayed === true || reading.tcp === true ? "restricted" : "direct";
4565
+ }
4566
+ var POOR_RTT_MS = 300;
4567
+ var RECOVERED_RTT_MS = 220;
4568
+ var POOR_LOSS = 0.08;
4569
+ var RECOVERED_LOSS = 0.03;
4570
+ function createSelfAssessor(options = {}) {
4571
+ const poorSamples = options.poorSamples ?? 2;
4572
+ const goodSamples = options.goodSamples ?? 3;
4573
+ let quality = "unknown";
4574
+ let badRun = 0;
4575
+ let goodRun = 0;
4576
+ return {
4577
+ push(reading) {
4578
+ const { rttMs, lossRatio } = reading;
4579
+ if (rttMs === null && lossRatio === null) return quality;
4580
+ const bad = rttMs !== null && rttMs >= POOR_RTT_MS || lossRatio !== null && lossRatio >= POOR_LOSS;
4581
+ const clear = (rttMs === null || rttMs < RECOVERED_RTT_MS) && (lossRatio === null || lossRatio < RECOVERED_LOSS);
4582
+ badRun = bad ? badRun + 1 : 0;
4583
+ goodRun = clear ? goodRun + 1 : 0;
4584
+ if (badRun >= poorSamples) quality = "poor";
4585
+ else if (quality !== "poor" && !bad) quality = "good";
4586
+ else if (quality === "poor" && goodRun >= goodSamples) quality = "good";
4587
+ return quality;
4588
+ },
4589
+ current: () => quality,
4590
+ reset() {
4591
+ quality = "unknown";
4592
+ badRun = 0;
4593
+ goodRun = 0;
4594
+ }
4595
+ };
4596
+ }
4597
+ var RANK = {
4598
+ lost: 0,
4599
+ poor: 1,
4600
+ good: 2,
4601
+ excellent: 3,
4602
+ unknown: 4
4603
+ };
4604
+ function worstQuality(a, b) {
4605
+ if (b === null || b === void 0 || b === "unknown") return a;
4606
+ if (a === "unknown") return b;
4607
+ return RANK[b] < RANK[a] ? b : a;
4608
+ }
4609
+ var ALIVE_TOPIC = "mx.alive";
4610
+ function encodeBeat(beat) {
4611
+ return JSON.stringify({ q: beat.q, vp: beat.vp });
4612
+ }
4613
+ function decodeBeat(payload) {
4614
+ try {
4615
+ const raw = JSON.parse(payload);
4616
+ const q = raw.q === "good" || raw.q === "poor" ? raw.q : "unknown";
4617
+ return { q, vp: raw.vp === true };
4618
+ } catch {
4619
+ return null;
4620
+ }
4621
+ }
4622
+ function heartbeatIntervalMs(roomSize) {
4623
+ return 2e3 * Math.max(1, Math.ceil(Math.max(1, roomSize) / 25));
4624
+ }
4625
+ function staleAfterMs(roomSize) {
4626
+ return heartbeatIntervalMs(roomSize) * 3 + 1e3;
4627
+ }
4628
+ function createLivenessTracker(now) {
4629
+ const lastHeard = /* @__PURE__ */ new Map();
4630
+ const beats = /* @__PURE__ */ new Map();
4631
+ return {
4632
+ heard(who, beat) {
4633
+ lastHeard.set(who, now());
4634
+ if (beat !== null) beats.set(who, beat);
4635
+ },
4636
+ stale(present, roomSize) {
4637
+ const limit = staleAfterMs(roomSize);
4638
+ const at = now();
4639
+ const out = /* @__PURE__ */ new Set();
4640
+ for (const who of present) {
4641
+ const heard = lastHeard.get(who);
4642
+ if (heard !== void 0 && at - heard > limit) out.add(who);
4643
+ }
4644
+ return out;
4645
+ },
4646
+ reported: (who) => beats.get(who) ?? null,
4647
+ restartClock() {
4648
+ const at = now();
4649
+ for (const who of lastHeard.keys()) lastHeard.set(who, at);
4650
+ },
4651
+ forget(who) {
4652
+ lastHeard.delete(who);
4653
+ beats.delete(who);
4654
+ },
4655
+ clear() {
4656
+ lastHeard.clear();
4657
+ beats.clear();
4658
+ }
4659
+ };
4660
+ }
4661
+ function createVideoAutoOff(afterMs, now) {
4662
+ let poorSince = null;
4663
+ let armed = true;
4664
+ return {
4665
+ step(quality, cameraOn) {
4666
+ if (quality === "good") {
4667
+ poorSince = null;
4668
+ armed = true;
4669
+ return null;
4670
+ }
4671
+ if (quality !== "poor" || !cameraOn) {
4672
+ poorSince = quality === "poor" ? poorSince : null;
4673
+ return null;
4674
+ }
4675
+ const at = now();
4676
+ if (poorSince === null) poorSince = at;
4677
+ const limit = afterMs();
4678
+ if (!armed || limit <= 0 || at - poorSince < limit) return null;
4679
+ armed = false;
4680
+ return "pause";
4681
+ },
4682
+ retried() {
4683
+ armed = false;
4684
+ },
4685
+ reset() {
4686
+ poorSince = null;
4687
+ armed = true;
4688
+ }
4689
+ };
4690
+ }
4691
+ function readingFromStats(entries) {
4692
+ const byId2 = /* @__PURE__ */ new Map();
4693
+ for (const entry of entries) byId2.set(entry.id, entry);
4694
+ let pair;
4695
+ for (const entry of byId2.values()) {
4696
+ if (entry.type === "transport" && typeof entry["selectedCandidatePairId"] === "string") {
4697
+ pair = byId2.get(entry["selectedCandidatePairId"]);
4698
+ if (pair !== void 0) break;
4699
+ }
4700
+ }
4701
+ if (pair === void 0) {
4702
+ for (const entry of byId2.values()) {
4703
+ if (entry.type === "candidate-pair" && entry["nominated"] === true && entry["state"] === "succeeded") {
4704
+ pair = entry;
4705
+ break;
4706
+ }
4707
+ }
4708
+ }
4709
+ let lossRatio = null;
4710
+ for (const entry of byId2.values()) {
4711
+ if (entry.type === "remote-inbound-rtp" && typeof entry["fractionLost"] === "number") {
4712
+ lossRatio = Math.max(lossRatio ?? 0, entry["fractionLost"]);
4713
+ }
4714
+ }
4715
+ if (pair === void 0) return { rttMs: null, lossRatio, relayed: null, tcp: null };
4716
+ const rtt = pair["currentRoundTripTime"];
4717
+ const local = typeof pair["localCandidateId"] === "string" ? byId2.get(pair["localCandidateId"]) : void 0;
4718
+ const candidateType = local?.["candidateType"];
4719
+ const protocol = local?.["protocol"];
4720
+ const relayProtocol = local?.["relayProtocol"];
4721
+ return {
4722
+ rttMs: typeof rtt === "number" ? Math.round(rtt * 1e3) : null,
4723
+ lossRatio,
4724
+ relayed: typeof candidateType === "string" ? candidateType === "relay" : null,
4725
+ tcp: typeof protocol === "string" || typeof relayProtocol === "string" ? protocol === "tcp" || relayProtocol === "tcp" || relayProtocol === "tls" : null
4726
+ };
4727
+ }
4728
+ function mergeReadings(readings) {
4729
+ const max = (values) => {
4730
+ const known = values.filter((v) => v !== null);
4731
+ return known.length === 0 ? null : Math.max(...known);
4732
+ };
4733
+ const any = (values) => values.every((v) => v === null) ? null : values.some((v) => v === true);
4734
+ return {
4735
+ rttMs: max(readings.map((r) => r.rttMs)),
4736
+ lossRatio: max(readings.map((r) => r.lossRatio)),
4737
+ relayed: any(readings.map((r) => r.relayed)),
4738
+ tcp: any(readings.map((r) => r.tcp))
4739
+ };
4740
+ }
4741
+
4537
4742
  // src/core/livekit-driver.ts
4538
4743
  function mapQuality(quality) {
4539
4744
  switch (quality) {
@@ -4623,6 +4828,30 @@ function createLiveKitDriver(handlers, options = {}) {
4623
4828
  let projectRoster = null;
4624
4829
  let audioCapture = DEFAULT_AUDIO_PROCESSING;
4625
4830
  let videoEffect = { kind: "none" };
4831
+ let statsTimer = null;
4832
+ function stopStatsPoll() {
4833
+ if (statsTimer !== null) clearInterval(statsTimer);
4834
+ statsTimer = null;
4835
+ }
4836
+ function startStatsPoll(target) {
4837
+ stopStatsPoll();
4838
+ if (handlers.networkReading === void 0) return;
4839
+ const sample = async () => {
4840
+ if (room !== target) return;
4841
+ const manager = target.engine.pcManager;
4842
+ if (manager === void 0) return;
4843
+ const readings = [];
4844
+ for (const transport of [manager.publisher, manager.subscriber]) {
4845
+ try {
4846
+ const report = await transport?.getStats();
4847
+ if (report !== void 0) readings.push(readingFromStats(report.values()));
4848
+ } catch {
4849
+ }
4850
+ }
4851
+ if (readings.length > 0 && room === target) handlers.networkReading?.(mergeReadings(readings));
4852
+ };
4853
+ statsTimer = setInterval(() => void sample(), 2e3);
4854
+ }
4626
4855
  async function load() {
4627
4856
  if (room !== null) return room;
4628
4857
  let module;
@@ -4697,6 +4926,7 @@ function createLiveKitDriver(handlers, options = {}) {
4697
4926
  participant?.identity ?? null
4698
4927
  );
4699
4928
  }).on(RoomEvent.Disconnected, (reason) => {
4929
+ stopStatsPoll();
4700
4930
  audioContainer?.remove();
4701
4931
  audioContainer = null;
4702
4932
  handlers.disconnected(reasonName(reason));
@@ -4782,6 +5012,7 @@ function createLiveKitDriver(handlers, options = {}) {
4782
5012
  projectRoster?.();
4783
5013
  handlers.roomMetadata?.(target.metadata ?? "");
4784
5014
  handlers.audioPlayback?.(target.canPlaybackAudio);
5015
+ startStatsPoll(target);
4785
5016
  },
4786
5017
  async disconnect() {
4787
5018
  if (room === null) return;
@@ -4792,6 +5023,7 @@ function createLiveKitDriver(handlers, options = {}) {
4792
5023
  } catch {
4793
5024
  }
4794
5025
  projectRoster = null;
5026
+ stopStatsPoll();
4795
5027
  audioContainer?.remove();
4796
5028
  audioContainer = null;
4797
5029
  await target.disconnect();
@@ -6568,6 +6800,76 @@ function createRoomEngine(options) {
6568
6800
  return personConnections.get(personOf(who)) ?? [who];
6569
6801
  }
6570
6802
  const departures = /* @__PURE__ */ new Map();
6803
+ const liveness = createLivenessTracker(now);
6804
+ const assessor = createSelfAssessor();
6805
+ const autoOff = createVideoAutoOff(() => connectionPolicy.videoAutoOffAfterPoorSeconds * 1e3, now);
6806
+ const lkQuality = /* @__PURE__ */ new Map();
6807
+ let silent = /* @__PURE__ */ new Set();
6808
+ let healthTimer = null;
6809
+ let lastBeatAt = 0;
6810
+ let wasUnstable = false;
6811
+ function patchLocalNetwork(next) {
6812
+ const before = store.snapshot().localNetwork;
6813
+ const merged = { ...before, ...next };
6814
+ if (merged.path !== before.path || merged.quality !== before.quality || merged.videoPaused !== before.videoPaused) {
6815
+ store.patch({ localNetwork: merged });
6816
+ }
6817
+ }
6818
+ function effectiveQuality(person, connection, isLocal) {
6819
+ const fromServer = lkQuality.get(person) ?? "unknown";
6820
+ if (isLocal) return worstQuality(fromServer, assessor.current());
6821
+ return worstQuality(fromServer, connection === void 0 ? null : liveness.reported(connection)?.q);
6822
+ }
6823
+ function refreshQualities() {
6824
+ const snap = store.snapshot();
6825
+ for (const p of snap.participants) {
6826
+ if (p.reconnecting === true) continue;
6827
+ const next = effectiveQuality(p.identity, mainConnection.get(p.identity), p.isLocal);
6828
+ if (next !== "unknown" && next !== p.quality) store.setQuality(p.identity, next);
6829
+ }
6830
+ }
6831
+ function stopHealth() {
6832
+ if (healthTimer !== null) clearInterval(healthTimer);
6833
+ healthTimer = null;
6834
+ liveness.clear();
6835
+ assessor.reset();
6836
+ autoOff.reset();
6837
+ silent = /* @__PURE__ */ new Set();
6838
+ lkQuality.clear();
6839
+ lastBeatAt = 0;
6840
+ wasUnstable = false;
6841
+ if (store.snapshot().localNetwork !== UNKNOWN_LOCAL_NETWORK) store.patch({ localNetwork: UNKNOWN_LOCAL_NETWORK });
6842
+ }
6843
+ function healthTick() {
6844
+ const snap = store.snapshot();
6845
+ const target = driver;
6846
+ if (disposed || target === null || snap.phase !== "in_call") return;
6847
+ if (snap.connection !== "stable") {
6848
+ wasUnstable = true;
6849
+ return;
6850
+ }
6851
+ if (wasUnstable) {
6852
+ wasUnstable = false;
6853
+ liveness.restartClock();
6854
+ }
6855
+ const size = liveRoster.length;
6856
+ const at = now();
6857
+ if (at - lastBeatAt >= heartbeatIntervalMs(size)) {
6858
+ lastBeatAt = at;
6859
+ const beat = encodeBeat({ q: assessor.current(), vp: snap.localNetwork.videoPaused });
6860
+ void target.publishData(ALIVE_TOPIC, beat).catch(() => void 0);
6861
+ }
6862
+ const remotes = liveRoster.filter((p) => !p.isLocal).map((p) => p.identity);
6863
+ const next = liveness.stale(remotes, size);
6864
+ if (next.size !== silent.size || [...next].some((who) => !silent.has(who))) {
6865
+ silent = next;
6866
+ projectRoster(liveRoster, new Date(at).toISOString());
6867
+ }
6868
+ }
6869
+ function startHealth() {
6870
+ if (healthTimer !== null) return;
6871
+ healthTimer = setInterval(healthTick, 1e3);
6872
+ }
6571
6873
  function requestAsNow() {
6572
6874
  if (lastRequest === null) return null;
6573
6875
  const media2 = store.snapshot().media;
@@ -6586,6 +6888,7 @@ function createRoomEngine(options) {
6586
6888
  media.onDisconnected();
6587
6889
  store.patch({ share: NO_SHARE, connection: "stable" });
6588
6890
  clearGhosts();
6891
+ stopHealth();
6589
6892
  await target?.disconnect();
6590
6893
  }
6591
6894
  async function leaveRoom() {
@@ -6677,6 +6980,8 @@ function createRoomEngine(options) {
6677
6980
  },
6678
6981
  participantLeft(who, reason) {
6679
6982
  departures.set(who, reason);
6983
+ liveness.forget(who);
6984
+ silent.delete(who);
6680
6985
  },
6681
6986
  roomMetadata(metadata) {
6682
6987
  let parsed = {};
@@ -6710,7 +7015,27 @@ function createRoomEngine(options) {
6710
7015
  store.setSpeaking([...new Set(identities.map((who) => personOf(who)))]);
6711
7016
  },
6712
7017
  quality(who, value) {
6713
- store.setQuality(personOf(who), value);
7018
+ const person = personOf(who);
7019
+ lkQuality.set(person, value);
7020
+ const local = store.snapshot().participants.find((p) => p.identity === person)?.isLocal === true;
7021
+ store.setQuality(person, value === "lost" ? value : effectiveQuality(person, who, local));
7022
+ },
7023
+ networkReading(reading) {
7024
+ const snap = store.snapshot();
7025
+ if (snap.phase !== "in_call" || snap.connection !== "stable") return;
7026
+ startHealth();
7027
+ const quality = assessor.push(reading);
7028
+ const path = pathOf(reading);
7029
+ patchLocalNetwork({ quality, ...path !== "unknown" ? { path } : {} });
7030
+ refreshQualities();
7031
+ const cameraOn = snap.media.camera.enabled;
7032
+ if (autoOff.step(quality, cameraOn) === "pause" && driver !== null) {
7033
+ const target = driver;
7034
+ report("info", "meet: the camera was paused because the connection is poor", "The audio is kept; Try video again turns it back on.");
7035
+ void enableTrack(target, "camera", false).then((state) => {
7036
+ if (!state.enabled) patchLocalNetwork({ videoPaused: true });
7037
+ });
7038
+ }
6714
7039
  },
6715
7040
  connectionState(state) {
6716
7041
  supervisor.driverState(state);
@@ -6805,6 +7130,22 @@ function createRoomEngine(options) {
6805
7130
  return;
6806
7131
  }
6807
7132
  const sender = personOf(from ?? "");
7133
+ if (from !== null) {
7134
+ const beat = topic === ALIVE_TOPIC ? decodeBeat(payload) : null;
7135
+ const before = liveness.reported(from);
7136
+ liveness.heard(from, beat);
7137
+ if (topic === ALIVE_TOPIC) {
7138
+ startHealth();
7139
+ if (beat !== null && (before?.q !== beat.q || before?.vp !== beat.vp || silent.has(from))) {
7140
+ silent.delete(from);
7141
+ projectRoster(liveRoster, new Date(now()).toISOString());
7142
+ refreshQualities();
7143
+ } else if (silent.delete(from)) {
7144
+ projectRoster(liveRoster, new Date(now()).toISOString());
7145
+ }
7146
+ return;
7147
+ }
7148
+ }
6808
7149
  switch (topic) {
6809
7150
  case DATA_TOPICS.reaction:
6810
7151
  if (typeof envelope.emoji === "string") {
@@ -7047,7 +7388,16 @@ function createRoomEngine(options) {
7047
7388
  store.setParticipants(
7048
7389
  [...people.values()].map(({ entry }) => {
7049
7390
  const projected = projectParticipant(entry, joinedAt);
7050
- return entry.reconnecting === true ? { ...projected, reconnecting: true, quality: "lost" } : projected;
7391
+ if (entry.reconnecting === true || !entry.isLocal && silent.has(entry.identity)) {
7392
+ return { ...projected, reconnecting: true, quality: "lost" };
7393
+ }
7394
+ const videoPaused = entry.isLocal ? store.snapshot().localNetwork.videoPaused : liveness.reported(entry.identity)?.vp === true;
7395
+ const quality = effectiveQuality(projected.identity, entry.identity, entry.isLocal);
7396
+ return {
7397
+ ...projected,
7398
+ ...quality !== "unknown" && quality !== "lost" ? { quality } : {},
7399
+ ...videoPaused ? { videoPaused: true } : {}
7400
+ };
7051
7401
  })
7052
7402
  );
7053
7403
  scheduleGhostExpiry();
@@ -7233,7 +7583,12 @@ function createRoomEngine(options) {
7233
7583
  },
7234
7584
  async setCameraEnabled(enabled) {
7235
7585
  if (driver === null) return;
7236
- await enableTrack(driver, "camera", enabled);
7586
+ const state = await enableTrack(driver, "camera", enabled);
7587
+ if (enabled && state.enabled && store.snapshot().localNetwork.videoPaused) {
7588
+ autoOff.retried();
7589
+ patchLocalNetwork({ videoPaused: false });
7590
+ }
7591
+ if (!enabled && store.snapshot().localNetwork.videoPaused) patchLocalNetwork({ videoPaused: false });
7237
7592
  },
7238
7593
  async setScreenShareEnabled(enabled) {
7239
7594
  if (driver === null) return;
@@ -7279,7 +7634,8 @@ function createRoomEngine(options) {
7279
7634
  }
7280
7635
  },
7281
7636
  dismissShareNotice() {
7282
- if (store.snapshot().share.state === "refused") store.patch({ share: NO_SHARE });
7637
+ const state = store.snapshot().share.state;
7638
+ if (state === "refused" || state === "ended") store.patch({ share: NO_SHARE });
7283
7639
  },
7284
7640
  async react(emoji) {
7285
7641
  const local = store.snapshot().localIdentity;
@@ -8313,6 +8669,7 @@ async function moveToRoom(runtime, roomId) {
8313
8669
  if (runtime === null) return { ok: false, message: "This meeting is not connected." };
8314
8670
  try {
8315
8671
  await runtime.engine.moveToBreakout(roomId);
8672
+ await runtime.inRoom.loadCollab?.().catch(() => void 0);
8316
8673
  return { ok: true, message: roomId === null ? "Back in the main room." : "Joined the breakout room." };
8317
8674
  } catch (error) {
8318
8675
  return { ok: false, message: error.message ?? "That room could not be joined." };
@@ -8396,7 +8753,7 @@ function observe(input) {
8396
8753
  const phase = observedPhase(input);
8397
8754
  const inCall = phase === "in_call";
8398
8755
  const actual = inCall && snapshot !== null ? effectiveRole(snapshot) : "none";
8399
- const canAdmit = actual !== "none" && ADMITTER_ROLES.has(actual);
8756
+ const canAdmit = snapshot !== null && mayAdmitNow(actual, snapshot.participants, snapshot.livePolicy);
8400
8757
  const role = actual === "none" || snapshot === null ? "none" : observedRole(actual, effectiveStanding(snapshot));
8401
8758
  const deviceInPlay = phase === "joining" || inCall;
8402
8759
  const region = snapshot?.mediaRegion;