@semiont/react-ui 0.4.7 → 0.4.10

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.
Files changed (190) hide show
  1. package/dist/{PdfAnnotationCanvas.client-LF6DDTCV.mjs → PdfAnnotationCanvas.client-CW6SKH2U.mjs} +7 -25
  2. package/dist/PdfAnnotationCanvas.client-CW6SKH2U.mjs.map +1 -0
  3. package/dist/{EventBusContext-DUIMowqQ.d.mts → TranslationManager-CudgH3gw.d.mts} +1 -74
  4. package/dist/{ar-3URRW77J.mjs → ar-R4CRNXEF.mjs} +3 -2
  5. package/dist/ar-R4CRNXEF.mjs.map +1 -0
  6. package/dist/{bn-DCQD3XZ5.mjs → bn-CZKGRHTA.mjs} +3 -2
  7. package/dist/bn-CZKGRHTA.mjs.map +1 -0
  8. package/dist/{chunk-XMCUHQ2Y.mjs → chunk-BQJWOK4C.mjs} +15 -34
  9. package/dist/chunk-BQJWOK4C.mjs.map +1 -0
  10. package/dist/{chunk-5JZFKRLW.mjs → chunk-HNZOXH4L.mjs} +33 -35
  11. package/dist/chunk-HNZOXH4L.mjs.map +1 -0
  12. package/dist/{chunk-PWIVZQ4X.mjs → chunk-HVMAGUFA.mjs} +3 -2
  13. package/dist/chunk-HVMAGUFA.mjs.map +1 -0
  14. package/dist/{chunk-4RMWYJUJ.mjs → chunk-OL5UST25.mjs} +31 -31
  15. package/dist/{cs-23KOZUFE.mjs → cs-4WIB2IHH.mjs} +3 -2
  16. package/dist/cs-4WIB2IHH.mjs.map +1 -0
  17. package/dist/{da-OIQ66A42.mjs → da-JWYEUYPX.mjs} +3 -2
  18. package/dist/da-JWYEUYPX.mjs.map +1 -0
  19. package/dist/{de-FCCLKE2X.mjs → de-GWUQZGER.mjs} +3 -2
  20. package/dist/de-GWUQZGER.mjs.map +1 -0
  21. package/dist/{el-3ADITCGI.mjs → el-DM2GT7P5.mjs} +3 -2
  22. package/dist/el-DM2GT7P5.mjs.map +1 -0
  23. package/dist/{en-LNW2A3RA.mjs → en-IUV4ZXKH.mjs} +2 -2
  24. package/dist/{es-POQEEYIW.mjs → es-6LVQIM3D.mjs} +3 -2
  25. package/dist/es-6LVQIM3D.mjs.map +1 -0
  26. package/dist/{fa-RQPXVELG.mjs → fa-IRUJY3QI.mjs} +3 -2
  27. package/dist/fa-IRUJY3QI.mjs.map +1 -0
  28. package/dist/{fi-UXOVOUGT.mjs → fi-53FBOEVT.mjs} +3 -2
  29. package/dist/fi-53FBOEVT.mjs.map +1 -0
  30. package/dist/{fr-6W2T3R7G.mjs → fr-Q5KY7QL6.mjs} +3 -2
  31. package/dist/fr-Q5KY7QL6.mjs.map +1 -0
  32. package/dist/{he-65UHPZIU.mjs → he-HJNKULBY.mjs} +3 -2
  33. package/dist/he-HJNKULBY.mjs.map +1 -0
  34. package/dist/{hi-SGJIVPTN.mjs → hi-UYZ4X6CR.mjs} +3 -2
  35. package/dist/hi-UYZ4X6CR.mjs.map +1 -0
  36. package/dist/{id-EYJJQCS2.mjs → id-UAQMH6U2.mjs} +3 -2
  37. package/dist/id-UAQMH6U2.mjs.map +1 -0
  38. package/dist/index.css +48 -0
  39. package/dist/index.css.map +1 -1
  40. package/dist/index.d.mts +176 -125
  41. package/dist/index.mjs +556 -781
  42. package/dist/index.mjs.map +1 -1
  43. package/dist/{it-IZGQEDO7.mjs → it-C7QEBNFA.mjs} +3 -2
  44. package/dist/it-C7QEBNFA.mjs.map +1 -0
  45. package/dist/{ja-SR272JSY.mjs → ja-THS6AOSJ.mjs} +3 -2
  46. package/dist/ja-THS6AOSJ.mjs.map +1 -0
  47. package/dist/{ko-YWTXVVXE.mjs → ko-XKK3TWQG.mjs} +3 -2
  48. package/dist/ko-XKK3TWQG.mjs.map +1 -0
  49. package/dist/{ms-3K2XSJGM.mjs → ms-GSK7LIF7.mjs} +3 -2
  50. package/dist/ms-GSK7LIF7.mjs.map +1 -0
  51. package/dist/{nl-YIGP4SLE.mjs → nl-KUBWITGY.mjs} +3 -2
  52. package/dist/nl-KUBWITGY.mjs.map +1 -0
  53. package/dist/{no-IFYIL3ND.mjs → no-ECWZUHT6.mjs} +3 -2
  54. package/dist/no-ECWZUHT6.mjs.map +1 -0
  55. package/dist/{pl-6MWSASJR.mjs → pl-PLVWSZWS.mjs} +3 -2
  56. package/dist/pl-PLVWSZWS.mjs.map +1 -0
  57. package/dist/{pt-NZNN6WUN.mjs → pt-AL74ZTKB.mjs} +3 -2
  58. package/dist/pt-AL74ZTKB.mjs.map +1 -0
  59. package/dist/{ro-NF3SMUJS.mjs → ro-WTPHLHGS.mjs} +3 -2
  60. package/dist/ro-WTPHLHGS.mjs.map +1 -0
  61. package/dist/{sv-ZHM7GSTD.mjs → sv-QCLI7SG4.mjs} +3 -2
  62. package/dist/sv-QCLI7SG4.mjs.map +1 -0
  63. package/dist/test-utils.d.mts +1 -4
  64. package/dist/test-utils.mjs +4 -6
  65. package/dist/test-utils.mjs.map +1 -1
  66. package/dist/{th-LX4NO5BJ.mjs → th-WCKVZU6U.mjs} +3 -2
  67. package/dist/th-WCKVZU6U.mjs.map +1 -0
  68. package/dist/{tr-DZ4GDSRR.mjs → tr-2CAFS2XS.mjs} +3 -2
  69. package/dist/tr-2CAFS2XS.mjs.map +1 -0
  70. package/dist/{uk-KC5KVVBY.mjs → uk-TDE4JLCY.mjs} +3 -2
  71. package/dist/uk-TDE4JLCY.mjs.map +1 -0
  72. package/dist/{vi-KNCR3OXZ.mjs → vi-KKXZ4PCX.mjs} +3 -2
  73. package/dist/vi-KKXZ4PCX.mjs.map +1 -0
  74. package/dist/{zh-M2HV2A27.mjs → zh-VH4XN5PV.mjs} +3 -2
  75. package/dist/zh-VH4XN5PV.mjs.map +1 -0
  76. package/package.json +1 -1
  77. package/src/components/Toolbar.tsx +15 -0
  78. package/src/components/__tests__/AnnotateReferencesProgressWidget.test.tsx +2 -6
  79. package/src/components/__tests__/Toolbar.test.tsx +2 -6
  80. package/src/components/annotation/__tests__/AnnotateToolbar.test.tsx +1 -2
  81. package/src/components/image-annotation/SvgDrawingCanvas.tsx +4 -7
  82. package/src/components/modals/ConfigureGenerationStep.tsx +54 -60
  83. package/src/components/modals/ReferenceWizardModal.tsx +3 -3
  84. package/src/components/navigation/__tests__/ObservableLink.test.tsx +2 -6
  85. package/src/components/navigation/__tests__/SimpleNavigation.test.tsx +2 -6
  86. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +3 -9
  87. package/src/components/resource/AnnotateView.tsx +4 -5
  88. package/src/components/resource/AnnotationHistory.tsx +2 -5
  89. package/src/components/resource/BrowseView.tsx +2 -3
  90. package/src/components/resource/HistoryEvent.tsx +3 -3
  91. package/src/components/resource/__tests__/BrowseView.test.tsx +1 -2
  92. package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +8 -8
  93. package/src/components/resource/event-formatting.ts +22 -19
  94. package/src/components/resource/panels/__tests__/AssessmentEntry.test.tsx +1 -2
  95. package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +1 -2
  96. package/src/components/resource/panels/__tests__/AssistSection.test.tsx +0 -2
  97. package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +1 -2
  98. package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +1 -2
  99. package/src/components/resource/panels/__tests__/HighlightEntry.test.tsx +1 -2
  100. package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +0 -2
  101. package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +1 -2
  102. package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +1 -2
  103. package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +1 -2
  104. package/src/components/resource/panels/__tests__/TagEntry.test.tsx +1 -2
  105. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +1 -2
  106. package/src/components/settings/__tests__/SettingsPanel.test.tsx +1 -2
  107. package/src/components/viewers/ImageViewer.tsx +2 -8
  108. package/src/components/viewers/__tests__/ImageViewer.test.tsx +3 -16
  109. package/src/features/auth/__tests__/SignInForm.a11y.test.tsx +8 -0
  110. package/src/features/auth/auth.css +62 -0
  111. package/src/features/auth/components/SignInForm.tsx +139 -29
  112. package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +2 -6
  113. package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +1 -2
  114. package/src/features/resource-viewer/__tests__/AnnotationCreationPending.test.tsx +1 -2
  115. package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +1 -2
  116. package/src/features/resource-viewer/__tests__/AnnotationProgressDismissal.test.tsx +1 -2
  117. package/src/features/resource-viewer/__tests__/BindFlowIntegration.test.tsx +1 -2
  118. package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +1 -2
  119. package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +1 -2
  120. package/src/features/resource-viewer/__tests__/ResourceMutations.test.tsx +9 -10
  121. package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +9 -6
  122. package/src/features/resource-viewer/__tests__/ToastNotifications.test.tsx +2 -12
  123. package/src/features/resource-viewer/__tests__/YieldFlowIntegration.test.tsx +1 -2
  124. package/src/features/resource-viewer/__tests__/annotation-progress-flow.test.tsx +16 -6
  125. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +45 -75
  126. package/src/styles/core/forms.css +32 -0
  127. package/src/styles/core/sliders.css +5 -0
  128. package/translations/ar.json +3 -2
  129. package/translations/bn.json +3 -2
  130. package/translations/cs.json +3 -2
  131. package/translations/da.json +3 -2
  132. package/translations/de.json +3 -2
  133. package/translations/el.json +3 -2
  134. package/translations/en.json +4 -3
  135. package/translations/es.json +3 -2
  136. package/translations/fa.json +3 -2
  137. package/translations/fi.json +3 -2
  138. package/translations/fr.json +3 -2
  139. package/translations/he.json +3 -2
  140. package/translations/hi.json +3 -2
  141. package/translations/id.json +3 -2
  142. package/translations/it.json +3 -2
  143. package/translations/ja.json +3 -2
  144. package/translations/ko.json +3 -2
  145. package/translations/ms.json +3 -2
  146. package/translations/nl.json +3 -2
  147. package/translations/no.json +3 -2
  148. package/translations/pl.json +3 -2
  149. package/translations/pt.json +3 -2
  150. package/translations/ro.json +3 -2
  151. package/translations/sv.json +3 -2
  152. package/translations/th.json +3 -2
  153. package/translations/tr.json +3 -2
  154. package/translations/uk.json +3 -2
  155. package/translations/vi.json +3 -2
  156. package/translations/zh.json +3 -2
  157. package/dist/PdfAnnotationCanvas.client-LF6DDTCV.mjs.map +0 -1
  158. package/dist/ar-3URRW77J.mjs.map +0 -1
  159. package/dist/bn-DCQD3XZ5.mjs.map +0 -1
  160. package/dist/chunk-5JZFKRLW.mjs.map +0 -1
  161. package/dist/chunk-PWIVZQ4X.mjs.map +0 -1
  162. package/dist/chunk-XMCUHQ2Y.mjs.map +0 -1
  163. package/dist/cs-23KOZUFE.mjs.map +0 -1
  164. package/dist/da-OIQ66A42.mjs.map +0 -1
  165. package/dist/de-FCCLKE2X.mjs.map +0 -1
  166. package/dist/el-3ADITCGI.mjs.map +0 -1
  167. package/dist/es-POQEEYIW.mjs.map +0 -1
  168. package/dist/fa-RQPXVELG.mjs.map +0 -1
  169. package/dist/fi-UXOVOUGT.mjs.map +0 -1
  170. package/dist/fr-6W2T3R7G.mjs.map +0 -1
  171. package/dist/he-65UHPZIU.mjs.map +0 -1
  172. package/dist/hi-SGJIVPTN.mjs.map +0 -1
  173. package/dist/id-EYJJQCS2.mjs.map +0 -1
  174. package/dist/it-IZGQEDO7.mjs.map +0 -1
  175. package/dist/ja-SR272JSY.mjs.map +0 -1
  176. package/dist/ko-YWTXVVXE.mjs.map +0 -1
  177. package/dist/ms-3K2XSJGM.mjs.map +0 -1
  178. package/dist/nl-YIGP4SLE.mjs.map +0 -1
  179. package/dist/no-IFYIL3ND.mjs.map +0 -1
  180. package/dist/pl-6MWSASJR.mjs.map +0 -1
  181. package/dist/pt-NZNN6WUN.mjs.map +0 -1
  182. package/dist/ro-NF3SMUJS.mjs.map +0 -1
  183. package/dist/sv-ZHM7GSTD.mjs.map +0 -1
  184. package/dist/th-LX4NO5BJ.mjs.map +0 -1
  185. package/dist/tr-DZ4GDSRR.mjs.map +0 -1
  186. package/dist/uk-KC5KVVBY.mjs.map +0 -1
  187. package/dist/vi-KNCR3OXZ.mjs.map +0 -1
  188. package/dist/zh-M2HV2A27.mjs.map +0 -1
  189. /package/dist/{chunk-4RMWYJUJ.mjs.map → chunk-OL5UST25.mjs.map} +0 -0
  190. /package/dist/{en-LNW2A3RA.mjs.map → en-IUV4ZXKH.mjs.map} +0 -0
package/dist/index.mjs CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  useEventSubscription,
10
10
  useEventSubscriptions,
11
11
  useHoverEmitter
12
- } from "./chunk-XMCUHQ2Y.mjs";
12
+ } from "./chunk-BQJWOK4C.mjs";
13
13
  import {
14
14
  AVAILABLE_LOCALES,
15
15
  OpenResourcesProvider,
@@ -22,15 +22,14 @@ import {
22
22
  useSessionContext,
23
23
  useToast,
24
24
  useTranslations
25
- } from "./chunk-4RMWYJUJ.mjs";
25
+ } from "./chunk-OL5UST25.mjs";
26
26
  import {
27
27
  ApiClientProvider,
28
28
  EventBusProvider,
29
- resetEventBusForTesting,
30
29
  useApiClient,
31
30
  useEventBus
32
- } from "./chunk-5JZFKRLW.mjs";
33
- import "./chunk-PWIVZQ4X.mjs";
31
+ } from "./chunk-HNZOXH4L.mjs";
32
+ import "./chunk-HVMAGUFA.mjs";
34
33
  import {
35
34
  __commonJS,
36
35
  __export,
@@ -541,7 +540,9 @@ import {
541
540
  cloneToken,
542
541
  entityType,
543
542
  userDID,
544
- accessToken
543
+ accessToken,
544
+ resourceId as resourceIdBrand,
545
+ annotationId as annotationIdBrand
545
546
  } from "@semiont/core";
546
547
  import { decodeWithCharset } from "@semiont/api-client";
547
548
 
@@ -560,11 +561,12 @@ var QUERY_KEYS = {
560
561
  events: (id2) => ["resources", id2, "events"],
561
562
  annotations: (id2) => ["resources", id2, "annotations"],
562
563
  referencedBy: (id2) => ["resources", id2, "referenced-by"],
563
- representation: (id2) => ["resources", id2, "representation"]
564
+ representation: (id2) => ["resources", id2, "representation"],
565
+ mediaToken: (id2) => ["resources", id2, "media-token"]
564
566
  },
565
567
  annotations: {
566
568
  detail: (id2) => ["annotations", id2],
567
- history: (resourceId2, annotationId4) => ["annotations", resourceId2, annotationId4, "history"]
569
+ history: (resourceId2, annotationId3) => ["annotations", resourceId2, annotationId3, "history"]
568
570
  },
569
571
  entityTypes: {
570
572
  all: () => ["entity-types"]
@@ -586,8 +588,8 @@ function toAccessToken(token) {
586
588
  }
587
589
  function useResources() {
588
590
  const client = useApiClient();
589
- const queryClient = useQueryClient();
590
591
  const token = useAuthToken();
592
+ const eventBus = useEventBus();
591
593
  return {
592
594
  list: {
593
595
  useQuery: (options) => useQuery({
@@ -638,6 +640,14 @@ function useResources() {
638
640
  enabled: !!client && !!id2 && !!mediaType
639
641
  })
640
642
  },
643
+ mediaToken: {
644
+ useQuery: (id2) => useQuery({
645
+ queryKey: QUERY_KEYS.resources.mediaToken(id2),
646
+ queryFn: () => client.getMediaToken(id2, { auth: toAccessToken(token) }),
647
+ enabled: !!client && !!id2,
648
+ staleTime: 4 * 60 * 1e3
649
+ })
650
+ },
641
651
  search: {
642
652
  useQuery: (query, limit) => useQuery({
643
653
  queryKey: QUERY_KEYS.resources.search(query, limit),
@@ -655,8 +665,9 @@ function useResources() {
655
665
  }
656
666
  return client.yieldResource(data2, { auth: toAccessToken(token2) });
657
667
  },
658
- onSuccess: () => {
659
- queryClient.invalidateQueries({ queryKey: ["documents"] });
668
+ onSuccess: (result) => {
669
+ client.stores.resources.invalidateDetail(resourceIdBrand(result.resourceId));
670
+ client.stores.resources.invalidateLists();
660
671
  }
661
672
  });
662
673
  }
@@ -670,8 +681,7 @@ function useResources() {
670
681
  return client.updateResource(id2, data2, { auth: toAccessToken(token2) });
671
682
  },
672
683
  onSuccess: (_data, variables) => {
673
- queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.detail(variables.id) });
674
- queryClient.invalidateQueries({ queryKey: ["documents"] });
684
+ eventBus.get("yield:updated").next({ resourceId: variables.id });
675
685
  }
676
686
  });
677
687
  }
@@ -705,8 +715,9 @@ function useResources() {
705
715
  if (!client) throw new Error("Not authenticated");
706
716
  return client.createResourceFromToken(data2, { auth: toAccessToken(token2) });
707
717
  },
708
- onSuccess: () => {
709
- queryClient.invalidateQueries({ queryKey: ["documents"] });
718
+ onSuccess: (result) => {
719
+ client.stores.resources.invalidateDetail(resourceIdBrand(result.resourceId));
720
+ client.stores.resources.invalidateLists();
710
721
  }
711
722
  });
712
723
  }
@@ -726,17 +737,17 @@ function useAnnotations() {
726
737
  })
727
738
  },
