@semiont/react-ui 0.4.20 → 0.4.22

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 (125) hide show
  1. package/README.md +8 -5
  2. package/dist/{PdfAnnotationCanvas.client-CHDCGQBR.mjs → PdfAnnotationCanvas.client-5QESNO5H.mjs} +13 -16
  3. package/dist/PdfAnnotationCanvas.client-5QESNO5H.mjs.map +1 -0
  4. package/dist/TranslationManager-9Xj3MIWQ.d.mts +16 -0
  5. package/dist/chunk-4NOUO3W6.mjs +7788 -0
  6. package/dist/chunk-4NOUO3W6.mjs.map +1 -0
  7. package/dist/index.d.mts +212 -1206
  8. package/dist/index.mjs +3332 -13712
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/test-utils.d.mts +48 -21
  11. package/dist/test-utils.mjs +2505 -87
  12. package/dist/test-utils.mjs.map +1 -1
  13. package/package.json +2 -2
  14. package/src/components/AnnotateReferencesProgressWidget.tsx +21 -28
  15. package/src/components/CodeMirrorRenderer.tsx +12 -12
  16. package/src/components/LiveRegion.tsx +1 -2
  17. package/src/components/StatusDisplay.tsx +42 -16
  18. package/src/components/Toolbar.tsx +4 -4
  19. package/src/components/__tests__/AnnotateReferencesProgressWidget.test.tsx +34 -20
  20. package/src/components/__tests__/StatusDisplay.test.tsx +50 -65
  21. package/src/components/__tests__/Toolbar.test.tsx +4 -4
  22. package/src/components/annotation/AnnotateToolbar.tsx +8 -9
  23. package/src/components/annotation/__tests__/AnnotateToolbar.test.tsx +31 -77
  24. package/src/components/annotation-popups/JsonLdView.tsx +1 -2
  25. package/src/components/annotation-popups/__tests__/JsonLdView.test.tsx +1 -2
  26. package/src/components/image-annotation/AnnotationOverlay.tsx +15 -18
  27. package/src/components/image-annotation/SvgDrawingCanvas.tsx +12 -17
  28. package/src/components/modals/ConfigureGenerationStep.tsx +1 -2
  29. package/src/components/modals/PermissionDeniedModal.tsx +11 -11
  30. package/src/components/modals/ReferenceWizardModal.tsx +14 -18
  31. package/src/components/modals/ResourceSearchModal.tsx +12 -8
  32. package/src/components/modals/SearchModal.tsx +11 -6
  33. package/src/components/modals/SearchResultsStep.tsx +1 -3
  34. package/src/components/modals/SessionExpiredModal.tsx +11 -11
  35. package/src/components/modals/__tests__/PermissionDeniedModal.test.tsx +7 -7
  36. package/src/components/modals/__tests__/ResourceSearchModal.test.tsx +10 -8
  37. package/src/components/modals/__tests__/SearchModal.accessibility.test.tsx +6 -2
  38. package/src/components/modals/__tests__/SearchModal.basic.test.tsx +6 -2
  39. package/src/components/modals/__tests__/SearchModal.keyboard.test.tsx +6 -2
  40. package/src/components/modals/__tests__/SearchModal.search-wiring.test.tsx +10 -7
  41. package/src/components/modals/__tests__/SearchModal.visual.test.tsx +6 -2
  42. package/src/components/modals/__tests__/SessionExpiredModal.test.tsx +5 -5
  43. package/src/components/navigation/CollapsibleResourceNavigation.tsx +10 -10
  44. package/src/components/navigation/ObservableLink.tsx +6 -6
  45. package/src/components/navigation/SimpleNavigation.tsx +4 -4
  46. package/src/components/navigation/__tests__/ObservableLink.test.tsx +4 -4
  47. package/src/components/navigation/__tests__/SimpleNavigation.test.tsx +4 -4
  48. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +15 -18
  49. package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +1 -2
  50. package/src/components/resource/AnnotateView.tsx +8 -10
  51. package/src/components/resource/AnnotationHistory.tsx +9 -12
  52. package/src/components/resource/BrowseView.tsx +11 -8
  53. package/src/components/resource/ResourceViewer.tsx +22 -34
  54. package/src/components/resource/__tests__/AnnotationHistory.test.tsx +54 -192
  55. package/src/components/resource/__tests__/BrowseView.test.tsx +38 -87
  56. package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +41 -31
  57. package/src/components/resource/__tests__/event-formatting.test.ts +6 -2
  58. package/src/components/resource/event-formatting.ts +2 -3
  59. package/src/components/resource/panels/AssessmentEntry.tsx +7 -8
  60. package/src/components/resource/panels/AssessmentPanel.tsx +21 -17
  61. package/src/components/resource/panels/AssistSection.tsx +15 -21
  62. package/src/components/resource/panels/CollaborationPanel.tsx +29 -7
  63. package/src/components/resource/panels/CommentEntry.tsx +7 -8
  64. package/src/components/resource/panels/CommentsPanel.tsx +11 -13
  65. package/src/components/resource/panels/HighlightEntry.tsx +7 -8
  66. package/src/components/resource/panels/HighlightPanel.tsx +12 -13
  67. package/src/components/resource/panels/ReferenceEntry.tsx +13 -15
  68. package/src/components/resource/panels/ReferencesPanel.tsx +17 -19
  69. package/src/components/resource/panels/ResourceInfoPanel.tsx +8 -7
  70. package/src/components/resource/panels/StatisticsPanel.tsx +2 -3
  71. package/src/components/resource/panels/TagEntry.tsx +7 -8
  72. package/src/components/resource/panels/TaggingPanel.tsx +14 -23
  73. package/src/components/resource/panels/UnifiedAnnotationsPanel.tsx +4 -3
  74. package/src/components/resource/panels/__tests__/AssessmentEntry.test.tsx +4 -4
  75. package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +22 -57
  76. package/src/components/resource/panels/__tests__/CollaborationPanel.test.tsx +51 -20
  77. package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +4 -4
  78. package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +22 -61
  79. package/src/components/resource/panels/__tests__/HighlightEntry.test.tsx +4 -4
  80. package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +1 -2
  81. package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +7 -8
  82. package/src/components/resource/panels/__tests__/ReferencesPanel.observable-flow.test.tsx +153 -0
  83. package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +51 -106
  84. package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +28 -53
  85. package/src/components/resource/panels/__tests__/StatisticsPanel.test.tsx +3 -3
  86. package/src/components/resource/panels/__tests__/TagEntry.test.tsx +4 -4
  87. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +19 -52
  88. package/src/components/settings/SettingsPanel.tsx +9 -9
  89. package/src/components/settings/__tests__/SettingsPanel.test.tsx +15 -15
  90. package/src/features/admin-devops/components/AdminDevOpsPage.tsx +1 -2
  91. package/src/features/admin-exchange/components/AdminExchangePage.tsx +1 -1
  92. package/src/features/admin-exchange/components/ImportCard.tsx +2 -7
  93. package/src/features/admin-security/components/AdminSecurityPage.tsx +1 -2
  94. package/src/features/admin-users/components/AdminUsersPage.tsx +1 -1
  95. package/src/features/moderate-entity-tags/components/EntityTagsPage.tsx +1 -2
  96. package/src/features/moderate-recent/components/RecentDocumentsPage.tsx +1 -2
  97. package/src/features/moderate-tag-schemas/components/TagSchemasPage.tsx +1 -1
  98. package/src/features/moderation-linked-data/components/LinkedDataPage.tsx +1 -1
  99. package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +5 -3
  100. package/src/features/resource-compose/components/ResourceComposePage.tsx +6 -22
  101. package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +4 -3
  102. package/src/features/resource-discovery/components/ResourceCard.tsx +1 -2
  103. package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +3 -4
  104. package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +37 -45
  105. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +129 -197
  106. package/dist/KnowledgeBaseSessionContext-BNNunwzO.d.mts +0 -175
  107. package/dist/PdfAnnotationCanvas.client-CHDCGQBR.mjs.map +0 -1
  108. package/dist/chunk-OZICDVH7.mjs +0 -62
  109. package/dist/chunk-OZICDVH7.mjs.map +0 -1
  110. package/dist/chunk-R4CCMFJH.mjs +0 -877
  111. package/dist/chunk-R4CCMFJH.mjs.map +0 -1
  112. package/dist/chunk-VN5NY4SN.mjs +0 -200
  113. package/dist/chunk-VN5NY4SN.mjs.map +0 -1
  114. package/src/components/modals/ProposeEntitiesModal.tsx +0 -179
  115. package/src/components/modals/__tests__/ProposeEntitiesModal.test.tsx +0 -129
  116. package/src/features/resource-viewer/__tests__/AnnotationCreationPending.test.tsx +0 -323
  117. package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +0 -245
  118. package/src/features/resource-viewer/__tests__/AnnotationProgressDismissal.test.tsx +0 -303
  119. package/src/features/resource-viewer/__tests__/BindFlowIntegration.test.tsx +0 -150
  120. package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +0 -243
  121. package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +0 -383
  122. package/src/features/resource-viewer/__tests__/ResourceMutations.test.tsx +0 -299
  123. package/src/features/resource-viewer/__tests__/ToastNotifications.test.tsx +0 -186
  124. package/src/features/resource-viewer/__tests__/YieldFlowIntegration.test.tsx +0 -429
  125. package/src/features/resource-viewer/__tests__/annotation-progress-flow.test.tsx +0 -348
package/dist/index.d.mts CHANGED
@@ -1,31 +1,28 @@
1
- import * as _semiont_core from '@semiont/core';
2
- import { components, ResourceId, Selector, AnnotationId, PersistedEvent, EventBus, EventMap, MarkProgress, StoredEventLike, paths, GatheredContext, Motivation as Motivation$9, YieldProgress } from '@semiont/core';
1
+ import { Annotation, ResourceId, Selector, components, ResourceDescriptor, ValidationResult, EventMap, AnnotationId, StoredEventLike, ConnectionState, GatheredContext } from '@semiont/core';
2
+ export { Annotation } from '@semiont/core';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as React$1 from 'react';
5
5
  import React__default, { ComponentType, ReactNode, KeyboardEvent as KeyboardEvent$1, Component, ErrorInfo, Ref } from 'react';
6
- import { O as OpenResourcesManager, K as KbSessionStatus, a as KnowledgeBase, T as TranslationManager, b as OpenResource } from './KnowledgeBaseSessionContext-BNNunwzO.mjs';
7
- export { A as AuthSession, c as KnowledgeBaseSessionContext, d as KnowledgeBaseSessionProvider, e as KnowledgeBaseSessionValue, N as NewKnowledgeBase, u as useKnowledgeBaseSession } from './KnowledgeBaseSessionContext-BNNunwzO.mjs';
8
- import * as _tanstack_react_query from '@tanstack/react-query';
9
- import { UseQueryOptions } from '@tanstack/react-query';
10
- import { SemiontApiClient, ValidationResult, TokenRefresher } from '@semiont/api-client';
6
+ import { T as TranslationManager } from './TranslationManager-9Xj3MIWQ.mjs';
11
7
  import * as _codemirror_state from '@codemirror/state';
12
8
  import { HighlightStyle } from '@codemirror/language';
13
9
  import { WidgetType } from '@codemirror/view';
14
- import { Observable } from 'rxjs';
10
+ import { ViewModel, SemiontBrowser, SessionStorage, SemiontSession, OpenResource, ImportPreview, CloneData, ReferenceData, ShellVM } from '@semiont/sdk';
11
+ export { ActiveJob, AdminSecurityVM, AdminUsersVM, AnnotationGroups, BeckonVM, COMMON_PANELS, CloneData, ComposeMode, ComposePageVM, ComposeParams, DiscoverVM, EntityTagsVM, ExchangeVM, GatherVM, GenerateDocumentOptions, HOVER_DELAY_MS, HoverHandlers, ImportPreview, Job, JobAssignment, JobClaimAdapter, JobClaimAdapterOptions, JobQueueVM, MarkVM, MatchVM, PendingAnnotation, RESOURCE_PANELS, ReferenceData, ResourceLoaderVM, ResourceViewerPageVM, SaveResourceParams, SearchPipeline, SearchPipelineOptions, SearchState, SessionVM, ShellVM, ShellVMOptions, ToolbarPanelType, WelcomeVM, WizardState, YieldVM, createAdminSecurityVM, createAdminUsersVM, createBeckonVM, createComposePageVM, createDiscoverVM, createEntityTagsVM, createExchangeVM, createGatherVM, createHoverHandlers, createJobClaimAdapter, createJobQueueVM, createMarkVM, createMatchVM, createResourceLoaderVM, createResourceViewerPageVM, createSearchPipeline, createSessionVM, createShellVM, createWelcomeVM, createYieldVM } from '@semiont/sdk';
15
12
  import { TagSchema } from '@semiont/ontology';
16
13
  export { TAG_SCHEMAS, TagCategory, TagSchema, getAllTagSchemas, getSchemaCategory as getTagCategory, getTagSchema, getTagSchemasByDomain, isValidCategory } from '@semiont/ontology';
14
+ import { Observable } from 'rxjs';
17
15
 
18
- type Annotation$m = components['schemas']['Annotation'];
19
16
  /**
20
17
  * Collection of all annotation types for a resource.
21
18
  * Replaces separate highlights, references, assessments, comments, tags props.
22
19
  */
23
20
  interface AnnotationsCollection {
24
- highlights: Annotation$m[];
25
- references: Annotation$m[];
26
- assessments: Annotation$m[];
27
- comments: Annotation$m[];
28
- tags: Annotation$m[];
21
+ highlights: Annotation[];
22
+ references: Annotation[];
23
+ assessments: Annotation[];
24
+ comments: Annotation[];
25
+ tags: Annotation[];
29
26
  }
30
27
  /**
31
28
  * Event handlers for annotation interactions.
@@ -33,7 +30,7 @@ interface AnnotationsCollection {
33
30
  */
