@semiont/react-ui 0.2.33 → 0.2.34-build.89

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 (82) hide show
  1. package/dist/EventBusContext-BmzEcGHZ.d.mts +177 -0
  2. package/dist/{PdfAnnotationCanvas.client-FGV33CWN.mjs → PdfAnnotationCanvas.client-VLNA5O5M.mjs} +7 -7
  3. package/dist/PdfAnnotationCanvas.client-VLNA5O5M.mjs.map +1 -0
  4. package/dist/{chunk-YPYLOBA2.mjs → chunk-C63BARI7.mjs} +3 -2
  5. package/dist/chunk-C63BARI7.mjs.map +1 -0
  6. package/dist/{chunk-FC6SGLLT.mjs → chunk-M7SZRRIE.mjs} +24 -16
  7. package/dist/chunk-M7SZRRIE.mjs.map +1 -0
  8. package/dist/chunk-ULIET3MW.mjs +31 -0
  9. package/dist/chunk-ULIET3MW.mjs.map +1 -0
  10. package/dist/index.d.mts +33 -60
  11. package/dist/index.mjs +171 -363
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/test-utils.d.mts +3 -5
  14. package/dist/test-utils.mjs +2 -2
  15. package/dist/test-utils.mjs.map +1 -1
  16. package/package.json +2 -3
  17. package/src/components/CodeMirrorRenderer.tsx +4 -4
  18. package/src/components/DetectionProgressWidget.tsx +3 -3
  19. package/src/components/LiveRegion.tsx +1 -1
  20. package/src/components/Toolbar.tsx +1 -1
  21. package/src/components/annotation/AnnotateToolbar.tsx +5 -5
  22. package/src/components/annotation/__tests__/AnnotateToolbar.test.tsx +4 -4
  23. package/src/components/annotation-popups/JsonLdView.tsx +1 -1
  24. package/src/components/image-annotation/AnnotationOverlay.tsx +9 -9
  25. package/src/components/image-annotation/SvgDrawingCanvas.tsx +5 -5
  26. package/src/components/navigation/CollapsibleResourceNavigation.tsx +4 -4
  27. package/src/components/navigation/ObservableLink.tsx +1 -1
  28. package/src/components/navigation/SimpleNavigation.tsx +1 -1
  29. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +6 -6
  30. package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +2 -2
  31. package/src/components/resource/AnnotateView.tsx +5 -4
  32. package/src/components/resource/AnnotationHistory.tsx +1 -1
  33. package/src/components/resource/BrowseView.tsx +5 -4
  34. package/src/components/resource/ResourceViewer.tsx +5 -4
  35. package/src/components/resource/__tests__/BrowseView.test.tsx +11 -22
  36. package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +1 -1
  37. package/src/components/resource/event-formatting.ts +1 -1
  38. package/src/components/resource/panels/AssessmentEntry.tsx +2 -2
  39. package/src/components/resource/panels/AssessmentPanel.tsx +4 -4
  40. package/src/components/resource/panels/CommentEntry.tsx +2 -2
  41. package/src/components/resource/panels/CommentsPanel.tsx +4 -4
  42. package/src/components/resource/panels/DetectSection.tsx +3 -3
  43. package/src/components/resource/panels/HighlightEntry.tsx +2 -2
  44. package/src/components/resource/panels/HighlightPanel.tsx +2 -2
  45. package/src/components/resource/panels/JsonLdPanel.tsx +1 -1
  46. package/src/components/resource/panels/ReferenceEntry.tsx +6 -6
  47. package/src/components/resource/panels/ReferencesPanel.tsx +5 -5
  48. package/src/components/resource/panels/ResourceInfoPanel.tsx +3 -3
  49. package/src/components/resource/panels/StatisticsPanel.tsx +1 -1
  50. package/src/components/resource/panels/TagEntry.tsx +2 -2
  51. package/src/components/resource/panels/TaggingPanel.tsx +5 -5
  52. package/src/components/resource/panels/UnifiedAnnotationsPanel.tsx +1 -1
  53. package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +5 -5
  54. package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +10 -10
  55. package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +5 -5
  56. package/src/components/resource/panels/__tests__/DetectSection.test.tsx +9 -9
  57. package/src/components/resource/panels/__tests__/HighlightPanel.detectionProgress.test.tsx +1 -1
  58. package/src/components/resource/panels/__tests__/JsonLdPanel.test.tsx +1 -1
  59. package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +4 -4
  60. package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +4 -4
  61. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +5 -5
  62. package/src/components/settings/SettingsPanel.tsx +5 -5
  63. package/src/components/viewers/ImageViewer.tsx +1 -1
  64. package/src/features/resource-compose/components/ResourceComposePage.tsx +1 -1
  65. package/src/features/resource-discovery/components/ResourceCard.tsx +1 -1
  66. package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +1 -1
  67. package/src/features/resource-viewer/__tests__/AnnotationCreationPending.test.tsx +7 -5
  68. package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +5 -4
  69. package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +5 -5
  70. package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +29 -43
  71. package/src/features/resource-viewer/__tests__/DetectionProgressDismissal.test.tsx +20 -39
  72. package/src/features/resource-viewer/__tests__/GenerationFlowIntegration.test.tsx +38 -46
  73. package/src/features/resource-viewer/__tests__/ResolutionFlowIntegration.test.tsx +36 -43
  74. package/src/features/resource-viewer/__tests__/ResourceMutations.test.tsx +8 -8
  75. package/src/features/resource-viewer/__tests__/detection-progress-flow.test.tsx +14 -21
  76. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +8 -7
  77. package/dist/EventBusContext-CJjL_cCf.d.mts +0 -462
  78. package/dist/PdfAnnotationCanvas.client-FGV33CWN.mjs.map +0 -1
  79. package/dist/chunk-FC6SGLLT.mjs.map +0 -1
  80. package/dist/chunk-XS27QKGP.mjs +0 -55
  81. package/dist/chunk-XS27QKGP.mjs.map +0 -1
  82. package/dist/chunk-YPYLOBA2.mjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  useEventSubscription,
7
7
  useEventSubscriptions,
8
8
  useHoverEmitter
9
- } from "./chunk-FC6SGLLT.mjs";
9
+ } from "./chunk-M7SZRRIE.mjs";
10
10
  import {
11
11
  AVAILABLE_LOCALES,
12
12
  ApiClientProvider,
@@ -21,12 +21,12 @@ import {
21
21
  useSessionContext,
22
22
  useToast,
23
23
  useTranslations
24
- } from "./chunk-YPYLOBA2.mjs";
24
+ } from "./chunk-C63BARI7.mjs";
25
25
  import {
26
26
  EventBusProvider,
27
27
  resetEventBusForTesting,
28
28
  useEventBus
29
- } from "./chunk-XS27QKGP.mjs";
29
+ } from "./chunk-ULIET3MW.mjs";
30
30
  import "./chunk-D7NBW4RV.mjs";
31
31
  import {
32
32
  __commonJS,
@@ -364,7 +364,7 @@ var require_extend = __commonJS({
364
364
  });
365
365
 
366
366
  // src/lib/annotation-registry.ts
367
- import { entityType, isHighlight, isComment, isReference, isTag } from "@semiont/api-client";
367
+ import { isHighlight, isComment, isReference, isTag } from "@semiont/api-client";
368
368
  var ANNOTATORS = {
369
369
  highlight: {
370
370
  motivation: "highlighting",
@@ -530,122 +530,17 @@ var ANNOTATORS = {
530
530
  }
531
531
  }
532
532
  };
533
- function createDetectionHandler(annotator, context) {
534
- const { detection } = annotator;
535
- if (!detection) {
536
- throw new Error(`Annotator ${annotator.internalType} does not support detection`);
537
- }
538
- const detectionConfig = detection;
539
- return async (...args) => {
540
- if (!context.client) return;
541
- const requestParams = detectionConfig.formatRequestParams ? detectionConfig.formatRequestParams(args) : [];
542
- context.setDetectingMotivation(annotator.motivation);
543
- context.setMotivationDetectionProgress({
544
- status: "started",
545
- message: `Starting ${detectionConfig.displayNameSingular} detection...`,
546
- requestParams
547
- });
548
- function attachHandlers(stream) {
549
- context.detectionStreamRef.current = stream;
550
- stream.onProgress((progress) => {
551
- if (detectionConfig.sseMethod === "detectReferences") {
552
- const refProgress = progress;
553
- context.setMotivationDetectionProgress({
554
- status: refProgress.status,
555
- message: refProgress.message || (refProgress.currentEntityType ? `Detecting ${refProgress.currentEntityType}...` : `Processing ${refProgress.processedEntityTypes} of ${refProgress.totalEntityTypes} entity types...`),
556
- processedCategories: refProgress.processedEntityTypes,
557
- totalCategories: refProgress.totalEntityTypes,
558
- ...refProgress.currentEntityType && { currentCategory: refProgress.currentEntityType },
559
- requestParams
560
- });
561
- } else {
562
- context.setMotivationDetectionProgress({
563
- status: progress.status,
564
- percentage: progress.percentage,
565
- message: progress.message,
566
- ...progress.currentCategory && { currentCategory: progress.currentCategory },
567
- ...progress.processedCategories !== void 0 && { processedCategories: progress.processedCategories },
568
- ...progress.totalCategories !== void 0 && { totalCategories: progress.totalCategories },
569
- requestParams
570
- });
571
- }
572
- });
573
- stream.onComplete((result) => {
574
- const resultRecord = result;
575
- const count2 = resultRecord[detectionConfig.countField] ?? 0;
576
- context.setMotivationDetectionProgress({
577
- status: "complete",
578
- percentage: 100,
579
- message: `Created ${count2} ${count2 === 1 ? detectionConfig.displayNameSingular : detectionConfig.displayNamePlural}`,
580
- requestParams
581
- });
582
- context.setDetectingMotivation(null);
583
- context.detectionStreamRef.current = null;
584
- context.cacheManager.invalidateAnnotations(context.rUri);
585
- context.cacheManager.invalidateEvents(context.rUri);
586
- context.showSuccess(`Created ${count2} ${count2 === 1 ? detectionConfig.displayNameSingular : detectionConfig.displayNamePlural}`);
587
- });
588
- stream.onError((error) => {
589
- context.setMotivationDetectionProgress(null);
590
- context.setDetectingMotivation(null);
591
- context.detectionStreamRef.current = null;
592
- context.showError(`${annotator.displayName} detection failed: ${error.message}`);
593
- });
594
- }
595
- try {
596
- const sseClient = context.client.sse;
597
- if (detectionConfig.sseMethod === "detectReferences") {
598
- const selectedTypes = Array.isArray(args[0]) ? args[0] : [];
599
- const includeDescriptiveReferences = args[1] === true;
600
- attachHandlers(sseClient.detectReferences(context.rUri, {
601
- entityTypes: selectedTypes.map((t12) => entityType(t12)),
602
- includeDescriptiveReferences
603
- }));
604
- } else if (detectionConfig.sseMethod === "detectTags") {
605
- const schemaId = typeof args[0] === "string" ? args[0] : "";
606
- const categories = Array.isArray(args[1]) ? args[1] : [];
607
- attachHandlers(sseClient.detectTags(context.rUri, { schemaId, categories }));
608
- } else if (detectionConfig.sseMethod === "detectHighlights") {
609
- const instructions = typeof args[0] === "string" ? args[0] : void 0;
610
- attachHandlers(sseClient.detectHighlights(context.rUri, { instructions }));
611
- } else if (detectionConfig.sseMethod === "detectComments") {
612
- const instructions = typeof args[0] === "string" ? args[0] : void 0;
613
- attachHandlers(sseClient.detectComments(context.rUri, { instructions }));
614
- } else if (detectionConfig.sseMethod === "detectAssessments") {
615
- const instructions = typeof args[0] === "string" ? args[0] : void 0;
616
- attachHandlers(sseClient.detectAssessments(context.rUri, { instructions }));
617
- } else {
618
- throw new Error(`Unknown detection method: ${detectionConfig.sseMethod}`);
619
- }
620
- } catch (error) {
621
- context.setDetectingMotivation(null);
622
- context.setMotivationDetectionProgress(null);
623
- context.detectionStreamRef.current = null;
624
- context.showError(`Failed to start ${detectionConfig.displayNameSingular} detection`);
625
- }
626
- };
627
- }
628
- function createCancelDetectionHandler(context) {
629
- return () => {
630
- if (context.detectionStreamRef.current) {
631
- context.detectionStreamRef.current.close();
632
- context.detectionStreamRef.current = null;
633
- }
634
- context.setDetectingMotivation(null);
635
- context.setMotivationDetectionProgress(null);
636
- };
637
- }
638
533
 
639
534
  // src/lib/api-hooks.ts
640
535
  import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
641
536
  import {
642
537
  searchQuery,
643
538
  cloneToken,
644
- entityType as entityType2,
539
+ entityType,
645
540
  userDID,
646
- accessToken,
647
- decodeWithCharset
648
- } from "@semiont/api-client";
541
+ accessToken
542
+ } from "@semiont/core";
543
+ import { decodeWithCharset } from "@semiont/api-client";
649
544
  import { extractResourceUriFromAnnotationUri, uriToAnnotationId } from "@semiont/core";