728
739
  browseAnnotation: {
729
- useQuery: (resourceId2, annotationId4) => useQuery({
730
- queryKey: ["annotations", resourceId2, annotationId4],
731
- queryFn: () => client.browseAnnotation(resourceId2, annotationId4, { auth: toAccessToken(token) }),
732
- enabled: !!client && !!resourceId2 && !!annotationId4
740
+ useQuery: (resourceId2, annotationId3) => useQuery({
741
+ queryKey: ["annotations", resourceId2, annotationId3],
742
+ queryFn: () => client.browseAnnotation(resourceId2, annotationId3, { auth: toAccessToken(token) }),
743
+ enabled: !!client && !!resourceId2 && !!annotationId3
733
744
  })
734
745
  },
735
746
  history: {
736
- useQuery: (resourceId2, annotationId4) => useQuery({
737
- queryKey: QUERY_KEYS.annotations.history(resourceId2, annotationId4),
738
- queryFn: () => client.getAnnotationHistory(resourceId2, annotationId4, { auth: toAccessToken(token) }),
739
- enabled: !!client && !!resourceId2 && !!annotationId4
747
+ useQuery: (resourceId2, annotationId3) => useQuery({
748
+ queryKey: QUERY_KEYS.annotations.history(resourceId2, annotationId3),
749
+ queryFn: () => client.getAnnotationHistory(resourceId2, annotationId3, { auth: toAccessToken(token) }),
750
+ enabled: !!client && !!resourceId2 && !!annotationId3
740
751
  })
741
752
  },
742
753
  create: {
@@ -750,8 +761,8 @@ function useAnnotations() {
750
761
  if (!client) throw new Error("Not authenticated");
751
762
  return client.markAnnotation(resourceId2, data2, { auth: toAccessToken(token2) });
752
763
  },
753
- onSuccess: (_4, variables) => {
754
- queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.annotations(variables.resourceId) });
764
+ onSuccess: (result, variables) => {
765
+ client.stores.annotations.invalidateDetail(annotationIdBrand(result.annotationId));
755
766
  queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.events(variables.resourceId) });
756
767
  }
757
768
  });
@@ -766,18 +777,8 @@ function useAnnotations() {
766
777
  return client.deleteAnnotation(variables.resourceId, variables.annotationId, { auth: toAccessToken(token2) });
767
778
  },
768
779
  onSuccess: (_4, variables) => {
769
- const queryKey = QUERY_KEYS.resources.annotations(variables.resourceId);
770
- const currentData = queryClient.getQueryData(queryKey);
771
- if (currentData) {
772
- queryClient.setQueryData(queryKey, {
773
- ...currentData,
774
- annotations: currentData.annotations.filter((ann) => ann.id !== variables.annotationId)
775
- });
776
- } else {
777
- queryClient.invalidateQueries({ queryKey });
778
- }
780
+ client.stores.annotations.invalidateDetail(variables.annotationId);
779
781
  queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.events(variables.resourceId) });
780
- queryClient.invalidateQueries({ queryKey: ["annotations", variables.annotationId] });
781
782
  }
782
783
  });
783
784
  }
@@ -788,15 +789,15 @@ function useAnnotations() {
788
789
  return useMutation({
789
790
  mutationFn: ({
790
791
  resourceId: resourceId2,
791
- annotationId: annotationId4,
792
+ annotationId: annotationId3,
792
793
  data: data2
793
794
  }) => {
794
795
  if (!client) throw new Error("Not authenticated");
795
- return client.bindAnnotation(resourceId2, annotationId4, data2, { auth: toAccessToken(token2) });
796
+ return client.bindAnnotation(resourceId2, annotationId3, data2, { auth: toAccessToken(token2) });
796
797
  },
797
798
  onSuccess: (_4, variables) => {
798
- queryClient.invalidateQueries({ queryKey: ["annotations", variables.annotationId] });
799
- queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.annotations(variables.resourceId) });
799
+ client.stores.annotations.invalidateDetail(variables.annotationId);
800
+ queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.events(variables.resourceId) });
800
801
  if (variables.data.operations) {
801
802
  for (const op of variables.data.operations) {
802
803
  if (op.op === "add" && op.item && typeof op.item === "object") {
@@ -809,7 +810,6 @@ function useAnnotations() {
809
810
  }
810
811
  }
811
812
  }
812
- queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.events(variables.resourceId) });
813
813
  }
814
814
  });
815
815
  }
