@semiont/react-ui 0.5.4 → 0.5.6
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/README.md +59 -55
- package/dist/{PdfAnnotationCanvas.client-CN3C3S55.js → PdfAnnotationCanvas.client-NIMALXNZ.js} +7 -27
- package/dist/PdfAnnotationCanvas.client-NIMALXNZ.js.map +1 -0
- package/dist/index.css +6 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +3704 -149
- package/dist/index.js +539 -405
- package/dist/index.js.map +1 -1
- package/dist/test-utils.d.ts +34 -16
- package/package.json +19 -13
- package/src/components/Button/__tests__/Button.test.tsx +0 -2
- package/src/components/CodeMirrorRenderer.tsx +2 -0
- package/src/components/ErrorBoundary.tsx +0 -9
- package/src/components/ProtectedErrorBoundary.tsx +6 -2
- package/src/components/__tests__/AnnotateReferencesProgressWidget.test.tsx +0 -1
- package/src/components/__tests__/ErrorBoundary.test.tsx +20 -13
- package/src/components/__tests__/LiveRegion.hooks.test.tsx +1 -1
- package/src/components/__tests__/ProtectedErrorBoundary.test.tsx +2 -1
- package/src/components/__tests__/ResizeHandle.test.tsx +0 -1
- package/src/components/__tests__/SessionExpiryBanner.test.tsx +0 -1
- package/src/components/__tests__/StatusDisplay.test.tsx +0 -1
- package/src/components/__tests__/Toast.test.tsx +2 -3
- package/src/components/__tests__/Toolbar.test.tsx +0 -1
- package/src/components/annotation/annotations.css +14 -0
- package/src/components/annotation-popups/__tests__/JsonLdView.test.tsx +3 -5
- package/src/components/annotation-popups/__tests__/SharedPopupElements.test.tsx +0 -1
- package/src/components/branding/__tests__/SemiontBranding.test.tsx +1 -2
- package/src/components/layout/__tests__/LeftSidebar.test.tsx +5 -6
- package/src/components/layout/__tests__/PageLayout.test.tsx +1 -3
- package/src/components/layout/__tests__/SkipLinks.a11y.test.tsx +8 -8
- package/src/components/layout/__tests__/UnifiedHeader.test.tsx +12 -1
- package/src/components/modals/__tests__/KeyboardShortcutsHelpModal.test.tsx +0 -1
- package/src/components/modals/__tests__/PermissionDeniedModal.test.tsx +3 -4
- package/src/components/modals/__tests__/ResourceSearchModal.test.tsx +0 -1
- package/src/components/modals/__tests__/SearchModal.basic.test.tsx +1 -1
- package/src/components/modals/__tests__/SearchModal.keyboard.test.tsx +0 -5
- package/src/components/modals/__tests__/SearchModal.search-wiring.test.tsx +0 -1
- package/src/components/modals/__tests__/SearchModal.visual.test.tsx +2 -2
- package/src/components/modals/__tests__/SessionExpiredModal.test.tsx +0 -1
- package/src/components/navigation/NavigationMenu.tsx +1 -1
- package/src/components/navigation/__tests__/Footer.a11y.test.tsx +4 -0
- package/src/components/navigation/__tests__/Footer.test.tsx +3 -6
- package/src/components/navigation/__tests__/NavigationMenu.a11y.test.tsx +1 -1
- package/src/components/navigation/__tests__/NavigationMenu.test.tsx +7 -9
- package/src/components/navigation/__tests__/ObservableLink.test.tsx +0 -1
- package/src/components/navigation/__tests__/SimpleNavigation.test.tsx +1 -2
- package/src/components/navigation/__tests__/SortableResourceTab.test.tsx +0 -1
- package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +6 -4
- package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +10 -19
- package/src/components/resource/__tests__/BrowseView.test.tsx +8 -6
- package/src/components/resource/__tests__/HistoryEvent.test.tsx +0 -4
- package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +4 -6
- package/src/components/resource/panels/ReferencesPanel.tsx +1 -1
- package/src/components/resource/panels/__tests__/AssessmentEntry.test.tsx +3 -4
- package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +7 -6
- package/src/components/resource/panels/__tests__/AssistSection.test.tsx +14 -10
- package/src/components/resource/panels/__tests__/CollaborationPanel.test.tsx +0 -1
- package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +30 -17
- package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +6 -5
- package/src/components/resource/panels/__tests__/HighlightEntry.test.tsx +4 -5
- package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +19 -13
- package/src/components/resource/panels/__tests__/JsonLdPanel.test.tsx +1 -3
- package/src/components/resource/panels/__tests__/PanelHeader.test.tsx +0 -1
- package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +5 -5
- package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +40 -7
- package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +3 -3
- package/src/components/resource/panels/__tests__/StatisticsPanel.test.tsx +30 -32
- package/src/components/resource/panels/__tests__/TagEntry.test.tsx +5 -5
- package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +6 -5
- package/src/components/settings/__tests__/SettingsPanel.test.tsx +0 -1
- package/src/components/viewers/__tests__/ImageViewer.test.tsx +0 -1
- package/src/features/auth/__tests__/SignInForm.a11y.test.tsx +2 -0
- package/src/features/auth/__tests__/SignUpForm.a11y.test.tsx +11 -12
- package/src/features/auth/__tests__/SignUpForm.test.tsx +3 -3
- package/src/features/moderate-tag-schemas/components/TagSchemasPage.tsx +1 -0
- package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +2 -1
- package/src/features/resource-discovery/__tests__/ResourceCard.test.tsx +0 -1
- package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +33 -35
- package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +12 -11
- package/src/features/resource-discovery/state/__tests__/discover-state-unit.test.ts +204 -11
- package/src/features/resource-discovery/state/discover-state-unit.ts +70 -11
- package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +2 -2
- package/src/features/resource-viewer/components/ResourceViewerPage.tsx +3 -2
- package/src/features/resource-viewer/state/__tests__/resource-viewer-page-state-unit.test.ts +0 -1
- package/src/features/resource-viewer/state/resource-viewer-page-state-unit.ts +5 -2
- package/src/integrations/__tests__/css-modules-helper.test.tsx +2 -3
- package/src/integrations/__tests__/styled-components-theme.test.ts +1 -3
- package/dist/PdfAnnotationCanvas.client-CN3C3S55.js.map +0 -1
- package/dist/assets/favicons/SemiontFavicon.d.ts +0 -9
- package/dist/assets/favicons/SemiontFavicon.d.ts.map +0 -1
- package/dist/assets/favicons/index.d.ts +0 -12
- package/dist/assets/favicons/index.d.ts.map +0 -1
- package/dist/components/AnnotateReferencesProgressWidget.d.ts +0 -15
- package/dist/components/AnnotateReferencesProgressWidget.d.ts.map +0 -1
- package/dist/components/Button/Button.d.ts +0 -69
- package/dist/components/Button/Button.d.ts.map +0 -1
- package/dist/components/CodeMirrorRenderer.d.ts +0 -25
- package/dist/components/CodeMirrorRenderer.d.ts.map +0 -1
- package/dist/components/ErrorBoundary.d.ts +0 -30
- package/dist/components/ErrorBoundary.d.ts.map +0 -1
- package/dist/components/LiveRegion.d.ts +0 -41
- package/dist/components/LiveRegion.d.ts.map +0 -1
- package/dist/components/ProtectedErrorBoundary.d.ts +0 -27
- package/dist/components/ProtectedErrorBoundary.d.ts.map +0 -1
- package/dist/components/ResizeHandle.d.ts +0 -39
- package/dist/components/ResizeHandle.d.ts.map +0 -1
- package/dist/components/ResourceTagsInline.d.ts +0 -10
- package/dist/components/ResourceTagsInline.d.ts.map +0 -1
- package/dist/components/SessionExpiryBanner.d.ts +0 -2
- package/dist/components/SessionExpiryBanner.d.ts.map +0 -1
- package/dist/components/SessionTimer.d.ts +0 -2
- package/dist/components/SessionTimer.d.ts.map +0 -1
- package/dist/components/StatusDisplay.d.ts +0 -9
- package/dist/components/StatusDisplay.d.ts.map +0 -1
- package/dist/components/Toast.d.ts +0 -27
- package/dist/components/Toast.d.ts.map +0 -1
- package/dist/components/Toolbar.d.ts +0 -15
- package/dist/components/Toolbar.d.ts.map +0 -1
- package/dist/components/UserMenuSkeleton.d.ts +0 -2
- package/dist/components/UserMenuSkeleton.d.ts.map +0 -1
- package/dist/components/annotation/AnnotateToolbar.d.ts +0 -29
- package/dist/components/annotation/AnnotateToolbar.d.ts.map +0 -1
- package/dist/components/annotation-popups/JsonLdView.d.ts +0 -8
- package/dist/components/annotation-popups/JsonLdView.d.ts.map +0 -1
- package/dist/components/annotation-popups/SharedPopupElements.d.ts +0 -28
- package/dist/components/annotation-popups/SharedPopupElements.d.ts.map +0 -1
- package/dist/components/branding/SemiontBranding.d.ts +0 -13
- package/dist/components/branding/SemiontBranding.d.ts.map +0 -1
- package/dist/components/error-states/ResourceErrorState.d.ts +0 -11
- package/dist/components/error-states/ResourceErrorState.d.ts.map +0 -1
- package/dist/components/image-annotation/AnnotationOverlay.d.ts +0 -22
- package/dist/components/image-annotation/AnnotationOverlay.d.ts.map +0 -1
- package/dist/components/image-annotation/SvgDrawingCanvas.d.ts +0 -23
- package/dist/components/image-annotation/SvgDrawingCanvas.d.ts.map +0 -1
- package/dist/components/layout/LeftSidebar.d.ts +0 -24
- package/dist/components/layout/LeftSidebar.d.ts.map +0 -1
- package/dist/components/layout/PageLayout.d.ts +0 -21
- package/dist/components/layout/PageLayout.d.ts.map +0 -1
- package/dist/components/layout/SkipLinks.d.ts +0 -8
- package/dist/components/layout/SkipLinks.d.ts.map +0 -1
- package/dist/components/layout/UnifiedHeader.d.ts +0 -21
- package/dist/components/layout/UnifiedHeader.d.ts.map +0 -1
- package/dist/components/loading-states/ComposeLoadingState.d.ts +0 -10
- package/dist/components/loading-states/ComposeLoadingState.d.ts.map +0 -1
- package/dist/components/loading-states/ResourceLoadingState.d.ts +0 -7
- package/dist/components/loading-states/ResourceLoadingState.d.ts.map +0 -1
- package/dist/components/modals/ConfigureGenerationStep.d.ts +0 -36
- package/dist/components/modals/ConfigureGenerationStep.d.ts.map +0 -1
- package/dist/components/modals/ConfigureSearchStep.d.ts +0 -21
- package/dist/components/modals/ConfigureSearchStep.d.ts.map +0 -1
- package/dist/components/modals/ContextSummary.d.ts +0 -14
- package/dist/components/modals/ContextSummary.d.ts.map +0 -1
- package/dist/components/modals/GatherContextStep.d.ts +0 -23
- package/dist/components/modals/GatherContextStep.d.ts.map +0 -1
- package/dist/components/modals/KeyboardShortcutsHelpModal.d.ts +0 -8
- package/dist/components/modals/KeyboardShortcutsHelpModal.d.ts.map +0 -1
- package/dist/components/modals/PermissionDeniedModal.d.ts +0 -12
- package/dist/components/modals/PermissionDeniedModal.d.ts.map +0 -1
- package/dist/components/modals/ReferenceWizardModal.d.ts +0 -64
- package/dist/components/modals/ReferenceWizardModal.d.ts.map +0 -1
- package/dist/components/modals/ResourceSearchModal.d.ts +0 -16
- package/dist/components/modals/ResourceSearchModal.d.ts.map +0 -1
- package/dist/components/modals/SearchModal.d.ts +0 -20
- package/dist/components/modals/SearchModal.d.ts.map +0 -1
- package/dist/components/modals/SearchResultsStep.d.ts +0 -22
- package/dist/components/modals/SearchResultsStep.d.ts.map +0 -1
- package/dist/components/modals/SessionExpiredModal.d.ts +0 -12
- package/dist/components/modals/SessionExpiredModal.d.ts.map +0 -1
- package/dist/components/navigation/CollapsibleResourceNavigation.d.ts +0 -13
- package/dist/components/navigation/CollapsibleResourceNavigation.d.ts.map +0 -1
- package/dist/components/navigation/Footer.d.ts +0 -20
- package/dist/components/navigation/Footer.d.ts.map +0 -1
- package/dist/components/navigation/NavigationMenu.d.ts +0 -18
- package/dist/components/navigation/NavigationMenu.d.ts.map +0 -1
- package/dist/components/navigation/ObservableLink.d.ts +0 -52
- package/dist/components/navigation/ObservableLink.d.ts.map +0 -1
- package/dist/components/navigation/SimpleNavigation.d.ts +0 -35
- package/dist/components/navigation/SimpleNavigation.d.ts.map +0 -1
- package/dist/components/navigation/SortableResourceTab.d.ts +0 -7
- package/dist/components/navigation/SortableResourceTab.d.ts.map +0 -1
- package/dist/components/pdf-annotation/PdfAnnotationCanvas.client.d.ts +0 -8
- package/dist/components/pdf-annotation/PdfAnnotationCanvas.client.d.ts.map +0 -1
- package/dist/components/pdf-annotation/PdfAnnotationCanvas.d.ts +0 -25
- package/dist/components/pdf-annotation/PdfAnnotationCanvas.d.ts.map +0 -1
- package/dist/components/resource/AnnotateView.d.ts +0 -29
- package/dist/components/resource/AnnotateView.d.ts.map +0 -1
- package/dist/components/resource/AnnotationHistory.d.ts +0 -14
- package/dist/components/resource/AnnotationHistory.d.ts.map +0 -1
- package/dist/components/resource/BrowseView.d.ts +0 -28
- package/dist/components/resource/BrowseView.d.ts.map +0 -1
- package/dist/components/resource/HistoryEvent.d.ts +0 -19
- package/dist/components/resource/HistoryEvent.d.ts.map +0 -1
- package/dist/components/resource/ResourceViewer.d.ts +0 -46
- package/dist/components/resource/ResourceViewer.d.ts.map +0 -1
- package/dist/components/resource/event-formatting.d.ts +0 -61
- package/dist/components/resource/event-formatting.d.ts.map +0 -1
- package/dist/components/resource/panels/AssessmentEntry.d.ts +0 -11
- package/dist/components/resource/panels/AssessmentEntry.d.ts.map +0 -1
- package/dist/components/resource/panels/AssessmentPanel.d.ts +0 -32
- package/dist/components/resource/panels/AssessmentPanel.d.ts.map +0 -1
- package/dist/components/resource/panels/AssistSection.d.ts +0 -27
- package/dist/components/resource/panels/AssistSection.d.ts.map +0 -1
- package/dist/components/resource/panels/CollaborationPanel.d.ts +0 -28
- package/dist/components/resource/panels/CollaborationPanel.d.ts.map +0 -1
- package/dist/components/resource/panels/CommentEntry.d.ts +0 -12
- package/dist/components/resource/panels/CommentEntry.d.ts.map +0 -1
- package/dist/components/resource/panels/CommentsPanel.d.ts +0 -32
- package/dist/components/resource/panels/CommentsPanel.d.ts.map +0 -1
- package/dist/components/resource/panels/HighlightEntry.d.ts +0 -11
- package/dist/components/resource/panels/HighlightEntry.d.ts.map +0 -1
- package/dist/components/resource/panels/HighlightPanel.d.ts +0 -30
- package/dist/components/resource/panels/HighlightPanel.d.ts.map +0 -1
- package/dist/components/resource/panels/JsonLdPanel.d.ts +0 -9
- package/dist/components/resource/panels/JsonLdPanel.d.ts.map +0 -1
- package/dist/components/resource/panels/PanelHeader.d.ts +0 -13
- package/dist/components/resource/panels/PanelHeader.d.ts.map +0 -1
- package/dist/components/resource/panels/ReferenceEntry.d.ts +0 -15
- package/dist/components/resource/panels/ReferenceEntry.d.ts.map +0 -1
- package/dist/components/resource/panels/ReferencesPanel.d.ts +0 -43
- package/dist/components/resource/panels/ReferencesPanel.d.ts.map +0 -1
- package/dist/components/resource/panels/ResourceInfoPanel.d.ts +0 -27
- package/dist/components/resource/panels/ResourceInfoPanel.d.ts.map +0 -1
- package/dist/components/resource/panels/StatisticsPanel.d.ts +0 -12
- package/dist/components/resource/panels/StatisticsPanel.d.ts.map +0 -1
- package/dist/components/resource/panels/TagEntry.d.ts +0 -11
- package/dist/components/resource/panels/TagEntry.d.ts.map +0 -1
- package/dist/components/resource/panels/TaggingPanel.d.ts +0 -34
- package/dist/components/resource/panels/TaggingPanel.d.ts.map +0 -1
- package/dist/components/resource/panels/UnifiedAnnotationsPanel.d.ts +0 -52
- package/dist/components/resource/panels/UnifiedAnnotationsPanel.d.ts.map +0 -1
- package/dist/components/resource/panels/agent-label.d.ts +0 -11
- package/dist/components/resource/panels/agent-label.d.ts.map +0 -1
- package/dist/components/settings/SettingsPanel.d.ts +0 -19
- package/dist/components/settings/SettingsPanel.d.ts.map +0 -1
- package/dist/components/viewers/ImageViewer.d.ts +0 -8
- package/dist/components/viewers/ImageViewer.d.ts.map +0 -1
- package/dist/components/viewers/index.d.ts +0 -2
- package/dist/components/viewers/index.d.ts.map +0 -1
- package/dist/contexts/AnnotationContext.d.ts +0 -46
- package/dist/contexts/AnnotationContext.d.ts.map +0 -1
- package/dist/contexts/ResourceAnnotationsContext.d.ts +0 -14
- package/dist/contexts/ResourceAnnotationsContext.d.ts.map +0 -1
- package/dist/contexts/RoutingContext.d.ts +0 -59
- package/dist/contexts/RoutingContext.d.ts.map +0 -1
- package/dist/contexts/ThemeContext.d.ts +0 -15
- package/dist/contexts/ThemeContext.d.ts.map +0 -1
- package/dist/contexts/TranslationContext.d.ts +0 -51
- package/dist/contexts/TranslationContext.d.ts.map +0 -1
- package/dist/contexts/useEventSubscription.d.ts +0 -41
- package/dist/contexts/useEventSubscription.d.ts.map +0 -1
- package/dist/design-tokens/index.d.ts +0 -178
- package/dist/design-tokens/index.d.ts.map +0 -1
- package/dist/features/admin-devops/components/AdminDevOpsPage.d.ts +0 -33
- package/dist/features/admin-devops/components/AdminDevOpsPage.d.ts.map +0 -1
- package/dist/features/admin-exchange/components/AdminExchangePage.d.ts +0 -37
- package/dist/features/admin-exchange/components/AdminExchangePage.d.ts.map +0 -1
- package/dist/features/admin-exchange/components/ExportCard.d.ts +0 -18
- package/dist/features/admin-exchange/components/ExportCard.d.ts.map +0 -1
- package/dist/features/admin-exchange/components/ImportCard.d.ts +0 -32
- package/dist/features/admin-exchange/components/ImportCard.d.ts.map +0 -1
- package/dist/features/admin-exchange/components/ImportProgress.d.ts +0 -26
- package/dist/features/admin-exchange/components/ImportProgress.d.ts.map +0 -1
- package/dist/features/admin-exchange/state/exchange-state-unit.d.ts +0 -31
- package/dist/features/admin-exchange/state/exchange-state-unit.d.ts.map +0 -1
- package/dist/features/admin-security/components/AdminSecurityPage.d.ts +0 -42
- package/dist/features/admin-security/components/AdminSecurityPage.d.ts.map +0 -1
- package/dist/features/admin-security/state/admin-security-state-unit.d.ts +0 -12
- package/dist/features/admin-security/state/admin-security-state-unit.d.ts.map +0 -1
- package/dist/features/admin-users/components/AdminUsersPage.d.ts +0 -88
- package/dist/features/admin-users/components/AdminUsersPage.d.ts.map +0 -1
- package/dist/features/admin-users/state/admin-users-state-unit.d.ts +0 -17
- package/dist/features/admin-users/state/admin-users-state-unit.d.ts.map +0 -1
- package/dist/features/auth/components/AuthErrorDisplay.d.ts +0 -34
- package/dist/features/auth/components/AuthErrorDisplay.d.ts.map +0 -1
- package/dist/features/auth/components/SignInForm.d.ts +0 -80
- package/dist/features/auth/components/SignInForm.d.ts.map +0 -1
- package/dist/features/auth/components/SignUpForm.d.ts +0 -39
- package/dist/features/auth/components/SignUpForm.d.ts.map +0 -1
- package/dist/features/auth-welcome/components/WelcomePage.d.ts +0 -62
- package/dist/features/auth-welcome/components/WelcomePage.d.ts.map +0 -1
- package/dist/features/auth-welcome/state/welcome-state-unit.d.ts +0 -12
- package/dist/features/auth-welcome/state/welcome-state-unit.d.ts.map +0 -1
- package/dist/features/moderate-entity-tags/components/EntityTagsPage.d.ts +0 -32
- package/dist/features/moderate-entity-tags/components/EntityTagsPage.d.ts.map +0 -1
- package/dist/features/moderate-entity-tags/state/entity-tags-state-unit.d.ts +0 -16
- package/dist/features/moderate-entity-tags/state/entity-tags-state-unit.d.ts.map +0 -1
- package/dist/features/moderate-recent/components/RecentDocumentsPage.d.ts +0 -27
- package/dist/features/moderate-recent/components/RecentDocumentsPage.d.ts.map +0 -1
- package/dist/features/moderate-tag-schemas/components/TagSchemasPage.d.ts +0 -25
- package/dist/features/moderate-tag-schemas/components/TagSchemasPage.d.ts.map +0 -1
- package/dist/features/moderation-linked-data/components/LinkedDataPage.d.ts +0 -38
- package/dist/features/moderation-linked-data/components/LinkedDataPage.d.ts.map +0 -1
- package/dist/features/resource-compose/components/ResourceComposePage.d.ts +0 -83
- package/dist/features/resource-compose/components/ResourceComposePage.d.ts.map +0 -1
- package/dist/features/resource-compose/components/UploadProgressBar.d.ts +0 -23
- package/dist/features/resource-compose/components/UploadProgressBar.d.ts.map +0 -1
- package/dist/features/resource-compose/state/compose-page-state-unit.d.ts +0 -59
- package/dist/features/resource-compose/state/compose-page-state-unit.d.ts.map +0 -1
- package/dist/features/resource-discovery/components/ResourceCard.d.ts +0 -17
- package/dist/features/resource-discovery/components/ResourceCard.d.ts.map +0 -1
- package/dist/features/resource-discovery/components/ResourceDiscoveryPage.d.ts +0 -43
- package/dist/features/resource-discovery/components/ResourceDiscoveryPage.d.ts.map +0 -1
- package/dist/features/resource-discovery/state/discover-state-unit.d.ts +0 -15
- package/dist/features/resource-discovery/state/discover-state-unit.d.ts.map +0 -1
- package/dist/features/resource-viewer/components/ResourceViewerPage.d.ts +0 -80
- package/dist/features/resource-viewer/components/ResourceViewerPage.d.ts.map +0 -1
- package/dist/features/resource-viewer/state/resource-loader-state-unit.d.ts +0 -11
- package/dist/features/resource-viewer/state/resource-loader-state-unit.d.ts.map +0 -1
- package/dist/features/resource-viewer/state/resource-viewer-page-state-unit.d.ts +0 -48
- package/dist/features/resource-viewer/state/resource-viewer-page-state-unit.d.ts.map +0 -1
- package/dist/hooks/useDebounce.d.ts +0 -29
- package/dist/hooks/useDebounce.d.ts.map +0 -1
- package/dist/hooks/useDragAnnouncements.d.ts +0 -12
- package/dist/hooks/useDragAnnouncements.d.ts.map +0 -1
- package/dist/hooks/useHoverDelay.d.ts +0 -8
- package/dist/hooks/useHoverDelay.d.ts.map +0 -1
- package/dist/hooks/useHoverEmitter.d.ts +0 -8
- package/dist/hooks/useHoverEmitter.d.ts.map +0 -1
- package/dist/hooks/useKeyboardShortcuts.d.ts +0 -29
- package/dist/hooks/useKeyboardShortcuts.d.ts.map +0 -1
- package/dist/hooks/useLineNumbers.d.ts +0 -8
- package/dist/hooks/useLineNumbers.d.ts.map +0 -1
- package/dist/hooks/useMediaToken.d.ts +0 -7
- package/dist/hooks/useMediaToken.d.ts.map +0 -1
- package/dist/hooks/useObservable.d.ts +0 -23
- package/dist/hooks/useObservable.d.ts.map +0 -1
- package/dist/hooks/useObservableBrowse.d.ts +0 -70
- package/dist/hooks/useObservableBrowse.d.ts.map +0 -1
- package/dist/hooks/usePanelWidth.d.ts +0 -37
- package/dist/hooks/usePanelWidth.d.ts.map +0 -1
- package/dist/hooks/useResourceContent.d.ts +0 -7
- package/dist/hooks/useResourceContent.d.ts.map +0 -1
- package/dist/hooks/useRovingTabIndex.d.ts +0 -13
- package/dist/hooks/useRovingTabIndex.d.ts.map +0 -1
- package/dist/hooks/useSearchAnnouncements.d.ts +0 -10
- package/dist/hooks/useSearchAnnouncements.d.ts.map +0 -1
- package/dist/hooks/useSessionExpiry.d.ts +0 -10
- package/dist/hooks/useSessionExpiry.d.ts.map +0 -1
- package/dist/hooks/useShellStateUnit.d.ts +0 -9
- package/dist/hooks/useShellStateUnit.d.ts.map +0 -1
- package/dist/hooks/useStateUnit.d.ts +0 -3
- package/dist/hooks/useStateUnit.d.ts.map +0 -1
- package/dist/hooks/useUI.d.ts +0 -24
- package/dist/hooks/useUI.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/integrations/css-modules-helper.d.ts +0 -114
- package/dist/integrations/css-modules-helper.d.ts.map +0 -1
- package/dist/integrations/styled-components-theme.d.ts +0 -95
- package/dist/integrations/styled-components-theme.d.ts.map +0 -1
- package/dist/integrations/tailwind-plugin.d.cts +0 -3
- package/dist/integrations/tailwind-plugin.d.cts.map +0 -1
- package/dist/lib/annotation-overlay.d.ts +0 -71
- package/dist/lib/annotation-overlay.d.ts.map +0 -1
- package/dist/lib/annotation-registry.d.ts +0 -62
- package/dist/lib/annotation-registry.d.ts.map +0 -1
- package/dist/lib/browser-pdfjs.d.ts +0 -93
- package/dist/lib/browser-pdfjs.d.ts.map +0 -1
- package/dist/lib/button-styles.d.ts +0 -27
- package/dist/lib/button-styles.d.ts.map +0 -1
- package/dist/lib/codemirror-handlers.d.ts +0 -52
- package/dist/lib/codemirror-handlers.d.ts.map +0 -1
- package/dist/lib/codemirror-json-theme.d.ts +0 -8
- package/dist/lib/codemirror-json-theme.d.ts.map +0 -1
- package/dist/lib/codemirror-logic.d.ts +0 -66
- package/dist/lib/codemirror-logic.d.ts.map +0 -1
- package/dist/lib/codemirror-widgets.d.ts +0 -39
- package/dist/lib/codemirror-widgets.d.ts.map +0 -1
- package/dist/lib/formatTime.d.ts +0 -2
- package/dist/lib/formatTime.d.ts.map +0 -1
- package/dist/lib/media-shapes.d.ts +0 -51
- package/dist/lib/media-shapes.d.ts.map +0 -1
- package/dist/lib/pdf-coordinates.d.ts +0 -69
- package/dist/lib/pdf-coordinates.d.ts.map +0 -1
- package/dist/lib/resource-utils.d.ts +0 -22
- package/dist/lib/resource-utils.d.ts.map +0 -1
- package/dist/lib/scroll-utils.d.ts +0 -20
- package/dist/lib/scroll-utils.d.ts.map +0 -1
- package/dist/lib/text-segmentation.d.ts +0 -25
- package/dist/lib/text-segmentation.d.ts.map +0 -1
- package/dist/lib/text-selection-handler.d.ts +0 -46
- package/dist/lib/text-selection-handler.d.ts.map +0 -1
- package/dist/lib/validation.d.ts +0 -47
- package/dist/lib/validation.d.ts.map +0 -1
- package/dist/session/SemiontProvider.d.ts +0 -28
- package/dist/session/SemiontProvider.d.ts.map +0 -1
- package/dist/session/web-browser-storage.d.ts +0 -19
- package/dist/session/web-browser-storage.d.ts.map +0 -1
- package/dist/state/session-state-unit.d.ts +0 -9
- package/dist/state/session-state-unit.d.ts.map +0 -1
- package/dist/state/shell-state-unit.d.ts +0 -33
- package/dist/state/shell-state-unit.d.ts.map +0 -1
- package/dist/test-utils.d.ts.map +0 -1
- package/dist/types/AnnotationManager.d.ts +0 -53
- package/dist/types/AnnotationManager.d.ts.map +0 -1
- package/dist/types/TranslationManager.d.ts +0 -15
- package/dist/types/TranslationManager.d.ts.map +0 -1
- package/dist/types/annotation-props.d.ts +0 -108
- package/dist/types/annotation-props.d.ts.map +0 -1
- package/dist/types/collapsible-navigation.d.ts +0 -69
- package/dist/types/collapsible-navigation.d.ts.map +0 -1
- package/dist/types/modals.d.ts +0 -77
- package/dist/types/modals.d.ts.map +0 -1
- package/dist/types/navigation.d.ts +0 -35
- package/dist/types/navigation.d.ts.map +0 -1
- package/dist/types/resource-viewer.d.ts +0 -19
- package/dist/types/resource-viewer.d.ts.map +0 -1
- package/dist/types/simple-navigation.d.ts +0 -15
- package/dist/types/simple-navigation.d.ts.map +0 -1
- package/dist/types/translation.d.ts +0 -5
- package/dist/types/translation.d.ts.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, vi } from 'vitest';
|
|
2
2
|
import { BehaviorSubject, firstValueFrom } from 'rxjs';
|
|
3
|
-
import { filter } from 'rxjs/operators';
|
|
3
|
+
import { filter, skip, take, toArray } from 'rxjs/operators';
|
|
4
4
|
import type { SemiontClient } from '@semiont/sdk';
|
|
5
5
|
import type { ShellStateUnit } from '../../../../state/shell-state-unit';
|
|
6
6
|
import { createDiscoverStateUnit } from '../discover-state-unit';
|
|
@@ -9,23 +9,43 @@ function mockBrowse(): ShellStateUnit {
|
|
|
9
9
|
return { dispose: vi.fn() } as unknown as ShellStateUnit;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
interface BrowseFilters {
|
|
13
|
+
limit?: number;
|
|
14
|
+
archived?: boolean;
|
|
15
|
+
search?: string;
|
|
16
|
+
entityType?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
12
19
|
function mockClient(overrides: {
|
|
13
20
|
resources$?: BehaviorSubject<unknown[] | undefined>;
|
|
14
21
|
entityTypes$?: BehaviorSubject<string[] | undefined>;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
22
|
+
resourcesFn?: (filters: BrowseFilters) => BehaviorSubject<unknown[] | undefined>;
|
|
23
|
+
} = {}): { client: SemiontClient; resourceCalls: BrowseFilters[] } {
|
|
24
|
+
const resourceCalls: BrowseFilters[] = [];
|
|
25
|
+
const defaultResources$ =
|
|
26
|
+
overrides.resources$ ?? new BehaviorSubject<unknown[] | undefined>([{ '@id': 'r1' }]);
|
|
27
|
+
const entityTypes$ =
|
|
28
|
+
overrides.entityTypes$ ?? new BehaviorSubject<string[] | undefined>(['Person']);
|
|
29
|
+
|
|
30
|
+
const resourcesFn = overrides.resourcesFn ?? (() => defaultResources$);
|
|
31
|
+
|
|
32
|
+
const client = {
|
|
19
33
|
browse: {
|
|
20
|
-
resources: () =>
|
|
34
|
+
resources: (filters: BrowseFilters = {}) => {
|
|
35
|
+
resourceCalls.push(filters);
|
|
36
|
+
return resourcesFn(filters).asObservable();
|
|
37
|
+
},
|
|
21
38
|
entityTypes: () => entityTypes$.asObservable(),
|
|
22
39
|
},
|
|
23
40
|
} as unknown as SemiontClient;
|
|
41
|
+
|
|
42
|
+
return { client, resourceCalls };
|
|
24
43
|
}
|
|
25
44
|
|
|
26
45
|
describe('createDiscoverStateUnit', () => {
|
|
27
46
|
it('exposes recent resources from browse namespace', async () => {
|
|
28
|
-
const
|
|
47
|
+
const { client } = mockClient();
|
|
48
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
29
49
|
|
|
30
50
|
const recent = await firstValueFrom(stateUnit.recentResources$);
|
|
31
51
|
expect(recent).toEqual([{ '@id': 'r1' }]);
|
|
@@ -34,7 +54,8 @@ describe('createDiscoverStateUnit', () => {
|
|
|
34
54
|
});
|
|
35
55
|
|
|
36
56
|
it('exposes entity types from browse namespace', async () => {
|
|
37
|
-
const
|
|
57
|
+
const { client } = mockClient();
|
|
58
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
38
59
|
|
|
39
60
|
const types = await firstValueFrom(stateUnit.entityTypes$);
|
|
40
61
|
expect(types).toEqual(['Person']);
|
|
@@ -42,9 +63,21 @@ describe('createDiscoverStateUnit', () => {
|
|
|
42
63
|
stateUnit.dispose();
|
|
43
64
|
});
|
|
44
65
|
|
|
66
|
+
it('falls back to [] when entityTypes() emits undefined', async () => {
|
|
67
|
+
const entityTypes$ = new BehaviorSubject<string[] | undefined>(undefined);
|
|
68
|
+
const { client } = mockClient({ entityTypes$ });
|
|
69
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
70
|
+
|
|
71
|
+
const types = await firstValueFrom(stateUnit.entityTypes$);
|
|
72
|
+
expect(types).toEqual([]);
|
|
73
|
+
|
|
74
|
+
stateUnit.dispose();
|
|
75
|
+
});
|
|
76
|
+
|
|
45
77
|
it('reports loading when resources are undefined', async () => {
|
|
46
78
|
const resources$ = new BehaviorSubject<unknown[] | undefined>(undefined);
|
|
47
|
-
const
|
|
79
|
+
const { client } = mockClient({ resources$ });
|
|
80
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
48
81
|
|
|
49
82
|
const loading = await firstValueFrom(stateUnit.isLoadingRecent$);
|
|
50
83
|
expect(loading).toBe(true);
|
|
@@ -57,7 +90,8 @@ describe('createDiscoverStateUnit', () => {
|
|
|
57
90
|
});
|
|
58
91
|
|
|
59
92
|
it('exposes a search pipeline', () => {
|
|
60
|
-
const
|
|
93
|
+
const { client } = mockClient();
|
|
94
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
61
95
|
|
|
62
96
|
expect(stateUnit.search).toBeDefined();
|
|
63
97
|
expect(typeof stateUnit.search.setQuery).toBe('function');
|
|
@@ -68,9 +102,168 @@ describe('createDiscoverStateUnit', () => {
|
|
|
68
102
|
|
|
69
103
|
it('disposes browse and search on dispose', () => {
|
|
70
104
|
const browse = mockBrowse();
|
|
71
|
-
const
|
|
105
|
+
const { client } = mockClient();
|
|
106
|
+
const stateUnit = createDiscoverStateUnit(client, browse);
|
|
72
107
|
stateUnit.dispose();
|
|
73
108
|
|
|
74
109
|
expect(browse.dispose).toHaveBeenCalled();
|
|
75
110
|
});
|
|
111
|
+
|
|
112
|
+
it('initial selectedEntityType$ is empty and recent fetch carries no entityType', async () => {
|
|
113
|
+
const { client, resourceCalls } = mockClient();
|
|
114
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
115
|
+
|
|
116
|
+
await firstValueFrom(stateUnit.recentResources$);
|
|
117
|
+
|
|
118
|
+
expect(resourceCalls).toHaveLength(1);
|
|
119
|
+
expect(resourceCalls[0]).toEqual({ limit: 10, archived: false });
|
|
120
|
+
expect(await firstValueFrom(stateUnit.selectedEntityType$)).toBe('');
|
|
121
|
+
|
|
122
|
+
stateUnit.dispose();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('setSelectedEntityType drives a refetch with the entityType filter', async () => {
|
|
126
|
+
const { client, resourceCalls } = mockClient();
|
|
127
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
128
|
+
|
|
129
|
+
// Prime the first subscription so the switchMap is live.
|
|
130
|
+
const sub = stateUnit.recentResources$.subscribe();
|
|
131
|
+
|
|
132
|
+
stateUnit.setSelectedEntityType('Person');
|
|
133
|
+
|
|
134
|
+
expect(await firstValueFrom(stateUnit.selectedEntityType$)).toBe('Person');
|
|
135
|
+
// Two calls expected: initial '' then 'Person'.
|
|
136
|
+
expect(resourceCalls.length).toBeGreaterThanOrEqual(2);
|
|
137
|
+
expect(resourceCalls.at(-1)).toEqual({ limit: 10, archived: false, entityType: 'Person' });
|
|
138
|
+
|
|
139
|
+
sub.unsubscribe();
|
|
140
|
+
stateUnit.dispose();
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('search with an empty query yields no results without hitting the wire', async () => {
|
|
144
|
+
vi.useFakeTimers();
|
|
145
|
+
try {
|
|
146
|
+
const { client, resourceCalls } = mockClient();
|
|
147
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
148
|
+
|
|
149
|
+
const collected: Array<{ results: unknown[]; isSearching: boolean }> = [];
|
|
150
|
+
const sub = stateUnit.search.state$.subscribe((s) => collected.push(s));
|
|
151
|
+
|
|
152
|
+
await vi.advanceTimersByTimeAsync(300);
|
|
153
|
+
|
|
154
|
+
expect(collected.at(-1)).toEqual({ results: [], isSearching: false });
|
|
155
|
+
const searchCalls = resourceCalls.filter((c) => c.search !== undefined);
|
|
156
|
+
expect(searchCalls).toHaveLength(0);
|
|
157
|
+
|
|
158
|
+
sub.unsubscribe();
|
|
159
|
+
stateUnit.dispose();
|
|
160
|
+
} finally {
|
|
161
|
+
vi.useRealTimers();
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('search with a non-empty query and selected entityType pushes both into the filter', async () => {
|
|
166
|
+
vi.useFakeTimers();
|
|
167
|
+
try {
|
|
168
|
+
const results$ = new BehaviorSubject<unknown[] | undefined>([{ '@id': 'hit' }]);
|
|
169
|
+
const { client, resourceCalls } = mockClient({
|
|
170
|
+
resourcesFn: (filters) => (filters.search ? results$ : new BehaviorSubject<unknown[] | undefined>([])),
|
|
171
|
+
});
|
|
172
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
173
|
+
|
|
174
|
+
const sub = stateUnit.search.state$.subscribe();
|
|
175
|
+
stateUnit.setSelectedEntityType('Person');
|
|
176
|
+
stateUnit.search.setQuery('lincoln');
|
|
177
|
+
|
|
178
|
+
await vi.advanceTimersByTimeAsync(300);
|
|
179
|
+
|
|
180
|
+
const searchCalls = resourceCalls.filter((c) => c.search !== undefined);
|
|
181
|
+
expect(searchCalls.length).toBeGreaterThanOrEqual(1);
|
|
182
|
+
expect(searchCalls.at(-1)).toEqual({
|
|
183
|
+
search: 'lincoln',
|
|
184
|
+
limit: 20,
|
|
185
|
+
entityType: 'Person',
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
sub.unsubscribe();
|
|
189
|
+
stateUnit.dispose();
|
|
190
|
+
} finally {
|
|
191
|
+
vi.useRealTimers();
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('search results flow through state$ once the debounced query fetches', async () => {
|
|
196
|
+
vi.useFakeTimers();
|
|
197
|
+
try {
|
|
198
|
+
const results$ = new BehaviorSubject<unknown[] | undefined>([{ '@id': 'hit' }]);
|
|
199
|
+
const { client } = mockClient({
|
|
200
|
+
resourcesFn: () => results$,
|
|
201
|
+
});
|
|
202
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
203
|
+
|
|
204
|
+
const collected: Array<{ results: unknown[]; isSearching: boolean }> = [];
|
|
205
|
+
const sub = stateUnit.search.state$.subscribe((s) => collected.push(s));
|
|
206
|
+
|
|
207
|
+
stateUnit.search.setQuery('lincoln');
|
|
208
|
+
await vi.advanceTimersByTimeAsync(300);
|
|
209
|
+
|
|
210
|
+
expect(collected.at(-1)).toEqual({ results: [{ '@id': 'hit' }], isSearching: false });
|
|
211
|
+
|
|
212
|
+
sub.unsubscribe();
|
|
213
|
+
stateUnit.dispose();
|
|
214
|
+
} finally {
|
|
215
|
+
vi.useRealTimers();
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('search reports isSearching while the fetch is in flight', async () => {
|
|
220
|
+
vi.useFakeTimers();
|
|
221
|
+
try {
|
|
222
|
+
const inflight$ = new BehaviorSubject<unknown[] | undefined>(undefined);
|
|
223
|
+
const { client } = mockClient({
|
|
224
|
+
resourcesFn: () => inflight$,
|
|
225
|
+
});
|
|
226
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
227
|
+
|
|
228
|
+
const collected: Array<{ results: unknown[]; isSearching: boolean }> = [];
|
|
229
|
+
const sub = stateUnit.search.state$.subscribe((s) => collected.push(s));
|
|
230
|
+
|
|
231
|
+
stateUnit.search.setQuery('lincoln');
|
|
232
|
+
await vi.advanceTimersByTimeAsync(300);
|
|
233
|
+
|
|
234
|
+
expect(collected.at(-1)).toEqual({ results: [], isSearching: true });
|
|
235
|
+
|
|
236
|
+
sub.unsubscribe();
|
|
237
|
+
stateUnit.dispose();
|
|
238
|
+
} finally {
|
|
239
|
+
vi.useRealTimers();
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('search query observable echoes the latest setQuery value', async () => {
|
|
244
|
+
const { client } = mockClient();
|
|
245
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
246
|
+
|
|
247
|
+
const queries = stateUnit.search.query$.pipe(skip(1), take(1), toArray()).toPromise();
|
|
248
|
+
stateUnit.search.setQuery('alpha');
|
|
249
|
+
|
|
250
|
+
expect(await queries).toEqual(['alpha']);
|
|
251
|
+
|
|
252
|
+
stateUnit.dispose();
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it('omits entityType from the filter when the empty sentinel is selected', async () => {
|
|
256
|
+
const { client, resourceCalls } = mockClient();
|
|
257
|
+
const stateUnit = createDiscoverStateUnit(client, mockBrowse());
|
|
258
|
+
|
|
259
|
+
const sub = stateUnit.recentResources$.subscribe();
|
|
260
|
+
stateUnit.setSelectedEntityType('Person');
|
|
261
|
+
stateUnit.setSelectedEntityType('');
|
|
262
|
+
|
|
263
|
+
const last = resourceCalls.at(-1)!;
|
|
264
|
+
expect(last.entityType).toBeUndefined();
|
|
265
|
+
|
|
266
|
+
sub.unsubscribe();
|
|
267
|
+
stateUnit.dispose();
|
|
268
|
+
});
|
|
76
269
|
});
|
|
@@ -1,20 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BehaviorSubject, Subject, combineLatest, of, type Observable } from 'rxjs';
|
|
2
|
+
import { debounceTime, distinctUntilChanged, map, startWith, switchMap, shareReplay } from 'rxjs/operators';
|
|
2
3
|
import type { ResourceDescriptor } from '@semiont/core';
|
|
3
|
-
import type { StateUnit } from '@semiont/sdk';
|
|
4
|
+
import type { SemiontClient, StateUnit } from '@semiont/sdk';
|
|
4
5
|
import { createDisposer } from '@semiont/sdk';
|
|
5
6
|
import type { ShellStateUnit } from '../../../state/shell-state-unit';
|
|
6
|
-
import { createSearchPipeline, type SearchPipeline } from '@semiont/sdk';
|
|
7
|
-
import type { SemiontClient } from '@semiont/sdk';
|
|
8
7
|
|
|
9
8
|
const RECENT_LIMIT = 10;
|
|
10
9
|
const SEARCH_LIMIT = 20;
|
|
10
|
+
const DEBOUNCE_MS = 250;
|
|
11
|
+
|
|
12
|
+
export interface DiscoverSearchPipeline {
|
|
13
|
+
query$: Observable<string>;
|
|
14
|
+
state$: Observable<{ results: ResourceDescriptor[]; isSearching: boolean }>;
|
|
15
|
+
setQuery(value: string): void;
|
|
16
|
+
}
|
|
11
17
|
|
|
12
18
|
export interface DiscoverStateUnit extends StateUnit {
|
|
13
19
|
browse: ShellStateUnit;
|
|
14
|
-
search:
|
|
20
|
+
search: DiscoverSearchPipeline;
|
|
15
21
|
recentResources$: Observable<ResourceDescriptor[]>;
|
|
16
22
|
entityTypes$: Observable<string[]>;
|
|
17
23
|
isLoadingRecent$: Observable<boolean>;
|
|
24
|
+
selectedEntityType$: Observable<string>;
|
|
25
|
+
setSelectedEntityType(value: string): void;
|
|
18
26
|
}
|
|
19
27
|
|
|
20
28
|
export function createDiscoverStateUnit(
|
|
@@ -22,14 +30,27 @@ export function createDiscoverStateUnit(
|
|
|
22
30
|
browse: ShellStateUnit,
|
|
23
31
|
): DiscoverStateUnit {
|
|
24
32
|
const disposer = createDisposer();
|
|
25
|
-
|
|
26
|
-
const search = createSearchPipeline<ResourceDescriptor>((q) =>
|
|
27
|
-
client.browse.resources({ search: q, limit: SEARCH_LIMIT }),
|
|
28
|
-
);
|
|
29
|
-
disposer.add(search);
|
|
30
33
|
disposer.add(browse);
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
// Selected entity-type chip on the Discover page. Drives both the
|
|
36
|
+
// `recent` list and the search results — filtering happens on the
|
|
37
|
+
// backend, not via post-fetch array filtering.
|
|
38
|
+
const selectedEntityType$ = new BehaviorSubject<string>('');
|
|
39
|
+
disposer.add(() => selectedEntityType$.complete());
|
|
40
|
+
|
|
41
|
+
const queryInput$ = new Subject<string>();
|
|
42
|
+
disposer.add(() => queryInput$.complete());
|
|
43
|
+
|
|
44
|
+
const recent$ = selectedEntityType$.pipe(
|
|
45
|
+
switchMap((et) =>
|
|
46
|
+
client.browse.resources({
|
|
47
|
+
limit: RECENT_LIMIT,
|
|
48
|
+
archived: false,
|
|
49
|
+
...(et ? { entityType: et } : {}),
|
|
50
|
+
}),
|
|
51
|
+
),
|
|
52
|
+
shareReplay({ bufferSize: 1, refCount: true }),
|
|
53
|
+
);
|
|
33
54
|
|
|
34
55
|
const recentResources$: Observable<ResourceDescriptor[]> = recent$.pipe(
|
|
35
56
|
map((r) => r ?? []),
|
|
@@ -43,12 +64,50 @@ export function createDiscoverStateUnit(
|
|
|
43
64
|
map((e) => e ?? []),
|
|
44
65
|
);
|
|
45
66
|
|
|
67
|
+
const debouncedQuery$ = queryInput$.pipe(
|
|
68
|
+
startWith(''),
|
|
69
|
+
debounceTime(DEBOUNCE_MS),
|
|
70
|
+
distinctUntilChanged(),
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const state$: Observable<{ results: ResourceDescriptor[]; isSearching: boolean }> =
|
|
74
|
+
combineLatest([debouncedQuery$, selectedEntityType$]).pipe(
|
|
75
|
+
switchMap(([q, et]) => {
|
|
76
|
+
const trimmed = q.trim();
|
|
77
|
+
if (!trimmed) {
|
|
78
|
+
return of({ results: [] as ResourceDescriptor[], isSearching: false });
|
|
79
|
+
}
|
|
80
|
+
return client.browse
|
|
81
|
+
.resources({
|
|
82
|
+
search: trimmed,
|
|
83
|
+
limit: SEARCH_LIMIT,
|
|
84
|
+
...(et ? { entityType: et } : {}),
|
|
85
|
+
})
|
|
86
|
+
.pipe(
|
|
87
|
+
map((results) => ({
|
|
88
|
+
results: results ?? [],
|
|
89
|
+
isSearching: results === undefined,
|
|
90
|
+
})),
|
|
91
|
+
startWith({ results: [] as ResourceDescriptor[], isSearching: true }),
|
|
92
|
+
);
|
|
93
|
+
}),
|
|
94
|
+
shareReplay({ bufferSize: 1, refCount: true }),
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const search: DiscoverSearchPipeline = {
|
|
98
|
+
query$: queryInput$.pipe(startWith('')),
|
|
99
|
+
state$,
|
|
100
|
+
setQuery: (value) => queryInput$.next(value),
|
|
101
|
+
};
|
|
102
|
+
|
|
46
103
|
return {
|
|
47
104
|
browse,
|
|
48
105
|
search,
|
|
49
106
|
recentResources$,
|
|
50
107
|
entityTypes$,
|
|
51
108
|
isLoadingRecent$,
|
|
109
|
+
selectedEntityType$: selectedEntityType$.asObservable(),
|
|
110
|
+
setSelectedEntityType: (value) => selectedEntityType$.next(value),
|
|
52
111
|
dispose: () => disposer.dispose(),
|
|
53
112
|
};
|
|
54
113
|
}
|
|
@@ -13,6 +13,7 @@ import type { ResourceViewerPageProps } from '../components/ResourceViewerPage';
|
|
|
13
13
|
import { ToastProvider } from '../../../components/Toast';
|
|
14
14
|
import { ThemeProvider } from '../../../contexts/ThemeContext';
|
|
15
15
|
import { createTestSemiontWrapper } from '../../../test-utils';
|
|
16
|
+
import type { ResourceId } from '@semiont/core';
|
|
16
17
|
|
|
17
18
|
// jsdom doesn't implement window.matchMedia — mock it for useTheme
|
|
18
19
|
Object.defineProperty(window, 'matchMedia', {
|
|
@@ -131,7 +132,7 @@ vi.mock('@/components/toolbar/ToolbarPanels', () => ({
|
|
|
131
132
|
const createMockProps = (overrides?: Partial<ResourceViewerPageProps>): ResourceViewerPageProps => ({
|
|
132
133
|
resource: {
|
|
133
134
|
'@context': 'https://www.w3.org/ns/anno.jsonld',
|
|
134
|
-
'@id': 'test-123',
|
|
135
|
+
'@id': 'test-123' as ResourceId,
|
|
135
136
|
'@type': 'schema:DigitalDocument',
|
|
136
137
|
name: 'Test Resource',
|
|
137
138
|
description: 'A test resource for unit testing',
|
|
@@ -147,7 +148,6 @@ const createMockProps = (overrides?: Partial<ResourceViewerPageProps>): Resource
|
|
|
147
148
|
},
|
|
148
149
|
rUri: 'test-123' as any,
|
|
149
150
|
locale: 'en',
|
|
150
|
-
cacheManager: {},
|
|
151
151
|
Link: ({ children }: any) => <a>{children}</a>,
|
|
152
152
|
routes: {},
|
|
153
153
|
refetchDocument: vi.fn().mockResolvedValue(undefined),
|
|
@@ -265,8 +265,9 @@ export function ResourceViewerPage({
|
|
|
265
265
|
|
|
266
266
|
// Domain events flow through the bus gateway (ActorStateUnit → local EventBus).
|
|
267
267
|
// BrowseNamespace cache invalidation handles annotation/resource updates.
|
|
268
|
-
//
|
|
269
|
-
//
|
|
268
|
+
// Resource-scoped freshness follows observation (#847): subscribing to the
|
|
269
|
+
// resource's `browse.*` live queries acquires its scope (which bridges scoped
|
|
270
|
+
// domain events into the local EventBus) and releases it on teardown.
|
|
270
271
|
|
|
271
272
|
const handleResourceArchive = useCallback(async () => {
|
|
272
273
|
if (!semiont) return;
|
package/src/features/resource-viewer/state/__tests__/resource-viewer-page-state-unit.test.ts
CHANGED
|
@@ -56,7 +56,6 @@ function clientWithNamespaces(overrides: {
|
|
|
56
56
|
match: { search: vi.fn(() => new Observable(() => {})) },
|
|
57
57
|
yield: { fromAnnotation: vi.fn(() => new Observable(() => {})) },
|
|
58
58
|
bind: { body: vi.fn().mockResolvedValue(undefined) },
|
|
59
|
-
subscribeToResource: vi.fn().mockReturnValue(() => {}),
|
|
60
59
|
});
|
|
61
60
|
}
|
|
62
61
|
|
|
@@ -133,8 +133,11 @@ export function createResourceViewerPageStateUnit(
|
|
|
133
133
|
|
|
134
134
|
const wizard$ = new BehaviorSubject<WizardState>(WIZARD_CLOSED);
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
// Resource-scoped freshness follows observation (#847): subscribing to the
|
|
137
|
+
// `browse.*(resourceId)` live queries exposed by this state unit
|
|
138
|
+
// (annotations$, events$, referencedBy$) acquires the resource scope for as
|
|
139
|
+
// long as they're observed and releases it on teardown — so no manual
|
|
140
|
+
// `subscribeToResource` call is needed.
|
|
138
141
|
|
|
139
142
|
const bindInitiateSub = client.bus.get('bind:initiate').subscribe((event) => {
|
|
140
143
|
wizard$.next({
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
import { render } from '@testing-library/react';
|
|
4
3
|
import {
|
|
5
4
|
createSemiontClassName,
|
|
@@ -96,7 +95,7 @@ describe('css-modules-helper', () => {
|
|
|
96
95
|
|
|
97
96
|
describe('mergeDataAttributes', () => {
|
|
98
97
|
it('merges data attributes into props', () => {
|
|
99
|
-
const props = { id: 'btn', className: 'foo' };
|
|
98
|
+
const props: Record<string, string> = { id: 'btn', className: 'foo' };
|
|
100
99
|
const dataAttrs = { 'data-variant': 'primary', 'data-size': 'md' };
|
|
101
100
|
const merged = mergeDataAttributes(props, dataAttrs);
|
|
102
101
|
|
|
@@ -107,7 +106,7 @@ describe('css-modules-helper', () => {
|
|
|
107
106
|
});
|
|
108
107
|
|
|
109
108
|
it('skips undefined data attributes', () => {
|
|
110
|
-
const props = { id: 'btn' };
|
|
109
|
+
const props: Record<string, string> = { id: 'btn' };
|
|
111
110
|
const dataAttrs = { 'data-variant': 'primary', 'data-size': undefined };
|
|
112
111
|
const merged = mergeDataAttributes(props, dataAttrs);
|
|
113
112
|
|
|
@@ -122,14 +122,12 @@ describe('styled-components-theme', () => {
|
|
|
122
122
|
|
|
123
123
|
it('calls styled.button.attrs', () => {
|
|
124
124
|
let attrsArg: any;
|
|
125
|
-
let templateArg: any;
|
|
126
125
|
|
|
127
126
|
const mockStyled = {
|
|
128
127
|
button: {
|
|
129
128
|
attrs: (arg: any) => {
|
|
130
129
|
attrsArg = arg;
|
|
131
|
-
return (
|
|
132
|
-
templateArg = { strings, exprs };
|
|
130
|
+
return (_strings: TemplateStringsArray) => {
|
|
133
131
|
return 'MockComponent';
|
|
134
132
|
};
|
|
135
133
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/pdf-annotation/PdfAnnotationCanvas.tsx","../src/lib/pdf-coordinates.ts","../src/lib/browser-pdfjs.ts"],"sourcesContent":["'use client';\n\nimport React, { useRef, useState, useCallback, useEffect, useMemo } from 'react';\nimport type { Annotation } from '@semiont/core';\nimport { getTargetSelector } from '@semiont/core';\nimport { createHoverHandlers, type SemiontSession } from '@semiont/sdk';\nimport type { SelectionMotivation } from '../annotation/AnnotateToolbar';\nimport {\n canvasToPdfCoordinates,\n pdfToCanvasCoordinates,\n createFragmentSelector,\n parseFragmentSelector,\n getPageFromFragment,\n type CanvasRectangle\n} from '../../lib/pdf-coordinates';\nimport {\n loadPdfDocument,\n renderPdfPageToDataUrl,\n type PDFDocumentProxy\n} from '../../lib/browser-pdfjs';\nimport './PdfAnnotationCanvas.css';\n\nexport type DrawingMode = 'rectangle' | 'circle' | 'polygon' | null;\n\n/**\n * Get color for annotation based on motivation\n */\nfunction getMotivationColor(motivation: SelectionMotivation | null): { stroke: string; fill: string } {\n if (!motivation) {\n return { stroke: 'rgb(156, 163, 175)', fill: 'rgba(156, 163, 175, 0.2)' };\n }\n\n switch (motivation) {\n case 'highlighting':\n return { stroke: 'rgb(250, 204, 21)', fill: 'rgba(250, 204, 21, 0.3)' };\n case 'linking':\n return { stroke: 'rgb(59, 130, 246)', fill: 'rgba(59, 130, 246, 0.2)' };\n case 'assessing':\n return { stroke: 'rgb(239, 68, 68)', fill: 'rgba(239, 68, 68, 0.2)' };\n case 'commenting':\n return { stroke: 'rgb(255, 255, 255)', fill: 'rgba(255, 255, 255, 0.2)' };\n default:\n return { stroke: 'rgb(156, 163, 175)', fill: 'rgba(156, 163, 175, 0.2)' };\n }\n}\n\ninterface PdfAnnotationCanvasProps {\n pdfUrl: string;\n existingAnnotations?: Annotation[];\n drawingMode: DrawingMode;\n selectedMotivation?: SelectionMotivation | null;\n session?: SemiontSession | null | undefined;\n hoveredAnnotationId?: string | null;\n selectedAnnotationId?: string | null;\n hoverDelayMs?: number;\n}\n\n/**\n * PDF annotation canvas with page navigation and rectangle drawing\n *\n * @emits browse:click - Annotation clicked on PDF. Payload: { annotationId: string, motivation: Motivation }\n * @emits mark:requested - New annotation drawn on PDF. Payload: { selector: FragmentSelector, motivation: SelectionMotivation }\n * @emits beckon:hover - Annotation hovered or unhovered. Payload: { annotationId: string | null }\n */\nexport function PdfAnnotationCanvas({\n pdfUrl,\n existingAnnotations = [],\n drawingMode,\n selectedMotivation,\n session,\n hoveredAnnotationId,\n selectedAnnotationId,\n hoverDelayMs = 150\n}: PdfAnnotationCanvasProps) {\n // PDF state\n const [pdfDoc, setPdfDoc] = useState<PDFDocumentProxy | null>(null);\n const [numPages, setNumPages] = useState<number>(0);\n const [pageNumber, setPageNumber] = useState(1);\n const [pageImageUrl, setPageImageUrl] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [pageDimensions, setPageDimensions] = useState<{ width: number; height: number } | null>(null);\n const [displayDimensions, setDisplayDimensions] = useState<{ width: number; height: number } | null>(null);\n const [scale] = useState(1.5); // Fixed scale for better quality\n\n // Drawing state\n const [isDrawing, setIsDrawing] = useState(false);\n const [selection, setSelection] = useState<CanvasRectangle | null>(null);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const imageRef = useRef<HTMLImageElement>(null);\n\n // Load PDF document on mount\n useEffect(() => {\n let cancelled = false;\n\n async function loadPdf() {\n try {\n setIsLoading(true);\n setError(null);\n\n const doc = await loadPdfDocument(pdfUrl);\n\n if (cancelled) return;\n\n setPdfDoc(doc);\n setNumPages(doc.numPages);\n setIsLoading(false);\n } catch (err) {\n if (cancelled) return;\n\n console.error('Error loading PDF:', err);\n setError('Failed to load PDF');\n setIsLoading(false);\n }\n }\n\n loadPdf();\n\n return () => {\n cancelled = true;\n };\n }, [pdfUrl]);\n\n // Load current page when page number changes\n useEffect(() => {\n if (!pdfDoc) return;\n\n let cancelled = false;\n const doc = pdfDoc;\n\n async function loadPage() {\n try {\n const page = await doc.getPage(pageNumber);\n\n if (cancelled) return;\n\n // Get page dimensions (at scale 1.0)\n const viewport = page.getViewport({ scale: 1.0 });\n setPageDimensions({\n width: viewport.width,\n height: viewport.height\n });\n\n // Render page to image\n const { dataUrl } = await renderPdfPageToDataUrl(page, scale);\n\n if (cancelled) return;\n\n setPageImageUrl(dataUrl);\n } catch (err) {\n if (cancelled) return;\n\n console.error('Error loading page:', err);\n setError('Failed to load page');\n }\n }\n\n loadPage();\n\n return () => {\n cancelled = true;\n };\n }, [pdfDoc, pageNumber, scale]);\n\n // Update display dimensions on resize\n useEffect(() => {\n const updateDisplayDimensions = () => {\n if (imageRef.current) {\n setDisplayDimensions({\n width: imageRef.current.clientWidth,\n height: imageRef.current.clientHeight\n });\n }\n };\n\n updateDisplayDimensions();\n\n // Use ResizeObserver to detect image element size changes\n // This catches: sidebar open/close, window resize, font size changes, etc.\n let resizeObserver: ResizeObserver | null = null;\n\n try {\n resizeObserver = new ResizeObserver(updateDisplayDimensions);\n if (imageRef.current) {\n resizeObserver.observe(imageRef.current);\n }\n } catch (error) {\n // Fallback for browsers without ResizeObserver support\n console.warn('ResizeObserver not supported, falling back to window resize listener');\n window.addEventListener('resize', updateDisplayDimensions);\n }\n\n return () => {\n if (resizeObserver) {\n resizeObserver.disconnect();\n } else {\n window.removeEventListener('resize', updateDisplayDimensions);\n }\n };\n }, [pageImageUrl]);\n\n // Mouse event handlers for drawing\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n if (!drawingMode) return;\n if (!imageRef.current) return;\n\n const rect = imageRef.current.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n\n // Clear any previous selection when starting new drawing\n setIsDrawing(true);\n setSelection({\n startX: x,\n startY: y,\n endX: x,\n endY: y\n });\n }, [drawingMode]);\n\n const handleMouseMove = useCallback((e: React.MouseEvent) => {\n if (!isDrawing || !selection || !imageRef.current) return;\n\n const rect = imageRef.current.getBoundingClientRect();\n\n setSelection({\n ...selection,\n endX: e.clientX - rect.left,\n endY: e.clientY - rect.top\n });\n }, [isDrawing, selection]);\n\n const handleMouseUp = useCallback(() => {\n if (!isDrawing || !selection || !pageDimensions || !displayDimensions || !session) {\n setIsDrawing(false);\n setSelection(null);\n return;\n }\n\n // Calculate drag distance\n const dragDistance = Math.sqrt(\n Math.pow(selection.endX - selection.startX, 2) +\n Math.pow(selection.endY - selection.startY, 2)\n );\n\n // Minimum drag threshold in pixels (10px)\n const MIN_DRAG_DISTANCE = 10;\n\n if (dragDistance < MIN_DRAG_DISTANCE) {\n // This was a click, not a drag - check if we clicked an existing annotation\n if (existingAnnotations.length > 0) {\n const clickedAnnotation = pageAnnotations.find(ann => {\n const fragmentSel = getFragmentSelector(ann.target);\n if (!fragmentSel) return false;\n\n const pdfCoord = parseFragmentSelector(fragmentSel.value);\n if (!pdfCoord) return false;\n\n const rect = pdfToCanvasCoordinates(pdfCoord, pageDimensions.height, 1.0);\n\n // Scale to display coordinates\n const scaleX = displayDimensions.width / pageDimensions.width;\n const scaleY = displayDimensions.height / pageDimensions.height;\n\n const displayX = rect.x * scaleX;\n const displayY = rect.y * scaleY;\n const displayWidth = rect.width * scaleX;\n const displayHeight = rect.height * scaleY;\n\n return (\n selection.endX >= displayX &&\n selection.endX <= displayX + displayWidth &&\n selection.endY >= displayY &&\n selection.endY <= displayY + displayHeight\n );\n });\n\n if (clickedAnnotation) {\n session?.client.browse.click(clickedAnnotation.id, clickedAnnotation.motivation);\n setIsDrawing(false);\n setSelection(null);\n return;\n }\n }\n\n // Click on empty space - do nothing\n setIsDrawing(false);\n setSelection(null);\n return;\n }\n\n // This was a drag - create new annotation\n // Scale selection from display coordinates to native page coordinates\n const scaleX = pageDimensions.width / displayDimensions.width;\n const scaleY = pageDimensions.height / displayDimensions.height;\n\n const nativeSelection: CanvasRectangle = {\n startX: selection.startX * scaleX,\n startY: selection.startY * scaleY,\n endX: selection.endX * scaleX,\n endY: selection.endY * scaleY\n };\n\n // Convert canvas coordinates to PDF coordinates\n const pdfCoord = canvasToPdfCoordinates(\n nativeSelection,\n pageNumber,\n pageDimensions.width,\n pageDimensions.height,\n 1.0 // Use scale 1.0 since we already scaled to native coords\n );\n\n // Create FragmentSelector\n const fragmentSelector = createFragmentSelector(pdfCoord);\n\n // Emit annotation:requested event with FragmentSelector\n if (selectedMotivation) {\n session.client.mark.request(\n {\n type: 'FragmentSelector',\n conformsTo: 'http://tools.ietf.org/rfc/rfc3778',\n value: fragmentSelector,\n },\n selectedMotivation,\n );\n }\n\n // Keep drawing state active to show preview until annotation is persisted\n // The parent component should clear this by changing drawingMode after save\n setIsDrawing(false);\n // Note: We keep selection so the preview remains visible\n // It will be cleared when drawingMode changes or user starts new selection\n }, [isDrawing, selection, pageNumber, pageDimensions, displayDimensions, selectedMotivation, existingAnnotations]);\n\n // Helper to get FragmentSelector from annotation target\n const getFragmentSelector = (target: Annotation['target']) => {\n const selector = getTargetSelector(target);\n if (!selector) return null;\n const selectors = Array.isArray(selector) ? selector : [selector];\n\n const found = selectors.find(s => s.type === 'FragmentSelector');\n if (!found || found.type !== 'FragmentSelector') return null;\n return found as { type: 'FragmentSelector'; value: string; conformsTo?: string };\n };\n\n // Filter annotations for current page\n const pageAnnotations = existingAnnotations.filter(ann => {\n const fragmentSel = getFragmentSelector(ann.target);\n if (!fragmentSel) return false;\n const page = getPageFromFragment(fragmentSel.value);\n return page === pageNumber;\n });\n\n // Hover handlers with currentHover guard and dwell delay\n const { handleMouseEnter, handleMouseLeave } = useMemo(\n () => createHoverHandlers((id) => session?.client.beckon.hover(id), hoverDelayMs),\n [session, hoverDelayMs]\n );\n\n // Calculate motivation color\n const { stroke, fill } = getMotivationColor(selectedMotivation ?? null);\n\n if (error) {\n return <div className=\"semiont-pdf-annotation-canvas__error\">{error}</div>;\n }\n\n return (\n <div className=\"semiont-pdf-annotation-canvas\">\n {isLoading && <div className=\"semiont-pdf-annotation-canvas__loading\">Loading PDF...</div>}\n\n <div\n ref={containerRef}\n className=\"semiont-pdf-annotation-canvas__container\"\n style={{ display: isLoading ? 'none' : undefined }}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={() => {\n if (isDrawing) {\n setIsDrawing(false);\n setSelection(null);\n }\n }}\n data-drawing-mode={drawingMode || 'none'}\n >\n {/* PDF page rendered as image */}\n {pageImageUrl && (\n <img\n ref={imageRef}\n src={pageImageUrl}\n alt={`PDF page ${pageNumber}`}\n className=\"semiont-pdf-annotation-canvas__image\"\n draggable={false}\n style={{ pointerEvents: 'none' }}\n onLoad={() => {\n // Use double RAF to ensure layout is complete even in onLoad\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (imageRef.current) {\n setDisplayDimensions({\n width: imageRef.current.clientWidth,\n height: imageRef.current.clientHeight\n });\n }\n });\n });\n }}\n />\n )}\n\n {/* SVG overlay for annotations */}\n {displayDimensions && pageDimensions && (\n <div className=\"semiont-pdf-annotation-canvas__overlay-container\">\n <div className=\"semiont-pdf-annotation-canvas__overlay\">\n <svg\n className=\"semiont-pdf-annotation-canvas__svg\"\n width={displayDimensions.width}\n height={displayDimensions.height}\n >\n {/* Render existing annotations for this page */}\n {pageAnnotations.map(ann => {\n const fragmentSel = getFragmentSelector(ann.target);\n if (!fragmentSel) return null;\n\n const pdfCoord = parseFragmentSelector(fragmentSel.value);\n if (!pdfCoord) return null;\n\n const rect = pdfToCanvasCoordinates(pdfCoord, pageDimensions.height, 1.0);\n\n // Scale to display coordinates\n const scaleX = displayDimensions.width / pageDimensions.width;\n const scaleY = displayDimensions.height / pageDimensions.height;\n\n const isHovered = ann.id === hoveredAnnotationId;\n const isSelected = ann.id === selectedAnnotationId;\n\n // Get color for this annotation's motivation (not the selected motivation)\n const annMotivation = ann.motivation as SelectionMotivation | null;\n const { stroke: annStroke, fill: annFill } = getMotivationColor(annMotivation);\n\n return (\n <rect\n key={ann.id}\n x={rect.x * scaleX}\n y={rect.y * scaleY}\n width={rect.width * scaleX}\n height={rect.height * scaleY}\n stroke={annStroke}\n strokeWidth={isSelected ? 4 : isHovered ? 3 : 2}\n fill={annFill}\n style={{\n pointerEvents: 'auto',\n cursor: 'pointer',\n opacity: isSelected ? 1 : isHovered ? 0.9 : 0.7\n }}\n onClick={() => session?.client.browse.click(ann.id, ann.motivation)}\n onMouseEnter={() => handleMouseEnter(ann.id)}\n onMouseLeave={handleMouseLeave}\n />\n );\n })}\n\n {/* Render current selection while drawing or awaiting save */}\n {selection && (() => {\n const rectX = Math.min(selection.startX, selection.endX);\n const rectY = Math.min(selection.startY, selection.endY);\n const rectWidth = Math.abs(selection.endX - selection.startX);\n const rectHeight = Math.abs(selection.endY - selection.startY);\n\n // PDF only supports rectangle shapes (FragmentSelector with viewrect)\n // Circle/polygon are disabled in the UI for PDF media types\n return (\n <rect\n x={rectX}\n y={rectY}\n width={rectWidth}\n height={rectHeight}\n stroke={stroke}\n strokeWidth={2}\n strokeDasharray=\"5,5\"\n fill={fill}\n pointerEvents=\"none\"\n />\n );\n })()}\n </svg>\n </div>\n </div>\n )}\n </div>\n\n {/* Page navigation controls */}\n {numPages > 0 && (\n <div className=\"semiont-pdf-annotation-canvas__controls\">\n <button\n disabled={pageNumber <= 1}\n onClick={() => setPageNumber(pageNumber - 1)}\n className=\"semiont-pdf-annotation-canvas__button\"\n >\n Previous\n </button>\n <span className=\"semiont-pdf-annotation-canvas__page-info\">\n Page {pageNumber} of {numPages}\n </span>\n <button\n disabled={pageNumber >= numPages}\n onClick={() => setPageNumber(pageNumber + 1)}\n className=\"semiont-pdf-annotation-canvas__button\"\n >\n Next\n </button>\n </div>\n )}\n </div>\n );\n}\n","/**\n * PDF Coordinate Utilities\n *\n * Handles coordinate transformations between:\n * - Canvas space (pixels, top-left origin, Y increases downward)\n * - PDF space (points, bottom-left origin, Y increases upward)\n *\n * Based on RFC 3778 PDF Fragment Identifiers:\n * https://tools.ietf.org/html/rfc3778\n */\n\nexport interface Rectangle {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface PdfCoordinate {\n page: number;\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface CanvasRectangle {\n startX: number;\n startY: number;\n endX: number;\n endY: number;\n}\n\n/**\n * Convert canvas coordinates to PDF coordinates\n *\n * Canvas: Origin at top-left, Y increases downward\n * PDF: Origin at bottom-left, Y increases upward\n *\n * @param canvasRect - Rectangle in canvas pixel coordinates\n * @param page - PDF page number (1-indexed)\n * @param pageWidth - PDF page width in points\n * @param pageHeight - PDF page height in points\n * @param scale - Current canvas scale factor\n */\nexport function canvasToPdfCoordinates(\n canvasRect: CanvasRectangle,\n page: number,\n _pageWidth: number,\n pageHeight: number,\n scale: number = 1\n): PdfCoordinate {\n // Normalize rectangle (handle drag in any direction)\n const x1 = Math.min(canvasRect.startX, canvasRect.endX);\n const y1 = Math.min(canvasRect.startY, canvasRect.endY);\n const x2 = Math.max(canvasRect.startX, canvasRect.endX);\n const y2 = Math.max(canvasRect.startY, canvasRect.endY);\n\n // Convert from canvas pixels to PDF points\n const pdfX = x1 / scale;\n const pdfWidth = (x2 - x1) / scale;\n\n // Flip Y coordinate (canvas top-left to PDF bottom-left)\n const pdfY = pageHeight - (y2 / scale);\n const pdfHeight = (y2 - y1) / scale;\n\n return {\n page,\n x: Math.round(pdfX),\n y: Math.round(pdfY),\n width: Math.round(pdfWidth),\n height: Math.round(pdfHeight)\n };\n}\n\n/**\n * Convert PDF coordinates to canvas coordinates\n *\n * @param pdfCoord - Coordinates in PDF space\n * @param pageHeight - PDF page height in points\n * @param scale - Current canvas scale factor\n */\nexport function pdfToCanvasCoordinates(\n pdfCoord: PdfCoordinate,\n pageHeight: number,\n scale: number = 1\n): Rectangle {\n // Convert from PDF points to canvas pixels\n const canvasX = pdfCoord.x * scale;\n const canvasWidth = pdfCoord.width * scale;\n\n // Flip Y coordinate (PDF bottom-left to canvas top-left)\n const canvasY = (pageHeight - pdfCoord.y - pdfCoord.height) * scale;\n const canvasHeight = pdfCoord.height * scale;\n\n return {\n x: canvasX,\n y: canvasY,\n width: canvasWidth,\n height: canvasHeight\n };\n}\n\n/**\n * Generate RFC 3778 FragmentSelector value\n *\n * Format: page=N&viewrect=left,top,width,height\n * All coordinates in PDF points\n */\nexport function createFragmentSelector(coord: PdfCoordinate): string {\n return `page=${coord.page}&viewrect=${coord.x},${coord.y},${coord.width},${coord.height}`;\n}\n\n/**\n * Parse RFC 3778 FragmentSelector value\n *\n * @param fragment - Fragment string like \"page=5&viewrect=100,200,300,400\"\n * @returns Parsed PDF coordinates or null if invalid\n */\nexport function parseFragmentSelector(fragment: string): PdfCoordinate | null {\n try {\n // Parse page number\n const pageMatch = fragment.match(/page=(\\d+)/);\n if (!pageMatch) return null;\n const page = parseInt(pageMatch[1], 10);\n\n // Parse viewrect coordinates\n const viewrectMatch = fragment.match(/viewrect=([\\d.]+),([\\d.]+),([\\d.]+),([\\d.]+)/);\n if (!viewrectMatch) return null;\n\n return {\n page,\n x: parseFloat(viewrectMatch[1]),\n y: parseFloat(viewrectMatch[2]),\n width: parseFloat(viewrectMatch[3]),\n height: parseFloat(viewrectMatch[4])\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Extract page number from FragmentSelector\n */\nexport function getPageFromFragment(fragment: string): number | null {\n const match = fragment.match(/page=(\\d+)/);\n return match ? parseInt(match[1], 10) : null;\n}\n","/**\n * Browser PDF.js utilities\n *\n * Uses native browser PDF.js when available, falls back to CDN.\n * Zero npm dependencies - no webpack bundling issues.\n */\n\n// Type definitions for PDF.js API\nexport interface PDFDocumentProxy {\n numPages: number;\n getPage(pageNumber: number): Promise<PDFPageProxy>;\n}\n\nexport interface PDFPageProxy {\n getViewport(params: { scale: number; rotation?: number }): PDFViewport;\n render(params: PDFRenderParams): PDFRenderTask;\n getTextContent(): Promise<TextContent>;\n}\n\nexport interface PDFViewport {\n width: number;\n height: number;\n scale: number;\n rotation: number;\n}\n\nexport interface PDFRenderParams {\n canvasContext: CanvasRenderingContext2D;\n viewport: PDFViewport;\n}\n\nexport interface PDFRenderTask {\n promise: Promise<void>;\n cancel(): void;\n}\n\nexport interface PDFLib {\n getDocument(params: { url: string }): PDFLoadingTask;\n GlobalWorkerOptions: {\n workerSrc: string;\n };\n version: string;\n}\n\nexport interface PDFLoadingTask {\n promise: Promise<PDFDocumentProxy>;\n destroy(): void;\n}\n\n/**\n * Text content types (for Phase 2)\n */\nexport interface TextItem {\n str: string;\n dir: string;\n transform: number[]; // [scaleX, skewX, skewY, scaleY, x, y]\n width: number;\n height: number;\n fontName: string;\n hasEOL: boolean;\n}\n\nexport interface TextContent {\n items: TextItem[];\n styles: Record<string, any>;\n}\n\n/**\n * Ensure PDF.js is available, loading from local public folder if needed\n */\nexport async function ensurePdfJs(): Promise<PDFLib> {\n // Check if already available (browser native or already loaded)\n if (typeof window !== 'undefined' && (window as any).pdfjsLib) {\n return (window as any).pdfjsLib as PDFLib;\n }\n\n // Load from local public folder (staged during build)\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = '/pdfjs/pdf.min.mjs';\n script.type = 'module';\n\n script.onload = () => {\n const pdfjsLib = (window as any).pdfjsLib as PDFLib;\n\n if (!pdfjsLib) {\n reject(new Error('PDF.js loaded but pdfjsLib not available'));\n return;\n }\n\n // Configure worker (also served from local public folder)\n pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdfjs/pdf.worker.min.mjs';\n\n resolve(pdfjsLib);\n };\n\n script.onerror = () => {\n reject(new Error('Failed to load PDF.js from /pdfjs/pdf.min.mjs'));\n };\n\n document.head.appendChild(script);\n });\n}\n\n/**\n * Load PDF document from a URL.\n *\n * The URL must include authentication (e.g. ?token=<media-token>).\n * PDF.js streams the document directly — no ArrayBuffer buffering in JS.\n */\nexport async function loadPdfDocument(url: string): Promise<PDFDocumentProxy> {\n const pdfjsLib = await ensurePdfJs();\n const loadingTask = pdfjsLib.getDocument({ url });\n return loadingTask.promise;\n}\n\n/**\n * Render PDF page to canvas and return as data URL\n */\nexport async function renderPdfPageToDataUrl(\n page: PDFPageProxy,\n scale = 1.0\n): Promise<{ dataUrl: string; width: number; height: number }> {\n const viewport = page.getViewport({ scale });\n\n // Create canvas\n const canvas = document.createElement('canvas');\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Failed to get 2D context');\n }\n\n canvas.width = viewport.width;\n canvas.height = viewport.height;\n\n // Render PDF page to canvas\n const renderTask = page.render({\n canvasContext: context,\n viewport: viewport\n });\n\n await renderTask.promise;\n\n // Convert to data URL\n return {\n dataUrl: canvas.toDataURL('image/png'),\n width: viewport.width,\n height: viewport.height\n };\n}\n\n/**\n * Render PDF page with text content extraction (Phase 2)\n *\n * This function extracts text in parallel with rendering for future\n * text layer support. Currently the text content is available but not used.\n */\nexport async function renderPdfPageWithText(\n page: PDFPageProxy,\n scale = 1.0\n): Promise<{\n dataUrl: string;\n width: number;\n height: number;\n textContent: TextContent;\n}> {\n const viewport = page.getViewport({ scale });\n\n // Create canvas for rendering\n const canvas = document.createElement('canvas');\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Failed to get 2D context');\n }\n\n canvas.width = viewport.width;\n canvas.height = viewport.height;\n\n // Render PDF page to canvas\n const renderTask = page.render({\n canvasContext: context,\n viewport: viewport\n });\n\n // Extract text content in parallel (for future text layer support)\n const [, textContent] = await Promise.all([\n renderTask.promise,\n page.getTextContent()\n ]);\n\n // Convert to data URL\n return {\n dataUrl: canvas.toDataURL('image/png'),\n width: viewport.width,\n height: viewport.height,\n textContent\n };\n}\n"],"mappings":"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","names":["error","pdfCoord","scaleX","scaleY"]}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
interface SemiontFaviconProps {
|
|
2
|
-
size?: number;
|
|
3
|
-
className?: string;
|
|
4
|
-
variant?: 'gradient' | 'solid' | 'outline';
|
|
5
|
-
background?: boolean;
|
|
6
|
-
}
|
|
7
|
-
export declare function SemiontFavicon({ size, className, variant, background }: SemiontFaviconProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
-
export {};
|
|
9
|
-
//# sourceMappingURL=SemiontFavicon.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SemiontFavicon.d.ts","sourceRoot":"","sources":["../../../src/assets/favicons/SemiontFavicon.tsx"],"names":[],"mappings":"AAAA,UAAU,mBAAmB;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;IAC3C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,cAAc,CAAC,EAC7B,IAAS,EACT,SAAc,EACd,OAAoB,EACpB,UAAiB,EAClB,EAAE,mBAAmB,2CAkDrB"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export declare const faviconPaths: {
|
|
2
|
-
readonly ico: "/favicons/favicon.ico";
|
|
3
|
-
readonly svg: "/favicons/favicon.svg";
|
|
4
|
-
readonly appleTouchIcon: "/favicons/apple-touch-icon.png";
|
|
5
|
-
readonly favicon32: "/favicons/favicon-32x32.png";
|
|
6
|
-
readonly favicon16: "/favicons/favicon-16x16.png";
|
|
7
|
-
readonly androidChrome192: "/favicons/android-chrome-192x192.png";
|
|
8
|
-
readonly androidChrome512: "/favicons/android-chrome-512x512.png";
|
|
9
|
-
readonly manifest: "/favicons/site.webmanifest";
|
|
10
|
-
};
|
|
11
|
-
export { SemiontFavicon } from './SemiontFavicon';
|
|
12
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/assets/favicons/index.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY;;;;;;;;;CASf,CAAC;AAGX,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { components } from '@semiont/core';
|
|
2
|
-
type Motivation = components['schemas']['Motivation'];
|
|
3
|
-
type JobProgress = components['schemas']['JobProgress'];
|
|
4
|
-
interface AnnotateReferencesProgressWidgetProps {
|
|
5
|
-
progress: JobProgress | null;
|
|
6
|
-
annotationType?: Motivation | 'reference';
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Widget for displaying reference annotation progress with cancel functionality
|
|
10
|
-
*
|
|
11
|
-
* @emits job:cancel-requested - User requested to cancel annotation job. Payload: { jobType: string }
|
|
12
|
-
*/
|
|
13
|
-
export declare function AnnotateReferencesProgressWidget({ progress, annotationType }: AnnotateReferencesProgressWidgetProps): import("react/jsx-runtime").JSX.Element | null;
|
|
14
|
-
export {};
|
|
15
|
-
//# sourceMappingURL=AnnotateReferencesProgressWidget.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnnotateReferencesProgressWidget.d.ts","sourceRoot":"","sources":["../../src/components/AnnotateReferencesProgressWidget.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,KAAK,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC;AACtD,KAAK,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,CAAC;AAExD,UAAU,qCAAqC;IAC7C,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,cAAc,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;CAC3C;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAAC,EAAE,QAAQ,EAAE,cAA4B,EAAE,EAAE,qCAAqC,kDAqFjI"}
|