650
545
 
651
546
  // src/lib/query-keys.ts
@@ -992,7 +887,7 @@ function useEntityTypes() {
992
887
  return useMutation({
993
888
  mutationFn: (type) => {
994
889
  if (!client) throw new Error("Not authenticated");
995
- return client.addEntityType(entityType2(type), { auth: toAccessToken(token2) });
890
+ return client.addEntityType(entityType(type), { auth: toAccessToken(token2) });
996
891
  },
997
892
  onSuccess: () => {
998
893
  queryClient.invalidateQueries({ queryKey: QUERY_KEYS.entityTypes.all() });
@@ -1006,7 +901,7 @@ function useEntityTypes() {
1006
901
  return useMutation({
1007
902
  mutationFn: (types2) => {
1008
903
  if (!client) throw new Error("Not authenticated");
1009
- return client.addEntityTypesBulk(types2.map(entityType2), { auth: toAccessToken(token2) });
904
+ return client.addEntityTypesBulk(types2.map(entityType), { auth: toAccessToken(token2) });
1010
905
  },
1011
906
  onSuccess: () => {
1012
907
  queryClient.invalidateQueries({ queryKey: QUERY_KEYS.entityTypes.all() });
@@ -17358,7 +17253,7 @@ var ReferenceResolutionWidget = class extends WidgetType {
17358
17253
  indicator.addEventListener("click", (e6) => {
17359
17254
  e6.preventDefault();
17360
17255
  e6.stopPropagation();
17361
- eventBus.emit("navigation:reference-navigate", { documentId: bodySource });
17256
+ eventBus.get("navigation:reference-navigate").next({ documentId: bodySource });
17362
17257
  });
17363
17258
  } else if (!isResolved && this.eventBus) {
17364
17259
  const eventBus = this.eventBus;
@@ -17366,7 +17261,7 @@ var ReferenceResolutionWidget = class extends WidgetType {
17366
17261
  indicator.addEventListener("click", (e6) => {
17367
17262
  e6.preventDefault();
17368
17263
  e6.stopPropagation();
17369
- eventBus.emit("annotation:click", { annotationId: annotation.id, motivation: annotation.motivation });
17264
+ eventBus.get("annotation:click").next({ annotationId: annotation.id, motivation: annotation.motivation });
17370
17265
  });
17371
17266
  }
17372
17267
  }
@@ -18066,7 +17961,9 @@ function isTag2(annotation) {
18066
17961
  function getTagCategory(annotation) {
18067
17962
  if (!isTag2(annotation)) return void 0;
18068
17963
  const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];
18069
- const taggingBody = bodies.find((b8) => b8 && "purpose" in b8 && b8.purpose === "tagging");
17964
+ const taggingBody = bodies.find(
17965
+ (b8) => b8 !== null && typeof b8 === "object" && "purpose" in b8 && b8.purpose === "tagging"
17966
+ );
18070
17967
  if (taggingBody && "value" in taggingBody) {
18071
17968
  return taggingBody.value;
18072
17969
  }
@@ -18075,7 +17972,9 @@ function getTagCategory(annotation) {
18075
17972
  function getTagSchemaId(annotation) {
18076
17973
  if (!isTag2(annotation)) return void 0;
18077
17974
  const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];
18078
- const classifyingBody = bodies.find((b8) => b8 && "purpose" in b8 && b8.purpose === "classifying");
17975
+ const classifyingBody = bodies.find(
17976
+ (b8) => b8 !== null && typeof b8 === "object" && "purpose" in b8 && b8.purpose === "classifying"
17977
+ );
18079
17978
  if (classifyingBody && "value" in classifyingBody) {
18080
17979
  return classifyingBody.value;
18081
17980
  }
@@ -18375,7 +18274,7 @@ import { useCallback as useCallback4 } from "react";
18375
18274
  function useObservableRouter(baseRouter) {
18376
18275
  const eventBus = useEventBus();
18377
18276
  const push2 = useCallback4((path2, options) => {
18378
- eventBus.emit("navigation:router-push", {
18277
+ eventBus.get("navigation:router-push").next({
18379
18278
  path: path2,
18380
18279
  reason: options?.reason
18381
18280
  });
@@ -18383,7 +18282,7 @@ function useObservableRouter(baseRouter) {
18383
18282
  }, []);
18384
18283
  const replace3 = useCallback4((path2, options) => {
18385
18284
  if (!baseRouter.replace) return;
18386
- eventBus.emit("navigation:router-push", {
18285
+ eventBus.get("navigation:router-push").next({
18387
18286
  path: path2,
18388
18287
  reason: options?.reason ? `replace:${options.reason}` : "replace"
18389
18288
  });
@@ -18404,7 +18303,7 @@ function useObservableExternalNavigation() {
18404
18303
  );
18405
18304
  window.location.href = url;
18406
18305
  }, 10);
18407
- eventBus.emit("navigation:external-navigate", {
18306
+ eventBus.get("navigation:external-navigate").next({
18408
18307
  url,
18409
18308
  resourceId: metadata?.resourceId,
18410
18309
  cancelFallback: () => clearTimeout(fallbackTimer)
@@ -18448,7 +18347,7 @@ function usePanelWidth({
18448
18347
 
18449
18348
  // src/hooks/useResourceEvents.ts
18450
18349
  import { useEffect as useEffect4, useState as useState4, useRef as useRef4, useCallback as useCallback5 } from "react";
18451
- import { accessToken as accessToken2 } from "@semiont/api-client";
18350
+ import { accessToken as accessToken2 } from "@semiont/core";
18452
18351
  function useResourceEvents({
18453
18352
  rUri,
18454
18353
  onEvent,
@@ -18464,6 +18363,7 @@ function useResourceEvents({
18464
18363
  }) {
18465
18364
  const client = useApiClient();
18466
18365
  const token = useAuthToken();
18366
+ const eventBus = useEventBus();
18467
18367
  const [status, setStatus] = useState4("disconnected");
18468
18368
  const [lastEvent, setLastEvent] = useState4(null);
18469
18369
  const [eventCount, setEventCount] = useState4(0);
@@ -18519,6 +18419,12 @@ function useResourceEvents({
18519
18419
  break;
18520
18420
  }
18521
18421
  }, []);
18422
+ useEffect4(() => {
18423
+ const subscription = eventBus.get("make-meaning:event").subscribe((event) => {
18424
+ handleEvent(event);
18425
+ });
18426
+ return () => subscription.unsubscribe();
18427
+ }, [eventBus, handleEvent]);
18522
18428
  const connect = useCallback5(async () => {
18523
18429
  if (connectingRef.current || streamRef.current) {
18524
18430
  return;
@@ -18539,40 +18445,20 @@ function useResourceEvents({
18539
18445
  try {
18540
18446
  const stream = client.sse.resourceEvents(rUri, {
18541
18447
  ...token ? { auth: accessToken2(token) } : {},
18542
- onConnected: () => {
18543
- setStatus("connected");
18544
- reconnectAttemptsRef.current = 0;
18545
- }
18448
+ eventBus
18449
+ // ← Stream auto-emits to EventBus
18546
18450
  });
18547
18451
  streamRef.current = stream;
18548
- stream.onProgress((event) => {
18549
- handleEvent(event);
18550
- });
18551
- stream.onError((error) => {
18552
- console.error(`[ResourceEvents] Stream error for ${rUri}:`, error);
18553
- setStatus("error");
18554
- if (error.message.includes("404")) {
18555
- console.error(`[ResourceEvents] Document ${rUri} not found (404). Stopping reconnection attempts.`);
18556
- onErrorRef.current?.("Document not found");
18557
- streamRef.current = null;
18558
- connectingRef.current = false;
18559
- return;
18560
- }
18561
- reconnectAttemptsRef.current++;
18562
- const delay = reconnectAttemptsRef.current === 1 ? 100 : Math.min(1e3 * Math.pow(2, reconnectAttemptsRef.current - 2), 3e4);
18563
- reconnectTimeoutRef.current = setTimeout(() => {
18564
- if (!streamRef.current) {
18565
- connect();
18566
- }
18567
- }, delay);
18568
- });
18452
+ setStatus("connected");
18453
+ reconnectAttemptsRef.current = 0;
18454
+ connectingRef.current = false;
18569
18455
  } catch (error) {
18570
18456
  console.error("[ResourceEvents] Failed to connect:", error);
18571
18457
  setStatus("error");
18572
18458
  onErrorRef.current?.("Failed to connect to event stream");
18573
18459
  connectingRef.current = false;
18574
18460
  }
18575
- }, [rUri, handleEvent, client]);
18461
+ }, [rUri, client, token, eventBus]);
18576
18462
  const disconnect = useCallback5(() => {
18577
18463
  if (streamRef.current) {
18578
18464
  streamRef.current.close();
@@ -26693,7 +26579,7 @@ function CodeMirrorRenderer({
26693
26579
  const segment = segmentsRef.current.find((s11) => s11.annotation?.id === annotationId);
26694
26580
  if (segment?.annotation) {
26695
26581
  event.preventDefault();
26696
- eventBusRef.current.emit("annotation:click", {
26582
+ eventBusRef.current.get("annotation:click").next({
26697
26583
  annotationId,
26698
26584
  motivation: segment.annotation.motivation
26699
26585
  });
@@ -26754,7 +26640,7 @@ function CodeMirrorRenderer({
26754
26640
  containerRef.current.__cmView = view;
26755
26641
  const container = view.dom;
26756
26642
  const { handleMouseEnter, handleMouseLeave, cleanup: cleanupHover } = createHoverHandlers(
26757
- (annotationId) => eventBusRef.current?.emit("annotation:hover", { annotationId })
26643
+ (annotationId) => eventBusRef.current?.get("annotation:hover").next({ annotationId })
26758
26644
  );
26759
26645
  const handleMouseOver = (e6) => {
26760
26646
  const target = e6.target;
@@ -26899,7 +26785,7 @@ function DetectionProgressWidget({ progress, annotationType = "reference" }) {
26899
26785
  const t12 = useTranslations("DetectionProgressWidget");
26900
26786
  const eventBus = useEventBus();
26901
26787
  const handleCancel = () => {
26902
- eventBus.emit("job:cancel-requested", { jobType: "detection" });
26788
+ eventBus.get("job:cancel-requested").next({ jobType: "detection" });
26903
26789
  };
26904
26790
  if (!progress) return null;
26905
26791
  return /* @__PURE__ */ jsxs2(
@@ -27194,7 +27080,7 @@ function Toolbar({
27194
27080
  const t12 = useTranslations("Toolbar");
27195
27081
  const eventBus = useEventBus();
27196
27082
  const handlePanelToggle = (panel) => {
27197
- eventBus.emit("panel:toggle", { panel });
27083
+ eventBus.get("panel:toggle").next({ panel });
27198
27084
  };
27199
27085
  return /* @__PURE__ */ jsxs4("div", { className: "semiont-toolbar", "data-context": context, children: [
27200
27086
  context === "document" && /* @__PURE__ */ jsxs4(Fragment, { children: [
@@ -27310,7 +27196,7 @@ function SettingsPanel({
27310
27196
  const handleLocaleChange = (newLocale) => {
27311
27197
  const localeName = LOCALES.find((l10) => l10.code === newLocale)?.nativeName || newLocale;
27312
27198
  announceLanguageChanging(localeName);
27313
- eventBus.emit("settings:locale-changed", { locale: newLocale });
27199
+ eventBus.get("settings:locale-changed").next({ locale: newLocale });
27314
27200
  };
27315
27201
  useEffect12(() => {
27316
27202
  if (locale !== previousLocale && !isPendingLocaleChange) {
@@ -27331,7 +27217,7 @@ function SettingsPanel({
27331
27217
  type: "button",
27332
27218
  role: "switch",
27333
27219
  "aria-checked": showLineNumbers,
27334
- onClick: () => eventBus.emit("settings:line-numbers-toggled", void 0),
27220
+ onClick: () => eventBus.get("settings:line-numbers-toggled").next(void 0),
27335
27221
  className: `semiont-toggle ${showLineNumbers ? "semiont-toggle--active" : ""}`,
27336
27222
  children: /* @__PURE__ */ jsx14(
27337
27223
  "span",
@@ -27350,7 +27236,7 @@ function SettingsPanel({
27350
27236
  /* @__PURE__ */ jsxs5(
27351
27237
  "button",
27352
27238
  {
27353
- onClick: () => eventBus.emit("settings:theme-changed", { theme: "light" }),
27239
+ onClick: () => eventBus.get("settings:theme-changed").next({ theme: "light" }),
27354
27240
  className: `semiont-panel-button ${theme2 === "light" ? "semiont-panel-button-active" : ""}`,
27355
27241
  "aria-pressed": theme2 === "light",
27356
27242
  children: [
@@ -27362,7 +27248,7 @@ function SettingsPanel({
27362
27248
  /* @__PURE__ */ jsxs5(
27363
27249
  "button",
27364
27250
  {
27365
- onClick: () => eventBus.emit("settings:theme-changed", { theme: "dark" }),
27251
+ onClick: () => eventBus.get("settings:theme-changed").next({ theme: "dark" }),
27366
27252
  className: `semiont-panel-button ${theme2 === "dark" ? "semiont-panel-button-active" : ""}`,
27367
27253
  "aria-pressed": theme2 === "dark",
27368
27254
  children: [
@@ -27374,7 +27260,7 @@ function SettingsPanel({
27374
27260
  /* @__PURE__ */ jsxs5(
27375
27261
  "button",
27376
27262
  {
27377
- onClick: () => eventBus.emit("settings:theme-changed", { theme: "system" }),
27263
+ onClick: () => eventBus.get("settings:theme-changed").next({ theme: "system" }),
27378
27264
  className: `semiont-panel-button ${theme2 === "system" ? "semiont-panel-button-active" : ""}`,
27379
27265
  "aria-pressed": theme2 === "system",
27380
27266
  children: [
@@ -27531,9 +27417,9 @@ function AnnotateToolbar({
27531
27417
  }, []);
27532
27418
  const handleSelectionClick = (motivation) => {
27533
27419
  if (motivation === null) {
27534
- eventBus.emit("toolbar:selection-changed", { motivation: null });
27420
+ eventBus.get("toolbar:selection-changed").next({ motivation: null });
27535
27421
  } else {
27536
- eventBus.emit("toolbar:selection-changed", {
27422
+ eventBus.get("toolbar:selection-changed").next({
27537
27423
  motivation: selectedMotivation === motivation ? null : motivation
27538
27424
  });
27539
27425
  }
@@ -27541,17 +27427,17 @@ function AnnotateToolbar({
27541
27427
  setSelectionHovered(false);
27542
27428
  };
27543
27429
  const handleClickClick = (action) => {
27544
- eventBus.emit("toolbar:click-changed", { action });
27430
+ eventBus.get("toolbar:click-changed").next({ action });
27545
27431
  setClickPinned(false);
27546
27432
  setClickHovered(false);
27547
27433
  };
27548
27434
  const handleShapeClick = (shape) => {
27549
- eventBus.emit("toolbar:shape-changed", { shape });
27435
+ eventBus.get("toolbar:shape-changed").next({ shape });
27550
27436
  setShapePinned(false);
27551
27437
  setShapeHovered(false);
27552
27438
  };
27553
27439
  const handleModeToggle = () => {
27554
- eventBus.emit("view:mode-toggled", void 0);
27440
+ eventBus.get("view:mode-toggled").next(void 0);
27555
27441
  setModePinned(false);
27556
27442
  setModeHovered(false);
27557
27443
  };
@@ -29636,7 +29522,7 @@ function AnnotationOverlay({
29636
29522
  const scaleX = displayWidth / imageWidth;
29637
29523
  const scaleY = displayHeight / imageHeight;
29638
29524
  const { handleMouseEnter, handleMouseLeave } = useMemo2(
29639
- () => createHoverHandlers((annotationId) => eventBus?.emit("annotation:hover", { annotationId })),
29525
+ () => createHoverHandlers((annotationId) => eventBus?.get("annotation:hover").next({ annotationId })),
29640
29526
  [eventBus]
29641
29527
  );
29642
29528
  return /* @__PURE__ */ jsx18(
@@ -29677,7 +29563,7 @@ function AnnotationOverlay({
29677
29563
  className: "semiont-annotation-overlay__shape",
29678
29564
  "data-hovered": isHovered ? "true" : "false",
29679
29565
  "data-selected": isSelected ? "true" : "false",
29680
- onClick: () => eventBus?.emit("annotation:click", { annotationId: annotation.id, motivation: annotation.motivation }),
29566
+ onClick: () => eventBus?.get("annotation:click").next({ annotationId: annotation.id, motivation: annotation.motivation }),
29681
29567
  onMouseEnter: () => handleMouseEnter(annotation.id),
29682
29568
  onMouseLeave: handleMouseLeave
29683
29569
  }
@@ -29692,7 +29578,7 @@ function AnnotationOverlay({
29692
29578
  style: { userSelect: "none" },
29693
29579
  onClick: (e6) => {
29694
29580
  e6.stopPropagation();
29695
- eventBus?.emit("annotation:click", { annotationId: annotation.id, motivation: annotation.motivation });
29581
+ eventBus?.get("annotation:click").next({ annotationId: annotation.id, motivation: annotation.motivation });
29696
29582
  },
29697
29583
  onMouseEnter: () => handleMouseEnter(annotation.id),
29698
29584
  onMouseLeave: handleMouseLeave,
@@ -29722,7 +29608,7 @@ function AnnotationOverlay({
29722
29608
  className: "semiont-annotation-overlay__shape",
29723
29609
  "data-hovered": isHovered ? "true" : "false",
29724
29610
  "data-selected": isSelected ? "true" : "false",
29725
- onClick: () => eventBus?.emit("annotation:click", { annotationId: annotation.id, motivation: annotation.motivation }),
29611
+ onClick: () => eventBus?.get("annotation:click").next({ annotationId: annotation.id, motivation: annotation.motivation }),
29726
29612
  onMouseEnter: () => handleMouseEnter(annotation.id),
29727
29613
  onMouseLeave: handleMouseLeave
29728
29614
  }
@@ -29737,7 +29623,7 @@ function AnnotationOverlay({
29737
29623
  style: { userSelect: "none" },
29738
29624
  onClick: (e6) => {
29739
29625
  e6.stopPropagation();
29740
- eventBus?.emit("annotation:click", { annotationId: annotation.id, motivation: annotation.motivation });
29626
+ eventBus?.get("annotation:click").next({ annotationId: annotation.id, motivation: annotation.motivation });
29741
29627
  },
29742
29628
  onMouseEnter: () => handleMouseEnter(annotation.id),
29743
29629
  onMouseLeave: handleMouseLeave,
@@ -29771,7 +29657,7 @@ function AnnotationOverlay({
29771
29657
  className: "semiont-annotation-overlay__shape",
29772
29658
  "data-hovered": isHovered ? "true" : "false",
29773
29659
  "data-selected": isSelected ? "true" : "false",
29774
- onClick: () => eventBus?.emit("annotation:click", { annotationId: annotation.id, motivation: annotation.motivation }),
29660
+ onClick: () => eventBus?.get("annotation:click").next({ annotationId: annotation.id, motivation: annotation.motivation }),
29775
29661
  onMouseEnter: () => handleMouseEnter(annotation.id),
29776
29662
  onMouseLeave: handleMouseLeave
29777
29663
  }
@@ -29786,7 +29672,7 @@ function AnnotationOverlay({
29786
29672
  style: { userSelect: "none" },
29787
29673
  onClick: (e6) => {
29788
29674
  e6.stopPropagation();
29789
- eventBus?.emit("annotation:click", { annotationId: annotation.id, motivation: annotation.motivation });
29675
+ eventBus?.get("annotation:click").next({ annotationId: annotation.id, motivation: annotation.motivation });
29790
29676
  },
29791
29677
  onMouseEnter: () => handleMouseEnter(annotation.id),
29792
29678
  onMouseLeave: handleMouseLeave,
@@ -29942,7 +29828,7 @@ function SvgDrawingCanvas({
29942
29828
  return false;
29943
29829
  });
29944
29830
  if (clickedAnnotation) {
29945
- eventBus?.emit("annotation:click", { annotationId: clickedAnnotation.id, motivation: clickedAnnotation.motivation });
29831
+ eventBus?.get("annotation:click").next({ annotationId: clickedAnnotation.id, motivation: clickedAnnotation.motivation });
29946
29832
  setIsDrawing(false);
29947
29833
  setStartPoint(null);
29948
29834
  setCurrentPoint(null);
@@ -29994,7 +29880,7 @@ function SvgDrawingCanvas({
29994
29880
  imageDimensions.height
29995
29881
  );
29996
29882
  if (eventBus && selectedMotivation) {
29997
- eventBus.emit("annotation:requested", {
29883
+ eventBus.get("annotation:requested").next({
29998
29884
  selector: {
29999
29885
  type: "SvgSelector",
30000
29886
  value: nativeSvg
@@ -30417,9 +30303,10 @@ function ProposeEntitiesModal({
30417
30303
 
30418
30304
  // src/components/resource/AnnotateView.tsx
30419
30305
  import { useRef as useRef12, useEffect as useEffect18, useCallback as useCallback12, lazy, Suspense } from "react";
30420
- import { getTextPositionSelector, getTextQuoteSelector, getTargetSelector, getMimeCategory, isPdfMimeType as isPdfMimeType2, resourceUri as toResourceUri, extractContext, findTextWithContext } from "@semiont/api-client";
30306
+ import { resourceUri as toResourceUri } from "@semiont/core";
30307
+ import { getTextPositionSelector, getTextQuoteSelector, getTargetSelector, getMimeCategory, isPdfMimeType as isPdfMimeType2, extractContext, findTextWithContext } from "@semiont/api-client";
30421
30308
  import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
30422
- var PdfAnnotationCanvas = lazy(() => import("./PdfAnnotationCanvas.client-FGV33CWN.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
30309
+ var PdfAnnotationCanvas = lazy(() => import("./PdfAnnotationCanvas.client-VLNA5O5M.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
30423
30310
  function segmentTextWithAnnotations(content4, annotations) {
30424
30311
  if (!content4) {
30425
30312
  return [{ exact: "", start: 0, end: 0 }];
@@ -30556,7 +30443,7 @@ function AnnotateView({
30556
30443
  const end2 = start3 + text7.length;
30557
30444
  const context = extractContext(content4, start3, end2);
30558
30445
  if (selectedMotivation) {
30559
- eventBus.emit("annotation:requested", {
30446
+ eventBus.get("annotation:requested").next({
30560
30447
  selector: [
30561
30448
  {
30562
30449
  type: "TextPositionSelector",
@@ -30582,7 +30469,7 @@ function AnnotateView({
30582
30469
  if (start2 >= 0) {
30583
30470
  const context = extractContext(content4, start2, end);
30584
30471
  if (selectedMotivation) {
30585
- eventBus.emit("annotation:requested", {
30472
+ eventBus.get("annotation:requested").next({
30586
30473
  selector: [
30587
30474
  {
30588
30475
  type: "TextPositionSelector",
@@ -45454,7 +45341,8 @@ function remarkGfm(options) {
45454
45341
  }
45455
45342
 
45456
45343
  // src/components/resource/BrowseView.tsx
45457
- import { getExactText as getExactText2, getTextPositionSelector as getTextPositionSelector2, getTargetSelector as getTargetSelector3, getBodySource as getBodySource3, getMimeCategory as getMimeCategory2, isPdfMimeType as isPdfMimeType3, resourceUri as toResourceUri2 } from "@semiont/api-client";
45344
+ import { resourceUri as toResourceUri2 } from "@semiont/core";
45345
+ import { getExactText as getExactText2, getTextPositionSelector as getTextPositionSelector2, getTargetSelector as getTargetSelector3, getBodySource as getBodySource3, getMimeCategory as getMimeCategory2, isPdfMimeType as isPdfMimeType3 } from "@semiont/api-client";
45458
45346
 
45459
45347
  // src/components/viewers/ImageViewer.tsx
45460
45348
  import { jsx as jsx26 } from "react/jsx-runtime";
@@ -45474,7 +45362,7 @@ function ImageViewer({ resourceUri: resourceUri2, alt = "Resource image" }) {
45474
45362
 
45475
45363
  // src/components/resource/BrowseView.tsx
45476
45364
  import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
45477
- var PdfAnnotationCanvas2 = lazy2(() => import("./PdfAnnotationCanvas.client-FGV33CWN.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
45365
+ var PdfAnnotationCanvas2 = lazy2(() => import("./PdfAnnotationCanvas.client-VLNA5O5M.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
45478
45366
  function prepareAnnotations(annotations) {
45479
45367
  return annotations.map((ann) => {
45480
45368
  const targetSelector = getTargetSelector3(ann.target);
@@ -45521,12 +45409,12 @@ function BrowseView({
45521
45409
  if (annotationId && annotationType === "reference") {
45522
45410
  const annotation = allAnnotations.find((a15) => a15.id === annotationId);
45523
45411
  if (annotation) {
45524
- eventBus.emit("annotation:click", { annotationId, motivation: annotation.motivation });
45412
+ eventBus.get("annotation:click").next({ annotationId, motivation: annotation.motivation });
45525
45413
  }
45526
45414
  }
45527
45415
  };
45528
45416
  const { handleMouseEnter, handleMouseLeave, cleanup: cleanupHover } = createHoverHandlers(
45529
- (annotationId) => eventBus.emit("annotation:hover", { annotationId })
45417
+ (annotationId) => eventBus.get("annotation:hover").next({ annotationId })
45530
45418
  );
45531
45419
  const handleMouseOver = (e6) => {
45532
45420
  const target = e6.target;
@@ -45689,7 +45577,8 @@ function BrowseView({
45689
45577
 
45690
45578
  // src/components/resource/ResourceViewer.tsx
45691
45579
  import { useState as useState16, useEffect as useEffect23, useCallback as useCallback15, useRef as useRef16 } from "react";
45692
- import { getExactText as getExactText3, getTargetSelector as getTargetSelector4, resourceUri, isHighlight as isHighlight4, isAssessment as isAssessment3, isReference as isReference4, isComment as isComment4, isTag as isTag5, getBodySource as getBodySource4 } from "@semiont/api-client";
45580
+ import { resourceUri } from "@semiont/core";
45581
+ import { getExactText as getExactText3, getTargetSelector as getTargetSelector4, isHighlight as isHighlight4, isAssessment as isAssessment3, isReference as isReference4, isComment as isComment4, isTag as isTag5, getBodySource as getBodySource4 } from "@semiont/api-client";
45693
45582
  import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
45694
45583
  function ResourceViewer({
45695
45584
  resource,
@@ -45819,7 +45708,7 @@ function ResourceViewer({
45819
45708
  };
45820
45709
  };
45821
45710
  const handleDeleteAnnotation = useCallback15((id2) => {
45822
- eventBus.emit("annotation:delete", { annotationId: id2 });
45711
+ eventBus.get("annotation:delete").next({ annotationId: id2 });
45823
45712
  }, []);
45824
45713
  const handleAnnotationClick = useCallback15((annotation, event) => {
45825
45714
  const metadata = Object.values(ANNOTATORS).find((a15) => a15.matchesAnnotation(annotation));
@@ -45873,7 +45762,7 @@ function ResourceViewer({
45873
45762
  }
45874
45763
  return;
45875
45764
  }
45876
- eventBus.emit("panel:open", { panel: "annotations", scrollToAnnotationId: annotationId, motivation });
45765
+ eventBus.get("panel:open").next({ panel: "annotations", scrollToAnnotationId: annotationId, motivation });
45877
45766
  }, [highlights, references, assessments, comments, tags3, handleAnnotationClick, selectedClick]);
45878
45767
  useEventSubscriptions({
45879
45768
  // View mode
@@ -46053,7 +45942,7 @@ var AssessmentEntry = forwardRef(
46053
45942
  "data-type": "assessment",
46054
45943
  "data-focused": isFocused ? "true" : "false",
46055
45944
  onClick: () => {
46056
- eventBus.emit("annotation:click", { annotationId: assessment.id, motivation: assessment.motivation });
45945
+ eventBus.get("annotation:click").next({ annotationId: assessment.id, motivation: assessment.motivation });
46057
45946
  },
46058
45947
  ...hoverProps,
46059
45948
  children: [
@@ -46107,7 +45996,7 @@ function DetectSection({
46107
45996
  }, [isExpanded, annotationType]);
46108
45997
  const handleDetect = useCallback16(() => {
46109
45998
  const motivation = annotationType === "highlight" ? "highlighting" : annotationType === "assessment" ? "assessing" : "commenting";
46110
- eventBus.emit("detection:start", {
45999
+ eventBus.get("detection:start").next({
46111
46000
  motivation,
46112
46001
  options: {
46113
46002
  instructions: instructions.trim() || void 0,
@@ -46119,7 +46008,7 @@ function DetectSection({
46119
46008
  setTone("");
46120
46009
  }, [annotationType, instructions, tone, useDensity, density]);
46121
46010
  const handleDismissProgress = useCallback16(() => {
46122
- eventBus.emit("detection:dismiss-progress", void 0);
46011
+ eventBus.get("detection:dismiss-progress").next(void 0);
46123
46012
  }, []);
46124
46013
  return /* @__PURE__ */ jsxs20("div", { className: "semiont-panel__section", children: [
46125
46014
  /* @__PURE__ */ jsxs20(
@@ -46376,7 +46265,7 @@ function AssessmentPanel({
46376
46265
  const handleSaveNewAssessment = () => {
46377
46266
  if (pendingAnnotation) {
46378
46267
  const body = newAssessmentText.trim() ? [{ type: "TextualBody", value: newAssessmentText, purpose: "assessing" }] : [];
46379
- eventBus.emit("annotation:create", {
46268
+ eventBus.get("annotation:create").next({
46380
46269
  motivation: "assessing",
46381
46270
  selector: pendingAnnotation.selector,
46382
46271
  body
@@ -46388,7 +46277,7 @@ function AssessmentPanel({
46388
46277
  if (!pendingAnnotation) return;
46389
46278
  const handleEscape = (e6) => {
46390
46279
  if (e6.key === "Escape") {
46391
- eventBus.emit("annotation:cancel-pending", void 0);
46280
+ eventBus.get("annotation:cancel-pending").next(void 0);
46392
46281
  setNewAssessmentText("");
46393
46282
  }
46394
46283
  };
@@ -46434,7 +46323,7 @@ function AssessmentPanel({
46434
46323
  "button",
46435
46324
  {
46436
46325
  onClick: () => {
46437
- eventBus.emit("annotation:cancel-pending", void 0);
46326
+ eventBus.get("annotation:cancel-pending").next(void 0);
46438
46327
  setNewAssessmentText("");
46439
46328
  },
46440
46329
  className: "semiont-button semiont-button--secondary",
@@ -46616,7 +46505,7 @@ var CommentEntry = forwardRef2(
46616
46505
  "data-type": "comment",
46617
46506
  "data-focused": isFocused ? "true" : "false",
46618
46507
  onClick: () => {
46619
- eventBus.emit("annotation:click", { annotationId: comment2.id, motivation: comment2.motivation });
46508
+ eventBus.get("annotation:click").next({ annotationId: comment2.id, motivation: comment2.motivation });
46620
46509
  },
46621
46510
  ...hoverProps,
46622
46511
  children: [
@@ -46777,7 +46666,7 @@ function CommentsPanel({
46777
46666
  });
46778
46667
  const handleSaveNewComment = () => {
46779
46668
  if (newCommentText.trim() && pendingAnnotation) {
46780
- eventBus.emit("annotation:create", {
46669
+ eventBus.get("annotation:create").next({
46781
46670
  motivation: "commenting",
46782
46671
  selector: pendingAnnotation.selector,
46783
46672
  body: [{ type: "TextualBody", value: newCommentText, purpose: "commenting" }]
@@ -46789,7 +46678,7 @@ function CommentsPanel({
46789
46678
  if (!pendingAnnotation) return;
46790
46679
  const handleEscape = (e6) => {
46791
46680
  if (e6.key === "Escape") {
46792
- eventBus.emit("annotation:cancel-pending", void 0);
46681
+ eventBus.get("annotation:cancel-pending").next(void 0);
46793
46682
  setNewCommentText("");
46794
46683
  }
46795
46684
  };
@@ -46828,7 +46717,7 @@ function CommentsPanel({
46828
46717
  "button",
46829
46718
  {
46830
46719
  onClick: () => {
46831
- eventBus.emit("annotation:cancel-pending", void 0);
46720
+ eventBus.get("annotation:cancel-pending").next(void 0);
46832
46721
  setNewCommentText("");
46833
46722
  },
46834
46723
  className: "semiont-button semiont-button--secondary",
@@ -46908,7 +46797,7 @@ var HighlightEntry = forwardRef3(
46908
46797
  "data-type": "highlight",
46909
46798
  "data-focused": isFocused ? "true" : "false",
46910
46799
  onClick: () => {
46911
- eventBus.emit("annotation:click", { annotationId: highlight.id, motivation: highlight.motivation });
46800
+ eventBus.get("annotation:click").next({ annotationId: highlight.id, motivation: highlight.motivation });
46912
46801
  },
46913
46802
  ...hoverProps,
46914
46803
  children: [
@@ -47004,7 +46893,7 @@ function HighlightPanel({
47004
46893
  });
47005
46894
  useEffect28(() => {
47006
46895
  if (pendingAnnotation && pendingAnnotation.motivation === "highlighting") {
47007
- eventBus.emit("annotation:create", {
46896
+ eventBus.get("annotation:create").next({
47008
46897
  motivation: "highlighting",
47009
46898
  selector: pendingAnnotation.selector,
47010
46899
  body: []
@@ -47143,7 +47032,7 @@ var ReferenceEntry = forwardRef4(
47143
47032
  }
47144
47033
  };
47145
47034
  const handleComposeDocument = () => {
47146
- eventBus.emit("reference:create-manual", {
47035
+ eventBus.get("reference:create-manual").next({
47147
47036
  annotationUri: reference.id,
47148
47037
  title: selectedText,
47149
47038
  entityTypes
@@ -47152,7 +47041,7 @@ var ReferenceEntry = forwardRef4(
47152
47041
  const handleUnlink = () => {
47153
47042
  const sourceUri = typeof reference.target === "object" && "source" in reference.target ? reference.target.source : "";
47154
47043
  if (sourceUri) {
47155
- eventBus.emit("annotation:update-body", {
47044
+ eventBus.get("annotation:update-body").next({
47156
47045
  annotationUri: reference.id,
47157
47046
  resourceId: sourceUri.split("/resources/")[1] || "",
47158
47047
  operations: [{ op: "remove" }]
@@ -47162,14 +47051,14 @@ var ReferenceEntry = forwardRef4(
47162
47051
  };
47163
47052
  const handleGenerate = () => {
47164
47053
  const resourceUri2 = typeof reference.target === "object" && "source" in reference.target ? reference.target.source : "";
47165
- eventBus.emit("generation:modal-open", {
47054
+ eventBus.get("generation:modal-open").next({
47166
47055
  annotationUri: reference.id,
47167
47056
  resourceUri: resourceUri2,
47168
47057
  defaultTitle: selectedText
47169
47058
  });
47170
47059
  };
47171
47060
  const handleSearch = () => {
47172
- eventBus.emit("reference:link", {
47061
+ eventBus.get("reference:link").next({
47173
47062
  annotationUri: reference.id,
47174
47063
  searchTerm: selectedText
47175
47064
  });
@@ -47182,7 +47071,7 @@ var ReferenceEntry = forwardRef4(
47182
47071
  "data-type": "reference",
47183
47072
  "data-focused": isFocused ? "true" : "false",
47184
47073
  onClick: () => {
47185
- eventBus.emit("annotation:click", { annotationId: reference.id, motivation: reference.motivation });
47074
+ eventBus.get("annotation:click").next({ annotationId: reference.id, motivation: reference.motivation });
47186
47075
  },
47187
47076
  ...hoverProps,
47188
47077
  children: [
@@ -47385,7 +47274,7 @@ function ReferencesPanel({
47385
47274
  });
47386
47275
  const handleDetect = () => {
47387
47276
  setLastDetectionLog(null);
47388
- eventBus.emit("detection:start", {
47277
+ eventBus.get("detection:start").next({
47389
47278
  motivation: "linking",
47390
47279
  options: {
47391
47280
  entityTypes: selectedEntityTypes,
@@ -47412,11 +47301,11 @@ function ReferencesPanel({
47412
47301
  };
47413
47302
  const handleCreateReference = () => {
47414
47303
  if (pendingAnnotation) {
47415
- const entityType4 = pendingEntityTypes.join(",") || void 0;
47416
- eventBus.emit("annotation:create", {
47304
+ const entityType3 = pendingEntityTypes.join(",") || void 0;
47305
+ eventBus.get("annotation:create").next({
47417
47306
  motivation: "linking",
47418
47307
  selector: pendingAnnotation.selector,
47419
- body: entityType4 ? [{ type: "TextualBody", value: entityType4, purpose: "tagging" }] : []
47308
+ body: entityType3 ? [{ type: "TextualBody", value: entityType3, purpose: "tagging" }] : []
47420
47309
  });
47421
47310
  setPendingEntityTypes([]);
47422
47311
  }
@@ -47425,7 +47314,7 @@ function ReferencesPanel({
47425
47314
  if (!pendingAnnotation) return;
47426
47315
  const handleEscape = (e6) => {
47427
47316
  if (e6.key === "Escape") {
47428
- eventBus.emit("annotation:cancel-pending", void 0);
47317
+ eventBus.get("annotation:cancel-pending").next(void 0);
47429
47318
  setPendingEntityTypes([]);
47430
47319
  }
47431
47320
  };
@@ -47460,7 +47349,7 @@ function ReferencesPanel({
47460
47349
  "button",
47461
47350
  {
47462
47351
  onClick: () => {
47463
- eventBus.emit("annotation:cancel-pending", void 0);
47352
+ eventBus.get("annotation:cancel-pending").next(void 0);
47464
47353
  setPendingEntityTypes([]);
47465
47354
  },
47466
47355
  className: "semiont-button semiont-button--secondary",
@@ -47689,7 +47578,7 @@ function ResourceInfoPanel({
47689
47578
  /* @__PURE__ */ jsxs31(
47690
47579
  "button",
47691
47580
  {
47692
- onClick: () => eventBus.emit("resource:clone", void 0),
47581
+ onClick: () => eventBus.get("resource:clone").next(void 0),
47693
47582
  className: "semiont-resource-button semiont-resource-button--secondary",
47694
47583
  children: [
47695
47584
  "\u{1F517} ",
@@ -47703,7 +47592,7 @@ function ResourceInfoPanel({
47703
47592
  /* @__PURE__ */ jsxs31(
47704
47593
  "button",
47705
47594
  {
47706
- onClick: () => eventBus.emit("resource:unarchive", void 0),
47595
+ onClick: () => eventBus.get("resource:unarchive").next(void 0),
47707
47596
  className: "semiont-resource-button semiont-resource-button--secondary",
47708
47597
  children: [
47709
47598
  "\u{1F4E4} ",
@@ -47716,7 +47605,7 @@ function ResourceInfoPanel({
47716
47605
  /* @__PURE__ */ jsxs31(
47717
47606
  "button",
47718
47607
  {
47719
- onClick: () => eventBus.emit("resource:archive", void 0),
47608
+ onClick: () => eventBus.get("resource:archive").next(void 0),
47720
47609
  className: "semiont-resource-button semiont-resource-button--archive",
47721
47610
  children: [
47722
47611
  "\u{1F4E6} ",
@@ -47822,7 +47711,7 @@ var TagEntry = forwardRef5(
47822
47711
  {
47823
47712
  ref,
47824
47713
  onClick: () => {
47825
- eventBus.emit("annotation:click", { annotationId: tag.id, motivation: tag.motivation });
47714
+ eventBus.get("annotation:click").next({ annotationId: tag.id, motivation: tag.motivation });
47826
47715
  },
47827
47716
  ...hoverProps,
47828
47717
  className: `semiont-annotation-entry${isHovered ? " semiont-annotation-pulse" : ""}`,
@@ -47966,7 +47855,7 @@ function TaggingPanel({
47966
47855
  };
47967
47856
  const handleDetect = () => {
47968
47857
  if (selectedCategories.size > 0) {
47969
- eventBus.emit("detection:start", {
47858
+ eventBus.get("detection:start").next({
47970
47859
  motivation: "tagging",
47971
47860
  options: {
47972
47861
  schemaId: selectedSchemaId,
@@ -47980,7 +47869,7 @@ function TaggingPanel({
47980
47869
  if (!pendingAnnotation) return;
47981
47870
  const handleEscape = (e6) => {
47982
47871
  if (e6.key === "Escape") {
47983
- eventBus.emit("annotation:cancel-pending", void 0);
47872
+ eventBus.get("annotation:cancel-pending").next(void 0);
47984
47873
  }
47985
47874
  };
47986
47875
  document.addEventListener("keydown", handleEscape);
@@ -48018,7 +47907,7 @@ function TaggingPanel({
48018
47907
  className: "semiont-select",
48019
47908
  onChange: (e6) => {
48020
47909
  if (e6.target.value && pendingAnnotation) {
48021
- eventBus.emit("annotation:create", {
47910
+ eventBus.get("annotation:create").next({
48022
47911
  motivation: "tagging",
48023
47912
  selector: pendingAnnotation.selector,
48024
47913
  body: [
@@ -48047,7 +47936,7 @@ function TaggingPanel({
48047
47936
  /* @__PURE__ */ jsx43("div", { className: "semiont-annotation-prompt__footer", children: /* @__PURE__ */ jsx43(
48048
47937
  "button",
48049
47938
  {
48050
- onClick: () => eventBus.emit("annotation:cancel-pending", void 0),
47939
+ onClick: () => eventBus.get("annotation:cancel-pending").next(void 0),
48051
47940
  className: "semiont-button semiont-button--secondary",
48052
47941
  "data-type": "tag",
48053
47942
  children: t12("cancel")
@@ -48548,7 +48437,7 @@ function ObservableLink({
48548
48437
  onClickRef.current = onClick;
48549
48438
  });
48550
48439
  const handleClick = useCallback22((e6) => {
48551
- eventBus.emit("navigation:link-clicked", {
48440
+ eventBus.get("navigation:link-clicked").next({
48552
48441
  href,
48553
48442
  label
48554
48443
  });
@@ -48615,7 +48504,7 @@ function SimpleNavigation({
48615
48504
  /* @__PURE__ */ jsx48(
48616
48505
  "button",
48617
48506
  {
48618
- onClick: () => eventBus.emit("navigation:sidebar-toggle", void 0),
48507
+ onClick: () => eventBus.get("navigation:sidebar-toggle").next(void 0),
48619
48508
  className: "semiont-nav-section__header-icon",
48620
48509
  title: isCollapsed ? expandSidebarLabel : collapseSidebarLabel,
48621
48510
  "aria-label": isCollapsed ? expandSidebarLabel : collapseSidebarLabel,
@@ -52842,14 +52731,14 @@ function CollapsibleResourceNavigation({
52842
52731
  announceCannotMove(direction);
52843
52732
  return;
52844
52733
  }
52845
- eventBus.emit("navigation:resource-reorder", { oldIndex: currentIndex, newIndex });
52734
+ eventBus.get("navigation:resource-reorder").next({ oldIndex: currentIndex, newIndex });
52846
52735
  const resource = resources[currentIndex];
52847
52736
  announceKeyboardReorder(resource.name, direction, newIndex + 1, resources.length);
52848
52737
  }, [resources]);
52849
52738
  const handleResourceClose = (resourceId, e6) => {
52850
52739
  e6.preventDefault();
52851
52740
  e6.stopPropagation();
52852
- eventBus.emit("navigation:resource-close", { resourceId });
52741
+ eventBus.get("navigation:resource-close").next({ resourceId });
52853
52742
  const resourceHref = getResourceHref(resourceId);
52854
52743
  if (currentPath === resourceHref && onNavigate && fixedItems.length > 0) {
52855
52744
  onNavigate(fixedItems[0].href);
@@ -52869,7 +52758,7 @@ function CollapsibleResourceNavigation({
52869
52758
  const oldIndex = resources.findIndex((resource) => resource.id === active.id);
52870
52759
  const newIndex = resources.findIndex((resource) => resource.id === over.id);
52871
52760
  if (oldIndex !== -1 && newIndex !== -1) {
52872
- eventBus.emit("navigation:resource-reorder", { oldIndex, newIndex });
52761
+ eventBus.get("navigation:resource-reorder").next({ oldIndex, newIndex });
52873
52762
  const resource = resources[oldIndex];
52874
52763
  announceDrop(resource.name, newIndex + 1, resources.length);
52875
52764
  }
@@ -52896,7 +52785,7 @@ function CollapsibleResourceNavigation({
52896
52785
  /* @__PURE__ */ jsx50(
52897
52786
  "button",
52898
52787
  {
52899
- onClick: () => eventBus.emit("navigation:sidebar-toggle", void 0),
52788
+ onClick: () => eventBus.get("navigation:sidebar-toggle").next(void 0),
52900
52789
  className: "semiont-nav-section__header-icon",
52901
52790
  title: isCollapsed ? mergedTranslations.expandSidebar : mergedTranslations.collapseSidebar,
52902
52791
  "aria-label": isCollapsed ? mergedTranslations.expandSidebar : mergedTranslations.collapseSidebar,
@@ -56329,8 +56218,8 @@ function ResourceDiscoveryPage({
56329
56218
  );
56330
56219
  const onNavigateToResourceRef = useRef31(onNavigateToResource);
56331
56220
  onNavigateToResourceRef.current = onNavigateToResource;
56332
- const handleEntityTypeFilter = useCallback30((entityType4) => {
56333
- setSelectedEntityType(entityType4);
56221
+ const handleEntityTypeFilter = useCallback30((entityType3) => {
56222
+ setSelectedEntityType(entityType3);
56334
56223
  }, []);
56335
56224
  const openResource = useCallback30((resource) => {
56336
56225
  const resourceId = getResourceId2(resource);
@@ -56472,12 +56361,13 @@ function ResourceDiscoveryPage({
56472
56361
  // src/features/resource-viewer/components/ResourceViewerPage.tsx
56473
56362
  import { useState as useState44, useEffect as useEffect49, useCallback as useCallback35, useMemo as useMemo12 } from "react";
56474
56363
  import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
56475
- import { getLanguage, getPrimaryRepresentation, resourceAnnotationUri as resourceAnnotationUri3, getPrimaryMediaType as getPrimaryMediaType2 } from "@semiont/api-client";
56364
+ import { resourceAnnotationUri as resourceAnnotationUri3 } from "@semiont/core";
56365
+ import { getLanguage, getPrimaryRepresentation, getPrimaryMediaType as getPrimaryMediaType2 } from "@semiont/api-client";
56476
56366
  import { uriToAnnotationId as uriToAnnotationId2 } from "@semiont/core";
56477
56367
 
56478
56368
  // src/hooks/useResolutionFlow.ts
56479
56369
  import { useCallback as useCallback31, useEffect as useEffect44, useRef as useRef32, useState as useState39 } from "react";
56480
- import { resourceAnnotationUri, accessToken as accessToken3 } from "@semiont/api-client";
56370
+ import { resourceAnnotationUri, accessToken as accessToken3 } from "@semiont/core";
56481
56371
  import { uriToAnnotationIdOrPassthrough } from "@semiont/core";
56482
56372
  function toAccessToken2(token) {
56483
56373
  return token ? accessToken3(token) : void 0;
@@ -56512,23 +56402,23 @@ function useResolutionFlow(rUri) {
56512
56402
  resourceId: event.resourceId,
56513
56403
  operations: event.operations
56514
56404
  }, { auth: toAccessToken2(tokenRef.current) });
56515
- eventBus.emit("annotation:body-updated", { annotationUri: event.annotationUri });
56405
+ eventBus.get("annotation:body-updated").next({ annotationUri: event.annotationUri });
56516
56406
  } catch (error) {
56517
56407
  console.error("Failed to update annotation body:", error);
56518
- eventBus.emit("annotation:body-update-failed", { error });
56408
+ eventBus.get("annotation:body-update-failed").next({ error });
56519
56409
  }
56520
56410
  };
56521
56411
  const handleReferenceLink = (event) => {
56522
- eventBus.emit("resolution:search-requested", {
56412
+ eventBus.get("resolution:search-requested").next({
56523
56413
  referenceId: event.annotationUri,
56524
56414
  searchTerm: event.searchTerm
56525
56415
  });
56526
56416
  };
56527
- eventBus.on("annotation:update-body", handleAnnotationUpdateBody);
56528
- eventBus.on("reference:link", handleReferenceLink);
56417
+ const subscription1 = eventBus.get("annotation:update-body").subscribe(handleAnnotationUpdateBody);
56418
+ const subscription2 = eventBus.get("reference:link").subscribe(handleReferenceLink);
56529
56419
  return () => {
56530
- eventBus.off("annotation:update-body", handleAnnotationUpdateBody);
56531
- eventBus.off("reference:link", handleReferenceLink);
56420
+ subscription1.unsubscribe();
56421
+ subscription2.unsubscribe();
56532
56422
  };
56533
56423
  }, [eventBus]);
56534
56424
  useEffect44(() => {
@@ -56536,17 +56426,15 @@ function useResolutionFlow(rUri) {
56536
56426
  setPendingReferenceId(event.referenceId);
56537
56427
  setSearchModalOpen(true);
56538
56428
  };
56539
- eventBus.on("resolution:search-requested", handleResolutionSearchRequested);
56540
- return () => {
56541
- eventBus.off("resolution:search-requested", handleResolutionSearchRequested);
56542
- };
56429
+ const subscription = eventBus.get("resolution:search-requested").subscribe(handleResolutionSearchRequested);
56430
+ return () => subscription.unsubscribe();
56543
56431
  }, [eventBus]);
56544
56432
  return { searchModalOpen, pendingReferenceId, onCloseSearchModal };
56545
56433
  }
56546
56434
 
56547
56435
  // src/hooks/useDetectionFlow.ts
56548
56436
  import { useState as useState40, useRef as useRef33, useEffect as useEffect45, useCallback as useCallback32 } from "react";
56549
- import { resourceAnnotationUri as resourceAnnotationUri2, accessToken as accessToken4, entityType as entityType3 } from "@semiont/api-client";
56437
+ import { resourceAnnotationUri as resourceAnnotationUri2, accessToken as accessToken4, entityType as entityType2 } from "@semiont/core";
56550
56438
  import { uriToAnnotationIdOrPassthrough as uriToAnnotationIdOrPassthrough2 } from "@semiont/core";
56551
56439
  function toAccessToken3(token) {
56552
56440
  return token ? accessToken4(token) : void 0;
@@ -56584,7 +56472,7 @@ function useDetectionFlow(rUri) {
56584
56472
  questioning: "annotations",
56585
56473
  replying: "annotations"
56586
56474
  };
56587
- eventBus.emit("panel:open", { panel: MOTIVATION_TO_TAB[pending.motivation] || "annotations" });
56475
+ eventBus.get("panel:open").next({ panel: MOTIVATION_TO_TAB[pending.motivation] || "annotations" });
56588
56476
  setPendingAnnotation(pending);
56589
56477
  }, []);
56590
56478
  const selectionToSelector = useCallback32((selection2) => {
@@ -56687,11 +56575,11 @@ function useDetectionFlow(rUri) {
56687
56575
  }, { auth: toAccessToken3(tokenRef.current) });
56688
56576
  if (result.annotation) {
56689
56577
  setPendingAnnotation(null);
56690
- eventBus.emit("annotation:created", { annotation: result.annotation });
56578
+ eventBus.get("annotation:created").next({ annotation: result.annotation });
56691
56579
  }
56692
56580
  } catch (error) {
56693
56581
  console.error("Failed to create annotation:", error);
56694
- eventBus.emit("annotation:create-failed", { error });
56582
+ eventBus.get("annotation:create-failed").next({ error });
56695
56583
  }
56696
56584
  };
56697
56585
  const handleAnnotationDelete = async (event) => {
@@ -56701,10 +56589,10 @@ function useDetectionFlow(rUri) {
56701
56589
  const annotationIdSegment = uriToAnnotationIdOrPassthrough2(event.annotationId);
56702
56590
  const annotationUri2 = resourceAnnotationUri2(`${currentRUri}/annotations/${annotationIdSegment}`);
56703
56591
  await currentClient.deleteAnnotation(annotationUri2, { auth: toAccessToken3(tokenRef.current) });
56704
- eventBus.emit("annotation:deleted", { annotationId: event.annotationId });
56592
+ eventBus.get("annotation:deleted").next({ annotationId: event.annotationId });
56705
56593
  } catch (error) {
56706
56594
  console.error("Failed to delete annotation:", error);
56707
- eventBus.emit("annotation:delete-failed", { error });
56595
+ eventBus.get("annotation:delete-failed").next({ error });
56708
56596
  }
56709
56597
  };
56710
56598
  const handleDetectionStart = async (event) => {
@@ -56722,103 +56610,43 @@ function useDetectionFlow(rUri) {
56722
56610
  }
56723
56611
  setDetectingMotivation(event.motivation);
56724
56612
  setDetectionProgress(null);
56725
- const auth = { auth: toAccessToken3(tokenRef.current) };
56613
+ const auth = { auth: toAccessToken3(tokenRef.current), eventBus };
56726
56614
  if (event.motivation === "tagging") {
56727
56615
  const { schemaId, categories } = event.options;
56728
56616
  if (!schemaId || !categories || categories.length === 0) {
56729
56617
  throw new Error("Tag detection requires schemaId and categories");
56730
56618
  }
56731
- const stream = currentClient.sse.detectTags(currentRUri, { schemaId, categories }, auth);
56732
- stream.onProgress((chunk) => {
56733
- eventBus.emit("detection:progress", chunk);
56734
- });
56735
- stream.onComplete((finalChunk) => {
56736
- eventBus.emit("detection:progress", finalChunk);
56737
- eventBus.emit("detection:complete", { motivation: event.motivation });
56738
- });
56739
- stream.onError((error) => {
56740
- console.error("Detection failed:", error);
56741
- setDetectingMotivation(null);
56742
- setDetectionProgress(null);
56743
- });
56619
+ currentClient.sse.detectTags(currentRUri, { schemaId, categories }, auth);
56744
56620
  } else if (event.motivation === "linking") {
56745
56621
  const { entityTypes, includeDescriptiveReferences } = event.options;
56746
56622
  if (!entityTypes || entityTypes.length === 0) {
56747
56623
  throw new Error("Reference detection requires entityTypes");
56748
56624
  }
56749
- const stream = currentClient.sse.detectReferences(currentRUri, {
56750
- entityTypes: entityTypes.map((et) => entityType3(et)),
56625
+ currentClient.sse.detectReferences(currentRUri, {
56626
+ entityTypes: entityTypes.map((et) => entityType2(et)),
56751
56627
  includeDescriptiveReferences: includeDescriptiveReferences || false
56752
56628
  }, auth);
56753
- stream.onProgress((chunk) => {
56754
- eventBus.emit("detection:progress", chunk);
56755
- });
56756
- stream.onComplete((finalChunk) => {
56757
- eventBus.emit("detection:progress", finalChunk);
56758
- eventBus.emit("detection:complete", { motivation: event.motivation });
56759
- });
56760
- stream.onError((error) => {
56761
- console.error("[useDetectionFlow] Detection failed:", error);
56762
- setDetectingMotivation(null);
56763
- setDetectionProgress(null);
56764
- });
56765
56629
  } else if (event.motivation === "highlighting") {
56766
- const stream = currentClient.sse.detectHighlights(currentRUri, {
56630
+ currentClient.sse.detectHighlights(currentRUri, {
56767
56631
  instructions: event.options.instructions,
56768
56632
  density: event.options.density
56769
56633
  }, auth);
56770
- stream.onProgress((chunk) => {
56771
- eventBus.emit("detection:progress", chunk);
56772
- });
56773
- stream.onComplete((finalChunk) => {
56774
- eventBus.emit("detection:progress", finalChunk);
56775
- eventBus.emit("detection:complete", { motivation: event.motivation });
56776
- });
56777
- stream.onError((error) => {
56778
- console.error("Detection failed:", error);
56779
- setDetectingMotivation(null);
56780
- setDetectionProgress(null);
56781
- });
56782
56634
  } else if (event.motivation === "assessing") {
56783
- const stream = currentClient.sse.detectAssessments(currentRUri, {
56635
+ currentClient.sse.detectAssessments(currentRUri, {
56784
56636
  instructions: event.options.instructions,
56785
56637
  tone: event.options.tone,
56786
56638
  density: event.options.density
56787
56639
  }, auth);
56788
- stream.onProgress((chunk) => {
56789
- eventBus.emit("detection:progress", chunk);
56790
- });
56791
- stream.onComplete((finalChunk) => {
56792
- eventBus.emit("detection:progress", finalChunk);
56793
- eventBus.emit("detection:complete", { motivation: event.motivation });
56794
- });
56795
- stream.onError((error) => {
56796
- console.error("[useDetectionFlow] Assessment detection error:", error);
56797
- setDetectingMotivation(null);
56798
- setDetectionProgress(null);
56799
- });
56800
56640
  } else if (event.motivation === "commenting") {
56801
- const stream = currentClient.sse.detectComments(currentRUri, {
56641
+ currentClient.sse.detectComments(currentRUri, {
56802
56642
  instructions: event.options.instructions,
56803
56643
  tone: event.options.tone,
56804
56644
  density: event.options.density
56805
56645
  }, auth);
56806
- stream.onProgress((chunk) => {
56807
- eventBus.emit("detection:progress", chunk);
56808
- });
56809
- stream.onComplete((finalChunk) => {
56810
- eventBus.emit("detection:progress", finalChunk);
56811
- eventBus.emit("detection:complete", { motivation: event.motivation });
56812
- });
56813
- stream.onError((error) => {
56814
- console.error("Detection failed:", error);
56815
- setDetectingMotivation(null);
56816
- setDetectionProgress(null);
56817
- });
56818
56646
  }
56819
56647
  } catch (error) {
56820
56648
  if (error instanceof Error && error.name === "AbortError") {
56821
- eventBus.emit("detection:cancelled", void 0);
56649
+ eventBus.get("detection:cancelled").next(void 0);
56822
56650
  } else {
56823
56651
  console.error("Detection failed:", error);
56824
56652
  setDetectingMotivation(null);
@@ -56832,15 +56660,15 @@ function useDetectionFlow(rUri) {
56832
56660
  detectionStreamRef.current = null;
56833
56661
  }
56834
56662
  };
56835
- eventBus.on("annotation:create", handleAnnotationCreate);
56836
- eventBus.on("annotation:delete", handleAnnotationDelete);
56837
- eventBus.on("detection:start", handleDetectionStart);
56838
- eventBus.on("job:cancel-requested", handleJobCancelRequested);
56663
+ const subscription1 = eventBus.get("annotation:create").subscribe(handleAnnotationCreate);
56664
+ const subscription2 = eventBus.get("annotation:delete").subscribe(handleAnnotationDelete);
56665
+ const subscription3 = eventBus.get("detection:start").subscribe(handleDetectionStart);
56666
+ const subscription4 = eventBus.get("job:cancel-requested").subscribe(handleJobCancelRequested);
56839
56667
  return () => {
56840
- eventBus.off("annotation:create", handleAnnotationCreate);
56841
- eventBus.off("annotation:delete", handleAnnotationDelete);
56842
- eventBus.off("detection:start", handleDetectionStart);
56843
- eventBus.off("job:cancel-requested", handleJobCancelRequested);
56668
+ subscription1.unsubscribe();
56669
+ subscription2.unsubscribe();
56670
+ subscription3.unsubscribe();
56671
+ subscription4.unsubscribe();
56844
56672
  detectionStreamRef.current?.abort();
56845
56673
  };
56846
56674
  }, [eventBus]);
@@ -56934,7 +56762,7 @@ function usePanelNavigation() {
56934
56762
 
56935
56763
  // src/hooks/useGenerationFlow.ts
56936
56764
  import { useState as useState42, useCallback as useCallback34, useEffect as useEffect47, useRef as useRef34 } from "react";
56937
- import { annotationUri, accessToken as accessToken5 } from "@semiont/api-client";
56765
+ import { annotationUri, accessToken as accessToken5 } from "@semiont/core";
56938
56766
  function toAccessToken4(token) {
56939
56767
  return token ? accessToken5(token) : void 0;
56940
56768
  }
@@ -56972,7 +56800,7 @@ function useGenerationFlow(locale, resourceId, showSuccess, showError, cacheMana
56972
56800
  }
56973
56801
  clearNewAnnotationId(annotationUri(referenceId));
56974
56802
  const resourceUriStr = `resource://${resourceId}`;
56975
- eventBus.emit("generation:start", {
56803
+ eventBus.get("generation:start").next({
56976
56804
  annotationUri: referenceId,
56977
56805
  resourceUri: resourceUriStr,
56978
56806
  options: {
@@ -56991,7 +56819,7 @@ function useGenerationFlow(locale, resourceId, showSuccess, showError, cacheMana
56991
56819
  setGenerationReferenceId(annUri);
56992
56820
  setGenerationDefaultTitle(defaultTitle);
56993
56821
  setGenerationModalOpen(true);
56994
- eventBus.emit("context:retrieval-requested", { annotationUri: annUri, resourceUri: resourceUri2 });
56822
+ eventBus.get("context:retrieval-requested").next({ annotationUri: annUri, resourceUri: resourceUri2 });
56995
56823
  }, []);
56996
56824
  const handleGenerationComplete = useCallback34(({ progress }) => {
56997
56825
  setGenerationProgress(progress);
@@ -57017,34 +56845,18 @@ function useGenerationFlow(locale, resourceId, showSuccess, showError, cacheMana
57017
56845
  try {
57018
56846
  generationStreamRef.current?.abort();
57019
56847
  generationStreamRef.current = new AbortController();
57020
- const stream = clientRef.current.sse.generateResourceFromAnnotation(
56848
+ clientRef.current.sse.generateResourceFromAnnotation(
57021
56849
  event.resourceUri,
57022
56850
  event.annotationUri,
57023
56851
  event.options,
57024
- { auth: toAccessToken4(tokenRef.current) }
56852
+ { auth: toAccessToken4(tokenRef.current), eventBus }
57025
56853
  );
57026
- stream.onProgress((chunk) => {
57027
- console.log("[useGenerationFlow] Generation progress chunk received", chunk);
57028
- eventBus.emit("generation:progress", chunk);
57029
- });
57030
- stream.onComplete((finalChunk) => {
57031
- console.log("[useGenerationFlow] Generation complete with final chunk", finalChunk);
57032
- eventBus.emit("generation:progress", finalChunk);
57033
- eventBus.emit("generation:complete", {
57034
- annotationUri: event.annotationUri,
57035
- progress: finalChunk
57036
- });
57037
- });
57038
- stream.onError((error) => {
57039
- console.error("[useGenerationFlow] Generation failed:", error);
57040
- eventBus.emit("generation:failed", { error });
57041
- });
57042
56854
  } catch (error) {
57043
56855
  if (error.name === "AbortError") {
57044
56856
  console.log("[useGenerationFlow] Generation cancelled");
57045
56857
  } else {
57046
56858
  console.error("[useGenerationFlow] Generation failed:", error);
57047
- eventBus.emit("generation:failed", { error });
56859
+ eventBus.get("generation:failed").next({ error });
57048
56860
  }
57049
56861
  }
57050
56862
  };
@@ -57064,13 +56876,13 @@ function useGenerationFlow(locale, resourceId, showSuccess, showError, cacheMana
57064
56876
  });
57065
56877
  window.location.href = `${baseUrl}/know/compose?${params.toString()}`;
57066
56878
  };
57067
- eventBus.on("generation:start", handleGenerationStart);
57068
- eventBus.on("job:cancel-requested", handleJobCancelRequested);
57069
- eventBus.on("reference:create-manual", handleReferenceCreateManual);
56879
+ const subscription1 = eventBus.get("generation:start").subscribe(handleGenerationStart);
56880
+ const subscription2 = eventBus.get("job:cancel-requested").subscribe(handleJobCancelRequested);
56881
+ const subscription3 = eventBus.get("reference:create-manual").subscribe(handleReferenceCreateManual);
57070
56882
  return () => {
57071
- eventBus.off("generation:start", handleGenerationStart);
57072
- eventBus.off("job:cancel-requested", handleJobCancelRequested);
57073
- eventBus.off("reference:create-manual", handleReferenceCreateManual);
56883
+ subscription1.unsubscribe();
56884
+ subscription2.unsubscribe();
56885
+ subscription3.unsubscribe();
57074
56886
  generationStreamRef.current?.abort();
57075
56887
  };
57076
56888
  }, [eventBus, resourceId]);
@@ -57093,11 +56905,11 @@ function useGenerationFlow(locale, resourceId, showSuccess, showError, cacheMana
57093
56905
 
57094
56906
  // src/hooks/useContextRetrievalFlow.ts
57095
56907
  import { useState as useState43, useEffect as useEffect48, useRef as useRef35 } from "react";
57096
- import { accessToken as accessToken6 } from "@semiont/api-client";
56908
+ import { accessToken as accessToken6 } from "@semiont/core";
57097
56909
  function toAccessToken5(token) {
57098
56910
  return token ? accessToken6(token) : void 0;
57099
56911
  }
57100
- function useContextRetrievalFlow(emitter, config) {
56912
+ function useContextRetrievalFlow(eventBus, config) {
57101
56913
  const token = useAuthToken();
57102
56914
  const [retrievalContext, setRetrievalContext] = useState43(null);
57103
56915
  const [retrievalLoading, setRetrievalLoading] = useState43(false);
@@ -57129,7 +56941,7 @@ function useContextRetrievalFlow(emitter, config) {
57129
56941
  setRetrievalContext(context);
57130
56942
  setRetrievalLoading(false);
57131
56943
  if (context) {
57132
- emitter.emit("context:retrieval-complete", {
56944
+ eventBus.get("context:retrieval-complete").next({
57133
56945
  annotationUri: event.annotationUri,
57134
56946
  context
57135
56947
  });
@@ -57138,17 +56950,15 @@ function useContextRetrievalFlow(emitter, config) {
57138
56950
  const err = error;
57139
56951
  setRetrievalError(err);
57140
56952
  setRetrievalLoading(false);
57141
- emitter.emit("context:retrieval-failed", {
56953
+ eventBus.get("context:retrieval-failed").next({
57142
56954
  annotationUri: event.annotationUri,
57143
56955
  error: err
57144
56956
  });
57145
56957
  }
57146
56958
  };
57147
- emitter.on("context:retrieval-requested", handleContextRetrievalRequested);
57148
- return () => {
57149
- emitter.off("context:retrieval-requested", handleContextRetrievalRequested);
57150
- };
57151
- }, [emitter]);
56959
+ const subscription = eventBus.get("context:retrieval-requested").subscribe(handleContextRetrievalRequested);
56960
+ return () => subscription.unsubscribe();
56961
+ }, [eventBus]);
57152
56962
  return { retrievalContext, retrievalLoading, retrievalError, retrievalAnnotationUri };
57153
56963
  }
57154
56964
 
@@ -57310,7 +57120,7 @@ function ResourceViewerPage({
57310
57120
  try {
57311
57121
  const result2 = await generateCloneTokenMutation.mutateAsync(rUri);
57312
57122
  const token = result2.token;
57313
- eventBus.emit("navigation:router-push", { path: `/know/compose?mode=clone&token=${token}`, reason: "clone" });
57123
+ eventBus.get("navigation:router-push").next({ path: `/know/compose?mode=clone&token=${token}`, reason: "clone" });
57314
57124
  } catch (err) {
57315
57125
  console.error("Failed to generate clone token:", err);
57316
57126
  showError("Failed to generate clone link");
@@ -57340,13 +57150,13 @@ function ResourceViewerPage({
57340
57150
  const handleReferenceNavigate = useCallback35(({ documentId }) => {
57341
57151
  if (routes.resource) {
57342
57152
  const path2 = routes.resource.replace("[resourceId]", encodeURIComponent(documentId));
57343
- eventBus.emit("navigation:router-push", { path: path2, reason: "reference-link" });
57153
+ eventBus.get("navigation:router-push").next({ path: path2, reason: "reference-link" });
57344
57154
  }
57345
57155
  }, [routes.resource]);
57346
- const handleEntityTypeClicked = useCallback35(({ entityType: entityType4 }) => {
57156
+ const handleEntityTypeClicked = useCallback35(({ entityType: entityType3 }) => {
57347
57157
  if (routes.know) {
57348
- const path2 = `${routes.know}?entityType=${encodeURIComponent(entityType4)}`;
57349
- eventBus.emit("navigation:router-push", { path: path2, reason: "entity-type-filter" });
57158
+ const path2 = `${routes.know}?entityType=${encodeURIComponent(entityType3)}`;
57159
+ eventBus.get("navigation:router-push").next({ path: path2, reason: "entity-type-filter" });
57350
57160
  }
57351
57161
  }, [routes.know]);
57352
57162
  useEventSubscriptions({
@@ -57410,7 +57220,7 @@ function ResourceViewerPage({
57410
57220
  const resourceWithContent = { ...resource, content: content4 };
57411
57221
  const handleEventHover = useCallback35((annotationId) => {
57412
57222
  if (annotationId) {
57413
- eventBus.emit("annotation:sparkle", { annotationId });
57223
+ eventBus.get("annotation:sparkle").next({ annotationId });
57414
57224
  }
57415
57225
  }, []);
57416
57226
  const handleEventClick = useCallback35((_annotationId) => {
@@ -57536,7 +57346,7 @@ function ResourceViewerPage({
57536
57346
  }
57537
57347
  const resourceIdSegment = rUri.split("/").pop() || "";
57538
57348
  const nestedUri = `${window.location.origin}/resources/${resourceIdSegment}/annotations/${annotationIdShort}`;
57539
- eventBus.emit("annotation:update-body", {
57349
+ eventBus.get("annotation:update-body").next({
57540
57350
  annotationUri: resourceAnnotationUri3(nestedUri),
57541
57351
  resourceId: resourceIdSegment,
57542
57352
  operations: [{
@@ -57678,8 +57488,6 @@ export {
57678
57488
  UserMenuSkeleton,
57679
57489
  WelcomePage,
57680
57490
  buttonStyles,
57681
- createCancelDetectionHandler,
57682
- createDetectionHandler,
57683
57491
  createHoverHandlers,
57684
57492
  cssVariables,
57685
57493
  dispatch401Error,