@arbidocs/react 0.5.111 → 0.5.113
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/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.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.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.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/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.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.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.js +702 -17116
- package/dist/index.js.map +7 -1
- package/dist/{chunk-SSXFVWCT.js → lazy-chunk.js} +8 -8
- 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/{chunk-ZM6N7YZH.js → query-keys.js} +18 -31
- 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.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.js +290 -10
- 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.js +19 -3
- package/dist/viewers/PdfViewer.js.map +7 -1
- package/dist/{PdfViewerImpl-TEBYF2QI.js → viewers/PdfViewerImpl.js} +25 -19
- 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.js +61 -271
- 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 +4 -4
- package/dist/PdfViewerImpl-TEBYF2QI.js.map +0 -1
- package/dist/PdfViewerImpl.d-B28hLEuj.d.cts +0 -62
- 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-4FL3X3LA.js +0 -2057
- package/dist/chunk-4FL3X3LA.js.map +0 -1
- package/dist/chunk-6QNBSXCE.js +0 -271
- package/dist/chunk-6QNBSXCE.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-DPYBZDJB.js.map +0 -1
- package/dist/chunk-DZKRL5H3.js +0 -2766
- package/dist/chunk-DZKRL5H3.js.map +0 -1
- package/dist/chunk-HDCRPPBW.js +0 -75
- package/dist/chunk-HDCRPPBW.js.map +0 -1
- package/dist/chunk-L2IPPTVC.js +0 -20
- package/dist/chunk-L2IPPTVC.js.map +0 -1
- package/dist/chunk-LSU4UPS5.js +0 -1011
- package/dist/chunk-LSU4UPS5.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-PTOP7OHG.js.map +0 -1
- package/dist/chunk-QMY2JKBI.js +0 -246
- package/dist/chunk-QMY2JKBI.js.map +0 -1
- package/dist/chunk-SN5YV6FF.js +0 -11
- package/dist/chunk-SN5YV6FF.js.map +0 -1
- package/dist/chunk-SSXFVWCT.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-XWPLOFDN.js +0 -644
- package/dist/chunk-XWPLOFDN.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/chunk-ZM6N7YZH.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-LArLnpI8.d.cts +0 -2036
- package/dist/index.d-oR5FKZpJ.d.cts +0 -579
- package/dist/index.d.cts +0 -15923
- package/dist/lazy-chunk.d-B6YDLMKI.d.cts +0 -31
- package/dist/model.d-CNtRWKVK.d.cts +0 -110
- package/dist/query-keys.d-B1Am9tIF.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 -26
- package/dist/useAudioRecorder.d-B9rlMI_E.d.cts +0 -778
- package/dist/viewers/PdfViewer.d.cts +0 -9
- package/dist/viewers/index.d.cts +0 -262
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/documents/useAudioRecorder.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * useAudioRecorder\n *\n * Shared recording engine \u2014 getUserMedia capture, MediaRecorder lifecycle,\n * and an AnalyserNode-driven live level meter. Host apps layer their own\n * interaction model on top of the primitives here: a press-and-hold mic\n * calls start()/stop() on press/release and never pauses; a toggle-style\n * recorder exposes all of start/pause/resume/stop/reset as buttons.\n *\n * Two optional modes extend it (both used by live call transcription):\n * - `track`: record from a MediaStreamTrack the host already has (a call's\n * microphone track) instead of opening the microphone; the track stays the\n * host's and is never stopped here.\n * - `onSegment`: segmenting mode. Instead of one recording, the level meter\n * drives a voice-activity state machine (`audio-segmenter.ts`) and each\n * speech segment is recorded by its own MediaRecorder, so every emitted\n * blob is a standalone file. Too-short segments are dropped. `blob` stays\n * null and pause/resume do nothing in this mode. Stopping, unmounting or\n * hiding the page emits the open segment (if it held enough voice).\n * - `chunkMs` (with `onSegment`): chunk mode, used by call recording. No\n * voice detection: the recorder is restarted every `chunkMs`\n * (`chunked-recorder.ts`), so every part \u2014 silence included \u2014 is a\n * standalone file, emitted in order through `onSegment`. Stopping (or\n * unmounting) flushes the tail part: a recording never drops audio.\n *\n * REUSE-FIRST: no app coupling. Failures surface via the returned `error`\n * string rather than an app-specific toast/notification call \u2014 the host\n * decides how (or whether) to display it.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { classifyMediaError } from './media-error'\nimport {\n createChunkedRecorder,\n pickRecorderMimeType,\n type ChunkedRecorder,\n} from './chunked-recorder'\nimport {\n DEFAULT_SEGMENTER_CONFIG,\n flushSegmenter,\n INITIAL_SEGMENTER_STATE,\n levelFromRms,\n stepSegmenter,\n type SegmenterConfig,\n type SegmenterEvent,\n type SegmenterState,\n} from './audio-segmenter'\n\n// How often the live level meter updates (ms). Fast enough to read as live,\n// slow enough not to spam React with a render per animation frame.\nconst LEVEL_UPDATE_INTERVAL_MS = 50\n\nexport type AudioRecorderState = 'idle' | 'recording' | 'paused' | 'stopped'\n\n/** One speech segment emitted in segmenting mode. */\nexport interface AudioSegment {\n /** A standalone recording (its own container header), ready to upload. */\n blob: Blob\n mimeType: string\n /** Wall-clock start of the segment, ms since epoch. */\n startedAt: number\n durationMs: number\n /** How much of it carried voice (chunk mode: the whole part). */\n voiceMs: number\n /** Chunk mode: the part's index in this recording run (0, 1, 2\u2026). */\n index?: number\n}\n\nexport interface UseAudioRecorderOptions {\n /** Record from this track instead of opening the microphone (it is never stopped here). */\n track?: MediaStreamTrack | null\n /** Segmenting mode: called with each kept speech segment. */\n onSegment?: (segment: AudioSegment) => void\n /** Voice-activity tuning for segmenting mode. */\n segmenter?: Partial<SegmenterConfig>\n /** Chunk mode (with `onSegment`): a standalone part every `chunkMs`, no voice detection. */\n chunkMs?: number\n /** Chunk mode: the MediaRecorder MIME type (default: Opus/WebM, else AAC/MP4). */\n mimeType?: string\n /** Chunk mode: the encoder bitrate. */\n audioBitsPerSecond?: number\n}\n\nexport interface UseAudioRecorderResult {\n state: AudioRecorderState\n /** Live input level, 0-1. 0 while idle/paused/stopped. */\n level: number\n /** Total recorded duration so far (excludes time spent paused). Frozen at\n * its final value once stopped, until reset() clears it. */\n elapsedMs: number\n /** The finished recording. Only set once state === 'stopped'. */\n blob: Blob | null\n /** The MediaRecorder MIME type used (e.g. 'audio/webm'). Only set once\n * recording has started at least once. */\n mimeType: string | null\n /** A human-readable message from the last failed start() attempt. Cleared\n * at the start of every new attempt, so it always transitions through\n * `null` even if the next failure has the same message. */\n error: string | null\n start: () => Promise<void>\n pause: () => void\n resume: () => void\n stop: () => void\n /** Back to idle: clears blob/elapsedMs/mimeType, ready to record again. */\n reset: () => void\n}\n\nfunction pickSegmentMimeType(): string {\n if (MediaRecorder.isTypeSupported('audio/webm;codecs=opus')) return 'audio/webm;codecs=opus'\n return MediaRecorder.isTypeSupported('audio/webm') ? 'audio/webm' : 'audio/mp4'\n}\n\ninterface OpenSegment {\n recorder: MediaRecorder\n chunks: Blob[]\n /** Wall clock, ms since epoch. */\n startedAt: number\n}\n\nexport function useAudioRecorder(options: UseAudioRecorderOptions = {}): UseAudioRecorderResult {\n const optionsRef = useRef(options)\n optionsRef.current = options\n\n const [state, setState] = useState<AudioRecorderState>('idle')\n const [level, setLevel] = useState(0)\n const [elapsedMs, setElapsedMs] = useState(0)\n const [blob, setBlob] = useState<Blob | null>(null)\n const [mimeType, setMimeType] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n\n const mediaRecorderRef = useRef<MediaRecorder | null>(null)\n const chunksRef = useRef<Blob[]>([])\n const streamRef = useRef<MediaStream | null>(null)\n // Only a stream this hook opened (getUserMedia) is stopped here; a host's track is left alone.\n const ownsStreamRef = useRef(false)\n const stateRef = useRef<AudioRecorderState>('idle')\n stateRef.current = state\n // Elapsed time is tracked as (time accumulated in prior recording segments)\n // + (time since the current segment started) \u2014 pause/resume closes one\n // segment and opens another, so a pause never counts toward the duration.\n const segmentStartRef = useRef(0)\n const accumulatedMsRef = useRef(0)\n const audioContextRef = useRef<AudioContext | null>(null)\n const analyserRef = useRef<AnalyserNode | null>(null)\n const levelRafRef = useRef<number | null>(null)\n const levelIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null)\n\n // Segmenting mode: the voice-activity state and the recorder of the open segment.\n const segmentingRef = useRef(false)\n const segmenterStateRef = useRef<SegmenterState>(INITIAL_SEGMENTER_STATE)\n const openSegmentRef = useRef<OpenSegment | null>(null)\n const segmentMimeTypeRef = useRef<string | null>(null)\n // Chunk mode: the running chunked recorder.\n const chunkedRef = useRef<ChunkedRecorder | null>(null)\n\n const segmenterConfig = useCallback(\n (): SegmenterConfig => ({ ...DEFAULT_SEGMENTER_CONFIG, ...optionsRef.current.segmenter }),\n []\n )\n\n const beginSegment = useCallback(() => {\n const stream = streamRef.current\n const mt = segmentMimeTypeRef.current\n if (!stream || !mt) return\n const recorder = new MediaRecorder(stream, { mimeType: mt })\n const chunks: Blob[] = []\n recorder.ondataavailable = (e) => {\n if (e.data.size > 0) chunks.push(e.data)\n }\n recorder.start()\n openSegmentRef.current = { recorder, chunks, startedAt: Date.now() }\n }, [])\n\n /** Close the open segment's recorder; hand its file to `onSegment` when `keep`. */\n const endSegment = useCallback((keep: boolean, voiceMs: number) => {\n const open = openSegmentRef.current\n openSegmentRef.current = null\n if (!open) return\n const { recorder, chunks, startedAt } = open\n const durationMs = Date.now() - startedAt\n recorder.onstop = () => {\n const onSegment = optionsRef.current.onSegment\n if (!keep || !chunks.length || !onSegment) return\n const type = recorder.mimeType || segmentMimeTypeRef.current || 'audio/webm'\n onSegment({\n blob: new Blob(chunks, { type }),\n mimeType: type,\n startedAt,\n durationMs,\n voiceMs,\n })\n }\n if (recorder.state !== 'inactive') recorder.stop()\n }, [])\n\n const applySegmenterEvents = useCallback(\n (events: SegmenterEvent[]) => {\n for (const event of events) {\n if (event.type === 'start') beginSegment()\n else endSegment(event.keep, event.voiceMs)\n }\n },\n [beginSegment, endSegment]\n )\n\n /**\n * Segmenting mode: close what is being said now, emitting it through `onSegment` when it held\n * enough voice (stop, unmount, page hide) \u2014 the last line of a call is never silently dropped.\n */\n const flushOpenSegment = useCallback(() => {\n if (!segmentingRef.current) return\n const flushed = flushSegmenter(segmenterStateRef.current, performance.now(), segmenterConfig())\n segmenterStateRef.current = flushed.state\n applySegmenterEvents(flushed.events)\n endSegment(false, 0)\n }, [segmenterConfig, applySegmenterEvents, endSegment])\n\n const stopMeter = useCallback(() => {\n if (levelRafRef.current !== null) cancelAnimationFrame(levelRafRef.current)\n levelRafRef.current = null\n if (levelIntervalRef.current !== null) clearInterval(levelIntervalRef.current)\n levelIntervalRef.current = null\n analyserRef.current = null\n void audioContextRef.current?.close().catch(() => {})\n audioContextRef.current = null\n }, [])\n\n const startMeter = useCallback(\n (stream: MediaStream) => {\n const audioContext = new AudioContext()\n const source = audioContext.createMediaStreamSource(stream)\n const analyser = audioContext.createAnalyser()\n analyser.fftSize = 256\n source.connect(analyser)\n audioContextRef.current = audioContext\n analyserRef.current = analyser\n\n const data = new Uint8Array(analyser.frequencyBinCount)\n const segmenting = segmentingRef.current\n let lastUpdate = 0\n const tick = (t: number) => {\n const active = analyserRef.current\n if (!active) return\n if (t - lastUpdate >= LEVEL_UPDATE_INTERVAL_MS) {\n lastUpdate = t\n active.getByteTimeDomainData(data)\n let sumSquares = 0\n for (let i = 0; i < data.length; i++) {\n const centered = (data[i] - 128) / 128\n sumSquares += centered * centered\n }\n const rms = Math.sqrt(sumSquares / data.length)\n const nextLevel = levelFromRms(rms)\n setLevel(nextLevel)\n setElapsedMs(accumulatedMsRef.current + (t - segmentStartRef.current))\n if (segmenting) {\n const step = stepSegmenter(segmenterStateRef.current, nextLevel, t, segmenterConfig())\n segmenterStateRef.current = step.state\n applySegmenterEvents(step.events)\n }\n }\n if (!segmenting) levelRafRef.current = requestAnimationFrame(tick)\n }\n if (segmenting) {\n // A timer, not animation frames: frames stop in a background tab, and a\n // call keeps transcribing while its tab is hidden (an audible tab's\n // timers are not throttled).\n levelIntervalRef.current = setInterval(\n () => tick(performance.now()),\n LEVEL_UPDATE_INTERVAL_MS\n )\n } else {\n levelRafRef.current = requestAnimationFrame(tick)\n }\n },\n [segmenterConfig, applySegmenterEvents]\n )\n\n const stopTracks = useCallback(() => {\n if (ownsStreamRef.current) streamRef.current?.getTracks().forEach((t) => t.stop())\n streamRef.current = null\n ownsStreamRef.current = false\n }, [])\n\n useEffect(\n () => () => {\n // Unmounting emits the open segment (when it held enough voice: the host's handler outlives\n // it, e.g. a call's last line as the user hangs up), and a chunked recording flushes its\n // tail (the host's uploader outlives it).\n void chunkedRef.current?.stop()\n chunkedRef.current = null\n flushOpenSegment()\n endSegment(false, 0)\n segmentingRef.current = false\n segmenterStateRef.current = INITIAL_SEGMENTER_STATE\n stopTracks()\n stopMeter()\n },\n [flushOpenSegment, endSegment, stopTracks, stopMeter]\n )\n\n // Segmenting mode: the page going away (tab closed, reload) emits what was being said \u2014 best\n // effort, the host may still get to send it.\n useEffect(() => {\n const onPageHide = () => flushOpenSegment()\n window.addEventListener('pagehide', onPageHide)\n return () => window.removeEventListener('pagehide', onPageHide)\n }, [flushOpenSegment])\n\n const start = useCallback(async () => {\n if (stateRef.current === 'recording' || stateRef.current === 'paused') return\n setError(null)\n try {\n const { track, onSegment } = optionsRef.current\n // No await on the track path, so a host can start() and stop() within one effect cycle.\n const stream = track\n ? new MediaStream([track])\n : await navigator.mediaDevices.getUserMedia({ audio: true })\n streamRef.current = stream\n ownsStreamRef.current = !track\n const { chunkMs } = optionsRef.current\n if (onSegment && chunkMs) {\n const mt = optionsRef.current.mimeType ?? pickRecorderMimeType('audio')\n const chunked = createChunkedRecorder({\n stream,\n mimeType: mt,\n chunkMs,\n audioBitsPerSecond: optionsRef.current.audioBitsPerSecond,\n onChunk: (chunk) =>\n optionsRef.current.onSegment?.({\n blob: chunk.blob,\n mimeType: chunk.mimeType,\n startedAt: chunk.startedAt,\n durationMs: chunk.durationMs,\n voiceMs: chunk.durationMs,\n index: chunk.index,\n }),\n onError: (err) => setError(classifyMediaError(err, 'microphone')),\n })\n chunkedRef.current = chunked\n segmentingRef.current = false\n setMimeType(mt)\n setBlob(null)\n accumulatedMsRef.current = 0\n segmentStartRef.current = performance.now()\n chunked.start()\n stateRef.current = 'recording'\n setState('recording')\n return\n }\n if (onSegment) {\n const mt = pickSegmentMimeType()\n segmentMimeTypeRef.current = mt\n segmentingRef.current = true\n segmenterStateRef.current = INITIAL_SEGMENTER_STATE\n setMimeType(mt)\n setBlob(null)\n accumulatedMsRef.current = 0\n segmentStartRef.current = performance.now()\n stateRef.current = 'recording'\n setState('recording')\n startMeter(stream)\n return\n }\n segmentingRef.current = false\n const mt = MediaRecorder.isTypeSupported('audio/webm') ? 'audio/webm' : 'audio/mp4'\n const recorder = new MediaRecorder(stream, { mimeType: mt })\n chunksRef.current = []\n recorder.ondataavailable = (e) => {\n if (e.data.size > 0) chunksRef.current.push(e.data)\n }\n mediaRecorderRef.current = recorder\n setMimeType(mt)\n setBlob(null)\n accumulatedMsRef.current = 0\n segmentStartRef.current = performance.now()\n recorder.start()\n setState('recording')\n startMeter(stream)\n } catch (err) {\n segmentingRef.current = false\n stopTracks()\n setError(classifyMediaError(err, 'microphone'))\n }\n }, [startMeter, stopTracks])\n\n const pause = useCallback(() => {\n if (segmentingRef.current || chunkedRef.current) return\n const recorder = mediaRecorderRef.current\n if (!recorder || recorder.state !== 'recording') return\n recorder.pause()\n accumulatedMsRef.current += performance.now() - segmentStartRef.current\n stopMeter()\n setLevel(0)\n setState('paused')\n }, [stopMeter])\n\n const resume = useCallback(() => {\n if (segmentingRef.current || chunkedRef.current) return\n const recorder = mediaRecorderRef.current\n if (!recorder || recorder.state !== 'paused') return\n recorder.resume()\n segmentStartRef.current = performance.now()\n setState('recording')\n if (streamRef.current) startMeter(streamRef.current)\n }, [startMeter])\n\n const stop = useCallback(() => {\n const chunked = chunkedRef.current\n if (chunked) {\n // Flushes the tail part through onSegment.\n chunkedRef.current = null\n void chunked.stop()\n setElapsedMs(accumulatedMsRef.current + (performance.now() - segmentStartRef.current))\n stopTracks()\n stateRef.current = 'stopped'\n setState('stopped')\n return\n }\n if (segmentingRef.current) {\n // Emit what was being said when recording stopped (if it held enough voice).\n flushOpenSegment()\n segmentingRef.current = false\n stopMeter()\n stopTracks()\n setLevel(0)\n stateRef.current = 'stopped'\n setState('stopped')\n return\n }\n const recorder = mediaRecorderRef.current\n if (!recorder || recorder.state === 'inactive') return\n // Freeze the final duration before tearing the meter down \u2014 recording\n // won't include the time it takes MediaRecorder to flush+fire onstop.\n const finalElapsed =\n recorder.state === 'paused'\n ? accumulatedMsRef.current\n : accumulatedMsRef.current + (performance.now() - segmentStartRef.current)\n stopMeter()\n recorder.onstop = () => {\n stopTracks()\n const finalBlob = chunksRef.current.length\n ? new Blob(chunksRef.current, { type: recorder.mimeType })\n : null\n setBlob(finalBlob)\n setElapsedMs(finalElapsed)\n setLevel(0)\n setState('stopped')\n }\n recorder.stop()\n }, [stopMeter, stopTracks, flushOpenSegment])\n\n const reset = useCallback(() => {\n setState('idle')\n setBlob(null)\n setElapsedMs(0)\n setLevel(0)\n setMimeType(null)\n setError(null)\n }, [])\n\n return { state, level, elapsedMs, blob, mimeType, error, start, pause, resume, stop, reset }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["mt"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { classifyMediaError } from "./media-error.js";
|
|
3
|
+
function useCameraStream(constraints = { video: true, audio: false }) {
|
|
4
|
+
const [stream, setStream] = useState(null);
|
|
5
|
+
const [isStarting, setIsStarting] = useState(false);
|
|
6
|
+
const [error, setError] = useState(null);
|
|
7
|
+
const streamRef = useRef(null);
|
|
8
|
+
const stop = useCallback(() => {
|
|
9
|
+
streamRef.current?.getTracks().forEach((t) => t.stop());
|
|
10
|
+
streamRef.current = null;
|
|
11
|
+
setStream(null);
|
|
12
|
+
}, []);
|
|
13
|
+
const constraintsRef = useRef(constraints);
|
|
14
|
+
constraintsRef.current = constraints;
|
|
15
|
+
const start = useCallback(async () => {
|
|
16
|
+
if (streamRef.current) return;
|
|
17
|
+
setError(null);
|
|
18
|
+
setIsStarting(true);
|
|
19
|
+
try {
|
|
20
|
+
const media = await navigator.mediaDevices.getUserMedia(constraintsRef.current);
|
|
21
|
+
streamRef.current = media;
|
|
22
|
+
setStream(media);
|
|
23
|
+
} catch (err) {
|
|
24
|
+
setError(classifyMediaError(err, "camera"));
|
|
25
|
+
} finally {
|
|
26
|
+
setIsStarting(false);
|
|
27
|
+
}
|
|
28
|
+
}, []);
|
|
29
|
+
useEffect(() => () => stop(), [stop]);
|
|
30
|
+
return { stream, isStarting, error, start, stop };
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
useCameraStream
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=useCameraStream.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/documents/useCameraStream.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * useCameraStream\n *\n * Shared camera-acquisition engine for photo and video capture \u2014 requests\n * `getUserMedia`, hands back the live `MediaStream` for a host to bind to a\n * `<video>` element, and tears the tracks down on stop()/unmount. Mirrors\n * `useAudioRecorder`'s permission/error handling (same DOMException\n * classification, via `classifyMediaError`) but stays a separate hook rather\n * than folding into it: audio's state machine centers on an AnalyserNode\n * level meter with no visual preview, while camera capture centers on a live\n * video preview with no metering \u2014 sharing \"here is a device stream and an\n * error string\" is the useful overlap, not the recording state machine\n * itself. `useVideoRecorder` layers MediaRecorder on top of the stream this\n * returns; photo capture reads a frame off it directly (see capture-frame.ts).\n *\n * REUSE-FIRST: no app coupling, failures surface via `error` rather than a\n * toast call \u2014 same contract as useAudioRecorder.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { classifyMediaError } from './media-error'\n\nexport interface UseCameraStreamResult {\n /** The live camera stream, or null before start()/after stop(). */\n stream: MediaStream | null\n /** True while the getUserMedia() prompt/negotiation is in flight. */\n isStarting: boolean\n /** A human-readable message from the last failed start() attempt. */\n error: string | null\n start: () => Promise<void>\n /** Stops all tracks and clears the stream. Safe to call repeatedly. */\n stop: () => void\n}\n\n/**\n * @param constraints The `video`/`audio` constraints passed to getUserMedia.\n * Defaults to video-only (photo capture never needs a mic); video capture\n * passes `{ video: true, audio: true }` to record sound with the picture.\n */\nexport function useCameraStream(\n constraints: MediaStreamConstraints = { video: true, audio: false }\n): UseCameraStreamResult {\n const [stream, setStream] = useState<MediaStream | null>(null)\n const [isStarting, setIsStarting] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const streamRef = useRef<MediaStream | null>(null)\n\n const stop = useCallback(() => {\n streamRef.current?.getTracks().forEach((t) => t.stop())\n streamRef.current = null\n setStream(null)\n }, [])\n\n // Constraints are read fresh each start() call rather than becoming a hook\n // dependency: a host re-rendering with a new (but equivalent) constraints\n // object shouldn't force callers to memoize it just to avoid an effect loop.\n const constraintsRef = useRef(constraints)\n constraintsRef.current = constraints\n\n const start = useCallback(async () => {\n if (streamRef.current) return\n setError(null)\n setIsStarting(true)\n try {\n const media = await navigator.mediaDevices.getUserMedia(constraintsRef.current)\n streamRef.current = media\n setStream(media)\n } catch (err) {\n setError(classifyMediaError(err, 'camera'))\n } finally {\n setIsStarting(false)\n }\n }, [])\n\n useEffect(() => () => stop(), [stop])\n\n return { stream, isStarting, error, start, stop }\n}\n"],
|
|
5
|
+
"mappings": "AAmBA,SAAS,aAAa,WAAW,QAAQ,gBAAgB;AACzD,SAAS,0BAA0B;AAmB5B,SAAS,gBACd,cAAsC,EAAE,OAAO,MAAM,OAAO,MAAM,GAC3C;AACvB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAA6B,IAAI;AAC7D,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,YAAY,OAA2B,IAAI;AAEjD,QAAM,OAAO,YAAY,MAAM;AAC7B,cAAU,SAAS,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;AACtD,cAAU,UAAU;AACpB,cAAU,IAAI;AAAA,EAChB,GAAG,CAAC,CAAC;AAKL,QAAM,iBAAiB,OAAO,WAAW;AACzC,iBAAe,UAAU;AAEzB,QAAM,QAAQ,YAAY,YAAY;AACpC,QAAI,UAAU,QAAS;AACvB,aAAS,IAAI;AACb,kBAAc,IAAI;AAClB,QAAI;AACF,YAAM,QAAQ,MAAM,UAAU,aAAa,aAAa,eAAe,OAAO;AAC9E,gBAAU,UAAU;AACpB,gBAAU,KAAK;AAAA,IACjB,SAAS,KAAK;AACZ,eAAS,mBAAmB,KAAK,QAAQ,CAAC;AAAA,IAC5C,UAAE;AACA,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC;AAEpC,SAAO,EAAE,QAAQ,YAAY,OAAO,OAAO,KAAK;AAClD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { useArbi } from "../useArbi.js";
|
|
3
|
+
import { FINISHED_DOCUMENT_STATUSES } from "./documents-data.js";
|
|
4
|
+
import { useProcessingTasks } from "./support.js";
|
|
5
|
+
const BATCH_SIZE = 200;
|
|
6
|
+
const IN_PROGRESS = /* @__PURE__ */ new Set(["queued", "parsing", "encrypting", "indexing", "analysing"]);
|
|
7
|
+
function useDocumentThumbnails(visibleIds) {
|
|
8
|
+
const arbi = useArbi();
|
|
9
|
+
const workspaceId = arbi.hasWorkspace ? arbi.getWorkspaceId() : null;
|
|
10
|
+
const tasks = useProcessingTasks();
|
|
11
|
+
const tasksRef = useRef(tasks);
|
|
12
|
+
tasksRef.current = tasks;
|
|
13
|
+
const [thumbnails, setThumbnails] = useState(/* @__PURE__ */ new Map());
|
|
14
|
+
const resolvedRef = useRef(/* @__PURE__ */ new Set());
|
|
15
|
+
const inflightRef = useRef(/* @__PURE__ */ new Set());
|
|
16
|
+
const idsKey = visibleIds.join(",");
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
resolvedRef.current = /* @__PURE__ */ new Set();
|
|
19
|
+
inflightRef.current = /* @__PURE__ */ new Set();
|
|
20
|
+
setThumbnails(/* @__PURE__ */ new Map());
|
|
21
|
+
}, [workspaceId]);
|
|
22
|
+
const fetchMissing = useCallback(
|
|
23
|
+
async (ids) => {
|
|
24
|
+
if (!workspaceId) return;
|
|
25
|
+
const need = ids.filter((id) => !resolvedRef.current.has(id) && !inflightRef.current.has(id));
|
|
26
|
+
if (need.length === 0) return;
|
|
27
|
+
need.forEach((id) => inflightRef.current.add(id));
|
|
28
|
+
try {
|
|
29
|
+
const batches = [];
|
|
30
|
+
for (let i = 0; i < need.length; i += BATCH_SIZE)
|
|
31
|
+
batches.push(need.slice(i, i + BATCH_SIZE));
|
|
32
|
+
const results = await Promise.all(
|
|
33
|
+
batches.map((batch) => arbi.documents.getThumbnails(batch).catch(() => ({})))
|
|
34
|
+
);
|
|
35
|
+
const map = Object.assign({}, ...results);
|
|
36
|
+
setThumbnails((prev) => {
|
|
37
|
+
const next = new Map(prev);
|
|
38
|
+
for (const id of need) {
|
|
39
|
+
const uri = map[id];
|
|
40
|
+
if (uri) {
|
|
41
|
+
next.set(id, uri);
|
|
42
|
+
resolvedRef.current.add(id);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (!IN_PROGRESS.has(tasksRef.current[id]?.status ?? "")) resolvedRef.current.add(id);
|
|
46
|
+
}
|
|
47
|
+
return next;
|
|
48
|
+
});
|
|
49
|
+
} finally {
|
|
50
|
+
need.forEach((id) => inflightRef.current.delete(id));
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
[arbi, workspaceId]
|
|
54
|
+
);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (visibleIds.length > 0) void fetchMissing(visibleIds);
|
|
57
|
+
}, [idsKey, fetchMissing]);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
for (const id of visibleIds)
|
|
60
|
+
if (IN_PROGRESS.has(tasks[id]?.status ?? "")) resolvedRef.current.delete(id);
|
|
61
|
+
const ready = visibleIds.filter(
|
|
62
|
+
(id) => !resolvedRef.current.has(id) && FINISHED_DOCUMENT_STATUSES.has(tasks[id]?.status ?? "")
|
|
63
|
+
);
|
|
64
|
+
if (ready.length > 0) void fetchMissing(ready);
|
|
65
|
+
}, [tasks, idsKey, fetchMissing]);
|
|
66
|
+
return thumbnails;
|
|
67
|
+
}
|
|
68
|
+
export {
|
|
69
|
+
useDocumentThumbnails
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=useDocumentThumbnails.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/documents/useDocumentThumbnails.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Windowed thumbnail loader for a gallery of documents.\n *\n * - The caller passes only the **visible** document ids (a virtualised window plus overscan), not\n * the whole folder. They are fetched in batches \u2014 never one request per document.\n * - Results accumulate in a map that survives scrolling, so an id is fetched at most once;\n * scrolling fetches only the newly revealed ids.\n * - A freshly uploaded document's thumbnail exists once its processing finishes. Nothing polls:\n * a visible document reaching a finished status (its live processing, `useProcessingTasks`) is\n * fetched once at that moment. One that finishes with no thumbnail (video, audio, a failed\n * render) is not asked for again \u2014 until it is processed again, which is how a missing\n * thumbnail gets generated: going back into processing forgets what was known about it.\n * - Thumbnails come as `data:image/webp` URIs, used directly as `<img src>`.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { useArbi } from '../useArbi'\nimport { FINISHED_DOCUMENT_STATUSES } from './documents-data'\nimport { useProcessingTasks } from './support'\n\nconst BATCH_SIZE = 200\n\n/** Statuses of a document being (re)processed: what is known about its thumbnail is stale. */\nconst IN_PROGRESS = new Set(['queued', 'parsing', 'encrypting', 'indexing', 'analysing'])\n\n/** A `Map<docId, dataUri>` of thumbnails for the visible documents, growing as they scroll. */\nexport function useDocumentThumbnails(visibleIds: string[]): Map<string, string> {\n const arbi = useArbi()\n const workspaceId = arbi.hasWorkspace ? arbi.getWorkspaceId() : null\n const tasks = useProcessingTasks()\n const tasksRef = useRef(tasks)\n tasksRef.current = tasks\n\n const [thumbnails, setThumbnails] = useState<Map<string, string>>(new Map())\n // Ids already resolved (a thumbnail, or a final \"none\"): never fetched again.\n const resolvedRef = useRef<Set<string>>(new Set())\n // Ids with a request in flight: no duplicate concurrent fetches.\n const inflightRef = useRef<Set<string>>(new Set())\n const idsKey = visibleIds.join(',')\n\n // Another workspace: another set of documents.\n useEffect(() => {\n resolvedRef.current = new Set()\n inflightRef.current = new Set()\n setThumbnails(new Map())\n }, [workspaceId])\n\n const fetchMissing = useCallback(\n async (ids: string[]) => {\n if (!workspaceId) return\n const need = ids.filter((id) => !resolvedRef.current.has(id) && !inflightRef.current.has(id))\n if (need.length === 0) return\n need.forEach((id) => inflightRef.current.add(id))\n try {\n const batches: string[][] = []\n for (let i = 0; i < need.length; i += BATCH_SIZE)\n batches.push(need.slice(i, i + BATCH_SIZE))\n const results = await Promise.all(\n batches.map((batch) => arbi.documents.getThumbnails(batch).catch(() => ({})))\n )\n const map: Record<string, string | null> = Object.assign({}, ...results)\n setThumbnails((prev) => {\n const next = new Map(prev)\n for (const id of need) {\n const uri = map[id]\n if (uri) {\n next.set(id, uri)\n resolvedRef.current.add(id)\n continue\n }\n // Still mid-pipeline: its thumbnail may not exist yet; the finish will ask again.\n if (!IN_PROGRESS.has(tasksRef.current[id]?.status ?? '')) resolvedRef.current.add(id)\n }\n return next\n })\n } finally {\n need.forEach((id) => inflightRef.current.delete(id))\n }\n },\n [arbi, workspaceId]\n )\n\n // The newly revealed window.\n useEffect(() => {\n if (visibleIds.length > 0) void fetchMissing(visibleIds)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [idsKey, fetchMissing])\n\n // A visible document going back into processing forgets its thumbnail; one finishing is fetched.\n useEffect(() => {\n for (const id of visibleIds)\n if (IN_PROGRESS.has(tasks[id]?.status ?? '')) resolvedRef.current.delete(id)\n const ready = visibleIds.filter(\n (id) =>\n !resolvedRef.current.has(id) && FINISHED_DOCUMENT_STATUSES.has(tasks[id]?.status ?? '')\n )\n if (ready.length > 0) void fetchMissing(ready)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tasks, idsKey, fetchMissing])\n\n return thumbnails\n}\n"],
|
|
5
|
+
"mappings": "AAeA,SAAS,aAAa,WAAW,QAAQ,gBAAgB;AACzD,SAAS,eAAe;AACxB,SAAS,kCAAkC;AAC3C,SAAS,0BAA0B;AAEnC,MAAM,aAAa;AAGnB,MAAM,cAAc,oBAAI,IAAI,CAAC,UAAU,WAAW,cAAc,YAAY,WAAW,CAAC;AAGjF,SAAS,sBAAsB,YAA2C;AAC/E,QAAM,OAAO,QAAQ;AACrB,QAAM,cAAc,KAAK,eAAe,KAAK,eAAe,IAAI;AAChE,QAAM,QAAQ,mBAAmB;AACjC,QAAM,WAAW,OAAO,KAAK;AAC7B,WAAS,UAAU;AAEnB,QAAM,CAAC,YAAY,aAAa,IAAI,SAA8B,oBAAI,IAAI,CAAC;AAE3E,QAAM,cAAc,OAAoB,oBAAI,IAAI,CAAC;AAEjD,QAAM,cAAc,OAAoB,oBAAI,IAAI,CAAC;AACjD,QAAM,SAAS,WAAW,KAAK,GAAG;AAGlC,YAAU,MAAM;AACd,gBAAY,UAAU,oBAAI,IAAI;AAC9B,gBAAY,UAAU,oBAAI,IAAI;AAC9B,kBAAc,oBAAI,IAAI,CAAC;AAAA,EACzB,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,eAAe;AAAA,IACnB,OAAO,QAAkB;AACvB,UAAI,CAAC,YAAa;AAClB,YAAM,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,QAAQ,IAAI,EAAE,KAAK,CAAC,YAAY,QAAQ,IAAI,EAAE,CAAC;AAC5F,UAAI,KAAK,WAAW,EAAG;AACvB,WAAK,QAAQ,CAAC,OAAO,YAAY,QAAQ,IAAI,EAAE,CAAC;AAChD,UAAI;AACF,cAAM,UAAsB,CAAC;AAC7B,iBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,kBAAQ,KAAK,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC;AAC5C,cAAM,UAAU,MAAM,QAAQ;AAAA,UAC5B,QAAQ,IAAI,CAAC,UAAU,KAAK,UAAU,cAAc,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE,CAAC;AAAA,QAC9E;AACA,cAAM,MAAqC,OAAO,OAAO,CAAC,GAAG,GAAG,OAAO;AACvE,sBAAc,CAAC,SAAS;AACtB,gBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,qBAAW,MAAM,MAAM;AACrB,kBAAM,MAAM,IAAI,EAAE;AAClB,gBAAI,KAAK;AACP,mBAAK,IAAI,IAAI,GAAG;AAChB,0BAAY,QAAQ,IAAI,EAAE;AAC1B;AAAA,YACF;AAEA,gBAAI,CAAC,YAAY,IAAI,SAAS,QAAQ,EAAE,GAAG,UAAU,EAAE,EAAG,aAAY,QAAQ,IAAI,EAAE;AAAA,UACtF;AACA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH,UAAE;AACA,aAAK,QAAQ,CAAC,OAAO,YAAY,QAAQ,OAAO,EAAE,CAAC;AAAA,MACrD;AAAA,IACF;AAAA,IACA,CAAC,MAAM,WAAW;AAAA,EACpB;AAGA,YAAU,MAAM;AACd,QAAI,WAAW,SAAS,EAAG,MAAK,aAAa,UAAU;AAAA,EAEzD,GAAG,CAAC,QAAQ,YAAY,CAAC;AAGzB,YAAU,MAAM;AACd,eAAW,MAAM;AACf,UAAI,YAAY,IAAI,MAAM,EAAE,GAAG,UAAU,EAAE,EAAG,aAAY,QAAQ,OAAO,EAAE;AAC7E,UAAM,QAAQ,WAAW;AAAA,MACvB,CAAC,OACC,CAAC,YAAY,QAAQ,IAAI,EAAE,KAAK,2BAA2B,IAAI,MAAM,EAAE,GAAG,UAAU,EAAE;AAAA,IAC1F;AACA,QAAI,MAAM,SAAS,EAAG,MAAK,aAAa,KAAK;AAAA,EAE/C,GAAG,CAAC,OAAO,QAAQ,YAAY,CAAC;AAEhC,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { useCallback, useState } from "react";
|
|
2
|
+
import { useArbi } from "../useArbi.js";
|
|
3
|
+
import { notify } from "../notifications/notify-store.js";
|
|
4
|
+
import { downloadBlob } from "../document-tools/environment.js";
|
|
5
|
+
import { fetchDocumentFile } from "../document-tools/document-pdf.js";
|
|
6
|
+
import { getDocumentTitle } from "../entities/DocumentEntity.js";
|
|
7
|
+
import { archiveName, buildDocumentMetadataRows, fallbackFileName } from "./document-download.js";
|
|
8
|
+
function useDownloadDocuments({ workspaceName } = {}) {
|
|
9
|
+
const arbi = useArbi();
|
|
10
|
+
const [isDownloading, setIsDownloading] = useState(false);
|
|
11
|
+
const fetchNamedFile = useCallback(
|
|
12
|
+
async (doc) => {
|
|
13
|
+
const blob = await fetchDocumentFile(arbi.getClient().fetch, doc.external_id);
|
|
14
|
+
return { blob, name: blob instanceof File && blob.name ? blob.name : fallbackFileName(doc) };
|
|
15
|
+
},
|
|
16
|
+
[arbi]
|
|
17
|
+
);
|
|
18
|
+
const downloadDocuments = useCallback(
|
|
19
|
+
// selectedColumns: undefined = all default columns; [] = files only (no index.csv)
|
|
20
|
+
async (documents, selectedColumns) => {
|
|
21
|
+
const includeMetadataCsv = selectedColumns === void 0 || selectedColumns.length > 0;
|
|
22
|
+
if (documents.length === 0) {
|
|
23
|
+
notify.error("No documents to download");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
setIsDownloading(true);
|
|
27
|
+
try {
|
|
28
|
+
const JSZip = (await import("jszip")).default;
|
|
29
|
+
const zip = new JSZip();
|
|
30
|
+
const downloaded = [];
|
|
31
|
+
const failedDocs = [];
|
|
32
|
+
for (const doc of documents) {
|
|
33
|
+
try {
|
|
34
|
+
const file = await fetchNamedFile(doc);
|
|
35
|
+
zip.file(file.name, file.blob);
|
|
36
|
+
downloaded.push(doc);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error(`Failed to download document ${doc.external_id}:`, error);
|
|
39
|
+
failedDocs.push(getDocumentTitle(doc, doc.external_id));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const successCount = downloaded.length;
|
|
43
|
+
if (successCount === 0) {
|
|
44
|
+
notify.error("Failed to download documents");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (includeMetadataCsv) {
|
|
48
|
+
const Papa = (await import("papaparse")).default;
|
|
49
|
+
zip.file(
|
|
50
|
+
"index.csv",
|
|
51
|
+
Papa.unparse(buildDocumentMetadataRows(downloaded, selectedColumns))
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
const zipFileName = archiveName(workspaceName, `${successCount}_documents`);
|
|
55
|
+
downloadBlob(await zip.generateAsync({ type: "blob" }), zipFileName);
|
|
56
|
+
const documentsLabel = `${successCount} document${successCount !== 1 ? "s" : ""}`;
|
|
57
|
+
const contents = includeMetadataCsv ? `${documentsLabel} and index.csv in ${zipFileName}` : `${documentsLabel} in ${zipFileName}`;
|
|
58
|
+
if (failedDocs.length === 0) notify.success(`Successfully downloaded ${contents}`);
|
|
59
|
+
else notify.warning(`Downloaded ${contents}, ${failedDocs.length} failed`);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.error("Failed to create zip file:", error);
|
|
62
|
+
notify.error("Failed to download documents. Please try again.");
|
|
63
|
+
} finally {
|
|
64
|
+
setIsDownloading(false);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
[workspaceName, fetchNamedFile]
|
|
68
|
+
);
|
|
69
|
+
const downloadDocument = useCallback(
|
|
70
|
+
async (doc) => {
|
|
71
|
+
setIsDownloading(true);
|
|
72
|
+
try {
|
|
73
|
+
const file = await fetchNamedFile(doc);
|
|
74
|
+
downloadBlob(file.blob, file.name);
|
|
75
|
+
notify.success(`Successfully downloaded ${file.name}`);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error("Failed to download document", error);
|
|
78
|
+
notify.error("Failed to download document. Please try again.");
|
|
79
|
+
} finally {
|
|
80
|
+
setIsDownloading(false);
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
[fetchNamedFile]
|
|
84
|
+
);
|
|
85
|
+
return { downloadDocuments, downloadDocument, isDownloading };
|
|
86
|
+
}
|
|
87
|
+
export {
|
|
88
|
+
useDownloadDocuments
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=useDownloadDocuments.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/documents/useDownloadDocuments.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Downloading documents: one file as stored, or several as a ZIP (the files, plus an `index.csv`\n * of their metadata unless asked for files only). Used by the explorer (a file, a folder) and the\n * documents table. Progress and outcome are told through `notify`.\n */\n\nimport { useCallback, useState } from 'react'\nimport { useArbi } from '../useArbi'\nimport { notify } from '../notifications/notify-store'\nimport { downloadBlob } from '../document-tools/environment'\nimport { fetchDocumentFile } from '../document-tools/document-pdf'\nimport { getDocumentTitle } from '../entities/DocumentEntity'\nimport type { WorkspaceDocument } from './documents-cache'\nimport { archiveName, buildDocumentMetadataRows, fallbackFileName } from './document-download'\n\nexport interface UseDownloadDocumentsOptions {\n /** Names the ZIP. */\n workspaceName?: string\n}\n\nexport function useDownloadDocuments({ workspaceName }: UseDownloadDocumentsOptions = {}) {\n const arbi = useArbi()\n const [isDownloading, setIsDownloading] = useState(false)\n\n /** The stored file of a document and the name to save it under (the server's, else ours). */\n const fetchNamedFile = useCallback(\n async (doc: WorkspaceDocument): Promise<{ blob: Blob; name: string }> => {\n const blob = await fetchDocumentFile(arbi.getClient().fetch, doc.external_id)\n return { blob, name: blob instanceof File && blob.name ? blob.name : fallbackFileName(doc) }\n },\n [arbi]\n )\n\n // Stable, so a caller can depend on it (the table's columns) without rebuilding every render.\n const downloadDocuments = useCallback(\n // selectedColumns: undefined = all default columns; [] = files only (no index.csv)\n async (documents: WorkspaceDocument[], selectedColumns?: string[]) => {\n const includeMetadataCsv = selectedColumns === undefined || selectedColumns.length > 0\n if (documents.length === 0) {\n notify.error('No documents to download')\n return\n }\n setIsDownloading(true)\n try {\n const JSZip = (await import('jszip')).default\n const zip = new JSZip()\n const downloaded: WorkspaceDocument[] = []\n const failedDocs: string[] = []\n for (const doc of documents) {\n try {\n const file = await fetchNamedFile(doc)\n zip.file(file.name, file.blob)\n downloaded.push(doc)\n } catch (error) {\n console.error(`Failed to download document ${doc.external_id}:`, error)\n failedDocs.push(getDocumentTitle(doc, doc.external_id))\n }\n }\n const successCount = downloaded.length\n if (successCount === 0) {\n notify.error('Failed to download documents')\n return\n }\n if (includeMetadataCsv) {\n const Papa = (await import('papaparse')).default\n zip.file(\n 'index.csv',\n Papa.unparse(buildDocumentMetadataRows(downloaded, selectedColumns))\n )\n }\n const zipFileName = archiveName(workspaceName, `${successCount}_documents`)\n downloadBlob(await zip.generateAsync({ type: 'blob' }), zipFileName)\n // Name the ZIP and, when written, the metadata CSV so the user knows where to find them.\n const documentsLabel = `${successCount} document${successCount !== 1 ? 's' : ''}`\n const contents = includeMetadataCsv\n ? `${documentsLabel} and index.csv in ${zipFileName}`\n : `${documentsLabel} in ${zipFileName}`\n if (failedDocs.length === 0) notify.success(`Successfully downloaded ${contents}`)\n else notify.warning(`Downloaded ${contents}, ${failedDocs.length} failed`)\n } catch (error) {\n console.error('Failed to create zip file:', error)\n notify.error('Failed to download documents. Please try again.')\n } finally {\n setIsDownloading(false)\n }\n },\n [workspaceName, fetchNamedFile]\n )\n\n // A single file (a card's or a row's Download) is saved as-is, not wrapped in a ZIP.\n const downloadDocument = useCallback(\n async (doc: WorkspaceDocument) => {\n setIsDownloading(true)\n try {\n const file = await fetchNamedFile(doc)\n downloadBlob(file.blob, file.name)\n notify.success(`Successfully downloaded ${file.name}`)\n } catch (error) {\n console.error('Failed to download document', error)\n notify.error('Failed to download document. Please try again.')\n } finally {\n setIsDownloading(false)\n }\n },\n [fetchNamedFile]\n )\n\n return { downloadDocuments, downloadDocument, isDownloading }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { useQueries } from "@tanstack/react-query";
|
|
3
|
+
import { useArbi } from "../useArbi.js";
|
|
4
|
+
import { arbiQueryKeys } from "../hooks.js";
|
|
5
|
+
const PARSED_STALE_TIME = 5 * 60 * 1e3;
|
|
6
|
+
function indexPassages(results) {
|
|
7
|
+
const index = /* @__PURE__ */ new Map();
|
|
8
|
+
for (const r of results)
|
|
9
|
+
(r.data?.chunks ?? []).forEach((chunk, order) => {
|
|
10
|
+
const id = chunk.metadata?.chunk_ext_id;
|
|
11
|
+
if (id && !index.has(id)) index.set(id, { text: (chunk.content ?? "").trim(), order });
|
|
12
|
+
});
|
|
13
|
+
return index;
|
|
14
|
+
}
|
|
15
|
+
function usePassageQuotes(docIds) {
|
|
16
|
+
const arbi = useArbi();
|
|
17
|
+
const passages = useQueries({
|
|
18
|
+
queries: [...new Set(docIds ?? [])].map((docId) => ({
|
|
19
|
+
queryKey: arbiQueryKeys.parsedDoc(docId, "final"),
|
|
20
|
+
queryFn: () => arbi.documents.getParsedContent(docId, "final"),
|
|
21
|
+
enabled: arbi.hasWorkspace,
|
|
22
|
+
staleTime: PARSED_STALE_TIME
|
|
23
|
+
})),
|
|
24
|
+
combine: indexPassages
|
|
25
|
+
});
|
|
26
|
+
return useMemo(
|
|
27
|
+
() => ({
|
|
28
|
+
quoteFor: (chunkId) => passages.get(chunkId)?.text || void 0,
|
|
29
|
+
orderOf: (chunkId) => passages.get(chunkId)?.order ?? Number.POSITIVE_INFINITY
|
|
30
|
+
}),
|
|
31
|
+
[passages]
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
usePassageQuotes
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=usePassageQuotes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/documents/usePassageQuotes.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Cited passages' text, read live from their documents. A citation stores only chunk ids (plus the\n * document and page); the passage text stays encrypted in the document, so an excerpt is read on\n * demand from the document's parsed content \u2014 the same `final` stage the viewer renders and\n * highlights from, cached with it (`useParsedDocument`), one read per distinct document.\n */\n\nimport { useMemo } from 'react'\nimport { useQueries } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\nimport type { ParsedDocument } from './parsed-types'\n\n/** A passage's excerpt (raw markdown) by its chunk id; undefined while loading or unknown. */\nexport type QuoteResolver = (chunkId: string) => string | undefined\n\n/** A passage's 0-based position in its document (`Infinity` while loading or unknown). */\nexport type OrderResolver = (chunkId: string) => number\n\nexport interface PassageResolvers {\n quoteFor: QuoteResolver\n orderOf: OrderResolver\n}\n\n/** The parsed document lasts until it is re-ingested: keep it while several citations open. */\nconst PARSED_STALE_TIME = 5 * 60 * 1000\n\n/** Every passage of the read documents by chunk id: its text and its place in its document. */\ntype PassageIndex = Map<string, { text: string; order: number }>\n\n/** One index over the documents' parsed content (newlines kept, uncapped: it renders as markdown). */\nfunction indexPassages(results: ReadonlyArray<{ data?: ParsedDocument }>): PassageIndex {\n const index: PassageIndex = new Map()\n for (const r of results)\n (r.data?.chunks ?? []).forEach((chunk, order) => {\n const id = chunk.metadata?.chunk_ext_id\n if (id && !index.has(id)) index.set(id, { text: (chunk.content ?? '').trim(), order })\n })\n return index\n}\n\n/**\n * Resolve the passages of these documents (`null`: none yet \u2014 e.g. until a list is opened, so a\n * closed popover reads nothing).\n */\nexport function usePassageQuotes(docIds: readonly string[] | null | undefined): PassageResolvers {\n const arbi = useArbi()\n const passages = useQueries({\n queries: [...new Set(docIds ?? [])].map((docId) => ({\n queryKey: arbiQueryKeys.parsedDoc(docId, 'final'),\n queryFn: () =>\n arbi.documents.getParsedContent(docId, 'final') as unknown as Promise<ParsedDocument>,\n enabled: arbi.hasWorkspace,\n staleTime: PARSED_STALE_TIME,\n })),\n combine: indexPassages,\n })\n return useMemo(\n () => ({\n quoteFor: (chunkId: string) => passages.get(chunkId)?.text || undefined,\n orderOf: (chunkId: string) => passages.get(chunkId)?.order ?? Number.POSITIVE_INFINITY,\n }),\n [passages]\n )\n}\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,eAAe;AACxB,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAe9B,MAAM,oBAAoB,IAAI,KAAK;AAMnC,SAAS,cAAc,SAAiE;AACtF,QAAM,QAAsB,oBAAI,IAAI;AACpC,aAAW,KAAK;AACd,KAAC,EAAE,MAAM,UAAU,CAAC,GAAG,QAAQ,CAAC,OAAO,UAAU;AAC/C,YAAM,KAAK,MAAM,UAAU;AAC3B,UAAI,MAAM,CAAC,MAAM,IAAI,EAAE,EAAG,OAAM,IAAI,IAAI,EAAE,OAAO,MAAM,WAAW,IAAI,KAAK,GAAG,MAAM,CAAC;AAAA,IACvF,CAAC;AACH,SAAO;AACT;AAMO,SAAS,iBAAiB,QAAgE;AAC/F,QAAM,OAAO,QAAQ;AACrB,QAAM,WAAW,WAAW;AAAA,IAC1B,SAAS,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW;AAAA,MAClD,UAAU,cAAc,UAAU,OAAO,OAAO;AAAA,MAChD,SAAS,MACP,KAAK,UAAU,iBAAiB,OAAO,OAAO;AAAA,MAChD,SAAS,KAAK;AAAA,MACd,WAAW;AAAA,IACb,EAAE;AAAA,IACF,SAAS;AAAA,EACX,CAAC;AACD,SAAO;AAAA,IACL,OAAO;AAAA,MACL,UAAU,CAAC,YAAoB,SAAS,IAAI,OAAO,GAAG,QAAQ;AAAA,MAC9D,SAAS,CAAC,YAAoB,SAAS,IAAI,OAAO,GAAG,SAAS,OAAO;AAAA,IACvE;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
3
|
+
import { documents as documentOps } from "@arbidocs/sdk/browser";
|
|
4
|
+
import { useArbi } from "../useArbi.js";
|
|
5
|
+
import { arbiQueryKeys } from "../hooks.js";
|
|
6
|
+
import { useUserSettings } from "../account/settings.js";
|
|
7
|
+
import { patchDocuments } from "./documents-cache.js";
|
|
8
|
+
import { refreshDocuments } from "./documents-data.js";
|
|
9
|
+
import { useGenerateDocTags } from "./documents-writes.js";
|
|
10
|
+
import { useDocumentsSupport } from "./support.js";
|
|
11
|
+
import { uploadFolderOf } from "./upload-files.js";
|
|
12
|
+
const { mimeFromName } = documentOps;
|
|
13
|
+
const BATCH_SIZE = 100;
|
|
14
|
+
const CONCURRENT_BATCHES = 4;
|
|
15
|
+
const uploadedFolders = /* @__PURE__ */ new Map();
|
|
16
|
+
function uploadedDocumentFolder(workspaceId, docId) {
|
|
17
|
+
const pending = uploadedFolders.get(docId);
|
|
18
|
+
return pending?.workspaceId === workspaceId ? pending.folder : void 0;
|
|
19
|
+
}
|
|
20
|
+
function forgetUploadedDocumentFolder(docId) {
|
|
21
|
+
uploadedFolders.delete(docId);
|
|
22
|
+
}
|
|
23
|
+
async function runLimited(tasks, limit) {
|
|
24
|
+
const results = new Array(tasks.length);
|
|
25
|
+
let next = 0;
|
|
26
|
+
const worker = async () => {
|
|
27
|
+
while (next < tasks.length) {
|
|
28
|
+
const index = next++;
|
|
29
|
+
results[index] = await tasks[index]();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
await Promise.all(Array.from({ length: Math.min(limit, tasks.length) }, worker));
|
|
33
|
+
return results;
|
|
34
|
+
}
|
|
35
|
+
function useUploadFiles() {
|
|
36
|
+
const arbi = useArbi();
|
|
37
|
+
const qc = useQueryClient();
|
|
38
|
+
const { resolveWorkspaceKey } = useDocumentsSupport();
|
|
39
|
+
const { data: settings } = useUserSettings();
|
|
40
|
+
const { mutateAsync: generateDocTags } = useGenerateDocTags();
|
|
41
|
+
const direct = settings?.use_s3_direct_upload === true;
|
|
42
|
+
return useCallback(
|
|
43
|
+
async (input, onProgress) => {
|
|
44
|
+
const workspaceId = input.workspaceExtId ?? arbi.getWorkspaceId();
|
|
45
|
+
const groups = /* @__PURE__ */ new Map();
|
|
46
|
+
for (const file of input.files) {
|
|
47
|
+
const folder = uploadFolderOf(file, input.folder);
|
|
48
|
+
groups.set(folder, [...groups.get(folder) ?? [], file]);
|
|
49
|
+
}
|
|
50
|
+
const batches = [];
|
|
51
|
+
for (const [folder, files] of groups)
|
|
52
|
+
for (let i = 0; i < files.length; i += BATCH_SIZE)
|
|
53
|
+
batches.push({ folder, files: files.slice(i, i + BATCH_SIZE) });
|
|
54
|
+
let workspaceKey = null;
|
|
55
|
+
if (direct && workspaceId && resolveWorkspaceKey) {
|
|
56
|
+
try {
|
|
57
|
+
workspaceKey = await resolveWorkspaceKey(workspaceId);
|
|
58
|
+
} catch {
|
|
59
|
+
workspaceKey = null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const total = input.files.reduce((sum, file) => sum + file.size, 0);
|
|
63
|
+
const loadedByBatch = new Array(batches.length).fill(0);
|
|
64
|
+
const filesByBatch = new Array(batches.length).fill(0);
|
|
65
|
+
let done = 0;
|
|
66
|
+
let highest = 0;
|
|
67
|
+
const report = () => {
|
|
68
|
+
const loaded = loadedByBatch.reduce((sum, bytes) => sum + bytes, 0);
|
|
69
|
+
const sent = filesByBatch.reduce((sum, files) => sum + files, 0);
|
|
70
|
+
const share = input.files.length > 0 ? sent / input.files.length : 0;
|
|
71
|
+
highest = Math.max(highest, Math.min(Math.round(share * 100), 100));
|
|
72
|
+
onProgress?.({
|
|
73
|
+
loaded,
|
|
74
|
+
total,
|
|
75
|
+
percentage: highest,
|
|
76
|
+
batches: batches.length > 1 ? { current: done, total: batches.length } : null
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
report();
|
|
80
|
+
const results = await runLimited(
|
|
81
|
+
batches.map(({ folder, files }, index) => async () => {
|
|
82
|
+
const bytes = files.reduce((sum, file) => sum + file.size, 0);
|
|
83
|
+
const throughServer = () => arbi.documents.upload(files, {
|
|
84
|
+
shared: input.shared,
|
|
85
|
+
folder: folder ?? void 0,
|
|
86
|
+
configExtId: input.configExtId ?? void 0,
|
|
87
|
+
// Named even when it is the open one: batches sent after a switch stay in this workspace.
|
|
88
|
+
workspaceExtId: workspaceId,
|
|
89
|
+
// One request for the batch: its files count by the share of its bytes sent.
|
|
90
|
+
onProgress: (loaded) => {
|
|
91
|
+
loadedByBatch[index] = Math.min(loaded, bytes);
|
|
92
|
+
filesByBatch[index] = bytes > 0 ? loadedByBatch[index] / bytes * files.length : 0;
|
|
93
|
+
report();
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
const fileShares = new Array(files.length).fill(0);
|
|
97
|
+
const directly = async (key, workspace) => arbi.documents.uploadDirect(
|
|
98
|
+
workspace,
|
|
99
|
+
key,
|
|
100
|
+
await Promise.all(
|
|
101
|
+
files.map(async (file) => ({
|
|
102
|
+
name: file.name,
|
|
103
|
+
data: new Uint8Array(await file.arrayBuffer()),
|
|
104
|
+
contentType: file.type || mimeFromName(file.name)
|
|
105
|
+
}))
|
|
106
|
+
),
|
|
107
|
+
{
|
|
108
|
+
shared: input.shared,
|
|
109
|
+
folder: folder ?? void 0,
|
|
110
|
+
configExtId: input.configExtId ?? void 0,
|
|
111
|
+
// Per file, in ciphertext bytes: that file's share sent, scaled back to its own
|
|
112
|
+
// size so the byte total stays true.
|
|
113
|
+
onBytesProgress: ({ fileIndex, loaded, total: sent }) => {
|
|
114
|
+
const share = sent > 0 ? Math.min(loaded / sent, 1) : 0;
|
|
115
|
+
fileShares[fileIndex] = Math.max(fileShares[fileIndex] ?? 0, share);
|
|
116
|
+
loadedByBatch[index] = Math.round(
|
|
117
|
+
files.reduce((sum, file, i) => sum + (fileShares[i] ?? 0) * file.size, 0)
|
|
118
|
+
);
|
|
119
|
+
filesByBatch[index] = fileShares.reduce((sum, part) => sum + part, 0);
|
|
120
|
+
report();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
const result = workspaceKey && workspaceId ? await directly(workspaceKey, workspaceId) : await throughServer();
|
|
125
|
+
const docIds2 = result.doc_ext_ids ?? [];
|
|
126
|
+
if (docIds2.length > 0) {
|
|
127
|
+
for (const docId of docIds2) uploadedFolders.set(docId, { workspaceId, folder });
|
|
128
|
+
const made = new Set(docIds2);
|
|
129
|
+
patchDocuments(
|
|
130
|
+
qc,
|
|
131
|
+
(rows) => rows.map((doc) => made.has(doc.external_id) ? { ...doc, folder } : doc),
|
|
132
|
+
workspaceId
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
loadedByBatch[index] = bytes;
|
|
136
|
+
filesByBatch[index] = files.length;
|
|
137
|
+
done += 1;
|
|
138
|
+
report();
|
|
139
|
+
return result;
|
|
140
|
+
}),
|
|
141
|
+
CONCURRENT_BATCHES
|
|
142
|
+
);
|
|
143
|
+
const docIds = results.flatMap((result) => result.doc_ext_ids ?? []);
|
|
144
|
+
const skipped = results.flatMap((result) => result.skipped ?? []);
|
|
145
|
+
if (docIds.length > 0) {
|
|
146
|
+
const read = await refreshDocuments(qc, arbi, docIds);
|
|
147
|
+
for (const doc of read) forgetUploadedDocumentFolder(doc.external_id);
|
|
148
|
+
}
|
|
149
|
+
await qc.invalidateQueries({ queryKey: arbiQueryKeys.workspaces() });
|
|
150
|
+
if (docIds.length > 0 && input.generateTagIds?.length) {
|
|
151
|
+
await generateDocTags({ tagIds: input.generateTagIds, docIds, overwrite: false }).catch(
|
|
152
|
+
() => void 0
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
return { docIds, skipped };
|
|
156
|
+
},
|
|
157
|
+
[arbi, qc, direct, resolveWorkspaceKey, generateDocTags]
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
export {
|
|
161
|
+
forgetUploadedDocumentFolder,
|
|
162
|
+
uploadedDocumentFolder,
|
|
163
|
+
useUploadFiles
|
|
164
|
+
};
|
|
165
|
+
//# sourceMappingURL=useUploadFiles.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/documents/useUploadFiles.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Upload chosen files to the open workspace, with progress. Files go in batches (one per folder\n * they land in, at most 100 files each, four at a time); each file keeps the folder it sat in below\n * where the upload started. With direct upload on in the user's settings, and the workspace key\n * held here, files are encrypted here and sent straight to storage; otherwise through the server.\n * The new documents join their list in their folder; the labels asked for fill their AI fields.\n */\n\nimport { useCallback } from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { documents as documentOps } from '@arbidocs/sdk/browser'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\nimport { useUserSettings } from '../account/settings'\nimport { patchDocuments } from './documents-cache'\nimport { refreshDocuments } from './documents-data'\nimport { useGenerateDocTags } from './documents-writes'\nimport { useDocumentsSupport } from './support'\nimport { uploadFolderOf } from './upload-files'\n\nconst { mimeFromName } = documentOps\n\nconst BATCH_SIZE = 100\nconst CONCURRENT_BATCHES = 4\n\nexport interface UploadFilesInput {\n files: File[]\n /** Upload to this member workspace instead of the currently open workspace. */\n workspaceExtId?: string\n /** Where the upload started (a folder path); null or absent: the workspace root. */\n folder?: string | null\n shared: boolean\n configExtId?: string | null\n /** Labels whose AI fields are filled on the new documents. */\n generateTagIds?: string[]\n}\n\nexport interface UploadFilesProgress {\n loaded: number\n total: number\n /** Share of the files sent (one on the wire counts by its bytes sent); it never goes back. */\n percentage: number\n /** Batches done of all, when there is more than one. */\n batches: { current: number; total: number } | null\n}\n\nexport interface UploadFilesResult {\n docIds: string[]\n /** Files the server did not take, and why. */\n skipped: { file_name: string; reason: string }[]\n}\n\ninterface PendingFolder {\n workspaceId: string\n folder: string | null\n}\n\n// The folder of each document an upload made, until its row is read: a row announced live before\n// that (processing started) is shown in it.\nconst uploadedFolders = new Map<string, PendingFolder>()\n\n/** The folder an upload put `docId` in, while its row has not been read yet. */\nexport function uploadedDocumentFolder(\n workspaceId: string,\n docId: string\n): string | null | undefined {\n const pending = uploadedFolders.get(docId)\n return pending?.workspaceId === workspaceId ? pending.folder : undefined\n}\n\n/** `docId`'s row was read: its folder is known. */\nexport function forgetUploadedDocumentFolder(docId: string): void {\n uploadedFolders.delete(docId)\n}\n\n/** Run `tasks` at most `limit` at a time; resolves with their results in order. */\nasync function runLimited<T>(tasks: Array<() => Promise<T>>, limit: number): Promise<T[]> {\n const results = new Array<T>(tasks.length)\n let next = 0\n const worker = async () => {\n while (next < tasks.length) {\n const index = next++\n results[index] = await tasks[index]()\n }\n }\n await Promise.all(Array.from({ length: Math.min(limit, tasks.length) }, worker))\n return results\n}\n\nexport function useUploadFiles() {\n const arbi = useArbi()\n const qc = useQueryClient()\n const { resolveWorkspaceKey } = useDocumentsSupport()\n const { data: settings } = useUserSettings()\n const { mutateAsync: generateDocTags } = useGenerateDocTags()\n const direct = settings?.use_s3_direct_upload === true\n\n return useCallback(\n async (\n input: UploadFilesInput,\n onProgress?: (progress: UploadFilesProgress) => void\n ): Promise<UploadFilesResult> => {\n const workspaceId = input.workspaceExtId ?? arbi.getWorkspaceId()\n const groups = new Map<string | null, File[]>()\n for (const file of input.files) {\n const folder = uploadFolderOf(file, input.folder)\n groups.set(folder, [...(groups.get(folder) ?? []), file])\n }\n const batches: { folder: string | null; files: File[] }[] = []\n for (const [folder, files] of groups)\n for (let i = 0; i < files.length; i += BATCH_SIZE)\n batches.push({ folder, files: files.slice(i, i + BATCH_SIZE) })\n\n // The direct upload needs the workspace key here; without it the server encrypts. The key and\n // the workspace its init and commit name are both this upload's `workspaceId`, captured now,\n // so a switch while it runs cannot move a batch (or encrypt one for another workspace).\n let workspaceKey: Uint8Array | null = null\n if (direct && workspaceId && resolveWorkspaceKey) {\n try {\n workspaceKey = await resolveWorkspaceKey(workspaceId)\n } catch {\n workspaceKey = null\n }\n }\n\n const total = input.files.reduce((sum, file) => sum + file.size, 0)\n // Per batch: the bytes sent, and how many of its files that is (a file part-sent counts by its\n // share of bytes). The bar follows the files, and with four batches on the wire it only grows.\n const loadedByBatch = new Array<number>(batches.length).fill(0)\n const filesByBatch = new Array<number>(batches.length).fill(0)\n let done = 0\n let highest = 0\n const report = () => {\n const loaded = loadedByBatch.reduce((sum, bytes) => sum + bytes, 0)\n const sent = filesByBatch.reduce((sum, files) => sum + files, 0)\n const share = input.files.length > 0 ? sent / input.files.length : 0\n highest = Math.max(highest, Math.min(Math.round(share * 100), 100))\n onProgress?.({\n loaded,\n total,\n percentage: highest,\n batches: batches.length > 1 ? { current: done, total: batches.length } : null,\n })\n }\n report()\n\n const results = await runLimited(\n batches.map(({ folder, files }, index) => async () => {\n const bytes = files.reduce((sum, file) => sum + file.size, 0)\n const throughServer = () =>\n arbi.documents.upload(files, {\n shared: input.shared,\n folder: folder ?? undefined,\n configExtId: input.configExtId ?? undefined,\n // Named even when it is the open one: batches sent after a switch stay in this workspace.\n workspaceExtId: workspaceId,\n // One request for the batch: its files count by the share of its bytes sent.\n onProgress: (loaded) => {\n loadedByBatch[index] = Math.min(loaded, bytes)\n filesByBatch[index] = bytes > 0 ? (loadedByBatch[index] / bytes) * files.length : 0\n report()\n },\n })\n // One PUT per file: how much of each has gone.\n const fileShares = new Array<number>(files.length).fill(0)\n const directly = async (key: Uint8Array, workspace: string) =>\n arbi.documents.uploadDirect(\n workspace,\n key,\n await Promise.all(\n files.map(async (file) => ({\n name: file.name,\n data: new Uint8Array(await file.arrayBuffer()),\n contentType: file.type || mimeFromName(file.name),\n }))\n ),\n {\n shared: input.shared,\n folder: folder ?? undefined,\n configExtId: input.configExtId ?? undefined,\n // Per file, in ciphertext bytes: that file's share sent, scaled back to its own\n // size so the byte total stays true.\n onBytesProgress: ({ fileIndex, loaded, total: sent }) => {\n const share = sent > 0 ? Math.min(loaded / sent, 1) : 0\n fileShares[fileIndex] = Math.max(fileShares[fileIndex] ?? 0, share)\n loadedByBatch[index] = Math.round(\n files.reduce((sum, file, i) => sum + (fileShares[i] ?? 0) * file.size, 0)\n )\n filesByBatch[index] = fileShares.reduce((sum, part) => sum + part, 0)\n report()\n },\n }\n )\n const result =\n workspaceKey && workspaceId\n ? await directly(workspaceKey, workspaceId)\n : await throughServer()\n const docIds = result.doc_ext_ids ?? []\n if (docIds.length > 0) {\n for (const docId of docIds) uploadedFolders.set(docId, { workspaceId, folder })\n const made = new Set(docIds)\n patchDocuments(\n qc,\n (rows) => rows.map((doc) => (made.has(doc.external_id) ? { ...doc, folder } : doc)),\n workspaceId\n )\n }\n loadedByBatch[index] = bytes\n filesByBatch[index] = files.length\n done += 1\n report()\n return result\n }),\n CONCURRENT_BATCHES\n )\n\n const docIds = results.flatMap((result) => result.doc_ext_ids ?? [])\n const skipped = results.flatMap((result) => result.skipped ?? [])\n if (docIds.length > 0) {\n const read = await refreshDocuments(qc, arbi, docIds)\n for (const doc of read) forgetUploadedDocumentFolder(doc.external_id)\n }\n await qc.invalidateQueries({ queryKey: arbiQueryKeys.workspaces() })\n if (docIds.length > 0 && input.generateTagIds?.length) {\n // The upload stands even when filling the AI fields could not start.\n await generateDocTags({ tagIds: input.generateTagIds, docIds, overwrite: false }).catch(\n () => undefined\n )\n }\n return { docIds, skipped }\n },\n [arbi, qc, direct, resolveWorkspaceKey, generateDocTags]\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["docIds"]
|
|
7
|
+
}
|