@@ -18274,10 +18274,7 @@ function useResourceEvents({
18274
18274
  const [status, setStatus] = useState5("disconnected");
18275
18275
  const [lastEvent, setLastEvent] = useState5(null);
18276
18276
  const [eventCount, setEventCount] = useState5(0);
18277
- const streamRef = useRef4(null);
18278
- const reconnectTimeoutRef = useRef4(null);
18279
- const reconnectAttemptsRef = useRef4(0);
18280
- const connectingRef = useRef4(false);
18277
+ const tokenRef = useRef4(token);
18281
18278
  const onEventRef = useRef4(onEvent);
18282
18279
  const onAnnotationAddedRef = useRef4(onAnnotationAdded);
18283
18280
  const onAnnotationRemovedRef = useRef4(onAnnotationRemoved);
@@ -18288,6 +18285,7 @@ function useResourceEvents({
18288
18285
  const onDocumentUnarchivedRef = useRef4(onDocumentUnarchived);
18289
18286
  const onErrorRef = useRef4(onError);
18290
18287
  useEffect4(() => {
18288
+ tokenRef.current = token;
18291
18289
  onEventRef.current = onEvent;
18292
18290
  onAnnotationAddedRef.current = onAnnotationAdded;
18293
18291
  onAnnotationRemovedRef.current = onAnnotationRemoved;
@@ -18332,62 +18330,36 @@ function useResourceEvents({
18332
18330
  });
18333
18331
  return () => subscription.unsubscribe();
18334
18332
  }, [eventBus, handleEvent]);
18335
- const connect = useCallback6(async () => {
18336
- if (connectingRef.current || streamRef.current) {
18337
- return;
18338
- }
18339
- connectingRef.current = true;
18340
- if (reconnectTimeoutRef.current) {
18341
- clearTimeout(reconnectTimeoutRef.current);
18342
- reconnectTimeoutRef.current = null;
18343
- }
18344
- if (!client) {
18345
- console.error(`[ResourceEvents] Cannot connect to ${rUri}: No API client available`);
18346
- onErrorRef.current?.("Authentication required");
18347
- setStatus("error");
18348
- connectingRef.current = false;
18349
- return;
18350
- }
18333
+ const subRef = useRef4(null);
18334
+ const connect = useCallback6(() => {
18335
+ if (subRef.current) return;
18351
18336
  setStatus("connecting");
18352
18337
  try {
18353
- const sseOptions = {
18354
- ...token ? { auth: accessToken2(token) } : {},
18355
- eventBus
18356
- // ← Stream auto-emits to EventBus
18357
- };
18358
- const stream = client.sse.resourceEvents(rUri, sseOptions);
18359
- streamRef.current = stream;
18338
+ const sub = client.flows.resourceEvents(
18339
+ rUri,
18340
+ () => tokenRef.current ? accessToken2(tokenRef.current) : void 0
18341
+ );
18342
+ subRef.current = sub;
18360
18343
  setStatus("connected");
18361
- reconnectAttemptsRef.current = 0;
18362
- connectingRef.current = false;
18363
18344
  } catch (error) {
18364
18345
  console.error("[ResourceEvents] Failed to connect:", error);
18365
18346
  setStatus("error");
18366
18347
  onErrorRef.current?.("Failed to connect to event stream");
18367
- connectingRef.current = false;
18368
18348
  }
18369
- }, [rUri, client, token, eventBus]);
18349
+ }, [rUri, client]);
18370
18350
  const disconnect = useCallback6(() => {
18371
- if (streamRef.current) {
18372
- streamRef.current.close();
18373
- streamRef.current = null;
18374
- }
18375
- if (reconnectTimeoutRef.current) {
18376
- clearTimeout(reconnectTimeoutRef.current);
18377
- reconnectTimeoutRef.current = null;
18351
+ if (subRef.current) {
18352
+ subRef.current.unsubscribe();
18353
+ subRef.current = null;
18378
18354
  }
18379
18355
  setStatus("disconnected");
18380
- reconnectAttemptsRef.current = 0;
18381
- connectingRef.current = false;
18382
18356
  }, []);
18383
18357
  useEffect4(() => {
18384
- if (autoConnect && client) {
18358
+ if (autoConnect) {
18385
18359
  connect();
18386
18360
  }
18387
- return () => {
18388
- disconnect();
18389
- };
18390
- }, [autoConnect, client]);
18361
+ return () => disconnect();
18362
+ }, [autoConnect, rUri, client]);
18391
18363
  return {
18392
18364
  status,
18393
18365
  lastEvent,
@@ -18757,10 +18729,10 @@ function useLocalStorage(key, initialValue) {
18757
18729
  // src/hooks/useResourceContent.ts
18758
18730
  import { useEffect as useEffect10 } from "react";
18759
18731
  import { getPrimaryMediaType } from "@semiont/api-client";
18760
- function useResourceContent(rUri, resource) {
18732
+ function useResourceContent(rUri, resource, enabled = true) {
18761
18733
  const { showError } = useToast();
18762
18734
  const resources = useResources();
18763
- const mediaType = getPrimaryMediaType(resource) || "text/plain";
18735
+ const mediaType = enabled ? getPrimaryMediaType(resource) || "text/plain" : "";
18764
18736
  const { data: data2, isLoading, error } = resources.representation.useQuery(rUri, mediaType);
18765
18737
  useEffect10(() => {
18766
18738
  if (error) {
@@ -19011,12 +18983,12 @@ function ResourceAnnotationsProvider({ children }) {
19011
18983
  return next;
19012
18984
  });
19013
18985
  }, []);
19014
- const triggerSparkleAnimation = useCallback11((annotationId4) => {
19015
- setNewAnnotationIds((prev) => new Set(prev).add(annotationId4));
18986
+ const triggerSparkleAnimation = useCallback11((annotationId3) => {
18987
+ setNewAnnotationIds((prev) => new Set(prev).add(annotationId3));
19016
18988
  setTimeout(() => {
19017
18989
  setNewAnnotationIds((prev) => {
19018
18990
  const next = new Set(prev);
19019
- next.delete(annotationId4);
18991
+ next.delete(annotationId3);
19020
18992
  return next;
19021
18993
  });
19022
18994
  }, 6e3);
@@ -26376,11 +26348,11 @@ var pasteURLAsLink = /* @__PURE__ */ EditorView.domEventHandlers({
26376
26348
  });
26377
26349
 
26378
26350
  // src/lib/scroll-utils.ts
26379
- function scrollAnnotationIntoView(annotationId4, rootElement, options = {}) {
26380
- if (!annotationId4) return false;
26351
+ function scrollAnnotationIntoView(annotationId3, rootElement, options = {}) {
26352
+ if (!annotationId3) return false;
26381
26353
  const { pulse = false, behavior = "smooth" } = options;
26382
26354
  const element2 = rootElement.querySelector(
26383
- `[data-annotation-id="${CSS.escape(annotationId4)}"]`
26355
+ `[data-annotation-id="${CSS.escape(annotationId3)}"]`
26384
26356
  );
26385
26357
  if (!element2) return false;
26386
26358
  const scrollContainer = element2.closest(".semiont-browse-view__content") || element2.closest(".semiont-annotate-view__content") || element2.closest(".semiont-document-viewer__scrollable-body");
@@ -26509,12 +26481,12 @@ function computeWidgetDecorations(segments, generatingReferenceId, getTargetReso
26509
26481
  // src/lib/codemirror-handlers.ts
26510
26482
  function handleAnnotationClick(target, segmentsById, eventBus) {
26511
26483
  const annotationElement = target.closest("[data-annotation-id]");
26512
- const annotationId4 = annotationElement?.getAttribute("data-annotation-id");
26513
- if (!annotationId4) return false;
26514
- const segment = segmentsById.get(annotationId4);
26484
+ const annotationId3 = annotationElement?.getAttribute("data-annotation-id");
26485
+ if (!annotationId3) return false;
26486
+ const segment = segmentsById.get(annotationId3);
26515
26487
  if (!segment?.annotation) return false;
26516
26488
  eventBus.get("browse:click").next({
26517
- annotationId: annotationId4,
26489
+ annotationId: annotationId3,
26518
26490
  motivation: segment.annotation.motivation
26519
26491
  });
26520
26492
  return true;
@@ -26524,22 +26496,22 @@ function handleWidgetClick(target) {
26524
26496
  if (!widget || widget.dataset.widgetGenerating === "true") {
26525
26497
  return { handled: false };
26526
26498
  }
26527
- const annotationId4 = widget.dataset.widgetAnnotationId;
26499
+ const annotationId3 = widget.dataset.widgetAnnotationId;
26528
26500
  const bodySource = widget.dataset.widgetBodySource;
26529
26501
  const isResolved = widget.dataset.widgetResolved === "true";
26530
- if (!annotationId4) return { handled: false };
26502
+ if (!annotationId3) return { handled: false };
26531
26503
  if (isResolved && bodySource) {
26532
26504
  return {
26533
26505
  handled: true,
26534
26506
  action: "navigate",
26535
26507
  resourceId: bodySource,
26536
- annotationId: annotationId4
26508
+ annotationId: annotationId3
26537
26509
  };
26538
26510
  }
26539
26511
  return {
26540
26512
  handled: true,
26541
26513
  action: "browse-click",
26542
- annotationId: annotationId4,
26514
+ annotationId: annotationId3,
26543
26515
  motivation: widget.dataset.widgetMotivation || "linking"
26544
26516
  };
26545
26517
  }
@@ -26775,14 +26747,14 @@ function CodeMirrorRenderer({
26775
26747
  containerRef.current.__cmView = view;
26776
26748
  const container = view.dom;
26777
26749
  const { handleMouseEnter, handleMouseLeave, cleanup: cleanupHover } = createHoverHandlers(
26778
- (annotationId4) => eventBusRef.current?.get("beckon:hover").next({ annotationId: annotationId4 }),
26750
+ (annotationId3) => eventBusRef.current?.get("beckon:hover").next({ annotationId: annotationId3 }),
26779
26751
  hoverDelayMs
26780
26752
  );
26781
26753
  const handleMouseOver = (e6) => {
26782
26754
  const target = e6.target;
26783
26755
  const annotationElement = target.closest("[data-annotation-id]");
26784
- const annotationId4 = annotationElement?.getAttribute("data-annotation-id");
26785
- if (annotationId4) handleMouseEnter(annotationId4);
26756
+ const annotationId3 = annotationElement?.getAttribute("data-annotation-id");
26757
+ if (annotationId3) handleMouseEnter(annotationId3);
26786
26758
  };
26787
26759
  const handleMouseOut = (e6) => {
26788
26760
  const target = e6.target;
@@ -27275,6 +27247,19 @@ function Toolbar({
27275
27247
  }
27276
27248
  )
27277
27249
  ] }),
27250
+ /* @__PURE__ */ jsx12(
27251
+ "button",
27252
+ {
27253
+ onClick: () => handlePanelToggle("knowledge-base"),
27254
+ className: "semiont-toolbar-button",
27255
+ "data-active": activePanel === "knowledge-base",
27256
+ "data-panel": "knowledge-base",
27257
+ "aria-label": t12("knowledgeBase"),
27258
+ "aria-pressed": activePanel === "knowledge-base",
27259
+ title: t12("knowledgeBase"),
27260
+ children: /* @__PURE__ */ jsx12("svg", { className: "semiont-toolbar-icon", "aria-hidden": "true", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 5.625c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125" }) })
27261
+ }
27262
+ ),
27278
27263
  /* @__PURE__ */ jsx12(
27279
27264
  "button",
27280
27265
  {
@@ -29666,7 +29651,7 @@ function AnnotationOverlay({
29666
29651
  const scaleX = displayWidth / imageWidth;
29667
29652
  const scaleY = displayHeight / imageHeight;
29668
29653
  const { handleMouseEnter, handleMouseLeave } = useMemo2(
29669
- () => createHoverHandlers((annotationId4) => eventBus?.get("beckon:hover").next({ annotationId: annotationId4 }), hoverDelayMs),
29654
+ () => createHoverHandlers((annotationId3) => eventBus?.get("beckon:hover").next({ annotationId: annotationId3 }), hoverDelayMs),
29670
29655
  [eventBus, hoverDelayMs]
29671
29656
  );
29672
29657
  return /* @__PURE__ */ jsx17(
@@ -29834,7 +29819,7 @@ function AnnotationOverlay({
29834
29819
  }
29835
29820
 
29836
29821
  // src/components/image-annotation/SvgDrawingCanvas.tsx
29837
- import { useRef as useRef12, useState as useState15, useEffect as useEffect17, useCallback as useCallback13, useMemo as useMemo3 } from "react";
29822
+ import { useRef as useRef12, useState as useState15, useEffect as useEffect17, useCallback as useCallback13 } from "react";
29838
29823
  import { createRectangleSvg, createCircleSvg, createPolygonSvg, scaleSvgToNative, parseSvgSelector as parseSvgSelector2 } from "@semiont/api-client";
29839
29824
  import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
29840
29825
  function getMotivationColor(motivation) {
@@ -29859,7 +29844,7 @@ function getMotivationColor(motivation) {
29859
29844
  }
29860
29845
  }
29861
29846
  function SvgDrawingCanvas({
29862
- resourceUri,
29847
+ imageUrl,
29863
29848
  existingAnnotations = [],
29864
29849
  drawingMode,
29865
29850
  selectedMotivation,
@@ -29868,9 +29853,6 @@ function SvgDrawingCanvas({
29868
29853
  selectedAnnotationId
29869
29854
  }) {
29870
29855
  const { hoverDelayMs } = useHoverDelay();
29871
- const imageUrl = useMemo3(() => {
29872
- return `/api/resources/${resourceUri}`;
29873
- }, [resourceUri]);
29874
29856
  const containerRef = useRef12(null);
29875
29857
  const imageRef = useRef12(null);
29876
29858
  const [imageDimensions, setImageDimensions] = useState15(null);
@@ -30444,7 +30426,6 @@ function ProposeEntitiesModal({
30444
30426
 
30445
30427
  // src/components/resource/AnnotateView.tsx
30446
30428
  import { useRef as useRef13, useEffect as useEffect19, useCallback as useCallback14, lazy, Suspense } from "react";
30447
- import { resourceId as toResourceId } from "@semiont/core";
30448
30429
  import { getMimeCategory, isPdfMimeType as isPdfMimeType2 } from "@semiont/api-client";
30449
30430
 
30450
30431
  // src/lib/text-segmentation.ts
@@ -30538,7 +30519,7 @@ function fallbackTextPosition(content4, selectedText) {
30538
30519
 
30539
30520
  // src/components/resource/AnnotateView.tsx
30540
30521
  import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
30541
- var PdfAnnotationCanvas = lazy(() => import("./PdfAnnotationCanvas.client-LF6DDTCV.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
30522
+ var PdfAnnotationCanvas = lazy(() => import("./PdfAnnotationCanvas.client-CW6SKH2U.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
30542
30523
  function AnnotateView({
30543
30524
  content: content4,
30544
30525
  mimeType = "text/plain",
@@ -30572,8 +30553,8 @@ function AnnotateView({
30572
30553
  const handleToolbarShapeChanged = useCallback14(({ shape }) => {
30573
30554
  onUIStateChangeRef.current?.({ selectedShape: shape });
30574
30555
  }, []);
30575
- const handleAnnotationHover = useCallback14(({ annotationId: annotationId4 }) => {
30576
- onUIStateChangeRef.current?.({ hoveredAnnotationId: annotationId4 });
30556
+ const handleAnnotationHover = useCallback14(({ annotationId: annotationId3 }) => {
30557
+ onUIStateChangeRef.current?.({ hoveredAnnotationId: annotationId3 });
30577
30558
  }, []);
30578
30559
  useEventSubscriptions({
30579
30560
  "mark:selection-changed": handleToolbarSelectionChanged,
@@ -30685,10 +30666,10 @@ function AnnotateView({
30685
30666
  annotators: ANNOTATORS
30686
30667
  }
30687
30668
  ),
30688
- /* @__PURE__ */ jsx21("div", { className: "semiont-annotate-view__content", children: resourceUri && /* @__PURE__ */ jsx21(Suspense, { fallback: /* @__PURE__ */ jsx21("div", { className: "semiont-annotate-view__loading", children: "Loading PDF viewer..." }), children: /* @__PURE__ */ jsx21(
30669
+ /* @__PURE__ */ jsx21("div", { className: "semiont-annotate-view__content", children: content4 && /* @__PURE__ */ jsx21(Suspense, { fallback: /* @__PURE__ */ jsx21("div", { className: "semiont-annotate-view__loading", children: "Loading PDF viewer..." }), children: /* @__PURE__ */ jsx21(
30689
30670
  PdfAnnotationCanvas,
30690
30671
  {
30691
- resourceUri: toResourceId(resourceUri),
30672
+ pdfUrl: content4,
30692
30673
  existingAnnotations: allAnnotations,
30693
30674
  drawingMode: selectedMotivation ? selectedShape : null,
30694
30675
  selectedMotivation,
@@ -30712,10 +30693,10 @@ function AnnotateView({
30712
30693
  annotators: ANNOTATORS
30713
30694
  }
30714
30695
  ),
30715
- /* @__PURE__ */ jsx21("div", { className: "semiont-annotate-view__content", children: resourceUri && /* @__PURE__ */ jsx21(
30696
+ /* @__PURE__ */ jsx21("div", { className: "semiont-annotate-view__content", children: content4 && /* @__PURE__ */ jsx21(
30716
30697
  SvgDrawingCanvas,
30717
30698
  {
30718
- resourceUri: toResourceId(resourceUri),
30699
+ imageUrl: content4,
30719
30700
  existingAnnotations: allAnnotations,
30720
30701
  drawingMode: selectedMotivation ? selectedShape : null,
30721
30702
  selectedMotivation,
@@ -30853,15 +30834,16 @@ function truncateText(text7, maxLength = 50) {
30853
30834
  }
30854
30835
  function getEventDisplayContent(event, annotations, allEvents) {
30855
30836
  const eventData = event.event;
30837
+ const payload = eventData.payload;
30856
30838
  switch (eventData.type) {
30857
30839
  case "resource.created":
30858
30840
  case "resource.cloned": {
30859
- return { exact: eventData.payload.name, isQuoted: false, isTag: false };
30841
+ return { exact: payload.name, isQuoted: false, isTag: false };
30860
30842
  }
30861
30843
  // Unified annotation events
30862
30844
  case "annotation.body.updated": {
30863
30845
  const annotation = annotations.find(
30864
- (a15) => a15.id.endsWith(`/annotations/${eventData.payload.annotationId}`)
30846
+ (a15) => a15.id.endsWith(`/annotations/${payload.annotationId}`)
30865
30847
  );
30866
30848
  if (annotation?.target) {
30867
30849
  try {
@@ -30877,7 +30859,7 @@ function getEventDisplayContent(event, annotations, allEvents) {
30877
30859
  }
30878
30860
  case "annotation.removed": {
30879
30861
  const addedEvent = allEvents.find(
30880
- (e6) => e6.event.type === "annotation.added" && e6.event.payload.annotation.id.endsWith(`/annotations/${eventData.payload.annotationId}`)
30862
+ (e6) => e6.event.type === "annotation.added" && e6.event.payload.annotation.id.endsWith(`/annotations/${payload.annotationId}`)
30881
30863
  );
30882
30864
  if (addedEvent && addedEvent.event.type === "annotation.added") {
30883
30865
  try {
@@ -30895,7 +30877,7 @@ function getEventDisplayContent(event, annotations, allEvents) {
30895
30877
  }
30896
30878
  case "annotation.added": {
30897
30879
  try {
30898
- const target = eventData.payload.annotation.target;
30880
+ const target = payload.annotation.target;
30899
30881
  if (typeof target !== "string" && target.selector) {
30900
30882
  const exact = getExactText2(target.selector);
30901
30883
  if (exact) {
@@ -30908,12 +30890,12 @@ function getEventDisplayContent(event, annotations, allEvents) {
30908
30890
  }
30909
30891
  case "entitytag.added":
30910
30892
  case "entitytag.removed": {
30911
- return { exact: eventData.payload.entityType, isQuoted: false, isTag: true };
30893
+ return { exact: payload.entityType, isQuoted: false, isTag: true };
30912
30894
  }
30913
30895
  case "job.completed": {
30914
- if (eventData.payload.annotationUri) {
30896
+ if (payload.annotationUri) {
30915
30897
  const annotation = annotations.find(
30916
- (a15) => a15.id === eventData.payload.annotationUri
30898
+ (a15) => a15.id === payload.annotationUri
30917
30899
  );
30918
30900
  if (annotation?.target) {
30919
30901
  try {
@@ -30940,9 +30922,10 @@ function getEventDisplayContent(event, annotations, allEvents) {
30940
30922
  }
30941
30923
  function getEventEntityTypes(event) {
30942
30924
  const eventData = event.event;
30925
+ const payload = eventData.payload;
30943
30926
  if (eventData.type === "annotation.added") {
30944
- const motivation = eventData.payload.annotation.motivation;
30945
- const body = eventData.payload.annotation.body;
30927
+ const motivation = payload.annotation.motivation;
30928
+ const body = payload.annotation.body;
30946
30929
  if (motivation === "linking" && body && "entityTypes" in body) {
30947
30930
  return body.entityTypes ?? [];
30948
30931
  }
@@ -30951,10 +30934,11 @@ function getEventEntityTypes(event) {
30951
30934
  }
30952
30935
  function getResourceCreationDetails(event) {
30953
30936
  const eventData = event.event;
30937
+ const payload = eventData.payload;
30954
30938
  if (eventData.type === "resource.created") {
30955
30939
  return {
30956
30940
  type: "created",
30957
- method: eventData.payload.creationMethod || "unknown",
30941
+ method: payload.creationMethod || "unknown",
30958
30942
  userId: eventData.userId,
30959
30943
  metadata: void 0
30960
30944
  };
@@ -30962,10 +30946,10 @@ function getResourceCreationDetails(event) {
30962
30946
  if (eventData.type === "resource.cloned") {
30963
30947
  return {
30964
30948
  type: "cloned",
30965
- method: eventData.payload.creationMethod || "clone",
30949
+ method: payload.creationMethod || "clone",
30966
30950
  userId: eventData.userId,
30967
- sourceDocId: eventData.payload.parentResourceId,
30968
- parentResourceId: eventData.payload.parentResourceId,
30951
+ sourceDocId: payload.parentResourceId,
30952
+ parentResourceId: payload.parentResourceId,
30969
30953
  metadata: void 0
30970
30954
  };
30971
30955
  }
@@ -31101,9 +31085,7 @@ function AnnotationHistory({ rUri, hoveredAnnotationId, onEventHover, onEventCli
31101
31085
  const events2 = !eventsData?.events ? [] : [...eventsData.events].filter((e6) => {
31102
31086
  const eventType = e6.event.type;
31103
31087
  return eventType !== "job.started" && eventType !== "job.progress" && eventType !== "job.completed";
31104
- }).sort(
31105
- (a15, b8) => a15.metadata.sequenceNumber - b8.metadata.sequenceNumber
31106
- );
31088
+ }).sort((a15, b8) => a15.metadata.sequenceNumber - b8.metadata.sequenceNumber);
31107
31089
  useEffect21(() => {
31108
31090
  if (containerRef.current && events2.length > 0) {
31109
31091
  requestAnimationFrame(() => {
@@ -31154,11 +31136,11 @@ function AnnotationHistory({ rUri, hoveredAnnotationId, onEventHover, onEventCli
31154
31136
  t: t12,
31155
31137
  Link,
31156
31138
  routes,
31157
- onEventRef: (annotationId4, el) => {
31158
- if (el && annotationId4) {
31159
- eventRefs.current.set(annotationId4, el);
31160
- } else if (!el && annotationId4) {
31161
- eventRefs.current.delete(annotationId4);
31139
+ onEventRef: (annotationId3, el) => {
31140
+ if (el && annotationId3) {
31141
+ eventRefs.current.set(annotationId3, el);
31142
+ } else if (!el && annotationId3) {
31143
+ eventRefs.current.delete(annotationId3);
31162
31144
  }
31163
31145
  },
31164
31146
  ...onEventClick && { onEventClick },
@@ -31171,7 +31153,7 @@ function AnnotationHistory({ rUri, hoveredAnnotationId, onEventHover, onEventCli
31171
31153
  }
31172
31154
 
31173
31155
  // src/components/resource/BrowseView.tsx
31174
- import { useEffect as useEffect23, useRef as useRef16, useCallback as useCallback16, useMemo as useMemo4, memo, lazy as lazy2, Suspense as Suspense2 } from "react";
31156
+ import { useEffect as useEffect23, useRef as useRef16, useCallback as useCallback16, useMemo as useMemo3, memo, lazy as lazy2, Suspense as Suspense2 } from "react";
31175
31157
 
31176
31158
  // ../../node_modules/devlop/lib/default.js
31177
31159
  function ok() {
@@ -45687,13 +45669,11 @@ function remarkGfm(options) {
45687
45669
  }
45688
45670
 
45689
45671
  // src/components/resource/BrowseView.tsx
45690
- import { resourceId as toResourceId2 } from "@semiont/core";
45691
45672
  import { getMimeCategory as getMimeCategory2, isPdfMimeType as isPdfMimeType3 } from "@semiont/api-client";
45692
45673
 
45693
45674
  // src/components/viewers/ImageViewer.tsx
45694
45675
  import { jsx as jsx25 } from "react/jsx-runtime";
45695
- function ImageViewer({ resourceUri, alt = "Resource image" }) {
45696
- const imageUrl = `/api/resources/${resourceUri}`;
45676
+ function ImageViewer({ imageUrl, alt = "Resource image" }) {
45697
45677
  return /* @__PURE__ */ jsx25("div", { className: "semiont-image-viewer", children: /* @__PURE__ */ jsx25(
45698
45678
  "img",
45699
45679
  {
@@ -45707,7 +45687,7 @@ function ImageViewer({ resourceUri, alt = "Resource image" }) {
45707
45687
 
45708
45688
  // src/components/resource/BrowseView.tsx
45709
45689
  import { jsx as jsx26, jsxs as jsxs17 } from "react/jsx-runtime";
45710
- var PdfAnnotationCanvas2 = lazy2(() => import("./PdfAnnotationCanvas.client-LF6DDTCV.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
45690
+ var PdfAnnotationCanvas2 = lazy2(() => import("./PdfAnnotationCanvas.client-CW6SKH2U.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
45711
45691
  var MemoizedMarkdown = memo(function MemoizedMarkdown2({
45712
45692
  content: content4
45713
45693
  }) {
@@ -45733,11 +45713,11 @@ var BrowseView = memo(function BrowseView2({
45733
45713
  const containerRef = useRef16(null);
45734
45714
  const category = getMimeCategory2(mimeType);
45735
45715
  const { highlights, references, assessments, comments, tags: tags3 } = annotations;
45736
- const allAnnotations = useMemo4(
45716
+ const allAnnotations = useMemo3(
45737
45717
  () => [...highlights, ...references, ...assessments, ...comments, ...tags3],
45738
45718
  [highlights, references, assessments, comments, tags3]
45739
45719
  );
45740
- const overlayAnnotations = useMemo4(
45720
+ const overlayAnnotations = useMemo3(
45741
45721
  () => toOverlayAnnotations(allAnnotations),
45742
45722
  [allAnnotations]
45743
45723
  );
@@ -45761,24 +45741,24 @@ var BrowseView = memo(function BrowseView2({
45761
45741
  const target = e6.target;
45762
45742
  const annotationElement = target.closest("[data-annotation-id]");
45763
45743
  if (!annotationElement) return;
45764
- const annotationId4 = annotationElement.getAttribute("data-annotation-id");
45744
+ const annotationId3 = annotationElement.getAttribute("data-annotation-id");
45765
45745
  const annotationType = annotationElement.getAttribute("data-annotation-type");
45766
- if (annotationId4 && annotationType === "reference") {
45767
- const annotation = allAnnotations.find((a15) => a15.id === annotationId4);
45746
+ if (annotationId3 && annotationType === "reference") {
45747
+ const annotation = allAnnotations.find((a15) => a15.id === annotationId3);
45768
45748
  if (annotation) {
45769
- eventBus.get("browse:click").next({ annotationId: annotationId4, motivation: annotation.motivation });
45749
+ eventBus.get("browse:click").next({ annotationId: annotationId3, motivation: annotation.motivation });
45770
45750
  }
45771
45751
  }
45772
45752
  };
45773
45753
  const { handleMouseEnter, handleMouseLeave, cleanup: cleanupHover } = createHoverHandlers(
45774
- (annotationId4) => eventBus.get("beckon:hover").next({ annotationId: annotationId4 }),
45754
+ (annotationId3) => eventBus.get("beckon:hover").next({ annotationId: annotationId3 }),
45775
45755
  hoverDelayMs
45776
45756
  );
45777
45757
  const handleMouseOver = (e6) => {
45778
45758
  const target = e6.target;
45779
45759
  const annotationElement = target.closest("[data-annotation-id]");
45780
- const annotationId4 = annotationElement?.getAttribute("data-annotation-id");
45781
- if (annotationId4) handleMouseEnter(annotationId4);
45760
+ const annotationId3 = annotationElement?.getAttribute("data-annotation-id");
45761
+ if (annotationId3) handleMouseEnter(annotationId3);
45782
45762
  };
45783
45763
  const handleMouseOut = (e6) => {
45784
45764
  const target = e6.target;
@@ -45788,8 +45768,8 @@ var BrowseView = memo(function BrowseView2({
45788
45768
  if (newAnnotationIds) {
45789
45769
  const annotationSpans = container.querySelectorAll("[data-annotation-id]");
45790
45770
  annotationSpans.forEach((span) => {
45791
- const annotationId4 = span.getAttribute("data-annotation-id");
45792
- if (annotationId4 && newAnnotationIds.has(annotationId4)) {
45771
+ const annotationId3 = span.getAttribute("data-annotation-id");
45772
+ if (annotationId3 && newAnnotationIds.has(annotationId3)) {
45793
45773
  span.classList.add("annotation-sparkle");
45794
45774
  }
45795
45775
  });
@@ -45804,15 +45784,15 @@ var BrowseView = memo(function BrowseView2({
45804
45784
  cleanupHover();
45805
45785
  };
45806
45786
  }, [content4, allAnnotations, newAnnotationIds, hoverDelayMs]);
45807
- const scrollToAnnotation = useCallback16((annotationId4, removePulse = false) => {
45787
+ const scrollToAnnotation = useCallback16((annotationId3, removePulse = false) => {
45808
45788
  if (!containerRef.current) return;
45809
- scrollAnnotationIntoView(annotationId4, containerRef.current, { pulse: removePulse });
45789
+ scrollAnnotationIntoView(annotationId3, containerRef.current, { pulse: removePulse });
45810
45790
  }, []);
45811
- const handleAnnotationHover = useCallback16(({ annotationId: annotationId4 }) => {
45812
- scrollToAnnotation(annotationId4);
45791
+ const handleAnnotationHover = useCallback16(({ annotationId: annotationId3 }) => {
45792
+ scrollToAnnotation(annotationId3);
45813
45793
  }, [scrollToAnnotation]);
45814
- const handleAnnotationFocus = useCallback16(({ annotationId: annotationId4 }) => {
45815
- scrollToAnnotation(annotationId4 ?? null, true);
45794
+ const handleAnnotationFocus = useCallback16(({ annotationId: annotationId3 }) => {
45795
+ scrollToAnnotation(annotationId3 ?? null, true);
45816
45796
  }, [scrollToAnnotation]);
45817
45797
  useEventSubscriptions({
45818
45798
  "beckon:hover": handleAnnotationHover,
@@ -45851,7 +45831,7 @@ var BrowseView = memo(function BrowseView2({
45851
45831
  /* @__PURE__ */ jsx26("div", { ref: containerRef, className: "semiont-browse-view__content", children: /* @__PURE__ */ jsx26(Suspense2, { fallback: /* @__PURE__ */ jsx26("div", { className: "semiont-browse-view__loading", children: "Loading PDF viewer..." }), children: /* @__PURE__ */ jsx26(
45852
45832
  PdfAnnotationCanvas2,
45853
45833
  {
45854
- resourceUri: toResourceId2(resourceUri),
45834
+ pdfUrl: content4,
45855
45835
  existingAnnotations: allAnnotations,
45856
45836
  drawingMode: null,
45857
45837
  selectedMotivation: null
@@ -45874,7 +45854,7 @@ var BrowseView = memo(function BrowseView2({
45874
45854
  /* @__PURE__ */ jsx26("div", { ref: containerRef, className: "semiont-browse-view__content", children: /* @__PURE__ */ jsx26(
45875
45855
  ImageViewer,
45876
45856
  {
45877
- resourceUri: toResourceId2(resourceUri),
45857
+ imageUrl: content4,
45878
45858
  mimeType,
45879
45859
  alt: "Resource content"
45880
45860
  }
@@ -45900,8 +45880,8 @@ var BrowseView = memo(function BrowseView2({
45900
45880
  });
45901
45881
 
45902
45882
  // src/components/resource/ResourceViewer.tsx
45903
- import { useState as useState18, useEffect as useEffect24, useCallback as useCallback17, useRef as useRef17, useMemo as useMemo5 } from "react";
45904
- import { resourceId as toResourceId3, annotationId as toAnnotationId } from "@semiont/core";
45883
+ import { useState as useState18, useEffect as useEffect24, useCallback as useCallback17, useRef as useRef17, useMemo as useMemo4 } from "react";
45884
+ import { resourceId as toResourceId, annotationId as toAnnotationId } from "@semiont/core";
45905
45885
  import { getExactText as getExactText3, getTargetSelector as getTargetSelector4, isHighlight as isHighlight4, isAssessment as isAssessment3, isReference as isReference5, isComment as isComment4, isTag as isTag5, getBodySource as getBodySource4 } from "@semiont/api-client";
45906
45886
  import { jsx as jsx27, jsxs as jsxs18 } from "react/jsx-runtime";
45907
45887
  function ResourceViewer({
@@ -45920,7 +45900,7 @@ function ResourceViewer({
45920
45900
  if (!resource["@id"]) {
45921
45901
  throw new Error("Resource has no @id");
45922
45902
  }
45923
- const rUri = toResourceId3(resource["@id"]);
45903
+ const rUri = toResourceId(resource["@id"]);
45924
45904
  const getMimeType = () => {
45925
45905
  const reps = resource.representations;
45926
45906
  if (Array.isArray(reps) && reps.length > 0 && reps[0]) {
@@ -46017,9 +45997,9 @@ function ResourceViewer({
46017
45997
  const hoveredAnnotationId = hoveredAnnotationIdProp ?? null;
46018
45998
  const [scrollToAnnotationId, setScrollToAnnotationId] = useState18(null);
46019
45999
  const [_focusedAnnotationId, setFocusedAnnotationId] = useState18(null);
46020
- const focusAnnotation = useCallback17((annotationId4) => {
46021
- setFocusedAnnotationId(annotationId4);
46022
- setScrollToAnnotationId(annotationId4);
46000
+ const focusAnnotation = useCallback17((annotationId3) => {
46001
+ setFocusedAnnotationId(annotationId3);
46002
+ setScrollToAnnotationId(annotationId3);
46023
46003
  setTimeout(() => setFocusedAnnotationId(null), 3e3);
46024
46004
  }, []);
46025
46005
  const getJsonLdModalPosition = () => {
@@ -46065,11 +46045,11 @@ function ResourceViewer({
46065
46045
  return;
46066
46046
  }
46067
46047
  }, [annotateMode, selectedClick, focusAnnotation]);
46068
- const handleAnnotationClickEvent = useCallback17(({ annotationId: annotationId4, motivation }) => {
46048
+ const handleAnnotationClickEvent = useCallback17(({ annotationId: annotationId3, motivation }) => {
46069
46049
  const metadata = Object.values(ANNOTATORS).find((a15) => a15.matchesAnnotation({ motivation }));
46070
46050
  if (!metadata?.hasSidePanel) {
46071
46051
  const allAnnotations = [...highlights, ...references, ...assessments, ...comments, ...tags3];
46072
- const annotation = allAnnotations.find((a15) => a15.id === annotationId4);
46052
+ const annotation = allAnnotations.find((a15) => a15.id === annotationId3);
46073
46053
  if (annotation) {
46074
46054
  handleAnnotationClick2(annotation);
46075
46055
  }
@@ -46077,13 +46057,13 @@ function ResourceViewer({
46077
46057
  }
46078
46058
  if (selectedClick !== "detail") {
46079
46059
  const allAnnotations = [...highlights, ...references, ...assessments, ...comments, ...tags3];
46080
- const annotation = allAnnotations.find((a15) => a15.id === annotationId4);
46060
+ const annotation = allAnnotations.find((a15) => a15.id === annotationId3);
46081
46061
  if (annotation) {
46082
46062
  handleAnnotationClick2(annotation);
46083
46063
  }
46084
46064
  return;
46085
46065
  }
46086
- eventBus.get("browse:panel-open").next({ panel: "annotations", scrollToAnnotationId: annotationId4, motivation });
46066
+ eventBus.get("browse:panel-open").next({ panel: "annotations", scrollToAnnotationId: annotationId3, motivation });
46087
46067
  }, [highlights, references, assessments, comments, tags3, handleAnnotationClick2, selectedClick]);
46088
46068
  useEventSubscriptions({
46089
46069
  // View mode
@@ -46099,7 +46079,7 @@ function ResourceViewer({
46099
46079
  // Annotation clicks
46100
46080
  "browse:click": handleAnnotationClickEvent
46101
46081
  });
46102
- const annotationsCollection = useMemo5(
46082
+ const annotationsCollection = useMemo4(
46103
46083
  () => ({ highlights, references, assessments, comments, tags: tags3 }),
46104
46084
  [highlights, references, assessments, comments, tags3]
46105
46085
  );
@@ -46293,7 +46273,7 @@ function AssessmentEntry({
46293
46273
  }
46294
46274
 
46295
46275
  // src/components/resource/panels/AssessmentPanel.tsx
46296
- import { useState as useState20, useEffect as useEffect26, useRef as useRef18, useCallback as useCallback19, useMemo as useMemo6 } from "react";
46276
+ import { useState as useState20, useEffect as useEffect26, useRef as useRef18, useCallback as useCallback19, useMemo as useMemo5 } from "react";
46297
46277
  import { getTextPositionSelector as getTextPositionSelector3, getTargetSelector as getTargetSelector5 } from "@semiont/api-client";
46298
46278
 
46299
46279
  // src/components/resource/panels/AssistSection.tsx
@@ -46546,7 +46526,7 @@ function AssessmentPanel({
46546
46526
  const [focusedAnnotationId, setFocusedAnnotationId] = useState20(null);
46547
46527
  const containerRef = useRef18(null);
46548
46528
  const entryRefs = useRef18(/* @__PURE__ */ new Map());
46549
- const sortedAnnotations = useMemo6(() => {
46529
+ const sortedAnnotations = useMemo5(() => {
46550
46530
  return [...annotations].sort((a15, b8) => {
46551
46531
  const aSelector = getTextPositionSelector3(getTargetSelector5(a15.target));
46552
46532
  const bSelector = getTextPositionSelector3(getTargetSelector5(b8.target));
@@ -46614,8 +46594,8 @@ function AssessmentPanel({
46614
46594
  document.addEventListener("keydown", handleEscape);
46615
46595
  return () => document.removeEventListener("keydown", handleEscape);
46616
46596
  }, [pendingAnnotation]);
46617
- const handleAnnotationClick2 = useCallback19(({ annotationId: annotationId4 }) => {
46618
- setFocusedAnnotationId(annotationId4);
46597
+ const handleAnnotationClick2 = useCallback19(({ annotationId: annotationId3 }) => {
46598
+ setFocusedAnnotationId(annotationId3);
46619
46599
  setTimeout(() => setFocusedAnnotationId(null), 3e3);
46620
46600
  }, []);
46621
46601
  useEventSubscriptions({
@@ -46911,7 +46891,7 @@ function CommentEntry({
46911
46891
  }
46912
46892
 
46913
46893
  // src/components/resource/panels/CommentsPanel.tsx
46914
- import { useState as useState22, useEffect as useEffect28, useRef as useRef20, useCallback as useCallback20, useMemo as useMemo7 } from "react";
46894
+ import { useState as useState22, useEffect as useEffect28, useRef as useRef20, useCallback as useCallback20, useMemo as useMemo6 } from "react";
46915
46895
  import { getTextPositionSelector as getTextPositionSelector4, getTargetSelector as getTargetSelector6 } from "@semiont/api-client";
46916
46896
  import { jsx as jsx34, jsxs as jsxs25 } from "react/jsx-runtime";
46917
46897
  function getSelectorDisplayText2(selector) {
@@ -46944,7 +46924,7 @@ function CommentsPanel({
46944
46924
  const [focusedAnnotationId, setFocusedAnnotationId] = useState22(null);
46945
46925
  const containerRef = useRef20(null);
46946
46926
  const entryRefs = useRef20(/* @__PURE__ */ new Map());
46947
- const sortedAnnotations = useMemo7(() => {
46927
+ const sortedAnnotations = useMemo6(() => {
46948
46928
  return [...annotations].sort((a15, b8) => {
46949
46929
  const aSelector = getTextPositionSelector4(getTargetSelector6(a15.target));
46950
46930
  const bSelector = getTextPositionSelector4(getTargetSelector6(b8.target));
@@ -46992,8 +46972,8 @@ function CommentsPanel({
46992
46972
  container.scrollTo({ top: scrollTo, behavior: "smooth" });
46993
46973
  }
46994
46974
  }, [hoveredAnnotationId]);
46995
- const handleAnnotationClick2 = useCallback20(({ annotationId: annotationId4 }) => {
46996
- setFocusedAnnotationId(annotationId4);
46975
+ const handleAnnotationClick2 = useCallback20(({ annotationId: annotationId3 }) => {
46976
+ setFocusedAnnotationId(annotationId3);
46997
46977
  setTimeout(() => setFocusedAnnotationId(null), 3e3);
46998
46978
  }, []);
46999
46979
  useEventSubscriptions({
@@ -47158,7 +47138,7 @@ function HighlightEntry({
47158
47138
  }
47159
47139
 
47160
47140
  // src/components/resource/panels/HighlightPanel.tsx
47161
- import { useEffect as useEffect29, useState as useState23, useRef as useRef21, useCallback as useCallback21, useMemo as useMemo8 } from "react";
47141
+ import { useEffect as useEffect29, useState as useState23, useRef as useRef21, useCallback as useCallback21, useMemo as useMemo7 } from "react";
47162
47142
  import { getTextPositionSelector as getTextPositionSelector5, getTargetSelector as getTargetSelector7 } from "@semiont/api-client";
47163
47143
  import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
47164
47144
  function HighlightPanel({
@@ -47176,7 +47156,7 @@ function HighlightPanel({
47176
47156
  const [focusedAnnotationId, setFocusedAnnotationId] = useState23(null);
47177
47157
  const containerRef = useRef21(null);
47178
47158
  const entryRefs = useRef21(/* @__PURE__ */ new Map());
47179
- const sortedAnnotations = useMemo8(() => {
47159
+ const sortedAnnotations = useMemo7(() => {
47180
47160
  return [...annotations].sort((a15, b8) => {
47181
47161
  const aSelector = getTextPositionSelector5(getTargetSelector7(a15.target));
47182
47162
  const bSelector = getTextPositionSelector5(getTargetSelector7(b8.target));
@@ -47222,8 +47202,8 @@ function HighlightPanel({
47222
47202
  container.scrollTo({ top: scrollTo, behavior: "smooth" });
47223
47203
  }
47224
47204
  }, [hoveredAnnotationId]);
47225
- const handleAnnotationClick2 = useCallback21(({ annotationId: annotationId4 }) => {
47226
- setFocusedAnnotationId(annotationId4);
47205
+ const handleAnnotationClick2 = useCallback21(({ annotationId: annotationId3 }) => {
47206
+ setFocusedAnnotationId(annotationId3);
47227
47207
  setTimeout(() => setFocusedAnnotationId(null), 3e3);
47228
47208
  }, []);
47229
47209
  useEventSubscriptions({
@@ -47466,7 +47446,7 @@ function ReferenceEntry({
47466
47446
  }
47467
47447
 
47468
47448
  // src/components/resource/panels/ReferencesPanel.tsx
47469
- import { useState as useState24, useRef as useRef23, useEffect as useEffect31, useCallback as useCallback22, useMemo as useMemo9 } from "react";
47449
+ import { useState as useState24, useRef as useRef23, useEffect as useEffect31, useCallback as useCallback22, useMemo as useMemo8 } from "react";
47470
47450
  import { getTextPositionSelector as getTextPositionSelector6, getTargetSelector as getTargetSelector9 } from "@semiont/api-client";
47471
47451
  import { Fragment as Fragment6, jsx as jsx38, jsxs as jsxs30 } from "react/jsx-runtime";
47472
47452
  function getSelectorDisplayText3(selector) {
@@ -47516,7 +47496,7 @@ function ReferencesPanel({
47516
47496
  localStorage.setItem("assist-section-expanded-reference", String(isAssistExpanded));
47517
47497
  }, [isAssistExpanded]);
47518
47498
  const entryRefs = useRef23(/* @__PURE__ */ new Map());
47519
- const sortedAnnotations = useMemo9(() => {
47499
+ const sortedAnnotations = useMemo8(() => {
47520
47500
  return [...annotations].sort((a15, b8) => {
47521
47501
  const aSelector = getTextPositionSelector6(getTargetSelector9(a15.target));
47522
47502
  const bSelector = getTextPositionSelector6(getTargetSelector9(b8.target));
@@ -47566,8 +47546,8 @@ function ReferencesPanel({
47566
47546
  container.scrollTo({ top: scrollTo, behavior: "smooth" });
47567
47547
  }
47568
47548
  }, [hoveredAnnotationId]);
47569
- const handleAnnotationClick2 = useCallback22(({ annotationId: annotationId4 }) => {
47570
- setFocusedAnnotationId(annotationId4);
47549
+ const handleAnnotationClick2 = useCallback22(({ annotationId: annotationId3 }) => {
47550
+ setFocusedAnnotationId(annotationId3);
47571
47551
  setTimeout(() => setFocusedAnnotationId(null), 3e3);
47572
47552
  }, []);
47573
47553
  useEventSubscriptions({
@@ -47602,11 +47582,11 @@ function ReferencesPanel({
47602
47582
  };
47603
47583
  const handleCreateReference = () => {
47604
47584
  if (pendingAnnotation) {
47605
- const entityType3 = pendingEntityTypes.join(",") || void 0;
47585
+ const entityType2 = pendingEntityTypes.join(",") || void 0;
47606
47586
  eventBus.get("mark:submit").next({
47607
47587
  motivation: "linking",
47608
47588
  selector: pendingAnnotation.selector,
47609
- body: entityType3 ? [{ type: "TextualBody", value: entityType3, purpose: "tagging" }] : []
47589
+ body: entityType2 ? [{ type: "TextualBody", value: entityType2, purpose: "tagging" }] : []
47610
47590
  });
47611
47591
  setPendingEntityTypes([]);
47612
47592
  }
@@ -48072,7 +48052,7 @@ function TagEntry({
48072
48052
  }
48073
48053
 
48074
48054
  // src/components/resource/panels/TaggingPanel.tsx
48075
- import { useState as useState25, useEffect as useEffect32, useRef as useRef24, useCallback as useCallback23, useMemo as useMemo10 } from "react";
48055
+ import { useState as useState25, useEffect as useEffect32, useRef as useRef24, useCallback as useCallback23, useMemo as useMemo9 } from "react";
48076
48056
  import { getTextPositionSelector as getTextPositionSelector7, getTargetSelector as getTargetSelector10 } from "@semiont/api-client";
48077
48057
  import { Fragment as Fragment8, jsx as jsx42, jsxs as jsxs34 } from "react/jsx-runtime";
48078
48058
  function getSelectorDisplayText4(selector) {
@@ -48113,15 +48093,15 @@ function TaggingPanel({
48113
48093
  if (typeof window === "undefined") return;
48114
48094
  localStorage.setItem("assist-section-expanded-tag", String(isAssistExpanded));
48115
48095
  }, [isAssistExpanded]);
48116
- const handleAnnotationClick2 = useCallback23(({ annotationId: annotationId4 }) => {
48117
- setFocusedAnnotationId(annotationId4);
48096
+ const handleAnnotationClick2 = useCallback23(({ annotationId: annotationId3 }) => {
48097
+ setFocusedAnnotationId(annotationId3);
48118
48098
  setTimeout(() => setFocusedAnnotationId(null), 3e3);
48119
48099
  }, []);
48120
48100
  useEventSubscriptions({
48121
48101
  "browse:click": handleAnnotationClick2
48122
48102
  });
48123
48103
  const entryRefs = useRef24(/* @__PURE__ */ new Map());
48124
- const sortedAnnotations = useMemo10(() => {
48104
+ const sortedAnnotations = useMemo9(() => {
48125
48105
  return [...annotations].sort((a15, b8) => {
48126
48106
  const aSelector = getTextPositionSelector7(getTargetSelector10(a15.target));
48127
48107
  const bSelector = getTextPositionSelector7(getTargetSelector10(b8.target));
@@ -48891,16 +48871,16 @@ function SimpleNavigation({
48891
48871
  import { useCallback as useCallback30, useState as useState32, useRef as useRef31, useEffect as useEffect40 } from "react";
48892
48872
 
48893
48873
  // ../../node_modules/@dnd-kit/core/dist/core.esm.js
48894
- import React19, { createContext as createContext6, useContext as useContext6, useEffect as useEffect37, useState as useState30, useCallback as useCallback27, useMemo as useMemo12, useRef as useRef28, memo as memo2, useReducer, cloneElement, forwardRef } from "react";
48874
+ import React19, { createContext as createContext6, useContext as useContext6, useEffect as useEffect37, useState as useState30, useCallback as useCallback27, useMemo as useMemo11, useRef as useRef28, memo as memo2, useReducer, cloneElement, forwardRef } from "react";
48895
48875
  import { createPortal, unstable_batchedUpdates } from "react-dom";
48896
48876
 
48897
48877
  // ../../node_modules/@dnd-kit/utilities/dist/utilities.esm.js
48898
- import { useMemo as useMemo11, useLayoutEffect, useEffect as useEffect36, useRef as useRef27, useCallback as useCallback25 } from "react";
48878
+ import { useMemo as useMemo10, useLayoutEffect, useEffect as useEffect36, useRef as useRef27, useCallback as useCallback25 } from "react";
48899
48879
  function useCombinedRefs() {
48900
48880
  for (var _len = arguments.length, refs = new Array(_len), _key = 0; _key < _len; _key++) {
48901
48881
  refs[_key] = arguments[_key];
48902
48882
  }
48903
- return useMemo11(
48883
+ return useMemo10(
48904
48884
  () => (node2) => {
48905
48885
  refs.forEach((ref) => ref(node2));
48906
48886
  },
@@ -49003,7 +48983,7 @@ function useLatestValue(value, dependencies) {
49003
48983
  }
49004
48984
  function useLazyMemo(callback, dependencies) {
49005
48985
  const valueRef = useRef27();
49006
- return useMemo11(
48986
+ return useMemo10(
49007
48987
  () => {
49008
48988
  const newValue = callback(valueRef.current);
49009
48989
  valueRef.current = newValue;
@@ -49037,7 +49017,7 @@ function usePrevious(value) {
49037
49017
  }
49038
49018
  var ids = {};
49039
49019
  function useUniqueId(prefix, value) {
49040
- return useMemo11(() => {
49020
+ return useMemo10(() => {
49041
49021
  if (value) {
49042
49022
  return value;
49043
49023
  }
@@ -49309,7 +49289,7 @@ function Accessibility(_ref) {
49309
49289
  useEffect37(() => {
49310
49290
  setMounted(true);
49311
49291
  }, []);
49312
- useDndMonitor(useMemo12(() => ({
49292
+ useDndMonitor(useMemo11(() => ({
49313
49293
  onDragStart(_ref2) {
49314
49294
  let {
49315
49295
  active
@@ -49387,7 +49367,7 @@ var Action;
49387
49367
  function noop() {
49388
49368
  }
49389
49369
  function useSensor(sensor, options) {
49390
- return useMemo12(
49370
+ return useMemo11(
49391
49371
  () => ({
49392
49372
  sensor,
49393
49373
  options: options != null ? options : {}
@@ -49400,7 +49380,7 @@ function useSensors() {
49400
49380
  for (var _len = arguments.length, sensors = new Array(_len), _key = 0; _key < _len; _key++) {
49401
49381
  sensors[_key] = arguments[_key];
49402
49382
  }
49403
- return useMemo12(
49383
+ return useMemo11(
49404
49384
  () => [...sensors].filter((sensor) => sensor != null),
49405
49385
  // eslint-disable-next-line react-hooks/exhaustive-deps
49406
49386
  [...sensors]
@@ -50650,7 +50630,7 @@ function useAutoScroller(_ref) {
50650
50630
  x: 0,
50651
50631
  y: 0
50652
50632
  });
50653
- const rect = useMemo12(() => {
50633
+ const rect = useMemo11(() => {
50654
50634
  switch (activator) {
50655
50635
  case AutoScrollActivator.Pointer:
50656
50636
  return pointerCoordinates ? {
@@ -50673,7 +50653,7 @@ function useAutoScroller(_ref) {
50673
50653
  const scrollTop = scrollSpeed.current.y * scrollDirection.current.y;
50674
50654
  scrollContainer.scrollBy(scrollLeft, scrollTop);
50675
50655
  }, []);
50676
- const sortedScrollableAncestors = useMemo12(() => order2 === TraversalOrder.TreeOrder ? [...scrollableAncestors].reverse() : scrollableAncestors, [order2, scrollableAncestors]);
50656
+ const sortedScrollableAncestors = useMemo11(() => order2 === TraversalOrder.TreeOrder ? [...scrollableAncestors].reverse() : scrollableAncestors, [order2, scrollableAncestors]);
50677
50657
  useEffect37(
50678
50658
  () => {
50679
50659
  if (!enabled || !scrollableAncestors.length || !rect) {
@@ -50787,7 +50767,7 @@ function useCachedNode(draggableNodes, id2) {
50787
50767
  }, [node2, id2]);
50788
50768
  }
50789
50769
  function useCombineActivators(sensors, getSyntheticHandler) {
50790
- return useMemo12(() => sensors.reduce((accumulator, sensor) => {
50770
+ return useMemo11(() => sensors.reduce((accumulator, sensor) => {
50791
50771
  const {
50792
50772
  sensor: Sensor
50793
50773
  } = sensor;
@@ -50935,7 +50915,7 @@ function useMutationObserver(_ref) {
50935
50915
  disabled
50936
50916
  } = _ref;
50937
50917
  const handleMutations = useEvent(callback);
50938
- const mutationObserver = useMemo12(() => {
50918
+ const mutationObserver = useMemo11(() => {
50939
50919
  if (disabled || typeof window === "undefined" || typeof window.MutationObserver === "undefined") {
50940
50920
  return void 0;
50941
50921
  }
@@ -50955,7 +50935,7 @@ function useResizeObserver(_ref) {
50955
50935
  disabled
50956
50936
  } = _ref;
50957
50937
  const handleResize = useEvent(callback);
50958
- const resizeObserver = useMemo12(
50938
+ const resizeObserver = useMemo11(
50959
50939
  () => {
50960
50940
  if (disabled || typeof window === "undefined" || typeof window.ResizeObserver === "undefined") {
50961
50941
  return void 0;
@@ -51097,7 +51077,7 @@ function useScrollOffsets(elements) {
51097
51077
  });
51098
51078
  }
51099
51079
  }, [handleScroll, elements]);
51100
- return useMemo12(() => {
51080
+ return useMemo11(() => {
51101
51081
  if (elements.length) {
51102
51082
  return scrollCoordinates ? Array.from(scrollCoordinates.values()).reduce((acc, coordinates) => add(acc, coordinates), defaultCoordinates) : getScrollOffsets(elements);
51103
51083
  }
@@ -51156,7 +51136,7 @@ function useSensorSetup(sensors) {
51156
51136
  );
51157
51137
  }
51158
51138
  function useSyntheticListeners(listeners, id2) {
51159
- return useMemo12(() => {
51139
+ return useMemo11(() => {
51160
51140
  return listeners.reduce((acc, _ref) => {
51161
51141
  let {
51162
51142
  eventName,
@@ -51170,7 +51150,7 @@ function useSyntheticListeners(listeners, id2) {
51170
51150
  }, [listeners, id2]);
51171
51151
  }
51172
51152
  function useWindowRect(element2) {
51173
- return useMemo12(() => element2 ? getWindowClientRect(element2) : null, [element2]);
51153
+ return useMemo11(() => element2 ? getWindowClientRect(element2) : null, [element2]);
51174
51154
  }
51175
51155
  var defaultValue$2 = [];
51176
51156
  function useRects(elements, measure) {
@@ -51242,7 +51222,7 @@ function useDragOverlayMeasuring(_ref) {
51242
51222
  setRect(node2 ? measure(node2) : null);
51243
51223
  }, [measure, resizeObserver]);
51244
51224
  const [nodeRef, setRef] = useNodeRef(handleNodeChange);
51245
- return useMemo12(() => ({
51225
+ return useMemo11(() => ({
51246
51226
  nodeRef,
51247
51227
  rect,
51248
51228
  setRef
@@ -51519,7 +51499,7 @@ function applyModifiers(modifiers2, _ref) {
51519
51499
  }, transform) : transform;
51520
51500
  }
51521
51501
  function useMeasuringConfiguration(config) {
51522
- return useMemo12(
51502
+ return useMemo11(
51523
51503
  () => ({
51524
51504
  draggable: {
51525
51505
  ...defaultMeasuringConfiguration.draggable,
@@ -51630,7 +51610,7 @@ var DndContext = /* @__PURE__ */ memo2(function DndContext2(_ref) {
51630
51610
  initial: null,
51631
51611
  translated: null
51632
51612
  });
51633
- const active = useMemo12(() => {
51613
+ const active = useMemo11(() => {
51634
51614
  var _node$data;
51635
51615
  return activeId != null ? {
51636
51616
  id: activeId,
@@ -51644,7 +51624,7 @@ var DndContext = /* @__PURE__ */ memo2(function DndContext2(_ref) {
51644
51624
  const [activatorEvent, setActivatorEvent] = useState30(null);
51645
51625
  const latestProps = useLatestValue(props, Object.values(props));
51646
51626
  const draggableDescribedById = useUniqueId("DndDescribedBy", id2);
51647
- const enabledDroppableContainers = useMemo12(() => droppableContainers.getEnabled(), [droppableContainers]);
51627
+ const enabledDroppableContainers = useMemo11(() => droppableContainers.getEnabled(), [droppableContainers]);
51648
51628
  const measuringConfiguration = useMeasuringConfiguration(measuring);
51649
51629
  const {
51650
51630
  droppableRects,
@@ -51656,7 +51636,7 @@ var DndContext = /* @__PURE__ */ memo2(function DndContext2(_ref) {
51656
51636
  config: measuringConfiguration.droppable
51657
51637
  });
51658
51638
  const activeNode = useCachedNode(draggableNodes, activeId);
51659
- const activationCoordinates = useMemo12(() => activatorEvent ? getEventCoordinates(activatorEvent) : null, [activatorEvent]);
51639
+ const activationCoordinates = useMemo11(() => activatorEvent ? getEventCoordinates(activatorEvent) : null, [activatorEvent]);
51660
51640
  const autoScrollOptions = getAutoScrollerOptions();
51661
51641
  const initialActiveNodeRect = useInitialRect(activeNode, measuringConfiguration.draggable.measure);
51662
51642
  useLayoutShiftScrollCompensation({
@@ -52027,7 +52007,7 @@ var DndContext = /* @__PURE__ */ memo2(function DndContext2(_ref) {
52027
52007
  scrollableAncestors,
52028
52008
  scrollableAncestorRects
52029
52009
  });
52030
- const publicContext = useMemo12(() => {
52010
+ const publicContext = useMemo11(() => {
52031
52011
  const context = {
52032
52012
  active,
52033
52013
  activeNode,
@@ -52049,7 +52029,7 @@ var DndContext = /* @__PURE__ */ memo2(function DndContext2(_ref) {
52049
52029
  };
52050
52030
  return context;
52051
52031
  }, [active, activeNode, activeNodeRect, activatorEvent, collisions, containerNodeRect, dragOverlay, draggableNodes, droppableContainers, droppableRects, over, measureDroppableContainers, scrollableAncestors, scrollableAncestorRects, measuringConfiguration, measuringScheduled, windowRect2]);
52052
- const internalContext = useMemo12(() => {
52032
+ const internalContext = useMemo11(() => {
52053
52033
  const context = {
52054
52034
  activatorEvent,
52055
52035
  activators,
@@ -52144,7 +52124,7 @@ function useDraggable(_ref) {
52144
52124
  // eslint-disable-next-line react-hooks/exhaustive-deps
52145
52125
  [draggableNodes, id2]
52146
52126
  );
52147
- const memoizedAttributes = useMemo12(() => ({
52127
+ const memoizedAttributes = useMemo11(() => ({
52148
52128
  role,
52149
52129
  tabIndex,
52150
52130
  "aria-disabled": disabled,
@@ -52289,7 +52269,7 @@ function useDroppable(_ref) {
52289
52269
  }
52290
52270
 
52291
52271
  // ../../node_modules/@dnd-kit/sortable/dist/sortable.esm.js
52292
- import React20, { useMemo as useMemo13, useRef as useRef29, useEffect as useEffect38, useState as useState31, useContext as useContext7 } from "react";
52272
+ import React20, { useMemo as useMemo12, useRef as useRef29, useEffect as useEffect38, useState as useState31, useContext as useContext7 } from "react";
52293
52273
  function arrayMove(array, from, to) {
52294
52274
  const newArray = array.slice();
52295
52275
  newArray.splice(to < 0 ? newArray.length + to : to, 0, newArray.splice(from, 1)[0]);
@@ -52443,7 +52423,7 @@ function SortableContext(_ref) {
52443
52423
  } = useDndContext();
52444
52424
  const containerId = useUniqueId(ID_PREFIX2, id2);
52445
52425
  const useDragOverlay = Boolean(dragOverlay.rect !== null);
52446
- const items = useMemo13(() => userDefinedItems.map((item) => typeof item === "object" && "id" in item ? item.id : item), [userDefinedItems]);
52426
+ const items = useMemo12(() => userDefinedItems.map((item) => typeof item === "object" && "id" in item ? item.id : item), [userDefinedItems]);
52447
52427
  const isDragging = active != null;
52448
52428
  const activeIndex = active ? items.indexOf(active.id) : -1;
52449
52429
  const overIndex = over ? items.indexOf(over.id) : -1;
@@ -52459,7 +52439,7 @@ function SortableContext(_ref) {
52459
52439
  useEffect38(() => {
52460
52440
  previousItemsRef.current = items;
52461
52441
  }, [items]);
52462
- const contextValue = useMemo13(
52442
+ const contextValue = useMemo12(
52463
52443
  () => ({
52464
52444
  activeIndex,
52465
52445
  containerId,
@@ -52586,7 +52566,7 @@ function useSortable(_ref) {
52586
52566
  } = useContext7(Context2);
52587
52567
  const disabled = normalizeLocalDisabled(localDisabled, globalDisabled);
52588
52568
  const index2 = items.indexOf(id2);
52589
- const data2 = useMemo13(() => ({
52569
+ const data2 = useMemo12(() => ({
52590
52570
  sortable: {
52591
52571
  containerId,
52592
52572
  index: index2,
@@ -52594,7 +52574,7 @@ function useSortable(_ref) {
52594
52574
  },
52595
52575
  ...customData
52596
52576
  }), [containerId, customData, index2, items]);
52597
- const itemsAfterCurrentSortable = useMemo13(() => items.slice(items.indexOf(id2)), [items, id2]);
52577
+ const itemsAfterCurrentSortable = useMemo12(() => items.slice(items.indexOf(id2)), [items, id2]);
52598
52578
  const {
52599
52579
  rect,
52600
52580
  node: node2,
@@ -53457,7 +53437,7 @@ function ConfigureGenerationStep({
53457
53437
  context
53458
53438
  });
53459
53439
  };
53460
- return /* @__PURE__ */ jsxs43("form", { onSubmit: handleSubmit, className: "semiont-form", children: [
53440
+ return /* @__PURE__ */ jsxs43("form", { onSubmit: handleSubmit, className: "semiont-form semiont-form--scrollable", children: [
53461
53441
  /* @__PURE__ */ jsxs43("div", { className: "semiont-form__field", children: [
53462
53442
  /* @__PURE__ */ jsx52("label", { htmlFor: "wizard-title", className: "semiont-form__label", children: t12.resourceTitle }),
53463
53443
  /* @__PURE__ */ jsx52(
@@ -53499,68 +53479,68 @@ function ConfigureGenerationStep({
53499
53479
  id: "wizard-prompt",
53500
53480
  value: prompt,
53501
53481
  onChange: (e6) => setPrompt(e6.target.value),
53502
- rows: 3,
53482
+ rows: 2,
53503
53483
  className: "semiont-textarea",
53504
53484
  placeholder: t12.additionalInstructionsPlaceholder
53505
53485
  }
53506
53486
  )
53507
53487
  ] }),
53508
- /* @__PURE__ */ jsxs43("div", { className: "semiont-form__field", children: [
53509
- /* @__PURE__ */ jsx52("label", { htmlFor: "wizard-language", className: "semiont-form__label", children: t12.language }),
53510
- /* @__PURE__ */ jsx52(
53511
- "select",
53512
- {
53513
- id: "wizard-language",
53514
- value: language2,
53515
- onChange: (e6) => setLanguage(e6.target.value),
53516
- className: "semiont-select",
53517
- children: LOCALES2.map((lang) => /* @__PURE__ */ jsx52("option", { value: lang.code, children: lang.nativeName }, lang.code))
53518
- }
53519
- ),
53520
- /* @__PURE__ */ jsx52("p", { className: "semiont-form__help", children: t12.languageHelp })
53521
- ] }),
53522
- /* @__PURE__ */ jsxs43("div", { className: "semiont-form__field", children: [
53523
- /* @__PURE__ */ jsxs43("label", { htmlFor: "wizard-temperature", className: "semiont-form__label", children: [
53524
- t12.creativity,
53525
- " (",
53526
- temperature.toFixed(1),
53527
- ")"
53488
+ /* @__PURE__ */ jsxs43("div", { className: "semiont-form__inline-row", children: [
53489
+ /* @__PURE__ */ jsxs43("div", { className: "semiont-form__field semiont-form__field--inline", children: [
53490
+ /* @__PURE__ */ jsx52("label", { htmlFor: "wizard-language", className: "semiont-form__label", children: t12.language }),
53491
+ /* @__PURE__ */ jsx52(
53492
+ "select",
53493
+ {
53494
+ id: "wizard-language",
53495
+ value: language2,
53496
+ onChange: (e6) => setLanguage(e6.target.value),
53497
+ className: "semiont-select",
53498
+ children: LOCALES2.map((lang) => /* @__PURE__ */ jsx52("option", { value: lang.code, children: lang.nativeName }, lang.code))
53499
+ }
53500
+ )
53528
53501
  ] }),
53529
- /* @__PURE__ */ jsx52(
53530
- "input",
53531
- {
53532
- id: "wizard-temperature",
53533
- type: "range",
53534
- min: "0",
53535
- max: "1",
53536
- step: "0.1",
53537
- value: temperature,
53538
- onChange: (e6) => setTemperature(parseFloat(e6.target.value)),
53539
- className: "semiont-slider"
53540
- }
53541
- ),
53542
- /* @__PURE__ */ jsxs43("div", { className: "semiont-slider__labels", children: [
53543
- /* @__PURE__ */ jsx52("span", { children: t12.creativityFocused }),
53544
- /* @__PURE__ */ jsx52("span", { children: t12.creativityCreative })
53502
+ /* @__PURE__ */ jsxs43("div", { className: "semiont-form__field semiont-form__field--inline semiont-form__field--grow", children: [
53503
+ /* @__PURE__ */ jsxs43("label", { htmlFor: "wizard-temperature", className: "semiont-form__label", children: [
53504
+ t12.creativity,
53505
+ " (",
53506
+ temperature.toFixed(1),
53507
+ ")"
53508
+ ] }),
53509
+ /* @__PURE__ */ jsx52(
53510
+ "input",
53511
+ {
53512
+ id: "wizard-temperature",
53513
+ type: "range",
53514
+ min: "0",
53515
+ max: "1",
53516
+ step: "0.1",
53517
+ value: temperature,
53518
+ onChange: (e6) => setTemperature(parseFloat(e6.target.value)),
53519
+ className: "semiont-slider"
53520
+ }
53521
+ ),
53522
+ /* @__PURE__ */ jsxs43("div", { className: "semiont-slider__labels semiont-slider__labels--small", children: [
53523
+ /* @__PURE__ */ jsx52("span", { children: t12.creativityFocused }),
53524
+ /* @__PURE__ */ jsx52("span", { children: t12.creativityCreative })
53525
+ ] })
53526
+ ] }),
53527
+ /* @__PURE__ */ jsxs43("div", { className: "semiont-form__field semiont-form__field--inline semiont-form__field--narrow", children: [
53528
+ /* @__PURE__ */ jsx52("label", { htmlFor: "wizard-maxTokens", className: "semiont-form__label", children: t12.maxLength }),
53529
+ /* @__PURE__ */ jsx52(
53530
+ "input",
53531
+ {
53532
+ id: "wizard-maxTokens",
53533
+ type: "number",
53534
+ min: "100",
53535
+ max: "4000",
53536
+ step: "100",
53537
+ value: maxTokens,
53538
+ onChange: (e6) => setMaxTokens(parseInt(e6.target.value)),
53539
+ className: "semiont-input"
53540
+ }
53541
+ )
53545
53542
  ] })
53546
53543
  ] }),
53547
- /* @__PURE__ */ jsxs43("div", { className: "semiont-form__field", children: [
53548
- /* @__PURE__ */ jsx52("label", { htmlFor: "wizard-maxTokens", className: "semiont-form__label", children: t12.maxLength }),
53549
- /* @__PURE__ */ jsx52(
53550
- "input",
53551
- {
53552
- id: "wizard-maxTokens",
53553
- type: "number",
53554
- min: "100",
53555
- max: "4000",
53556
- step: "100",
53557
- value: maxTokens,
53558
- onChange: (e6) => setMaxTokens(parseInt(e6.target.value)),
53559
- className: "semiont-input"
53560
- }
53561
- ),
53562
- /* @__PURE__ */ jsx52("p", { className: "semiont-form__help", children: t12.maxLengthHelp })
53563
- ] }),
53564
53544
  /* @__PURE__ */ jsxs43("div", { className: "semiont-modal__actions", style: { paddingTop: "0.5rem" }, children: [
53565
53545
  /* @__PURE__ */ jsxs43(
53566
53546
  "button",
@@ -53790,7 +53770,7 @@ import { jsx as jsx55, jsxs as jsxs46 } from "react/jsx-runtime";
53790
53770
  function ReferenceWizardModal({
53791
53771
  isOpen,
53792
53772
  onClose,
53793
- annotationId: annotationId4,
53773
+ annotationId: annotationId3,
53794
53774
  resourceId: resourceId2,
53795
53775
  defaultTitle,
53796
53776
  entityTypes,
@@ -53817,14 +53797,13 @@ function ReferenceWizardModal({
53817
53797
  useEffect42(() => {
53818
53798
  if (!isOpen) return;
53819
53799
  const subscription = eventBus.get("match:search-results").subscribe((event) => {
53820
- const e6 = event;
53821
- if (annotationId4 && e6.referenceId === annotationId4) {
53800
+ if (annotationId3 && event.referenceId === annotationId3) {
53822
53801
  setIsSearching(false);
53823
- setWizardStep({ step: "search-results", results: e6.results });
53802
+ setWizardStep({ step: "search-results", results: event.response });
53824
53803
  }
53825
53804
  });
53826
53805
  return () => subscription.unsubscribe();
53827
- }, [isOpen, eventBus, annotationId4]);
53806
+ }, [isOpen, eventBus, annotationId3]);
53828
53807
  const handleBind = useCallback31(() => {
53829
53808
  setWizardStep({ step: "configure-search" });
53830
53809
  }, []);
@@ -53832,35 +53811,36 @@ function ReferenceWizardModal({
53832
53811
  setWizardStep({ step: "configure-generation" });
53833
53812
  }, []);
53834
53813
  const handleCompose = useCallback31(() => {
53835
- if (!context || !annotationId4 || !resourceId2) return;
53814
+ if (!context || !annotationId3 || !resourceId2) return;
53836
53815
  const contextWithHint = userHint ? { ...context, userHint } : context;
53837
- onComposeNavigate(contextWithHint, annotationId4, resourceId2, defaultTitle, entityTypes);
53816
+ onComposeNavigate(contextWithHint, annotationId3, resourceId2, defaultTitle, entityTypes);
53838
53817
  onClose();
53839
- }, [context, annotationId4, resourceId2, defaultTitle, entityTypes, onComposeNavigate, onClose, userHint]);
53818
+ }, [context, annotationId3, resourceId2, defaultTitle, entityTypes, onComposeNavigate, onClose, userHint]);
53840
53819
  const handleBackToGather = useCallback31(() => {
53841
53820
  setWizardStep({ step: "gather" });
53842
53821
  }, []);
53843
53822
  const handleSearchSubmit = useCallback31((config) => {
53844
- if (!annotationId4 || !context) return;
53823
+ if (!annotationId3 || !context) return;
53845
53824
  setIsSearching(true);
53846
53825
  const contextWithHint = userHint ? { ...context, userHint } : context;
53847
53826
  eventBus.get("match:search-requested").next({
53848
- referenceId: annotationId4,
53827
+ correlationId: crypto.randomUUID(),
53828
+ referenceId: annotationId3,
53849
53829
  context: contextWithHint,
53850
53830
  limit: config.limit,
53851
53831
  useSemanticScoring: config.useSemanticScoring
53852
53832
  });
53853
- }, [annotationId4, context, eventBus, userHint]);
53833
+ }, [annotationId3, context, eventBus, userHint]);
53854
53834
  const handleGenerateSubmit = useCallback31((config) => {
53855
- if (!annotationId4) return;
53856
- onGenerateSubmit(annotationId4, config);
53835
+ if (!annotationId3) return;
53836
+ onGenerateSubmit(annotationId3, config);
53857
53837
  onClose();
53858
- }, [annotationId4, onGenerateSubmit, onClose]);
53838
+ }, [annotationId3, onGenerateSubmit, onClose]);
53859
53839
  const handleLink = useCallback31((targetResourceId) => {
53860
- if (!annotationId4) return;
53861
- onLinkResource(annotationId4, targetResourceId);
53840
+ if (!annotationId3) return;
53841
+ onLinkResource(annotationId3, targetResourceId);
53862
53842
  onClose();
53863
- }, [annotationId4, onLinkResource, onClose]);
53843
+ }, [annotationId3, onLinkResource, onClose]);
53864
53844
  const stepTitle = wizardStep.step === "gather" ? t12.gatherTitle : wizardStep.step === "configure-generation" ? t12.configureGenerationTitle : wizardStep.step === "configure-search" ? t12.configureSearchTitle : t12.searchResultsTitle;
53865
53845
  return /* @__PURE__ */ jsx55(Ke, { appear: true, show: isOpen, children: /* @__PURE__ */ jsxs46(ht, { as: "div", className: "semiont-search-modal", onClose, children: [
53866
53846
  /* @__PURE__ */ jsx55(
@@ -55748,7 +55728,7 @@ var UserCircleIcon_default = ForwardRef17;
55748
55728
 
55749
55729
  // src/hooks/usePanelBrowse.ts
55750
55730
  import { useState as useState41, useCallback as useCallback33, useEffect as useEffect46 } from "react";
55751
- var COMMON_PANELS = ["user", "settings"];
55731
+ var COMMON_PANELS = ["knowledge-base", "user", "settings"];
55752
55732
  var RESOURCE_PANELS = ["history", "info", "annotations", "collaboration", "jsonld"];
55753
55733
  var tabGenerationCounter = 0;
55754
55734
  function usePanelBrowse() {
@@ -56605,23 +56585,51 @@ function GoogleIcon() {
56605
56585
  )
56606
56586
  ] });
56607
56587
  }
56588
+ function normalizeUrlForProbe(raw) {
56589
+ const trimmed = raw.trim();
56590
+ if (!trimmed) return null;
56591
+ if (/^https?:\/\//i.test(trimmed)) return trimmed;
56592
+ return `http://${trimmed}`;
56593
+ }
56608
56594
  function CredentialsAuthForm({
56595
+ lockedBackendUrl,
56609
56596
  onSubmit,
56610
56597
  translations: t12
56611
56598
  }) {
56599
+ const [backendUrl, setBackendUrl] = React47.useState(lockedBackendUrl ?? "");
56612
56600
  const [email, setEmail] = React47.useState("");
56613
56601
  const [password, setPassword] = React47.useState("");
56614
56602
  const [validationError, setValidationError] = React47.useState(null);
56615
56603
  const [fieldErrors, setFieldErrors] = React47.useState({});
56604
+ const [urlProbeStatus, setUrlProbeStatus] = React47.useState("idle");
56605
+ const probeUrl = async (raw) => {
56606
+ const url = normalizeUrlForProbe(raw);
56607
+ if (!url) return;
56608
+ try {
56609
+ new URL(url);
56610
+ } catch {
56611
+ setFieldErrors((prev) => ({ ...prev, backendUrl: t12.errorBackendUrlInvalid }));
56612
+ setUrlProbeStatus("error");
56613
+ return;
56614
+ }
56615
+ setUrlProbeStatus("checking");
56616
+ try {
56617
+ const res = await fetch(`${url}/api/health`, { signal: AbortSignal.timeout(5e3) });
56618
+ setUrlProbeStatus(res.ok ? "ok" : "error");
56619
+ if (!res.ok) {
56620
+ setFieldErrors((prev) => ({ ...prev, backendUrl: t12.errorBackendUrlUnreachable }));
56621
+ }
56622
+ } catch {
56623
+ setUrlProbeStatus("error");
56624
+ setFieldErrors((prev) => ({ ...prev, backendUrl: t12.errorBackendUrlUnreachable }));
56625
+ }
56626
+ };
56616
56627
  const handleSubmit = async (e6) => {
56617
56628
  e6.preventDefault();
56618
56629
  const errors = {};
56619
- if (!email) {
56620
- errors.email = t12.errorEmailRequired;
56621
- }
56622
- if (!password) {
56623
- errors.password = t12.errorPasswordRequired;
56624
- }
56630
+ if (!backendUrl.trim()) errors.backendUrl = t12.errorBackendUrlRequired;
56631
+ if (!email) errors.email = t12.errorEmailRequired;
56632
+ if (!password) errors.password = t12.errorPasswordRequired;
56625
56633
  if (Object.keys(errors).length > 0) {
56626
56634
  setFieldErrors(errors);
56627
56635
  setValidationError(Object.values(errors)[0]);
@@ -56629,11 +56637,53 @@ function CredentialsAuthForm({
56629
56637
  }
56630
56638
  setFieldErrors({});
56631
56639
  setValidationError(null);
56632
- await onSubmit(email, password);
56640
+ await onSubmit(backendUrl.trim(), email, password);
56633
56641
  };
56642
+ const probeIndicator = !lockedBackendUrl && urlProbeStatus !== "idle" ? /* @__PURE__ */ jsxs68(
56643
+ "span",
56644
+ {
56645
+ className: `semiont-form__url-status semiont-form__url-status--${urlProbeStatus}`,
56646
+ "aria-live": "polite",
56647
+ children: [
56648
+ urlProbeStatus === "checking" && "\u27F3",
56649
+ urlProbeStatus === "ok" && "\u2713",
56650
+ urlProbeStatus === "error" && "\u2717"
56651
+ ]
56652
+ }
56653
+ ) : null;
56634
56654
  return /* @__PURE__ */ jsxs68(Fragment16, { children: [
56635
56655
  validationError && /* @__PURE__ */ jsx79("div", { className: "semiont-auth__error", role: "alert", "aria-live": "polite", children: /* @__PURE__ */ jsx79("div", { className: "semiont-auth__error-text", children: validationError }) }),
56636
56656
  /* @__PURE__ */ jsxs68("form", { onSubmit: handleSubmit, className: "semiont-auth__form", noValidate: true, children: [
56657
+ /* @__PURE__ */ jsxs68("div", { className: "semiont-form__field", children: [
56658
+ /* @__PURE__ */ jsx79("label", { htmlFor: "backend-url", className: "semiont-form__label", children: t12.backendUrlLabel }),
56659
+ /* @__PURE__ */ jsxs68("div", { className: "semiont-form__input-row", children: [
56660
+ /* @__PURE__ */ jsx79(
56661
+ "input",
56662
+ {
56663
+ id: "backend-url",
56664
+ type: "url",
56665
+ value: backendUrl,
56666
+ onChange: (e6) => {
56667
+ if (lockedBackendUrl) return;
56668
+ setBackendUrl(e6.target.value);
56669
+ setUrlProbeStatus("idle");
56670
+ if (fieldErrors.backendUrl) setFieldErrors({ ...fieldErrors, backendUrl: void 0 });
56671
+ },
56672
+ onBlur: () => {
56673
+ if (!lockedBackendUrl) probeUrl(backendUrl);
56674
+ },
56675
+ readOnly: !!lockedBackendUrl,
56676
+ placeholder: t12.backendUrlPlaceholder,
56677
+ className: `semiont-input${lockedBackendUrl ? " semiont-input--readonly" : ""}`,
56678
+ "aria-invalid": !!fieldErrors.backendUrl,
56679
+ "aria-describedby": fieldErrors.backendUrl ? "backend-url-error" : void 0,
56680
+ required: true
56681
+ }
56682
+ ),
56683
+ probeIndicator
56684
+ ] }),
56685
+ fieldErrors.backendUrl && /* @__PURE__ */ jsx79("span", { id: "backend-url-error", className: "semiont-form__error", role: "alert", children: fieldErrors.backendUrl })
56686
+ ] }),
56637
56687
  /* @__PURE__ */ jsxs68("div", { className: "semiont-form__field", children: [
56638
56688
  /* @__PURE__ */ jsx79("label", { htmlFor: "email", className: "semiont-form__label", children: t12.emailLabel }),
56639
56689
  /* @__PURE__ */ jsx79(
@@ -56644,9 +56694,7 @@ function CredentialsAuthForm({
56644
56694
  value: email,
56645
56695
  onChange: (e6) => {
56646
56696
  setEmail(e6.target.value);
56647
- if (fieldErrors.email) {
56648
- setFieldErrors({ ...fieldErrors, email: void 0 });
56649
- }
56697
+ if (fieldErrors.email) setFieldErrors({ ...fieldErrors, email: void 0 });
56650
56698
  },
56651
56699
  placeholder: t12.emailPlaceholder,
56652
56700
  className: "semiont-input",
@@ -56667,9 +56715,7 @@ function CredentialsAuthForm({
56667
56715
  value: password,
56668
56716
  onChange: (e6) => {
56669
56717
  setPassword(e6.target.value);
56670
- if (fieldErrors.password) {
56671
- setFieldErrors({ ...fieldErrors, password: void 0 });
56672
- }
56718
+ if (fieldErrors.password) setFieldErrors({ ...fieldErrors, password: void 0 });
56673
56719
  },
56674
56720
  placeholder: t12.passwordPlaceholder,
56675
56721
  className: "semiont-input",
@@ -56691,12 +56737,18 @@ function CredentialsAuthForm({
56691
56737
  function SignInForm({
56692
56738
  onGoogleSignIn,
56693
56739
  onCredentialsSignIn,
56740
+ backendUrl,
56694
56741
  error,
56695
56742
  showCredentialsAuth = false,
56696
56743
  isLoading = false,
56697
56744
  Link,
56698
56745
  translations: t12
56699
56746
  }) {
56747
+ const handleGoogleClick = () => {
56748
+ if (backendUrl) {
56749
+ onGoogleSignIn(backendUrl);
56750
+ }
56751
+ };
56700
56752
  return /* @__PURE__ */ jsx79("main", { className: "semiont-auth__main", role: "main", children: /* @__PURE__ */ jsx79("div", { className: "semiont-auth__container", children: /* @__PURE__ */ jsxs68("div", { className: "semiont-auth__content", children: [
56701
56753
  /* @__PURE__ */ jsxs68("section", { "aria-labelledby": "signin-heading", className: "semiont-auth__branding", children: [
56702
56754
  /* @__PURE__ */ jsx79("h1", { id: "signin-heading", className: "sr-only", children: t12.pageTitle }),
@@ -56706,8 +56758,15 @@ function SignInForm({
56706
56758
  ] }),
56707
56759
  error && /* @__PURE__ */ jsx79("div", { className: "semiont-auth__error-container", children: /* @__PURE__ */ jsx79("div", { className: "semiont-auth__error", children: /* @__PURE__ */ jsx79("div", { className: "semiont-auth__error-text", children: error }) }) }),
56708
56760
  /* @__PURE__ */ jsx79("div", { className: "semiont-auth__forms", children: !isLoading ? /* @__PURE__ */ jsxs68(Fragment16, { children: [
56709
- showCredentialsAuth && onCredentialsSignIn && /* @__PURE__ */ jsx79(CredentialsAuthForm, { onSubmit: onCredentialsSignIn, translations: t12 }),
56710
- /* @__PURE__ */ jsxs68("button", { onClick: onGoogleSignIn, className: `${buttonStyles.primary.base} semiont-button--full-width`, children: [
56761
+ showCredentialsAuth && onCredentialsSignIn && /* @__PURE__ */ jsx79(
56762
+ CredentialsAuthForm,
56763
+ {
56764
+ lockedBackendUrl: backendUrl,
56765
+ onSubmit: onCredentialsSignIn,
56766
+ translations: t12
56767
+ }
56768
+ ),
56769
+ backendUrl && /* @__PURE__ */ jsxs68("button", { onClick: handleGoogleClick, className: `${buttonStyles.primary.base} semiont-button--full-width`, children: [
56711
56770
  /* @__PURE__ */ jsx79(GoogleIcon, {}),
56712
56771
  t12.continueWithGoogle
56713
56772
  ] }),
@@ -57778,8 +57837,8 @@ function ResourceDiscoveryPage({
57778
57837
  );
57779
57838
  const onNavigateToResourceRef = useRef34(onNavigateToResource);
57780
57839
  onNavigateToResourceRef.current = onNavigateToResource;
57781
- const handleEntityTypeFilter = useCallback35((entityType3) => {
57782
- setSelectedEntityType(entityType3);
57840
+ const handleEntityTypeFilter = useCallback35((entityType2) => {
57841
+ setSelectedEntityType(entityType2);
57783
57842
  }, []);
57784
57843
  const openResource = useCallback35((resource) => {
57785
57844
  const resourceId2 = getResourceId2(resource);
@@ -57919,71 +57978,39 @@ function ResourceDiscoveryPage({
57919
57978
  }
57920
57979
 
57921
57980
  // src/features/resource-viewer/components/ResourceViewerPage.tsx
57922
- import { useState as useState50, useEffect as useEffect52, useCallback as useCallback38, useMemo as useMemo14 } from "react";
57981
+ import { useState as useState50, useEffect as useEffect52, useCallback as useCallback38, useMemo as useMemo13 } from "react";
57923
57982
  import { useQueryClient as useQueryClient3 } from "@tanstack/react-query";
57924
- import { annotationId as annotationId3 } from "@semiont/core";
57925
- import { getLanguage, getPrimaryRepresentation, getPrimaryMediaType as getPrimaryMediaType2 } from "@semiont/api-client";
57983
+ import { annotationId as annotationId2 } from "@semiont/core";
57984
+ import { getLanguage, getPrimaryRepresentation, getPrimaryMediaType as getPrimaryMediaType2, getMimeCategory as getMimeCategory3 } from "@semiont/api-client";
57985
+
57986
+ // src/hooks/useMediaToken.ts
57987
+ function useMediaToken(id2) {
57988
+ const resources = useResources();
57989
+ const { data: data2, isLoading } = resources.mediaToken.useQuery(id2);
57990
+ return {
57991
+ token: data2?.token,
57992
+ loading: isLoading
57993
+ };
57994
+ }
57926
57995
 
57927
57996
  // src/hooks/useBindFlow.ts
57928
57997
  import { useEffect as useEffect48, useRef as useRef35 } from "react";
57929
57998
  import { accessToken as accessToken4 } from "@semiont/core";
57930
- function toAccessToken2(token) {
57931
- return token ? accessToken4(token) : void 0;
57932
- }
57933
57999
  function useBindFlow(rUri) {
57934
- const eventBus = useEventBus();
57935
58000
  const client = useApiClient();
57936
58001
  const token = useAuthToken();
57937
58002
  const { showError } = useToast();
57938
- const rUriRef = useRef35(rUri);
57939
- useEffect48(() => {
57940
- rUriRef.current = rUri;
57941
- });
57942
- const clientRef = useRef35(client);
57943
- useEffect48(() => {
57944
- clientRef.current = client;
57945
- });
57946
58003
  const tokenRef = useRef35(token);
57947
58004
  useEffect48(() => {
57948
58005
  tokenRef.current = token;
57949
58006
  });
57950
58007
  useEffect48(() => {
57951
- const handleAnnotationUpdateBody = (event) => {
57952
- const annotationId4 = event.annotationId;
57953
- const finishedSub = eventBus.get("bind:finished").subscribe((finishedEvent) => {
57954
- if (finishedEvent.annotationId !== annotationId4) return;
57955
- finishedSub.unsubscribe();
57956
- failedSub.unsubscribe();
57957
- eventBus.get("bind:body-updated").next({ annotationId: annotationId4 });
57958
- });
57959
- const failedSub = eventBus.get("bind:failed").subscribe((failedEvent) => {
57960
- finishedSub.unsubscribe();
57961
- failedSub.unsubscribe();
57962
- console.error("Failed to update annotation body:", failedEvent.error);
57963
- eventBus.get("bind:body-update-failed").next({ error: failedEvent.error ?? new Error("Bind failed") });
57964
- });
57965
- clientRef.current.sse.bindAnnotation(
57966
- rUriRef.current,
57967
- annotationId4,
57968
- { resourceId: event.resourceId, operations: event.operations },
57969
- { auth: toAccessToken2(tokenRef.current), eventBus }
57970
- );
57971
- };
57972
- const handleSearchRequested = (event) => {
57973
- clientRef.current.sse.bindSearch(rUriRef.current, {
57974
- referenceId: event.referenceId,
57975
- context: event.context,
57976
- limit: event.limit,
57977
- useSemanticScoring: event.useSemanticScoring
57978
- }, { auth: toAccessToken2(tokenRef.current), eventBus });
57979
- };
57980
- const updateSub = eventBus.get("bind:update-body").subscribe(handleAnnotationUpdateBody);
57981
- const searchSub = eventBus.get("match:search-requested").subscribe(handleSearchRequested);
57982
- return () => {
57983
- updateSub.unsubscribe();
57984
- searchSub.unsubscribe();
57985
- };
57986
- }, [eventBus]);
58008
+ const sub = client.flows.bind(
58009
+ rUri,
58010
+ () => tokenRef.current ? accessToken4(tokenRef.current) : void 0
58011
+ );
58012
+ return () => sub.unsubscribe();
58013
+ }, [rUri, client]);
57987
58014
  useEventSubscriptions({
57988
58015
  "bind:body-update-failed": ({ error }) => showError(`Failed to update reference: ${error.message}`)
57989
58016
  });
@@ -57991,102 +58018,46 @@ function useBindFlow(rUri) {
57991
58018
 
57992
58019
  // src/hooks/useMarkFlow.ts
57993
58020
  import { useState as useState47, useRef as useRef36, useEffect as useEffect49, useCallback as useCallback36 } from "react";
57994
- import { accessToken as accessToken5, entityType as entityType2, annotationId as annotationId2 } from "@semiont/core";
57995
- function toAccessToken3(token) {
57996
- return token ? accessToken5(token) : void 0;
57997
- }
58021
+ import { accessToken as accessToken5 } from "@semiont/core";
57998
58022
  function useMarkFlow(rUri) {
57999
58023
  const eventBus = useEventBus();
58000
58024
  const client = useApiClient();
58001
58025
  const token = useAuthToken();
58002
58026
  const { showSuccess, showError, showInfo } = useToast();
58003
- const clientRef = useRef36(client);
58004
- const rUriRef = useRef36(rUri);
58005
58027
  const tokenRef = useRef36(token);
58006
- useEffect49(() => {
58007
- clientRef.current = client;
58008
- });
58009
- useEffect49(() => {
58010
- rUriRef.current = rUri;
58011
- });
58012
58028
  useEffect49(() => {
58013
58029
  tokenRef.current = token;
58014
58030
  });
58031
+ useEffect49(() => {
58032
+ const sub = client.flows.mark(
58033
+ rUri,
58034
+ () => tokenRef.current ? accessToken5(tokenRef.current) : void 0
58035
+ );
58036
+ return () => sub.unsubscribe();
58037
+ }, [rUri, client]);
58015
58038
  const [pendingAnnotation, setPendingAnnotation] = useState47(null);
58016
- const handleAnnotationRequested = useCallback36((pending) => {
58017
- const MOTIVATION_TO_TAB = {
58018
- highlighting: "annotations",
58019
- commenting: "annotations",
58020
- assessing: "annotations",
58021
- tagging: "annotations",
58022
- linking: "annotations"
58023
- };
58024
- eventBus.get("browse:panel-open").next({ panel: MOTIVATION_TO_TAB[pending.motivation] || "annotations" });
58025
- setPendingAnnotation(pending);
58026
- }, []);
58027
58039
  const selectionToSelector = useCallback36((selection2) => {
58028
- if (selection2.svgSelector) {
58029
- return {
58030
- type: "SvgSelector",
58031
- value: selection2.svgSelector
58032
- };
58033
- }
58040
+ if (selection2.svgSelector) return { type: "SvgSelector", value: selection2.svgSelector };
58034
58041
  if (selection2.fragmentSelector) {
58035
- const selectors = [
58036
- {
58037
- type: "FragmentSelector",
58038
- value: selection2.fragmentSelector,
58039
- ...selection2.conformsTo && { conformsTo: selection2.conformsTo }
58040
- }
58041
- ];
58042
- if (selection2.exact) {
58043
- selectors.push({
58044
- type: "TextQuoteSelector",
58045
- exact: selection2.exact,
58046
- ...selection2.prefix && { prefix: selection2.prefix },
58047
- ...selection2.suffix && { suffix: selection2.suffix }
58048
- });
58049
- }
58042
+ const selectors = [{ type: "FragmentSelector", value: selection2.fragmentSelector, ...selection2.conformsTo && { conformsTo: selection2.conformsTo } }];
58043
+ if (selection2.exact) selectors.push({ type: "TextQuoteSelector", exact: selection2.exact, ...selection2.prefix && { prefix: selection2.prefix }, ...selection2.suffix && { suffix: selection2.suffix } });
58050
58044
  return selectors;
58051
58045
  }
58052
- return {
58053
- type: "TextQuoteSelector",
58054
- exact: selection2.exact,
58055
- ...selection2.prefix && { prefix: selection2.prefix },
58056
- ...selection2.suffix && { suffix: selection2.suffix }
58057
- };
58046
+ return { type: "TextQuoteSelector", exact: selection2.exact, ...selection2.prefix && { prefix: selection2.prefix }, ...selection2.suffix && { suffix: selection2.suffix } };
58058
58047
  }, []);
58059
- const handleCommentRequested = useCallback36((selection2) => {
58060
- handleAnnotationRequested({ selector: selectionToSelector(selection2), motivation: "commenting" });
58061
- }, [handleAnnotationRequested, selectionToSelector]);
58062
- const handleTagRequested = useCallback36((selection2) => {
58063
- handleAnnotationRequested({ selector: selectionToSelector(selection2), motivation: "tagging" });
58064
- }, [handleAnnotationRequested, selectionToSelector]);
58065
- const handleAssessmentRequested = useCallback36((selection2) => {
58066
- handleAnnotationRequested({ selector: selectionToSelector(selection2), motivation: "assessing" });
58067
- }, [handleAnnotationRequested, selectionToSelector]);
58068
- const handleReferenceRequested = useCallback36((selection2) => {
58069
- handleAnnotationRequested({ selector: selectionToSelector(selection2), motivation: "linking" });
58070
- }, [handleAnnotationRequested, selectionToSelector]);
58071
- const handleAnnotationCancelPending = useCallback36(() => {
58072
- setPendingAnnotation(null);
58048
+ const handleAnnotationRequested = useCallback36((pending) => {
58049
+ const MOTIVATION_TO_TAB = { highlighting: "annotations", commenting: "annotations", assessing: "annotations", tagging: "annotations", linking: "annotations" };
58050
+ eventBus.get("browse:panel-open").next({ panel: MOTIVATION_TO_TAB[pending.motivation] || "annotations" });
58051
+ setPendingAnnotation(pending);
58073
58052
  }, []);
58074
58053
  const [assistingMotivation, setAssistingMotivation] = useState47(null);
58075
58054
  const [progress, setProgress] = useState47(null);
58076
58055
  const assistStreamRef = useRef36(null);
58077
58056
  const progressDismissTimeoutRef = useRef36(null);
58078
- const handleMarkProgress = useCallback36((chunk) => {
58079
- setProgress(chunk);
58080
- }, []);
58081
58057
  const handleAnnotationComplete = useCallback36((event) => {
58082
- setAssistingMotivation((prev) => {
58083
- if (!event.motivation || event.motivation !== prev) return prev;
58084
- return null;
58085
- });
58058
+ setAssistingMotivation((prev) => !event.motivation || event.motivation !== prev ? prev : null);
58086
58059
  showSuccess("Annotation complete");
58087
- if (progressDismissTimeoutRef.current) {
58088
- clearTimeout(progressDismissTimeoutRef.current);
58089
- }
58060
+ if (progressDismissTimeoutRef.current) clearTimeout(progressDismissTimeoutRef.current);
58090
58061
  progressDismissTimeoutRef.current = setTimeout(() => {
58091
58062
  setProgress(null);
58092
58063
  progressDismissTimeoutRef.current = null;
@@ -58099,318 +58070,134 @@ function useMarkFlow(rUri) {
58099
58070
  }
58100
58071
  setAssistingMotivation(null);
58101
58072
  setProgress(null);
58102
- const errorMessage = event.payload.error || "Annotation failed";
58103
- showError(errorMessage);
58073
+ showError(event.message || "Annotation failed");
58104
58074
  }, [showError]);
58105
- const handleProgressDismiss = useCallback36(() => {
58106
- if (progressDismissTimeoutRef.current) {
58107
- clearTimeout(progressDismissTimeoutRef.current);
58108
- progressDismissTimeoutRef.current = null;
58109
- }
58110
- setProgress(null);
58111
- }, []);
58112
- useEffect49(() => {
58113
- const handleAnnotationSubmit = async (event) => {
58114
- const currentClient = clientRef.current;
58115
- const currentRUri = rUriRef.current;
58116
- if (!currentClient || !currentRUri) return;
58117
- try {
58118
- const result = await currentClient.markAnnotation(currentRUri, {
58119
- motivation: event.motivation,
58120
- target: {
58121
- source: currentRUri,
58122
- selector: event.selector
58123
- },
58124
- body: event.body
58125
- }, { auth: toAccessToken3(tokenRef.current) });
58126
- setPendingAnnotation(null);
58127
- eventBus.get("mark:created").next({ annotationId: annotationId2(result.annotationId) });
58128
- } catch (error) {
58129
- console.error("Failed to create annotation:", error);
58130
- eventBus.get("mark:create-failed").next({ error });
58131
- }
58132
- };
58133
- const handleAnnotationDelete = async (event) => {
58134
- const currentClient = clientRef.current;
58135
- const currentRUri = rUriRef.current;
58136
- try {
58137
- await currentClient.deleteAnnotation(currentRUri, event.annotationId, { auth: toAccessToken3(tokenRef.current) });
58138
- eventBus.get("mark:deleted").next({ annotationId: event.annotationId });
58139
- } catch (error) {
58140
- console.error("Failed to delete annotation:", error);
58141
- eventBus.get("mark:delete-failed").next({ error });
58142
- }
58143
- };
58144
- const handleAssistStart = async (event) => {
58145
- const currentClient = clientRef.current;
58146
- const currentRUri = rUriRef.current;
58147
- try {
58148
- if (assistStreamRef.current) {
58149
- assistStreamRef.current.abort();
58150
- }
58151
- assistStreamRef.current = new AbortController();
58152
- if (progressDismissTimeoutRef.current) {
58153
- clearTimeout(progressDismissTimeoutRef.current);
58154
- progressDismissTimeoutRef.current = null;
58155
- }
58156
- setAssistingMotivation(event.motivation);
58157
- setProgress(null);
58158
- const sseOptions = { auth: toAccessToken3(tokenRef.current), eventBus };
58159
- if (event.motivation === "tagging") {
58160
- const { schemaId, categories } = event.options;
58161
- if (!schemaId || !categories || categories.length === 0) {
58162
- throw new Error("Tag assist requires schemaId and categories");
58163
- }
58164
- currentClient.sse.markTags(currentRUri, { schemaId, categories }, sseOptions);
58165
- } else if (event.motivation === "linking") {
58166
- const { entityTypes, includeDescriptiveReferences } = event.options;
58167
- if (!entityTypes || entityTypes.length === 0) {
58168
- throw new Error("Reference assist requires entityTypes");
58169
- }
58170
- currentClient.sse.markReferences(currentRUri, {
58171
- entityTypes: entityTypes.map((et) => entityType2(et)),
58172
- includeDescriptiveReferences: includeDescriptiveReferences || false
58173
- }, sseOptions);
58174
- } else if (event.motivation === "highlighting") {
58175
- currentClient.sse.markHighlights(currentRUri, {
58176
- instructions: event.options.instructions,
58177
- density: event.options.density
58178
- }, sseOptions);
58179
- } else if (event.motivation === "assessing") {
58180
- currentClient.sse.markAssessments(currentRUri, {
58181
- instructions: event.options.instructions,
58182
- tone: event.options.tone,
58183
- density: event.options.density,
58184
- language: event.options.language
58185
- }, sseOptions);
58186
- } else if (event.motivation === "commenting") {
58187
- currentClient.sse.markComments(currentRUri, {
58188
- instructions: event.options.instructions,
58189
- tone: event.options.tone,
58190
- density: event.options.density,
58191
- language: event.options.language
58192
- }, sseOptions);
58193
- }
58194
- } catch (error) {
58195
- if (error instanceof Error && error.name === "AbortError") {
58196
- eventBus.get("mark:assist-cancelled").next(void 0);
58197
- } else {
58198
- console.error("Annotation assist failed:", error);
58199
- setAssistingMotivation(null);
58200
- setProgress(null);
58201
- }
58202
- }
58203
- };
58204
- const handleJobCancelRequested = (event) => {
58205
- if (event.jobType === "annotation") {
58206
- assistStreamRef.current?.abort();
58207
- assistStreamRef.current = null;
58208
- }
58209
- };
58210
- const subscription1 = eventBus.get("mark:submit").subscribe(handleAnnotationSubmit);
58211
- const subscription2 = eventBus.get("mark:delete").subscribe(handleAnnotationDelete);
58212
- const subscription3 = eventBus.get("mark:assist-request").subscribe(handleAssistStart);
58213
- const subscription4 = eventBus.get("job:cancel-requested").subscribe(handleJobCancelRequested);
58214
- return () => {
58215
- subscription1.unsubscribe();
58216
- subscription2.unsubscribe();
58217
- subscription3.unsubscribe();
58218
- subscription4.unsubscribe();
58219
- assistStreamRef.current?.abort();
58220
- };
58221
- }, [eventBus]);
58222
58075
  useEventSubscriptions({
58223
- // Manual annotation
58224
58076
  "mark:requested": handleAnnotationRequested,
58225
- "mark:select-comment": handleCommentRequested,
58226
- "mark:select-tag": handleTagRequested,
58227
- "mark:select-assessment": handleAssessmentRequested,
58228
- "mark:select-reference": handleReferenceRequested,
58229
- "mark:cancel-pending": handleAnnotationCancelPending,
58230
- // AI-assisted annotation state updates
58231
- "mark:progress": handleMarkProgress,
58077
+ "mark:select-comment": (s11) => handleAnnotationRequested({ selector: selectionToSelector(s11), motivation: "commenting" }),
58078
+ "mark:select-tag": (s11) => handleAnnotationRequested({ selector: selectionToSelector(s11), motivation: "tagging" }),
58079
+ "mark:select-assessment": (s11) => handleAnnotationRequested({ selector: selectionToSelector(s11), motivation: "assessing" }),
58080
+ "mark:select-reference": (s11) => handleAnnotationRequested({ selector: selectionToSelector(s11), motivation: "linking" }),
58081
+ "mark:cancel-pending": () => setPendingAnnotation(null),
58082
+ "mark:created": () => setPendingAnnotation(null),
58083
+ "mark:assist-request": (event) => {
58084
+ if (progressDismissTimeoutRef.current) {
58085
+ clearTimeout(progressDismissTimeoutRef.current);
58086
+ progressDismissTimeoutRef.current = null;
58087
+ }
58088
+ setAssistingMotivation(event.motivation);
58089
+ setProgress(null);
58090
+ },
58091
+ "mark:progress": (chunk) => setProgress(chunk),
58232
58092
  "mark:assist-finished": handleAnnotationComplete,
58233
58093
  "mark:assist-failed": handleAnnotationFailed,
58234
- "mark:progress-dismiss": handleProgressDismiss,
58094
+ "mark:progress-dismiss": () => {
58095
+ if (progressDismissTimeoutRef.current) {
58096
+ clearTimeout(progressDismissTimeoutRef.current);
58097
+ progressDismissTimeoutRef.current = null;
58098
+ }
58099
+ setProgress(null);
58100
+ },
58235
58101
  "mark:assist-cancelled": () => showInfo("Annotation cancelled"),
58236
- // CRUD error notifications
58237
58102
  "mark:create-failed": ({ error }) => showError(`Failed to create annotation: ${error.message}`),
58238
58103
  "mark:delete-failed": ({ error }) => showError(`Failed to delete annotation: ${error.message}`)
58239
58104
  });
58240
- useEffect49(() => {
58241
- return () => {
58242
- if (progressDismissTimeoutRef.current) {
58243
- clearTimeout(progressDismissTimeoutRef.current);
58244
- }
58245
- };
58105
+ useEffect49(() => () => {
58106
+ if (progressDismissTimeoutRef.current) clearTimeout(progressDismissTimeoutRef.current);
58246
58107
  }, []);
58247
- return {
58248
- pendingAnnotation,
58249
- assistingMotivation,
58250
- progress,
58251
- assistStreamRef
58252
- };
58108
+ return { pendingAnnotation, assistingMotivation, progress, assistStreamRef };
58253
58109
  }
58254
58110
 
58255
58111
  // src/hooks/useYieldFlow.ts
58256
58112
  import { useState as useState48, useCallback as useCallback37, useEffect as useEffect50, useRef as useRef37 } from "react";
58257
58113
  import { annotationId as makeAnnotationId, resourceId as makeResourceId, accessToken as accessToken6 } from "@semiont/core";
58258
- function toAccessToken4(token) {
58259
- return token ? accessToken6(token) : void 0;
58260
- }
58261
58114
  function useYieldFlow(locale, resourceId2, clearNewAnnotationId) {
58262
58115
  const eventBus = useEventBus();
58263
58116
  const client = useApiClient();
58264
58117
  const token = useAuthToken();
58265
58118
  const { showSuccess, showError } = useToast();
58266
- const clientRef = useRef37(client);
58267
58119
  const tokenRef = useRef37(token);
58268
- useEffect50(() => {
58269
- clientRef.current = client;
58270
- });
58271
58120
  useEffect50(() => {
58272
58121
  tokenRef.current = token;
58273
58122
  });
58274
- const generationStreamRef = useRef37(null);
58275
58123
  const [isGenerating, setIsGenerating] = useState48(false);
58276
58124
  const [generationProgress, setYieldProgress] = useState48(null);
58277
- const handleProgressEvent = useCallback37((chunk) => {
58278
- setYieldProgress(chunk);
58279
- setIsGenerating(true);
58280
- }, []);
58281
- const clearProgress = useCallback37(() => {
58282
- setYieldProgress(null);
58283
- }, []);
58125
+ useEffect50(() => {
58126
+ const sub = client.flows.yield(
58127
+ makeResourceId(resourceId2),
58128
+ () => tokenRef.current ? accessToken6(tokenRef.current) : void 0
58129
+ );
58130
+ return () => sub.unsubscribe();
58131
+ }, [resourceId2, client]);
58284
58132
  const handleGenerateDocument = useCallback37((referenceId, options) => {
58285
58133
  clearNewAnnotationId(makeAnnotationId(referenceId));
58286
58134
  eventBus.get("yield:request").next({
58287
58135
  annotationId: makeAnnotationId(referenceId),
58288
58136
  resourceId: makeResourceId(resourceId2),
58289
- options: {
58290
- ...options,
58291
- language: options.language || locale,
58292
- context: options.context,
58293
- storageUri: options.storageUri
58294
- }
58137
+ options: { ...options, language: options.language || locale }
58295
58138
  });
58296
58139
  }, [resourceId2, clearNewAnnotationId, locale]);
58297
- const handleGenerationComplete = useCallback37((progress) => {
58298
- setYieldProgress(progress);
58299
- setIsGenerating(false);
58300
- if (progress.resourceName) {
58301
- showSuccess(`Resource "${progress.resourceName}" created successfully!`);
58302
- } else {
58303
- showSuccess("Resource created successfully!");
58304
- }
58305
- setTimeout(() => clearProgress(), 2e3);
58306
- }, [showSuccess, clearProgress]);
58307
- const handleGenerationFailed = useCallback37(({ error }) => {
58140
+ const clearProgress = useCallback37(() => {
58308
58141
  setYieldProgress(null);
58309
- setIsGenerating(false);
58310
- showError(`Resource generation failed: ${error.message}`);
58311
- }, [showError]);
58312
- useEffect50(() => {
58313
- const handleGenerationStart = async (event) => {
58314
- try {
58315
- generationStreamRef.current?.abort();
58316
- generationStreamRef.current = new AbortController();
58317
- const sseOptions = { auth: toAccessToken4(tokenRef.current), eventBus };
58318
- clientRef.current.sse.yieldResource(
58319
- event.resourceId,
58320
- event.annotationId,
58321
- event.options,
58322
- sseOptions
58323
- );
58324
- } catch (error) {
58325
- if (error.name !== "AbortError") {
58326
- console.error("[useYieldFlow] Generation failed:", error);
58327
- eventBus.get("yield:failed").next({ error });
58328
- }
58329
- }
58330
- };
58331
- const handleJobCancelRequested = (event) => {
58332
- if (event.jobType === "generation") {
58333
- generationStreamRef.current?.abort();
58334
- generationStreamRef.current = null;
58335
- }
58336
- };
58337
- const subscription1 = eventBus.get("yield:request").subscribe(handleGenerationStart);
58338
- const subscription2 = eventBus.get("job:cancel-requested").subscribe(handleJobCancelRequested);
58339
- return () => {
58340
- subscription1.unsubscribe();
58341
- subscription2.unsubscribe();
58342
- generationStreamRef.current?.abort();
58343
- };
58344
- }, [eventBus]);
58142
+ }, []);
58345
58143
  useEventSubscriptions({
58346
- "yield:progress": handleProgressEvent,
58347
- "yield:finished": handleGenerationComplete,
58348
- "yield:failed": handleGenerationFailed
58144
+ "yield:progress": (chunk) => {
58145
+ setYieldProgress(chunk);
58146
+ setIsGenerating(true);
58147
+ },
58148
+ "yield:finished": (progress) => {
58149
+ setYieldProgress(progress);
58150
+ setIsGenerating(false);
58151
+ showSuccess(progress.resourceName ? `Resource "${progress.resourceName}" created successfully!` : "Resource created successfully!");
58152
+ setTimeout(() => clearProgress(), 2e3);
58153
+ },
58154
+ "yield:failed": ({ error, message }) => {
58155
+ setYieldProgress(null);
58156
+ setIsGenerating(false);
58157
+ const msg = message || (error instanceof Error ? error.message : error) || "Generation failed";
58158
+ showError(`Resource generation failed: ${msg}`);
58159
+ }
58349
58160
  });
58350
- return {
58351
- isGenerating,
58352
- generationProgress,
58353
- onGenerateDocument: handleGenerateDocument
58354
- };
58161
+ return { isGenerating, generationProgress, onGenerateDocument: handleGenerateDocument };
58355
58162
  }
58356
58163
 
58357
58164
  // src/hooks/useContextGatherFlow.ts
58358
58165
  import { useState as useState49, useEffect as useEffect51, useRef as useRef38 } from "react";
58359
58166
  import { accessToken as accessToken7 } from "@semiont/core";
58360
- function toAccessToken5(token) {
58361
- return token ? accessToken7(token) : void 0;
58362
- }
58363
- function useContextGatherFlow(eventBus, config) {
58167
+ function useContextGatherFlow(config) {
58168
+ const client = useApiClient();
58364
58169
  const token = useAuthToken();
58365
- const [gatherContext, setCorrelationContext] = useState49(null);
58366
- const [gatherLoading, setCorrelationLoading] = useState49(false);
58367
- const [gatherError, setCorrelationError] = useState49(null);
58368
- const [gatherAnnotationId, setCorrelationAnnotationId] = useState49(null);
58369
- const configRef = useRef38(config);
58370
58170
  const tokenRef = useRef38(token);
58371
- useEffect51(() => {
58372
- configRef.current = config;
58373
- });
58374
58171
  useEffect51(() => {
58375
58172
  tokenRef.current = token;
58376
58173
  });
58174
+ const [gatherContext, setGatherContext] = useState49(null);
58175
+ const [gatherLoading, setGatherLoading] = useState49(false);
58176
+ const [gatherError, setGatherError] = useState49(null);
58177
+ const [gatherAnnotationId, setGatherAnnotationId] = useState49(null);
58377
58178
  useEffect51(() => {
58378
- const handleGatherRequested = (event) => {
58379
- setCorrelationLoading(true);
58380
- setCorrelationError(null);
58381
- setCorrelationContext(null);
58382
- setCorrelationAnnotationId(event.annotationId);
58383
- const { client, resourceId: resourceId2 } = configRef.current;
58384
- const contextWindow = event.options?.contextWindow ?? 2e3;
58385
- const finishedSub = eventBus.get("gather:annotation-finished").subscribe((finishedEvent) => {
58386
- if (finishedEvent.annotationId !== event.annotationId) return;
58387
- finishedSub.unsubscribe();
58388
- failedSub.unsubscribe();
58389
- const context = finishedEvent.response.context ?? null;
58390
- setCorrelationContext(context);
58391
- setCorrelationLoading(false);
58392
- eventBus.get("gather:complete").next({
58393
- annotationId: finishedEvent.annotationId,
58394
- response: finishedEvent.response
58395
- });
58396
- });
58397
- const failedSub = eventBus.get("gather:failed").subscribe((failedEvent) => {
58398
- if (failedEvent.annotationId !== event.annotationId) return;
58399
- finishedSub.unsubscribe();
58400
- failedSub.unsubscribe();
58401
- setCorrelationError(failedEvent.error);
58402
- setCorrelationLoading(false);
58403
- });
58404
- client.sse.gatherAnnotation(
58405
- resourceId2,
58406
- event.annotationId,
58407
- { contextWindow },
58408
- { auth: toAccessToken5(tokenRef.current), eventBus }
58409
- );
58410
- };
58411
- const subscription = eventBus.get("gather:requested").subscribe(handleGatherRequested);
58412
- return () => subscription.unsubscribe();
58413
- }, [eventBus]);
58179
+ const sub = client.flows.gatherContext(
58180
+ config.resourceId,
58181
+ () => tokenRef.current ? accessToken7(tokenRef.current) : void 0
58182
+ );
58183
+ return () => sub.unsubscribe();
58184
+ }, [config.resourceId, client]);
58185
+ useEventSubscriptions({
58186
+ "gather:requested": (event) => {
58187
+ setGatherLoading(true);
58188
+ setGatherError(null);
58189
+ setGatherContext(null);
58190
+ setGatherAnnotationId(event.annotationId);
58191
+ },
58192
+ "gather:complete": (event) => {
58193
+ setGatherContext(event.response.context ?? null);
58194
+ setGatherLoading(false);
58195
+ },
58196
+ "gather:failed": (event) => {
58197
+ setGatherError(event.error);
58198
+ setGatherLoading(false);
58199
+ }
58200
+ });
58414
58201
  return { gatherContext, gatherLoading, gatherError, gatherAnnotationId };
58415
58202
  }
58416
58203
 
@@ -58423,7 +58210,8 @@ function ResourceViewerPage({
58423
58210
  Link,
58424
58211
  routes,
58425
58212
  ToolbarPanels,
58426
- refetchDocument
58213
+ refetchDocument,
58214
+ streamStatus
58427
58215
  }) {
58428
58216
  const tw = useTranslations("ReferenceWizard");
58429
58217
  const eventBus = useEventBus();
@@ -58437,9 +58225,15 @@ function ResourceViewerPage({
58437
58225
  const { triggerSparkleAnimation, clearNewAnnotationId } = useResourceAnnotations();
58438
58226
  const resources = useResources();
58439
58227
  const entityTypesAPI = useEntityTypes();
58440
- const { content: content4, loading: contentLoading } = useResourceContent(rUri, resource);
58441
- const { data: annotationsData } = resources.annotations.useQuery(rUri);
58442
- const annotations = useMemo14(
58228
+ const resourceMediaType = getPrimaryMediaType2(resource) || "text/plain";
58229
+ const isBinary = getMimeCategory3(resourceMediaType) === "image";
58230
+ const { content: textContent, loading: textLoading } = useResourceContent(rUri, resource, !isBinary);
58231
+ const { token: mediaToken, loading: mediaTokenLoading } = useMediaToken(rUri);
58232
+ const binaryContent = isBinary && mediaToken && client ? `${client.baseUrl}/api/resources/${rUri}?token=${mediaToken}` : "";
58233
+ const content4 = isBinary ? binaryContent : textContent;
58234
+ const contentLoading = isBinary ? mediaTokenLoading : textLoading;
58235
+ const annotationsData = useObservable(client.stores.annotations.listForResource(rUri));
58236
+ const annotations = useMemo13(
58443
58237
  () => annotationsData?.annotations || [],
58444
58238
  [annotationsData?.annotations]
58445
58239
  );
@@ -58455,7 +58249,7 @@ function ResourceViewerPage({
58455
58249
  generationProgress,
58456
58250
  onGenerateDocument
58457
58251
  } = useYieldFlow(locale, rUri, clearNewAnnotationId);
58458
- const { gatherContext, gatherLoading, gatherError } = useContextGatherFlow(eventBus, { client, resourceId: rUri });
58252
+ const { gatherContext, gatherLoading, gatherError } = useContextGatherFlow({ resourceId: rUri });
58459
58253
  const [wizardOpen, setWizardOpen] = useState50(false);
58460
58254
  const [wizardAnnotationId, setWizardAnnotationId] = useState50(null);
58461
58255
  const [wizardResourceId, setWizardResourceId] = useState50(null);
@@ -58468,7 +58262,7 @@ function ResourceViewerPage({
58468
58262
  setWizardDefaultTitle(event.defaultTitle);
58469
58263
  setWizardEntityTypes(event.entityTypes);
58470
58264
  setWizardOpen(true);
58471
- eventBus.get("gather:requested").next({ annotationId: event.annotationId, resourceId: event.resourceId });
58265
+ eventBus.get("gather:requested").next({ correlationId: crypto.randomUUID(), annotationId: event.annotationId, resourceId: event.resourceId });
58472
58266
  });
58473
58267
  return () => subscription.unsubscribe();
58474
58268
  }, [eventBus]);
@@ -58488,7 +58282,7 @@ function ResourceViewerPage({
58488
58282
  }, [onGenerateDocument]);
58489
58283
  const handleWizardLinkResource = useCallback38((referenceId, targetResourceId) => {
58490
58284
  eventBus.get("bind:update-body").next({
58491
- annotationId: annotationId3(referenceId),
58285
+ annotationId: annotationId2(referenceId),
58492
58286
  resourceId: rUri,
58493
58287
  operations: [{
58494
58288
  op: "add",
@@ -58514,13 +58308,6 @@ function ResourceViewerPage({
58514
58308
  reason: "compose-from-wizard"
58515
58309
  });
58516
58310
  }, []);
58517
- const debouncedInvalidateAnnotations = useDebouncedCallback(
58518
- () => {
58519
- queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.annotations(rUri) });
58520
- queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.events(rUri) });
58521
- },
58522
- 500
58523
- );
58524
58311
  useEffect52(() => {
58525
58312
  if (resource && rUri) {
58526
58313
  const mediaType = getPrimaryMediaType2(resource);
@@ -58533,68 +58320,31 @@ function ResourceViewerPage({
58533
58320
  useResourceEvents({
58534
58321
  rUri,
58535
58322
  autoConnect: true,
58536
- // Annotation events - use debounced invalidation to batch rapid updates
58537
58323
  onAnnotationAdded: useCallback38((_event) => {
58538
- debouncedInvalidateAnnotations();
58539
- }, [debouncedInvalidateAnnotations]),
58324
+ queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.events(rUri) });
58325
+ }, [queryClient, rUri]),
58540
58326
  onAnnotationRemoved: useCallback38((_event) => {
58541
- debouncedInvalidateAnnotations();
58542
- }, [debouncedInvalidateAnnotations]),
58543
- onAnnotationBodyUpdated: useCallback38((event) => {
58544
- queryClient.setQueryData(QUERY_KEYS.resources.annotations(rUri), (old) => {
58545
- if (!old) return old;
58546
- return {
58547
- ...old,
58548
- annotations: old.annotations.map((annotation) => {
58549
- if (annotation.id === event.payload.annotationId) {
58550
- let bodyArray = Array.isArray(annotation.body) ? [...annotation.body] : [];
58551
- for (const op of event.payload.operations || []) {
58552
- if (op.op === "add") {
58553
- bodyArray.push(op.item);
58554
- } else if (op.op === "remove") {
58555
- bodyArray = bodyArray.filter(
58556
- (item) => JSON.stringify(item) !== JSON.stringify(op.item)
58557
- );
58558
- } else if (op.op === "replace") {
58559
- const index2 = bodyArray.findIndex(
58560
- (item) => JSON.stringify(item) === JSON.stringify(op.oldItem)
58561
- );
58562
- if (index2 !== -1) {
58563
- bodyArray[index2] = op.newItem;
58564
- }
58565
- }
58566
- }
58567
- return {
58568
- ...annotation,
58569
- body: bodyArray
58570
- };
58571
- }
58572
- return annotation;
58573
- })
58574
- };
58575
- });
58327
+ queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.events(rUri) });
58328
+ }, [queryClient, rUri]),
58329
+ onAnnotationBodyUpdated: useCallback38((_event) => {
58576
58330
  queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.events(rUri) });
58577
58331
  }, [queryClient, rUri]),
58578
58332
  // Document status events
58579
58333
  onDocumentArchived: useCallback38((_event) => {
58580
58334
  refetchDocument();
58581
58335
  showSuccess("This document has been archived");
58582
- debouncedInvalidateAnnotations();
58583
- }, [refetchDocument, showSuccess, debouncedInvalidateAnnotations]),
58336
+ }, [refetchDocument, showSuccess]),
58584
58337
  onDocumentUnarchived: useCallback38((_event) => {
58585
58338
  refetchDocument();
58586
58339
  showSuccess("This document has been unarchived");
58587
- debouncedInvalidateAnnotations();
58588
- }, [refetchDocument, showSuccess, debouncedInvalidateAnnotations]),
58340
+ }, [refetchDocument, showSuccess]),
58589
58341
  // Entity tag events
58590
58342
  onEntityTagAdded: useCallback38((_event) => {
58591
58343
  refetchDocument();
58592
- debouncedInvalidateAnnotations();
58593
- }, [refetchDocument, debouncedInvalidateAnnotations]),
58344
+ }, [refetchDocument]),
58594
58345
  onEntityTagRemoved: useCallback38((_event) => {
58595
58346
  refetchDocument();
58596
- debouncedInvalidateAnnotations();
58597
- }, [refetchDocument, debouncedInvalidateAnnotations]),
58347
+ }, [refetchDocument]),
58598
58348
  onError: useCallback38((error) => {
58599
58349
  console.error("[RealTime] Event stream error:", error);
58600
58350
  }, [])
@@ -58629,13 +58379,12 @@ function ResourceViewerPage({
58629
58379
  showError("Failed to generate clone link");
58630
58380
  }
58631
58381
  }, [generateCloneTokenMutation, rUri, showError]);
58632
- const handleAnnotationSparkle = useCallback38(({ annotationId: annotationId4 }) => {
58633
- triggerSparkleAnimation(annotationId4);
58382
+ const handleAnnotationSparkle = useCallback38(({ annotationId: annotationId3 }) => {
58383
+ triggerSparkleAnimation(annotationId3);
58634
58384
  }, [triggerSparkleAnimation]);
58635
58385
  const handleAnnotationAdded = useCallback38((event) => {
58636
58386
  triggerSparkleAnimation(event.payload.annotation.id);
58637
- debouncedInvalidateAnnotations();
58638
- }, [triggerSparkleAnimation, debouncedInvalidateAnnotations]);
58387
+ }, [triggerSparkleAnimation]);
58639
58388
  const handleAnnotationCreateFailed = useCallback38(() => showError("Failed to create annotation"), [showError]);
58640
58389
  const handleAnnotationDeleteFailed = useCallback38(() => showError("Failed to delete annotation"), [showError]);
58641
58390
  const handleAnnotateBodyUpdated = useCallback38(() => {
@@ -58643,11 +58392,9 @@ function ResourceViewerPage({
58643
58392
  const handleAnnotateBodyUpdateFailed = useCallback38(() => showError("Failed to update annotation"), [showError]);
58644
58393
  const handleSettingsThemeChanged = useCallback38(({ theme: theme3 }) => setTheme(theme3), [setTheme]);
58645
58394
  const handleDetectionComplete = useCallback38(() => {
58646
- queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.annotations(rUri) });
58647
58395
  queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.events(rUri) });
58648
58396
  }, [queryClient, rUri]);
58649
58397
  const handleDetectionFailed = useCallback38(() => {
58650
- queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.annotations(rUri) });
58651
58398
  queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.events(rUri) });
58652
58399
  }, [queryClient, rUri]);
58653
58400
  const handleGenerationComplete = useCallback38(() => {
@@ -58660,9 +58407,9 @@ function ResourceViewerPage({
58660
58407
  eventBus.get("browse:router-push").next({ path: path2, reason: "reference-link" });
58661
58408
  }
58662
58409
  }, [routes.resourceDetail]);
58663
- const handleEntityTypeClicked = useCallback38(({ entityType: entityType3 }) => {
58410
+ const handleEntityTypeClicked = useCallback38(({ entityType: entityType2 }) => {
58664
58411
  if (routes.know) {
58665
- const path2 = `${routes.know}?entityType=${encodeURIComponent(entityType3)}`;
58412
+ const path2 = `${routes.know}?entityType=${encodeURIComponent(entityType2)}`;
58666
58413
  eventBus.get("browse:router-push").next({ path: path2, reason: "entity-type-filter" });
58667
58414
  }
58668
58415
  }, [routes.know]);
@@ -58676,7 +58423,6 @@ function ResourceViewerPage({
58676
58423
  "yield:clone": handleResourceClone,
58677
58424
  "beckon:sparkle": handleAnnotationSparkle,
58678
58425
  "mark:added": handleAnnotationAdded,
58679
- "mark:removed": debouncedInvalidateAnnotations,
58680
58426
  "mark:create-failed": handleAnnotationCreateFailed,
58681
58427
  "mark:delete-failed": handleAnnotationDeleteFailed,
58682
58428
  "mark:body-updated": handleAnnotateBodyUpdated,
@@ -58711,7 +58457,7 @@ function ResourceViewerPage({
58711
58457
  }
58712
58458
  return false;
58713
58459
  });
58714
- const groups = useMemo14(() => {
58460
+ const groups = useMemo13(() => {
58715
58461
  const result = {
58716
58462
  highlights: [],
58717
58463
  references: [],
@@ -58731,9 +58477,9 @@ function ResourceViewerPage({
58731
58477
  return result;
58732
58478
  }, [annotations]);
58733
58479
  const resourceWithContent = { ...resource, content: content4 };
58734
- const handleEventHover = useCallback38((annotationId4) => {
58735
- if (annotationId4) {
58736
- eventBus.get("beckon:sparkle").next({ annotationId: annotationId4 });
58480
+ const handleEventHover = useCallback38((annotationId3) => {
58481
+ if (annotationId3) {
58482
+ eventBus.get("beckon:sparkle").next({ annotationId: annotationId3 });
58737
58483
  }
58738
58484
  }, []);
58739
58485
  const handleEventClick = useCallback38((_annotationId) => {
@@ -58835,7 +58581,7 @@ function ResourceViewerPage({
58835
58581
  activePanel === "collaboration" && /* @__PURE__ */ jsx89(
58836
58582
  CollaborationPanel,
58837
58583
  {
58838
- isConnected: false,
58584
+ isConnected: streamStatus === "connected",
58839
58585
  eventCount: 0
58840
58586
  }
58841
58587
  ),
@@ -58911,6 +58657,34 @@ function ResourceViewerPage({
58911
58657
  )
58912
58658
  ] });
58913
58659
  }
58660
+
58661
+ // src/hooks/useObservable.ts
58662
+ import { useState as useState51, useEffect as useEffect53 } from "react";
58663
+ function useObservable(obs$) {
58664
+ const [value, setValue] = useState51(void 0);
58665
+ useEffect53(() => {
58666
+ const sub = obs$.subscribe(setValue);
58667
+ return () => sub.unsubscribe();
58668
+ }, [obs$]);
58669
+ return value;
58670
+ }
58671
+
58672
+ // src/hooks/useStoreTokenSync.ts
58673
+ import { useEffect as useEffect54, useRef as useRef39 } from "react";
58674
+ import { accessToken as accessToken8 } from "@semiont/core";
58675
+ function useStoreTokenSync() {
58676
+ const client = useApiClient();
58677
+ const token = useAuthToken();
58678
+ const tokenRef = useRef39(token);
58679
+ useEffect54(() => {
58680
+ tokenRef.current = token;
58681
+ });
58682
+ useEffect54(() => {
58683
+ const getter = () => tokenRef.current ? accessToken8(tokenRef.current) : void 0;
58684
+ client.stores.resources.setTokenGetter(getter);
58685
+ client.stores.annotations.setTokenGetter(getter);
58686
+ }, [client]);
58687
+ }
58914
58688
  export {
58915
58689
  ANNOTATORS,
58916
58690
  AUTH_EVENTS,
@@ -59048,7 +58822,6 @@ export {
59048
58822
  jsonLightHighlightStyle,
59049
58823
  jsonLightTheme,
59050
58824
  onAuthEvent,
59051
- resetEventBusForTesting,
59052
58825
  resolveAnnotationRanges,
59053
58826
  sanitizeImageURL,
59054
58827
  saveSelectedShapeForSelectorType,
@@ -59090,6 +58863,7 @@ export {
59090
58863
  useLocalStorage,
59091
58864
  useMarkFlow,
59092
58865
  useModeration,
58866
+ useObservable,
59093
58867
  useObservableExternalNavigation,
59094
58868
  useObservableRouter,
59095
58869
  useOpenResources,
@@ -59105,6 +58879,7 @@ export {
59105
58879
  useSearchAnnouncements,
59106
58880
  useSessionContext,
59107
58881
  useSessionExpiry,
58882
+ useStoreTokenSync,
59108
58883
  useTheme,
59109
58884
  useToast,
59110
58885
  useTranslations,