34
31
  interface AnnotationHandlers {
35
32
  /** Unified click handler - routes based on annotation type and current mode */
36
- onClick?: (annotation: Annotation$m, event?: React.MouseEvent) => void;
33
+ onClick?: (annotation: Annotation, event?: React.MouseEvent) => void;
37
34
  /** Unified hover handler for all annotation types */
38
35
  onHover?: (annotationId: string | null) => void;
39
36
  /** Hover handler specifically for comment panel highlighting */
@@ -82,7 +79,7 @@ interface UICreateAnnotationParams {
82
79
  * - linking: Shows Quick Reference popup FIRST, creates when user confirms
83
80
  */
84
81
  interface AnnotationCreationHandler {
85
- onCreate?: (params: UICreateAnnotationParams) => void | Promise<void> | Promise<Annotation$m | undefined>;
82
+ onCreate?: (params: UICreateAnnotationParams) => void | Promise<void> | Promise<Annotation | undefined>;
86
83
  }
87
84
  /**
88
85
  * UI state for annotation toolbar and interactions.
@@ -115,7 +112,6 @@ interface AnnotationConfig {
115
112
  annotateMode?: boolean;
116
113
  }
117
114
 
118
- type Annotation$l = components['schemas']['Annotation'];
119
115
  /**
120
116
  * Parameters for creating an annotation
121
117
  */
@@ -138,19 +134,16 @@ interface DeleteAnnotationParams {
138
134
  * Framework-agnostic interface for annotation mutations.
139
135
  * Apps provide implementations via AnnotationProvider.
140
136
  *
141
- * Example implementation (React Query):
137
+ * Example implementation:
142
138
  * ```typescript
143
- * function useAnnotationManager(): AnnotationManager {
144
- * const createMutation = useAnnotations().create.useMutation();
145
- * const deleteMutation = useAnnotations().delete.useMutation();
146
- *
139
+ * function useAnnotationManager(client: SemiontClient): AnnotationManager {
147
140
  * return {
148
141
  * markAnnotation: async (params) => {
149
- * const result = await createMutation.mutateAsync({...});
142
+ * const result = await client.mark.annotation(params.rUri, {...});
150
143
  * return result.annotation;
151
144
  * },
152
145
  * deleteAnnotation: async (params) => {
153
- * await deleteMutation.mutateAsync({...});
146
+ * await client.mark.delete(params.rUri, params.annotationId);
154
147
  * }
155
148
  * };
156
149
  * }
@@ -162,7 +155,7 @@ interface AnnotationManager {
162
155
  * @param params - Creation parameters (rUri, motivation, selector, body)
163
156
  * @returns Promise resolving to the created annotation, or undefined if creation fails
164
157
  */
165
- markAnnotation: (params: CreateAnnotationParams) => Promise<Annotation$l | undefined>;
158
+ markAnnotation: (params: CreateAnnotationParams) => Promise<Annotation | undefined>;
166
159
  /**
167
160
  * Delete an annotation
168
161
  * @param params - Deletion parameters (annotationId, rUri)
@@ -171,62 +164,6 @@ interface AnnotationManager {
171
164
  deleteAnnotation: (params: DeleteAnnotationParams) => Promise<void>;
172
165
  }
173
166
 
174
- /**
175
- * Cache Manager Interface
176
- *
177
- * Framework-agnostic interface for cache invalidation.
178
- * Apps provide implementations via CacheProvider.
179
- *
180
- * This abstraction allows react-ui to trigger cache invalidation
181
- * without depending on a specific data fetching library (React Query, SWR, Apollo, etc.)
182
- *
183
- * Example implementation (React Query):
184
- * ```typescript
185
- * function useCacheManager(): CacheManager {
186
- * const queryClient = useQueryClient();
187
- *
188
- * return {
189
- * invalidateAnnotations: (rUri) => {
190
- * queryClient.invalidateQueries({ queryKey: ['annotations', rUri] });
191
- * },
192
- * invalidateEvents: (rUri) => {
193
- * queryClient.invalidateQueries({ queryKey: ['documents', 'events', rUri] });
194
- * }
195
- * };
196
- * }
197
- * ```
198
- *
199
- * Example implementation (SWR):
200
- * ```typescript
201
- * function useCacheManager(): CacheManager {
202
- * const { mutate } = useSWRConfig();
203
- *
204
- * return {
205
- * invalidateAnnotations: (rUri) => {
206
- * mutate((key) => Array.isArray(key) && key[0] === 'annotations' && key[1] === rUri);
207
- * },
208
- * invalidateEvents: (rUri) => {
209
- * mutate((key) => Array.isArray(key) && key[0] === 'events' && key[1] === rUri);
210
- * }
211
- * };
212
- * }
213
- * ```
214
- */
215
- interface CacheManager {
216
- /**
217
- * Invalidate annotation cache for a resource
218
- * @param rUri - Resource URI
219
- * @returns Promise or void (synchronous invalidation is acceptable)
220
- */
221
- invalidateAnnotations: (rUri: ResourceId) => void | Promise<void>;
222
- /**
223
- * Invalidate events cache for a resource
224
- * @param rUri - Resource URI
225
- * @returns Promise or void (synchronous invalidation is acceptable)
226
- */
227
- invalidateEvents: (rUri: ResourceId) => void | Promise<void>;
228
- }
229
-
230
167
  /**
231
168
  * Represents a single navigation item
232
169
  */
@@ -265,8 +202,7 @@ interface NavigationProps {
265
202
  * Type definitions for resource viewer feature
266
203
  */
267
204
 
268
- type SemiontResource$4 = components['schemas']['ResourceDescriptor'];
269
- type Annotation$k = components['schemas']['Annotation'];
205
+ type SemiontResource$2 = ResourceDescriptor;
270
206
  type Motivation$8 = components['schemas']['Motivation'];
271
207
  /**
272
208
  * Selection for creating annotations
@@ -294,7 +230,6 @@ interface TextSelection {
294
230
  * No aliasing, wrappers, or compatibility layers elsewhere.
295
231
  */
296
232
 
297
- type Annotation$j = components['schemas']['Annotation'];
298
233
  type Motivation$7 = components['schemas']['Motivation'];
299
234
  /**
300
235
  * Detection configuration for SSE-based annotation detection
@@ -331,7 +266,7 @@ interface Annotator {
331
266
  isClickable: boolean;
332
267
  hasHoverInteraction: boolean;
333
268
  hasSidePanel: boolean;
334
- matchesAnnotation: (annotation: Annotation$j) => boolean;
269
+ matchesAnnotation: (annotation: Annotation) => boolean;
335
270
  announceOnCreate: string;
336
271
  detection?: DetectionConfig;
337
272
  create: CreateConfig;
@@ -341,369 +276,6 @@ interface Annotator {
341
276
  */
342
277
  declare const ANNOTATORS: Record<string, Annotator>;
343
278
 
344
- /**
345
- * Resource operations
346
- */
347
- declare function useResources(): {
348
- list: {
349
- useQuery: (options?: {
350
- limit?: number;
351
- archived?: boolean;
352
- query?: string;
353
- }) => _tanstack_react_query.UseQueryResult<{
354
- resources: _semiont_core.components["schemas"]["ResourceDescriptor"][];
355
- total: number;
356
- offset: number;
357
- limit: number;
358
- }, Error>;
359
- };
360
- get: {
361
- useQuery: (id: ResourceId, options?: Omit<UseQueryOptions, "queryKey" | "queryFn">) => _tanstack_react_query.UseQueryResult<unknown, Error>;
362
- };
363
- events: {
364
- useQuery: (id: ResourceId) => _tanstack_react_query.UseQueryResult<{
365
- events: _semiont_core.components["schemas"]["StoredEventResponse"][];
366
- total: number;
367
- resourceId: string;
368
- }, Error>;
369
- };
370
- annotations: {
371
- useQuery: (id: ResourceId) => _tanstack_react_query.UseQueryResult<{
372
- resource: _semiont_core.components["schemas"]["ResourceDescriptor"];
373
- annotations: _semiont_core.components["schemas"]["Annotation"][];
374
- }, Error>;
375
- };
376
- referencedBy: {
377
- useQuery: (id: ResourceId) => _tanstack_react_query.UseQueryResult<{
378
- referencedBy: {
379
- id: string;
380
- resourceName: string;
381
- target: {
382
- source: string;
383
- selector: {
384
- exact: string;
385
- };
386
- };
387
- }[];
388
- }, Error>;
389
- };
390
- representation: {
391
- useQuery: (id: ResourceId, mediaType: string) => _tanstack_react_query.UseQueryResult<string, Error>;
392
- };
393
- mediaToken: {
394
- useQuery: (id: ResourceId) => _tanstack_react_query.UseQueryResult<{
395
- token: string;
396
- }, Error>;
397
- };
398
- create: {
399
- useMutation: () => _tanstack_react_query.UseMutationResult<{
400
- resourceId: string;
401
- }, Error, {
402
- name: string;
403
- file: File | Buffer;
404
- format: string;
405
- entityTypes?: string[];
406
- language?: string;
407
- creationMethod?: string;
408
- sourceAnnotationId?: string;
409
- sourceResourceId?: string;
410
- storageUri: string;
411
- }, unknown>;
412
- };
413
- update: {
414
- useMutation: () => _tanstack_react_query.UseMutationResult<void, Error, {
415
- id: ResourceId;
416
- data: Parameters<SemiontApiClient["updateResource"]>[1];
417
- }, unknown>;
418
- };
419
- generateCloneToken: {
420
- useMutation: () => _tanstack_react_query.UseMutationResult<{
421
- token: string;
422
- expiresAt: string;
423
- resource: _semiont_core.components["schemas"]["ResourceDescriptor"];
424
- }, Error, ResourceId, unknown>;
425
- };
426
- getByToken: {
427
- useQuery: (cloneTokenStr: string) => _tanstack_react_query.UseQueryResult<{
428
- sourceResource: _semiont_core.components["schemas"]["ResourceDescriptor"];
429
- expiresAt: string;
430
- }, Error>;
431
- };
432
- createFromToken: {
433
- useMutation: () => _tanstack_react_query.UseMutationResult<{
434
- resourceId: string;
435
- }, Error, {
436
- token: string;
437
- name: string;
438
- content: string;
439
- archiveOriginal?: boolean;
440
- }, unknown>;
441
- };
442
- };
443
- /**
444
- * Annotation operations
445
- */
446
- declare function useAnnotations(): {
447
- get: {
448
- useQuery: (id: AnnotationId) => _tanstack_react_query.UseQueryResult<never, Error>;
449
- };
450
- browseAnnotation: {
451
- useQuery: (resourceId: ResourceId, annotationId: AnnotationId) => _tanstack_react_query.UseQueryResult<{
452
- annotation: _semiont_core.components["schemas"]["Annotation"];
453
- resource: _semiont_core.components["schemas"]["ResourceDescriptor"] | null;
454
- resolvedResource: _semiont_core.components["schemas"]["ResourceDescriptor"] | null;
455
- }, Error>;
456
- };
457
- history: {
458
- useQuery: (resourceId: ResourceId, annotationId: AnnotationId) => _tanstack_react_query.UseQueryResult<{
459
- events: _semiont_core.components["schemas"]["StoredEventResponse"][];
460
- total: number;
461
- annotationId: string;
462
- resourceId: string;
463
- }, Error>;
464
- };
465
- create: {
466
- useMutation: () => _tanstack_react_query.UseMutationResult<{
467
- annotationId: string;
468
- }, Error, {
469
- resourceId: ResourceId;
470
- data: Parameters<SemiontApiClient["markAnnotation"]>[1];
471
- }, unknown>;
472
- };
473
- delete: {
474
- useMutation: () => _tanstack_react_query.UseMutationResult<void, Error, {
475
- resourceId: ResourceId;
476
- annotationId: AnnotationId;
477
- }, unknown>;
478
- };
479
- updateBody: {
480
- useMutation: () => _tanstack_react_query.UseMutationResult<{
481
- correlationId: string;
482
- }, Error, {
483
- resourceId: ResourceId;
484
- annotationId: AnnotationId;
485
- data: Parameters<SemiontApiClient["bindAnnotation"]>[2];
486
- }, unknown>;
487
- };
488
- };
489
- /**
490
- * Entity type operations
491
- */
492
- declare function useEntityTypes(): {
493
- list: {
494
- useQuery: (options?: Omit<UseQueryOptions<{
495
- entityTypes: string[];
496
- }>, "queryKey" | "queryFn">) => _tanstack_react_query.UseQueryResult<{
497
- entityTypes: string[];
498
- }, Error>;
499
- };
500
- add: {
501
- useMutation: () => _tanstack_react_query.UseMutationResult<void, Error, string, unknown>;
502
- };
503
- addBulk: {
504
- useMutation: () => _tanstack_react_query.UseMutationResult<void, Error, string[], unknown>;
505
- };
506
- };
507
- /**
508
- * Admin operations
509
- */
510
- declare function useAdmin(): {
511
- users: {
512
- list: {
513
- useQuery: () => _tanstack_react_query.UseQueryResult<{
514
- success: boolean;
515
- users: {
516
- id: string;
517
- email: string;
518
- name: string | null;
519
- image: string | null;
520
- domain: string;
521
- provider: string;
522
- isAdmin: boolean;
523
- isActive: boolean;
524
- lastLogin: string | null;
525
- created: string;
526
- updatedAt: string;
527
- }[];
528
- }, Error>;
529
- };
530
- stats: {
531
- useQuery: () => _tanstack_react_query.UseQueryResult<{
532
- success: boolean;
533
- stats: {
534
- totalUsers: number;
535
- activeUsers: number;
536
- adminUsers: number;
537
- regularUsers: number;
538
- domainBreakdown: {
539
- domain: string;
540
- count: number;
541
- }[];
542
- recentSignups: {
543
- id: string;
544
- email: string;
545
- name: string | null;
546
- created: string;
547
- }[];
548
- };
549
- }, Error>;
550
- };
551
- update: {
552
- useMutation: () => _tanstack_react_query.UseMutationResult<{
553
- success: boolean;
554
- user: {
555
- id: string;
556
- email: string;
557
- name: string | null;
558
- image: string | null;
559
- domain: string;
560
- provider: string;
561
- isAdmin: boolean;
562
- isActive: boolean;
563
- lastLogin: string | null;
564
- created: string;
565
- updatedAt: string;
566
- };
567
- }, Error, {
568
- id: string;
569
- data: Parameters<SemiontApiClient["updateUser"]>[1];
570
- }, unknown>;
571
- };
572
- };
573
- oauth: {
574
- config: {
575
- useQuery: () => _tanstack_react_query.UseQueryResult<{
576
- providers: {
577
- name: string;
578
- isConfigured: boolean;
579
- clientId: string;
580
- }[];
581
- allowedDomains: string[];
582
- }, Error>;
583
- };
584
- };
585
- exchange: {
586
- backup: {
587
- useMutation: () => _tanstack_react_query.UseMutationResult<{
588
- filename: string;
589
- size: number;
590
- }, Error, void, unknown>;
591
- };
592
- restore: {
593
- useMutation: () => _tanstack_react_query.UseMutationResult<{
594
- phase: string;
595
- message?: string;
596
- result?: Record<string, unknown>;
597
- }, Error, {
598
- file: File;
599
- onProgress?: (event: {
600
- phase: string;
601
- message?: string;
602
- result?: Record<string, unknown>;
603
- }) => void;
604
- }, unknown>;
605
- };
606
- };
607
- };
608
- /**
609
- * Moderation operations (moderator or admin role required)
610
- */
611
- declare function useModeration(): {
612
- exchange: {
613
- export: {
614
- useMutation: () => _tanstack_react_query.UseMutationResult<{
615
- filename: string;
616
- size: number;
617
- }, Error, {
618
- includeArchived?: boolean;
619
- } | undefined, unknown>;
620
- };
621
- import: {
622
- useMutation: () => _tanstack_react_query.UseMutationResult<{
623
- phase: string;
624
- message?: string;
625
- result?: Record<string, unknown>;
626
- }, Error, {
627
- file: File;
628
- onProgress?: (event: {
629
- phase: string;
630
- message?: string;
631
- result?: Record<string, unknown>;
632
- }) => void;
633
- }, unknown>;
634
- };
635
- };
636
- };
637
- /**
638
- * Authentication and user operations via API
639
- */
640
- declare function useAuthApi(): {
641
- me: {
642
- useQuery: () => _tanstack_react_query.UseQueryResult<{
643
- id: string;
644
- email: string;
645
- name: string | null;
646
- image: string | null;
647
- domain: string;
648
- provider: string;
649
- isAdmin: boolean;
650
- isModerator: boolean;
651
- isActive: boolean;
652
- termsAcceptedAt: string | null;
653
- lastLogin: string | null;
654
- created: string;
655
- token: string;
656
- }, Error>;
657
- };
658
- acceptTerms: {
659
- useMutation: () => _tanstack_react_query.UseMutationResult<{
660
- success: boolean;
661
- message: string;
662
- }, Error, void, unknown>;
663
- };
664
- generateMCPToken: {
665
- useMutation: () => _tanstack_react_query.UseMutationResult<{
666
- refresh_token: string;
667
- }, Error, void, unknown>;
668
- };
669
- logout: {
670
- useMutation: () => _tanstack_react_query.UseMutationResult<{
671
- success: boolean;
672
- message: string;
673
- }, Error, void, unknown>;
674
- };
675
- };
676
- /**
677
- * Health check and system status
678
- */
679
- declare function useHealth(): {
680
- check: {
681
- useQuery: () => _tanstack_react_query.UseQueryResult<{
682
- status: string;
683
- message: string;
684
- version: string;
685
- timestamp: string;
686
- database: "connected" | "disconnected" | "unknown";
687
- environment: string;
688
- }, Error>;
689
- };
690
- status: {
691
- useQuery: (refetchInterval?: number) => _tanstack_react_query.UseQueryResult<{
692
- status: string;
693
- version: string;
694
- features: {
695
- semanticContent: string;
696
- collaboration: string;
697
- rbac: string;
698
- };
699
- message: string;
700
- authenticatedAs?: string;
701
- projectName?: string;
702
- gitBranch?: string;
703
- }, Error>;
704
- };
705
- };
706
-
707
279
  /**
708
280
  * Centralized button styles matching Figma design
709
281
  * Two primary styles from authenticated home page:
@@ -745,7 +317,6 @@ declare const jsonLightHighlightStyle: HighlightStyle;
745
317
  * clicks and hovers via a single set of delegated handlers.
746
318
  */
747
319
 
748
- type Annotation$i = components['schemas']['Annotation'];
749
320
  /**
750
321
  * Reference Resolution Widget
751
322
  * Shows a small indicator next to references with hover preview.
@@ -754,10 +325,10 @@ type Annotation$i = components['schemas']['Annotation'];
754
325
  * and CodeMirrorRenderer handles events via container-level listeners.
755
326
  */
756
327
  declare class ReferenceResolutionWidget extends WidgetType {
757
- readonly annotation: Annotation$i;
328
+ readonly annotation: Annotation;
758
329
  readonly targetDocumentName?: string | undefined;
759
330
  readonly isGenerating?: boolean | undefined;
760
- constructor(annotation: Annotation$i, targetDocumentName?: string | undefined, isGenerating?: boolean | undefined);
331
+ constructor(annotation: Annotation, targetDocumentName?: string | undefined, isGenerating?: boolean | undefined);
761
332
  eq(other: ReferenceResolutionWidget): boolean;
762
333
  toDOM(): HTMLSpanElement;
763
334
  ignoreEvent(event: Event): boolean;
@@ -848,90 +419,6 @@ declare function getSelectedShapeForSelectorType(selectorType: SelectorType): Sh
848
419
  */
849
420
  declare function saveSelectedShapeForSelectorType(selectorType: SelectorType, shape: ShapeType): void;
850
421
 
851
- /**
852
- * Centralized query keys for React Query
853
- * Following TanStack Query best practices for type-safe cache invalidation
854
- * @see https://tanstack.com/query/latest/docs/framework/react/guides/query-keys
855
- *
856
- * Keys use semantic names (not URL paths) and are properly typed with 'as const'
857
- */
858
-
859
- declare const QUERY_KEYS: {
860
- users: {
861
- me: () => readonly ["users", "me"];
862
- };
863
- health: () => readonly ["health"];
864
- status: () => readonly ["status"];
865
- resources: {
866
- all: (limit?: number, archived?: boolean) => readonly ["resources", {
867
- readonly limit: number | undefined;
868
- readonly archived: boolean | undefined;
869
- }];
870
- detail: (id: ResourceId) => readonly ["resources", ResourceId];
871
- byToken: (token: string) => readonly ["resources", "by-token", string];
872
- events: (id: ResourceId) => readonly ["resources", ResourceId, "events"];
873
- annotations: (id: ResourceId) => readonly ["resources", ResourceId, "annotations"];
874
- referencedBy: (id: ResourceId) => readonly ["resources", ResourceId, "referenced-by"];
875
- representation: (id: ResourceId) => readonly ["resources", ResourceId, "representation"];
876
- mediaToken: (id: ResourceId) => readonly ["resources", ResourceId, "media-token"];
877
- };
878
- annotations: {
879
- detail: (id: AnnotationId) => readonly ["annotations", AnnotationId];
880
- history: (resourceId: ResourceId, annotationId: AnnotationId) => readonly ["annotations", ResourceId, AnnotationId, "history"];
881
- };
882
- entityTypes: {
883
- all: () => readonly ["entity-types"];
884
- };
885
- admin: {
886
- users: {
887
- all: () => readonly ["admin", "users"];
888
- stats: () => readonly ["admin", "users", "stats"];
889
- };
890
- oauth: {
891
- config: () => readonly ["admin", "oauth", "config"];
892
- };
893
- };
894
- };
895
-
896
- /**
897
- * createSearchPipeline
898
- *
899
- * A debounced-search RxJS pipeline factory. Combines an input Subject with a
900
- * downstream fetch function and emits typed `{ results, isSearching }` state.
901
- *
902
- * Designed to be created once per component instance via React's
903
- * `useState(() => createSearchPipeline(...))` lazy initializer, then consumed
904
- * via `useObservable(pipeline.state$)`. The pipeline holds no React state and
905
- * has no React imports — it's pure RxJS, unit-testable without a renderer.
906
- *
907
- * The fetch function is expected to return `Observable<T[] | undefined>`,
908
- * matching the cache-miss-then-data shape of `BrowseNamespace` Observables:
909
- * `undefined` means "fetch in flight, no value yet"; an array means "data
910
- * available (possibly empty)".
911
- */
912
-
913
- interface SearchState<T> {
914
- results: T[];
915
- isSearching: boolean;
916
- }
917
- interface SearchPipeline<T> {
918
- /** Latest query string. Bind to a controlled input via `useObservable`. */
919
- query$: Observable<string>;
920
- /** Latest search state — results plus a loading flag. */
921
- state$: Observable<SearchState<T>>;
922
- /** Push a new query value. Triggers the debounced fetch. */
923
- setQuery(value: string): void;
924
- /** Tear down the input Subject. Call from `useEffect` cleanup. */
925
- dispose(): void;
926
- }
927
- interface SearchPipelineOptions {
928
- /** Milliseconds to wait after the last keystroke before fetching. Default 250. */
929
- debounceMs?: number;
930
- /** Initial query value. Useful for modals that open with a pre-filled term. */
931
- initialQuery?: string;
932
- }
933
- declare function createSearchPipeline<T>(fetch: (query: string) => Observable<T[] | undefined>, options?: SearchPipelineOptions): SearchPipeline<T>;
934
-
935
422
  /**
936
423
  * Annotation overlay: decouples annotation highlighting from markdown rendering.
937
424
  *
@@ -946,7 +433,6 @@ declare function createSearchPipeline<T>(fetch: (query: string) => Observable<T[
946
433
  * the overlay spans — no markdown re-parse, no AST walk.
947
434
  */
948
435
 
949
- type Annotation$h = components['schemas']['Annotation'];
950
436
  interface OverlayAnnotation {
951
437
  id: string;
952
438
  exact: string;
@@ -1001,7 +487,7 @@ declare function clearHighlights(container: HTMLElement): void;
1001
487
  * Convert W3C Annotations to the simplified overlay format.
1002
488
  * Extracts TextPositionSelector offsets and annotation type.
1003
489
  */
1004
- declare function toOverlayAnnotations(annotations: Annotation$h[]): OverlayAnnotation[];
490
+ declare function toOverlayAnnotations(annotations: Annotation[]): OverlayAnnotation[];
1005
491
 
1006
492
  /**
1007
493
  * Resource utilities
@@ -1072,6 +558,8 @@ declare const OAuthUserSchema: {
1072
558
  */
1073
559
  declare function sanitizeImageURL(url: string): string | null;
1074
560
 
561
+ declare function useViewModel<VM extends ViewModel>(factory: () => VM): VM;
562
+
1075
563
  /**
1076
564
  * Creates a debounced version of a callback function
1077
565
  *
@@ -1163,7 +651,7 @@ interface Router {
1163
651
  * Use this to wrap your router (Next.js, React Router, etc.) when you want
1164
652
  * navigation actions to be observable through the NavigationEventBus.
1165
653
  *
1166
- * @emits browse:router-push - Router navigation requested. Payload: { path: string, reason?: string }
654
+ * @emits nav:push - Router navigation requested. Payload: { path: string, reason?: string }
1167
655
  *
1168
656
  * @example
1169
657
  * ```typescript
@@ -1185,13 +673,13 @@ declare function useObservableRouter<T extends Router>(baseRouter: T): T;
1185
673
  * Request navigation with event emission
1186
674
  *
1187
675
  * This hook emits a navigation request event. The app must subscribe to
1188
- * 'browse:external-navigate' and perform the actual navigation using
676
+ * 'nav:external' and perform the actual navigation using
1189
677
  * its router (Next.js, React Router, etc.) to enable client-side routing.
1190
678
  *
1191
679
  * If no subscriber handles the event, falls back to window.location.href
1192
680
  * after a brief delay to allow for event handling.
1193
681
  *
1194
- * @emits browse:external-navigate - External navigation requested. Payload: { url: string, resourceId?: string, cancelFallback: () => void }
682
+ * @emits nav:external - External navigation requested. Payload: { url: string, resourceId?: string, cancelFallback: () => void }
1195
683
  *
1196
684
  * The payload includes a `cancelFallback` function that subscribers must call to
1197
685
  * prevent the window.location fallback from firing. Subscribers that handle the
@@ -1206,7 +694,7 @@ declare function useObservableRouter<T extends Router>(baseRouter: T): T;
1206
694
  * // In app (frontend package) - subscribe, cancel fallback, and handle with Next.js router
1207
695
  * const router = useRouter();
1208
696
  * useEventSubscriptions({
1209
- * 'browse:external-navigate': ({ url, cancelFallback }) => {
697
+ * 'nav:external': ({ url, cancelFallback }) => {
1210
698
  * cancelFallback(); // Prevent window.location fallback
1211
699
  * router.push(url); // Client-side navigation
1212
700
  * },
@@ -1253,84 +741,6 @@ storageKey }?: UsePanelWidthOptions): {
1253
741
  maxWidth: number;
1254
742
  };
1255
743
 
1256
- /**
1257
- * Stream connection status
1258
- */
1259
- type StreamStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
1260
- interface UseResourceEventsOptions {
1261
- rUri: ResourceId;
1262
- onEvent?: (event: PersistedEvent) => void;
1263
- onAnnotationAdded?: (event: Extract<PersistedEvent, {
1264
- type: 'mark:added';
1265
- }>) => void;
1266
- onAnnotationRemoved?: (event: Extract<PersistedEvent, {
1267
- type: 'mark:removed';
1268
- }>) => void;
1269
- onAnnotationBodyUpdated?: (event: Extract<PersistedEvent, {
1270
- type: 'mark:body-updated';
1271
- }>) => void;
1272
- onEntityTagAdded?: (event: Extract<PersistedEvent, {
1273
- type: 'mark:entity-tag-added';
1274
- }>) => void;
1275
- onEntityTagRemoved?: (event: Extract<PersistedEvent, {
1276
- type: 'mark:entity-tag-removed';
1277
- }>) => void;
1278
- onDocumentArchived?: (event: Extract<PersistedEvent, {
1279
- type: 'mark:archived';
1280
- }>) => void;
1281
- onDocumentUnarchived?: (event: Extract<PersistedEvent, {
1282
- type: 'mark:unarchived';
1283
- }>) => void;
1284
- onError?: (error: string) => void;
1285
- autoConnect?: boolean;
1286
- }
1287
- /**
1288
- * React hook for subscribing to real-time document events via SSE
1289
- *
1290
- * Opens a long-lived SSE connection to receive events as they happen.
1291
- *
1292
- * @example
1293
- * ```tsx
1294
- * const { status, connect, disconnect } = useResourceEvents({
1295
- * rUri: resourceUri('http://localhost:4000/resources/doc-123'),
1296
- * onAnnotationAdded: (event) => {
1297
- * console.log('New annotation:', event.payload);
1298
- * },
1299
- * });
1300
- * ```
1301
- */
1302
- declare function useResourceEvents({ rUri, onEvent, onAnnotationAdded, onAnnotationRemoved, onAnnotationBodyUpdated, onEntityTagAdded, onEntityTagRemoved, onDocumentArchived, onDocumentUnarchived, onError, autoConnect, }: UseResourceEventsOptions): {
1303
- status: StreamStatus;
1304
- lastEvent: PersistedEvent | null;
1305
- eventCount: number;
1306
- connect: () => void;
1307
- disconnect: () => void;
1308
- isConnected: boolean;
1309
- };
1310
-
1311
- /**
1312
- * React hook for subscribing to global system-level events via SSE
1313
- *
1314
- * Opens a long-lived SSE connection to GET /api/events/stream to receive
1315
- * domain events that are not scoped to a specific resource (e.g., entity type changes).
1316
- *
1317
- * Automatically invalidates relevant React Query caches when system events arrive.
1318
- *
1319
- * @example
1320
- * ```tsx
1321
- * // In your app layout:
1322
- * useGlobalEvents(); // That's it — auto-connects and invalidates queries
1323
- * ```
1324
- */
1325
- declare function useGlobalEvents({ autoConnect }?: {
1326
- autoConnect?: boolean;
1327
- }): {
1328
- status: StreamStatus;
1329
- connect: () => Promise<void>;
1330
- disconnect: () => void;
1331
- isConnected: boolean;
1332
- };
1333
-
1334
744
  interface UseRovingTabIndexOptions {
1335
745
  orientation?: 'horizontal' | 'vertical' | 'grid';
1336
746
  loop?: boolean;
@@ -1344,8 +754,8 @@ declare function useRovingTabIndex<T extends HTMLElement>(itemCount: number, opt
1344
754
 
1345
755
  /**
1346
756
  * Tracks the time remaining on the active KB session's JWT and whether it's
1347
- * expiring soon (< 5 minutes). Re-derives once per second from the
1348
- * KnowledgeBaseSession context.
757
+ * expiring soon (< 5 minutes). Reads the session's `expiresAt` getter (which
758
+ * derives from the current `token$` value) and re-derives once per second.
1349
759
  */
1350
760
  declare function useSessionExpiry(): {
1351
761
  timeRemaining: number | null;
@@ -1389,19 +799,38 @@ declare function useLoadingState(minLoadingTime?: number): {
1389
799
  */
1390
800
  declare function useLocalStorage<T>(key: string, initialValue: T): [T, (value: T | ((val: T) => T)) => void];
1391
801
 
1392
- type SemiontResource$3 = components['schemas']['ResourceDescriptor'];
1393
802
  interface UseResourceContentResult {
1394
803
  content: string;
1395
804
  loading: boolean;
1396
805
  }
806
+ declare function useResourceContent(rUri: ResourceId, resource: ResourceDescriptor, enabled?: boolean): UseResourceContentResult;
807
+
808
+ interface SemiontProviderProps {
809
+ /** Inject a specific browser (tests). Omit in production. */
810
+ browser?: SemiontBrowser;
811
+ children: ReactNode;
812
+ }
813
+ declare function SemiontProvider({ browser, children }: SemiontProviderProps): react_jsx_runtime.JSX.Element;
814
+ declare function useSemiont(): SemiontBrowser;
815
+
1397
816
  /**
1398
- * Hook to load text resource content (representation)
817
+ * WebBrowserStorage browser-backed `SessionStorage` implementation.
818
+ * Wraps `localStorage` for reads/writes and `window`'s `storage` event
819
+ * for cross-tab change notifications.
1399
820
  *
1400
- * Fetches and decodes the primary text representation of a resource.
1401
- * Only for text types (text/plain, text/markdown).
1402
- * Binary types (image/*, application/pdf) use useMediaToken instead.
821
+ * Construction requires a browser context. The guard matches the
822
+ * existing registry behavior: server rendering that accidentally
823
+ * instantiates this gets a loud error rather than a silent no-op
824
+ * that would mask token leaks.
1403
825
  */
1404
- declare function useResourceContent(rUri: ResourceId, resource: SemiontResource$3, enabled?: boolean): UseResourceContentResult;
826
+
827
+ declare class WebBrowserStorage implements SessionStorage {
828
+ constructor();
829
+ get(key: string): string | null;
830
+ set(key: string, value: string): void;
831
+ delete(key: string): void;
832
+ subscribe(handler: (key: string, newValue: string | null) => void): () => void;
833
+ }
1405
834
 
1406
835
  interface AnnotationProviderProps {
1407
836
  annotationManager: AnnotationManager;
@@ -1415,23 +844,18 @@ interface AnnotationProviderProps {
1415
844
  *
1416
845
  * Example usage:
1417
846
  * ```typescript
1418
- * // In app (apps/frontend/src/hooks/useAnnotationManager.ts)
1419
- *
1420
- * function useAnnotationManager(): AnnotationManager {
1421
- * const annotations = useAnnotations();
1422
- * const createMutation = annotations.create.useMutation();
1423
- * const deleteMutation = annotations.delete.useMutation();
1424
- *
847
+ * function useAnnotationManager(client: SemiontClient): AnnotationManager {
1425
848
  * return {
1426
849
  * markAnnotation: async (params) => {
1427
- * const result = await createMutation.mutateAsync({
1428
- * rUri: params.rUri,
1429
- * data: { motivation: params.motivation, target: { source: params.rUri, selector: params.selector }, body: params.body }
850
+ * const result = await client.mark.annotation(params.rUri, {
851
+ * motivation: params.motivation,
852
+ * target: { source: params.rUri, selector: params.selector },
853
+ * body: params.body,
1430
854
  * });
1431
855
  * return result.annotation;
1432
856
  * },
1433
857
  * deleteAnnotation: async (params) => {
1434
- * await deleteMutation.mutateAsync({ resourceId: params.rUri, annotationId: params.annotationId });
858
+ * await client.mark.delete(params.rUri, params.annotationId);
1435
859
  * }
1436
860
  * };
1437
861
  * }
@@ -1452,158 +876,39 @@ declare function AnnotationProvider({ annotationManager, children }: AnnotationP
1452
876
  */
1453
877
  declare function useAnnotationManager(): AnnotationManager;
1454
878
 
1455
- interface ApiClientProviderProps {
1456
- baseUrl: string;
1457
- /**
1458
- * Optional 401-recovery hook. If provided, the api-client will retry
1459
- * requests once with a fresh token when a 401 is encountered. The
1460
- * frontend's protected layouts pass `useKnowledgeBaseSession().refreshActive`
1461
- * here so the api-client can transparently recover from expired access tokens.
1462
- */
1463
- tokenRefresher?: TokenRefresher;
1464
- children: ReactNode;
1465
- }
1466
- /**
1467
- * Provider for API client — must be nested inside EventBusProvider.
1468
- * The client is re-created when the baseUrl changes (workspace switch).
1469
- * The EventBus is taken from EventBusContext so client and UI components
1470
- * share the same workspace-scoped bus.
1471
- */
1472
- declare function ApiClientProvider({ baseUrl: url, tokenRefresher, children, }: ApiClientProviderProps): react_jsx_runtime.JSX.Element;
1473
- /**
1474
- * Hook to access the stateless API client singleton
1475
- * Must be used within an ApiClientProvider
1476
- * @returns Stateless SemiontApiClient instance
1477
- */
1478
- declare function useApiClient(): SemiontApiClient;
1479
-
1480
- interface AuthTokenProviderProps {
1481
- token: string | null;
1482
- children: ReactNode;
1483
- }
1484
- /**
1485
- * Provider for auth token
1486
- * Pass the current token value - React handles the rest
1487
- */
1488
- declare function AuthTokenProvider({ token, children, }: AuthTokenProviderProps): react_jsx_runtime.JSX.Element;
1489
- /**
1490
- * Hook to get current auth token
1491
- *
1492
- * Returns the current token value from context.
1493
- * Re-renders automatically when token changes (normal React behavior).
1494
- *
1495
- * @returns Current access token (null if not authenticated)
1496
- * @throws Error if used outside AuthTokenProvider
1497
- */
1498
- declare function useAuthToken(): string | null;
1499
-
1500
- interface CacheProviderProps {
1501
- cacheManager: CacheManager;
1502
- children: React__default.ReactNode;
1503
- }
1504
879
  /**
1505
- * Cache Provider
880
+ * Subscribe to a bus event with automatic cleanup.
1506
881
  *
1507
- * Provides cache invalidation capabilities via the Provider Pattern.
1508
- * Apps inject their own CacheManager implementation.
882
+ * Two buses exist: the app-scoped bus on `SemiontBrowser` (panel, shell,
883
+ * tabs, nav, settings events that must work without a KB session) and
884
+ * the per-session bus on `SemiontClient` (mark, beckon, gather,
885
+ * match, bind, yield, browse — events tied to a live KB). This hook
886
+ * subscribes to BOTH so components don't need to know which scope a
887
+ * channel is on. Each channel only fires on one bus, so there's no
888
+ * double-delivery.
1509
889
  *
1510
- * Example usage:
1511
- * ```typescript
1512
- * // In app (apps/frontend/src/hooks/useCacheManager.ts)
1513
- * function useCacheManager(): CacheManager {
1514
- * const queryClient = useQueryClient();
1515
- *
1516
- * return {
1517
- * invalidateAnnotations: (rUri) => {
1518
- * queryClient.invalidateQueries({ queryKey: ['annotations', rUri] });
1519
- * },
1520
- * invalidateEvents: (rUri) => {
1521
- * queryClient.invalidateQueries({ queryKey: ['documents', 'events', rUri] });
1522
- * }
1523
- * };
1524
- * }
1525
- *
1526
- * // In app layout
1527
- * const cacheManager = useCacheManager();
1528
- * <CacheProvider cacheManager={cacheManager}>
1529
- * <YourComponents />
1530
- * </CacheProvider>
1531
- * ```
1532
- */
1533
- declare function CacheProvider({ cacheManager, children }: CacheProviderProps): react_jsx_runtime.JSX.Element;
1534
- /**
1535
- * Hook to access the CacheManager
1536
- *
1537
- * @throws Error if used outside CacheProvider
1538
- * @returns CacheManager instance
1539
- */
1540
- declare function useCacheManager(): CacheManager;
1541
-
1542
- interface EventBusProviderProps {
1543
- children: ReactNode;
1544
- }
1545
- /**
1546
- * Unified event bus provider for all application events.
1547
- *
1548
- * Each provider mount creates a fresh EventBus instance. This means:
1549
- * - Workspace switches (which remount via key prop) get isolated buses
1550
- * - Tests get isolation naturally — no resetEventBusForTesting needed
1551
- *
1552
- * Operation handlers (API calls triggered by events) are set up separately via
1553
- * the useBindFlow hook, which should be called at the resource page level.
1554
- */
1555
- declare function EventBusProvider({ children }: EventBusProviderProps): react_jsx_runtime.JSX.Element;
1556
- /**
1557
- * Hook to access the unified event bus
1558
- *
1559
- * Use this everywhere instead of:
1560
- * - useMakeMeaningEvents()
1561
- * - useNavigationEvents()
1562
- * - useGlobalSettingsEvents()
1563
- *
1564
- * @example
1565
- * ```typescript
1566
- * const eventBus = useEventBus();
1567
- *
1568
- * // Emit any event
1569
- * eventBus.get('beckon:hover').next({ annotationId: '123' });
1570
- * eventBus.get('browse:sidebar-toggle').next(undefined);
1571
- * eventBus.get('settings:theme-changed').next({ theme: 'dark' });
1572
- *
1573
- * // Subscribe to any event
1574
- * useEffect(() => {
1575
- * const unsubscribe = eventBus.on('beckon:hover', ({ annotationId }) => {
1576
- * console.log(annotationId);
1577
- * });
1578
- * return () => unsubscribe();
1579
- * }, []);
1580
- * ```
1581
- */
1582
- declare function useEventBus(): EventBus;
1583
-
1584
- /**
1585
- * Subscribe to an event bus event with automatic cleanup.
1586
- *
1587
- * This hook solves the "stale closure" problem by always using the latest
1588
- * version of the handler without re-subscribing.
890
+ * Stable-handler pattern: the ref-wrapped handler means `handler` itself
891
+ * can change on every render without causing a re-subscription.
1589
892
  *
1590
893
  * @example
1591
894
  * ```tsx
1592
895
  * useEventSubscription('mark:create-ok', ({ annotationId }) => {
1593
- * // This always uses the latest props/state
1594
- * triggerSparkleAnimation(annotation.id);
896
+ * triggerSparkleAnimation(annotationId);
1595
897
  * });
1596
898
  * ```
1597
899
  */
1598
900
  declare function useEventSubscription<K extends keyof EventMap>(eventName: K, handler: (payload: EventMap[K]) => void): void;
1599
901
  /**
1600
- * Subscribe to multiple events at once.
902
+ * Subscribe to multiple bus events at once. Same semantics as
903
+ * `useEventSubscription`, batched — each channel is subscribed on both
904
+ * the app bus (`SemiontBrowser`) and the session bus
905
+ * (`SemiontClient`, when a session is active).
1601
906
  *
1602
907
  * @example
1603
908
  * ```tsx
1604
909
  * useEventSubscriptions({
1605
910
  * 'mark:create-ok': ({ annotationId }) => handleCreated(annotationId),
1606
- * 'mark:delete-ok': ({ annotationId }) => removeAnnotation(annotationId),
911
+ * 'panel:toggle': ({ panel }) => console.log('toggled', panel),
1607
912
  * });
1608
913
  * ```
1609
914
  */
@@ -1611,33 +916,6 @@ declare function useEventSubscriptions(subscriptions: {
1611
916
  [K in keyof EventMap]?: (payload: EventMap[K]) => void;
1612
917
  }): void;
1613
918
 
1614
- /**
1615
- * Provider Pattern: Accepts OpenResourcesManager implementation as prop
1616
- * and makes it available to child components via Context.
1617
- *
1618
- * Apps provide their own implementation (localStorage, sessionStorage, database, etc.)
1619
- * and pass it to this provider at the root level.
1620
- *
1621
- * @example
1622
- * ```tsx
1623
- * // In app root
1624
- * const openResourcesManager = useOpenResourcesManager(); // App's implementation
1625
- *
1626
- * <OpenResourcesProvider openResourcesManager={openResourcesManager}>
1627
- * <App />
1628
- * </OpenResourcesProvider>
1629
- * ```
1630
- */
1631
- declare function OpenResourcesProvider({ openResourcesManager, children }: {
1632
- openResourcesManager: OpenResourcesManager;
1633
- children: React__default.ReactNode;
1634
- }): react_jsx_runtime.JSX.Element;
1635
- /**
1636
- * Hook to access OpenResourcesManager from Context
1637
- * Components use this hook to access open resources functionality
1638
- */
1639
- declare function useOpenResources(): OpenResourcesManager;
1640
-
1641
919
  interface ResourceAnnotationsContextType {
1642
920
  newAnnotationIds: Set<string>;
1643
921
  markAnnotation: (rUri: ResourceId, motivation: 'highlighting' | 'linking' | 'assessing' | 'commenting' | 'tagging', selector: Selector | Selector[], body?: any[]) => Promise<string | undefined>;
@@ -1707,41 +985,6 @@ interface RouteBuilder {
1707
985
  admin?: () => string;
1708
986
  }
1709
987
 
1710
- /**
1711
- * Pure helpers for the KnowledgeBaseSession provider.
1712
- *
1713
- * Contains:
1714
- * - localStorage shape and read/write helpers for KB list, active KB id,
1715
- * and per-KB sessions
1716
- * - JWT expiry parsing and "is expired" check
1717
- * - URL/protocol helpers for KB instances
1718
- * - The public `getKbSessionStatus(kbId)` helper that the KB-list UI uses
1719
- * to color status dots without subscribing to context changes
1720
- *
1721
- * No React imports, no module-scoped state, no side effects beyond
1722
- * localStorage. Splitting these out of the provider file makes them
1723
- * unit-testable in isolation and keeps the React provider focused on
1724
- * lifecycle and state.
1725
- */
1726
-
1727
- /** The shape persisted to localStorage per KB. */
1728
- interface StoredSession {
1729
- access: string;
1730
- refresh: string;
1731
- }
1732
- declare function defaultProtocol(host: string): 'http' | 'https';
1733
- declare function isValidHostname(host: string): boolean;
1734
- declare function kbBackendUrl(kb: KnowledgeBase): string;
1735
- /**
1736
- * Read the locally-stored credential status for a KB. Pure / synchronous —
1737
- * does not subscribe to context changes. Used by KB-list UI to color status
1738
- * dots without requiring re-renders on every tick.
1739
- */
1740
- declare function getKbSessionStatus(kbId: string): KbSessionStatus;
1741
-
1742
- declare function notifySessionExpired(message?: string): void;
1743
- declare function notifyPermissionDenied(message?: string): void;
1744
-
1745
988
  declare const AVAILABLE_LOCALES: readonly ["ar", "bn", "cs", "da", "de", "el", "en", "es", "fa", "fi", "fr", "he", "hi", "id", "it", "ja", "ko", "ms", "nl", "no", "pl", "pt", "ro", "sv", "th", "tr", "uk", "vi", "zh"];
1746
989
  type AvailableLocale = typeof AVAILABLE_LOCALES[number];
1747
990
  interface TranslationProviderProps {
@@ -1798,10 +1041,9 @@ declare function usePreloadTranslations(): {
1798
1041
  * They handle position conversion, tooltip generation, and decoration metadata.
1799
1042
  */
1800
1043
 
1801
- type Annotation$g = components['schemas']['Annotation'];
1802
1044
  interface TextSegment {
1803
1045
  exact: string;
1804
- annotation?: Annotation$g;
1046
+ annotation?: Annotation;
1805
1047
  start: number;
1806
1048
  end: number;
1807
1049
  }
@@ -1821,16 +1063,17 @@ interface Props$b {
1821
1063
  sourceView?: boolean;
1822
1064
  showLineNumbers?: boolean;
1823
1065
  enableWidgets?: boolean;
1824
- eventBus?: EventBus;
1066
+ session?: SemiontSession | null | undefined;
1825
1067
  getTargetResourceName?: (resourceId: string) => string | undefined;
1826
1068
  generatingReferenceId?: string | null;
1827
1069
  hoverDelayMs: number;
1828
1070
  }
1829
- declare function CodeMirrorRenderer({ content, segments, onChange, editable, newAnnotationIds, hoveredAnnotationId, scrollToAnnotationId, sourceView, showLineNumbers, enableWidgets, eventBus, getTargetResourceName, generatingReferenceId, hoverDelayMs }: Props$b): react_jsx_runtime.JSX.Element;
1071
+ declare function CodeMirrorRenderer({ content, segments, onChange, editable, newAnnotationIds, hoveredAnnotationId, scrollToAnnotationId, sourceView, showLineNumbers, enableWidgets, session, getTargetResourceName, generatingReferenceId, hoverDelayMs }: Props$b): react_jsx_runtime.JSX.Element;
1830
1072
 
1831
1073
  type Motivation$6 = components['schemas']['Motivation'];
1074
+ type JobProgress$7 = components['schemas']['JobProgress'];
1832
1075
  interface AnnotateReferencesProgressWidgetProps {
1833
- progress: MarkProgress | null;
1076
+ progress: JobProgress$7 | null;
1834
1077
  annotationType?: Motivation$6 | 'reference';
1835
1078
  }
1836
1079
  /**
@@ -1893,7 +1136,6 @@ interface ProtectedErrorBoundaryProps {
1893
1136
  */
1894
1137
  declare function ProtectedErrorBoundary({ children, resetKeys, }: ProtectedErrorBoundaryProps): react_jsx_runtime.JSX.Element;
1895
1138
 
1896
- type Annotation$f = components['schemas']['Annotation'];
1897
1139
  interface LiveRegionContextType {
1898
1140
  announce: (message: string, priority?: 'polite' | 'assertive') => void;
1899
1141
  }
@@ -1909,9 +1151,9 @@ declare function useSearchAnnouncements(): {
1909
1151
  declare function useDocumentAnnouncements(annotators?: Record<string, Annotator>): {
1910
1152
  announceDocumentSaved: () => void;
1911
1153
  announceDocumentDeleted: () => void;
1912
- announceAnnotationCreated: (annotation: Annotation$f) => void;
1154
+ announceAnnotationCreated: (annotation: Annotation) => void;
1913
1155
  announceAnnotationDeleted: () => void;
1914
- announceAnnotationUpdated: (annotation: Annotation$f) => void;
1156
+ announceAnnotationUpdated: (annotation: Annotation) => void;
1915
1157
  announceError: (message: string) => void;
1916
1158
  };
1917
1159
  declare function useResourceLoadingAnnouncements(): {
@@ -2010,7 +1252,7 @@ interface Props$9<T extends string = string> {
2010
1252
  /**
2011
1253
  * Toolbar component for panel navigation
2012
1254
  *
2013
- * @emits browse:panel-toggle - Toggle panel visibility. Payload: { panel: string }
1255
+ * @emits panel:toggle - Toggle panel visibility. Payload: { panel: string }
2014
1256
  */
2015
1257
  declare function Toolbar<T extends string = string>({ context, activePanel, isArchived }: Props$9<T>): react_jsx_runtime.JSX.Element;
2016
1258
 
@@ -2031,9 +1273,8 @@ interface SettingsPanelProps {
2031
1273
  */
2032
1274
  declare function SettingsPanel({ showLineNumbers, theme, locale, isPendingLocaleChange, hoverDelayMs }: SettingsPanelProps): react_jsx_runtime.JSX.Element;
2033
1275
 
2034
- type Annotation$e = components['schemas']['Annotation'];
2035
1276
  interface JsonLdViewProps {
2036
- annotation: Annotation$e;
1277
+ annotation: Annotation;
2037
1278
  onBack: () => void;
2038
1279
  }
2039
1280
  declare function JsonLdView({ annotation, onBack }: JsonLdViewProps): react_jsx_runtime.JSX.Element;
@@ -2064,14 +1305,13 @@ interface PopupContainerProps {
2064
1305
  }
2065
1306
  declare function PopupContainer({ children, position, onClose, isOpen, wide }: PopupContainerProps): react_jsx_runtime.JSX.Element;
2066
1307
 
2067
- type Annotation$d = components['schemas']['Annotation'];
2068
1308
  interface AnnotationOverlayProps {
2069
- annotations: Annotation$d[];
1309
+ annotations: Annotation[];
2070
1310
  imageWidth: number;
2071
1311
  imageHeight: number;
2072
1312
  displayWidth: number;
2073
1313
  displayHeight: number;
2074
- eventBus?: EventBus;
1314
+ session?: SemiontSession | null | undefined;
2075
1315
  hoveredAnnotationId?: string | null;
2076
1316
  selectedAnnotationId?: string | null;
2077
1317
  hoverDelayMs: number;
@@ -2082,16 +1322,15 @@ interface AnnotationOverlayProps {
2082
1322
  * @emits beckon:hover - Annotation hovered or unhovered. Payload: { annotationId: string | null }
2083
1323
  * @emits browse:click - Annotation clicked. Payload: { annotationId: string, motivation: Motivation }
2084
1324
  */
2085
- declare function AnnotationOverlay({ annotations, imageWidth, imageHeight, displayWidth, displayHeight, eventBus, hoveredAnnotationId, selectedAnnotationId, hoverDelayMs }: AnnotationOverlayProps): react_jsx_runtime.JSX.Element;
1325
+ declare function AnnotationOverlay({ annotations, imageWidth, imageHeight, displayWidth, displayHeight, session, hoveredAnnotationId, selectedAnnotationId, hoverDelayMs }: AnnotationOverlayProps): react_jsx_runtime.JSX.Element;
2086
1326
 
2087
- type Annotation$c = components['schemas']['Annotation'];
2088
1327
  type DrawingMode = 'rectangle' | 'polygon' | 'circle' | 'freeform' | null;
2089
1328
  interface SvgDrawingCanvasProps {
2090
1329
  imageUrl: string;
2091
- existingAnnotations?: Annotation$c[];
1330
+ existingAnnotations?: Annotation[];
2092
1331
  drawingMode: DrawingMode;
2093
1332
  selectedMotivation?: SelectionMotivation | null;
2094
- eventBus?: EventBus;
1333
+ session?: SemiontSession | null | undefined;
2095
1334
  hoveredAnnotationId?: string | null;
2096
1335
  selectedAnnotationId?: string | null;
2097
1336
  hoverDelayMs?: number;
@@ -2102,7 +1341,7 @@ interface SvgDrawingCanvasProps {
2102
1341
  * @emits browse:click - Annotation clicked on canvas. Payload: { annotationId: string, motivation: Motivation }
2103
1342
  * @emits mark:requested - New annotation drawn on canvas. Payload: { selector: SvgSelector, motivation: SelectionMotivation }
2104
1343
  */
2105
- declare function SvgDrawingCanvas({ imageUrl, existingAnnotations, drawingMode, selectedMotivation, eventBus, hoveredAnnotationId, selectedAnnotationId }: SvgDrawingCanvasProps): react_jsx_runtime.JSX.Element;
1344
+ declare function SvgDrawingCanvas({ imageUrl, existingAnnotations, drawingMode, selectedMotivation, session, hoveredAnnotationId, selectedAnnotationId }: SvgDrawingCanvasProps): react_jsx_runtime.JSX.Element;
2106
1345
 
2107
1346
  interface KeyboardShortcutsHelpModalProps {
2108
1347
  isOpen: boolean;
@@ -2114,30 +1353,23 @@ declare function KeyboardShortcutsHelpModal({ isOpen, onClose }: KeyboardShortcu
2114
1353
  * Modal that surfaces when a 403 forbidden error is reported via
2115
1354
  * `notifyPermissionDenied` (called from QueryCache.onError).
2116
1355
  *
2117
- * Reads `permissionDeniedAt` and `permissionDeniedMessage` from
2118
- * KnowledgeBaseSessionContext. The provider clears the flag when the user
2119
- * dismisses the modal.
2120
- *
2121
- * Must be mounted inside KnowledgeBaseSessionProvider.
1356
+ * Reads `permissionDeniedAt$` and `permissionDeniedMessage$` from the
1357
+ * active `FrontendSessionSignals`. The signals instance clears the
1358
+ * flag when the user dismisses the modal. Modal state lives on
1359
+ * signals (not the session itself) so headless sessions
1360
+ * (workers/CLIs) don't carry dead observables.
2122
1361
  */
2123
1362
  declare function PermissionDeniedModal(): react_jsx_runtime.JSX.Element;
2124
1363
 
2125
- interface ProposeEntitiesModalProps {
2126
- isOpen: boolean;
2127
- onConfirm: (selectedTypes: string[]) => void;
2128
- onCancel: () => void;
2129
- }
2130
- declare function ProposeEntitiesModal({ isOpen, onConfirm, onCancel }: ProposeEntitiesModalProps): react_jsx_runtime.JSX.Element;
2131
-
2132
1364
  /**
2133
1365
  * Modal that surfaces when the active KB's session expires (a 401 from
2134
- * either the provider's own JWT validation or from any React Query call
1366
+ * either the session's own JWT validation or from any React Query call
2135
1367
  * via the QueryCache.onError handler).
2136
1368
  *
2137
- * Reads `sessionExpiredAt` from KnowledgeBaseSessionContext. When the user
2138
- * dismisses the modal, the provider clears the flag.
2139
- *
2140
- * Must be mounted inside KnowledgeBaseSessionProvider.
1369
+ * Reads `sessionExpiredAt$` from the active `FrontendSessionSignals`.
1370
+ * When the user dismisses the modal, the signals instance clears the
1371
+ * flag. Modal state lives on signals (not the session itself) so
1372
+ * headless sessions (workers/CLIs) don't carry dead observables.
2141
1373
  */
2142
1374
  declare function SessionExpiredModal(): react_jsx_runtime.JSX.Element;
2143
1375
 
@@ -2217,7 +1449,6 @@ interface Props$5 {
2217
1449
  }
2218
1450
  declare function HistoryEvent({ event, annotations, allEvents, isRelated, t, Link, routes, onEventRef, onEventClick, onEventHover }: Props$5): react_jsx_runtime.JSX.Element;
2219
1451
 
2220
- type SemiontResource$2 = components['schemas']['ResourceDescriptor'];
2221
1452
  /**
2222
1453
  * ResourceViewer - Display and interact with resource content and annotations
2223
1454
  *
@@ -2227,7 +1458,7 @@ type SemiontResource$2 = components['schemas']['ResourceDescriptor'];
2227
1458
  * - No manual refetch needed - events handle cache invalidation
2228
1459
  *
2229
1460
  * Requirements:
2230
- * - Must be wrapped in MakeMeaningEventBusProvider (provides event bus)
1461
+ * - Must be wrapped in SemiontProvider (which owns the session's event bus)
2231
1462
  * - Must be wrapped in CacheContext (provides cache manager)
2232
1463
  *
2233
1464
  * Event flow:
@@ -2237,7 +1468,7 @@ type SemiontResource$2 = components['schemas']['ResourceDescriptor'];
2237
1468
  * Phase 3 complete: Fully event-driven - all user interactions use unified event bus
2238
1469
  */
2239
1470
  interface Props$4 {
2240
- resource: SemiontResource$2 & {
1471
+ resource: ResourceDescriptor & {
2241
1472
  content: string;
2242
1473
  };
2243
1474
  annotations: AnnotationsCollection;
@@ -2248,7 +1479,7 @@ interface Props$4 {
2248
1479
  }
2249
1480
  /**
2250
1481
  * @emits mark:delete - User requested to delete annotation. Payload: { annotationId: string }
2251
- * @emits browse:panel-open - Request to open panel with annotation. Payload: { panel: string, scrollToAnnotationId?: string, motivation?: Motivation }
1482
+ * @emits panel:open - Request to open panel with annotation. Payload: { panel: string, scrollToAnnotationId?: string, motivation?: Motivation }
2252
1483
  *
2253
1484
  * @subscribes mark:mode-toggled - Toggles between browse and annotate mode. Payload: { mode: 'browse' | 'annotate' }
2254
1485
  * @subscribes mark:added - New annotation was added. Payload: { annotation: Annotation }
@@ -2261,30 +1492,25 @@ interface Props$4 {
2261
1492
  */
2262
1493
  declare function ResourceViewer({ resource, annotations, generatingReferenceId, showLineNumbers, hoverDelayMs, hoveredAnnotationId: hoveredAnnotationIdProp }: Props$4): react_jsx_runtime.JSX.Element;
2263
1494
 
2264
- type Annotation$b = components['schemas']['Annotation'];
2265
1495
  interface AssessmentEntryProps {
2266
- assessment: Annotation$b;
1496
+ assessment: Annotation;
2267
1497
  isFocused: boolean;
2268
1498
  isHovered?: boolean;
2269
1499
  ref?: Ref<HTMLDivElement>;
2270
1500
  }
2271
1501
  declare function AssessmentEntry({ assessment, isFocused, isHovered, ref, }: AssessmentEntryProps): react_jsx_runtime.JSX.Element;
2272
1502
 
2273
- type Annotation$a = components['schemas']['Annotation'];
2274
1503
  type Motivation$5 = components['schemas']['Motivation'];
2275
- interface PendingAnnotation$6 {
1504
+ type JobProgress$6 = components['schemas']['JobProgress'];
1505
+ interface PendingAnnotation$5 {
2276
1506
  selector: Selector | Selector[];
2277
1507
  motivation: Motivation$5;
2278
1508
  }
2279
1509
  interface AssessmentPanelProps {
2280
- annotations: Annotation$a[];
2281
- pendingAnnotation: PendingAnnotation$6 | null;
1510
+ annotations: Annotation[];
1511
+ pendingAnnotation: PendingAnnotation$5 | null;
2282
1512
  isAssisting?: boolean;
2283
- progress?: {
2284
- status: string;
2285
- percentage?: number;
2286
- message?: string;
2287
- } | null;
1513
+ progress?: JobProgress$6 | null;
2288
1514
  locale?: string;
2289
1515
  annotateMode?: boolean;
2290
1516
  scrollToAnnotationId?: string | null;
@@ -2301,16 +1527,32 @@ interface AssessmentPanelProps {
2301
1527
  declare function AssessmentPanel({ annotations, pendingAnnotation, isAssisting, progress, locale, annotateMode, scrollToAnnotationId, onScrollCompleted, hoveredAnnotationId, }: AssessmentPanelProps): react_jsx_runtime.JSX.Element;
2302
1528
 
2303
1529
  interface Props$3 {
2304
- isConnected: boolean;
1530
+ /**
1531
+ * Connection state from `client.actor.state$`. See
1532
+ * `packages/api-client/src/view-models/domain/actor-vm.ts`.
1533
+ *
1534
+ * UI mapping:
1535
+ * `open` | `reconnecting` | `initial` | `connecting`
1536
+ * → treated as "healthy" (green dot, "Live" label, event count visible).
1537
+ * `reconnecting` is specifically INCLUDED in healthy because a
1538
+ * brief reconnect (mount churn, channel-set change, quick blip)
1539
+ * shouldn't alarm the user. The 100 ms reconnect debounce and
1540
+ * sub-second fetch retry make `reconnecting` a transient state.
1541
+ * `degraded` | `closed`
1542
+ * → treated as "disconnected" (red dot, "Disconnected" label).
1543
+ * `degraded` is the 3 s threshold at which the state machine
1544
+ * decides the disconnect is sustained; this is the UI-banner
1545
+ * trigger the plan was designed around.
1546
+ */
1547
+ state: ConnectionState;
2305
1548
  eventCount: number;
2306
1549
  lastEventTimestamp?: string;
2307
1550
  knowledgeBaseName?: string;
2308
1551
  }
2309
- declare function CollaborationPanel({ isConnected, eventCount, lastEventTimestamp, knowledgeBaseName }: Props$3): react_jsx_runtime.JSX.Element;
1552
+ declare function CollaborationPanel({ state, eventCount, lastEventTimestamp, knowledgeBaseName }: Props$3): react_jsx_runtime.JSX.Element;
2310
1553
 
2311
- type Annotation$9 = components['schemas']['Annotation'];
2312
1554
  interface CommentEntryProps {
2313
- comment: Annotation$9;
1555
+ comment: Annotation;
2314
1556
  isFocused: boolean;
2315
1557
  isHovered?: boolean;
2316
1558
  annotateMode?: boolean;
@@ -2318,22 +1560,18 @@ interface CommentEntryProps {
2318
1560
  }
2319
1561
  declare function CommentEntry({ comment, isFocused, isHovered, annotateMode, ref, }: CommentEntryProps): react_jsx_runtime.JSX.Element;
2320
1562
 
2321
- type Annotation$8 = components['schemas']['Annotation'];
2322
1563
  type Motivation$4 = components['schemas']['Motivation'];
2323
- interface PendingAnnotation$5 {
1564
+ type JobProgress$5 = components['schemas']['JobProgress'];
1565
+ interface PendingAnnotation$4 {
2324
1566
  selector: Selector | Selector[];
2325
1567
  motivation: Motivation$4;
2326
1568
  }
2327
1569
  interface CommentsPanelProps {
2328
- annotations: Annotation$8[];
2329
- pendingAnnotation: PendingAnnotation$5 | null;
1570
+ annotations: Annotation[];
1571
+ pendingAnnotation: PendingAnnotation$4 | null;
2330
1572
  annotateMode?: boolean;
2331
1573
  isAssisting?: boolean;
2332
- progress?: {
2333
- status: string;
2334
- percentage?: number;
2335
- message?: string;
2336
- } | null;
1574
+ progress?: JobProgress$5 | null;
2337
1575
  locale?: string;
2338
1576
  scrollToAnnotationId?: string | null;
2339
1577
  onScrollCompleted?: () => void;
@@ -2348,19 +1586,12 @@ interface CommentsPanelProps {
2348
1586
  */
2349
1587
  declare function CommentsPanel({ annotations, pendingAnnotation, annotateMode, isAssisting, progress, locale, scrollToAnnotationId, onScrollCompleted, hoveredAnnotationId, }: CommentsPanelProps): react_jsx_runtime.JSX.Element;
2350
1588
 
1589
+ type JobProgress$4 = components['schemas']['JobProgress'];
2351
1590
  interface AssistSectionProps {
2352
1591
  annotationType: 'highlight' | 'assessment' | 'comment';
2353
1592
  isAssisting: boolean;
2354
1593
  locale?: string;
2355
- progress?: {
2356
- status: string;
2357
- percentage?: number;
2358
- message?: string;
2359
- requestParams?: Array<{
2360
- label: string;
2361
- value: string;
2362
- }>;
2363
- } | null | undefined;
1594
+ progress?: JobProgress$4 | null | undefined;
2364
1595
  }
2365
1596
  /**
2366
1597
  * Shared assist section for Highlight, Assessment, and Comment panels
@@ -2376,30 +1607,25 @@ interface AssistSectionProps {
2376
1607
  */
2377
1608
  declare function AssistSection({ annotationType, isAssisting, locale, progress, }: AssistSectionProps): react_jsx_runtime.JSX.Element;
2378
1609
 
2379
- type Annotation$7 = components['schemas']['Annotation'];
2380
1610
  interface HighlightEntryProps {
2381
- highlight: Annotation$7;
1611
+ highlight: Annotation;
2382
1612
  isFocused: boolean;
2383
1613
  isHovered?: boolean;
2384
1614
  ref?: Ref<HTMLDivElement>;
2385
1615
  }
2386
1616
  declare function HighlightEntry({ highlight, isFocused, isHovered, ref, }: HighlightEntryProps): react_jsx_runtime.JSX.Element;
2387
1617
 
2388
- type Annotation$6 = components['schemas']['Annotation'];
2389
1618
  type Motivation$3 = components['schemas']['Motivation'];
2390
- interface PendingAnnotation$4 {
1619
+ type JobProgress$3 = components['schemas']['JobProgress'];
1620
+ interface PendingAnnotation$3 {
2391
1621
  selector: Selector | Selector[];
2392
1622
  motivation: Motivation$3;
2393
1623
  }
2394
1624
  interface HighlightPanelProps {
2395
- annotations: Annotation$6[];
2396
- pendingAnnotation: PendingAnnotation$4 | null;
1625
+ annotations: Annotation[];
1626
+ pendingAnnotation: PendingAnnotation$3 | null;
2397
1627
  isAssisting?: boolean;
2398
- progress?: {
2399
- status: string;
2400
- percentage?: number;
2401
- message?: string;
2402
- } | null;
1628
+ progress?: JobProgress$3 | null;
2403
1629
  annotateMode?: boolean;
2404
1630
  scrollToAnnotationId?: string | null;
2405
1631
  onScrollCompleted?: () => void;
@@ -2431,9 +1657,8 @@ interface PanelHeaderProps {
2431
1657
  */
2432
1658
  declare function PanelHeader({ count, title }: PanelHeaderProps): react_jsx_runtime.JSX.Element;
2433
1659
 
2434
- type Annotation$5 = components['schemas']['Annotation'];
2435
1660
  interface ReferenceEntryProps {
2436
- reference: Annotation$5;
1661
+ reference: Annotation;
2437
1662
  isFocused: boolean;
2438
1663
  isHovered?: boolean;
2439
1664
  routes: RouteBuilder;
@@ -2443,26 +1668,18 @@ interface ReferenceEntryProps {
2443
1668
  }
2444
1669
  declare function ReferenceEntry({ reference, isFocused, isHovered, routes, annotateMode, isGenerating, ref, }: ReferenceEntryProps): react_jsx_runtime.JSX.Element;
2445
1670
 
2446
- type Annotation$4 = components['schemas']['Annotation'];
1671
+ type JobProgress$2 = components['schemas']['JobProgress'];
1672
+
2447
1673
  type Motivation$2 = components['schemas']['Motivation'];
2448
- type ResponseContent<T> = T extends {
2449
- responses: {
2450
- 200: {
2451
- content: {
2452
- 'application/json': infer R;
2453
- };
2454
- };
2455
- };
2456
- } ? R : never;
2457
- type ReferencedBy = ResponseContent<paths['/resources/{id}/referenced-by']['get']>['referencedBy'][number];
2458
- interface PendingAnnotation$3 {
1674
+ type ReferencedBy = components['schemas']['GetReferencedByResponse']['referencedBy'][number];
1675
+ interface PendingAnnotation$2 {
2459
1676
  selector: Selector | Selector[];
2460
1677
  motivation: Motivation$2;
2461
1678
  }
2462
1679
  interface Props$1 {
2463
- annotations?: Annotation$4[];
1680
+ annotations?: Annotation[];
2464
1681
  isAssisting: boolean;
2465
- progress: MarkProgress | null;
1682
+ progress: JobProgress$2 | null;
2466
1683
  annotateMode?: boolean;
2467
1684
  Link: React__default.ComponentType<LinkComponentProps>;
2468
1685
  routes: RouteBuilder;
@@ -2470,7 +1687,7 @@ interface Props$1 {
2470
1687
  generatingReferenceId?: string | null;
2471
1688
  referencedBy?: ReferencedBy[];
2472
1689
  referencedByLoading?: boolean;
2473
- pendingAnnotation: PendingAnnotation$3 | null;
1690
+ pendingAnnotation: PendingAnnotation$2 | null;
2474
1691
  scrollToAnnotationId?: string | null;
2475
1692
  onScrollCompleted?: () => void;
2476
1693
  hoveredAnnotationId?: string | null;
@@ -2510,48 +1727,35 @@ interface Props {
2510
1727
  */
2511
1728
  declare function ResourceInfoPanel({ resourceId, documentEntityTypes, documentLocale, primaryMediaType, primaryByteSize, storageUri, isArchived, dateCreated, dateModified, creationMethod, wasAttributedTo, wasDerivedFrom, generator, }: Props): react_jsx_runtime.JSX.Element;
2512
1729
 
2513
- type Annotation$3 = components['schemas']['Annotation'];
2514
1730
  interface StatisticsPanelProps {
2515
- highlights: Annotation$3[];
2516
- comments: Annotation$3[];
2517
- assessments: Annotation$3[];
2518
- references: Annotation$3[];
2519
- tags: Annotation$3[];
1731
+ highlights: Annotation[];
1732
+ comments: Annotation[];
1733
+ assessments: Annotation[];
1734
+ references: Annotation[];
1735
+ tags: Annotation[];
2520
1736
  }
2521
1737
  declare function StatisticsPanel({ highlights, comments, assessments, references, tags }: StatisticsPanelProps): react_jsx_runtime.JSX.Element;
2522
1738
 
2523
- type Annotation$2 = components['schemas']['Annotation'];
2524
1739
  interface TagEntryProps {
2525
- tag: Annotation$2;
1740
+ tag: Annotation;
2526
1741
  isFocused: boolean;
2527
1742
  isHovered?: boolean;
2528
1743
  ref?: Ref<HTMLDivElement>;
2529
1744
  }
2530
1745
  declare function TagEntry({ tag, isFocused, isHovered, ref, }: TagEntryProps): react_jsx_runtime.JSX.Element;
2531
1746
 
2532
- type Annotation$1 = components['schemas']['Annotation'];
2533
1747
  type Motivation$1 = components['schemas']['Motivation'];
2534
- interface PendingAnnotation$2 {
1748
+ type JobProgress$1 = components['schemas']['JobProgress'];
1749
+ interface PendingAnnotation$1 {
2535
1750
  selector: Selector | Selector[];
2536
1751
  motivation: Motivation$1;
2537
1752
  }
2538
1753
  interface TaggingPanelProps {
2539
- annotations: Annotation$1[];
1754
+ annotations: Annotation[];
2540
1755
  annotateMode?: boolean;
2541
1756
  isAssisting?: boolean;
2542
- progress?: {
2543
- status: string;
2544
- percentage?: number;
2545
- currentCategory?: string;
2546
- processedCategories?: number;
2547
- totalCategories?: number;
2548
- message?: string;
2549
- requestParams?: Array<{
2550
- label: string;
2551
- value: string;
2552
- }>;
2553
- } | null;
2554
- pendingAnnotation: PendingAnnotation$2 | null;
1757
+ progress?: JobProgress$1 | null;
1758
+ pendingAnnotation: PendingAnnotation$1 | null;
2555
1759
  scrollToAnnotationId?: string | null;
2556
1760
  onScrollCompleted?: () => void;
2557
1761
  hoveredAnnotationId?: string | null;
@@ -2566,10 +1770,11 @@ interface TaggingPanelProps {
2566
1770
  */
2567
1771
  declare function TaggingPanel({ annotations, annotateMode, isAssisting, progress, pendingAnnotation, scrollToAnnotationId, onScrollCompleted, hoveredAnnotationId, }: TaggingPanelProps): react_jsx_runtime.JSX.Element;
2568
1772
 
2569
- type Annotation = components['schemas']['Annotation'];
1773
+ type JobProgress = components['schemas']['JobProgress'];
1774
+
2570
1775
  type Motivation = components['schemas']['Motivation'];
2571
1776
  type TabKey = 'statistics' | 'reference' | 'highlight' | 'assessment' | 'comment' | 'tag';
2572
- interface PendingAnnotation$1 {
1777
+ interface PendingAnnotation {
2573
1778
  selector: Selector | Selector[];
2574
1779
  motivation: Motivation;
2575
1780
  }
@@ -2587,8 +1792,8 @@ interface UnifiedAnnotationsPanelProps {
2587
1792
  annotators: Record<string, Annotator>;
2588
1793
  annotateMode?: boolean;
2589
1794
  assistingMotivation?: Motivation | null;
2590
- progress?: MarkProgress | null;
2591
- pendingAnnotation: PendingAnnotation$1 | null;
1795
+ progress?: JobProgress | null;
1796
+ pendingAnnotation: PendingAnnotation | null;
2592
1797
  allEntityTypes?: string[];
2593
1798
  generatingReferenceId?: string | null;
2594
1799
  referencedBy?: any[];
@@ -2665,7 +1870,7 @@ interface ObservableLinkProps extends React__default.AnchorHTMLAttributes<HTMLAn
2665
1870
  * - State coordination before navigation
2666
1871
  * - Logging navigation flows
2667
1872
  *
2668
- * The component emits 'browse:link-clicked' event before allowing
1873
+ * The component emits 'nav:link-clicked' event before allowing
2669
1874
  * the browser to follow the link.
2670
1875
  *
2671
1876
  * @example
@@ -2689,7 +1894,7 @@ interface ObservableLinkProps extends React__default.AnchorHTMLAttributes<HTMLAn
2689
1894
  * </Link>
2690
1895
  * ```
2691
1896
  *
2692
- * @emits browse:link-clicked - Link clicked by user. Payload: { href: string, label?: string }
1897
+ * @emits nav:link-clicked - Link clicked by user. Payload: { href: string, label?: string }
2693
1898
  */
2694
1899
  declare function ObservableLink({ href, label, onClick, children, ...anchorProps }: ObservableLinkProps): react_jsx_runtime.JSX.Element;
2695
1900
 
@@ -2723,7 +1928,7 @@ interface SimpleNavigationProps$1 {
2723
1928
  * Simple navigation component for Admin and Moderation modes.
2724
1929
  * Renders a section header with optional dropdown and static navigation tabs.
2725
1930
  *
2726
- * @emits browse:sidebar-toggle - Toggle sidebar collapsed/expanded state. Payload: undefined
1931
+ * @emits shell:sidebar-toggle - Toggle sidebar collapsed/expanded state. Payload: undefined
2727
1932
  */
2728
1933
  declare function SimpleNavigation({ title, items, currentPath, LinkComponent, dropdownContent, isCollapsed, icons, collapseSidebarLabel, expandSidebarLabel }: SimpleNavigationProps$1): react_jsx_runtime.JSX.Element;
2729
1934
 
@@ -2789,9 +1994,9 @@ interface CollapsibleResourceNavigationProps {
2789
1994
  * Supports drag and drop for resource reordering when expanded.
2790
1995
  * Platform-agnostic design for use across different React environments.
2791
1996
  *
2792
- * @emits browse:resource-reorder - Resource tab reordered. Payload: { oldIndex: number, newIndex: number }
2793
- * @emits browse:resource-close - Resource tab closed. Payload: { resourceId: string }
2794
- * @emits browse:sidebar-toggle - Toggle sidebar collapsed/expanded state. Payload: undefined
1997
+ * @emits tabs:reorder - Resource tab reordered. Payload: { oldIndex: number, newIndex: number }
1998
+ * @emits tabs:close - Resource tab closed. Payload: { resourceId: string }
1999
+ * @emits shell:sidebar-toggle - Toggle sidebar collapsed/expanded state. Payload: undefined
2795
2000
  */
2796
2001
  declare function CollapsibleResourceNavigation({ fixedItems, resources, isCollapsed, currentPath, LinkComponent, onNavigate, getResourceHref, className, translations, icons, navigationMenu }: CollapsibleResourceNavigationProps): react_jsx_runtime.JSX.Element;
2797
2002
 
@@ -2842,8 +2047,6 @@ interface ReferenceWizardModalProps {
2842
2047
  context: GatheredContext | null;
2843
2048
  contextLoading: boolean;
2844
2049
  contextError: Error | null;
2845
- /** Event bus for emitting downstream events */
2846
- eventBus: EventBus;
2847
2050
  /** Callbacks */
2848
2051
  onGenerateSubmit: (referenceId: string, config: GenerationConfig) => void;
2849
2052
  onLinkResource: (referenceId: string, targetResourceId: string) => void;
@@ -2887,7 +2090,7 @@ interface ReferenceWizardModalProps {
2887
2090
  semanticScoringHelp: string;
2888
2091
  };
2889
2092
  }
2890
- declare function ReferenceWizardModal({ isOpen, onClose, annotationId, resourceId, defaultTitle, entityTypes, locale, context, contextLoading, contextError, eventBus, onGenerateSubmit, onLinkResource, onComposeNavigate, translations: t, }: ReferenceWizardModalProps): react_jsx_runtime.JSX.Element;
2093
+ declare function ReferenceWizardModal({ isOpen, onClose, annotationId, resourceId, defaultTitle, entityTypes, locale, context, contextLoading, contextError, onGenerateSubmit, onLinkResource, onComposeNavigate, translations: t, }: ReferenceWizardModalProps): react_jsx_runtime.JSX.Element;
2891
2094
 
2892
2095
  interface SearchModalProps$1 {
2893
2096
  isOpen: boolean;
@@ -3391,17 +2594,6 @@ interface ExportCardProps {
3391
2594
  }
3392
2595
  declare function ExportCard({ onExport, isExporting, translations: t }: ExportCardProps): react_jsx_runtime.JSX.Element;
3393
2596
 
3394
- /**
3395
- * ImportCard — File drop zone, preview, and import trigger
3396
- *
3397
- * Pure React component. All state and handlers passed as props.
3398
- */
3399
- interface ImportPreview {
3400
- format: string;
3401
- version: number;
3402
- sourceUrl: string;
3403
- stats: Record<string, number>;
3404
- }
3405
2597
  interface ImportCardTranslations {
3406
2598
  title: string;
3407
2599
  description: string;
@@ -3871,19 +3063,10 @@ interface TagSchemasPageProps {
3871
3063
  }
3872
3064
  declare function TagSchemasPage({ schemas, isLoading, theme, showLineNumbers, activePanel, translations: t, ToolbarPanels, Toolbar, }: TagSchemasPageProps): react_jsx_runtime.JSX.Element;
3873
3065
 
3874
- type ResourceDescriptor$2 = components['schemas']['ResourceDescriptor'];
3875
3066
  interface ResourceComposePageProps {
3876
3067
  mode: 'new' | 'clone' | 'reference';
3877
- cloneData?: {
3878
- sourceResource: ResourceDescriptor$2;
3879
- sourceContent: string;
3880
- };
3881
- referenceData?: {
3882
- annotationUri: string;
3883
- sourceDocumentId: string;
3884
- name: string;
3885
- entityTypes: string[];
3886
- };
3068
+ cloneData?: CloneData | null;
3069
+ referenceData?: ReferenceData | null;
3887
3070
  gatheredContext?: GatheredContext | null;
3888
3071
  availableEntityTypes: string[];
3889
3072
  initialLocale: string;
@@ -3945,10 +3128,9 @@ interface SaveResourceParams {
3945
3128
  }
3946
3129
  declare function ResourceComposePage({ mode, cloneData, referenceData, gatheredContext, availableEntityTypes, initialLocale, theme, showLineNumbers, hoverDelayMs, activePanel, onSaveResource, onCancel, translations: t, ToolbarPanels, Toolbar, }: ResourceComposePageProps): react_jsx_runtime.JSX.Element;
3947
3130
 
3948
- type ResourceDescriptor$1 = components['schemas']['ResourceDescriptor'];
3949
3131
  interface ResourceDiscoveryPageProps {
3950
- recentDocuments: ResourceDescriptor$1[];
3951
- searchDocuments: ResourceDescriptor$1[];
3132
+ recentDocuments: ResourceDescriptor[];
3133
+ searchDocuments: ResourceDescriptor[];
3952
3134
  entityTypes: string[];
3953
3135
  isLoadingRecent: boolean;
3954
3136
  isSearching: boolean;
@@ -3981,7 +3163,6 @@ interface ResourceDiscoveryPageProps {
3981
3163
  }
3982
3164
  declare function ResourceDiscoveryPage({ recentDocuments, searchDocuments, entityTypes, isLoadingRecent, isSearching, searchQuery, onSearchQueryChange, theme, showLineNumbers, activePanel, onNavigateToResource, onNavigateToCompose, translations: t, ToolbarPanels, }: ResourceDiscoveryPageProps): react_jsx_runtime.JSX.Element;
3983
3165
 
3984
- type ResourceDescriptor = components['schemas']['ResourceDescriptor'];
3985
3166
  interface ResourceCardProps {
3986
3167
  resource: ResourceDescriptor;
3987
3168
  onOpen: (resource: ResourceDescriptor) => void;
@@ -3991,7 +3172,7 @@ interface ResourceCardProps {
3991
3172
  }
3992
3173
  declare const ResourceCard: React__default.MemoExoticComponent<({ resource, onOpen, tabIndex, archivedLabel, createdLabel }: ResourceCardProps) => react_jsx_runtime.JSX.Element>;
3993
3174
 
3994
- type SemiontResource = components['schemas']['ResourceDescriptor'];
3175
+ type SemiontResource = ResourceDescriptor;
3995
3176
  interface ResourceViewerPageProps {
3996
3177
  /**
3997
3178
  * The resource to display
@@ -4022,9 +3203,11 @@ interface ResourceViewerPageProps {
4022
3203
  */
4023
3204
  refetchDocument: () => Promise<unknown>;
4024
3205
  /**
4025
- * SSE attention stream connection status for the active workspace
3206
+ * Bus connection state for the active workspace. Six-valued state
3207
+ * machine from `actor.state$`; CollaborationPanel maps it to the
3208
+ * "Live" / "Disconnected" visual.
4026
3209
  */
4027
- streamStatus: StreamStatus;
3210
+ streamStatus: ConnectionState;
4028
3211
  /**
4029
3212
  * Name of the active knowledge base (for display in panels)
4030
3213
  */
@@ -4035,7 +3218,7 @@ interface ResourceViewerPageProps {
4035
3218
  *
4036
3219
  * Uses hooks directly (NO containers, NO render props, NO ResourceViewerPageContent wrapper)
4037
3220
  *
4038
- * @emits browse:router-push - Navigate to a resource or filtered view
3221
+ * @emits nav:push - Navigate to a resource or filtered view
4039
3222
  * @emits beckon:sparkle - Trigger sparkle animation on an annotation
4040
3223
  * @emits bind:update-body - Update annotation body content
4041
3224
  * @subscribes mark:archive - Archive the current resource
@@ -4059,217 +3242,40 @@ interface ResourceViewerPageProps {
4059
3242
  */
4060
3243
  declare function ResourceViewerPage({ resource, rUri, locale, Link, routes, ToolbarPanels, refetchDocument, streamStatus, knowledgeBaseName, }: ResourceViewerPageProps): react_jsx_runtime.JSX.Element;
4061
3244
 
4062
- /**
4063
- * useBeckonFlow — Annotation attention / pointer coordination hook
4064
- *
4065
- * Manages which annotation currently has the user's attention:
4066
- * - Hover state (hoveredAnnotationId)
4067
- * - Hover → sparkle relay
4068
- * - Click → focus relay
4069
- *
4070
- * Follows react-rxjs-guide.md Layer 2 pattern: Hook bridge that
4071
- * subscribes to events and pushes values into React state.
4072
- *
4073
- * Note: beckon:sparkle visual effect (triggerSparkleAnimation) is owned by
4074
- * ResourceViewerPage, which subscribes to beckon:sparkle and delegates to
4075
- * ResourceAnnotationsContext. This hook emits the signal; it does not render the effect.
4076
- *
4077
- * @subscribes beckon:hover - Sets hoveredAnnotationId; emits beckon:sparkle
4078
- * @subscribes browse:click - Emits beckon:focus (attention relay only)
4079
- * @emits beckon:sparkle
4080
- * @emits beckon:focus
4081
- */
4082
-
4083
- interface BeckonFlowState {
4084
- hoveredAnnotationId: string | null;
4085
- }
4086
- declare function useBeckonFlow(): BeckonFlowState;
4087
- /** Default milliseconds the mouse must dwell before beckon:hover is emitted. */
4088
- declare const HOVER_DELAY_MS = 150;
4089
- type EmitHover = (annotationId: string | null) => void;
4090
- interface HoverHandlers {
4091
- /** Call with the annotation ID when the mouse enters an annotation element. */
4092
- handleMouseEnter: (annotationId: string) => void;
4093
- /** Call when the mouse leaves the annotation element. */
4094
- handleMouseLeave: () => void;
4095
- /** Cancel any pending timer — call in the useEffect cleanup. */
4096
- cleanup: () => void;
4097
- }
4098
- /**
4099
- * Creates hover handlers for imperative code (non-hook contexts).
4100
- * @param emit - Callback to emit hover events
4101
- * @param delayMs - Hover delay in milliseconds
4102
- */
4103
- declare function createHoverHandlers(emit: EmitHover, delayMs: number): HoverHandlers;
4104
3245
  interface HoverEmitterProps {
4105
3246
  onMouseEnter: () => void;
4106
3247
  onMouseLeave: () => void;
4107
3248
  }
4108
- /**
4109
- * React hook that returns onMouseEnter / onMouseLeave props for a single
4110
- * annotation entry element.
4111
- *
4112
- * @param annotationId - The ID of the annotation this element represents.
4113
- * @param hoverDelayMs - Hover delay in milliseconds (defaults to HOVER_DELAY_MS for panel entries)
4114
- */
4115
- declare function useHoverEmitter(annotationId: string, hoverDelayMs?: number): HoverEmitterProps;
4116
- /**
4117
- * Opens a participant-scoped SSE connection to receive cross-participant
4118
- * beckon signals. Each incoming signal is emitted as beckon:focus on the
4119
- * EventBus — the existing scroll/highlight machinery handles it automatically.
4120
- *
4121
- * Signals are ephemeral: delivered if connected, silently dropped if not.
4122
- *
4123
- * @example
4124
- * ```tsx
4125
- * // In your layout (render-nothing connector):
4126
- * useAttentionStream();
4127
- * ```
4128
- */
4129
- declare function useAttentionStream(): {
4130
- status: StreamStatus;
4131
- };
4132
-
4133
- /**
4134
- * useMarkFlow - Annotation state management hook
4135
- *
4136
- * Bridges EventBus commands to namespace API methods for annotation CRUD
4137
- * and AI assist. Manages UI state (pendingAnnotation, assistingMotivation,
4138
- * progress) via EventBus subscriptions — the React-specific portion.
4139
- *
4140
- * The FlowEngine's HTTP bridging role is replaced by namespace methods:
4141
- * - mark:submit → semiont.mark.annotation()
4142
- * - mark:delete → semiont.mark.delete()
4143
- * - mark:assist-request → semiont.mark.assist() (Observable)
4144
- */
4145
-
4146
- interface PendingAnnotation {
4147
- selector: Selector | Selector[];
4148
- motivation: Motivation$9;
4149
- }
4150
- interface MarkFlowState {
4151
- pendingAnnotation: PendingAnnotation | null;
4152
- assistingMotivation: Motivation$9 | null;
4153
- progress: MarkProgress | null;
4154
- assistStreamRef: React.MutableRefObject<AbortController | null>;
4155
- }
4156
- declare function useMarkFlow(rUri: ResourceId): MarkFlowState;
4157
-
4158
- /**
4159
- * usePanelBrowse - Panel navigation and scroll coordination hook
4160
- *
4161
- * Manages sidebar panel state:
4162
- * - Active panel tracking (which panel is open)
4163
- * - Scroll coordination (scrollToAnnotationId)
4164
- * - Panel routing with initial tab
4165
- * - LocalStorage persistence
4166
- *
4167
- * Follows react-rxjs-guide.md Layer 2 pattern: Hook bridge that
4168
- * subscribes to events and pushes values into React state.
4169
- */
4170
- type ToolbarPanelType = 'history' | 'info' | 'annotations' | 'settings' | 'collaboration' | 'user' | 'jsonld' | 'knowledge-base';
4171
- /** Panels available on all pages */
4172
- declare const COMMON_PANELS: readonly ToolbarPanelType[];
4173
- /** Panels available only on resource viewer pages */
4174
- declare const RESOURCE_PANELS: readonly ToolbarPanelType[];
4175
- interface PanelBrowseState {
4176
- activePanel: ToolbarPanelType | null;
4177
- scrollToAnnotationId: string | null;
4178
- panelInitialTab: {
4179
- tab: string;
4180
- generation: number;
4181
- } | null;
4182
- onScrollCompleted: () => void;
4183
- }
4184
- /**
4185
- * Hook for panel navigation state management
4186
- *
4187
- * @subscribes browse:panel-toggle - Toggle a panel open/closed
4188
- * @subscribes browse:panel-open - Open a panel, optionally scrolling to an annotation
4189
- * @subscribes browse:panel-close - Close the active panel
4190
- * @returns Panel navigation state
4191
- */
4192
- declare function usePanelBrowse(): PanelBrowseState;
4193
-
4194
- /**
4195
- * useYieldFlow - Document generation flow hook
4196
- *
4197
- * Triggers yield.fromAnnotation() on the namespace API.
4198
- * Manages generation progress state (React-specific) via EventBus subscriptions
4199
- * from the events-stream auto-router.
4200
- */
4201
-
4202
- interface YieldFlowState {
4203
- isGenerating: boolean;
4204
- generationProgress: YieldProgress | null;
4205
- onGenerateDocument: (referenceId: string, options: {
4206
- title: string;
4207
- storageUri: string;
4208
- prompt?: string;
4209
- language?: string;
4210
- temperature?: number;
4211
- maxTokens?: number;
4212
- context: GatheredContext;
4213
- }) => void;
4214
- }
4215
- declare function useYieldFlow(locale: string, resourceId: string, clearNewAnnotationId: (annotationId: AnnotationId) => void): YieldFlowState;
3249
+ declare function useHoverEmitter(annotationId: AnnotationId, hoverDelayMs?: number): HoverEmitterProps;
4216
3250
 
4217
3251
  /**
4218
- * useContextGatherFlow - Context gather capability hook
4219
- *
4220
- * Manages UI state for context gathering. The actual gather trigger
4221
- * comes from components emitting gather:requested on the EventBus.
4222
- * This hook bridges to semiont.gather.annotation() and manages the
4223
- * React state (loading, context, error).
3252
+ * `ShellVM` is app-scoped it owns toolbar panel state and lives on
3253
+ * the `SemiontBrowser`'s own bus. Unlike session-scoped VMs, this hook
3254
+ * does not need to wait for an active KB session; `useSemiont()`
3255
+ * always returns the module-scoped `SemiontBrowser` singleton.
4224
3256
  */
4225
-
4226
- interface ContextGatherFlowConfig {
4227
- resourceId: ResourceId;
4228
- }
4229
- interface ContextGatherFlowState {
4230
- gatherContext: GatheredContext | null;
4231
- gatherLoading: boolean;
4232
- gatherError: Error | null;
4233
- /** The annotationId for which context was most recently gathered */
4234
- gatherAnnotationId: AnnotationId | null;
4235
- }
4236
- declare function useContextGatherFlow(config: ContextGatherFlowConfig): ContextGatherFlowState;
4237
-
4238
- /**
4239
- * useBindFlow - Reference resolution flow hook
4240
- *
4241
- * Bridges EventBus commands to namespace API methods.
4242
- * Components emit bind:update-body / match:search-requested on the EventBus;
4243
- * this hook calls semiont.bind.body() / semiont.match.search() in response.
4244
- *
4245
- * Toast notifications for resolution errors remain here (React-specific).
4246
- */
4247
-
4248
- declare function useBindFlow(rUri: ResourceId): void;
3257
+ declare function useShellVM(): ShellVM;
4249
3258
 
4250
3259
  /**
4251
3260
  * Subscribe to an RxJS Observable and return its current value as React state.
4252
3261
  *
4253
- * - Initialises to undefined until the first emission
4254
- * - Unsubscribes automatically on unmount or when `obs$` changes
4255
- */
4256
- declare function useObservable<T>(obs$: Observable<T>): T | undefined;
4257
-
4258
- /**
4259
- * useStoreTokenSync keeps observable store token getters in sync with auth
4260
- *
4261
- * Call once near the workspace root (inside both ApiClientProvider and AuthTokenProvider).
4262
- * Ensures stores can make authenticated fetches as the token changes.
4263
- *
4264
- * @example
4265
- * ```tsx
4266
- * function GlobalEventsConnector() {
4267
- * useStoreTokenSync();
4268
- * useGlobalEvents();
4269
- * return null;
4270
- * }
4271
- * ```
4272
- */
4273
- declare function useStoreTokenSync(): void;
4274
-
4275
- export { ANNOTATORS, AVAILABLE_LOCALES, AdminDevOpsPage, type AdminDevOpsPageProps, AdminExchangePage, type AdminExchangePageProps, type AdminExchangePageTranslations, AdminSecurityPage, type AdminSecurityPageProps, type AdminUser, type AdminUserStats, AdminUsersPage, type AdminUsersPageProps, AnnotateReferencesProgressWidget, AnnotateToolbar, AnnotateView, type Annotation$k as Annotation, type AnnotationConfig, type AnnotationCreationHandler, type AnnotationHandlers, AnnotationHistory, type AnnotationManager, AnnotationOverlay, AnnotationProvider, type AnnotationProviderProps, type AnnotationUIState, type AnnotationsCollection, type Annotator, ApiClientProvider, type ApiClientProviderProps, AssessmentEntry, AssessmentPanel, AssistSection, AsyncErrorBoundary, AuthErrorDisplay, type AuthErrorDisplayProps, AuthTokenProvider, type AuthTokenProviderProps, type AvailableLocale, type BeckonFlowState, type BorderRadiusToken, BrowseView, Button, ButtonGroup, type ButtonGroupProps, type ButtonProps, COMMON_PANELS, type CacheManager, CacheProvider, type CacheProviderProps, type ClickAction, CodeMirrorRenderer, CollaborationPanel, CollapsibleResourceNavigation, type CollapsibleResourceNavigationProps, type ColorToken, CommentEntry, CommentsPanel, ComposeLoadingState, type ComposeLoadingStateProps, type ContextGatherFlowConfig, type ContextGatherFlowState, type CreateAnnotationParams, type CreateConfig, type DeleteAnnotationParams, type DetectionConfig, type DevOpsFeature, type DrawingMode, EntityTagsPage, type EntityTagsPageProps, EntityTypeBadges, ErrorBoundary, EventBusProvider, type EventBusProviderProps, ExportCard, type ExportCardProps, type ExportCardTranslations, Footer, HOVER_DELAY_MS, HighlightEntry, HighlightPanel, HistoryEvent, type HoverEmitterProps, type HoverHandlers, ImageURLSchema, ImageViewer, ImportCard, type ImportCardProps, type ImportCardTranslations, type ImportPreview, ImportProgress, type ImportProgressProps, type ImportProgressTranslations, JsonLdPanel, JsonLdView, KbSessionStatus, type KeyboardShortcut, KeyboardShortcutsHelpModal, KnowledgeBase, LeftSidebar, type LinkComponentProps, LinkedDataPage, type LinkedDataPageProps, type LinkedDataPageTranslations, LiveRegionProvider, type MarkFlowState, type Motivation$8 as Motivation, type NavigationItem, NavigationMenu, type NavigationMenuHelper, type NavigationProps, type OAuthProvider, type OAuthUser, OAuthUserSchema, ObservableLink, type ObservableLinkProps, OpenResource, OpenResourcesManager, OpenResourcesProvider, type OverlayAnnotation, PageLayout, type PanelBrowseState, PanelHeader, PermissionDeniedModal, PopupContainer, PopupHeader, ProposeEntitiesModal, ProtectedErrorBoundary, QUERY_KEYS, RESOURCE_PANELS, RecentDocumentsPage, type RecentDocumentsPageProps, ReferenceEntry, ReferenceResolutionWidget, ReferenceWizardModal, type ReferenceWizardModalProps, ReferencesPanel, ResizeHandle, type ResolvedTheme, ResourceAnnotationsProvider, ResourceCard, type ResourceCardProps, ResourceComposePage, type ResourceComposePageProps, ResourceDiscoveryPage, type ResourceDiscoveryPageProps, ResourceErrorState, type ResourceErrorStateProps, ResourceInfoPanel, ResourceLoadingState, ResourceSearchModal, type ResourceSearchModalProps, ResourceTagsInline, ResourceViewer, ResourceViewerPage, type ResourceViewerPageProps, type RouteBuilder, type SaveResourceParams, SearchModal, type SearchModalProps, type SearchPipeline, type SearchPipelineOptions, type SearchState, SelectedTextDisplay, type SelectionMotivation, type SelectorType, SemiontBranding, SemiontFavicon, type SemiontResource$4 as SemiontResource, SessionExpiredModal, SessionExpiryBanner, SessionTimer, SettingsPanel, type ShadowToken, type ShapeType, SignInForm, type SignInFormProps, SignUpForm, type SignUpFormProps, SimpleNavigation, type SimpleNavigationItem, type SimpleNavigationProps, SkipLinks, SortableResourceTab, type SortableResourceTabProps, type SpacingToken, StatisticsPanel, StatusDisplay, type StoredSession, type StreamStatus, SvgDrawingCanvas, TagEntry, TagSchemasPage, type TagSchemasPageProps, TaggingPanel, type TextSegment, type TextSelection, type Theme, ThemeProvider, ToastContainer, type ToastMessage, ToastProvider, type ToastType, Toolbar, type ToolbarPanelType, type TransitionToken, TranslationManager, TranslationProvider, type TranslationProviderProps, type TypographyToken, type UICreateAnnotationParams, UnifiedAnnotationsPanel, UnifiedHeader, type UseResourceContentResult, UserMenuSkeleton, WelcomePage, type WelcomePageProps, type YieldFlowState, applyHighlights, buildSourceToRenderedMap, buildTextNodeIndex, buttonStyles, clearHighlights, createHoverHandlers, createSearchPipeline, cssVariables, defaultProtocol, faviconPaths, formatTime, generateCSSVariables, getKbSessionStatus, getResourceIcon, getSelectedShapeForSelectorType, getSelectorType, getShortcutDisplay, getSupportedShapes, hideWidgetPreview, isShapeSupported, isValidHostname, jsonLightHighlightStyle, jsonLightTheme, kbBackendUrl, notifyPermissionDenied, notifySessionExpired, resolveAnnotationRanges, sanitizeImageURL, saveSelectedShapeForSelectorType, showWidgetPreview, supportsDetection, toOverlayAnnotations, tokens, useAdmin, useAnnotationManager, useAnnotations, useApiClient, useAttentionStream, useAuthApi, useAuthToken, useBeckonFlow, useBindFlow, useCacheManager, useContextGatherFlow, useDebounce, useDebouncedCallback, useDocumentAnnouncements, useDoubleKeyPress, useDropdown, useEntityTypes, useEventBus, useEventSubscription, useEventSubscriptions, useFormAnnouncements, useGlobalEvents, useHealth, useHoverDelay, useHoverEmitter, useIsTyping, useKeyboardShortcuts, useLanguageChangeAnnouncements, useLineNumbers, useLiveRegion, useLoadingState, useLocalStorage, useMarkFlow, useModeration, useObservable, useObservableExternalNavigation, useObservableRouter, useOpenResources, usePanelBrowse, usePanelWidth, usePreloadTranslations, useResourceAnnotations, useResourceContent, useResourceEvents, useResourceLoadingAnnouncements, useResources, useRovingTabIndex, useSearchAnnouncements, useSessionExpiry, useStoreTokenSync, useTheme, useToast, useTranslations, useYieldFlow };
3262
+ * - For a `BehaviorSubject` (or anything with a `getValue()` method), returns
3263
+ * its current value synchronously at the first render. This matters for
3264
+ * callers that build derived objects in a `useState(factory)` initializer
3265
+ * at first render they need the subject's value present immediately, not
3266
+ * after a second render triggered by the useEffect subscribe.
3267
+ *
3268
+ * We duck-type on `.getValue` rather than using `instanceof BehaviorSubject`
3269
+ * because rxjs can be loaded through multiple module realms in tests (e.g.
3270
+ * a bundled CJS copy inside `@semiont/react-ui/dist` vs a fresh ESM import
3271
+ * in the test file), which makes `instanceof` unreliable.
3272
+ * - For non-BehaviorSubject Observables, starts at `undefined` and emits
3273
+ * asynchronously after the subscribe.
3274
+ * - Accepts `undefined`/`null` for cases where the observable's source isn't
3275
+ * ready yet (e.g. `semiont?.browse.events(rUri)` when the active session is
3276
+ * still loading). In that case the hook is a no-op and returns undefined.
3277
+ * - Unsubscribes automatically on unmount or when `obs$` changes.
3278
+ */
3279
+ declare function useObservable<T>(obs$: Observable<T> | null | undefined): T | undefined;
3280
+
3281
+ export { ANNOTATORS, AVAILABLE_LOCALES, AdminDevOpsPage, type AdminDevOpsPageProps, AdminExchangePage, type AdminExchangePageProps, type AdminExchangePageTranslations, AdminSecurityPage, type AdminSecurityPageProps, type AdminUser, type AdminUserStats, AdminUsersPage, type AdminUsersPageProps, AnnotateReferencesProgressWidget, AnnotateToolbar, AnnotateView, type AnnotationConfig, type AnnotationCreationHandler, type AnnotationHandlers, AnnotationHistory, type AnnotationManager, AnnotationOverlay, AnnotationProvider, type AnnotationProviderProps, type AnnotationUIState, type AnnotationsCollection, type Annotator, AssessmentEntry, AssessmentPanel, AssistSection, AsyncErrorBoundary, AuthErrorDisplay, type AuthErrorDisplayProps, type AvailableLocale, type BorderRadiusToken, BrowseView, Button, ButtonGroup, type ButtonGroupProps, type ButtonProps, type ClickAction, CodeMirrorRenderer, CollaborationPanel, CollapsibleResourceNavigation, type CollapsibleResourceNavigationProps, type ColorToken, CommentEntry, CommentsPanel, ComposeLoadingState, type ComposeLoadingStateProps, type CreateAnnotationParams, type CreateConfig, type DeleteAnnotationParams, type DetectionConfig, type DevOpsFeature, type DrawingMode, EntityTagsPage, type EntityTagsPageProps, EntityTypeBadges, ErrorBoundary, ExportCard, type ExportCardProps, type ExportCardTranslations, Footer, HighlightEntry, HighlightPanel, HistoryEvent, type HoverEmitterProps, ImageURLSchema, ImageViewer, ImportCard, type ImportCardProps, type ImportCardTranslations, ImportProgress, type ImportProgressProps, type ImportProgressTranslations, JsonLdPanel, JsonLdView, type KeyboardShortcut, KeyboardShortcutsHelpModal, LeftSidebar, type LinkComponentProps, LinkedDataPage, type LinkedDataPageProps, type LinkedDataPageTranslations, LiveRegionProvider, type Motivation$8 as Motivation, type NavigationItem, NavigationMenu, type NavigationMenuHelper, type NavigationProps, type OAuthProvider, type OAuthUser, OAuthUserSchema, ObservableLink, type ObservableLinkProps, type OverlayAnnotation, PageLayout, PanelHeader, PermissionDeniedModal, PopupContainer, PopupHeader, ProtectedErrorBoundary, RecentDocumentsPage, type RecentDocumentsPageProps, ReferenceEntry, ReferenceResolutionWidget, ReferenceWizardModal, type ReferenceWizardModalProps, ReferencesPanel, ResizeHandle, type ResolvedTheme, ResourceAnnotationsProvider, ResourceCard, type ResourceCardProps, ResourceComposePage, type ResourceComposePageProps, ResourceDiscoveryPage, type ResourceDiscoveryPageProps, ResourceErrorState, type ResourceErrorStateProps, ResourceInfoPanel, ResourceLoadingState, ResourceSearchModal, type ResourceSearchModalProps, ResourceTagsInline, ResourceViewer, ResourceViewerPage, type ResourceViewerPageProps, type RouteBuilder, SearchModal, type SearchModalProps, SelectedTextDisplay, type SelectionMotivation, type SelectorType, SemiontBranding, SemiontFavicon, SemiontProvider, type SemiontProviderProps, type SemiontResource$2 as SemiontResource, SessionExpiredModal, SessionExpiryBanner, SessionTimer, SettingsPanel, type ShadowToken, type ShapeType, SignInForm, type SignInFormProps, SignUpForm, type SignUpFormProps, SimpleNavigation, type SimpleNavigationItem, type SimpleNavigationProps, SkipLinks, SortableResourceTab, type SortableResourceTabProps, type SpacingToken, StatisticsPanel, StatusDisplay, SvgDrawingCanvas, TagEntry, TagSchemasPage, type TagSchemasPageProps, TaggingPanel, type TextSegment, type TextSelection, type Theme, ThemeProvider, ToastContainer, type ToastMessage, ToastProvider, type ToastType, Toolbar, type TransitionToken, TranslationManager, TranslationProvider, type TranslationProviderProps, type TypographyToken, type UICreateAnnotationParams, UnifiedAnnotationsPanel, UnifiedHeader, type UseResourceContentResult, UserMenuSkeleton, WebBrowserStorage, WelcomePage, type WelcomePageProps, applyHighlights, buildSourceToRenderedMap, buildTextNodeIndex, buttonStyles, clearHighlights, cssVariables, faviconPaths, formatTime, generateCSSVariables, getResourceIcon, getSelectedShapeForSelectorType, getSelectorType, getShortcutDisplay, getSupportedShapes, hideWidgetPreview, isShapeSupported, jsonLightHighlightStyle, jsonLightTheme, resolveAnnotationRanges, sanitizeImageURL, saveSelectedShapeForSelectorType, showWidgetPreview, supportsDetection, toOverlayAnnotations, tokens, useAnnotationManager, useDebounce, useDebouncedCallback, useDocumentAnnouncements, useDoubleKeyPress, useDropdown, useEventSubscription, useEventSubscriptions, useFormAnnouncements, useHoverDelay, useHoverEmitter, useIsTyping, useKeyboardShortcuts, useLanguageChangeAnnouncements, useLineNumbers, useLiveRegion, useLoadingState, useLocalStorage, useObservable, useObservableExternalNavigation, useObservableRouter, usePanelWidth, usePreloadTranslations, useResourceAnnotations, useResourceContent, useResourceLoadingAnnouncements, useRovingTabIndex, useSearchAnnouncements, useSemiont, useSessionExpiry, useShellVM, useTheme, useToast, useTranslations, useViewModel };