@semiont/react-ui 0.2.33-build.80 → 0.2.33-build.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{EventBusContext-7GvDyO0d.d.mts → EventBusContext-CJjL_cCf.d.mts} +67 -19
- package/dist/{chunk-ZR4ZV2LY.mjs → chunk-QB52Q7EQ.mjs} +7 -7
- package/dist/chunk-QB52Q7EQ.mjs.map +1 -0
- package/dist/index.d.mts +194 -208
- package/dist/index.mjs +1542 -1637
- package/dist/index.mjs.map +1 -1
- package/dist/test-utils.d.mts +2 -2
- package/dist/test-utils.mjs +1 -1
- package/package.json +1 -1
- package/src/components/LiveRegion.tsx +18 -18
- package/src/components/SessionExpiryBanner.tsx +2 -3
- package/src/components/SessionTimer.tsx +2 -2
- package/src/components/__tests__/SessionTimer.test.tsx +27 -27
- package/src/components/resource/panels/AssessmentPanel.tsx +2 -2
- package/src/components/resource/panels/DetectSection.tsx +13 -7
- package/src/components/resource/panels/ReferenceEntry.tsx +1 -1
- package/src/components/resource/panels/TaggingPanel.tsx +2 -3
- package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +1 -1
- package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +16 -13
- package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +1 -1
- package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +13 -13
- package/src/features/resource-viewer/__tests__/DetectionProgressDismissal.test.tsx +5 -5
- package/src/features/resource-viewer/__tests__/GenerationFlowIntegration.test.tsx +7 -12
- package/src/features/resource-viewer/__tests__/ResolutionFlowIntegration.test.tsx +266 -0
- package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +11 -12
- package/src/features/resource-viewer/__tests__/detection-progress-flow.test.tsx +3 -3
- package/src/features/resource-viewer/components/ResourceViewerPage.tsx +132 -93
- package/dist/chunk-ZR4ZV2LY.mjs.map +0 -1
|
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import mitt from 'mitt';
|
|
4
4
|
import { ResourceEvent } from '@semiont/core';
|
|
5
|
-
import { Selector, components, ResourceUri } from '@semiont/api-client';
|
|
5
|
+
import { GenerationProgress as GenerationProgress$1, Selector, components, ResourceUri, GenerationContext } from '@semiont/api-client';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Open Resources Manager Interface
|
|
@@ -107,6 +107,45 @@ interface TranslationManager {
|
|
|
107
107
|
t: (namespace: string, key: string, params?: Record<string, any>) => string;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Progress type definitions for detection and generation flows
|
|
112
|
+
*/
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Common detection progress fields shared across all motivation types.
|
|
116
|
+
*
|
|
117
|
+
* The five motivations have different SSE progress shapes
|
|
118
|
+
* (ReferenceDetectionProgress uses entity-type steps; the others use percentage).
|
|
119
|
+
* This local type captures the subset of fields used by the detection UI
|
|
120
|
+
* (DetectionProgressWidget, useDetectionFlow).
|
|
121
|
+
*/
|
|
122
|
+
interface DetectionProgress {
|
|
123
|
+
status: string;
|
|
124
|
+
message?: string;
|
|
125
|
+
/** Reference detection: currently scanning entity type */
|
|
126
|
+
currentEntityType?: string;
|
|
127
|
+
/** Reference detection: completed entity types with counts (frontend-only) */
|
|
128
|
+
completedEntityTypes?: Array<{
|
|
129
|
+
entityType: string;
|
|
130
|
+
foundCount: number;
|
|
131
|
+
}>;
|
|
132
|
+
/** Percentage-based motivations (highlight, assessment, comment, tag) */
|
|
133
|
+
percentage?: number;
|
|
134
|
+
/** Category-based motivations (tag) */
|
|
135
|
+
currentCategory?: string;
|
|
136
|
+
processedCategories?: number;
|
|
137
|
+
totalCategories?: number;
|
|
138
|
+
/** Request parameters for display in progress UI (frontend-only, added by annotation-registry) */
|
|
139
|
+
requestParams?: Array<{
|
|
140
|
+
label: string;
|
|
141
|
+
value: string;
|
|
142
|
+
}>;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Generation progress type (no extensions needed, re-export API type)
|
|
146
|
+
*/
|
|
147
|
+
type GenerationProgress = GenerationProgress$1;
|
|
148
|
+
|
|
110
149
|
type Annotation = components['schemas']['Annotation'];
|
|
111
150
|
type Motivation = components['schemas']['Motivation'];
|
|
112
151
|
interface SelectionData {
|
|
@@ -132,9 +171,6 @@ type EventMap = {
|
|
|
132
171
|
'detection:started': Extract<ResourceEvent, {
|
|
133
172
|
type: 'job.started';
|
|
134
173
|
}>;
|
|
135
|
-
'detection:progress': Extract<ResourceEvent, {
|
|
136
|
-
type: 'job.progress';
|
|
137
|
-
}>;
|
|
138
174
|
'detection:entity-found': Extract<ResourceEvent, {
|
|
139
175
|
type: 'annotation.added';
|
|
140
176
|
}>;
|
|
@@ -144,6 +180,7 @@ type EventMap = {
|
|
|
144
180
|
'detection:failed': Extract<ResourceEvent, {
|
|
145
181
|
type: 'job.failed';
|
|
146
182
|
}>;
|
|
183
|
+
'detection:progress': DetectionProgress;
|
|
147
184
|
'annotation:added': Extract<ResourceEvent, {
|
|
148
185
|
type: 'annotation.added';
|
|
149
186
|
}>;
|
|
@@ -174,9 +211,6 @@ type EventMap = {
|
|
|
174
211
|
motivation: Motivation;
|
|
175
212
|
};
|
|
176
213
|
'annotation:cancel-pending': void;
|
|
177
|
-
'annotation:dom-hover': {
|
|
178
|
-
annotationId: string | null;
|
|
179
|
-
};
|
|
180
214
|
'annotation:hover': {
|
|
181
215
|
annotationId: string | null;
|
|
182
216
|
};
|
|
@@ -228,6 +262,7 @@ type EventMap = {
|
|
|
228
262
|
'navigation:external-navigate': {
|
|
229
263
|
url: string;
|
|
230
264
|
resourceId?: string;
|
|
265
|
+
cancelFallback: () => void;
|
|
231
266
|
};
|
|
232
267
|
'navigation:reference-navigate': {
|
|
233
268
|
documentId: string;
|
|
@@ -251,7 +286,7 @@ type EventMap = {
|
|
|
251
286
|
'annotation:create': {
|
|
252
287
|
motivation: Motivation;
|
|
253
288
|
selector: Selector | Selector[];
|
|
254
|
-
body:
|
|
289
|
+
body: components['schemas']['AnnotationBody'][];
|
|
255
290
|
};
|
|
256
291
|
'annotation:created': {
|
|
257
292
|
annotation: Annotation;
|
|
@@ -273,9 +308,9 @@ type EventMap = {
|
|
|
273
308
|
resourceId: string;
|
|
274
309
|
operations: Array<{
|
|
275
310
|
op: 'add' | 'remove' | 'replace';
|
|
276
|
-
item?:
|
|
277
|
-
oldItem?:
|
|
278
|
-
newItem?:
|
|
311
|
+
item?: components['schemas']['AnnotationBody'];
|
|
312
|
+
oldItem?: components['schemas']['AnnotationBody'];
|
|
313
|
+
newItem?: components['schemas']['AnnotationBody'];
|
|
279
314
|
}>;
|
|
280
315
|
};
|
|
281
316
|
'annotation:body-updated': {
|
|
@@ -288,7 +323,8 @@ type EventMap = {
|
|
|
288
323
|
motivation: Motivation;
|
|
289
324
|
options: {
|
|
290
325
|
instructions?: string;
|
|
291
|
-
|
|
326
|
+
/** Comment tone */
|
|
327
|
+
tone?: 'scholarly' | 'explanatory' | 'conversational' | 'technical' | 'analytical' | 'critical' | 'balanced' | 'constructive';
|
|
292
328
|
density?: number;
|
|
293
329
|
entityTypes?: string[];
|
|
294
330
|
includeDescriptiveReferences?: boolean;
|
|
@@ -299,7 +335,7 @@ type EventMap = {
|
|
|
299
335
|
'detection:complete': {
|
|
300
336
|
motivation?: Motivation;
|
|
301
337
|
resourceUri?: ResourceUri;
|
|
302
|
-
progress?:
|
|
338
|
+
progress?: DetectionProgress;
|
|
303
339
|
};
|
|
304
340
|
'detection:cancelled': void;
|
|
305
341
|
'detection:dismiss-progress': void;
|
|
@@ -312,13 +348,13 @@ type EventMap = {
|
|
|
312
348
|
language?: string;
|
|
313
349
|
temperature?: number;
|
|
314
350
|
maxTokens?: number;
|
|
315
|
-
context:
|
|
351
|
+
context: GenerationContext;
|
|
316
352
|
};
|
|
317
353
|
};
|
|
318
|
-
'generation:progress':
|
|
354
|
+
'generation:progress': GenerationProgress;
|
|
319
355
|
'generation:complete': {
|
|
320
356
|
annotationUri: string;
|
|
321
|
-
progress:
|
|
357
|
+
progress: GenerationProgress;
|
|
322
358
|
};
|
|
323
359
|
'generation:failed': {
|
|
324
360
|
error: Error;
|
|
@@ -337,10 +373,22 @@ type EventMap = {
|
|
|
337
373
|
annotationUri: string;
|
|
338
374
|
searchTerm: string;
|
|
339
375
|
};
|
|
340
|
-
'
|
|
376
|
+
'resolution:search-requested': {
|
|
341
377
|
referenceId: string;
|
|
342
378
|
searchTerm: string;
|
|
343
379
|
};
|
|
380
|
+
'context:retrieval-requested': {
|
|
381
|
+
annotationUri: string;
|
|
382
|
+
resourceUri: string;
|
|
383
|
+
};
|
|
384
|
+
'context:retrieval-complete': {
|
|
385
|
+
annotationUri: string;
|
|
386
|
+
context: GenerationContext;
|
|
387
|
+
};
|
|
388
|
+
'context:retrieval-failed': {
|
|
389
|
+
annotationUri: string;
|
|
390
|
+
error: Error;
|
|
391
|
+
};
|
|
344
392
|
};
|
|
345
393
|
type EventBus = ReturnType<typeof mitt<EventMap>> & {
|
|
346
394
|
busId: string;
|
|
@@ -381,7 +429,7 @@ interface EventBusProviderProps {
|
|
|
381
429
|
* same global bus.
|
|
382
430
|
*
|
|
383
431
|
* Operation handlers (API calls triggered by events) are set up separately via
|
|
384
|
-
* the
|
|
432
|
+
* the useResolutionFlow hook, which should be called at the resource page level.
|
|
385
433
|
*/
|
|
386
434
|
declare function EventBusProvider({ children, }: EventBusProviderProps): react_jsx_runtime.JSX.Element;
|
|
387
435
|
/**
|
|
@@ -411,4 +459,4 @@ declare function EventBusProvider({ children, }: EventBusProviderProps): react_j
|
|
|
411
459
|
*/
|
|
412
460
|
declare function useEventBus(): EventBus;
|
|
413
461
|
|
|
414
|
-
export { type EventBus as E, type OpenResourcesManager as O, type SessionManager as S, type TranslationManager as T, type EventMap as a, type OpenResource as b, type SessionState as c, type EventBusProviderProps as d, EventBusProvider as e, resetEventBusForTesting as r, useEventBus as u };
|
|
462
|
+
export { type DetectionProgress as D, type EventBus as E, type GenerationProgress as G, type OpenResourcesManager as O, type SessionManager as S, type TranslationManager as T, type EventMap as a, type OpenResource as b, type SessionState as c, type EventBusProviderProps as d, EventBusProvider as e, resetEventBusForTesting as r, useEventBus as u };
|
|
@@ -47,20 +47,20 @@ function createEventBus() {
|
|
|
47
47
|
const busId = generateBusId();
|
|
48
48
|
bus.busId = busId;
|
|
49
49
|
const originalEmit = bus.emit.bind(bus);
|
|
50
|
-
bus.emit = (
|
|
50
|
+
bus.emit = (eventName, payload) => {
|
|
51
51
|
console.info(`[EventBus:${busId}] emit:`, eventName, payload);
|
|
52
52
|
return originalEmit(eventName, payload);
|
|
53
|
-
}
|
|
53
|
+
};
|
|
54
54
|
const originalOn = bus.on.bind(bus);
|
|
55
|
-
bus.on = (
|
|
55
|
+
bus.on = (eventName, handler) => {
|
|
56
56
|
console.debug(`[EventBus:${busId}] subscribe:`, eventName);
|
|
57
57
|
return originalOn(eventName, handler);
|
|
58
|
-
}
|
|
58
|
+
};
|
|
59
59
|
const originalOff = bus.off.bind(bus);
|
|
60
|
-
bus.off = (
|
|
60
|
+
bus.off = (eventName, handler) => {
|
|
61
61
|
console.debug(`[EventBus:${busId}] unsubscribe:`, eventName);
|
|
62
62
|
return originalOff(eventName, handler);
|
|
63
|
-
}
|
|
63
|
+
};
|
|
64
64
|
return bus;
|
|
65
65
|
}
|
|
66
66
|
var globalEventBus = createEventBus();
|
|
@@ -490,4 +490,4 @@ export {
|
|
|
490
490
|
useTranslations,
|
|
491
491
|
usePreloadTranslations
|
|
492
492
|
};
|
|
493
|
-
//# sourceMappingURL=chunk-
|
|
493
|
+
//# sourceMappingURL=chunk-QB52Q7EQ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/contexts/ApiClientContext.tsx","../src/contexts/EventBusContext.tsx","../src/contexts/SessionContext.tsx","../src/components/Toast.tsx","../src/contexts/OpenResourcesContext.tsx","../src/contexts/TranslationContext.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useContext, ReactNode, useMemo } from 'react';\nimport { SemiontApiClient, baseUrl } from '@semiont/api-client';\n\nconst ApiClientContext = createContext<SemiontApiClient | undefined>(undefined);\n\nexport interface ApiClientProviderProps {\n baseUrl: string;\n children: ReactNode;\n}\n\n/**\n * Provider for API client - creates a stateless singleton client\n * The client instance never changes (no token dependency)\n * Auth tokens are passed per-request via useAuthToken() in calling code\n */\nexport function ApiClientProvider({\n baseUrl: url,\n children,\n}: ApiClientProviderProps) {\n // Client created once and never recreated (no token dependency)\n const client = useMemo(\n () => new SemiontApiClient({\n baseUrl: baseUrl(url),\n // Use no timeout in test environment to avoid AbortController issues with ky + vitest\n ...(process.env.NODE_ENV !== 'test' && { timeout: 30000 }),\n }),\n [url] // Only baseUrl in deps, token removed\n );\n\n return (\n <ApiClientContext.Provider value={client}>\n {children}\n </ApiClientContext.Provider>\n );\n}\n\n/**\n * Hook to access the stateless API client singleton\n * Must be used within an ApiClientProvider\n * @returns Stateless SemiontApiClient instance\n */\nexport function useApiClient(): SemiontApiClient {\n const context = useContext(ApiClientContext);\n\n if (context === undefined) {\n throw new Error('useApiClient must be used within an ApiClientProvider');\n }\n\n return context;\n}\n","'use client';\n\nimport { createContext, useContext, useMemo, type ReactNode } from 'react';\nimport mitt from 'mitt';\nimport type { Handler } from 'mitt';\nimport type { ResourceEvent } from '@semiont/core';\nimport type { components, Selector, ResourceUri, GenerationContext } from '@semiont/api-client';\nimport type { DetectionProgress, GenerationProgress } from '../types/progress';\n\ntype Annotation = components['schemas']['Annotation'];\ntype Motivation = components['schemas']['Motivation'];\n\ninterface SelectionData {\n exact: string;\n start: number;\n end: number;\n svgSelector?: string;\n fragmentSelector?: string;\n conformsTo?: string;\n prefix?: string;\n suffix?: string;\n}\n\n/**\n * Unified event map for all application events\n *\n * Consolidates events from:\n * - MakeMeaningEventBus (document/annotation operations)\n * - NavigationEventBus (navigation and sidebar UI)\n * - GlobalSettingsEventBus (app-wide settings)\n */\nexport type EventMap = {\n // ===== BACKEND EVENTS (from SSE) =====\n\n // Generic event (all types)\n 'make-meaning:event': ResourceEvent;\n\n // Detection events (backend real-time stream via GET /resources/:id/events/stream)\n 'detection:started': Extract<ResourceEvent, { type: 'job.started' }>;\n 'detection:entity-found': Extract<ResourceEvent, { type: 'annotation.added' }>;\n 'detection:completed': Extract<ResourceEvent, { type: 'job.completed' }>;\n 'detection:failed': Extract<ResourceEvent, { type: 'job.failed' }>;\n // Detection progress from SSE detection streams (all 5 motivation types)\n 'detection:progress': DetectionProgress;\n\n // Annotation events (backend)\n 'annotation:added': Extract<ResourceEvent, { type: 'annotation.added' }>;\n 'annotation:removed': Extract<ResourceEvent, { type: 'annotation.removed' }>;\n 'annotation:updated': Extract<ResourceEvent, { type: 'annotation.body.updated' }>;\n\n // Entity tag events (backend)\n 'entity-tag:added': Extract<ResourceEvent, { type: 'entitytag.added' }>;\n 'entity-tag:removed': Extract<ResourceEvent, { type: 'entitytag.removed' }>;\n\n // Resource events (backend)\n 'resource:archived': Extract<ResourceEvent, { type: 'resource.archived' }>;\n 'resource:unarchived': Extract<ResourceEvent, { type: 'resource.unarchived' }>;\n\n // ===== USER INTERACTION EVENTS =====\n\n // Selection events (user highlighting text/regions)\n 'selection:comment-requested': SelectionData;\n 'selection:tag-requested': SelectionData;\n 'selection:assessment-requested': SelectionData;\n 'selection:reference-requested': SelectionData;\n\n // Unified annotation request event (all motivations)\n 'annotation:requested': {\n selector: Selector | Selector[];\n motivation: Motivation;\n };\n\n // Annotation interaction events\n 'annotation:cancel-pending': void;\n 'annotation:hover': { annotationId: string | null }; // Bidirectional hover: annotation overlay ↔ panel entry\n 'annotation:click': { annotationId: string; motivation: Motivation }; // Click on annotation - includes motivation for panel coordination\n 'annotation:focus': { annotationId: string | null };\n 'annotation:sparkle': { annotationId: string };\n\n // Panel management events\n 'panel:toggle': { panel: string };\n 'panel:open': { panel: string; scrollToAnnotationId?: string; motivation?: string };\n 'panel:close': void;\n\n // View mode events\n 'view:mode-toggled': void;\n\n // Toolbar events (annotation UI controls)\n 'toolbar:selection-changed': { motivation: string | null };\n 'toolbar:click-changed': { action: string };\n 'toolbar:shape-changed': { shape: string };\n\n // Navigation events (sidebar UI)\n 'navigation:sidebar-toggle': void;\n 'navigation:resource-close': { resourceId: string };\n 'navigation:resource-reorder': { oldIndex: number; newIndex: number };\n 'navigation:link-clicked': { href: string; label?: string };\n 'navigation:router-push': { path: string; reason?: string };\n 'navigation:external-navigate': { url: string; resourceId?: string; cancelFallback: () => void };\n 'navigation:reference-navigate': { documentId: string };\n 'navigation:entity-type-clicked': { entityType: string };\n\n // Settings events (app-wide)\n 'settings:theme-changed': { theme: 'light' | 'dark' | 'system' };\n 'settings:line-numbers-toggled': void;\n 'settings:locale-changed': { locale: string };\n\n // ===== API OPERATION EVENTS =====\n\n // Resource operations\n 'resource:archive': void;\n 'resource:unarchive': void;\n 'resource:clone': void;\n\n // Job control\n 'job:cancel-requested': { jobType: 'detection' | 'generation' };\n\n // Annotation CRUD operations\n 'annotation:create': {\n motivation: Motivation;\n selector: Selector | Selector[];\n body: components['schemas']['AnnotationBody'][];\n };\n 'annotation:created': { annotation: Annotation };\n 'annotation:create-failed': { error: Error };\n 'annotation:delete': { annotationId: string };\n 'annotation:deleted': { annotationId: string };\n 'annotation:delete-failed': { error: Error };\n 'annotation:update-body': {\n annotationUri: string;\n resourceId: string;\n operations: Array<{\n op: 'add' | 'remove' | 'replace';\n item?: components['schemas']['AnnotationBody'];\n oldItem?: components['schemas']['AnnotationBody'];\n newItem?: components['schemas']['AnnotationBody'];\n }>;\n };\n 'annotation:body-updated': { annotationUri: string };\n 'annotation:body-update-failed': { error: Error };\n\n // Detection operations\n 'detection:start': {\n motivation: Motivation;\n options: {\n instructions?: string;\n /** Comment tone */\n tone?: 'scholarly' | 'explanatory' | 'conversational' | 'technical' | 'analytical' | 'critical' | 'balanced' | 'constructive';\n density?: number;\n entityTypes?: string[];\n includeDescriptiveReferences?: boolean;\n schemaId?: string;\n categories?: string[];\n };\n };\n 'detection:complete': { motivation?: Motivation; resourceUri?: ResourceUri; progress?: DetectionProgress };\n 'detection:cancelled': void;\n 'detection:dismiss-progress': void;\n\n // Resource generation operations (unified event-driven flow)\n 'generation:start': {\n annotationUri: string;\n resourceUri: string;\n options: {\n title: string;\n prompt?: string;\n language?: string;\n temperature?: number;\n maxTokens?: number;\n context: GenerationContext;\n };\n };\n 'generation:progress': GenerationProgress;\n 'generation:complete': { annotationUri: string; progress: GenerationProgress };\n 'generation:failed': { error: Error };\n 'generation:modal-open': {\n annotationUri: string;\n resourceUri: string;\n defaultTitle: string;\n };\n 'reference:create-manual': {\n annotationUri: string;\n title: string;\n entityTypes: string[];\n };\n 'reference:link': {\n annotationUri: string;\n searchTerm: string;\n };\n 'resolution:search-requested': {\n referenceId: string;\n searchTerm: string;\n };\n 'context:retrieval-requested': {\n annotationUri: string;\n resourceUri: string;\n };\n 'context:retrieval-complete': {\n annotationUri: string;\n context: GenerationContext;\n };\n 'context:retrieval-failed': {\n annotationUri: string;\n error: Error;\n };\n};\n\nexport type EventBus = ReturnType<typeof mitt<EventMap>> & { busId: string };\n\nconst EventBusContext = createContext<EventBus | null>(null);\n\n/**\n * Generate an 8-digit hex identifier for an event bus instance\n */\nfunction generateBusId(): string {\n return Math.floor(Math.random() * 0xFFFFFFFF).toString(16).padStart(8, '0');\n}\n\n/**\n * Create an EventBus instance with logging and unique identifier\n */\nfunction createEventBus(): EventBus {\n const bus = mitt<EventMap>() as EventBus;\n const busId = generateBusId();\n\n // Add busId property\n bus.busId = busId;\n\n // Wrap emit to add logging with busId\n const originalEmit = bus.emit.bind(bus);\n bus.emit = <Key extends keyof EventMap>(eventName: Key, payload?: EventMap[Key]) => {\n console.info(`[EventBus:${busId}] emit:`, eventName, payload);\n return originalEmit(eventName, payload as EventMap[Key]);\n };\n\n // Wrap on to add logging with busId\n const originalOn = bus.on.bind(bus);\n bus.on = <Key extends keyof EventMap>(eventName: Key, handler: Handler<EventMap[Key]>) => {\n console.debug(`[EventBus:${busId}] subscribe:`, eventName);\n return originalOn(eventName, handler);\n };\n\n // Wrap off to add logging with busId\n const originalOff = bus.off.bind(bus);\n bus.off = <Key extends keyof EventMap>(eventName: Key, handler?: Handler<EventMap[Key]>) => {\n console.debug(`[EventBus:${busId}] unsubscribe:`, eventName);\n return originalOff(eventName, handler);\n };\n\n return bus;\n}\n\n/**\n * Global singleton event bus.\n *\n * This ensures all components in the application share the same event bus instance,\n * which is critical for cross-component communication (e.g., hovering an annotation\n * in one component scrolls the panel in another component).\n *\n * FUTURE: Multi-Window Support\n * When we need to support multiple document windows (e.g., pop-out resource viewers),\n * we'll need to transition to a per-window event bus architecture:\n *\n * Option 1: Window-scoped event bus\n * - Create a new event bus for each window/portal\n * - Pass windowId or documentId to EventBusProvider\n * - Store Map<windowId, EventBus> instead of single global\n * - Components use useEventBus(windowId) to get correct bus\n *\n * Option 2: Event bus hierarchy\n * - Global event bus for app-wide events (settings, navigation)\n * - Per-document event bus for document-specific events (annotation hover)\n * - Components subscribe to both buses as needed\n *\n * Option 3: Cross-window event bridge\n * - Keep per-window buses isolated\n * - Use BroadcastChannel or postMessage for cross-window events\n * - Bridge pattern to sync certain events across windows\n *\n * For now, single global bus is correct for single-window app.\n */\nlet globalEventBus = createEventBus();\n\n/**\n * Reset the global event bus - FOR TESTING ONLY.\n *\n * Call this in test setup (beforeEach) to ensure test isolation.\n * Each test gets a fresh event bus with no lingering subscriptions.\n *\n * @example\n * ```typescript\n * beforeEach(() => {\n * resetEventBusForTesting();\n * });\n * ```\n */\nexport function resetEventBusForTesting() {\n globalEventBus = createEventBus();\n}\n\nexport interface EventBusProviderProps {\n children: ReactNode;\n // rUri and client removed - operation handlers are now set up via useResolutionFlow hook\n}\n\n/**\n * Unified event bus provider for all application events\n *\n * Consolidates three previous event buses:\n * - MakeMeaningEventBus (document/annotation operations)\n * - NavigationEventBus (navigation and sidebar UI)\n * - GlobalSettingsEventBus (app-wide settings)\n *\n * Benefits:\n * - Single import: useEventBus()\n * - No decision fatigue about which bus to use\n * - Easier cross-domain coordination\n * - Simpler provider hierarchy\n *\n * NOTE: This provider uses a global singleton event bus to ensure all components\n * share the same instance. Multiple providers in the tree will all reference the\n * same global bus.\n *\n * Operation handlers (API calls triggered by events) are set up separately via\n * the useResolutionFlow hook, which should be called at the resource page level.\n */\nexport function EventBusProvider({\n children,\n}: EventBusProviderProps) {\n const eventBus = useMemo(() => globalEventBus, []);\n\n return (\n <EventBusContext.Provider value={eventBus}>\n {children}\n </EventBusContext.Provider>\n );\n}\n\n/**\n * Hook to access the unified event bus\n *\n * Use this everywhere instead of:\n * - useMakeMeaningEvents()\n * - useNavigationEvents()\n * - useGlobalSettingsEvents()\n *\n * @example\n * ```typescript\n * const eventBus = useEventBus();\n *\n * // Emit any event\n * eventBus.emit('annotation:hover', { annotationId: '123' });\n * eventBus.emit('navigation:sidebar-toggle', undefined);\n * eventBus.emit('settings:theme-changed', { theme: 'dark' });\n *\n * // Subscribe to any event\n * useEffect(() => {\n * const handler = ({ annotationId }) => console.log(annotationId);\n * eventBus.on('annotation:hover', handler);\n * return () => eventBus.off('annotation:hover', handler);\n * }, []);\n * ```\n */\nexport function useEventBus(): EventBus {\n const bus = useContext(EventBusContext);\n if (!bus) {\n throw new Error('useEventBus must be used within EventBusProvider');\n }\n return bus;\n}\n","'use client';\n\nimport { createContext, useContext, ReactNode } from 'react';\nimport type { SessionManager } from '../types/SessionManager';\n\nconst SessionContext = createContext<SessionManager | null>(null);\n\n/**\n * Provider Pattern: Accepts SessionManager implementation as prop\n * and makes it available to child components via Context.\n *\n * Apps provide their own implementation (next-auth, custom auth, etc.)\n * and pass it to this provider at the root level.\n *\n * @example\n * ```tsx\n * // In app root\n * const sessionManager = useSessionManager(); // App's implementation\n *\n * <SessionProvider sessionManager={sessionManager}>\n * <App />\n * </SessionProvider>\n * ```\n */\nexport function SessionProvider({\n sessionManager,\n children\n}: {\n sessionManager: SessionManager;\n children: ReactNode;\n}) {\n return (\n <SessionContext.Provider value={sessionManager}>\n {children}\n </SessionContext.Provider>\n );\n}\n\n/**\n * Hook to access SessionManager from Context\n * Components use this hook to access session state and expiry information\n */\nexport function useSessionContext() {\n const context = useContext(SessionContext);\n if (!context) {\n throw new Error('useSessionContext must be used within SessionProvider');\n }\n return context;\n}","'use client';\n\nimport React, { useEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport './Toast.css';\n\nexport type ToastType = 'success' | 'error' | 'info' | 'warning';\n\nexport interface ToastMessage {\n id: string;\n message: string;\n type: ToastType;\n duration?: number;\n}\n\ninterface ToastProps {\n toast: ToastMessage;\n onClose: (id: string) => void;\n}\n\nconst icons = {\n success: (\n <svg className=\"semiont-toast-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n ),\n error: (\n <svg className=\"semiont-toast-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n ),\n warning: (\n <svg className=\"semiont-toast-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\" />\n </svg>\n ),\n info: (\n <svg className=\"semiont-toast-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n ),\n};\n\nfunction Toast({ toast, onClose }: ToastProps) {\n useEffect(() => {\n const timer = setTimeout(() => {\n onClose(toast.id);\n }, toast.duration || 3000);\n\n return () => clearTimeout(timer);\n }, [toast, onClose]);\n\n return (\n <div\n className=\"semiont-toast\"\n data-variant={toast.type}\n role=\"alert\"\n >\n <div className=\"semiont-toast-icon-wrapper\">{icons[toast.type]}</div>\n <p className=\"semiont-toast-message\">{toast.message}</p>\n <button\n onClick={() => onClose(toast.id)}\n className=\"semiont-toast-close\"\n aria-label=\"Close\"\n >\n <svg className=\"semiont-toast-close-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n );\n}\n\ninterface ToastContainerProps {\n toasts: ToastMessage[];\n onClose: (id: string) => void;\n}\n\nexport function ToastContainer({ toasts, onClose }: ToastContainerProps) {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n setMounted(true);\n return () => setMounted(false);\n }, []);\n\n if (!mounted) return null;\n\n return createPortal(\n <div className=\"semiont-toast-container\">\n {toasts.map((toast) => (\n <Toast key={toast.id} toast={toast} onClose={onClose} />\n ))}\n </div>,\n document.body\n );\n}\n\n// Toast context and hook for global toast management\ninterface ToastContextType {\n showToast: (message: string, type?: ToastType, duration?: number) => void;\n showSuccess: (message: string, duration?: number) => void;\n showError: (message: string, duration?: number) => void;\n showWarning: (message: string, duration?: number) => void;\n showInfo: (message: string, duration?: number) => void;\n}\n\nconst ToastContext = React.createContext<ToastContextType | undefined>(undefined);\n\nexport function ToastProvider({ children }: { children: React.ReactNode }) {\n const [toasts, setToasts] = useState<ToastMessage[]>([]);\n\n const showToast = React.useCallback((message: string, type: ToastType = 'info', duration?: number) => {\n const id = Date.now().toString();\n const newToast: ToastMessage = duration !== undefined\n ? { id, message, type, duration }\n : { id, message, type };\n setToasts((prev) => [...prev, newToast]);\n }, []);\n\n const showSuccess = React.useCallback((message: string, duration?: number) => showToast(message, 'success', duration), [showToast]);\n const showError = React.useCallback((message: string, duration?: number) => showToast(message, 'error', duration), [showToast]);\n const showWarning = React.useCallback((message: string, duration?: number) => showToast(message, 'warning', duration), [showToast]);\n const showInfo = React.useCallback((message: string, duration?: number) => showToast(message, 'info', duration), [showToast]);\n\n const handleClose = React.useCallback((id: string) => {\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, []);\n\n const contextValue = React.useMemo(\n () => ({ showToast, showSuccess, showError, showWarning, showInfo }),\n [showToast, showSuccess, showError, showWarning, showInfo]\n );\n\n return (\n <ToastContext.Provider value={contextValue}>\n {children}\n <ToastContainer toasts={toasts} onClose={handleClose} />\n </ToastContext.Provider>\n );\n}\n\nexport function useToast() {\n const context = React.useContext(ToastContext);\n if (context === undefined) {\n throw new Error('useToast must be used within a ToastProvider');\n }\n return context;\n}","'use client';\n\nimport React, { createContext, useContext } from 'react';\nimport type { OpenResourcesManager } from '../types/OpenResourcesManager';\n\nconst OpenResourcesContext = createContext<OpenResourcesManager | undefined>(undefined);\n\n/**\n * Provider Pattern: Accepts OpenResourcesManager implementation as prop\n * and makes it available to child components via Context.\n *\n * Apps provide their own implementation (localStorage, sessionStorage, database, etc.)\n * and pass it to this provider at the root level.\n *\n * @example\n * ```tsx\n * // In app root\n * const openResourcesManager = useOpenResourcesManager(); // App's implementation\n *\n * <OpenResourcesProvider openResourcesManager={openResourcesManager}>\n * <App />\n * </OpenResourcesProvider>\n * ```\n */\nexport function OpenResourcesProvider({\n openResourcesManager,\n children\n}: {\n openResourcesManager: OpenResourcesManager;\n children: React.ReactNode;\n}) {\n return (\n <OpenResourcesContext.Provider value={openResourcesManager}>\n {children}\n </OpenResourcesContext.Provider>\n );\n}\n\n/**\n * Hook to access OpenResourcesManager from Context\n * Components use this hook to access open resources functionality\n */\nexport function useOpenResources(): OpenResourcesManager {\n const context = useContext(OpenResourcesContext);\n if (context === undefined) {\n throw new Error('useOpenResources must be used within an OpenResourcesProvider');\n }\n return context;\n}","'use client';\n\nimport { createContext, useContext, ReactNode, useState, useEffect, useMemo } from 'react';\nimport type { TranslationManager } from '../types/TranslationManager';\n\n// Static import for default English only - always needed as fallback\nimport enTranslations from '../../translations/en.json';\n\nconst TranslationContext = createContext<TranslationManager | null>(null);\n\n// Cache for dynamically loaded translations\nconst translationCache = new Map<string, any>();\n\n/**\n * Process ICU MessageFormat plural syntax\n * Supports: {count, plural, =0 {text} =1 {text} other {text}}\n */\nfunction processPluralFormat(text: string, params: Record<string, any>): string {\n // Match {paramName, plural, ...} with proper brace counting\n const pluralMatch = text.match(/\\{(\\w+),\\s*plural,\\s*/);\n if (!pluralMatch) {\n return text;\n }\n\n const paramName = pluralMatch[1];\n const count = params[paramName];\n if (count === undefined) {\n return text;\n }\n\n // Find the matching closing brace by counting\n let startPos = pluralMatch[0].length;\n let braceCount = 1; // We're inside the first {\n let endPos = startPos;\n\n for (let i = startPos; i < text.length; i++) {\n if (text[i] === '{') braceCount++;\n else if (text[i] === '}') {\n braceCount--;\n if (braceCount === 0) {\n endPos = i;\n break;\n }\n }\n }\n\n const pluralCases = text.substring(startPos, endPos);\n\n // Parse plural cases: =0 {text} =1 {text} other {text}\n const cases: Record<string, string> = {};\n const caseRegex = /(?:=(\\d+)|(\\w+))\\s*\\{([^}]+)\\}/g;\n let caseMatch;\n\n while ((caseMatch = caseRegex.exec(pluralCases)) !== null) {\n const [, exactNumber, keyword, textContent] = caseMatch;\n const key = exactNumber !== undefined ? `=${exactNumber}` : keyword;\n cases[key] = textContent;\n }\n\n // Select appropriate case\n const exactMatch = cases[`=${count}`];\n if (exactMatch !== undefined) {\n const result = exactMatch.replace(/#/g, String(count));\n return text.substring(0, pluralMatch.index!) + result + text.substring(endPos + 1);\n }\n\n const otherCase = cases['other'];\n if (otherCase !== undefined) {\n const result = otherCase.replace(/#/g, String(count));\n return text.substring(0, pluralMatch.index!) + result + text.substring(endPos + 1);\n }\n\n return text;\n}\n\n// List of available locales (can be extended without importing all files)\nexport const AVAILABLE_LOCALES = [\n 'ar', // Arabic\n 'bn', // Bengali\n 'cs', // Czech\n 'da', // Danish\n 'de', // German\n 'el', // Greek\n 'en', // English\n 'es', // Spanish\n 'fa', // Persian/Farsi\n 'fi', // Finnish\n 'fr', // French\n 'he', // Hebrew\n 'hi', // Hindi\n 'id', // Indonesian\n 'it', // Italian\n 'ja', // Japanese\n 'ko', // Korean\n 'ms', // Malay\n 'nl', // Dutch\n 'no', // Norwegian\n 'pl', // Polish\n 'pt', // Portuguese\n 'ro', // Romanian\n 'sv', // Swedish\n 'th', // Thai\n 'tr', // Turkish\n 'uk', // Ukrainian\n 'vi', // Vietnamese\n 'zh', // Chinese\n] as const;\nexport type AvailableLocale = typeof AVAILABLE_LOCALES[number];\n\n// Lazy load translations for a specific locale\nasync function loadTranslations(locale: string): Promise<any> {\n // Check cache first\n if (translationCache.has(locale)) {\n return translationCache.get(locale);\n }\n\n // English is already loaded statically\n if (locale === 'en') {\n translationCache.set('en', enTranslations);\n return enTranslations;\n }\n\n try {\n // Dynamic import for all other locales\n const translations = await import(`../../translations/${locale}.json`);\n const translationData = translations.default || translations;\n translationCache.set(locale, translationData);\n return translationData;\n } catch (error) {\n console.error(`Failed to load translations for locale: ${locale}`, error);\n // Fall back to English\n return enTranslations;\n }\n}\n\n// Default English translation manager (using static import)\nconst defaultTranslationManager: TranslationManager = {\n t: (namespace: string, key: string, params?: Record<string, any>) => {\n const translations = enTranslations as Record<string, Record<string, string>>;\n const translation = translations[namespace]?.[key];\n\n if (!translation) {\n console.warn(`Translation not found for ${namespace}.${key}`);\n return `${namespace}.${key}`;\n }\n\n // Handle parameter interpolation and plural format\n if (params && typeof translation === 'string') {\n let result = translation;\n // First process plural format\n result = processPluralFormat(result, params);\n // Then handle simple parameter interpolation\n Object.entries(params).forEach(([paramKey, paramValue]) => {\n result = result.replace(new RegExp(`\\\\{${paramKey}\\\\}`, 'g'), String(paramValue));\n });\n return result;\n }\n\n return translation;\n },\n};\n\nexport interface TranslationProviderProps {\n /**\n * Option 1: Provide a complete TranslationManager implementation\n */\n translationManager?: TranslationManager;\n\n /**\n * Option 2: Use built-in translations by specifying a locale\n * When adding new locales, just add the JSON file and update AVAILABLE_LOCALES\n */\n locale?: string;\n\n /**\n * Loading component to show while translations are being loaded\n * Only relevant when using dynamic locale loading\n */\n loadingComponent?: ReactNode;\n\n children: ReactNode;\n}\n\n/**\n * Provider for translation management with dynamic loading\n *\n * Three modes of operation:\n * 1. No provider: Components use default English strings\n * 2. With locale prop: Dynamically loads translations for that locale\n * 3. With translationManager: Use custom translation implementation\n */\nexport function TranslationProvider({\n translationManager,\n locale,\n loadingComponent = null,\n children,\n}: TranslationProviderProps) {\n const [loadedTranslations, setLoadedTranslations] = useState<any>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n // Load translations when locale changes\n useEffect(() => {\n if (locale && !translationManager) {\n setIsLoading(true);\n loadTranslations(locale)\n .then(translations => {\n setLoadedTranslations(translations);\n setIsLoading(false);\n })\n .catch(error => {\n console.error('Failed to load translations:', error);\n setLoadedTranslations(enTranslations); // Fall back to English\n setIsLoading(false);\n });\n }\n }, [locale, translationManager]);\n\n // Create translation manager from loaded translations\n const localeManager = useMemo<TranslationManager | null>(() => {\n if (!loadedTranslations) return null;\n\n return {\n t: (namespace: string, key: string, params?: Record<string, any>) => {\n const translation = loadedTranslations[namespace]?.[key];\n\n if (!translation) {\n console.warn(`Translation not found for ${namespace}.${key} in locale ${locale}`);\n return `${namespace}.${key}`;\n }\n\n // Handle parameter interpolation and plural format\n if (params && typeof translation === 'string') {\n let result = translation;\n // First process plural format\n result = processPluralFormat(result, params);\n // Then handle simple parameter interpolation\n Object.entries(params).forEach(([paramKey, paramValue]) => {\n result = result.replace(new RegExp(`\\\\{${paramKey}\\\\}`, 'g'), String(paramValue));\n });\n return result;\n }\n\n return translation;\n },\n };\n }, [loadedTranslations, locale]);\n\n // If custom translation manager provided, use it\n if (translationManager) {\n return (\n <TranslationContext.Provider value={translationManager}>\n {children}\n </TranslationContext.Provider>\n );\n }\n\n // If locale provided and still loading, show loading component\n if (locale && isLoading) {\n return <>{loadingComponent}</>;\n }\n\n // If locale provided and translations loaded, use them\n if (locale && localeManager) {\n return (\n <TranslationContext.Provider value={localeManager}>\n {children}\n </TranslationContext.Provider>\n );\n }\n\n // Default: use English translations\n return (\n <TranslationContext.Provider value={defaultTranslationManager}>\n {children}\n </TranslationContext.Provider>\n );\n}\n\n/**\n * Hook to access translations within a namespace\n *\n * Works in three modes:\n * 1. Without provider: Returns default English translations\n * 2. With provider using locale: Returns dynamically loaded translations for that locale\n * 3. With custom provider: Uses the custom translation manager\n *\n * @param namespace - Translation namespace (e.g., 'Toolbar', 'ResourceViewer')\n * @returns Function to translate keys within the namespace\n */\nexport function useTranslations(namespace: string) {\n const context = useContext(TranslationContext);\n\n // If no context (no provider), use default English translations\n if (!context) {\n return (key: string, params?: Record<string, any>) => {\n const translations = enTranslations as Record<string, Record<string, string>>;\n const translation = translations[namespace]?.[key];\n\n if (!translation) {\n console.warn(`Translation not found for ${namespace}.${key}`);\n return `${namespace}.${key}`;\n }\n\n // Handle parameter interpolation and plural format\n if (params && typeof translation === 'string') {\n let result = translation;\n // First process plural format\n result = processPluralFormat(result, params);\n // Then handle simple parameter interpolation\n Object.entries(params).forEach(([paramKey, paramValue]) => {\n result = result.replace(new RegExp(`\\\\{${paramKey}\\\\}`, 'g'), String(paramValue));\n });\n return result;\n }\n\n return translation;\n };\n }\n\n // Return a function that translates keys within this namespace\n return (key: string, params?: Record<string, any>) => context.t(namespace, key, params);\n}\n\n/**\n * Hook to preload translations for a locale\n * Useful for preloading translations before navigation\n */\nexport function usePreloadTranslations() {\n return {\n preload: async (locale: string) => {\n try {\n await loadTranslations(locale);\n return true;\n } catch (error) {\n console.error(`Failed to preload translations for ${locale}:`, error);\n return false;\n }\n },\n isLoaded: (locale: string) => translationCache.has(locale),\n };\n}"],"mappings":"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","names":["createContext","useContext","useMemo","jsx","createContext","useContext","jsx","jsx","createContext","useContext","jsx","createContext","useContext","useState","useEffect","useMemo","jsx","createContext","useState","useEffect","useMemo","jsx","useContext"]}
|