@arbidocs/react 0.5.110 → 0.5.112
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/PdfViewerImpl-QUSDLNNM.cjs +380 -0
- package/dist/PdfViewerImpl-QUSDLNNM.cjs.map +1 -0
- package/dist/{PdfViewer.d-bQH9yxFg.d.cts → PdfViewerImpl.d-B28hLEuj.d.ts} +8 -1
- package/dist/account/client.js +96 -0
- package/dist/account/client.js.map +7 -0
- package/dist/account/delete.js +70 -0
- package/dist/account/delete.js.map +7 -0
- package/dist/account/didit.js +34 -0
- package/dist/account/didit.js.map +7 -0
- package/dist/account/dismissed-tips.js +33 -0
- package/dist/account/dismissed-tips.js.map +7 -0
- package/dist/account/email.js +84 -0
- package/dist/account/email.js.map +7 -0
- package/dist/account/entitlements.js +47 -0
- package/dist/account/entitlements.js.map +7 -0
- package/dist/account/identity.js +270 -0
- package/dist/account/identity.js.map +7 -0
- package/dist/account/index.js +93 -0
- package/dist/account/index.js.map +7 -0
- package/dist/account/notifications.js +59 -0
- package/dist/account/notifications.js.map +7 -0
- package/dist/account/password.js +103 -0
- package/dist/account/password.js.map +7 -0
- package/dist/account/profile.js +116 -0
- package/dist/account/profile.js.map +7 -0
- package/dist/account/recovery.js +13 -0
- package/dist/account/recovery.js.map +7 -0
- package/dist/account/relevance.js +82 -0
- package/dist/account/relevance.js.map +7 -0
- package/dist/account/sessions.js +37 -0
- package/dist/account/sessions.js.map +7 -0
- package/dist/account/settings.js +39 -0
- package/dist/account/settings.js.map +7 -0
- package/dist/account/table-views.js +16 -0
- package/dist/account/table-views.js.map +7 -0
- package/dist/ai/AiAnswer.js +83 -0
- package/dist/ai/AiAnswer.js.map +7 -0
- package/dist/ai/AiMarkdown.js +40 -0
- package/dist/ai/AiMarkdown.js.map +7 -0
- package/dist/ai/ArtifactCanvas.js +193 -0
- package/dist/ai/ArtifactCanvas.js.map +7 -0
- package/dist/ai/CitationRenderer.js +413 -0
- package/dist/ai/CitationRenderer.js.map +7 -0
- package/dist/{chunk-WL2Y2T47.js → ai/MarkdownRenderer.js} +35 -101
- package/dist/ai/MarkdownRenderer.js.map +7 -0
- package/dist/ai/MessageArtifactCard.js +75 -0
- package/dist/ai/MessageArtifactCard.js.map +7 -0
- package/dist/ai/PassageCard.js +79 -0
- package/dist/ai/PassageCard.js.map +7 -0
- package/dist/ai/engine.js +110 -0
- package/dist/ai/engine.js.map +7 -0
- package/dist/ai/index.js +63 -0
- package/dist/ai/index.js.map +7 -0
- package/dist/ai/markdown-base-components.js +37 -0
- package/dist/ai/markdown-base-components.js.map +7 -0
- package/dist/ai/markdown-streaming-context.js +6 -0
- package/dist/ai/markdown-streaming-context.js.map +7 -0
- package/dist/{chunk-VSCU7K4V.js → ai/normalize-citations.js} +12 -19
- package/dist/ai/normalize-citations.js.map +7 -0
- package/dist/ai/redline.js +41 -0
- package/dist/ai/redline.js.map +7 -0
- package/dist/ai/split-markdown-blocks.js +40 -0
- package/dist/ai/split-markdown-blocks.js.map +7 -0
- package/dist/{chunk-UW2SGTI5.js → ai/stored-markdown.js} +41 -93
- package/dist/ai/stored-markdown.js.map +7 -0
- package/dist/annotations/AnnotationPageOverlay.js +807 -0
- package/dist/annotations/AnnotationPageOverlay.js.map +7 -0
- package/dist/annotations/AnnotationToolbar.js +398 -0
- package/dist/annotations/AnnotationToolbar.js.map +7 -0
- package/dist/annotations/FreezeDialog.js +170 -0
- package/dist/annotations/FreezeDialog.js.map +7 -0
- package/dist/annotations/ProductionDialog.js +354 -0
- package/dist/annotations/ProductionDialog.js.map +7 -0
- package/dist/annotations/controller.js +49 -0
- package/dist/annotations/controller.js.map +7 -0
- package/dist/annotations/freeze/browser.js +21 -0
- package/dist/annotations/freeze/browser.js.map +7 -0
- package/dist/annotations/freeze/bundle.js +201 -0
- package/dist/annotations/freeze/bundle.js.map +7 -0
- package/dist/annotations/freeze/coords.js +37 -0
- package/dist/annotations/freeze/coords.js.map +7 -0
- package/dist/annotations/freeze/freeze.js +261 -0
- package/dist/annotations/freeze/freeze.js.map +7 -0
- package/dist/annotations/freeze/hash.js +28 -0
- package/dist/annotations/freeze/hash.js.map +7 -0
- package/dist/annotations/freeze/index-page.js +78 -0
- package/dist/annotations/freeze/index-page.js.map +7 -0
- package/dist/annotations/freeze/index.d.ts +1 -1
- package/dist/annotations/freeze/index.js +28 -22
- package/dist/annotations/freeze/index.js.map +7 -1
- package/dist/annotations/freeze/raster.js +208 -0
- package/dist/annotations/freeze/raster.js.map +7 -0
- package/dist/annotations/freeze/stamp.js +117 -0
- package/dist/annotations/freeze/stamp.js.map +7 -0
- package/dist/annotations/freeze/types.js +14 -0
- package/dist/annotations/freeze/types.js.map +7 -0
- package/dist/annotations/freeze/vector.js +283 -0
- package/dist/annotations/freeze/vector.js.map +7 -0
- package/dist/annotations/geometry.js +81 -0
- package/dist/annotations/geometry.js.map +7 -0
- package/dist/annotations/index.js +125 -6
- package/dist/annotations/index.js.map +7 -1
- package/dist/annotations/merge.js +53 -0
- package/dist/annotations/merge.js.map +7 -0
- package/dist/{chunk-T3USOSVN.js → annotations/model.js} +23 -16
- package/dist/annotations/model.js.map +7 -0
- package/dist/annotations/overlay-geometry.js +41 -0
- package/dist/annotations/overlay-geometry.js.map +7 -0
- package/dist/annotations/redaction-log.js +33 -0
- package/dist/annotations/redaction-log.js.map +7 -0
- package/dist/annotations/selection-marks.js +122 -0
- package/dist/annotations/selection-marks.js.map +7 -0
- package/dist/annotations/state.js +140 -0
- package/dist/annotations/state.js.map +7 -0
- package/dist/annotations/store.js +49 -0
- package/dist/annotations/store.js.map +7 -0
- package/dist/annotations/useAnnotationLayer.js +306 -0
- package/dist/annotations/useAnnotationLayer.js.map +7 -0
- package/dist/annotations/useAnnotationShortcuts.js +31 -0
- package/dist/annotations/useAnnotationShortcuts.js.map +7 -0
- package/dist/annotations/useTextSelectionMarks.js +100 -0
- package/dist/annotations/useTextSelectionMarks.js.map +7 -0
- package/dist/artifacts/artifact-kind.js +19 -0
- package/dist/artifacts/artifact-kind.js.map +7 -0
- package/dist/artifacts/index.cjs +13 -13
- package/dist/artifacts/index.js +89 -571
- package/dist/artifacts/index.js.map +7 -1
- package/dist/{chunk-WUTL62MC.js → artifacts/normalize-markdown.js} +12 -14
- package/dist/artifacts/normalize-markdown.js.map +7 -0
- package/dist/artifacts/redline-core.js +12 -3
- package/dist/artifacts/redline-core.js.map +7 -1
- package/dist/{chunk-74N436VK.js → artifacts/redline-diff.js} +10 -9
- package/dist/artifacts/redline-diff.js.map +7 -0
- package/dist/artifacts/redline-engine.js +14 -0
- package/dist/artifacts/redline-engine.js.map +7 -0
- package/dist/artifacts/renderArtifactMarkdown.js +9 -0
- package/dist/artifacts/renderArtifactMarkdown.js.map +7 -0
- package/dist/artifacts/useArtifactEditSession.js +183 -0
- package/dist/artifacts/useArtifactEditSession.js.map +7 -0
- package/dist/artifacts/useArtifactSession.js +173 -0
- package/dist/artifacts/useArtifactSession.js.map +7 -0
- package/dist/artifacts/useArtifactSource.js +16 -0
- package/dist/artifacts/useArtifactSource.js.map +7 -0
- package/dist/artifacts/useArtifactText.js +78 -0
- package/dist/artifacts/useArtifactText.js.map +7 -0
- package/dist/artifacts/useRedline.js +65 -0
- package/dist/artifacts/useRedline.js.map +7 -0
- package/dist/artifacts/useStreamedArtifact.js +74 -0
- package/dist/artifacts/useStreamedArtifact.js.map +7 -0
- package/dist/artifacts/versions.js +68 -0
- package/dist/artifacts/versions.js.map +7 -0
- package/dist/billing.js +200 -0
- package/dist/billing.js.map +7 -0
- package/dist/boot-timeout.js +19 -0
- package/dist/boot-timeout.js.map +7 -0
- package/dist/calendar/accounts.js +213 -0
- package/dist/calendar/accounts.js.map +7 -0
- package/dist/calendar/hooks.js +409 -0
- package/dist/calendar/hooks.js.map +7 -0
- package/dist/calendar/index.js +31 -0
- package/dist/calendar/index.js.map +7 -0
- package/dist/calendar/keys.js +5 -0
- package/dist/calendar/keys.js.map +7 -0
- package/dist/calendar/offline/outbox.js +231 -0
- package/dist/calendar/offline/outbox.js.map +7 -0
- package/dist/calendar/offline/runtime.js +109 -0
- package/dist/calendar/offline/runtime.js.map +7 -0
- package/dist/calendar/offline/support.js +41 -0
- package/dist/calendar/offline/support.js.map +7 -0
- package/dist/calendar/support.js +34 -0
- package/dist/calendar/support.js.map +7 -0
- package/dist/calls/actions.js +226 -0
- package/dist/calls/actions.js.map +7 -0
- package/dist/calls/events.js +138 -0
- package/dist/calls/events.js.map +7 -0
- package/dist/calls/gate.js +19 -0
- package/dist/calls/gate.js.map +7 -0
- package/dist/calls/hooks.js +115 -0
- package/dist/calls/hooks.js.map +7 -0
- package/dist/calls/in-call-chat.js +132 -0
- package/dist/calls/in-call-chat.js.map +7 -0
- package/dist/calls/index.js +24 -0
- package/dist/calls/index.js.map +7 -0
- package/dist/calls/keys.js +17 -0
- package/dist/calls/keys.js.map +7 -0
- package/dist/calls/livekit/index.cjs +48 -48
- package/dist/calls/livekit/index.js +6 -958
- package/dist/calls/livekit/index.js.map +7 -1
- package/dist/calls/livekit/room.js +98 -0
- package/dist/calls/livekit/room.js.map +7 -0
- package/dist/calls/livekit/useCallRecorder.js +219 -0
- package/dist/calls/livekit/useCallRecorder.js.map +7 -0
- package/dist/calls/livekit/useCallTranscriber.js +309 -0
- package/dist/calls/livekit/useCallTranscriber.js.map +7 -0
- package/dist/calls/livekit/useHostMuteNotice.js +29 -0
- package/dist/calls/livekit/useHostMuteNotice.js.map +7 -0
- package/dist/calls/livekit/useInCallChat.js +161 -0
- package/dist/calls/livekit/useInCallChat.js.map +7 -0
- package/dist/calls/livekit/useWebinar.js +239 -0
- package/dist/calls/livekit/useWebinar.js.map +7 -0
- package/dist/calls/meeting-chat.js +149 -0
- package/dist/calls/meeting-chat.js.map +7 -0
- package/dist/calls/moderation.js +50 -0
- package/dist/calls/moderation.js.map +7 -0
- package/dist/calls/open-meeting-chat.js +29 -0
- package/dist/calls/open-meeting-chat.js.map +7 -0
- package/dist/calls/read-only.js +24 -0
- package/dist/calls/read-only.js.map +7 -0
- package/dist/calls/recording-media.js +218 -0
- package/dist/calls/recording-media.js.map +7 -0
- package/dist/calls/recording-playback.js +260 -0
- package/dist/calls/recording-playback.js.map +7 -0
- package/dist/calls/recording.js +268 -0
- package/dist/calls/recording.js.map +7 -0
- package/dist/calls/save-to-thread.js +80 -0
- package/dist/calls/save-to-thread.js.map +7 -0
- package/dist/calls/session.js +134 -0
- package/dist/calls/session.js.map +7 -0
- package/dist/calls/transcript-format.js +147 -0
- package/dist/calls/transcript-format.js.map +7 -0
- package/dist/calls/transcription.js +101 -0
- package/dist/calls/transcription.js.map +7 -0
- package/dist/calls/webinar.js +71 -0
- package/dist/calls/webinar.js.map +7 -0
- package/dist/charge-watch.js +71 -0
- package/dist/charge-watch.js.map +7 -0
- package/dist/chat/ChatBubble.js +146 -0
- package/dist/chat/ChatBubble.js.map +7 -0
- package/dist/chat/ConversationScope.js +30 -0
- package/dist/chat/ConversationScope.js.map +7 -0
- package/dist/chat/active-config.js +20 -0
- package/dist/chat/active-config.js.map +7 -0
- package/dist/chat/agent-chat-owner.js +25 -0
- package/dist/chat/agent-chat-owner.js.map +7 -0
- package/dist/chat/chat-artifacts.js +64 -0
- package/dist/chat/chat-artifacts.js.map +7 -0
- package/dist/chat/citations.js +32 -0
- package/dist/chat/citations.js.map +7 -0
- package/dist/chat/config-model.js +10 -0
- package/dist/chat/config-model.js.map +7 -0
- package/dist/chat/conversation-cache.js +676 -0
- package/dist/chat/conversation-cache.js.map +7 -0
- package/dist/chat/conversation-events.js +57 -0
- package/dist/chat/conversation-events.js.map +7 -0
- package/dist/chat/conversation-mentions.js +58 -0
- package/dist/chat/conversation-mentions.js.map +7 -0
- package/dist/chat/conversation-workspace.js +58 -0
- package/dist/chat/conversation-workspace.js.map +7 -0
- package/dist/chat/mentions.js +116 -0
- package/dist/chat/mentions.js.map +7 -0
- package/dist/chat/open-document.js +106 -0
- package/dist/chat/open-document.js.map +7 -0
- package/dist/chat/orphaned.js +44 -0
- package/dist/chat/orphaned.js.map +7 -0
- package/dist/chat/pendingFirstTurn.js +30 -0
- package/dist/chat/pendingFirstTurn.js.map +7 -0
- package/dist/chat/reply-target.js +12 -0
- package/dist/chat/reply-target.js.map +7 -0
- package/dist/chat/run-finished.js +28 -0
- package/dist/chat/run-finished.js.map +7 -0
- package/dist/chat/run-state.js +91 -0
- package/dist/chat/run-state.js.map +7 -0
- package/dist/chat/stream-handlers.js +419 -0
- package/dist/chat/stream-handlers.js.map +7 -0
- package/dist/chat/thread-binding.js +76 -0
- package/dist/chat/thread-binding.js.map +7 -0
- package/dist/chat/thread-document.js +53 -0
- package/dist/chat/thread-document.js.map +7 -0
- package/dist/chat/turn-control.js +79 -0
- package/dist/chat/turn-control.js.map +7 -0
- package/dist/chat/useAgentRunControl.js +36 -0
- package/dist/chat/useAgentRunControl.js.map +7 -0
- package/dist/chat/useAnswerAgentQuestion.js +19 -0
- package/dist/chat/useAnswerAgentQuestion.js.map +7 -0
- package/dist/chat/useAskAgain.js +32 -0
- package/dist/chat/useAskAgain.js.map +7 -0
- package/dist/chat/useAutoSendDraft.js +17 -0
- package/dist/chat/useAutoSendDraft.js.map +7 -0
- package/dist/chat/useBranchNavigation.js +97 -0
- package/dist/chat/useBranchNavigation.js.map +7 -0
- package/dist/chat/useConnectRunStream.js +169 -0
- package/dist/chat/useConnectRunStream.js.map +7 -0
- package/dist/chat/useConversation.js +431 -0
- package/dist/chat/useConversation.js.map +7 -0
- package/dist/chat/useConversationActions.js +662 -0
- package/dist/chat/useConversationActions.js.map +7 -0
- package/dist/chat/useConversationData.js +143 -0
- package/dist/chat/useConversationData.js.map +7 -0
- package/dist/chat/useConversationDocuments.js +41 -0
- package/dist/chat/useConversationDocuments.js.map +7 -0
- package/dist/chat/useConversationSettings.js +78 -0
- package/dist/chat/useConversationSettings.js.map +7 -0
- package/dist/chat/useConversationTurn.js +31 -0
- package/dist/chat/useConversationTurn.js.map +7 -0
- package/dist/chat/useConversationWorkspace.js +12 -0
- package/dist/chat/useConversationWorkspace.js.map +7 -0
- package/dist/chat/useDeleteMessage.js +15 -0
- package/dist/chat/useDeleteMessage.js.map +7 -0
- package/dist/chat/useDocumentAutoAdd.js +73 -0
- package/dist/chat/useDocumentAutoAdd.js.map +7 -0
- package/dist/chat/useMessageTimer.js +39 -0
- package/dist/chat/useMessageTimer.js.map +7 -0
- package/dist/chat/useThinkingContent.js +67 -0
- package/dist/chat/useThinkingContent.js.map +7 -0
- package/dist/chat/useThreadDocument.js +61 -0
- package/dist/chat/useThreadDocument.js.map +7 -0
- package/dist/chat/workflow-run-titles.js +50 -0
- package/dist/chat/workflow-run-titles.js.map +7 -0
- package/dist/{chunk-W2FATOTX.cjs → chunk-3JAEX57E.cjs} +4 -4
- package/dist/{chunk-W2FATOTX.cjs.map → chunk-3JAEX57E.cjs.map} +1 -1
- package/dist/{chunk-HD5H2PPP.cjs → chunk-5TRUFWKT.cjs} +66 -66
- package/dist/{chunk-HD5H2PPP.cjs.map → chunk-5TRUFWKT.cjs.map} +1 -1
- package/dist/{chunk-Z3W4XFWB.cjs → chunk-C72FSQUE.cjs} +3 -3
- package/dist/{chunk-Z3W4XFWB.cjs.map → chunk-C72FSQUE.cjs.map} +1 -1
- package/dist/{chunk-LBAG7KL7.cjs → chunk-FQVNZCTD.cjs} +3 -3
- package/dist/{chunk-LBAG7KL7.cjs.map → chunk-FQVNZCTD.cjs.map} +1 -1
- package/dist/{chunk-RVUGSM65.cjs → chunk-GKGAPU6T.cjs} +44 -44
- package/dist/{chunk-RVUGSM65.cjs.map → chunk-GKGAPU6T.cjs.map} +1 -1
- package/dist/{chunk-7LIMHY56.cjs → chunk-O32T7XRD.cjs} +3 -3
- package/dist/{chunk-7LIMHY56.cjs.map → chunk-O32T7XRD.cjs.map} +1 -1
- package/dist/chunk-PWGSIM3F.cjs +291 -0
- package/dist/chunk-PWGSIM3F.cjs.map +1 -0
- package/dist/chunk-QP3WQSAA.cjs +23 -0
- package/dist/chunk-QP3WQSAA.cjs.map +1 -0
- package/dist/chunk-T5FZICXN.cjs +50 -0
- package/dist/chunk-T5FZICXN.cjs.map +1 -0
- package/dist/{chunk-QF2BW6HZ.cjs → chunk-UDDJIUHJ.cjs} +38 -38
- package/dist/{chunk-QF2BW6HZ.cjs.map → chunk-UDDJIUHJ.cjs.map} +1 -1
- package/dist/{chunk-5HDKL6XB.cjs → chunk-YMB6XUR2.cjs} +57 -57
- package/dist/{chunk-5HDKL6XB.cjs.map → chunk-YMB6XUR2.cjs.map} +1 -1
- package/dist/config/config-hooks.js +209 -0
- package/dist/config/config-hooks.js.map +7 -0
- package/dist/connectivity.js +72 -0
- package/dist/connectivity.js.map +7 -0
- package/dist/connectors/hooks.js +263 -0
- package/dist/connectors/hooks.js.map +7 -0
- package/dist/connectors/index.js +28 -0
- package/dist/connectors/index.js.map +7 -0
- package/dist/contacts.js +100 -0
- package/dist/contacts.js.map +7 -0
- package/dist/conversation-list.js +65 -0
- package/dist/conversation-list.js.map +7 -0
- package/dist/databases.js +195 -0
- package/dist/databases.js.map +7 -0
- package/dist/datasets/aggregate.js +281 -0
- package/dist/datasets/aggregate.js.map +7 -0
- package/dist/datasets/index.js +122 -0
- package/dist/datasets/index.js.map +7 -0
- package/dist/datasets/members.js +27 -0
- package/dist/datasets/members.js.map +7 -0
- package/dist/datasets/panel.js +44 -0
- package/dist/datasets/panel.js.map +7 -0
- package/dist/datasets/registry.js +47 -0
- package/dist/datasets/registry.js.map +7 -0
- package/dist/datasets/rows-source.js +44 -0
- package/dist/datasets/rows-source.js.map +7 -0
- package/dist/datasets/sources/activity.js +83 -0
- package/dist/datasets/sources/activity.js.map +7 -0
- package/dist/datasets/sources/conversations.js +74 -0
- package/dist/datasets/sources/conversations.js.map +7 -0
- package/dist/datasets/sources/database.js +209 -0
- package/dist/datasets/sources/database.js.map +7 -0
- package/dist/datasets/sources/documents.js +93 -0
- package/dist/datasets/sources/documents.js.map +7 -0
- package/dist/datasets/sources/facts.js +56 -0
- package/dist/datasets/sources/facts.js.map +7 -0
- package/dist/datasets/sources/projects.js +117 -0
- package/dist/datasets/sources/projects.js.map +7 -0
- package/dist/datasets/sources/tags.js +67 -0
- package/dist/datasets/sources/tags.js.map +7 -0
- package/dist/datasets/sources/usage.js +268 -0
- package/dist/datasets/sources/usage.js.map +7 -0
- package/dist/datasets/sources/workflows.js +91 -0
- package/dist/datasets/sources/workflows.js.map +7 -0
- package/dist/datasets/sources/workspaces.js +67 -0
- package/dist/datasets/sources/workspaces.js.map +7 -0
- package/dist/datasets/store.js +194 -0
- package/dist/datasets/store.js.map +7 -0
- package/dist/datasets/types.js +14 -0
- package/dist/datasets/types.js.map +7 -0
- package/dist/directmessages/ConversationList.js +148 -0
- package/dist/directmessages/ConversationList.js.map +7 -0
- package/dist/directmessages/DateSeparator.js +8 -0
- package/dist/directmessages/DateSeparator.js.map +7 -0
- package/dist/directmessages/DmAvatar.js +29 -0
- package/dist/directmessages/DmAvatar.js.map +7 -0
- package/dist/directmessages/DmComposer.js +201 -0
- package/dist/directmessages/DmComposer.js.map +7 -0
- package/dist/directmessages/arrivals.js +29 -0
- package/dist/directmessages/arrivals.js.map +7 -0
- package/dist/directmessages/chat-cache.js +192 -0
- package/dist/directmessages/chat-cache.js.map +7 -0
- package/dist/directmessages/grouping.js +26 -0
- package/dist/directmessages/grouping.js.map +7 -0
- package/dist/directmessages/index.js +81 -0
- package/dist/directmessages/index.js.map +7 -0
- package/dist/directmessages/useChats.js +266 -0
- package/dist/directmessages/useChats.js.map +7 -0
- package/dist/directmessages/utils.js +23 -0
- package/dist/directmessages/utils.js.map +7 -0
- package/dist/document-tools/can-annotate.js +7 -0
- package/dist/document-tools/can-annotate.js.map +7 -0
- package/dist/document-tools/core.cjs +99 -99
- package/dist/document-tools/core.d.ts +2 -2
- package/dist/document-tools/core.js +218 -12
- package/dist/document-tools/core.js.map +7 -1
- package/dist/document-tools/document-pdf.js +76 -0
- package/dist/document-tools/document-pdf.js.map +7 -0
- package/dist/document-tools/environment.js +136 -0
- package/dist/document-tools/environment.js.map +7 -0
- package/dist/document-tools/file-shares.js +112 -0
- package/dist/document-tools/file-shares.js.map +7 -0
- package/dist/document-tools/frozen-copy.js +27 -0
- package/dist/document-tools/frozen-copy.js.map +7 -0
- package/dist/document-tools/index.cjs +101 -101
- package/dist/document-tools/index.d.ts +1 -1
- package/dist/document-tools/index.js +26 -148
- package/dist/document-tools/index.js.map +7 -1
- package/dist/document-tools/markup-download.js +51 -0
- package/dist/document-tools/markup-download.js.map +7 -0
- package/dist/document-tools/markup-store.js +138 -0
- package/dist/document-tools/markup-store.js.map +7 -0
- package/dist/document-tools/markup-transfer.js +88 -0
- package/dist/document-tools/markup-transfer.js.map +7 -0
- package/dist/document-tools/production.js +147 -0
- package/dist/document-tools/production.js.map +7 -0
- package/dist/document-tools/saved-signature.js +90 -0
- package/dist/document-tools/saved-signature.js.map +7 -0
- package/dist/document-tools/signature-requests.js +310 -0
- package/dist/document-tools/signature-requests.js.map +7 -0
- package/dist/document-tools/signing.js +127 -0
- package/dist/document-tools/signing.js.map +7 -0
- package/dist/document-tools/useDocumentBytes.js +38 -0
- package/dist/document-tools/useDocumentBytes.js.map +7 -0
- package/dist/document-tools/useDocumentMarkup.js +154 -0
- package/dist/document-tools/useDocumentMarkup.js.map +7 -0
- package/dist/document-tools/useIsOnline.js +13 -0
- package/dist/document-tools/useIsOnline.js.map +7 -0
- package/dist/document-tools/verification.js +60 -0
- package/dist/document-tools/verification.js.map +7 -0
- package/dist/documents/DocumentReview.js +220 -0
- package/dist/documents/DocumentReview.js.map +7 -0
- package/dist/documents/DraftTitleControls.js +41 -0
- package/dist/documents/DraftTitleControls.js.map +7 -0
- package/dist/documents/InlineMicButton.js +90 -0
- package/dist/documents/InlineMicButton.js.map +7 -0
- package/dist/documents/MicRecordingOverlay.js +29 -0
- package/dist/documents/MicRecordingOverlay.js.map +7 -0
- package/dist/documents/MicWaveformIndicator.js +68 -0
- package/dist/documents/MicWaveformIndicator.js.map +7 -0
- package/dist/documents/PhotoCapture.js +120 -0
- package/dist/documents/PhotoCapture.js.map +7 -0
- package/dist/documents/VideoCapture.js +129 -0
- package/dist/documents/VideoCapture.js.map +7 -0
- package/dist/documents/VoiceNoteRecorder.js +166 -0
- package/dist/documents/VoiceNoteRecorder.js.map +7 -0
- package/dist/documents/audio-segmenter.js +63 -0
- package/dist/documents/audio-segmenter.js.map +7 -0
- package/dist/documents/capture-frame.js +21 -0
- package/dist/documents/capture-frame.js.map +7 -0
- package/dist/documents/chunked-recorder.js +190 -0
- package/dist/documents/chunked-recorder.js.map +7 -0
- package/dist/documents/document-download.js +53 -0
- package/dist/documents/document-download.js.map +7 -0
- package/dist/documents/document-fields.js +109 -0
- package/dist/documents/document-fields.js.map +7 -0
- package/dist/documents/documents-cache.js +110 -0
- package/dist/documents/documents-cache.js.map +7 -0
- package/dist/documents/documents-data.js +128 -0
- package/dist/documents/documents-data.js.map +7 -0
- package/dist/documents/documents-loader.js +113 -0
- package/dist/documents/documents-loader.js.map +7 -0
- package/dist/documents/documents-writes.js +448 -0
- package/dist/documents/documents-writes.js.map +7 -0
- package/dist/documents/format-elapsed.js +10 -0
- package/dist/documents/format-elapsed.js.map +7 -0
- package/dist/documents/has-video-track.js +26 -0
- package/dist/documents/has-video-track.js.map +7 -0
- package/dist/documents/index.js +266 -0
- package/dist/documents/index.js.map +7 -0
- package/dist/documents/media-error.js +18 -0
- package/dist/documents/media-error.js.map +7 -0
- package/dist/documents/offline-documents.js +160 -0
- package/dist/documents/offline-documents.js.map +7 -0
- package/dist/documents/pending-sync.js +210 -0
- package/dist/documents/pending-sync.js.map +7 -0
- package/dist/documents/processing-live.js +122 -0
- package/dist/documents/processing-live.js.map +7 -0
- package/dist/documents/processing-order.js +59 -0
- package/dist/documents/processing-order.js.map +7 -0
- package/dist/documents/processing-settle.js +21 -0
- package/dist/documents/processing-settle.js.map +7 -0
- package/dist/documents/related-documents.js +133 -0
- package/dist/documents/related-documents.js.map +7 -0
- package/dist/documents/support.js +29 -0
- package/dist/documents/support.js.map +7 -0
- package/dist/documents/upload-files.js +169 -0
- package/dist/documents/upload-files.js.map +7 -0
- package/dist/documents/useAudioRecorder.js +315 -0
- package/dist/documents/useAudioRecorder.js.map +7 -0
- package/dist/documents/useCameraStream.js +35 -0
- package/dist/documents/useCameraStream.js.map +7 -0
- package/dist/documents/useDocumentThumbnails.js +71 -0
- package/dist/documents/useDocumentThumbnails.js.map +7 -0
- package/dist/documents/useDownloadDocuments.js +90 -0
- package/dist/documents/useDownloadDocuments.js.map +7 -0
- package/dist/documents/usePassageQuotes.js +37 -0
- package/dist/documents/usePassageQuotes.js.map +7 -0
- package/dist/documents/useUploadFiles.js +165 -0
- package/dist/documents/useUploadFiles.js.map +7 -0
- package/dist/documents/useUploadFromUrls.js +63 -0
- package/dist/documents/useUploadFromUrls.js.map +7 -0
- package/dist/documents/useVideoRecorder.js +62 -0
- package/dist/documents/useVideoRecorder.js.map +7 -0
- package/dist/entities/AgentMarkers.js +61 -0
- package/dist/entities/AgentMarkers.js.map +7 -0
- package/dist/entities/DocumentEntity.js +125 -0
- package/dist/entities/DocumentEntity.js.map +7 -0
- package/dist/entities/EntityPill.js +250 -0
- package/dist/entities/EntityPill.js.map +7 -0
- package/dist/entities/ProjectEntity.js +61 -0
- package/dist/entities/ProjectEntity.js.map +7 -0
- package/dist/entities/ShieldIcon.js +49 -0
- package/dist/entities/ShieldIcon.js.map +7 -0
- package/dist/entities/TagEntity.js +79 -0
- package/dist/entities/TagEntity.js.map +7 -0
- package/dist/entities/ThreadVisibilityIcon.js +15 -0
- package/dist/entities/ThreadVisibilityIcon.js.map +7 -0
- package/dist/entities/UserEntity.js +211 -0
- package/dist/entities/UserEntity.js.map +7 -0
- package/dist/entities/VerifiedBadge.js +19 -0
- package/dist/entities/VerifiedBadge.js.map +7 -0
- package/dist/entities/agent-avatar-colors.js +26 -0
- package/dist/entities/agent-avatar-colors.js.map +7 -0
- package/dist/entities/colors.js +64 -0
- package/dist/entities/colors.js.map +7 -0
- package/dist/entities/file-type.js +151 -0
- package/dist/entities/file-type.js.map +7 -0
- package/dist/entities/index.js +100 -0
- package/dist/entities/index.js.map +7 -0
- package/dist/entities/media-type.js +61 -0
- package/dist/entities/media-type.js.map +7 -0
- package/dist/entities/registry.js +385 -0
- package/dist/entities/registry.js.map +7 -0
- package/dist/entities/status.js +43 -0
- package/dist/entities/status.js.map +7 -0
- package/dist/entities/tag-kinds.js +23 -0
- package/dist/entities/tag-kinds.js.map +7 -0
- package/dist/entities/tag-types.js +44 -0
- package/dist/entities/tag-types.js.map +7 -0
- package/dist/entities/vocabulary.js +12 -0
- package/dist/entities/vocabulary.js.map +7 -0
- package/dist/entity-extraction.js +25 -0
- package/dist/entity-extraction.js.map +7 -0
- package/dist/facts-search.js +57 -0
- package/dist/facts-search.js.map +7 -0
- package/dist/facts.js +69 -0
- package/dist/facts.js.map +7 -0
- package/dist/hooks.js +320 -0
- package/dist/hooks.js.map +7 -0
- package/dist/host/ArbiHost.js +24 -0
- package/dist/host/ArbiHost.js.map +7 -0
- package/dist/host/assistant-copy.js +54 -0
- package/dist/host/assistant-copy.js.map +7 -0
- package/dist/host/config.js +9 -0
- package/dist/host/config.js.map +7 -0
- package/dist/host/context.js +10 -0
- package/dist/host/context.js.map +7 -0
- package/dist/host/features.js +144 -0
- package/dist/host/features.js.map +7 -0
- package/dist/host/index.js +12 -0
- package/dist/host/index.js.map +7 -0
- package/dist/{chunk-DPYBZDJB.js → host/merge.js} +7 -7
- package/dist/host/merge.js.map +7 -0
- package/dist/house-template.js +40 -0
- package/dist/house-template.js.map +7 -0
- package/dist/icons/AppleIcon.js +25 -0
- package/dist/icons/AppleIcon.js.map +7 -0
- package/dist/icons/ArbiBotHeadIcon.js +46 -0
- package/dist/icons/ArbiBotHeadIcon.js.map +7 -0
- package/dist/icons/ArbiIcon.js +24 -0
- package/dist/icons/ArbiIcon.js.map +7 -0
- package/dist/icons/AudIcon.js +56 -0
- package/dist/icons/AudIcon.js.map +7 -0
- package/dist/icons/ClaudeIcon.js +28 -0
- package/dist/icons/ClaudeIcon.js.map +7 -0
- package/dist/icons/DocIcon.js +56 -0
- package/dist/icons/DocIcon.js.map +7 -0
- package/dist/icons/EmlIcon.js +57 -0
- package/dist/icons/EmlIcon.js.map +7 -0
- package/dist/icons/FireworksIcon.js +47 -0
- package/dist/icons/FireworksIcon.js.map +7 -0
- package/dist/icons/GeminiIcon.js +37 -0
- package/dist/icons/GeminiIcon.js.map +7 -0
- package/dist/icons/GitHubIcon.js +32 -0
- package/dist/icons/GitHubIcon.js.map +7 -0
- package/dist/icons/GoogleIcon.js +53 -0
- package/dist/icons/GoogleIcon.js.map +7 -0
- package/dist/icons/HtmlIcon.js +56 -0
- package/dist/icons/HtmlIcon.js.map +7 -0
- package/dist/icons/ImgIcon.js +56 -0
- package/dist/icons/ImgIcon.js.map +7 -0
- package/dist/icons/LinkedInIcon.js +25 -0
- package/dist/icons/LinkedInIcon.js.map +7 -0
- package/dist/icons/OpenAIIcon.js +28 -0
- package/dist/icons/OpenAIIcon.js.map +7 -0
- package/dist/icons/PdfIcon.js +56 -0
- package/dist/icons/PdfIcon.js.map +7 -0
- package/dist/icons/ProviderIcon.js +42 -0
- package/dist/icons/ProviderIcon.js.map +7 -0
- package/dist/icons/TxtIcon.js +56 -0
- package/dist/icons/TxtIcon.js.map +7 -0
- package/dist/icons/VidIcon.js +56 -0
- package/dist/icons/VidIcon.js.map +7 -0
- package/dist/icons/XlsIcon.js +56 -0
- package/dist/icons/XlsIcon.js.map +7 -0
- package/dist/icons/arbi-mark.js +5 -0
- package/dist/icons/arbi-mark.js.map +7 -0
- package/dist/icons/colors.js +31 -0
- package/dist/icons/colors.js.map +7 -0
- package/dist/icons/file-type.js +105 -0
- package/dist/icons/file-type.js.map +7 -0
- package/dist/icons/index.js +55 -0
- package/dist/icons/index.js.map +7 -0
- package/dist/imagecrop/ImageCropModal.js +56 -0
- package/dist/imagecrop/ImageCropModal.js.map +7 -0
- package/dist/imagecrop/ImageCropper.js +100 -0
- package/dist/imagecrop/ImageCropper.js.map +7 -0
- package/dist/imagecrop/cropImage.js +43 -0
- package/dist/imagecrop/cropImage.js.map +7 -0
- package/dist/imagecrop/index.js +13 -0
- package/dist/imagecrop/index.js.map +7 -0
- package/dist/index.cjs +1689 -1619
- package/dist/index.cjs.map +1 -1
- package/dist/{index.d-BMhTH98a.d.ts → index.d-CYXcTKYt.d.ts} +1 -0
- package/dist/index.d.ts +38 -8
- package/dist/index.js +702 -17060
- package/dist/index.js.map +7 -1
- package/dist/lazy-chunk.d-B6YDLMKI.d.ts +31 -0
- package/dist/lazy-chunk.js +46 -0
- package/dist/lazy-chunk.js.map +7 -0
- package/dist/lib/collision-padding.js +13 -0
- package/dist/lib/collision-padding.js.map +7 -0
- package/dist/lib/format-friendly-date.js +55 -0
- package/dist/lib/format-friendly-date.js.map +7 -0
- package/dist/lib/format-relative-time.js +52 -0
- package/dist/lib/format-relative-time.js.map +7 -0
- package/dist/lib/markdown-to-text.js +35 -0
- package/dist/lib/markdown-to-text.js.map +7 -0
- package/dist/lib/toast-interaction.js +9 -0
- package/dist/lib/toast-interaction.js.map +7 -0
- package/dist/lib/utils.js +9 -0
- package/dist/lib/utils.js.map +7 -0
- package/dist/mail/client.js +103 -0
- package/dist/mail/client.js.map +7 -0
- package/dist/mail/document-attachment.js +38 -0
- package/dist/mail/document-attachment.js.map +7 -0
- package/dist/mail/filing.js +132 -0
- package/dist/mail/filing.js.map +7 -0
- package/dist/mail/hooks.js +393 -0
- package/dist/mail/hooks.js.map +7 -0
- package/dist/mail/index.js +120 -0
- package/dist/mail/index.js.map +7 -0
- package/dist/mail/offline/changes.js +258 -0
- package/dist/mail/offline/changes.js.map +7 -0
- package/dist/mail/offline/confirm-sign-out.js +37 -0
- package/dist/mail/offline/confirm-sign-out.js.map +7 -0
- package/dist/mail/offline/crypto.js +26 -0
- package/dist/mail/offline/crypto.js.map +7 -0
- package/dist/mail/offline/drafts.js +69 -0
- package/dist/mail/offline/drafts.js.map +7 -0
- package/dist/mail/offline/hooks.js +104 -0
- package/dist/mail/offline/hooks.js.map +7 -0
- package/dist/mail/offline/index.js +48 -0
- package/dist/mail/offline/index.js.map +7 -0
- package/dist/mail/offline/live.js +233 -0
- package/dist/mail/offline/live.js.map +7 -0
- package/dist/mail/offline/mailbox.js +191 -0
- package/dist/mail/offline/mailbox.js.map +7 -0
- package/dist/mail/offline/outbox.js +167 -0
- package/dist/mail/offline/outbox.js.map +7 -0
- package/dist/mail/offline/reads.js +159 -0
- package/dist/mail/offline/reads.js.map +7 -0
- package/dist/mail/offline/runtime.js +100 -0
- package/dist/mail/offline/runtime.js.map +7 -0
- package/dist/mail/offline/settings.js +84 -0
- package/dist/mail/offline/settings.js.map +7 -0
- package/dist/mail/offline/store.js +29 -0
- package/dist/mail/offline/store.js.map +7 -0
- package/dist/mail/offline/sync.js +251 -0
- package/dist/mail/offline/sync.js.map +7 -0
- package/dist/mail/offline/wipe.js +19 -0
- package/dist/mail/offline/wipe.js.map +7 -0
- package/dist/mail/thread-keys.js +53 -0
- package/dist/mail/thread-keys.js.map +7 -0
- package/dist/mail/threads.js +71 -0
- package/dist/mail/threads.js.map +7 -0
- package/dist/mail/useMailClient.js +42 -0
- package/dist/mail/useMailClient.js.map +7 -0
- package/dist/model-connections.js +58 -0
- package/dist/model-connections.js.map +7 -0
- package/dist/notifications/ActivityFeed.js +70 -0
- package/dist/notifications/ActivityFeed.js.map +7 -0
- package/dist/notifications/NotificationBell.js +200 -0
- package/dist/notifications/NotificationBell.js.map +7 -0
- package/dist/notifications/Toaster.js +24 -0
- package/dist/notifications/Toaster.js.map +7 -0
- package/dist/notifications/activity-types.js +65 -0
- package/dist/notifications/activity-types.js.map +7 -0
- package/dist/notifications/bell.js +24 -0
- package/dist/notifications/bell.js.map +7 -0
- package/dist/notifications/calendar-notifications.js +79 -0
- package/dist/notifications/calendar-notifications.js.map +7 -0
- package/dist/notifications/index.js +108 -0
- package/dist/notifications/index.js.map +7 -0
- package/dist/notifications/live.js +28 -0
- package/dist/notifications/live.js.map +7 -0
- package/dist/notifications/notification-types.js +127 -0
- package/dist/notifications/notification-types.js.map +7 -0
- package/dist/{chunk-BF5KW5ZI.js → notifications/notify-store.js} +24 -74
- package/dist/notifications/notify-store.js.map +7 -0
- package/dist/notifications/server-notifications.js +452 -0
- package/dist/notifications/server-notifications.js.map +7 -0
- package/dist/notifications/useNotifications.js +34 -0
- package/dist/notifications/useNotifications.js.map +7 -0
- package/dist/offline-store/network.js +11 -0
- package/dist/offline-store/network.js.map +7 -0
- package/dist/offline-store/store.js +136 -0
- package/dist/offline-store/store.js.map +7 -0
- package/dist/offline-store/wipe.js +8 -0
- package/dist/offline-store/wipe.js.map +7 -0
- package/dist/offline.js +58 -0
- package/dist/offline.js.map +7 -0
- package/dist/people.js +122 -0
- package/dist/people.js.map +7 -0
- package/dist/projects.js +30 -0
- package/dist/projects.js.map +7 -0
- package/dist/query-client.js +63 -0
- package/dist/query-client.js.map +7 -0
- package/dist/{query-keys.d-ChgpJLPF.d.ts → query-keys.d-B1Am9tIF.d.ts} +1 -1
- package/dist/{chunk-6H3O63TQ.js → query-keys.js} +19 -32
- package/dist/query-keys.js.map +7 -0
- package/dist/query-persist.js +66 -0
- package/dist/query-persist.js.map +7 -0
- package/dist/queued-writes.js +59 -0
- package/dist/queued-writes.js.map +7 -0
- package/dist/remote-control.js +67 -0
- package/dist/remote-control.js.map +7 -0
- package/dist/search/index.js +23 -0
- package/dist/search/index.js.map +7 -0
- package/dist/search/session.js +58 -0
- package/dist/search/session.js.map +7 -0
- package/dist/search/useSemanticSearch.js +82 -0
- package/dist/search/useSemanticSearch.js.map +7 -0
- package/dist/session/chat.js +512 -0
- package/dist/session/chat.js.map +7 -0
- package/dist/session/documents.js +196 -0
- package/dist/session/documents.js.map +7 -0
- package/dist/session/drafts.js +103 -0
- package/dist/session/drafts.js.map +7 -0
- package/dist/session/index.js +123 -0
- package/dist/session/index.js.map +7 -0
- package/dist/session/layout.js +339 -0
- package/dist/session/layout.js.map +7 -0
- package/dist/session/persist.js +106 -0
- package/dist/session/persist.js.map +7 -0
- package/dist/session/session-hooks.js +53 -0
- package/dist/session/session-hooks.js.map +7 -0
- package/dist/session/signed-in.js +36 -0
- package/dist/session/signed-in.js.map +7 -0
- package/dist/session/store.js +166 -0
- package/dist/session/store.js.map +7 -0
- package/dist/session/thread-tabs.js +121 -0
- package/dist/session/thread-tabs.js.map +7 -0
- package/dist/session/ui-state-storage.js +76 -0
- package/dist/session/ui-state-storage.js.map +7 -0
- package/dist/session/workspace.js +77 -0
- package/dist/session/workspace.js.map +7 -0
- package/dist/shell/index.cjs +37 -37
- package/dist/shell/index.js +43 -10
- package/dist/shell/index.js.map +7 -1
- package/dist/skill-pack.js +111 -0
- package/dist/skill-pack.js.map +7 -0
- package/dist/storage.js +186 -0
- package/dist/storage.js.map +7 -0
- package/dist/support/index.js +35 -0
- package/dist/support/index.js.map +7 -0
- package/dist/tags.js +204 -0
- package/dist/tags.js.map +7 -0
- package/dist/ui/DebouncedInput.js +109 -0
- package/dist/ui/DebouncedInput.js.map +7 -0
- package/dist/ui/DictateContext.js +8 -0
- package/dist/ui/DictateContext.js.map +7 -0
- package/dist/ui/IconToggle.js +79 -0
- package/dist/ui/IconToggle.js.map +7 -0
- package/dist/ui/VerifiedToggle.js +38 -0
- package/dist/ui/VerifiedToggle.js.map +7 -0
- package/dist/ui/VisibilityToggle.js +103 -0
- package/dist/ui/VisibilityToggle.js.map +7 -0
- package/dist/ui/avatar.js +40 -0
- package/dist/ui/avatar.js.map +7 -0
- package/dist/ui/badge.js +28 -0
- package/dist/ui/badge.js.map +7 -0
- package/dist/ui/button.js +48 -0
- package/dist/ui/button.js.map +7 -0
- package/dist/ui/card.js +90 -0
- package/dist/ui/card.js.map +7 -0
- package/dist/ui/checkbox.js +22 -0
- package/dist/ui/checkbox.js.map +7 -0
- package/dist/ui/collapsible.js +10 -0
- package/dist/ui/collapsible.js.map +7 -0
- package/dist/ui/command.js +103 -0
- package/dist/ui/command.js.map +7 -0
- package/dist/{chunk-YNNAJJ5Z.js → ui/dialog.js} +30 -68
- package/dist/ui/dialog.js.map +7 -0
- package/dist/{chunk-47CCGUWR.js → ui/dropdown-menu.js} +40 -45
- package/dist/ui/dropdown-menu.js.map +7 -0
- package/dist/ui/hover-card.js +36 -0
- package/dist/ui/hover-card.js.map +7 -0
- package/dist/ui/index.cjs +167 -154
- package/dist/ui/index.d.ts +2 -1
- package/dist/ui/index.js +290 -9
- package/dist/ui/index.js.map +7 -1
- package/dist/ui/input.js +65 -0
- package/dist/ui/input.js.map +7 -0
- package/dist/ui/label.js +16 -0
- package/dist/ui/label.js.map +7 -0
- package/dist/ui/mark-menu.js +300 -0
- package/dist/ui/mark-menu.js.map +7 -0
- package/dist/ui/popover.js +40 -0
- package/dist/ui/popover.js.map +7 -0
- package/dist/ui/portal-container.js +17 -0
- package/dist/ui/portal-container.js.map +7 -0
- package/dist/ui/progress.js +24 -0
- package/dist/ui/progress.js.map +7 -0
- package/dist/ui/radio-group.js +29 -0
- package/dist/ui/radio-group.js.map +7 -0
- package/dist/ui/scroll-area.js +39 -0
- package/dist/ui/scroll-area.js.map +7 -0
- package/dist/ui/select.js +130 -0
- package/dist/ui/select.js.map +7 -0
- package/dist/ui/separator.js +23 -0
- package/dist/ui/separator.js.map +7 -0
- package/dist/ui/slider.js +23 -0
- package/dist/ui/slider.js.map +7 -0
- package/dist/ui/switch.js +28 -0
- package/dist/ui/switch.js.map +7 -0
- package/dist/ui/table.js +75 -0
- package/dist/ui/table.js.map +7 -0
- package/dist/ui/tabs.js +48 -0
- package/dist/ui/tabs.js.map +7 -0
- package/dist/ui/textarea.js +63 -0
- package/dist/ui/textarea.js.map +7 -0
- package/dist/ui/toggle-group.js +43 -0
- package/dist/ui/toggle-group.js.map +7 -0
- package/dist/ui/toggle.js +40 -0
- package/dist/ui/toggle.js.map +7 -0
- package/dist/ui/tooltip.js +215 -0
- package/dist/ui/tooltip.js.map +7 -0
- package/dist/usage-metered.js +8 -0
- package/dist/usage-metered.js.map +7 -0
- package/dist/useArbi.js +16 -0
- package/dist/useArbi.js.map +7 -0
- package/dist/useInstallSkillPack.js +81 -0
- package/dist/useInstallSkillPack.js.map +7 -0
- package/dist/usermenu/UserMenu.js +188 -0
- package/dist/usermenu/UserMenu.js.map +7 -0
- package/dist/usermenu/index.js +5 -0
- package/dist/usermenu/index.js.map +7 -0
- package/dist/users/index.js +15 -0
- package/dist/users/index.js.map +7 -0
- package/dist/users/user-display.js +60 -0
- package/dist/users/user-display.js.map +7 -0
- package/dist/viewers/AudioViewer.js +23 -0
- package/dist/viewers/AudioViewer.js.map +7 -0
- package/dist/viewers/DocxViewer.js +81 -0
- package/dist/viewers/DocxViewer.js.map +7 -0
- package/dist/viewers/ImageViewer.js +31 -0
- package/dist/viewers/ImageViewer.js.map +7 -0
- package/dist/viewers/PdfViewer.cjs +17 -0
- package/dist/viewers/PdfViewer.cjs.map +1 -0
- package/dist/viewers/PdfViewer.d.ts +9 -0
- package/dist/viewers/PdfViewer.js +20 -0
- package/dist/viewers/PdfViewer.js.map +7 -0
- package/dist/viewers/PdfViewerImpl.js +384 -0
- package/dist/viewers/PdfViewerImpl.js.map +7 -0
- package/dist/viewers/VideoViewer.js +31 -0
- package/dist/viewers/VideoViewer.js.map +7 -0
- package/dist/viewers/XlsxViewer.js +102 -0
- package/dist/viewers/XlsxViewer.js.map +7 -0
- package/dist/viewers/index.cjs +79 -653
- package/dist/viewers/index.cjs.map +1 -1
- package/dist/viewers/index.d.ts +3 -1
- package/dist/viewers/index.js +60 -903
- package/dist/viewers/index.js.map +7 -1
- package/dist/viewers/page-scroll.js +59 -0
- package/dist/viewers/page-scroll.js.map +7 -0
- package/dist/viewers/pdf-viewer-constants.js +9 -0
- package/dist/viewers/pdf-viewer-constants.js.map +7 -0
- package/dist/{chunk-PTOP7OHG.js → viewers/pdfjs-polyfills.js} +5 -6
- package/dist/viewers/pdfjs-polyfills.js.map +7 -0
- package/dist/viewers/selection-runs.js +38 -0
- package/dist/viewers/selection-runs.js.map +7 -0
- package/dist/viewers/usePageIntersectionObserver.js +68 -0
- package/dist/viewers/usePageIntersectionObserver.js.map +7 -0
- package/dist/viewers/useProcessedChunks.js +58 -0
- package/dist/viewers/useProcessedChunks.js.map +7 -0
- package/dist/viewers/viewer-zoom.js +163 -0
- package/dist/viewers/viewer-zoom.js.map +7 -0
- package/dist/websocket/ArbiWebSocketProvider.js +207 -0
- package/dist/websocket/ArbiWebSocketProvider.js.map +7 -0
- package/dist/websocket/context.js +14 -0
- package/dist/websocket/context.js.map +7 -0
- package/dist/websocket/hooks.js +30 -0
- package/dist/websocket/hooks.js.map +7 -0
- package/dist/websocket/index.js +22 -0
- package/dist/websocket/index.js.map +7 -0
- package/dist/websocket/live-updates.js +38 -0
- package/dist/websocket/live-updates.js.map +7 -0
- package/dist/websocket/reconnect.js +13 -0
- package/dist/websocket/reconnect.js.map +7 -0
- package/dist/websocket/store.js +58 -0
- package/dist/websocket/store.js.map +7 -0
- package/dist/workforce.js +607 -0
- package/dist/workforce.js.map +7 -0
- package/dist/workspaces/access-request.js +35 -0
- package/dist/workspaces/access-request.js.map +7 -0
- package/dist/workspaces/archive.js +59 -0
- package/dist/workspaces/archive.js.map +7 -0
- package/dist/workspaces/current.js +20 -0
- package/dist/workspaces/current.js.map +7 -0
- package/dist/workspaces/delete-workspaces.js +15 -0
- package/dist/workspaces/delete-workspaces.js.map +7 -0
- package/dist/workspaces/export-archive.js +40 -0
- package/dist/workspaces/export-archive.js.map +7 -0
- package/dist/workspaces/index.js +99 -0
- package/dist/workspaces/index.js.map +7 -0
- package/dist/workspaces/settings.js +45 -0
- package/dist/workspaces/settings.js.map +7 -0
- package/dist/workspaces/shell-workspaces.js +49 -0
- package/dist/workspaces/shell-workspaces.js.map +7 -0
- package/dist/workspaces/switch.js +234 -0
- package/dist/workspaces/switch.js.map +7 -0
- package/dist/workspaces/transfer.js +170 -0
- package/dist/workspaces/transfer.js.map +7 -0
- package/dist/workspaces/useShellWorkspaces.js +86 -0
- package/dist/workspaces/useShellWorkspaces.js.map +7 -0
- package/dist/workspaces/workspace-users.js +65 -0
- package/dist/workspaces/workspace-users.js.map +7 -0
- package/package.json +12 -4
- package/dist/PdfViewer.d-bQH9yxFg.d.ts +0 -55
- package/dist/ProductionDialog.d-CpzslFn0.d.cts +0 -51
- package/dist/annotations/freeze/index.d.cts +0 -205
- package/dist/annotations/index.d.cts +0 -360
- package/dist/artifacts/index.d.cts +0 -476
- package/dist/artifacts/redline-core.d.cts +0 -39
- package/dist/bundle-YNOX7VIL.js +0 -5
- package/dist/bundle-YNOX7VIL.js.map +0 -1
- package/dist/bundle.d-BnCSbHy2.d.cts +0 -85
- package/dist/calls/livekit/index.d.cts +0 -280
- package/dist/chunk-47CCGUWR.js.map +0 -1
- package/dist/chunk-6H3O63TQ.js.map +0 -1
- package/dist/chunk-74N436VK.js.map +0 -1
- package/dist/chunk-APZZQZ6P.js +0 -147
- package/dist/chunk-APZZQZ6P.js.map +0 -1
- package/dist/chunk-BF5KW5ZI.js.map +0 -1
- package/dist/chunk-CPQ3CU4B.js +0 -246
- package/dist/chunk-CPQ3CU4B.js.map +0 -1
- package/dist/chunk-DPYBZDJB.js.map +0 -1
- package/dist/chunk-DQALOQPI.js +0 -2766
- package/dist/chunk-DQALOQPI.js.map +0 -1
- package/dist/chunk-FZJMA32S.js +0 -1011
- package/dist/chunk-FZJMA32S.js.map +0 -1
- package/dist/chunk-H5M7FXLB.js +0 -2057
- package/dist/chunk-H5M7FXLB.js.map +0 -1
- package/dist/chunk-HDCRPPBW.js +0 -75
- package/dist/chunk-HDCRPPBW.js.map +0 -1
- package/dist/chunk-NIKPG4PW.js +0 -1128
- package/dist/chunk-NIKPG4PW.js.map +0 -1
- package/dist/chunk-NNAJLY6B.js +0 -4974
- package/dist/chunk-NNAJLY6B.js.map +0 -1
- package/dist/chunk-OYPKKHXY.js +0 -559
- package/dist/chunk-OYPKKHXY.js.map +0 -1
- package/dist/chunk-P6WLV5UY.js +0 -644
- package/dist/chunk-P6WLV5UY.js.map +0 -1
- package/dist/chunk-PTOP7OHG.js.map +0 -1
- package/dist/chunk-SN5YV6FF.js +0 -11
- package/dist/chunk-SN5YV6FF.js.map +0 -1
- package/dist/chunk-T3USOSVN.js.map +0 -1
- package/dist/chunk-T4CLW3DN.js +0 -2560
- package/dist/chunk-T4CLW3DN.js.map +0 -1
- package/dist/chunk-UW2SGTI5.js.map +0 -1
- package/dist/chunk-VSCU7K4V.js.map +0 -1
- package/dist/chunk-WL2Y2T47.js.map +0 -1
- package/dist/chunk-WUTL62MC.js.map +0 -1
- package/dist/chunk-Y3MTRA7D.js +0 -97
- package/dist/chunk-Y3MTRA7D.js.map +0 -1
- package/dist/chunk-YNNAJJ5Z.js.map +0 -1
- package/dist/document-tools/core.d.cts +0 -883
- package/dist/document-tools/index.d.cts +0 -90
- package/dist/index.d-BMhTH98a.d.cts +0 -2035
- package/dist/index.d-oR5FKZpJ.d.cts +0 -579
- package/dist/index.d.cts +0 -15893
- package/dist/model.d-CNtRWKVK.d.cts +0 -110
- package/dist/query-keys.d-ChgpJLPF.d.cts +0 -337
- package/dist/shell/index.d.cts +0 -6
- package/dist/store.d-GADDvC7w.d.cts +0 -35
- package/dist/stored-markdown.d-Bp18vrbr.d.cts +0 -125
- package/dist/ui/index.d.cts +0 -25
- package/dist/useAudioRecorder.d-B9rlMI_E.d.cts +0 -778
- package/dist/viewers/index.d.cts +0 -260
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { useArbi } from "../../useArbi.js";
|
|
2
|
+
import { onCallEvent } from "../index.js";
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { RoomEvent } from "livekit-client";
|
|
5
|
+
import {
|
|
6
|
+
useLocalParticipant,
|
|
7
|
+
useLocalParticipantPermissions,
|
|
8
|
+
useRoomContext
|
|
9
|
+
} from "@livekit/components-react";
|
|
10
|
+
import { calls } from "@arbidocs/sdk/browser";
|
|
11
|
+
import { notify } from "../../notifications/notify-store.js";
|
|
12
|
+
import {
|
|
13
|
+
CALL_WEBINAR_TOPIC,
|
|
14
|
+
markRejoining,
|
|
15
|
+
openQuestion,
|
|
16
|
+
parseWebinarPacket,
|
|
17
|
+
sealQuestionText
|
|
18
|
+
} from "../webinar.js";
|
|
19
|
+
const DEMOTE_REJOIN_FALLBACK_MS = 5e3;
|
|
20
|
+
function failed(what) {
|
|
21
|
+
return (err) => {
|
|
22
|
+
notify.error(`Could not ${what}: ${err?.message ?? "unknown error"}`);
|
|
23
|
+
throw err;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function useWebinar({
|
|
27
|
+
role: roleHint = null,
|
|
28
|
+
callExtId,
|
|
29
|
+
linkVersion = null,
|
|
30
|
+
callKey
|
|
31
|
+
}) {
|
|
32
|
+
const arbi = useArbi();
|
|
33
|
+
const webinarApi = useCallback(() => arbi.calls.webinar, [arbi]);
|
|
34
|
+
const enabled = !!roleHint;
|
|
35
|
+
const room = useRoomContext();
|
|
36
|
+
const { localParticipant } = useLocalParticipant();
|
|
37
|
+
const myIdentity = localParticipant.identity;
|
|
38
|
+
const permissions = useLocalParticipantPermissions();
|
|
39
|
+
const [state, setState] = useState(null);
|
|
40
|
+
const [questions, setQuestions] = useState([]);
|
|
41
|
+
const [stageCheck, setStageCheck] = useState(false);
|
|
42
|
+
const stateRead = useRef(0);
|
|
43
|
+
const questionsRead = useRef(0);
|
|
44
|
+
const refresh = useCallback(async () => {
|
|
45
|
+
if (!enabled) return;
|
|
46
|
+
const n = ++stateRead.current;
|
|
47
|
+
try {
|
|
48
|
+
const next = await webinarApi().get(callExtId, linkVersion);
|
|
49
|
+
if (n === stateRead.current) setState(next);
|
|
50
|
+
} catch (err) {
|
|
51
|
+
console.warn("[calls] could not read the webinar state", err);
|
|
52
|
+
}
|
|
53
|
+
}, [enabled, callExtId, linkVersion]);
|
|
54
|
+
const refreshQuestions = useCallback(async () => {
|
|
55
|
+
if (!enabled || !callKey) return;
|
|
56
|
+
const n = ++questionsRead.current;
|
|
57
|
+
try {
|
|
58
|
+
const rows = await webinarApi().questions.list(callExtId, linkVersion);
|
|
59
|
+
const opened = await Promise.all(rows.map((q) => openQuestion(q, callKey)));
|
|
60
|
+
if (n === questionsRead.current) setQuestions(opened);
|
|
61
|
+
} catch (err) {
|
|
62
|
+
console.warn("[calls] could not load the questions", err);
|
|
63
|
+
}
|
|
64
|
+
}, [enabled, callExtId, linkVersion, callKey]);
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
void refresh();
|
|
67
|
+
void refreshQuestions();
|
|
68
|
+
}, [refresh, refreshQuestions]);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (!enabled) return;
|
|
71
|
+
return onCallEvent("call.webinar", (m) => {
|
|
72
|
+
if (m.call_ext_id !== callExtId) return;
|
|
73
|
+
setState((s) => s ? { ...s, live: m.live, chat: m.chat } : s);
|
|
74
|
+
});
|
|
75
|
+
}, [enabled, callExtId]);
|
|
76
|
+
const fallback = useRef(null);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
if (!enabled) return;
|
|
79
|
+
const onData = (payload, participant, _kind, topic, _encryption, participantIdentity) => {
|
|
80
|
+
if (topic !== CALL_WEBINAR_TOPIC) return;
|
|
81
|
+
const packet = parseWebinarPacket(payload, !!(participant || participantIdentity));
|
|
82
|
+
if (!packet) return;
|
|
83
|
+
switch (packet.type) {
|
|
84
|
+
case "state":
|
|
85
|
+
setState(
|
|
86
|
+
(s) => s ? { ...s, live: packet.live, live_at: packet.live_at, chat: packet.chat } : s
|
|
87
|
+
);
|
|
88
|
+
void refresh();
|
|
89
|
+
return;
|
|
90
|
+
case "hands":
|
|
91
|
+
setState((s) => s ? { ...s, hands: packet.hands } : s);
|
|
92
|
+
return;
|
|
93
|
+
case "questions":
|
|
94
|
+
void refreshQuestions();
|
|
95
|
+
return;
|
|
96
|
+
case "promoted":
|
|
97
|
+
setStageCheck(true);
|
|
98
|
+
void refresh();
|
|
99
|
+
return;
|
|
100
|
+
case "demoted":
|
|
101
|
+
setStageCheck(false);
|
|
102
|
+
markRejoining(callExtId);
|
|
103
|
+
if (fallback.current) clearTimeout(fallback.current);
|
|
104
|
+
fallback.current = setTimeout(() => void room.disconnect(), DEMOTE_REJOIN_FALLBACK_MS);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
room.on(RoomEvent.DataReceived, onData);
|
|
109
|
+
return () => {
|
|
110
|
+
room.off(RoomEvent.DataReceived, onData);
|
|
111
|
+
};
|
|
112
|
+
}, [enabled, room, callExtId, refresh, refreshQuestions]);
|
|
113
|
+
useEffect(
|
|
114
|
+
() => () => {
|
|
115
|
+
if (fallback.current) clearTimeout(fallback.current);
|
|
116
|
+
},
|
|
117
|
+
[]
|
|
118
|
+
);
|
|
119
|
+
const role = enabled ? state?.my_role ?? null : null;
|
|
120
|
+
const onStage = !enabled || (permissions ? permissions.canPublish : state ? state.on_stage : roleHint !== "attendee");
|
|
121
|
+
const patch = useCallback(
|
|
122
|
+
async (body, what) => {
|
|
123
|
+
const next = await webinarApi().update(callExtId, body, linkVersion).catch(failed(what));
|
|
124
|
+
setState(next);
|
|
125
|
+
},
|
|
126
|
+
[callExtId, linkVersion]
|
|
127
|
+
);
|
|
128
|
+
const stepDown = useCallback(async () => {
|
|
129
|
+
markRejoining(callExtId);
|
|
130
|
+
setStageCheck(false);
|
|
131
|
+
try {
|
|
132
|
+
await webinarApi().demote(callExtId, myIdentity, linkVersion);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
markRejoining(callExtId, false);
|
|
135
|
+
failed("leave the stage")(err);
|
|
136
|
+
}
|
|
137
|
+
}, [callExtId, myIdentity, linkVersion]);
|
|
138
|
+
const joinStage = useCallback(
|
|
139
|
+
async (choices) => {
|
|
140
|
+
const lp = room.localParticipant;
|
|
141
|
+
try {
|
|
142
|
+
await lp.setMicrophoneEnabled(
|
|
143
|
+
choices.audioEnabled,
|
|
144
|
+
choices.audioDeviceId ? { deviceId: choices.audioDeviceId } : void 0
|
|
145
|
+
);
|
|
146
|
+
await lp.setCameraEnabled(
|
|
147
|
+
choices.videoEnabled,
|
|
148
|
+
choices.videoDeviceId ? { deviceId: choices.videoDeviceId } : void 0
|
|
149
|
+
);
|
|
150
|
+
} catch (err) {
|
|
151
|
+
failed("turn on your microphone or camera")(err);
|
|
152
|
+
}
|
|
153
|
+
setStageCheck(false);
|
|
154
|
+
},
|
|
155
|
+
[room]
|
|
156
|
+
);
|
|
157
|
+
const questionAction = useCallback(
|
|
158
|
+
async (run, what) => {
|
|
159
|
+
await run().catch(failed(what));
|
|
160
|
+
void refreshQuestions();
|
|
161
|
+
},
|
|
162
|
+
[refreshQuestions]
|
|
163
|
+
);
|
|
164
|
+
return useMemo(
|
|
165
|
+
() => ({
|
|
166
|
+
enabled,
|
|
167
|
+
role,
|
|
168
|
+
moderator: !!role && calls.WEBINAR_MODERATORS.has(role),
|
|
169
|
+
team: !!role && calls.WEBINAR_TEAM.has(role),
|
|
170
|
+
live: !!state?.live,
|
|
171
|
+
chat: state?.chat ?? "panelists",
|
|
172
|
+
onStage,
|
|
173
|
+
handRaised: !!state?.hand_raised,
|
|
174
|
+
hands: state?.hands ?? [],
|
|
175
|
+
attendees: state?.attendees ?? [],
|
|
176
|
+
questions,
|
|
177
|
+
stageCheck: enabled && stageCheck,
|
|
178
|
+
refresh,
|
|
179
|
+
goLive: () => patch({ live: true }, "go live"),
|
|
180
|
+
end: () => patch({ live: false }, "end the webinar"),
|
|
181
|
+
setChat: (chat) => patch({ chat }, "change who can chat"),
|
|
182
|
+
setHand: async (raised) => {
|
|
183
|
+
const next = await webinarApi().setHand(callExtId, raised, linkVersion).catch(failed(raised ? "raise your hand" : "lower your hand"));
|
|
184
|
+
setState(next);
|
|
185
|
+
},
|
|
186
|
+
promote: (identity) => webinarApi().promote(callExtId, identity, linkVersion).catch(failed("bring them on stage")).then(refresh),
|
|
187
|
+
demote: (identity) => webinarApi().demote(callExtId, identity, linkVersion).catch(failed("move them to the audience")).then(refresh),
|
|
188
|
+
stepDown,
|
|
189
|
+
joinStage,
|
|
190
|
+
ask: (text) => questionAction(async () => {
|
|
191
|
+
if (!callKey) throw new Error("This call has no key.");
|
|
192
|
+
await webinarApi().questions.ask(
|
|
193
|
+
callExtId,
|
|
194
|
+
await sealQuestionText(text, callKey),
|
|
195
|
+
linkVersion
|
|
196
|
+
);
|
|
197
|
+
}, "ask the question"),
|
|
198
|
+
vote: (id, up) => questionAction(() => webinarApi().questions.vote(callExtId, id, up, linkVersion), "vote"),
|
|
199
|
+
setQuestionStatus: (id, status) => questionAction(
|
|
200
|
+
() => webinarApi().questions.update(callExtId, id, { status }, linkVersion),
|
|
201
|
+
"update the question"
|
|
202
|
+
),
|
|
203
|
+
answer: (id, text) => questionAction(async () => {
|
|
204
|
+
if (!callKey) throw new Error("This call has no key.");
|
|
205
|
+
await webinarApi().questions.update(
|
|
206
|
+
callExtId,
|
|
207
|
+
id,
|
|
208
|
+
{ answer: await sealQuestionText(text, callKey) },
|
|
209
|
+
linkVersion
|
|
210
|
+
);
|
|
211
|
+
}, "answer the question"),
|
|
212
|
+
removeQuestion: (id) => questionAction(
|
|
213
|
+
() => webinarApi().questions.delete(callExtId, id, linkVersion),
|
|
214
|
+
"delete the question"
|
|
215
|
+
)
|
|
216
|
+
}),
|
|
217
|
+
[
|
|
218
|
+
enabled,
|
|
219
|
+
role,
|
|
220
|
+
state,
|
|
221
|
+
onStage,
|
|
222
|
+
questions,
|
|
223
|
+
stageCheck,
|
|
224
|
+
refresh,
|
|
225
|
+
patch,
|
|
226
|
+
callExtId,
|
|
227
|
+
linkVersion,
|
|
228
|
+
callKey,
|
|
229
|
+
stepDown,
|
|
230
|
+
joinStage,
|
|
231
|
+
questionAction
|
|
232
|
+
]
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
export {
|
|
236
|
+
DEMOTE_REJOIN_FALLBACK_MS,
|
|
237
|
+
useWebinar
|
|
238
|
+
};
|
|
239
|
+
//# sourceMappingURL=useWebinar.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/calls/livekit/useWebinar.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * The webinar state of a LiveKit room (ARBI `docs/webinars-plan.md`). Must run inside\n * <LiveKitRoom>; with `enabled` false (an ordinary call) it does nothing.\n *\n * - The state (live, chat, my role and stage, the moderators' hands and audience) comes from\n * `GET /webinar`, then from the server's `arbi.webinar` data messages and WS `call.webinar`.\n * Only server-sent packets count: one from a participant is ignored.\n * - Whether I am on stage is the room's own word (my publish permission), so it flips the moment\n * the server promotes or demotes me.\n * - `promoted`: the \"You're on stage\" device check opens; joining it publishes my microphone (and\n * camera) with the devices I picked. `demoted` (and stepping down myself): the server removes me\n * from the room and the dock joins me again as the audience (`webinar-join.ts`).\n * - Q&A text is end-to-end under the call key K (`webinar-packets.ts`).\n */\n\nimport { useArbi } from '../../useArbi'\nimport { onCallEvent, type JoinChoices } from '..'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { RoomEvent, type RemoteParticipant } from 'livekit-client'\nimport {\n useLocalParticipant,\n useLocalParticipantPermissions,\n useRoomContext,\n} from '@livekit/components-react'\nimport { calls } from '@arbidocs/sdk/browser'\nimport { notify } from '../../notifications/notify-store'\nimport {\n CALL_WEBINAR_TOPIC,\n markRejoining,\n openQuestion,\n parseWebinarPacket,\n sealQuestionText,\n type OpenQuestion,\n} from '../webinar'\n\n/** After `demoted`, the server removes me at once; if it has not after this, I leave the room myself. */\nexport const DEMOTE_REJOIN_FALLBACK_MS = 5_000\n\nexport type WebinarHandRow = NonNullable<calls.WebinarState['hands']>[number]\nexport type WebinarAttendeeRow = NonNullable<calls.WebinarState['attendees']>[number]\n\nexport interface WebinarControl {\n /** The call is a webinar (everything below is inert otherwise). */\n enabled: boolean\n role: calls.WebinarRole | null\n /** Host or co-host: go live / end, chat setting, hands and audience, promote / demote. */\n moderator: boolean\n /** Host, co-host or panelist: moderates Q&A. */\n team: boolean\n live: boolean\n chat: calls.WebinarChat\n /** I may publish: on stage (always true outside a webinar). */\n onStage: boolean\n handRaised: boolean\n /** Moderators: the raised hands, oldest first. */\n hands: WebinarHandRow[]\n /** Moderators: everyone in the room (hidden audience included). */\n attendees: WebinarAttendeeRow[]\n questions: OpenQuestion[]\n /** A moderator brought me on stage: the device check is open. */\n stageCheck: boolean\n refresh(): Promise<void>\n goLive(): Promise<void>\n end(): Promise<void>\n setChat(chat: calls.WebinarChat): Promise<void>\n setHand(raised: boolean): Promise<void>\n promote(identity: string): Promise<void>\n demote(identity: string): Promise<void>\n /** Leave the stage myself (also \"Stay in audience\" on the device check). */\n stepDown(): Promise<void>\n /** Go on stage with the devices picked in the check. */\n joinStage(choices: JoinChoices): Promise<void>\n ask(text: string): Promise<void>\n vote(questionId: string, up: boolean): Promise<void>\n setQuestionStatus(questionId: string, status: calls.CallQuestionStatus): Promise<void>\n answer(questionId: string, text: string): Promise<void>\n removeQuestion(questionId: string): Promise<void>\n}\n\n/** Toast a failed action, then reject (the blocks keep their state on a rejection). */\nfunction failed(what: string) {\n return (err: unknown): never => {\n notify.error(`Could not ${what}: ${(err as Error)?.message ?? 'unknown error'}`)\n throw err\n }\n}\n\nexport function useWebinar({\n role: roleHint = null,\n callExtId,\n linkVersion = null,\n callKey,\n}: {\n /** My role from the call (null: not a webinar). Until the room says, the team counts as on stage. */\n role?: calls.WebinarRole | null\n callExtId: string\n linkVersion?: number | null\n callKey: Uint8Array | null\n}): WebinarControl {\n const arbi = useArbi()\n const webinarApi = useCallback(() => arbi.calls.webinar, [arbi])\n const enabled = !!roleHint\n const room = useRoomContext()\n const { localParticipant } = useLocalParticipant()\n const myIdentity = localParticipant.identity\n const permissions = useLocalParticipantPermissions()\n const [state, setState] = useState<calls.WebinarState | null>(null)\n const [questions, setQuestions] = useState<OpenQuestion[]>([])\n const [stageCheck, setStageCheck] = useState(false)\n const stateRead = useRef(0)\n const questionsRead = useRef(0)\n\n const refresh = useCallback(async () => {\n if (!enabled) return\n const n = ++stateRead.current\n try {\n const next = await webinarApi().get(callExtId, linkVersion)\n if (n === stateRead.current) setState(next)\n } catch (err) {\n console.warn('[calls] could not read the webinar state', err)\n }\n }, [enabled, callExtId, linkVersion])\n\n const refreshQuestions = useCallback(async () => {\n if (!enabled || !callKey) return\n const n = ++questionsRead.current\n try {\n const rows = await webinarApi().questions.list(callExtId, linkVersion)\n const opened = await Promise.all(rows.map((q) => openQuestion(q, callKey)))\n if (n === questionsRead.current) setQuestions(opened)\n } catch (err) {\n console.warn('[calls] could not load the questions', err)\n }\n }, [enabled, callExtId, linkVersion, callKey])\n\n useEffect(() => {\n void refresh()\n void refreshQuestions()\n }, [refresh, refreshQuestions])\n\n // Live / ended / chat setting, over WS (the room's own packet says the same).\n useEffect(() => {\n if (!enabled) return\n return onCallEvent('call.webinar', (m) => {\n if (m.call_ext_id !== callExtId) return\n setState((s) => (s ? { ...s, live: m.live, chat: m.chat } : s))\n })\n }, [enabled, callExtId])\n\n // The server's `arbi.webinar` messages.\n const fallback = useRef<ReturnType<typeof setTimeout> | null>(null)\n useEffect(() => {\n if (!enabled) return\n const onData = (\n payload: Uint8Array,\n participant?: RemoteParticipant,\n _kind?: unknown,\n topic?: string,\n _encryption?: unknown,\n participantIdentity?: string\n ) => {\n if (topic !== CALL_WEBINAR_TOPIC) return\n const packet = parseWebinarPacket(payload, !!(participant || participantIdentity))\n if (!packet) return\n switch (packet.type) {\n case 'state':\n setState((s) =>\n s ? { ...s, live: packet.live, live_at: packet.live_at, chat: packet.chat } : s\n )\n // Roles may have changed too: read them again.\n void refresh()\n return\n case 'hands':\n setState((s) => (s ? { ...s, hands: packet.hands } : s))\n return\n case 'questions':\n void refreshQuestions()\n return\n case 'promoted':\n setStageCheck(true)\n void refresh()\n return\n case 'demoted':\n setStageCheck(false)\n // The server removes me from the room now; the dock then joins me again as the audience.\n markRejoining(callExtId)\n if (fallback.current) clearTimeout(fallback.current)\n fallback.current = setTimeout(() => void room.disconnect(), DEMOTE_REJOIN_FALLBACK_MS)\n return\n }\n }\n room.on(RoomEvent.DataReceived, onData)\n return () => {\n room.off(RoomEvent.DataReceived, onData)\n }\n }, [enabled, room, callExtId, refresh, refreshQuestions])\n useEffect(\n () => () => {\n if (fallback.current) clearTimeout(fallback.current)\n },\n []\n )\n\n const role = enabled ? (state?.my_role ?? null) : null\n // The room's word once connected, else the server's, else my role: the team starts on stage, so\n // its UI (and the dock's placement) never flickers through the audience viewer while joining.\n const onStage =\n !enabled ||\n (permissions ? permissions.canPublish : state ? state.on_stage : roleHint !== 'attendee')\n\n const patch = useCallback(\n async (body: { live?: boolean; chat?: calls.WebinarChat }, what: string) => {\n const next = await webinarApi().update(callExtId, body, linkVersion).catch(failed(what))\n setState(next)\n },\n [callExtId, linkVersion]\n )\n\n const stepDown = useCallback(async () => {\n // The server removes me during the request: that disconnect is a rejoin, not a leave.\n markRejoining(callExtId)\n setStageCheck(false)\n try {\n await webinarApi().demote(callExtId, myIdentity, linkVersion)\n } catch (err) {\n markRejoining(callExtId, false)\n failed('leave the stage')(err)\n }\n }, [callExtId, myIdentity, linkVersion])\n\n const joinStage = useCallback(\n async (choices: JoinChoices) => {\n const lp = room.localParticipant\n try {\n await lp.setMicrophoneEnabled(\n choices.audioEnabled,\n choices.audioDeviceId ? { deviceId: choices.audioDeviceId } : undefined\n )\n await lp.setCameraEnabled(\n choices.videoEnabled,\n choices.videoDeviceId ? { deviceId: choices.videoDeviceId } : undefined\n )\n } catch (err) {\n failed('turn on your microphone or camera')(err)\n }\n setStageCheck(false)\n },\n [room]\n )\n\n const questionAction = useCallback(\n async (run: () => Promise<unknown>, what: string) => {\n await run().catch(failed(what))\n // Everyone (me too) also gets `questions` from the server; this makes my own change instant.\n void refreshQuestions()\n },\n [refreshQuestions]\n )\n\n return useMemo<WebinarControl>(\n () => ({\n enabled,\n role,\n moderator: !!role && calls.WEBINAR_MODERATORS.has(role),\n team: !!role && calls.WEBINAR_TEAM.has(role),\n live: !!state?.live,\n chat: state?.chat ?? 'panelists',\n onStage,\n handRaised: !!state?.hand_raised,\n hands: state?.hands ?? [],\n attendees: state?.attendees ?? [],\n questions,\n stageCheck: enabled && stageCheck,\n refresh,\n goLive: () => patch({ live: true }, 'go live'),\n end: () => patch({ live: false }, 'end the webinar'),\n setChat: (chat) => patch({ chat }, 'change who can chat'),\n setHand: async (raised) => {\n const next = await webinarApi()\n .setHand(callExtId, raised, linkVersion)\n .catch(failed(raised ? 'raise your hand' : 'lower your hand'))\n setState(next)\n },\n promote: (identity) =>\n webinarApi()\n .promote(callExtId, identity, linkVersion)\n .catch(failed('bring them on stage'))\n .then(refresh),\n demote: (identity) =>\n webinarApi()\n .demote(callExtId, identity, linkVersion)\n .catch(failed('move them to the audience'))\n .then(refresh),\n stepDown,\n joinStage,\n ask: (text) =>\n questionAction(async () => {\n if (!callKey) throw new Error('This call has no key.')\n await webinarApi().questions.ask(\n callExtId,\n await sealQuestionText(text, callKey),\n linkVersion\n )\n }, 'ask the question'),\n vote: (id, up) =>\n questionAction(() => webinarApi().questions.vote(callExtId, id, up, linkVersion), 'vote'),\n setQuestionStatus: (id, status) =>\n questionAction(\n () => webinarApi().questions.update(callExtId, id, { status }, linkVersion),\n 'update the question'\n ),\n answer: (id, text) =>\n questionAction(async () => {\n if (!callKey) throw new Error('This call has no key.')\n await webinarApi().questions.update(\n callExtId,\n id,\n { answer: await sealQuestionText(text, callKey) },\n linkVersion\n )\n }, 'answer the question'),\n removeQuestion: (id) =>\n questionAction(\n () => webinarApi().questions.delete(callExtId, id, linkVersion),\n 'delete the question'\n ),\n }),\n [\n enabled,\n role,\n state,\n onStage,\n questions,\n stageCheck,\n refresh,\n patch,\n callExtId,\n linkVersion,\n callKey,\n stepDown,\n joinStage,\n questionAction,\n ]\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {
|
|
2
|
+
decryptCallTitle,
|
|
3
|
+
encryptWithChatKey,
|
|
4
|
+
generateChatKey,
|
|
5
|
+
sealCallKey,
|
|
6
|
+
sealChatKey
|
|
7
|
+
} from "@arbidocs/client";
|
|
8
|
+
import { chats } from "@arbidocs/sdk/browser";
|
|
9
|
+
import { arbiQueryKeys } from "../hooks.js";
|
|
10
|
+
import { cachedChats } from "../directmessages/chat-cache.js";
|
|
11
|
+
import { invalidateConversationLists } from "../conversation-list.js";
|
|
12
|
+
function meetingChatRefFrom(row) {
|
|
13
|
+
if (row.chat_ext_id) return { kind: "chat", chatExtId: row.chat_ext_id };
|
|
14
|
+
const workspaceExtId = row.workspace_ext_id ?? row.locked_workspace_ext_id;
|
|
15
|
+
if (row.meeting_conversation_ext_id && workspaceExtId) {
|
|
16
|
+
return {
|
|
17
|
+
kind: "thread",
|
|
18
|
+
conversationExtId: row.meeting_conversation_ext_id,
|
|
19
|
+
workspaceExtId
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
function callMemberKeys(call) {
|
|
25
|
+
const keys = /* @__PURE__ */ new Map();
|
|
26
|
+
if (call.creator_ext_id && call.creator_encryption_public_key) {
|
|
27
|
+
keys.set(call.creator_ext_id, call.creator_encryption_public_key);
|
|
28
|
+
}
|
|
29
|
+
for (const i of call.invitees ?? []) {
|
|
30
|
+
if (i.encryption_public_key) keys.set(i.user_ext_id, i.encryption_public_key);
|
|
31
|
+
}
|
|
32
|
+
return keys;
|
|
33
|
+
}
|
|
34
|
+
async function publicKeysFor(arbi, queryClient, userExtIds, known) {
|
|
35
|
+
const wanted = new Set(userExtIds);
|
|
36
|
+
const keys = new Map([...known].filter(([id]) => wanted.has(id)));
|
|
37
|
+
if (![...wanted].some((id) => !keys.has(id))) return keys;
|
|
38
|
+
for (const chat of cachedChats(queryClient)) {
|
|
39
|
+
for (const m of chat.members) {
|
|
40
|
+
if (wanted.has(m.user.external_id) && !keys.has(m.user.external_id) && m.user.encryption_public_key) {
|
|
41
|
+
keys.set(m.user.external_id, m.user.encryption_public_key);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if ([...wanted].some((id) => !keys.has(id))) {
|
|
46
|
+
try {
|
|
47
|
+
for (const c of await arbi.contacts.list()) {
|
|
48
|
+
const u = c.user;
|
|
49
|
+
if (u && wanted.has(u.external_id) && u.encryption_public_key && !keys.has(u.external_id)) {
|
|
50
|
+
keys.set(u.external_id, u.encryption_public_key);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
} catch (err) {
|
|
54
|
+
console.warn("[calls] could not load contacts for the meeting chat", err);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return keys;
|
|
58
|
+
}
|
|
59
|
+
async function buildMeetingChatBody(arbi, queryClient, call, callKey, extraMembers = []) {
|
|
60
|
+
if (!arbi.isLoggedIn) throw new Error("Sign in to keep the meeting chat");
|
|
61
|
+
const { externalId: me, publicKey: myPublicKey } = await arbi.chats.identity();
|
|
62
|
+
const hosts = /* @__PURE__ */ new Set([
|
|
63
|
+
call.creator_ext_id,
|
|
64
|
+
...(call.invitees ?? []).map((i) => i.user_ext_id)
|
|
65
|
+
]);
|
|
66
|
+
const memberIds = [.../* @__PURE__ */ new Set([...hosts, ...extraMembers])].filter(
|
|
67
|
+
(id) => id && id !== me && !chats.isAgentExtId(id)
|
|
68
|
+
);
|
|
69
|
+
const pubKeys = await publicKeysFor(arbi, queryClient, memberIds, callMemberKeys(call));
|
|
70
|
+
const key = await generateChatKey();
|
|
71
|
+
try {
|
|
72
|
+
const members = [];
|
|
73
|
+
for (const id of memberIds) {
|
|
74
|
+
const pk = pubKeys.get(id);
|
|
75
|
+
if (!pk) {
|
|
76
|
+
console.warn("[calls] no public key for meeting-chat member", id);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
members.push({
|
|
80
|
+
user_ext_id: id,
|
|
81
|
+
sealed_key: await sealChatKey(key, pk),
|
|
82
|
+
...hosts.has(id) ? {} : { call_sealed_key: await sealCallKey(callKey, pk) }
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const title = call.title ? await decryptCallTitle(call.title, callKey) : null;
|
|
86
|
+
return {
|
|
87
|
+
title: await encryptWithChatKey(title?.trim() || "Meeting", key),
|
|
88
|
+
creator_sealed_key: await sealChatKey(key, myPublicKey),
|
|
89
|
+
members
|
|
90
|
+
};
|
|
91
|
+
} finally {
|
|
92
|
+
key.fill(0);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const pending = /* @__PURE__ */ new Map();
|
|
96
|
+
function ensureMeetingChat(arbi, queryClient, callExtId, callKey) {
|
|
97
|
+
const inFlight = pending.get(callExtId);
|
|
98
|
+
if (inFlight) return inFlight;
|
|
99
|
+
const run = (async () => {
|
|
100
|
+
const call = await arbi.calls.get(callExtId);
|
|
101
|
+
const existing = meetingChatRefFrom(call);
|
|
102
|
+
if (existing) return existing;
|
|
103
|
+
const body = call.workspace_locked ? void 0 : await buildMeetingChatBody(arbi, queryClient, call, callKey);
|
|
104
|
+
const answer = await arbi.calls.chat(callExtId, body);
|
|
105
|
+
const ref = meetingChatRefFrom({
|
|
106
|
+
...answer,
|
|
107
|
+
locked_workspace_ext_id: call.locked_workspace_ext_id
|
|
108
|
+
});
|
|
109
|
+
if (!ref) throw new Error("The server did not return a meeting chat");
|
|
110
|
+
if (ref.kind === "chat")
|
|
111
|
+
void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.chatList() });
|
|
112
|
+
else void invalidateConversationLists(queryClient);
|
|
113
|
+
return ref;
|
|
114
|
+
})();
|
|
115
|
+
pending.set(callExtId, run);
|
|
116
|
+
run.catch(() => pending.delete(callExtId));
|
|
117
|
+
return run;
|
|
118
|
+
}
|
|
119
|
+
function clearMeetingChatCache() {
|
|
120
|
+
pending.clear();
|
|
121
|
+
}
|
|
122
|
+
function knownMeetingChat(target) {
|
|
123
|
+
if (target.chatExtId) return { kind: "chat", chatExtId: target.chatExtId };
|
|
124
|
+
if (target.meetingConversationExtId && target.workspaceExtId) {
|
|
125
|
+
return {
|
|
126
|
+
kind: "thread",
|
|
127
|
+
conversationExtId: target.meetingConversationExtId,
|
|
128
|
+
workspaceExtId: target.workspaceExtId
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
async function resolveMeetingChat(arbi, queryClient, target) {
|
|
134
|
+
const known = knownMeetingChat(target);
|
|
135
|
+
if (known) return known;
|
|
136
|
+
const key = target.callKey ?? await arbi.calls.key(await arbi.calls.get(target.callExtId));
|
|
137
|
+
if (!key) throw new Error("You are not invited to this call");
|
|
138
|
+
return ensureMeetingChat(arbi, queryClient, target.callExtId, key);
|
|
139
|
+
}
|
|
140
|
+
export {
|
|
141
|
+
buildMeetingChatBody,
|
|
142
|
+
callMemberKeys,
|
|
143
|
+
clearMeetingChatCache,
|
|
144
|
+
ensureMeetingChat,
|
|
145
|
+
knownMeetingChat,
|
|
146
|
+
meetingChatRefFrom,
|
|
147
|
+
resolveMeetingChat
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=meeting-chat.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/calls/meeting-chat.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * The meeting chat of a call (ARBI `docs/meeting-chats-plan.md` \u00A73\u20134).\n *\n * Every call has one place its conversation persists:\n * - an E2E `chats` row (`cht-`): the direct chat of a DM call, the group of a group call, or a\n * `meeting` chat made lazily on first use \u2014 its key is a fresh random epoch key sealed in this\n * browser to each member (creator + invitees by default), its title encrypted under it;\n * - a shared thread (`con-`) in the locked workspace of a thread call \u2014 encrypted by the server\n * with the workspace key like any thread, so @ARBI works there.\n *\n * `ensureMeetingChat` is get-or-create (`POST /v1/calls/{id}/chat`; the server serialises\n * concurrent creators, the loser gets the winner's chat).\n */\n\nimport {\n decryptCallTitle,\n encryptWithChatKey,\n generateChatKey,\n sealCallKey,\n sealChatKey,\n} from '@arbidocs/client'\nimport type { QueryClient } from '@tanstack/react-query'\nimport { chats, type Arbi, type calls } from '@arbidocs/sdk/browser'\nimport { arbiQueryKeys } from '../hooks'\nimport { cachedChats } from '../directmessages/chat-cache'\nimport { invalidateConversationLists } from '../conversation-list'\n\nexport type MeetingChatRef =\n | { kind: 'chat'; chatExtId: string }\n | { kind: 'thread'; conversationExtId: string; workspaceExtId: string }\n\n/** The meeting chat a call (or a `POST /chat` answer) already names, or null. */\nexport function meetingChatRefFrom(\n row: Pick<calls.CallResponse, 'chat_ext_id' | 'meeting_conversation_ext_id'> & {\n locked_workspace_ext_id?: string | null\n workspace_ext_id?: string | null\n }\n): MeetingChatRef | null {\n if (row.chat_ext_id) return { kind: 'chat', chatExtId: row.chat_ext_id }\n const workspaceExtId = row.workspace_ext_id ?? row.locked_workspace_ext_id\n if (row.meeting_conversation_ext_id && workspaceExtId) {\n return {\n kind: 'thread',\n conversationExtId: row.meeting_conversation_ext_id,\n workspaceExtId,\n }\n }\n return null\n}\n\n/** The keys the call row itself carries: its creator's and each invitee's. */\nexport function callMemberKeys(\n call: Pick<calls.CallResponse, 'creator_ext_id' | 'creator_encryption_public_key' | 'invitees'>\n): Map<string, string> {\n const keys = new Map<string, string>()\n if (call.creator_ext_id && call.creator_encryption_public_key) {\n keys.set(call.creator_ext_id, call.creator_encryption_public_key)\n }\n for (const i of call.invitees ?? []) {\n if (i.encryption_public_key) keys.set(i.user_ext_id, i.encryption_public_key)\n }\n return keys\n}\n\n/**\n * Public keys of the people a meeting chat is sealed to: the call row's own keys first (creator and\n * invitees \u2014 no dependence on my chat list or contacts), then, for extra members only, known chat\n * members and contacts.\n */\nasync function publicKeysFor(\n arbi: Arbi,\n queryClient: QueryClient,\n userExtIds: string[],\n known: Map<string, string>\n): Promise<Map<string, string>> {\n const wanted = new Set(userExtIds)\n const keys = new Map<string, string>([...known].filter(([id]) => wanted.has(id)))\n if (![...wanted].some((id) => !keys.has(id))) return keys\n for (const chat of cachedChats(queryClient)) {\n for (const m of chat.members) {\n if (\n wanted.has(m.user.external_id) &&\n !keys.has(m.user.external_id) &&\n m.user.encryption_public_key\n ) {\n keys.set(m.user.external_id, m.user.encryption_public_key)\n }\n }\n }\n if ([...wanted].some((id) => !keys.has(id))) {\n try {\n for (const c of await arbi.contacts.list()) {\n const u = c.user\n if (u && wanted.has(u.external_id) && u.encryption_public_key && !keys.has(u.external_id)) {\n keys.set(u.external_id, u.encryption_public_key)\n }\n }\n } catch (err) {\n console.warn('[calls] could not load contacts for the meeting chat', err)\n }\n }\n return keys\n}\n\n/**\n * The E2E body for a new meeting chat: a fresh chat key sealed to me and to each member whose\n * public key is known (the call's creator and invitees by default, with the keys the call row\n * carries; `extraMembers` beyond them also get K sealed to them, so they can always join), and the\n * call's title under the chat key. A member without a key is left out (they can be added later);\n * `members` may be empty \u2014 a chat with only me is valid.\n */\nexport async function buildMeetingChatBody(\n arbi: Arbi,\n queryClient: QueryClient,\n call: calls.CallResponse,\n callKey: Uint8Array,\n extraMembers: string[] = []\n): Promise<calls.CallChatCreate> {\n if (!arbi.isLoggedIn) throw new Error('Sign in to keep the meeting chat')\n const { externalId: me, publicKey: myPublicKey } = await arbi.chats.identity()\n const hosts = new Set<string>([\n call.creator_ext_id,\n ...(call.invitees ?? []).map((i) => i.user_ext_id),\n ])\n const memberIds = [...new Set([...hosts, ...extraMembers])].filter(\n (id) => id && id !== me && !chats.isAgentExtId(id)\n )\n const pubKeys = await publicKeysFor(arbi, queryClient, memberIds, callMemberKeys(call))\n const key = await generateChatKey()\n try {\n const members: calls.CallChatCreate['members'] = []\n for (const id of memberIds) {\n const pk = pubKeys.get(id)\n if (!pk) {\n // Nobody to seal to: they can be added to the chat later.\n console.warn('[calls] no public key for meeting-chat member', id)\n continue\n }\n members.push({\n user_ext_id: id,\n sealed_key: await sealChatKey(key, pk),\n ...(hosts.has(id) ? {} : { call_sealed_key: await sealCallKey(callKey, pk) }),\n })\n }\n const title = call.title ? await decryptCallTitle(call.title, callKey) : null\n return {\n title: await encryptWithChatKey(title?.trim() || 'Meeting', key),\n creator_sealed_key: await sealChatKey(key, myPublicKey),\n members,\n }\n } finally {\n key.fill(0)\n }\n}\n\nconst pending = new Map<string, Promise<MeetingChatRef>>()\n\n/** The call's meeting chat, made now if it has none. Concurrent callers share one request. */\nexport function ensureMeetingChat(\n arbi: Arbi,\n queryClient: QueryClient,\n callExtId: string,\n callKey: Uint8Array\n): Promise<MeetingChatRef> {\n const inFlight = pending.get(callExtId)\n if (inFlight) return inFlight\n const run = (async () => {\n const call = await arbi.calls.get(callExtId)\n const existing = meetingChatRefFrom(call)\n if (existing) return existing\n const body = call.workspace_locked\n ? undefined\n : await buildMeetingChatBody(arbi, queryClient, call, callKey)\n const answer = await arbi.calls.chat(callExtId, body)\n const ref = meetingChatRefFrom({\n ...answer,\n locked_workspace_ext_id: call.locked_workspace_ext_id,\n })\n if (!ref) throw new Error('The server did not return a meeting chat')\n // The new chat or meeting thread joins its list.\n if (ref.kind === 'chat')\n void queryClient.invalidateQueries({ queryKey: arbiQueryKeys.chatList() })\n else void invalidateConversationLists(queryClient)\n return ref\n })()\n pending.set(callExtId, run)\n // Keep a resolved ref cached for the session; forget failures so a retry can succeed.\n run.catch(() => pending.delete(callExtId))\n return run\n}\n\n/** Forget cached refs (tests; sign-out). */\nexport function clearMeetingChatCache(): void {\n pending.clear()\n}\n\n/** A call whose meeting chat is to be shown, with what is already known about it. */\nexport interface MeetingChatTarget {\n callExtId: string\n /** The call's E2E chat (DM / group / meeting), when known. */\n chatExtId?: string | null\n /** A thread call's meeting thread, when known, and its workspace. */\n meetingConversationExtId?: string | null\n workspaceExtId?: string | null\n /** K, when the caller already has it (else my sealed copy is opened). */\n callKey?: Uint8Array | null\n}\n\n/** The ref for a target whose chat is already known, or null when it must be made / looked up. */\nexport function knownMeetingChat(target: MeetingChatTarget): MeetingChatRef | null {\n if (target.chatExtId) return { kind: 'chat', chatExtId: target.chatExtId }\n if (target.meetingConversationExtId && target.workspaceExtId) {\n return {\n kind: 'thread',\n conversationExtId: target.meetingConversationExtId,\n workspaceExtId: target.workspaceExtId,\n }\n }\n return null\n}\n\n/** The target's meeting chat: the known one, else made on first use (needs K). */\nexport async function resolveMeetingChat(\n arbi: Arbi,\n queryClient: QueryClient,\n target: MeetingChatTarget\n): Promise<MeetingChatRef> {\n const known = knownMeetingChat(target)\n if (known) return known\n const key = target.callKey ?? (await arbi.calls.key(await arbi.calls.get(target.callExtId)))\n if (!key) throw new Error('You are not invited to this call')\n return ensureMeetingChat(arbi, queryClient, target.callExtId, key)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const CALL_MODERATION_TOPIC = "arbi.moderation";
|
|
2
|
+
function trackOf(value) {
|
|
3
|
+
return value === "audio" || value === "video" ? value : null;
|
|
4
|
+
}
|
|
5
|
+
function mutedNoticeFromPacket(payload) {
|
|
6
|
+
try {
|
|
7
|
+
const parsed = JSON.parse(new TextDecoder().decode(payload));
|
|
8
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
9
|
+
const p = parsed;
|
|
10
|
+
const track = trackOf(p.track);
|
|
11
|
+
if (p.action !== "muted" || !track) return null;
|
|
12
|
+
return { track, byName: typeof p.by_name === "string" ? p.by_name : null };
|
|
13
|
+
} catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function mutedNoticeText(notice) {
|
|
18
|
+
return notice.track === "audio" ? "The host muted you" : "The host turned off your camera";
|
|
19
|
+
}
|
|
20
|
+
const MUTED_DEDUPE_MS = 5e3;
|
|
21
|
+
function createMutedNotifier(show, now = Date.now) {
|
|
22
|
+
const last = /* @__PURE__ */ new Map();
|
|
23
|
+
return (notice) => {
|
|
24
|
+
const at = now();
|
|
25
|
+
const prev = last.get(notice.track);
|
|
26
|
+
if (prev !== void 0 && at - prev < MUTED_DEDUPE_MS) return;
|
|
27
|
+
last.set(notice.track, at);
|
|
28
|
+
show(mutedNoticeText(notice));
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function mutedNoticeFromEvent(raw) {
|
|
32
|
+
if (!raw || typeof raw !== "object") return null;
|
|
33
|
+
const r = raw;
|
|
34
|
+
const track = trackOf(r.track);
|
|
35
|
+
if (typeof r.call_ext_id !== "string" || !track) return null;
|
|
36
|
+
return {
|
|
37
|
+
callExtId: r.call_ext_id,
|
|
38
|
+
track,
|
|
39
|
+
byName: typeof r.by_name === "string" ? r.by_name : null
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
CALL_MODERATION_TOPIC,
|
|
44
|
+
MUTED_DEDUPE_MS,
|
|
45
|
+
createMutedNotifier,
|
|
46
|
+
mutedNoticeFromEvent,
|
|
47
|
+
mutedNoticeFromPacket,
|
|
48
|
+
mutedNoticeText
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=moderation.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/calls/moderation.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * The host's moderation of a call, as the moderated participant sees it.\n *\n * `POST /v1/calls/{id}/participants/{identity}/mute` mutes one of my tracks server-side and tells me\n * twice: a SERVER-sent LiveKit data message on {@link CALL_MODERATION_TOPIC}\n * (`{action: \"muted\", track, by_identity, by_name}`, plaintext, no content) and WS `call.muted`\n * (`{call_ext_id, track, by_name}`). Either may arrive first (or alone); one toast is shown.\n */\n\nexport const CALL_MODERATION_TOPIC = 'arbi.moderation'\n\nexport type ModeratedTrack = 'audio' | 'video'\n\nexport interface CallMutedNotice {\n track: ModeratedTrack\n byName: string | null\n}\n\nfunction trackOf(value: unknown): ModeratedTrack | null {\n return value === 'audio' || value === 'video' ? value : null\n}\n\n/** A moderation data packet's \"muted\" notice; null when malformed or another action. */\nexport function mutedNoticeFromPacket(payload: Uint8Array): CallMutedNotice | null {\n try {\n const parsed: unknown = JSON.parse(new TextDecoder().decode(payload))\n if (!parsed || typeof parsed !== 'object') return null\n const p = parsed as { action?: unknown; track?: unknown; by_name?: unknown }\n const track = trackOf(p.track)\n if (p.action !== 'muted' || !track) return null\n return { track, byName: typeof p.by_name === 'string' ? p.by_name : null }\n } catch {\n return null\n }\n}\n\n/** The toast for a notice. */\nexport function mutedNoticeText(notice: CallMutedNotice): string {\n return notice.track === 'audio' ? 'The host muted you' : 'The host turned off your camera'\n}\n\n/** Both channels report one mute within this window; a later mute of the same track toasts again. */\nexport const MUTED_DEDUPE_MS = 5_000\n\n/**\n * A notifier that shows one toast per mute: the data message and the WS event for the same track\n * within {@link MUTED_DEDUPE_MS} collapse into one.\n */\nexport function createMutedNotifier(\n show: (text: string) => void,\n now: () => number = Date.now\n): (notice: CallMutedNotice) => void {\n const last = new Map<ModeratedTrack, number>()\n return (notice) => {\n const at = now()\n const prev = last.get(notice.track)\n if (prev !== undefined && at - prev < MUTED_DEDUPE_MS) return\n last.set(notice.track, at)\n show(mutedNoticeText(notice))\n }\n}\n\n/** A WS `call.muted` as a notice for the open room; null when malformed. */\nexport function mutedNoticeFromEvent(\n raw: unknown\n): (CallMutedNotice & { callExtId: string }) | null {\n if (!raw || typeof raw !== 'object') return null\n const r = raw as { call_ext_id?: unknown; track?: unknown; by_name?: unknown }\n const track = trackOf(r.track)\n if (typeof r.call_ext_id !== 'string' || !track) return null\n return {\n callExtId: r.call_ext_id,\n track,\n byName: typeof r.by_name === 'string' ? r.by_name : null,\n }\n}\n"],
|
|
5
|
+
"mappings": "AASO,MAAM,wBAAwB;AASrC,SAAS,QAAQ,OAAuC;AACtD,SAAO,UAAU,WAAW,UAAU,UAAU,QAAQ;AAC1D;AAGO,SAAS,sBAAsB,SAA6C;AACjF,MAAI;AACF,UAAM,SAAkB,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,OAAO,CAAC;AACpE,QAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO;AAClD,UAAM,IAAI;AACV,UAAM,QAAQ,QAAQ,EAAE,KAAK;AAC7B,QAAI,EAAE,WAAW,WAAW,CAAC,MAAO,QAAO;AAC3C,WAAO,EAAE,OAAO,QAAQ,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU,KAAK;AAAA,EAC3E,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,gBAAgB,QAAiC;AAC/D,SAAO,OAAO,UAAU,UAAU,uBAAuB;AAC3D;AAGO,MAAM,kBAAkB;AAMxB,SAAS,oBACd,MACA,MAAoB,KAAK,KACU;AACnC,QAAM,OAAO,oBAAI,IAA4B;AAC7C,SAAO,CAAC,WAAW;AACjB,UAAM,KAAK,IAAI;AACf,UAAM,OAAO,KAAK,IAAI,OAAO,KAAK;AAClC,QAAI,SAAS,UAAa,KAAK,OAAO,gBAAiB;AACvD,SAAK,IAAI,OAAO,OAAO,EAAE;AACzB,SAAK,gBAAgB,MAAM,CAAC;AAAA,EAC9B;AACF;AAGO,SAAS,qBACd,KACkD;AAClD,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,QAAM,IAAI;AACV,QAAM,QAAQ,QAAQ,EAAE,KAAK;AAC7B,MAAI,OAAO,EAAE,gBAAgB,YAAY,CAAC,MAAO,QAAO;AACxD,SAAO;AAAA,IACL,WAAW,EAAE;AAAA,IACb;AAAA,IACA,QAAQ,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;AAAA,EACtD;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
3
|
+
import { useArbi } from "../useArbi.js";
|
|
4
|
+
import { useArbiHost } from "../host/config.js";
|
|
5
|
+
import { notify } from "../notifications/notify-store.js";
|
|
6
|
+
import { resolveMeetingChat } from "./meeting-chat.js";
|
|
7
|
+
function useOpenCallMeetingChat() {
|
|
8
|
+
const arbi = useArbi();
|
|
9
|
+
const queryClient = useQueryClient();
|
|
10
|
+
const open = useArbiHost().calls?.openMeetingChat;
|
|
11
|
+
return useCallback(
|
|
12
|
+
async (target) => {
|
|
13
|
+
try {
|
|
14
|
+
const ref = await resolveMeetingChat(arbi, queryClient, target);
|
|
15
|
+
open?.(ref);
|
|
16
|
+
} catch (err) {
|
|
17
|
+
console.warn("[calls] could not open the meeting chat", err);
|
|
18
|
+
notify.error(
|
|
19
|
+
`Could not open the meeting chat: ${err instanceof Error ? err.message : "unknown error"}`
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
[arbi, queryClient, open]
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
useOpenCallMeetingChat
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=open-meeting-chat.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/calls/open-meeting-chat.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * \"Open meeting chat\" for every link that has one (a thread's call log card, a calendar event): a\n * known chat or meeting thread opens directly; otherwise the call's meeting chat is made on first\n * use. It opens where the host shows meeting chats (`calls.openMeetingChat`).\n */\n\nimport { useCallback } from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { useArbiHost } from '../host/config'\nimport { notify } from '../notifications/notify-store'\nimport { resolveMeetingChat, type MeetingChatTarget } from './meeting-chat'\n\nexport function useOpenCallMeetingChat(): (target: MeetingChatTarget) => Promise<void> {\n const arbi = useArbi()\n const queryClient = useQueryClient()\n const open = useArbiHost().calls?.openMeetingChat\n return useCallback(\n async (target) => {\n try {\n const ref = await resolveMeetingChat(arbi, queryClient, target)\n open?.(ref)\n } catch (err) {\n console.warn('[calls] could not open the meeting chat', err)\n notify.error(\n `Could not open the meeting chat: ${err instanceof Error ? err.message : 'unknown error'}`\n )\n }\n },\n [arbi, queryClient, open]\n )\n}\n"],
|
|
5
|
+
"mappings": "AAMA,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAC/B,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,SAAS,cAAc;AACvB,SAAS,0BAAkD;AAEpD,SAAS,yBAAuE;AACrF,QAAM,OAAO,QAAQ;AACrB,QAAM,cAAc,eAAe;AACnC,QAAM,OAAO,YAAY,EAAE,OAAO;AAClC,SAAO;AAAA,IACL,OAAO,WAAW;AAChB,UAAI;AACF,cAAM,MAAM,MAAM,mBAAmB,MAAM,aAAa,MAAM;AAC9D,eAAO,GAAG;AAAA,MACZ,SAAS,KAAK;AACZ,gBAAQ,KAAK,2CAA2C,GAAG;AAC3D,eAAO;AAAA,UACL,oCAAoC,eAAe,QAAQ,IAAI,UAAU,eAAe;AAAA,QAC1F;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,MAAM,aAAa,IAAI;AAAA,EAC1B;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useWorkspaces } from "../hooks.js";
|
|
2
|
+
import { useArbi } from "../useArbi.js";
|
|
3
|
+
function isWorkspaceGuestOf(workspaces, workspaceExtId, me) {
|
|
4
|
+
if (!workspaceExtId || !me || !workspaces) return false;
|
|
5
|
+
const workspace = workspaces.find((w) => w.external_id === workspaceExtId);
|
|
6
|
+
return workspace?.users?.find((wu) => wu.user.external_id === me)?.role === "guest";
|
|
7
|
+
}
|
|
8
|
+
function useMeetingReadOnly(lockedWorkspaceExtId) {
|
|
9
|
+
const arbi = useArbi();
|
|
10
|
+
const me = arbi.isLoggedIn ? arbi.user.identity()?.externalId ?? null : null;
|
|
11
|
+
const { data: workspaces } = useWorkspaces({
|
|
12
|
+
enabled: !!lockedWorkspaceExtId && arbi.isLoggedIn
|
|
13
|
+
});
|
|
14
|
+
return isWorkspaceGuestOf(
|
|
15
|
+
workspaces,
|
|
16
|
+
lockedWorkspaceExtId,
|
|
17
|
+
me
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
isWorkspaceGuestOf,
|
|
22
|
+
useMeetingReadOnly
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=read-only.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/calls/read-only.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Workspace guests may join a thread call (and are transcribed) but its meeting chat is read-only\n * for them: no in-call chat composer, no meeting-thread composer. Their transcript lines are stored\n * by a member's client (see `transcriptPersistRole`).\n */\n\nimport { useWorkspaces } from '../hooks'\nimport { useArbi } from '../useArbi'\n\ninterface WorkspaceRoster {\n external_id: string\n users?: { role?: string | null; user: { external_id: string } }[] | null\n}\n\n/** Whether I am a guest of `workspaceExtId` (pure, for tests). */\nexport function isWorkspaceGuestOf(\n workspaces: readonly WorkspaceRoster[] | undefined,\n workspaceExtId: string | null | undefined,\n me: string | null | undefined\n): boolean {\n if (!workspaceExtId || !me || !workspaces) return false\n const workspace = workspaces.find((w) => w.external_id === workspaceExtId)\n return workspace?.users?.find((wu) => wu.user.external_id === me)?.role === 'guest'\n}\n\n/** True when I am a guest of the workspace a thread call is locked to (null: not a thread call). */\nexport function useMeetingReadOnly(lockedWorkspaceExtId: string | null | undefined): boolean {\n const arbi = useArbi()\n const me = arbi.isLoggedIn ? (arbi.user.identity()?.externalId ?? null) : null\n const { data: workspaces } = useWorkspaces({\n enabled: !!lockedWorkspaceExtId && arbi.isLoggedIn,\n })\n return isWorkspaceGuestOf(\n workspaces as readonly WorkspaceRoster[] | undefined,\n lockedWorkspaceExtId,\n me\n )\n}\n"],
|
|
5
|
+
"mappings": "AAMA,SAAS,qBAAqB;AAC9B,SAAS,eAAe;AAQjB,SAAS,mBACd,YACA,gBACA,IACS;AACT,MAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAY,QAAO;AAClD,QAAM,YAAY,WAAW,KAAK,CAAC,MAAM,EAAE,gBAAgB,cAAc;AACzE,SAAO,WAAW,OAAO,KAAK,CAAC,OAAO,GAAG,KAAK,gBAAgB,EAAE,GAAG,SAAS;AAC9E;AAGO,SAAS,mBAAmB,sBAA0D;AAC3F,QAAM,OAAO,QAAQ;AACrB,QAAM,KAAK,KAAK,aAAc,KAAK,KAAK,SAAS,GAAG,cAAc,OAAQ;AAC1E,QAAM,EAAE,MAAM,WAAW,IAAI,cAAc;AAAA,IACzC,SAAS,CAAC,CAAC,wBAAwB,KAAK;AAAA,EAC1C,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|