@semiont/api-client 0.2.28-build.38 → 0.2.28-build.40

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/sse/stream.ts","../src/sse/index.ts","../src/client.ts","../src/branded-types.ts","../src/utils/annotations.ts","../src/utils/events.ts","../src/utils/fuzzy-anchor.ts","../src/utils/locales.ts","../src/utils/resources.ts","../src/utils/svg-utils.ts","../src/utils/text-encoding.ts","../src/utils/validation.ts","../src/mime-utils.ts"],"names":["baseUrl","accessToken","email","resourceUri","annotationUri","pos"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * SSE Stream Factory\n *\n * Creates Server-Sent Events streams using native fetch() and manual parsing.\n * Does NOT use the EventSource API for better control over connection lifecycle.\n */\n\nimport type { SSEStream } from './types';\nimport type { Logger } from '../logger';\n\n/**\n * Configuration for SSE stream event handling\n */\ninterface SSEConfig {\n /** Event types that trigger onProgress callback */\n progressEvents: string[];\n /** Event type that triggers onComplete callback (null for long-lived streams) */\n completeEvent: string | null;\n /** Event type that triggers onError callback */\n errorEvent: string | null;\n /** If true, use custom event handlers instead of standard mapping */\n customEventHandler?: boolean;\n}\n\n/**\n * Create an SSE stream with typed event callbacks\n *\n * Uses native fetch() with manual SSE parsing for fine-grained control.\n * Supports AbortController for cancellation.\n *\n * @typeParam TProgress - Type of progress event data\n * @typeParam TComplete - Type of completion event data\n *\n * @param url - Full URL to SSE endpoint\n * @param fetchOptions - fetch() options (method, headers, body)\n * @param config - Event mapping configuration\n * @returns SSEStream controller with callback registration and cleanup\n *\n * @example\n * ```typescript\n * const stream = createSSEStream<DetectionProgress, DetectionProgress>(\n * 'http://localhost:4000/resources/123/detect-annotations-stream',\n * {\n * method: 'POST',\n * headers: { 'Authorization': 'Bearer token', 'Content-Type': 'application/json' },\n * body: JSON.stringify({ entityTypes: ['Person'] })\n * },\n * {\n * progressEvents: ['detection-started', 'detection-progress'],\n * completeEvent: 'detection-complete',\n * errorEvent: 'detection-error'\n * }\n * );\n *\n * stream.onProgress((p) => console.log(p.message));\n * stream.onComplete((r) => console.log('Done!'));\n * stream.close(); // Cleanup\n * ```\n */\nexport function createSSEStream<TProgress, TComplete>(\n url: string,\n fetchOptions: RequestInit,\n config: SSEConfig,\n logger?: Logger\n): SSEStream<TProgress, TComplete> {\n const abortController = new AbortController();\n let progressCallback: ((data: TProgress) => void) | null = null;\n let completeCallback: ((data: TComplete) => void) | null = null;\n let errorCallback: ((error: Error) => void) | null = null;\n const customHandlers = new Map<string, (data?: any) => void>();\n let closed = false; // Flag to stop processing events after close/complete/error\n\n /**\n * Start the SSE connection and parse the stream\n */\n const connect = async () => {\n try {\n // Log stream request\n logger?.debug('SSE Stream Request', {\n type: 'sse_request',\n url,\n method: fetchOptions.method || 'GET',\n timestamp: Date.now()\n });\n\n const response = await fetch(url, {\n ...fetchOptions,\n signal: abortController.signal,\n headers: {\n ...fetchOptions.headers,\n 'Accept': 'text/event-stream'\n }\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({})) as { message?: string };\n const error = new Error(errorData.message || `HTTP ${response.status}: ${response.statusText}`);\n\n // Log connection error\n logger?.error('SSE Stream Error', {\n type: 'sse_error',\n url,\n error: error.message,\n status: response.status,\n phase: 'connect'\n });\n\n throw error;\n }\n\n if (!response.body) {\n const error = new Error('Response body is null - server did not return a stream');\n\n logger?.error('SSE Stream Error', {\n type: 'sse_error',\n url,\n error: error.message,\n phase: 'connect'\n });\n\n throw error;\n }\n\n // Log successful connection\n logger?.info('SSE Stream Connected', {\n type: 'sse_connected',\n url,\n status: response.status,\n contentType: response.headers.get('content-type') || 'unknown'\n });\n\n // Parse SSE stream\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n // Event state persists across reads to handle multi-chunk events\n let eventType = '';\n let eventData = '';\n let eventId = '';\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done || closed) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n\n // Keep the last partial line in the buffer\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('event:')) {\n eventType = line.slice(6).trim();\n } else if (line.startsWith('data:')) {\n eventData = line.slice(5).trim();\n } else if (line.startsWith('id:')) {\n eventId = line.slice(3).trim();\n } else if (line === '') {\n // Empty line marks end of event\n if (eventData && !closed) {\n handleEvent(eventType, eventData, eventId);\n if (closed) break; // Stop processing if event triggered close\n eventType = '';\n eventData = '';\n eventId = '';\n }\n }\n }\n\n if (closed) break; // Exit outer loop if closed\n }\n\n // Log stream close\n logger?.info('SSE Stream Closed', {\n type: 'sse_closed',\n url,\n reason: 'complete'\n });\n } catch (error) {\n // Don't report AbortError (normal cleanup)\n if (error instanceof Error && error.name !== 'AbortError') {\n logger?.error('SSE Stream Error', {\n type: 'sse_error',\n url,\n error: error.message,\n phase: 'stream'\n });\n errorCallback?.(error);\n } else if (error instanceof Error && error.name === 'AbortError') {\n // Log normal close (abort)\n logger?.info('SSE Stream Closed', {\n type: 'sse_closed',\n url,\n reason: 'abort'\n });\n }\n }\n };\n\n /**\n * Handle a parsed SSE event\n */\n const handleEvent = (eventType: string, data: string, _id: string) => {\n // Skip keep-alive comments\n if (data.startsWith(':')) {\n return;\n }\n\n try {\n const parsed = JSON.parse(data);\n\n // Log SSE event (debug level - can be verbose)\n logger?.debug('SSE Event Received', {\n type: 'sse_event',\n url,\n event: eventType || 'message',\n hasData: !!data\n });\n\n // Custom event handler (for resourceEvents which handles all events)\n if (config.customEventHandler) {\n const handler = customHandlers.get(eventType);\n if (handler) {\n handler(parsed);\n return;\n }\n // Pass all events to progress handler if no specific handler\n progressCallback?.(parsed as TProgress);\n return;\n }\n\n // Progress events\n if (config.progressEvents.includes(eventType)) {\n progressCallback?.(parsed as TProgress);\n }\n\n // Complete event\n if (config.completeEvent && eventType === config.completeEvent) {\n completeCallback?.(parsed as TComplete);\n closed = true; // Stop processing further events\n abortController.abort(); // Close stream on completion\n }\n\n // Error event\n if (config.errorEvent && eventType === config.errorEvent) {\n errorCallback?.(new Error(parsed.message || 'Stream error'));\n closed = true; // Stop processing further events\n abortController.abort(); // Close stream on error\n }\n } catch (error) {\n console.error('[SSE] Failed to parse event data:', error);\n console.error('[SSE] Event type:', eventType);\n console.error('[SSE] Data:', data);\n }\n };\n\n // Start connection immediately\n connect();\n\n // Return SSE stream controller\n return {\n onProgress(callback) {\n progressCallback = callback;\n },\n\n onComplete(callback) {\n completeCallback = callback;\n },\n\n onError(callback) {\n errorCallback = callback;\n },\n\n close() {\n abortController.abort();\n },\n\n // Internal method for custom event handlers (used by resourceEvents)\n on(event: string, callback: (data?: any) => void) {\n customHandlers.set(event, callback);\n }\n } as SSEStream<TProgress, TComplete> & { on?: (event: string, callback: (data?: any) => void) => void };\n}\n","/**\n * SSE Client for Semiont Streaming Endpoints\n *\n * Provides type-safe methods for Server-Sent Events streaming.\n * Does NOT use ky - uses native fetch() for SSE support.\n */\n\nimport { createSSEStream } from './stream';\nimport type {\n DetectionProgress,\n GenerationProgress,\n HighlightDetectionProgress,\n AssessmentDetectionProgress,\n CommentDetectionProgress,\n TagDetectionProgress,\n ResourceEvent,\n SSEStream\n} from './types';\nimport type { ResourceUri, AnnotationUri } from '../branded-types';\nimport type { AccessToken, BaseUrl, EntityType } from '../branded-types';\nimport type { components } from '../types';\nimport type { Logger } from '../logger';\n\n/**\n * Request body for detection stream\n */\nexport interface DetectAnnotationsStreamRequest {\n entityTypes: EntityType[];\n}\n\n/**\n * Request body for generation stream\n * Uses generated type from OpenAPI schema\n */\nexport type GenerateResourceStreamRequest = components['schemas']['GenerateResourceStreamRequest'];\n\n/**\n * Request body for highlight detection stream\n */\nexport interface DetectHighlightsStreamRequest {\n instructions?: string;\n}\n\n/**\n * Request body for assessment detection stream\n */\nexport interface DetectAssessmentsStreamRequest {\n instructions?: string;\n}\n\n/**\n * Request body for comment detection stream\n */\nexport interface DetectCommentsStreamRequest {\n instructions?: string;\n tone?: 'scholarly' | 'explanatory' | 'conversational' | 'technical';\n}\n\n/**\n * Request body for tag detection stream\n */\nexport interface DetectTagsStreamRequest {\n schemaId: string;\n categories: string[];\n}\n\n/**\n * SSE Client configuration\n */\nexport interface SSEClientConfig {\n baseUrl: BaseUrl;\n accessToken?: AccessToken;\n logger?: Logger;\n}\n\n/**\n * SSE Client for real-time streaming operations\n *\n * Separate from the main HTTP client to clearly mark streaming endpoints.\n * Uses native fetch() instead of ky for SSE support.\n *\n * @example\n * ```typescript\n * const sseClient = new SSEClient({\n * baseUrl: 'http://localhost:4000',\n * accessToken: 'your-token'\n * });\n *\n * const stream = sseClient.detectAnnotations(\n * 'http://localhost:4000/resources/doc-123',\n * { entityTypes: ['Person', 'Organization'] }\n * );\n *\n * stream.onProgress((p) => console.log(p.message));\n * stream.onComplete((r) => console.log(`Found ${r.foundCount} entities`));\n * stream.onError((e) => console.error('Detection failed:', e));\n * ```\n */\nexport class SSEClient {\n private baseUrl: BaseUrl;\n private accessToken: AccessToken | null = null;\n private logger?: Logger;\n\n constructor(config: SSEClientConfig) {\n // Remove trailing slash for consistent URL construction\n this.baseUrl = (config.baseUrl.endsWith('/') ? config.baseUrl.slice(0, -1) : config.baseUrl) as BaseUrl;\n this.accessToken = config.accessToken || null;\n this.logger = config.logger;\n }\n\n /**\n * Set the access token for authenticated requests\n */\n setAccessToken(token: AccessToken): void {\n this.accessToken = token;\n }\n\n /**\n * Clear the access token\n */\n clearAccessToken(): void {\n this.accessToken = null;\n }\n\n /**\n * Get common headers for SSE requests\n */\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json'\n };\n\n if (this.accessToken) {\n headers['Authorization'] = `Bearer ${this.accessToken}`;\n }\n\n return headers;\n }\n\n /**\n * Extract resource ID from URI\n *\n * Handles both full URIs and plain IDs:\n * - 'http://localhost:4000/resources/doc-123' -> 'doc-123'\n * - 'doc-123' -> 'doc-123'\n */\n private extractId(uri: string): string {\n const parts = uri.split('/');\n return parts[parts.length - 1];\n }\n\n /**\n * Detect annotations in a resource (streaming)\n *\n * Streams entity detection progress via Server-Sent Events.\n *\n * @param resourceId - Resource URI or ID\n * @param request - Detection configuration (entity types to detect)\n * @returns SSE stream controller with progress/complete/error callbacks\n *\n * @example\n * ```typescript\n * const stream = sseClient.detectAnnotations(\n * 'http://localhost:4000/resources/doc-123',\n * { entityTypes: ['Person', 'Organization'] }\n * );\n *\n * stream.onProgress((progress) => {\n * console.log(`Scanning: ${progress.currentEntityType}`);\n * console.log(`Progress: ${progress.processedEntityTypes}/${progress.totalEntityTypes}`);\n * });\n *\n * stream.onComplete((result) => {\n * console.log(`Detection complete! Found ${result.foundCount} entities`);\n * });\n *\n * stream.onError((error) => {\n * console.error('Detection failed:', error.message);\n * });\n *\n * // Cleanup when done\n * stream.close();\n * ```\n */\n detectAnnotations(\n resourceId: ResourceUri,\n request: DetectAnnotationsStreamRequest\n ): SSEStream<DetectionProgress, DetectionProgress> {\n const id = this.extractId(resourceId);\n const url = `${this.baseUrl}/resources/${id}/detect-annotations-stream`;\n\n return createSSEStream<DetectionProgress, DetectionProgress>(\n url,\n {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(request)\n },\n {\n progressEvents: ['detection-started', 'detection-progress'],\n completeEvent: 'detection-complete',\n errorEvent: 'detection-error'\n },\n this.logger\n );\n }\n\n /**\n * Generate resource from annotation (streaming)\n *\n * Streams resource generation progress via Server-Sent Events.\n *\n * @param resourceId - Source resource URI or ID\n * @param annotationId - Annotation URI or ID to use as generation source\n * @param request - Generation options (title, prompt, language)\n * @returns SSE stream controller with progress/complete/error callbacks\n *\n * @example\n * ```typescript\n * const stream = sseClient.generateResourceFromAnnotation(\n * 'http://localhost:4000/resources/doc-123',\n * 'http://localhost:4000/annotations/ann-456',\n * { language: 'es', title: 'Spanish Summary' }\n * );\n *\n * stream.onProgress((progress) => {\n * console.log(`${progress.status}: ${progress.percentage}%`);\n * console.log(progress.message);\n * });\n *\n * stream.onComplete((result) => {\n * console.log(`Generated resource: ${result.resourceId}`);\n * });\n *\n * stream.onError((error) => {\n * console.error('Generation failed:', error.message);\n * });\n *\n * // Cleanup when done\n * stream.close();\n * ```\n */\n generateResourceFromAnnotation(\n resourceId: ResourceUri,\n annotationId: AnnotationUri,\n request: GenerateResourceStreamRequest\n ): SSEStream<GenerationProgress, GenerationProgress> {\n const resId = this.extractId(resourceId);\n const annId = this.extractId(annotationId);\n const url = `${this.baseUrl}/resources/${resId}/annotations/${annId}/generate-resource-stream`;\n\n return createSSEStream<GenerationProgress, GenerationProgress>(\n url,\n {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(request)\n },\n {\n progressEvents: ['generation-started', 'generation-progress'],\n completeEvent: 'generation-complete',\n errorEvent: 'generation-error'\n },\n this.logger\n );\n }\n\n /**\n * Detect highlights in a resource (streaming)\n *\n * Streams highlight detection progress via Server-Sent Events.\n *\n * @param resourceId - Resource URI or ID\n * @param request - Detection configuration (optional instructions)\n * @returns SSE stream controller with progress/complete/error callbacks\n *\n * @example\n * ```typescript\n * const stream = sseClient.detectHighlights(\n * 'http://localhost:4000/resources/doc-123',\n * { instructions: 'Focus on key technical points' }\n * );\n *\n * stream.onProgress((progress) => {\n * console.log(`${progress.status}: ${progress.percentage}%`);\n * console.log(progress.message);\n * });\n *\n * stream.onComplete((result) => {\n * console.log(`Detection complete! Created ${result.createdCount} highlights`);\n * });\n *\n * stream.onError((error) => {\n * console.error('Detection failed:', error.message);\n * });\n *\n * // Cleanup when done\n * stream.close();\n * ```\n */\n detectHighlights(\n resourceId: ResourceUri,\n request: DetectHighlightsStreamRequest = {}\n ): SSEStream<HighlightDetectionProgress, HighlightDetectionProgress> {\n const id = this.extractId(resourceId);\n const url = `${this.baseUrl}/resources/${id}/detect-highlights-stream`;\n\n return createSSEStream<HighlightDetectionProgress, HighlightDetectionProgress>(\n url,\n {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(request)\n },\n {\n progressEvents: ['highlight-detection-started', 'highlight-detection-progress'],\n completeEvent: 'highlight-detection-complete',\n errorEvent: 'highlight-detection-error'\n },\n this.logger\n );\n }\n\n /**\n * Detect assessments in a resource (streaming)\n *\n * Streams assessment detection progress via Server-Sent Events.\n *\n * @param resourceId - Resource URI or ID\n * @param request - Detection configuration (optional instructions)\n * @returns SSE stream controller with progress/complete/error callbacks\n *\n * @example\n * ```typescript\n * const stream = sseClient.detectAssessments(\n * 'http://localhost:4000/resources/doc-123',\n * { instructions: 'Evaluate claims for accuracy' }\n * );\n *\n * stream.onProgress((progress) => {\n * console.log(`${progress.status}: ${progress.percentage}%`);\n * console.log(progress.message);\n * });\n *\n * stream.onComplete((result) => {\n * console.log(`Detection complete! Created ${result.createdCount} assessments`);\n * });\n *\n * stream.onError((error) => {\n * console.error('Detection failed:', error.message);\n * });\n *\n * // Cleanup when done\n * stream.close();\n * ```\n */\n detectAssessments(\n resourceId: ResourceUri,\n request: DetectAssessmentsStreamRequest = {}\n ): SSEStream<AssessmentDetectionProgress, AssessmentDetectionProgress> {\n const id = this.extractId(resourceId);\n const url = `${this.baseUrl}/resources/${id}/detect-assessments-stream`;\n\n return createSSEStream<AssessmentDetectionProgress, AssessmentDetectionProgress>(\n url,\n {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(request)\n },\n {\n progressEvents: ['assessment-detection-started', 'assessment-detection-progress'],\n completeEvent: 'assessment-detection-complete',\n errorEvent: 'assessment-detection-error'\n },\n this.logger\n );\n }\n\n /**\n * Detect comments in a resource (streaming)\n *\n * Streams comment detection progress via Server-Sent Events.\n * Uses AI to identify passages that would benefit from explanatory comments\n * and creates comment annotations with contextual information.\n *\n * @param resourceId - Resource URI or ID\n * @param request - Detection configuration (optional instructions and tone)\n * @returns SSE stream controller with progress/complete/error callbacks\n *\n * @example\n * ```typescript\n * const stream = sseClient.detectComments('http://localhost:4000/resources/doc-123', {\n * instructions: 'Focus on technical terminology',\n * tone: 'scholarly'\n * });\n *\n * stream.onProgress((progress) => {\n * console.log(`${progress.status}: ${progress.percentage}%`);\n * });\n *\n * stream.onComplete((result) => {\n * console.log(`Detection complete! Created ${result.createdCount} comments`);\n * });\n *\n * stream.onError((error) => {\n * console.error('Detection failed:', error.message);\n * });\n *\n * // Cleanup when done\n * stream.close();\n * ```\n */\n detectComments(\n resourceId: ResourceUri,\n request: DetectCommentsStreamRequest = {}\n ): SSEStream<CommentDetectionProgress, CommentDetectionProgress> {\n const id = this.extractId(resourceId);\n const url = `${this.baseUrl}/resources/${id}/detect-comments-stream`;\n\n return createSSEStream<CommentDetectionProgress, CommentDetectionProgress>(\n url,\n {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(request)\n },\n {\n progressEvents: ['comment-detection-started', 'comment-detection-progress'],\n completeEvent: 'comment-detection-complete',\n errorEvent: 'comment-detection-error'\n },\n this.logger\n );\n }\n\n /**\n * Detect tags in a resource (streaming)\n *\n * Streams tag detection progress via Server-Sent Events.\n * Uses AI to identify passages serving specific structural roles\n * (e.g., IRAC, IMRAD, Toulmin) and creates tag annotations with dual-body structure.\n *\n * @param resourceId - Resource URI or ID\n * @param request - Detection configuration (schema and categories to detect)\n * @returns SSE stream controller with progress/complete/error callbacks\n *\n * @example\n * ```typescript\n * const stream = sseClient.detectTags('http://localhost:4000/resources/doc-123', {\n * schemaId: 'legal-irac',\n * categories: ['Issue', 'Rule', 'Application', 'Conclusion']\n * });\n *\n * stream.onProgress((progress) => {\n * console.log(`${progress.status}: ${progress.percentage}%`);\n * console.log(`Processing ${progress.currentCategory}...`);\n * });\n *\n * stream.onComplete((result) => {\n * console.log(`Detection complete! Created ${result.tagsCreated} tags`);\n * });\n *\n * stream.onError((error) => {\n * console.error('Detection failed:', error.message);\n * });\n *\n * // Cleanup when done\n * stream.close();\n * ```\n */\n detectTags(\n resourceId: ResourceUri,\n request: DetectTagsStreamRequest\n ): SSEStream<TagDetectionProgress, TagDetectionProgress> {\n const id = this.extractId(resourceId);\n const url = `${this.baseUrl}/resources/${id}/detect-tags-stream`;\n\n return createSSEStream<TagDetectionProgress, TagDetectionProgress>(\n url,\n {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(request)\n },\n {\n progressEvents: ['tag-detection-started', 'tag-detection-progress'],\n completeEvent: 'tag-detection-complete',\n errorEvent: 'tag-detection-error'\n },\n this.logger\n );\n }\n\n /**\n * Subscribe to resource events (long-lived stream)\n *\n * Opens a long-lived SSE connection to receive real-time events for a resource.\n * Used for collaborative editing - see events from other users as they happen.\n *\n * This stream does NOT have a complete event - it stays open until explicitly closed.\n *\n * @param resourceId - Resource URI or ID to subscribe to\n * @returns SSE stream controller with event callback\n *\n * @example\n * ```typescript\n * const stream = sseClient.resourceEvents('http://localhost:4000/resources/doc-123');\n *\n * stream.onProgress((event) => {\n * console.log(`Event: ${event.type}`);\n * console.log(`User: ${event.userId}`);\n * console.log(`Sequence: ${event.metadata.sequenceNumber}`);\n * console.log(`Payload:`, event.payload);\n * });\n *\n * stream.onError((error) => {\n * console.error('Stream error:', error.message);\n * });\n *\n * // Close when no longer needed (e.g., component unmount)\n * stream.close();\n * ```\n */\n resourceEvents(resourceId: ResourceUri): SSEStream<ResourceEvent, never> {\n const id = this.extractId(resourceId);\n const url = `${this.baseUrl}/resources/${id}/events/stream`;\n\n return createSSEStream<ResourceEvent, never>(\n url,\n {\n method: 'GET',\n headers: this.getHeaders()\n },\n {\n progressEvents: ['*'], // Accept all event types\n completeEvent: null, // Long-lived stream - no completion\n errorEvent: 'error', // Generic error event\n customEventHandler: true // Use custom event handling\n },\n this.logger\n );\n }\n}\n","/**\n * Common API client for Semiont backend\n *\n * This client can be used by:\n * - MCP server (Node.js)\n * - Demo scripts (Node.js)\n * - Frontend (Next.js/React - can wrap with hooks)\n *\n * Uses ky for HTTP requests with built-in retry, timeout, and error handling.\n */\n\nimport ky, { type KyInstance } from 'ky';\nimport type { paths } from './types';\nimport type { AnnotationUri, ResourceUri, ResourceAnnotationUri } from './branded-types';\nimport type {\n AccessToken,\n BaseUrl,\n CloneToken,\n ContentFormat,\n Email,\n EntityType,\n GoogleCredential,\n JobId,\n Motivation,\n RefreshToken,\n SearchQuery,\n UserDID\n} from './branded-types';\nimport { SSEClient } from './sse/index';\nimport type { Logger } from './logger';\n\n// Type helpers to extract request/response types from OpenAPI paths\ntype ResponseContent<T> = T extends { responses: { 200: { content: { 'application/json': infer R } } } }\n ? R\n : T extends { responses: { 201: { content: { 'application/json': infer R } } } }\n ? R\n : never;\n\ntype RequestContent<T> = T extends { requestBody?: { content: { 'application/json': infer R } } } ? R : never;\n\n// API Error class\nexport class APIError extends Error {\n constructor(\n message: string,\n public status: number,\n public statusText: string,\n public details?: unknown\n ) {\n super(message);\n this.name = 'APIError';\n }\n}\n\nexport interface SemiontApiClientConfig {\n baseUrl: BaseUrl;\n accessToken?: AccessToken;\n timeout?: number;\n retry?: number;\n logger?: Logger;\n}\n\n/**\n * Semiont API Client\n *\n * Provides type-safe methods for all Semiont backend API endpoints.\n */\nexport class SemiontApiClient {\n private http: KyInstance;\n private baseUrl: BaseUrl;\n private accessToken: AccessToken | null = null;\n private logger?: Logger;\n\n /**\n * SSE streaming client for real-time operations\n *\n * Separate from the main HTTP client to clearly mark streaming endpoints.\n * Uses native fetch() instead of ky for SSE support.\n *\n * @example\n * ```typescript\n * const stream = client.sse.detectAnnotations(\n * resourceId,\n * { entityTypes: ['Person', 'Organization'] }\n * );\n *\n * stream.onProgress((p) => console.log(p.message));\n * stream.onComplete((r) => console.log(`Found ${r.foundCount} entities`));\n * stream.close();\n * ```\n */\n public readonly sse: SSEClient;\n\n constructor(config: SemiontApiClientConfig) {\n const { baseUrl, accessToken, timeout = 30000, retry = 2, logger } = config;\n\n // Store logger and baseUrl for constructing full URLs\n this.logger = logger;\n\n // Remove trailing slash for consistent URL construction\n this.baseUrl = (baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl) as BaseUrl;\n\n // Don't use prefixUrl - we'll construct full URLs or use provided full URIs\n this.http = ky.create({\n timeout,\n retry,\n hooks: {\n beforeRequest: [\n (request) => {\n // Add auth header\n if (this.accessToken) {\n request.headers.set('Authorization', `Bearer ${this.accessToken}`);\n }\n\n // Log HTTP request\n if (this.logger) {\n this.logger.debug('HTTP Request', {\n type: 'http_request',\n url: request.url,\n method: request.method,\n timestamp: Date.now(),\n hasAuth: !!this.accessToken\n });\n }\n },\n ],\n afterResponse: [\n (request, _options, response) => {\n // Log HTTP response\n if (this.logger) {\n this.logger.debug('HTTP Response', {\n type: 'http_response',\n url: request.url,\n method: request.method,\n status: response.status,\n statusText: response.statusText\n });\n }\n return response;\n }\n ],\n beforeError: [\n async (error) => {\n const { response, request } = error;\n if (response) {\n const body = await response.json().catch(() => ({})) as any;\n\n // Log HTTP error\n if (this.logger) {\n this.logger.error('HTTP Request Failed', {\n type: 'http_error',\n url: request.url,\n method: request.method,\n status: response.status,\n statusText: response.statusText,\n error: body.message || `HTTP ${response.status}: ${response.statusText}`\n });\n }\n\n throw new APIError(\n body.message || `HTTP ${response.status}: ${response.statusText}`,\n response.status,\n response.statusText,\n body\n );\n }\n return error;\n },\n ],\n },\n });\n\n if (accessToken) {\n this.accessToken = accessToken;\n }\n\n // Initialize SSE client (uses native fetch, not ky)\n this.sse = new SSEClient({\n baseUrl: this.baseUrl,\n accessToken: this.accessToken || undefined,\n logger: this.logger\n });\n }\n\n /**\n * Set the access token for authenticated requests\n */\n setAccessToken(token: AccessToken): void {\n this.accessToken = token;\n this.sse.setAccessToken(token);\n }\n\n /**\n * Clear the access token\n */\n clearAccessToken(): void {\n this.accessToken = null;\n this.sse.clearAccessToken();\n }\n\n // ============================================================================\n // AUTHENTICATION\n // ============================================================================\n\n async authenticatePassword(email: Email, password: string): Promise<ResponseContent<paths['/api/tokens/password']['post']>> {\n const response = await this.http.post(`${this.baseUrl}/api/tokens/password`, { json: { email, password } }).json<any>();\n if (response.token) {\n this.setAccessToken(response.token);\n }\n return response;\n }\n\n async refreshToken(token: RefreshToken): Promise<ResponseContent<paths['/api/tokens/refresh']['post']>> {\n const response = await this.http.post(`${this.baseUrl}/api/tokens/refresh`, { json: { refreshToken: token } }).json<any>();\n if (response.access_token) {\n this.setAccessToken(response.access_token);\n }\n return response;\n }\n\n async authenticateGoogle(credential: GoogleCredential): Promise<ResponseContent<paths['/api/tokens/google']['post']>> {\n const response = await this.http.post(`${this.baseUrl}/api/tokens/google`, { json: { credential } }).json<any>();\n if (response.token) {\n this.setAccessToken(response.token);\n }\n return response;\n }\n\n async generateMCPToken(): Promise<ResponseContent<paths['/api/tokens/mcp-generate']['post']>> {\n return this.http.post(`${this.baseUrl}/api/tokens/mcp-generate`).json();\n }\n\n // ============================================================================\n // USERS\n // ============================================================================\n\n async getMe(): Promise<ResponseContent<paths['/api/users/me']['get']>> {\n return this.http.get(`${this.baseUrl}/api/users/me`).json();\n }\n\n async acceptTerms(): Promise<ResponseContent<paths['/api/users/accept-terms']['post']>> {\n return this.http.post(`${this.baseUrl}/api/users/accept-terms`).json();\n }\n\n async logout(): Promise<ResponseContent<paths['/api/users/logout']['post']>> {\n return this.http.post(`${this.baseUrl}/api/users/logout`).json();\n }\n\n // ============================================================================\n // RESOURCES\n // ============================================================================\n\n /**\n * Create a new resource with binary content support\n *\n * @param data - Resource creation data\n * @param data.name - Resource name\n * @param data.file - File object or Buffer with binary content\n * @param data.format - MIME type (e.g., 'text/markdown', 'image/png')\n * @param data.entityTypes - Optional array of entity types\n * @param data.language - Optional ISO 639-1 language code\n * @param data.creationMethod - Optional creation method\n * @param data.sourceAnnotationId - Optional source annotation ID\n * @param data.sourceResourceId - Optional source resource ID\n */\n async createResource(data: {\n name: string;\n file: File | Buffer;\n format: string;\n entityTypes?: string[];\n language?: string;\n creationMethod?: string;\n sourceAnnotationId?: string;\n sourceResourceId?: string;\n }): Promise<ResponseContent<paths['/resources']['post']>> {\n // Build FormData\n const formData = new FormData();\n formData.append('name', data.name);\n formData.append('format', data.format);\n\n // Handle File or Buffer\n if (data.file instanceof File) {\n formData.append('file', data.file);\n } else if (Buffer.isBuffer(data.file)) {\n // Node.js environment: convert Buffer to Blob\n const blob = new Blob([data.file], { type: data.format });\n formData.append('file', blob, data.name);\n } else {\n throw new Error('file must be a File or Buffer');\n }\n\n // Optional fields\n if (data.entityTypes && data.entityTypes.length > 0) {\n formData.append('entityTypes', JSON.stringify(data.entityTypes));\n }\n if (data.language) {\n formData.append('language', data.language);\n }\n if (data.creationMethod) {\n formData.append('creationMethod', data.creationMethod);\n }\n if (data.sourceAnnotationId) {\n formData.append('sourceAnnotationId', data.sourceAnnotationId);\n }\n if (data.sourceResourceId) {\n formData.append('sourceResourceId', data.sourceResourceId);\n }\n\n // POST with multipart/form-data (ky automatically sets Content-Type)\n return this.http.post(`${this.baseUrl}/resources`, { body: formData }).json();\n }\n\n async getResource(resourceUri: ResourceUri): Promise<ResponseContent<paths['/resources/{id}']['get']>> {\n // resourceUri is already a full URI, use it directly\n return this.http.get(resourceUri).json();\n }\n\n /**\n * Get resource representation using W3C content negotiation\n * Returns raw binary content (images, PDFs, text, etc.) with content type\n *\n * @param resourceUri - Full resource URI\n * @param options - Options including Accept header for content negotiation\n * @returns Object with data (ArrayBuffer) and contentType (string)\n *\n * @example\n * ```typescript\n * // Get markdown representation\n * const { data, contentType } = await client.getResourceRepresentation(rUri, { accept: 'text/markdown' });\n * const markdown = new TextDecoder().decode(data);\n *\n * // Get image representation\n * const { data, contentType } = await client.getResourceRepresentation(rUri, { accept: 'image/png' });\n * const blob = new Blob([data], { type: contentType });\n *\n * // Get PDF representation\n * const { data, contentType } = await client.getResourceRepresentation(rUri, { accept: 'application/pdf' });\n * ```\n */\n async getResourceRepresentation(\n resourceUri: ResourceUri,\n options?: { accept?: ContentFormat }\n ): Promise<{ data: ArrayBuffer; contentType: string }> {\n // resourceUri is already a full URI, use it directly with Accept header\n const response = await this.http.get(resourceUri, {\n headers: {\n Accept: options?.accept || 'text/plain'\n }\n });\n\n const contentType = response.headers.get('content-type') || 'application/octet-stream';\n const data = await response.arrayBuffer();\n\n return { data, contentType };\n }\n\n /**\n * Get resource representation as a stream using W3C content negotiation\n * Returns streaming binary content (for large files: videos, large PDFs, etc.)\n *\n * Use this for large files to avoid loading entire content into memory.\n * The stream is consumed incrementally and the backend connection stays open\n * until the stream is fully consumed or closed.\n *\n * @param resourceUri - Full resource URI\n * @param options - Options including Accept header for content negotiation\n * @returns Object with stream (ReadableStream) and contentType (string)\n *\n * @example\n * ```typescript\n * // Stream large file\n * const { stream, contentType } = await client.getResourceRepresentationStream(rUri, {\n * accept: 'video/mp4'\n * });\n *\n * // Consume stream chunk by chunk (never loads entire file into memory)\n * for await (const chunk of stream) {\n * // Process chunk\n * console.log(`Received ${chunk.length} bytes`);\n * }\n *\n * // Or pipe to a file in Node.js\n * const fileStream = fs.createWriteStream('output.mp4');\n * const reader = stream.getReader();\n * while (true) {\n * const { done, value } = await reader.read();\n * if (done) break;\n * fileStream.write(value);\n * }\n * ```\n */\n async getResourceRepresentationStream(\n resourceUri: ResourceUri,\n options?: { accept?: ContentFormat }\n ): Promise<{ stream: ReadableStream<Uint8Array>; contentType: string }> {\n // resourceUri is already a full URI, use it directly with Accept header\n const response = await this.http.get(resourceUri, {\n headers: {\n Accept: options?.accept || 'text/plain'\n }\n });\n\n const contentType = response.headers.get('content-type') || 'application/octet-stream';\n\n if (!response.body) {\n throw new Error('Response body is null - cannot create stream');\n }\n\n return { stream: response.body, contentType };\n }\n\n async listResources(\n limit?: number,\n archived?: boolean,\n query?: SearchQuery\n ): Promise<ResponseContent<paths['/resources']['get']>> {\n const searchParams = new URLSearchParams();\n if (limit) searchParams.append('limit', limit.toString());\n if (archived !== undefined) searchParams.append('archived', archived.toString());\n if (query) searchParams.append('q', query);\n\n return this.http.get(`${this.baseUrl}/resources`, { searchParams }).json();\n }\n\n async updateResource(\n resourceUri: ResourceUri,\n data: RequestContent<paths['/resources/{id}']['patch']>\n ): Promise<ResponseContent<paths['/resources/{id}']['patch']>> {\n // resourceUri is already a full URI, use it directly\n return this.http.patch(resourceUri, { json: data }).json();\n }\n\n async getResourceEvents(resourceUri: ResourceUri): Promise<{ events: any[] }> {\n // resourceUri is already a full URI, use it directly\n return this.http.get(`${resourceUri}/events`).json();\n }\n\n async getResourceAnnotations(\n resourceUri: ResourceUri\n ): Promise<ResponseContent<paths['/resources/{id}/annotations']['get']>> {\n // resourceUri is already a full URI, use it directly\n return this.http.get(`${resourceUri}/annotations`).json();\n }\n\n async getAnnotationLLMContext(\n resourceUri: ResourceUri,\n annotationId: string,\n options?: { contextWindow?: number }\n ): Promise<ResponseContent<paths['/resources/{resourceId}/annotations/{annotationId}/llm-context']['get']>> {\n const searchParams = new URLSearchParams();\n if (options?.contextWindow) {\n searchParams.append('contextWindow', options.contextWindow.toString());\n }\n // resourceUri is already a full URI, use it directly\n return this.http.get(\n `${resourceUri}/annotations/${annotationId}/llm-context`,\n { searchParams }\n ).json();\n }\n\n async getResourceReferencedBy(resourceUri: ResourceUri): Promise<{ referencedBy: any[] }> {\n // resourceUri is already a full URI, use it directly\n return this.http.get(`${resourceUri}/referenced-by`).json();\n }\n\n async generateCloneToken(resourceUri: ResourceUri): Promise<ResponseContent<paths['/resources/{id}/clone-with-token']['post']>> {\n // resourceUri is already a full URI, use it directly\n return this.http.post(`${resourceUri}/clone-with-token`).json();\n }\n\n async getResourceByToken(token: CloneToken): Promise<ResponseContent<paths['/api/resources/token/{token}']['get']>> {\n return this.http.get(`${this.baseUrl}/api/resources/token/${token}`).json();\n }\n\n async createResourceFromToken(\n data: RequestContent<paths['/api/resources/create-from-token']['post']>\n ): Promise<ResponseContent<paths['/api/resources/create-from-token']['post']>> {\n return this.http.post(`${this.baseUrl}/api/resources/create-from-token`, { json: data }).json();\n }\n\n // ============================================================================\n // ANNOTATIONS\n // ============================================================================\n\n async createAnnotation(\n resourceUri: ResourceUri,\n data: RequestContent<paths['/resources/{id}/annotations']['post']>\n ): Promise<ResponseContent<paths['/resources/{id}/annotations']['post']>> {\n // resourceUri is already a full URI, use it directly\n return this.http.post(`${resourceUri}/annotations`, { json: data }).json();\n }\n\n async getAnnotation(annotationUri: AnnotationUri): Promise<ResponseContent<paths['/annotations/{id}']['get']>> {\n // annotationUri is already a full URI, use it directly\n return this.http.get(annotationUri).json();\n }\n\n async getResourceAnnotation(annotationUri: ResourceAnnotationUri): Promise<ResponseContent<paths['/resources/{resourceId}/annotations/{annotationId}']['get']>> {\n // annotationUri is already a full URI, use it directly\n return this.http.get(annotationUri).json();\n }\n\n async listAnnotations(\n resourceUri: ResourceUri,\n motivation?: Motivation\n ): Promise<ResponseContent<paths['/resources/{id}/annotations']['get']>> {\n const searchParams = new URLSearchParams();\n if (motivation) searchParams.append('motivation', motivation);\n\n // resourceUri is already a full URI, use it directly\n return this.http.get(`${resourceUri}/annotations`, { searchParams }).json();\n }\n\n async deleteAnnotation(annotationUri: ResourceAnnotationUri): Promise<void> {\n // annotationUri is already a full URI, use it directly\n await this.http.delete(annotationUri);\n }\n\n async updateAnnotationBody(\n annotationUri: ResourceAnnotationUri,\n data: RequestContent<paths['/resources/{resourceId}/annotations/{annotationId}/body']['put']>\n ): Promise<ResponseContent<paths['/resources/{resourceId}/annotations/{annotationId}/body']['put']>> {\n // annotationUri is already a full URI, use it directly\n return this.http.put(`${annotationUri}/body`, {\n json: data,\n }).json();\n }\n\n async getAnnotationHistory(\n annotationUri: ResourceAnnotationUri\n ): Promise<ResponseContent<paths['/resources/{resourceId}/annotations/{annotationId}/history']['get']>> {\n // annotationUri is already a full URI, use it directly\n return this.http.get(`${annotationUri}/history`).json();\n }\n\n // ============================================================================\n // ENTITY TYPES\n // ============================================================================\n\n async addEntityType(type: EntityType): Promise<ResponseContent<paths['/api/entity-types']['post']>> {\n return this.http.post(`${this.baseUrl}/api/entity-types`, { json: { type } }).json();\n }\n\n async addEntityTypesBulk(types: EntityType[]): Promise<ResponseContent<paths['/api/entity-types/bulk']['post']>> {\n return this.http.post(`${this.baseUrl}/api/entity-types/bulk`, { json: { tags: types } }).json();\n }\n\n async listEntityTypes(): Promise<ResponseContent<paths['/api/entity-types']['get']>> {\n return this.http.get(`${this.baseUrl}/api/entity-types`).json();\n }\n\n // ============================================================================\n // ADMIN\n // ============================================================================\n\n async listUsers(): Promise<ResponseContent<paths['/api/admin/users']['get']>> {\n return this.http.get(`${this.baseUrl}/api/admin/users`).json();\n }\n\n async getUserStats(): Promise<ResponseContent<paths['/api/admin/users/stats']['get']>> {\n return this.http.get(`${this.baseUrl}/api/admin/users/stats`).json();\n }\n\n /**\n * Update a user by ID\n * Note: Users use DID identifiers (did:web:domain:users:id), not HTTP URIs.\n */\n async updateUser(\n id: UserDID,\n data: RequestContent<paths['/api/admin/users/{id}']['patch']>\n ): Promise<ResponseContent<paths['/api/admin/users/{id}']['patch']>> {\n return this.http.patch(`${this.baseUrl}/api/admin/users/${id}`, { json: data }).json();\n }\n\n async getOAuthConfig(): Promise<ResponseContent<paths['/api/admin/oauth/config']['get']>> {\n return this.http.get(`${this.baseUrl}/api/admin/oauth/config`).json();\n }\n\n // ============================================================================\n // JOB STATUS\n // ============================================================================\n\n async getJobStatus(id: JobId): Promise<ResponseContent<paths['/api/jobs/{id}']['get']>> {\n return this.http.get(`${this.baseUrl}/api/jobs/${id}`).json();\n }\n\n /**\n * Poll a job until it completes or fails\n * @param id - The job ID to poll\n * @param options - Polling options\n * @returns The final job status\n */\n async pollJobUntilComplete(\n id: JobId,\n options?: {\n interval?: number; // Milliseconds between polls (default: 1000)\n timeout?: number; // Total timeout in milliseconds (default: 60000)\n onProgress?: (status: ResponseContent<paths['/api/jobs/{id}']['get']>) => void;\n }\n ): Promise<ResponseContent<paths['/api/jobs/{id}']['get']>> {\n const interval = options?.interval ?? 1000;\n const timeout = options?.timeout ?? 60000;\n const startTime = Date.now();\n\n while (true) {\n const status = await this.getJobStatus(id);\n\n // Call progress callback if provided\n if (options?.onProgress) {\n options.onProgress(status);\n }\n\n // Check if job is in a terminal state\n if (status.status === 'complete' || status.status === 'failed' || status.status === 'cancelled') {\n return status;\n }\n\n // Check timeout\n if (Date.now() - startTime > timeout) {\n throw new Error(`Job polling timeout after ${timeout}ms`);\n }\n\n // Wait before next poll\n await new Promise(resolve => setTimeout(resolve, interval));\n }\n }\n\n // ============================================================================\n // LLM CONTEXT\n // ============================================================================\n\n async getResourceLLMContext(\n resourceUri: ResourceUri,\n options?: {\n depth?: number;\n maxResources?: number;\n includeContent?: boolean;\n includeSummary?: boolean;\n }\n ): Promise<ResponseContent<paths['/resources/{id}/llm-context']['get']>> {\n const searchParams = new URLSearchParams();\n if (options?.depth !== undefined) searchParams.append('depth', options.depth.toString());\n if (options?.maxResources !== undefined) searchParams.append('maxResources', options.maxResources.toString());\n if (options?.includeContent !== undefined) searchParams.append('includeContent', options.includeContent.toString());\n if (options?.includeSummary !== undefined) searchParams.append('includeSummary', options.includeSummary.toString());\n\n return this.http.get(`${resourceUri}/llm-context`, { searchParams }).json();\n }\n\n // ============================================================================\n // SYSTEM STATUS\n // ============================================================================\n\n async healthCheck(): Promise<ResponseContent<paths['/api/health']['get']>> {\n return this.http.get(`${this.baseUrl}/api/health`).json();\n }\n\n async getStatus(): Promise<ResponseContent<paths['/api/status']['get']>> {\n return this.http.get(`${this.baseUrl}/api/status`).json();\n }\n}\n","/**\n * Branded string types for compile-time type safety\n *\n * These types are zero-cost at runtime but prevent mixing\n * different string types at compile time.\n */\n\nimport type { components } from './types';\n\n// ============================================================================\n// OPENAPI-GENERATED TYPES (use directly from spec)\n// ============================================================================\n\nexport type Motivation = components['schemas']['Motivation'];\nexport type ContentFormat = components['schemas']['ContentFormat'];\n\n// ============================================================================\n// AUTHENTICATION & TOKENS\n// ============================================================================\n\nexport type Email = string & { readonly __brand: 'Email' };\nexport type AuthCode = string & { readonly __brand: 'AuthCode' };\nexport type GoogleCredential = string & { readonly __brand: 'GoogleCredential' };\nexport type AccessToken = string & { readonly __brand: 'AccessToken' };\nexport type RefreshToken = string & { readonly __brand: 'RefreshToken' };\nexport type MCPToken = string & { readonly __brand: 'MCPToken' };\nexport type CloneToken = string & { readonly __brand: 'CloneToken' };\n\n// ============================================================================\n// SYSTEM IDENTIFIERS\n// ============================================================================\n\nexport type JobId = string & { readonly __brand: 'JobId' };\nexport type UserDID = string & { readonly __brand: 'UserDID' };\nexport type EntityType = string & { readonly __brand: 'EntityType' };\nexport type SearchQuery = string & { readonly __brand: 'SearchQuery' };\nexport type BaseUrl = string & { readonly __brand: 'BaseUrl' };\n\n// ============================================================================\n// HELPER FUNCTIONS (minimal validation, just branding)\n// ============================================================================\n\nexport function email(value: string): Email { return value as Email; }\nexport function authCode(value: string): AuthCode { return value as AuthCode; }\nexport function googleCredential(value: string): GoogleCredential { return value as GoogleCredential; }\nexport function accessToken(value: string): AccessToken { return value as AccessToken; }\nexport function refreshToken(value: string): RefreshToken { return value as RefreshToken; }\nexport function mcpToken(value: string): MCPToken { return value as MCPToken; }\nexport function cloneToken(value: string): CloneToken { return value as CloneToken; }\nexport function jobId(value: string): JobId { return value as JobId; }\nexport function userDID(value: string): UserDID { return value as UserDID; }\nexport function entityType(value: string): EntityType { return value as EntityType; }\nexport function searchQuery(value: string): SearchQuery { return value as SearchQuery; }\nexport function baseUrl(value: string): BaseUrl { return value as BaseUrl; }\n\n// Motivation and ContentFormat use OpenAPI enums - no helpers needed\n// Use the enum values directly from the OpenAPI spec\n\n// ============================================================================\n// HTTP URI TYPES\n// ============================================================================\n\n// Branded type definitions for HTTP URIs returned by the API\nexport type ResourceUri = string & { readonly __brand: 'ResourceUri' };\n\n// W3C flat format for content negotiation: http://localhost:4000/annotations/{id}\nexport type AnnotationUri = string & { readonly __brand: 'AnnotationUri' };\n\n// Nested format for CRUD operations: http://localhost:4000/resources/{resourceId}/annotations/{annotationId}\nexport type ResourceAnnotationUri = string & { readonly __brand: 'ResourceAnnotationUri' };\n\n// Factory functions with runtime validation\nexport function resourceUri(uri: string): ResourceUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected ResourceUri, got: ${uri}`);\n }\n return uri as ResourceUri;\n}\n\nexport function annotationUri(uri: string): AnnotationUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected AnnotationUri, got: ${uri}`);\n }\n return uri as AnnotationUri;\n}\n\nexport function resourceAnnotationUri(uri: string): ResourceAnnotationUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected ResourceAnnotationUri, got: ${uri}`);\n }\n // Additional validation: must contain /resources/ and /annotations/\n if (!uri.includes('/resources/') || !uri.includes('/annotations/')) {\n throw new TypeError(`Expected nested ResourceAnnotationUri format, got: ${uri}`);\n }\n return uri as ResourceAnnotationUri;\n}\n","/**\n * Annotation and Selector Utilities\n *\n * Pure TypeScript utilities for working with W3C Web Annotations.\n * No React dependencies - safe to use in any JavaScript environment.\n *\n * Body is either empty array (stub) or single SpecificResource (resolved)\n * Body can be array of TextualBody (tagging) + SpecificResource (linking)\n * Target can be simple string IRI or object with source and optional selector\n */\n\nimport type { components } from '../types';\nimport type { ResourceUri } from '../branded-types';\nimport { resourceUri } from '../branded-types';\n\ntype Annotation = components['schemas']['Annotation'];\ntype HighlightAnnotation = Annotation;\ntype ReferenceAnnotation = Annotation;\ntype TextPositionSelector = components['schemas']['TextPositionSelector'];\ntype TextQuoteSelector = components['schemas']['TextQuoteSelector'];\ntype SvgSelector = components['schemas']['SvgSelector'];\ntype Selector = TextPositionSelector | TextQuoteSelector | SvgSelector;\n\n// Re-export selector types for convenience\nexport type { TextPositionSelector, TextQuoteSelector, SvgSelector, Selector };\n\n/**\n * Get the source from an annotation body (null if stub)\n * Search for SpecificResource in body array\n */\nexport function getBodySource(body: Annotation['body']): ResourceUri | null {\n if (Array.isArray(body)) {\n // Search for SpecificResource with source\n for (const item of body) {\n if (\n typeof item === 'object' &&\n item !== null &&\n 'type' in item &&\n 'source' in item\n ) {\n const itemType = (item as { type: unknown }).type;\n const itemSource = (item as { source: unknown }).source;\n\n if (itemType === 'SpecificResource' && typeof itemSource === 'string') {\n return resourceUri(itemSource);\n }\n }\n }\n return null; // No SpecificResource found = stub\n }\n\n // Single body object (SpecificResource)\n if (\n typeof body === 'object' &&\n body !== null &&\n 'type' in body &&\n 'source' in body\n ) {\n const bodyType = (body as { type: unknown }).type;\n const bodySource = (body as { source: unknown }).source;\n\n if (bodyType === 'SpecificResource' && typeof bodySource === 'string') {\n return resourceUri(bodySource);\n }\n }\n\n return null;\n}\n\n/**\n * Get the type from an annotation body (returns first body type in array)\n */\nexport function getBodyType(body: Annotation['body']): 'TextualBody' | 'SpecificResource' | null {\n if (Array.isArray(body)) {\n if (body.length === 0) {\n return null;\n }\n // Return type of first body item\n if (typeof body[0] === 'object' && body[0] !== null && 'type' in body[0]) {\n const firstType = (body[0] as { type: unknown }).type;\n if (firstType === 'TextualBody' || firstType === 'SpecificResource') {\n return firstType;\n }\n }\n return null;\n }\n\n // Single body object\n if (typeof body === 'object' && body !== null && 'type' in body) {\n const bodyType = (body as { type: unknown }).type;\n if (bodyType === 'TextualBody' || bodyType === 'SpecificResource') {\n return bodyType;\n }\n }\n\n return null;\n}\n\n/**\n * Check if body is resolved (has a source)\n * Check for SpecificResource in body array\n */\nexport function isBodyResolved(body: Annotation['body']): boolean {\n return getBodySource(body) !== null;\n}\n\n/**\n * Get the source IRI from target (handles both string and object forms)\n */\nexport function getTargetSource(target: Annotation['target']): ResourceUri {\n if (typeof target === 'string') {\n return resourceUri(target);\n }\n return resourceUri(target.source);\n}\n\n/**\n * Get the selector from target (undefined if string or no selector)\n */\nexport function getTargetSelector(target: Annotation['target']) {\n if (typeof target === 'string') {\n return undefined;\n }\n return target.selector;\n}\n\n/**\n * Check if target has a selector\n */\nexport function hasTargetSelector(target: Annotation['target']): boolean {\n return typeof target !== 'string' && target.selector !== undefined;\n}\n\n/**\n * Extract entity types from annotation bodies\n * Entity types are stored as TextualBody with purpose: \"tagging\"\n * Accepts any object with a body property matching Annotation['body']\n */\nexport function getEntityTypes(annotation: { body: Annotation['body'] }): string[] {\n // Extract from TextualBody bodies with purpose: \"tagging\"\n if (Array.isArray(annotation.body)) {\n const entityTags: string[] = [];\n\n for (const item of annotation.body) {\n // Runtime check for TextualBody with tagging purpose\n // TypeScript incorrectly narrows the union type here, so we use runtime checks only\n if (\n typeof item === 'object' &&\n item !== null &&\n 'type' in item &&\n 'value' in item &&\n 'purpose' in item\n ) {\n // Access properties as unknown first to avoid TypeScript narrowing issues\n const itemType = (item as { type: unknown }).type;\n const itemValue = (item as { value: unknown }).value;\n const itemPurpose = (item as { purpose: unknown }).purpose;\n\n if (itemType === 'TextualBody' && itemPurpose === 'tagging' && typeof itemValue === 'string' && itemValue.length > 0) {\n entityTags.push(itemValue);\n }\n }\n }\n\n return entityTags;\n }\n\n return [];\n}\n\n/**\n * Type guard to check if an annotation is a highlight\n */\nexport function isHighlight(annotation: Annotation): annotation is HighlightAnnotation {\n return annotation.motivation === 'highlighting';\n}\n\n/**\n * Type guard to check if an annotation is a reference (linking)\n */\nexport function isReference(annotation: Annotation): annotation is ReferenceAnnotation {\n return annotation.motivation === 'linking';\n}\n\n/**\n * Type guard to check if an annotation is an assessment\n */\nexport function isAssessment(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'assessing';\n}\n\n/**\n * Type guard to check if an annotation is a comment\n */\nexport function isComment(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'commenting';\n}\n\n/**\n * Type guard to check if an annotation is a tag\n */\nexport function isTag(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'tagging';\n}\n\n/**\n * Extract comment text from a comment annotation's body\n * @param annotation - The annotation to extract comment text from\n * @returns The comment text, or undefined if not a comment or no text found\n */\nexport function getCommentText(annotation: Annotation): string | undefined {\n if (!isComment(annotation)) return undefined;\n const body = Array.isArray(annotation.body) ? annotation.body[0] : annotation.body;\n if (body && 'value' in body) {\n return body.value;\n }\n return undefined;\n}\n\n/**\n * Extract tag category from a tag annotation's body\n * Tags use dual-body structure: first body has purpose: \"tagging\" with category value\n * @param annotation - The annotation to extract category from\n * @returns The tag category (e.g., \"Issue\", \"Rule\"), or undefined if not a tag or no category found\n */\nexport function getTagCategory(annotation: Annotation): string | undefined {\n if (!isTag(annotation)) return undefined;\n const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];\n const taggingBody = bodies.find(b => b && 'purpose' in b && b.purpose === 'tagging');\n if (taggingBody && 'value' in taggingBody) {\n return taggingBody.value;\n }\n return undefined;\n}\n\n/**\n * Extract tag schema ID from a tag annotation's body\n * Tags use dual-body structure: second body has purpose: \"classifying\" with schema ID\n * @param annotation - The annotation to extract schema ID from\n * @returns The schema ID (e.g., \"legal-irac\"), or undefined if not a tag or no schema found\n */\nexport function getTagSchemaId(annotation: Annotation): string | undefined {\n if (!isTag(annotation)) return undefined;\n const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];\n const classifyingBody = bodies.find(b => b && 'purpose' in b && b.purpose === 'classifying');\n if (classifyingBody && 'value' in classifyingBody) {\n return classifyingBody.value;\n }\n return undefined;\n}\n\n/**\n * Type guard to check if a reference annotation is a stub (unresolved)\n * Stub if no SpecificResource in body array\n */\nexport function isStubReference(annotation: Annotation): boolean {\n return isReference(annotation) && !isBodyResolved(annotation.body);\n}\n\n/**\n * Type guard to check if a reference annotation is resolved\n * Resolved if SpecificResource exists in body array\n */\nexport function isResolvedReference(annotation: Annotation): annotation is ReferenceAnnotation {\n return isReference(annotation) && isBodyResolved(annotation.body);\n}\n\n// =============================================================================\n// SELECTOR UTILITIES\n// =============================================================================\n\n/**\n * Get the exact text from a selector (single or array)\n *\n * When selector is an array, tries to find a TextQuoteSelector (which has exact text).\n * TextPositionSelector does not have exact text, only character offsets.\n * Handles undefined selector (when target is a string IRI with no selector)\n */\nexport function getExactText(selector: Selector | Selector[] | undefined): string {\n if (!selector) {\n return ''; // No selector means entire resource\n }\n const selectors = Array.isArray(selector) ? selector : [selector];\n\n // Try to find TextQuoteSelector (has exact text)\n const quoteSelector = selectors.find(s => s.type === 'TextQuoteSelector') as TextQuoteSelector | undefined;\n if (quoteSelector) {\n return quoteSelector.exact;\n }\n\n // No TextQuoteSelector found\n return '';\n}\n\n/**\n * Get the exact text from an annotation's target selector\n * Uses getTargetSelector helper to safely get selector\n */\nexport function getAnnotationExactText(annotation: Annotation): string {\n const selector = getTargetSelector(annotation.target);\n return getExactText(selector as Selector | Selector[] | undefined);\n}\n\n/**\n * Get the primary selector from a selector (single or array)\n *\n * When selector is an array, returns the first selector.\n * When selector is a single object, returns it as-is.\n */\nexport function getPrimarySelector(selector: Selector | Selector[]): Selector {\n if (Array.isArray(selector)) {\n if (selector.length === 0) {\n throw new Error('Empty selector array');\n }\n const first = selector[0];\n if (!first) {\n throw new Error('Invalid selector array');\n }\n return first;\n }\n return selector;\n}\n\n/**\n * Get TextPositionSelector from a selector (single or array)\n *\n * Returns the first TextPositionSelector found, or null if none exists.\n * Handles undefined selector (when target is a string IRI with no selector)\n */\nexport function getTextPositionSelector(selector: Selector | Selector[] | undefined): TextPositionSelector | null {\n if (!selector) return null; // No selector means entire resource\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'TextPositionSelector');\n if (!found) return null;\n return found.type === 'TextPositionSelector' ? found : null;\n}\n\n/**\n * Get TextQuoteSelector from a selector (single or array)\n *\n * Returns the first TextQuoteSelector found, or null if none exists.\n */\nexport function getTextQuoteSelector(selector: Selector | Selector[]): TextQuoteSelector | null {\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'TextQuoteSelector');\n if (!found) return null;\n return found.type === 'TextQuoteSelector' ? found : null;\n}\n\n/**\n * Get SvgSelector from a selector (single or array)\n *\n * Returns the first SvgSelector found, or null if none exists.\n */\nexport function getSvgSelector(selector: Selector | Selector[] | undefined): SvgSelector | null {\n if (!selector) return null;\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'SvgSelector');\n if (!found) return null;\n return found.type === 'SvgSelector' ? found : null;\n}\n\n/**\n * Validate SVG markup for W3C compliance\n *\n * Checks that:\n * - SVG contains xmlns attribute\n * - SVG is well-formed XML\n * - SVG contains at least one shape element\n *\n * @returns null if valid, error message if invalid\n */\nexport function validateSvgMarkup(svg: string): string | null {\n // Check for xmlns attribute (required by W3C spec)\n if (!svg.includes('xmlns=\"http://www.w3.org/2000/svg\"')) {\n return 'SVG must include xmlns=\"http://www.w3.org/2000/svg\" attribute';\n }\n\n // Check for basic SVG tag structure\n if (!svg.includes('<svg') || !svg.includes('</svg>')) {\n return 'SVG must have opening and closing tags';\n }\n\n // Check for at least one shape element\n const shapeElements = ['rect', 'circle', 'ellipse', 'polygon', 'polyline', 'path', 'line'];\n const hasShape = shapeElements.some(shape =>\n svg.includes(`<${shape}`) || svg.includes(`<${shape} `)\n );\n\n if (!hasShape) {\n return 'SVG must contain at least one shape element (rect, circle, ellipse, polygon, polyline, path, or line)';\n }\n\n return null; // Valid\n}\n\n/**\n * Extract bounding box from SVG markup\n *\n * Attempts to extract x, y, width, height from the SVG viewBox or root element.\n * Returns null if bounding box cannot be determined.\n */\nexport function extractBoundingBox(svg: string): { x: number; y: number; width: number; height: number } | null {\n // Try to extract viewBox attribute from SVG element\n const viewBoxMatch = svg.match(/<svg[^>]*viewBox=\"([^\"]+)\"/);\n if (viewBoxMatch) {\n const values = viewBoxMatch[1].split(/\\s+/).map(parseFloat);\n if (values.length === 4 && values.every(v => !isNaN(v))) {\n return {\n x: values[0],\n y: values[1],\n width: values[2],\n height: values[3]\n };\n }\n }\n\n // Try to extract width/height attributes from SVG element (assume x=0, y=0)\n const svgTagMatch = svg.match(/<svg[^>]*>/);\n if (svgTagMatch) {\n const svgTag = svgTagMatch[0];\n const widthMatch = svgTag.match(/width=\"([^\"]+)\"/);\n const heightMatch = svgTag.match(/height=\"([^\"]+)\"/);\n\n if (widthMatch && heightMatch) {\n const width = parseFloat(widthMatch[1]);\n const height = parseFloat(heightMatch[1]);\n\n if (!isNaN(width) && !isNaN(height)) {\n return { x: 0, y: 0, width, height };\n }\n }\n }\n\n return null;\n}\n","/**\n * Event Utilities\n *\n * Pure TypeScript utilities for working with resource events.\n * No React dependencies - safe to use in any JavaScript environment.\n */\n\nimport type { paths, components } from '../types';\nimport { AnnotationUri } from '../branded-types';\nimport { getExactText, getTargetSelector } from './annotations';\n\n// Extract StoredEvent type from events endpoint response\ntype EventsResponse = paths['/resources/{id}/events']['get']['responses'][200]['content']['application/json'];\nexport type StoredEvent = EventsResponse['events'][number];\nexport type ResourceEvent = StoredEvent['event'];\nexport type EventMetadata = StoredEvent['metadata'];\ntype Annotation = components['schemas']['Annotation'];\n\n// Event types\nexport type ResourceEventType =\n | 'resource.created'\n | 'resource.cloned'\n | 'resource.archived'\n | 'resource.unarchived'\n | 'annotation.added'\n | 'annotation.removed'\n | 'annotation.body.updated'\n | 'entitytag.added'\n | 'entitytag.removed'\n | 'entitytype.added' // Global entity type collection\n | 'job.started'\n | 'job.progress'\n | 'job.completed'\n | 'job.failed';\n\ntype TranslateFn = (key: string, params?: Record<string, string | number>) => string;\n\n// =============================================================================\n// EVENT TYPE GUARDS AND EXTRACTION\n// =============================================================================\n\n/**\n * Extract annotation ID from event payload\n * Returns null if event is not annotation-related\n *\n * For annotation.added: extracts full URI from payload.annotation.id\n * For annotation.removed/body.updated: constructs full URI from payload.annotationId (UUID) + resourceId\n */\nexport function getAnnotationUriFromEvent(event: StoredEvent): AnnotationUri | null {\n const eventData = event.event;\n const payload = eventData.payload as any;\n\n if (!payload) {\n return null;\n }\n\n switch (eventData.type) {\n case 'annotation.added':\n // annotation.added has the full annotation object with id as full URI\n return payload.annotation?.id || null;\n\n case 'annotation.removed':\n case 'annotation.body.updated':\n // These events have annotationId (UUID only), need to construct full URI\n // Extract base URL from resourceId (format: http://host/resources/id)\n if (payload.annotationId && eventData.resourceId) {\n try {\n const resourceUri = eventData.resourceId;\n // Extract base URL by removing the /resources/{id} part\n const baseUrl = resourceUri.substring(0, resourceUri.lastIndexOf('/resources/'));\n return `${baseUrl}/annotations/${payload.annotationId}` as AnnotationUri;\n } catch (e) {\n return null;\n }\n }\n return null;\n\n default:\n return null;\n }\n}\n\n/**\n * Check if an event is related to a specific annotation\n */\nexport function isEventRelatedToAnnotation(event: StoredEvent, annotationUri: AnnotationUri): boolean {\n const eventAnnotationUri = getAnnotationUriFromEvent(event);\n return eventAnnotationUri === annotationUri;\n}\n\n/**\n * Type guard to check if event is a resource event\n */\nexport function isResourceEvent(event: any): event is StoredEvent {\n return event &&\n typeof event.event === 'object' &&\n typeof event.event.id === 'string' &&\n typeof event.event.timestamp === 'string' &&\n typeof event.event.resourceId === 'string' &&\n typeof event.event.type === 'string' &&\n typeof event.metadata === 'object' &&\n typeof event.metadata.sequenceNumber === 'number';\n}\n\n// =============================================================================\n// EVENT FORMATTING AND DISPLAY\n// =============================================================================\n\n/**\n * Format event type for display with i18n support\n */\nexport function formatEventType(type: ResourceEventType, t: TranslateFn, payload?: any): string {\n switch (type) {\n case 'resource.created':\n return t('resourceCreated');\n case 'resource.cloned':\n return t('resourceCloned');\n case 'resource.archived':\n return t('resourceArchived');\n case 'resource.unarchived':\n return t('resourceUnarchived');\n\n case 'annotation.added': {\n const motivation = payload?.annotation?.motivation;\n if (motivation === 'highlighting') return t('highlightAdded');\n if (motivation === 'linking') return t('referenceCreated');\n if (motivation === 'assessing') return t('assessmentAdded');\n return t('annotationAdded');\n }\n case 'annotation.removed': {\n return t('annotationRemoved');\n }\n case 'annotation.body.updated': {\n return t('annotationBodyUpdated');\n }\n\n case 'entitytag.added':\n return t('entitytagAdded');\n case 'entitytag.removed':\n return t('entitytagRemoved');\n case 'entitytype.added':\n return t('entitytypeAdded');\n\n case 'job.completed':\n case 'job.started':\n case 'job.progress':\n case 'job.failed':\n return t('jobEvent');\n\n default:\n const _exhaustiveCheck: never = type;\n return _exhaustiveCheck;\n }\n}\n\n/**\n * Get emoji for event type\n * For unified annotation events, pass the payload to determine motivation\n */\nexport function getEventEmoji(type: ResourceEventType, payload?: any): string {\n switch (type) {\n case 'resource.created':\n case 'resource.cloned':\n case 'resource.archived':\n case 'resource.unarchived':\n return '📄';\n\n case 'annotation.added': {\n const motivation = payload?.annotation?.motivation;\n if (motivation === 'highlighting') return '🟡';\n if (motivation === 'linking') return '🔵';\n if (motivation === 'assessing') return '🔴';\n return '📝';\n }\n case 'annotation.removed': {\n return '🗑️';\n }\n case 'annotation.body.updated': {\n return '✏️';\n }\n\n case 'entitytag.added':\n case 'entitytag.removed':\n return '🏷️';\n case 'entitytype.added':\n return '🏷️'; // Same emoji as entitytag (global entity type collection)\n\n case 'job.completed':\n return '🔗'; // Link emoji for linked document creation\n case 'job.started':\n case 'job.progress':\n return '⚙️'; // Gear for job processing\n case 'job.failed':\n return '❌'; // X mark for failed jobs\n\n default:\n const _exhaustiveCheck: never = type;\n return _exhaustiveCheck;\n }\n}\n\n/**\n * Format timestamp as relative time with i18n support\n */\nexport function formatRelativeTime(timestamp: string, t: TranslateFn): string {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return t('justNow');\n if (diffMins < 60) return t('minutesAgo', { count: diffMins });\n if (diffHours < 24) return t('hoursAgo', { count: diffHours });\n if (diffDays < 7) return t('daysAgo', { count: diffDays });\n\n return date.toLocaleDateString();\n}\n\n/**\n * Helper to truncate text for display\n */\nfunction truncateText(text: string, maxLength = 50): string {\n const trimmed = text.trim();\n return trimmed.length > maxLength ? trimmed.substring(0, maxLength) + '...' : trimmed;\n}\n\n/**\n * Get display content from event payload - complete implementation\n */\nexport function getEventDisplayContent(\n event: StoredEvent,\n annotations: Annotation[], // Unified annotations array (all types)\n allEvents: StoredEvent[]\n): { exact: string; isQuoted: boolean; isTag: boolean } | null {\n const eventData = event.event;\n const payload = eventData.payload as any;\n\n // Use type discriminators instead of runtime typeof checks\n switch (eventData.type) {\n case 'resource.created':\n case 'resource.cloned': {\n return { exact: payload.name, isQuoted: false, isTag: false };\n }\n\n // Unified annotation events\n case 'annotation.body.updated': {\n // Find current annotation to get its text\n // payload.annotationId is just the UUID, but annotation.id is the full URI\n const annotation = annotations.find(a =>\n a.id.endsWith(`/annotations/${payload.annotationId}`)\n );\n\n if (annotation?.target) {\n try {\n const targetSelector = getTargetSelector(annotation.target);\n const exact = getExactText(targetSelector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, continue to return null\n }\n }\n return null;\n }\n\n case 'annotation.removed': {\n // Find the original annotation.added event to get the text\n // payload.annotationId is just the UUID, but annotation.id in the added event is the full URI\n const addedEvent = allEvents.find(e =>\n e.event.type === 'annotation.added' &&\n (e.event.payload as any).annotation?.id?.endsWith(`/annotations/${payload.annotationId}`)\n );\n if (addedEvent) {\n const addedPayload = addedEvent.event.payload as any;\n try {\n const exact = getExactText(addedPayload.annotation.target.selector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, return null\n }\n }\n return null;\n }\n\n case 'annotation.added': {\n // New unified event structure - annotation is in payload\n try {\n const exact = getExactText(payload.annotation.target.selector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, return null\n }\n return null;\n }\n\n case 'entitytag.added':\n case 'entitytag.removed': {\n return { exact: payload.entityType, isQuoted: false, isTag: true };\n }\n\n case 'job.completed': {\n // Find the annotation that was used to generate the resource\n if (payload.annotationUri) {\n const annotation = annotations.find(a =>\n a.id === payload.annotationUri\n );\n\n if (annotation?.target) {\n try {\n const targetSelector = getTargetSelector(annotation.target);\n const exact = getExactText(targetSelector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, continue to return null\n }\n }\n }\n return null;\n }\n\n default:\n return null;\n }\n}\n\n/**\n * Get entity types from event payload\n */\nexport function getEventEntityTypes(event: StoredEvent): string[] {\n const eventData = event.event;\n\n if (eventData.type === 'annotation.added') {\n const payload = eventData.payload as any;\n const motivation = payload?.annotation?.motivation;\n if (motivation === 'linking') {\n return payload.annotation?.body?.entityTypes ?? [];\n }\n }\n\n return [];\n}\n\n/**\n * Resource creation details\n */\nexport interface ResourceCreationDetails {\n type: 'created' | 'cloned';\n method: string;\n userId?: string;\n sourceDocId?: string; // For cloned resources\n parentResourceId?: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * Get resource creation details from event\n */\nexport function getResourceCreationDetails(event: StoredEvent): ResourceCreationDetails | null {\n const eventData = event.event;\n const payload = eventData.payload as any;\n\n if (eventData.type === 'resource.created') {\n return {\n type: 'created',\n method: payload.creationMethod || 'unknown',\n userId: eventData.userId,\n metadata: payload.metadata,\n };\n }\n\n if (eventData.type === 'resource.cloned') {\n return {\n type: 'cloned',\n method: payload.creationMethod || 'clone',\n userId: eventData.userId,\n sourceDocId: payload.parentResourceId,\n parentResourceId: payload.parentResourceId,\n metadata: payload.metadata,\n };\n }\n\n return null;\n}\n","/**\n * Fuzzy Anchoring for W3C Web Annotation TextQuoteSelector\n *\n * Uses prefix/suffix context to disambiguate when the same text appears multiple times.\n * Implements fuzzy matching as specified in the W3C Web Annotation Data Model.\n *\n * @see https://www.w3.org/TR/annotation-model/#text-quote-selector\n */\n\nexport interface TextPosition {\n start: number;\n end: number;\n}\n\n/**\n * Find text using exact match with optional prefix/suffix context\n *\n * When the exact text appears multiple times in the content, prefix and suffix\n * are used to disambiguate and find the correct occurrence.\n *\n * @param content - Full text content to search within\n * @param exact - The exact text to find\n * @param prefix - Optional text that should appear immediately before the match\n * @param suffix - Optional text that should appear immediately after the match\n * @returns Position of the matched text, or null if not found\n *\n * @example\n * ```typescript\n * const content = \"The cat sat. The cat ran.\";\n * // Find second \"The cat\" occurrence\n * const pos = findTextWithContext(content, \"The cat\", \"sat. \", \" ran\");\n * // Returns { start: 13, end: 20 }\n * ```\n */\nexport function findTextWithContext(\n content: string,\n exact: string,\n prefix?: string,\n suffix?: string\n): TextPosition | null {\n if (!exact) return null;\n\n // Find all occurrences of exact text\n const occurrences: number[] = [];\n let index = content.indexOf(exact);\n while (index !== -1) {\n occurrences.push(index);\n index = content.indexOf(exact, index + 1);\n }\n\n // No matches found\n if (occurrences.length === 0) {\n console.warn(`[FuzzyAnchor] Text not found: \"${exact.substring(0, 50)}...\"`);\n return null;\n }\n\n // Only one match - no need for prefix/suffix disambiguation\n if (occurrences.length === 1) {\n const pos = occurrences[0]!; // Safe: length === 1 means first element exists\n return { start: pos, end: pos + exact.length };\n }\n\n // Multiple matches - use prefix/suffix to disambiguate\n if (prefix || suffix) {\n for (const pos of occurrences) {\n // Extract actual prefix from content\n const actualPrefixStart = Math.max(0, pos - (prefix?.length || 0));\n const actualPrefix = content.substring(actualPrefixStart, pos);\n\n // Extract actual suffix from content\n const actualSuffixEnd = Math.min(content.length, pos + exact.length + (suffix?.length || 0));\n const actualSuffix = content.substring(pos + exact.length, actualSuffixEnd);\n\n // Check if prefix matches\n const prefixMatch = !prefix || actualPrefix.endsWith(prefix);\n\n // Check if suffix matches\n const suffixMatch = !suffix || actualSuffix.startsWith(suffix);\n\n if (prefixMatch && suffixMatch) {\n return { start: pos, end: pos + exact.length };\n }\n }\n\n // No match with exact prefix/suffix - try fuzzy matching\n console.warn(\n `[FuzzyAnchor] Multiple matches found but none match prefix/suffix exactly. ` +\n `Exact: \"${exact.substring(0, 30)}...\", ` +\n `Prefix: \"${prefix?.substring(0, 20) || 'none'}\", ` +\n `Suffix: \"${suffix?.substring(0, 20) || 'none'}\"`\n );\n\n // Fallback: try partial prefix/suffix match\n for (const pos of occurrences) {\n const actualPrefix = content.substring(Math.max(0, pos - (prefix?.length || 0)), pos);\n const actualSuffix = content.substring(pos + exact.length, pos + exact.length + (suffix?.length || 0));\n\n // Fuzzy match: check if prefix/suffix are substrings (handles whitespace variations)\n const fuzzyPrefixMatch = !prefix || actualPrefix.includes(prefix.trim());\n const fuzzySuffixMatch = !suffix || actualSuffix.includes(suffix.trim());\n\n if (fuzzyPrefixMatch && fuzzySuffixMatch) {\n console.warn(`[FuzzyAnchor] Using fuzzy match at position ${pos}`);\n return { start: pos, end: pos + exact.length };\n }\n }\n }\n\n // Fallback: return first occurrence if no prefix/suffix or no match\n console.warn(\n `[FuzzyAnchor] Multiple matches but no context match. Using first occurrence. ` +\n `Exact: \"${exact.substring(0, 30)}...\"`\n );\n const pos = occurrences[0]!; // Safe: we checked length > 0 earlier\n return { start: pos, end: pos + exact.length };\n}\n\n/**\n * Verify that a position correctly points to the exact text\n * Useful for debugging and validation\n */\nexport function verifyPosition(\n content: string,\n position: TextPosition,\n expectedExact: string\n): boolean {\n const actualText = content.substring(position.start, position.end);\n return actualText === expectedExact;\n}\n","/**\n * Locale information\n * Copied from SDK for frontend use\n */\n\nexport interface LocaleInfo {\n code: string;\n nativeName: string;\n englishName: string;\n}\n\nexport const LOCALES: readonly LocaleInfo[] = [\n { code: 'ar', nativeName: 'العربية', englishName: 'Arabic' },\n { code: 'bn', nativeName: 'বাংলা', englishName: 'Bengali' },\n { code: 'cs', nativeName: 'Čeština', englishName: 'Czech' },\n { code: 'da', nativeName: 'Dansk', englishName: 'Danish' },\n { code: 'de', nativeName: 'Deutsch', englishName: 'German' },\n { code: 'el', nativeName: 'Ελληνικά', englishName: 'Greek' },\n { code: 'en', nativeName: 'English', englishName: 'English' },\n { code: 'es', nativeName: 'Español', englishName: 'Spanish' },\n { code: 'fa', nativeName: 'فارسی', englishName: 'Persian' },\n { code: 'fi', nativeName: 'Suomi', englishName: 'Finnish' },\n { code: 'fr', nativeName: 'Français', englishName: 'French' },\n { code: 'he', nativeName: 'עברית', englishName: 'Hebrew' },\n { code: 'hi', nativeName: 'हिन्दी', englishName: 'Hindi' },\n { code: 'id', nativeName: 'Bahasa Indonesia', englishName: 'Indonesian' },\n { code: 'it', nativeName: 'Italiano', englishName: 'Italian' },\n { code: 'ja', nativeName: '日本語', englishName: 'Japanese' },\n { code: 'ko', nativeName: '한국어', englishName: 'Korean' },\n { code: 'ms', nativeName: 'Bahasa Melayu', englishName: 'Malay' },\n { code: 'nl', nativeName: 'Nederlands', englishName: 'Dutch' },\n { code: 'no', nativeName: 'Norsk', englishName: 'Norwegian' },\n { code: 'pl', nativeName: 'Polski', englishName: 'Polish' },\n { code: 'pt', nativeName: 'Português', englishName: 'Portuguese' },\n { code: 'ro', nativeName: 'Română', englishName: 'Romanian' },\n { code: 'sv', nativeName: 'Svenska', englishName: 'Swedish' },\n { code: 'th', nativeName: 'ไทย', englishName: 'Thai' },\n { code: 'tr', nativeName: 'Türkçe', englishName: 'Turkish' },\n { code: 'uk', nativeName: 'Українська', englishName: 'Ukrainian' },\n { code: 'vi', nativeName: 'Tiếng Việt', englishName: 'Vietnamese' },\n { code: 'zh', nativeName: '中文', englishName: 'Chinese' },\n] as const;\n\n// Create lookup map for efficient access\nconst localeByCode = new Map<string, LocaleInfo>(\n LOCALES.map(locale => [locale.code.toLowerCase(), locale])\n);\n\n/**\n * Get locale information by code\n */\nexport function getLocaleInfo(code: string | undefined): LocaleInfo | undefined {\n if (!code) return undefined;\n return localeByCode.get(code.toLowerCase());\n}\n\n/**\n * Get the native name of a language by its locale code\n */\nexport function getLocaleNativeName(code: string | undefined): string | undefined {\n return getLocaleInfo(code)?.nativeName;\n}\n\n/**\n * Get the English name of a language by its locale code\n */\nexport function getLocaleEnglishName(code: string | undefined): string | undefined {\n return getLocaleInfo(code)?.englishName;\n}\n\n/**\n * Format locale code for display as \"Native Name (code)\"\n */\nexport function formatLocaleDisplay(code: string | undefined): string | undefined {\n if (!code) return undefined;\n\n const info = getLocaleInfo(code);\n if (!info) return code;\n\n return `${info.nativeName} (${code.toLowerCase()})`;\n}\n\n/**\n * Get all supported locale codes\n */\nexport function getAllLocaleCodes(): readonly string[] {\n return LOCALES.map(l => l.code);\n}\n","/**\n * Helper functions for working with W3C ResourceDescriptor\n */\n\nimport type { components } from '../types';\n\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\ntype Representation = components['schemas']['Representation'];\n\n/**\n * Get the resource ID from @id property\n *\n * For internal resources: extracts UUID from \"http://localhost:4000/resources/{uuid}\"\n * For external resources: returns undefined\n *\n * This is used for routing - the frontend URL should contain only the resource ID,\n * not the full HTTP URI.\n */\nexport function getResourceId(resource: ResourceDescriptor | undefined): string | undefined {\n if (!resource) return undefined;\n\n const fullId = resource['@id'];\n\n // For internal resources, extract the last path segment\n // http://localhost:4000/resources/{uuid} -> {uuid}\n if (fullId.includes('/resources/')) {\n const parts = fullId.split('/resources/');\n const lastPart = parts[parts.length - 1];\n return lastPart || undefined;\n }\n\n // For external resources, cannot extract ID\n return undefined;\n}\n\n/**\n * Get the primary representation (first or only representation)\n */\nexport function getPrimaryRepresentation(resource: ResourceDescriptor | undefined): Representation | undefined {\n if (!resource?.representations) return undefined;\n const reps = Array.isArray(resource.representations)\n ? resource.representations\n : [resource.representations];\n return reps[0];\n}\n\n/**\n * Get the media type from the primary representation\n */\nexport function getPrimaryMediaType(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.mediaType;\n}\n\n/**\n * Get the checksum from the primary representation\n */\nexport function getChecksum(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.checksum;\n}\n\n/**\n * Get the language from the primary representation\n */\nexport function getLanguage(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.language;\n}\n","/**\n * SVG Utility Functions\n *\n * Utilities for creating, parsing, and manipulating W3C-compliant SVG selectors\n * for image annotation.\n */\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface BoundingBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Create W3C-compliant SVG rectangle selector\n */\nexport function createRectangleSvg(start: Point, end: Point): string {\n const x = Math.min(start.x, end.x);\n const y = Math.min(start.y, end.y);\n const width = Math.abs(end.x - start.x);\n const height = Math.abs(end.y - start.y);\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"${x}\" y=\"${y}\" width=\"${width}\" height=\"${height}\"/></svg>`;\n}\n\n/**\n * Create W3C-compliant SVG polygon selector\n */\nexport function createPolygonSvg(points: Point[]): string {\n if (points.length < 3) {\n throw new Error('Polygon requires at least 3 points');\n }\n\n const pointsStr = points.map(p => `${p.x},${p.y}`).join(' ');\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"${pointsStr}\"/></svg>`;\n}\n\n/**\n * Create W3C-compliant SVG circle selector\n */\nexport function createCircleSvg(center: Point, radius: number): string {\n if (radius <= 0) {\n throw new Error('Circle radius must be positive');\n }\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"${center.x}\" cy=\"${center.y}\" r=\"${radius}\"/></svg>`;\n}\n\n/**\n * Parse SVG selector to extract shape type and data\n */\nexport function parseSvgSelector(svg: string): {\n type: 'rect' | 'polygon' | 'circle' | 'path';\n data: any;\n} | null {\n // Extract rectangle\n const rectMatch = svg.match(/<rect\\s+([^>]+)\\/>/);\n if (rectMatch && rectMatch[1]) {\n const attrs = rectMatch[1];\n const x = parseFloat(attrs.match(/x=\"([^\"]+)\"/)?.[1] || '0');\n const y = parseFloat(attrs.match(/y=\"([^\"]+)\"/)?.[1] || '0');\n const width = parseFloat(attrs.match(/width=\"([^\"]+)\"/)?.[1] || '0');\n const height = parseFloat(attrs.match(/height=\"([^\"]+)\"/)?.[1] || '0');\n\n return {\n type: 'rect',\n data: { x, y, width, height }\n };\n }\n\n // Extract polygon\n const polygonMatch = svg.match(/<polygon\\s+points=\"([^\"]+)\"/);\n if (polygonMatch && polygonMatch[1]) {\n const pointsStr = polygonMatch[1];\n const points = pointsStr.split(/\\s+/).map(pair => {\n const [x, y] = pair.split(',').map(parseFloat);\n return { x, y };\n });\n\n return {\n type: 'polygon',\n data: { points }\n };\n }\n\n // Extract circle\n const circleMatch = svg.match(/<circle\\s+([^>]+)\\/>/);\n if (circleMatch && circleMatch[1]) {\n const attrs = circleMatch[1];\n const cx = parseFloat(attrs.match(/cx=\"([^\"]+)\"/)?.[1] || '0');\n const cy = parseFloat(attrs.match(/cy=\"([^\"]+)\"/)?.[1] || '0');\n const r = parseFloat(attrs.match(/r=\"([^\"]+)\"/)?.[1] || '0');\n\n return {\n type: 'circle',\n data: { cx, cy, r }\n };\n }\n\n return null;\n}\n\n/**\n * Normalize coordinates from display space to image native resolution\n */\nexport function normalizeCoordinates(\n point: Point,\n displayWidth: number,\n displayHeight: number,\n imageWidth: number,\n imageHeight: number\n): Point {\n return {\n x: (point.x / displayWidth) * imageWidth,\n y: (point.y / displayHeight) * imageHeight\n };\n}\n\n/**\n * Scale entire SVG selector from display space to image native resolution\n */\nexport function scaleSvgToNative(\n svg: string,\n displayWidth: number,\n displayHeight: number,\n imageWidth: number,\n imageHeight: number\n): string {\n const parsed = parseSvgSelector(svg);\n if (!parsed) return svg;\n\n const scaleX = imageWidth / displayWidth;\n const scaleY = imageHeight / displayHeight;\n\n switch (parsed.type) {\n case 'rect': {\n const { x, y, width, height } = parsed.data;\n return createRectangleSvg(\n { x: x * scaleX, y: y * scaleY },\n { x: (x + width) * scaleX, y: (y + height) * scaleY }\n );\n }\n\n case 'circle': {\n const { cx, cy, r } = parsed.data;\n return createCircleSvg(\n { x: cx * scaleX, y: cy * scaleY },\n r * Math.min(scaleX, scaleY)\n );\n }\n\n case 'polygon': {\n const points = parsed.data.points.map((p: Point) => ({\n x: p.x * scaleX,\n y: p.y * scaleY\n }));\n return createPolygonSvg(points);\n }\n }\n\n return svg;\n}\n","/**\n * Text encoding utilities for consistent charset handling\n *\n * Ensures frontend decoding matches backend decoding by respecting\n * charset parameters in mediaType (e.g., \"text/plain; charset=iso-8859-1\")\n */\n\n/**\n * Extract charset from mediaType parameter\n *\n * @param mediaType - Media type with optional charset (e.g., \"text/plain; charset=utf-8\")\n * @returns Charset name in lowercase (defaults to \"utf-8\")\n *\n * @example\n * extractCharset(\"text/plain; charset=iso-8859-1\") // \"iso-8859-1\"\n * extractCharset(\"text/plain\") // \"utf-8\"\n */\nexport function extractCharset(mediaType: string): string {\n const charsetMatch = mediaType.match(/charset=([^\\s;]+)/i);\n return (charsetMatch?.[1] || 'utf-8').toLowerCase();\n}\n\n/**\n * Decode ArrayBuffer to string using charset from mediaType\n *\n * Uses TextDecoder with the charset extracted from mediaType parameter.\n * This ensures the same character space is used for both annotation creation\n * (backend) and rendering (frontend).\n *\n * @param buffer - Binary data to decode\n * @param mediaType - Media type with optional charset parameter\n * @returns Decoded string in the original character space\n *\n * @example\n * const buffer = new Uint8Array([...]);\n * const text = decodeWithCharset(buffer, \"text/plain; charset=iso-8859-1\");\n */\nexport function decodeWithCharset(buffer: ArrayBuffer, mediaType: string): string {\n const charset = extractCharset(mediaType);\n\n // TextDecoder supports standard charset names\n // Common mappings that work in browsers:\n // - utf-8, utf-16, utf-16le, utf-16be\n // - iso-8859-1 through iso-8859-15\n // - windows-1252, windows-1251, etc.\n const decoder = new TextDecoder(charset);\n return decoder.decode(buffer);\n}\n","/**\n * Generic validation utilities for @semiont/api-client\n *\n * Pure TypeScript validation with no external dependencies.\n * Safe to use in any JavaScript environment (Node.js, browser, Deno, etc.)\n */\n\n/**\n * Validation result types\n */\nexport type ValidationSuccess<T> = { success: true; data: T };\nexport type ValidationFailure = { success: false; error: string; details?: string[] };\nexport type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;\n\n/**\n * JWT Token validation\n *\n * Validates JWT token format (header.payload.signature).\n * Does not verify signature - use for format validation only.\n */\nexport const JWTTokenSchema = {\n parse(token: unknown): string {\n if (typeof token !== 'string') {\n throw new Error('Token must be a string');\n }\n if (!token || token.length === 0) {\n throw new Error('Token is required');\n }\n // JWT format: header.payload.signature\n const jwtRegex = /^[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]*$/;\n if (!jwtRegex.test(token)) {\n throw new Error('Invalid JWT token format');\n }\n return token;\n },\n\n safeParse(token: unknown): ValidationResult<string> {\n try {\n const validated = this.parse(token);\n return { success: true, data: validated };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Invalid JWT token',\n };\n }\n },\n};\n\n/**\n * Generic validation helper with error formatting\n *\n * Wraps any schema's parse method with try/catch and returns ValidationResult.\n *\n * @example\n * ```typescript\n * const result = validateData(JWTTokenSchema, 'eyJ...');\n * if (result.success) {\n * console.log('Valid token:', result.data);\n * } else {\n * console.error('Invalid:', result.error);\n * }\n * ```\n */\nexport function validateData<T>(\n schema: { parse(data: unknown): T },\n data: unknown\n): ValidationResult<T> {\n try {\n const validated = schema.parse(data);\n return { success: true, data: validated };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Validation failed',\n };\n }\n}\n\n/**\n * Email validation helper\n *\n * Validates email format using RFC 5322 simplified regex.\n *\n * @param email - Email address to validate\n * @returns true if valid email format\n */\nexport function isValidEmail(email: string): boolean {\n if (email.length < 1 || email.length > 255) {\n return false;\n }\n // RFC 5322 simplified email regex\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n}\n","/**\n * MIME type utilities for Semiont\n *\n * Initial support for:\n * - text/plain\n * - text/markdown\n * - image/png\n * - image/jpeg\n */\n\n/**\n * Map MIME type to file extension\n */\nexport function getExtensionForMimeType(mimeType: string): string {\n const map: Record<string, string> = {\n 'text/plain': 'txt',\n 'text/markdown': 'md',\n 'image/png': 'png',\n 'image/jpeg': 'jpg',\n };\n\n return map[mimeType] || 'dat'; // fallback to .dat for unknown types\n}\n\n/**\n * Detect if MIME type is an image (png or jpeg only for now)\n */\nexport function isImageMimeType(mimeType: string): boolean {\n return mimeType === 'image/png' || mimeType === 'image/jpeg';\n}\n\n/**\n * Detect if MIME type is text-based (plain or markdown only for now)\n */\nexport function isTextMimeType(mimeType: string): boolean {\n return mimeType === 'text/plain' || mimeType === 'text/markdown';\n}\n\n/**\n * Get category for MIME type (for routing to appropriate viewer)\n */\nexport type MimeCategory = 'text' | 'image' | 'unsupported';\n\nexport function getMimeCategory(mimeType: string): MimeCategory {\n if (isTextMimeType(mimeType)) {\n return 'text';\n }\n if (isImageMimeType(mimeType)) {\n return 'image';\n }\n return 'unsupported';\n}\n"]}
1
+ {"version":3,"sources":["../src/sse/stream.ts","../src/sse/index.ts","../src/client.ts","../src/branded-types.ts","../src/utils/annotations.ts","../src/utils/events.ts","../src/utils/fuzzy-anchor.ts","../src/utils/locales.ts","../src/utils/resources.ts","../src/utils/svg-utils.ts","../src/utils/text-context.ts","../src/utils/text-encoding.ts","../src/utils/validation.ts","../src/mime-utils.ts"],"names":["baseUrl","accessToken","email","resourceUri","annotationUri","pos","context"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * SSE Stream Factory\n *\n * Creates Server-Sent Events streams using native fetch() and manual parsing.\n * Does NOT use the EventSource API for better control over connection lifecycle.\n */\n\nimport type { SSEStream } from './types';\nimport type { Logger } from '../logger';\n\n/**\n * Configuration for SSE stream event handling\n */\ninterface SSEConfig {\n /** Event types that trigger onProgress callback */\n progressEvents: string[];\n /** Event type that triggers onComplete callback (null for long-lived streams) */\n completeEvent: string | null;\n /** Event type that triggers onError callback */\n errorEvent: string | null;\n /** If true, use custom event handlers instead of standard mapping */\n customEventHandler?: boolean;\n}\n\n/**\n * Create an SSE stream with typed event callbacks\n *\n * Uses native fetch() with manual SSE parsing for fine-grained control.\n * Supports AbortController for cancellation.\n *\n * @typeParam TProgress - Type of progress event data\n * @typeParam TComplete - Type of completion event data\n *\n * @param url - Full URL to SSE endpoint\n * @param fetchOptions - fetch() options (method, headers, body)\n * @param config - Event mapping configuration\n * @returns SSEStream controller with callback registration and cleanup\n *\n * @example\n * ```typescript\n * const stream = createSSEStream<DetectionProgress, DetectionProgress>(\n * 'http://localhost:4000/resources/123/detect-annotations-stream',\n * {\n * method: 'POST',\n * headers: { 'Authorization': 'Bearer token', 'Content-Type': 'application/json' },\n * body: JSON.stringify({ entityTypes: ['Person'] })\n * },\n * {\n * progressEvents: ['detection-started', 'detection-progress'],\n * completeEvent: 'detection-complete',\n * errorEvent: 'detection-error'\n * }\n * );\n *\n * stream.onProgress((p) => console.log(p.message));\n * stream.onComplete((r) => console.log('Done!'));\n * stream.close(); // Cleanup\n * ```\n */\nexport function createSSEStream<TProgress, TComplete>(\n url: string,\n fetchOptions: RequestInit,\n config: SSEConfig,\n logger?: Logger\n): SSEStream<TProgress, TComplete> {\n const abortController = new AbortController();\n let progressCallback: ((data: TProgress) => void) | null = null;\n let completeCallback: ((data: TComplete) => void) | null = null;\n let errorCallback: ((error: Error) => void) | null = null;\n const customHandlers = new Map<string, (data?: any) => void>();\n let closed = false; // Flag to stop processing events after close/complete/error\n\n /**\n * Start the SSE connection and parse the stream\n */\n const connect = async () => {\n try {\n // Log stream request\n logger?.debug('SSE Stream Request', {\n type: 'sse_request',\n url,\n method: fetchOptions.method || 'GET',\n timestamp: Date.now()\n });\n\n const response = await fetch(url, {\n ...fetchOptions,\n signal: abortController.signal,\n headers: {\n ...fetchOptions.headers,\n 'Accept': 'text/event-stream'\n }\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({})) as { message?: string };\n const error = new Error(errorData.message || `HTTP ${response.status}: ${response.statusText}`);\n\n // Log connection error\n logger?.error('SSE Stream Error', {\n type: 'sse_error',\n url,\n error: error.message,\n status: response.status,\n phase: 'connect'\n });\n\n throw error;\n }\n\n if (!response.body) {\n const error = new Error('Response body is null - server did not return a stream');\n\n logger?.error('SSE Stream Error', {\n type: 'sse_error',\n url,\n error: error.message,\n phase: 'connect'\n });\n\n throw error;\n }\n\n // Log successful connection\n logger?.info('SSE Stream Connected', {\n type: 'sse_connected',\n url,\n status: response.status,\n contentType: response.headers.get('content-type') || 'unknown'\n });\n\n // Parse SSE stream\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n // Event state persists across reads to handle multi-chunk events\n let eventType = '';\n let eventData = '';\n let eventId = '';\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done || closed) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n\n // Keep the last partial line in the buffer\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('event:')) {\n eventType = line.slice(6).trim();\n } else if (line.startsWith('data:')) {\n eventData = line.slice(5).trim();\n } else if (line.startsWith('id:')) {\n eventId = line.slice(3).trim();\n } else if (line === '') {\n // Empty line marks end of event\n if (eventData && !closed) {\n handleEvent(eventType, eventData, eventId);\n if (closed) break; // Stop processing if event triggered close\n eventType = '';\n eventData = '';\n eventId = '';\n }\n }\n }\n\n if (closed) break; // Exit outer loop if closed\n }\n\n // Log stream close\n logger?.info('SSE Stream Closed', {\n type: 'sse_closed',\n url,\n reason: 'complete'\n });\n } catch (error) {\n // Don't report AbortError (normal cleanup)\n if (error instanceof Error && error.name !== 'AbortError') {\n logger?.error('SSE Stream Error', {\n type: 'sse_error',\n url,\n error: error.message,\n phase: 'stream'\n });\n errorCallback?.(error);\n } else if (error instanceof Error && error.name === 'AbortError') {\n // Log normal close (abort)\n logger?.info('SSE Stream Closed', {\n type: 'sse_closed',\n url,\n reason: 'abort'\n });\n }\n }\n };\n\n /**\n * Handle a parsed SSE event\n */\n const handleEvent = (eventType: string, data: string, _id: string) => {\n // Skip keep-alive comments\n if (data.startsWith(':')) {\n return;\n }\n\n try {\n const parsed = JSON.parse(data);\n\n // Log SSE event (debug level - can be verbose)\n logger?.debug('SSE Event Received', {\n type: 'sse_event',\n url,\n event: eventType || 'message',\n hasData: !!data\n });\n\n // Custom event handler (for resourceEvents which handles all events)\n if (config.customEventHandler) {\n const handler = customHandlers.get(eventType);\n if (handler) {\n handler(parsed);\n return;\n }\n // Pass all events to progress handler if no specific handler\n progressCallback?.(parsed as TProgress);\n return;\n }\n\n // Progress events\n if (config.progressEvents.includes(eventType)) {\n progressCallback?.(parsed as TProgress);\n }\n\n // Complete event\n if (config.completeEvent && eventType === config.completeEvent) {\n completeCallback?.(parsed as TComplete);\n closed = true; // Stop processing further events\n abortController.abort(); // Close stream on completion\n }\n\n // Error event\n if (config.errorEvent && eventType === config.errorEvent) {\n errorCallback?.(new Error(parsed.message || 'Stream error'));\n closed = true; // Stop processing further events\n abortController.abort(); // Close stream on error\n }\n } catch (error) {\n console.error('[SSE] Failed to parse event data:', error);\n console.error('[SSE] Event type:', eventType);\n console.error('[SSE] Data:', data);\n }\n };\n\n // Start connection immediately\n connect();\n\n // Return SSE stream controller\n return {\n onProgress(callback) {\n progressCallback = callback;\n },\n\n onComplete(callback) {\n completeCallback = callback;\n },\n\n onError(callback) {\n errorCallback = callback;\n },\n\n close() {\n abortController.abort();\n },\n\n // Internal method for custom event handlers (used by resourceEvents)\n on(event: string, callback: (data?: any) => void) {\n customHandlers.set(event, callback);\n }\n } as SSEStream<TProgress, TComplete> & { on?: (event: string, callback: (data?: any) => void) => void };\n}\n","/**\n * SSE Client for Semiont Streaming Endpoints\n *\n * Provides type-safe methods for Server-Sent Events streaming.\n * Does NOT use ky - uses native fetch() for SSE support.\n */\n\nimport { createSSEStream } from './stream';\nimport type {\n DetectionProgress,\n GenerationProgress,\n HighlightDetectionProgress,\n AssessmentDetectionProgress,\n CommentDetectionProgress,\n TagDetectionProgress,\n ResourceEvent,\n SSEStream\n} from './types';\nimport type { ResourceUri, AnnotationUri } from '../branded-types';\nimport type { AccessToken, BaseUrl, EntityType } from '../branded-types';\nimport type { components } from '../types';\nimport type { Logger } from '../logger';\n\n/**\n * Request body for detection stream\n */\nexport interface DetectAnnotationsStreamRequest {\n entityTypes: EntityType[];\n}\n\n/**\n * Request body for generation stream\n * Uses generated type from OpenAPI schema\n */\nexport type GenerateResourceStreamRequest = components['schemas']['GenerateResourceStreamRequest'];\n\n/**\n * Request body for highlight detection stream\n */\nexport interface DetectHighlightsStreamRequest {\n instructions?: string;\n}\n\n/**\n * Request body for assessment detection stream\n */\nexport interface DetectAssessmentsStreamRequest {\n instructions?: string;\n}\n\n/**\n * Request body for comment detection stream\n */\nexport interface DetectCommentsStreamRequest {\n instructions?: string;\n tone?: 'scholarly' | 'explanatory' | 'conversational' | 'technical';\n}\n\n/**\n * Request body for tag detection stream\n */\nexport interface DetectTagsStreamRequest {\n schemaId: string;\n categories: string[];\n}\n\n/**\n * SSE Client configuration\n */\nexport interface SSEClientConfig {\n baseUrl: BaseUrl;\n accessToken?: AccessToken;\n logger?: Logger;\n}\n\n/**\n * SSE Client for real-time streaming operations\n *\n * Separate from the main HTTP client to clearly mark streaming endpoints.\n * Uses native fetch() instead of ky for SSE support.\n *\n * @example\n * ```typescript\n * const sseClient = new SSEClient({\n * baseUrl: 'http://localhost:4000',\n * accessToken: 'your-token'\n * });\n *\n * const stream = sseClient.detectAnnotations(\n * 'http://localhost:4000/resources/doc-123',\n * { entityTypes: ['Person', 'Organization'] }\n * );\n *\n * stream.onProgress((p) => console.log(p.message));\n * stream.onComplete((r) => console.log(`Found ${r.foundCount} entities`));\n * stream.onError((e) => console.error('Detection failed:', e));\n * ```\n */\nexport class SSEClient {\n private baseUrl: BaseUrl;\n private accessToken: AccessToken | null = null;\n private logger?: Logger;\n\n constructor(config: SSEClientConfig) {\n // Remove trailing slash for consistent URL construction\n this.baseUrl = (config.baseUrl.endsWith('/') ? config.baseUrl.slice(0, -1) : config.baseUrl) as BaseUrl;\n this.accessToken = config.accessToken || null;\n this.logger = config.logger;\n }\n\n /**\n * Set the access token for authenticated requests\n */\n setAccessToken(token: AccessToken): void {\n this.accessToken = token;\n }\n\n /**\n * Clear the access token\n */\n clearAccessToken(): void {\n this.accessToken = null;\n }\n\n /**\n * Get common headers for SSE requests\n */\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json'\n };\n\n if (this.accessToken) {\n headers['Authorization'] = `Bearer ${this.accessToken}`;\n }\n\n return headers;\n }\n\n /**\n * Extract resource ID from URI\n *\n * Handles both full URIs and plain IDs:\n * - 'http://localhost:4000/resources/doc-123' -> 'doc-123'\n * - 'doc-123' -> 'doc-123'\n */\n private extractId(uri: string): string {\n const parts = uri.split('/');\n return parts[parts.length - 1];\n }\n\n /**\n * Detect annotations in a resource (streaming)\n *\n * Streams entity detection progress via Server-Sent Events.\n *\n * @param resourceId - Resource URI or ID\n * @param request - Detection configuration (entity types to detect)\n * @returns SSE stream controller with progress/complete/error callbacks\n *\n * @example\n * ```typescript\n * const stream = sseClient.detectAnnotations(\n * 'http://localhost:4000/resources/doc-123',\n * { entityTypes: ['Person', 'Organization'] }\n * );\n *\n * stream.onProgress((progress) => {\n * console.log(`Scanning: ${progress.currentEntityType}`);\n * console.log(`Progress: ${progress.processedEntityTypes}/${progress.totalEntityTypes}`);\n * });\n *\n * stream.onComplete((result) => {\n * console.log(`Detection complete! Found ${result.foundCount} entities`);\n * });\n *\n * stream.onError((error) => {\n * console.error('Detection failed:', error.message);\n * });\n *\n * // Cleanup when done\n * stream.close();\n * ```\n */\n detectAnnotations(\n resourceId: ResourceUri,\n request: DetectAnnotationsStreamRequest\n ): SSEStream<DetectionProgress, DetectionProgress> {\n const id = this.extractId(resourceId);\n const url = `${this.baseUrl}/resources/${id}/detect-annotations-stream`;\n\n return createSSEStream<DetectionProgress, DetectionProgress>(\n url,\n {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(request)\n },\n {\n progressEvents: ['detection-started', 'detection-progress'],\n completeEvent: 'detection-complete',\n errorEvent: 'detection-error'\n },\n this.logger\n );\n }\n\n /**\n * Generate resource from annotation (streaming)\n *\n * Streams resource generation progress via Server-Sent Events.\n *\n * @param resourceId - Source resource URI or ID\n * @param annotationId - Annotation URI or ID to use as generation source\n * @param request - Generation options (title, prompt, language)\n * @returns SSE stream controller with progress/complete/error callbacks\n *\n * @example\n * ```typescript\n * const stream = sseClient.generateResourceFromAnnotation(\n * 'http://localhost:4000/resources/doc-123',\n * 'http://localhost:4000/annotations/ann-456',\n * { language: 'es', title: 'Spanish Summary' }\n * );\n *\n * stream.onProgress((progress) => {\n * console.log(`${progress.status}: ${progress.percentage}%`);\n * console.log(progress.message);\n * });\n *\n * stream.onComplete((result) => {\n * console.log(`Generated resource: ${result.resourceId}`);\n * });\n *\n * stream.onError((error) => {\n * console.error('Generation failed:', error.message);\n * });\n *\n * // Cleanup when done\n * stream.close();\n * ```\n */\n generateResourceFromAnnotation(\n resourceId: ResourceUri,\n annotationId: AnnotationUri,\n request: GenerateResourceStreamRequest\n ): SSEStream<GenerationProgress, GenerationProgress> {\n const resId = this.extractId(resourceId);\n const annId = this.extractId(annotationId);\n const url = `${this.baseUrl}/resources/${resId}/annotations/${annId}/generate-resource-stream`;\n\n return createSSEStream<GenerationProgress, GenerationProgress>(\n url,\n {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(request)\n },\n {\n progressEvents: ['generation-started', 'generation-progress'],\n completeEvent: 'generation-complete',\n errorEvent: 'generation-error'\n },\n this.logger\n );\n }\n\n /**\n * Detect highlights in a resource (streaming)\n *\n * Streams highlight detection progress via Server-Sent Events.\n *\n * @param resourceId - Resource URI or ID\n * @param request - Detection configuration (optional instructions)\n * @returns SSE stream controller with progress/complete/error callbacks\n *\n * @example\n * ```typescript\n * const stream = sseClient.detectHighlights(\n * 'http://localhost:4000/resources/doc-123',\n * { instructions: 'Focus on key technical points' }\n * );\n *\n * stream.onProgress((progress) => {\n * console.log(`${progress.status}: ${progress.percentage}%`);\n * console.log(progress.message);\n * });\n *\n * stream.onComplete((result) => {\n * console.log(`Detection complete! Created ${result.createdCount} highlights`);\n * });\n *\n * stream.onError((error) => {\n * console.error('Detection failed:', error.message);\n * });\n *\n * // Cleanup when done\n * stream.close();\n * ```\n */\n detectHighlights(\n resourceId: ResourceUri,\n request: DetectHighlightsStreamRequest = {}\n ): SSEStream<HighlightDetectionProgress, HighlightDetectionProgress> {\n const id = this.extractId(resourceId);\n const url = `${this.baseUrl}/resources/${id}/detect-highlights-stream`;\n\n return createSSEStream<HighlightDetectionProgress, HighlightDetectionProgress>(\n url,\n {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(request)\n },\n {\n progressEvents: ['highlight-detection-started', 'highlight-detection-progress'],\n completeEvent: 'highlight-detection-complete',\n errorEvent: 'highlight-detection-error'\n },\n this.logger\n );\n }\n\n /**\n * Detect assessments in a resource (streaming)\n *\n * Streams assessment detection progress via Server-Sent Events.\n *\n * @param resourceId - Resource URI or ID\n * @param request - Detection configuration (optional instructions)\n * @returns SSE stream controller with progress/complete/error callbacks\n *\n * @example\n * ```typescript\n * const stream = sseClient.detectAssessments(\n * 'http://localhost:4000/resources/doc-123',\n * { instructions: 'Evaluate claims for accuracy' }\n * );\n *\n * stream.onProgress((progress) => {\n * console.log(`${progress.status}: ${progress.percentage}%`);\n * console.log(progress.message);\n * });\n *\n * stream.onComplete((result) => {\n * console.log(`Detection complete! Created ${result.createdCount} assessments`);\n * });\n *\n * stream.onError((error) => {\n * console.error('Detection failed:', error.message);\n * });\n *\n * // Cleanup when done\n * stream.close();\n * ```\n */\n detectAssessments(\n resourceId: ResourceUri,\n request: DetectAssessmentsStreamRequest = {}\n ): SSEStream<AssessmentDetectionProgress, AssessmentDetectionProgress> {\n const id = this.extractId(resourceId);\n const url = `${this.baseUrl}/resources/${id}/detect-assessments-stream`;\n\n return createSSEStream<AssessmentDetectionProgress, AssessmentDetectionProgress>(\n url,\n {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(request)\n },\n {\n progressEvents: ['assessment-detection-started', 'assessment-detection-progress'],\n completeEvent: 'assessment-detection-complete',\n errorEvent: 'assessment-detection-error'\n },\n this.logger\n );\n }\n\n /**\n * Detect comments in a resource (streaming)\n *\n * Streams comment detection progress via Server-Sent Events.\n * Uses AI to identify passages that would benefit from explanatory comments\n * and creates comment annotations with contextual information.\n *\n * @param resourceId - Resource URI or ID\n * @param request - Detection configuration (optional instructions and tone)\n * @returns SSE stream controller with progress/complete/error callbacks\n *\n * @example\n * ```typescript\n * const stream = sseClient.detectComments('http://localhost:4000/resources/doc-123', {\n * instructions: 'Focus on technical terminology',\n * tone: 'scholarly'\n * });\n *\n * stream.onProgress((progress) => {\n * console.log(`${progress.status}: ${progress.percentage}%`);\n * });\n *\n * stream.onComplete((result) => {\n * console.log(`Detection complete! Created ${result.createdCount} comments`);\n * });\n *\n * stream.onError((error) => {\n * console.error('Detection failed:', error.message);\n * });\n *\n * // Cleanup when done\n * stream.close();\n * ```\n */\n detectComments(\n resourceId: ResourceUri,\n request: DetectCommentsStreamRequest = {}\n ): SSEStream<CommentDetectionProgress, CommentDetectionProgress> {\n const id = this.extractId(resourceId);\n const url = `${this.baseUrl}/resources/${id}/detect-comments-stream`;\n\n return createSSEStream<CommentDetectionProgress, CommentDetectionProgress>(\n url,\n {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(request)\n },\n {\n progressEvents: ['comment-detection-started', 'comment-detection-progress'],\n completeEvent: 'comment-detection-complete',\n errorEvent: 'comment-detection-error'\n },\n this.logger\n );\n }\n\n /**\n * Detect tags in a resource (streaming)\n *\n * Streams tag detection progress via Server-Sent Events.\n * Uses AI to identify passages serving specific structural roles\n * (e.g., IRAC, IMRAD, Toulmin) and creates tag annotations with dual-body structure.\n *\n * @param resourceId - Resource URI or ID\n * @param request - Detection configuration (schema and categories to detect)\n * @returns SSE stream controller with progress/complete/error callbacks\n *\n * @example\n * ```typescript\n * const stream = sseClient.detectTags('http://localhost:4000/resources/doc-123', {\n * schemaId: 'legal-irac',\n * categories: ['Issue', 'Rule', 'Application', 'Conclusion']\n * });\n *\n * stream.onProgress((progress) => {\n * console.log(`${progress.status}: ${progress.percentage}%`);\n * console.log(`Processing ${progress.currentCategory}...`);\n * });\n *\n * stream.onComplete((result) => {\n * console.log(`Detection complete! Created ${result.tagsCreated} tags`);\n * });\n *\n * stream.onError((error) => {\n * console.error('Detection failed:', error.message);\n * });\n *\n * // Cleanup when done\n * stream.close();\n * ```\n */\n detectTags(\n resourceId: ResourceUri,\n request: DetectTagsStreamRequest\n ): SSEStream<TagDetectionProgress, TagDetectionProgress> {\n const id = this.extractId(resourceId);\n const url = `${this.baseUrl}/resources/${id}/detect-tags-stream`;\n\n return createSSEStream<TagDetectionProgress, TagDetectionProgress>(\n url,\n {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(request)\n },\n {\n progressEvents: ['tag-detection-started', 'tag-detection-progress'],\n completeEvent: 'tag-detection-complete',\n errorEvent: 'tag-detection-error'\n },\n this.logger\n );\n }\n\n /**\n * Subscribe to resource events (long-lived stream)\n *\n * Opens a long-lived SSE connection to receive real-time events for a resource.\n * Used for collaborative editing - see events from other users as they happen.\n *\n * This stream does NOT have a complete event - it stays open until explicitly closed.\n *\n * @param resourceId - Resource URI or ID to subscribe to\n * @returns SSE stream controller with event callback\n *\n * @example\n * ```typescript\n * const stream = sseClient.resourceEvents('http://localhost:4000/resources/doc-123');\n *\n * stream.onProgress((event) => {\n * console.log(`Event: ${event.type}`);\n * console.log(`User: ${event.userId}`);\n * console.log(`Sequence: ${event.metadata.sequenceNumber}`);\n * console.log(`Payload:`, event.payload);\n * });\n *\n * stream.onError((error) => {\n * console.error('Stream error:', error.message);\n * });\n *\n * // Close when no longer needed (e.g., component unmount)\n * stream.close();\n * ```\n */\n resourceEvents(resourceId: ResourceUri): SSEStream<ResourceEvent, never> {\n const id = this.extractId(resourceId);\n const url = `${this.baseUrl}/resources/${id}/events/stream`;\n\n return createSSEStream<ResourceEvent, never>(\n url,\n {\n method: 'GET',\n headers: this.getHeaders()\n },\n {\n progressEvents: ['*'], // Accept all event types\n completeEvent: null, // Long-lived stream - no completion\n errorEvent: 'error', // Generic error event\n customEventHandler: true // Use custom event handling\n },\n this.logger\n );\n }\n}\n","/**\n * Common API client for Semiont backend\n *\n * This client can be used by:\n * - MCP server (Node.js)\n * - Demo scripts (Node.js)\n * - Frontend (Next.js/React - can wrap with hooks)\n *\n * Uses ky for HTTP requests with built-in retry, timeout, and error handling.\n */\n\nimport ky, { type KyInstance } from 'ky';\nimport type { paths } from './types';\nimport type { AnnotationUri, ResourceUri, ResourceAnnotationUri } from './branded-types';\nimport type {\n AccessToken,\n BaseUrl,\n CloneToken,\n ContentFormat,\n Email,\n EntityType,\n GoogleCredential,\n JobId,\n Motivation,\n RefreshToken,\n SearchQuery,\n UserDID\n} from './branded-types';\nimport { SSEClient } from './sse/index';\nimport type { Logger } from './logger';\n\n// Type helpers to extract request/response types from OpenAPI paths\ntype ResponseContent<T> = T extends { responses: { 200: { content: { 'application/json': infer R } } } }\n ? R\n : T extends { responses: { 201: { content: { 'application/json': infer R } } } }\n ? R\n : never;\n\ntype RequestContent<T> = T extends { requestBody?: { content: { 'application/json': infer R } } } ? R : never;\n\n// API Error class\nexport class APIError extends Error {\n constructor(\n message: string,\n public status: number,\n public statusText: string,\n public details?: unknown\n ) {\n super(message);\n this.name = 'APIError';\n }\n}\n\nexport interface SemiontApiClientConfig {\n baseUrl: BaseUrl;\n accessToken?: AccessToken;\n timeout?: number;\n retry?: number;\n logger?: Logger;\n}\n\n/**\n * Semiont API Client\n *\n * Provides type-safe methods for all Semiont backend API endpoints.\n */\nexport class SemiontApiClient {\n private http: KyInstance;\n private baseUrl: BaseUrl;\n private accessToken: AccessToken | null = null;\n private logger?: Logger;\n\n /**\n * SSE streaming client for real-time operations\n *\n * Separate from the main HTTP client to clearly mark streaming endpoints.\n * Uses native fetch() instead of ky for SSE support.\n *\n * @example\n * ```typescript\n * const stream = client.sse.detectAnnotations(\n * resourceId,\n * { entityTypes: ['Person', 'Organization'] }\n * );\n *\n * stream.onProgress((p) => console.log(p.message));\n * stream.onComplete((r) => console.log(`Found ${r.foundCount} entities`));\n * stream.close();\n * ```\n */\n public readonly sse: SSEClient;\n\n constructor(config: SemiontApiClientConfig) {\n const { baseUrl, accessToken, timeout = 30000, retry = 2, logger } = config;\n\n // Store logger and baseUrl for constructing full URLs\n this.logger = logger;\n\n // Remove trailing slash for consistent URL construction\n this.baseUrl = (baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl) as BaseUrl;\n\n // Don't use prefixUrl - we'll construct full URLs or use provided full URIs\n this.http = ky.create({\n timeout,\n retry,\n hooks: {\n beforeRequest: [\n (request) => {\n // Add auth header\n if (this.accessToken) {\n request.headers.set('Authorization', `Bearer ${this.accessToken}`);\n }\n\n // Log HTTP request\n if (this.logger) {\n this.logger.debug('HTTP Request', {\n type: 'http_request',\n url: request.url,\n method: request.method,\n timestamp: Date.now(),\n hasAuth: !!this.accessToken\n });\n }\n },\n ],\n afterResponse: [\n (request, _options, response) => {\n // Log HTTP response\n if (this.logger) {\n this.logger.debug('HTTP Response', {\n type: 'http_response',\n url: request.url,\n method: request.method,\n status: response.status,\n statusText: response.statusText\n });\n }\n return response;\n }\n ],\n beforeError: [\n async (error) => {\n const { response, request } = error;\n if (response) {\n const body = await response.json().catch(() => ({})) as any;\n\n // Log HTTP error\n if (this.logger) {\n this.logger.error('HTTP Request Failed', {\n type: 'http_error',\n url: request.url,\n method: request.method,\n status: response.status,\n statusText: response.statusText,\n error: body.message || `HTTP ${response.status}: ${response.statusText}`\n });\n }\n\n throw new APIError(\n body.message || `HTTP ${response.status}: ${response.statusText}`,\n response.status,\n response.statusText,\n body\n );\n }\n return error;\n },\n ],\n },\n });\n\n if (accessToken) {\n this.accessToken = accessToken;\n }\n\n // Initialize SSE client (uses native fetch, not ky)\n this.sse = new SSEClient({\n baseUrl: this.baseUrl,\n accessToken: this.accessToken || undefined,\n logger: this.logger\n });\n }\n\n /**\n * Set the access token for authenticated requests\n */\n setAccessToken(token: AccessToken): void {\n this.accessToken = token;\n this.sse.setAccessToken(token);\n }\n\n /**\n * Clear the access token\n */\n clearAccessToken(): void {\n this.accessToken = null;\n this.sse.clearAccessToken();\n }\n\n // ============================================================================\n // AUTHENTICATION\n // ============================================================================\n\n async authenticatePassword(email: Email, password: string): Promise<ResponseContent<paths['/api/tokens/password']['post']>> {\n const response = await this.http.post(`${this.baseUrl}/api/tokens/password`, { json: { email, password } }).json<any>();\n if (response.token) {\n this.setAccessToken(response.token);\n }\n return response;\n }\n\n async refreshToken(token: RefreshToken): Promise<ResponseContent<paths['/api/tokens/refresh']['post']>> {\n const response = await this.http.post(`${this.baseUrl}/api/tokens/refresh`, { json: { refreshToken: token } }).json<any>();\n if (response.access_token) {\n this.setAccessToken(response.access_token);\n }\n return response;\n }\n\n async authenticateGoogle(credential: GoogleCredential): Promise<ResponseContent<paths['/api/tokens/google']['post']>> {\n const response = await this.http.post(`${this.baseUrl}/api/tokens/google`, { json: { credential } }).json<any>();\n if (response.token) {\n this.setAccessToken(response.token);\n }\n return response;\n }\n\n async generateMCPToken(): Promise<ResponseContent<paths['/api/tokens/mcp-generate']['post']>> {\n return this.http.post(`${this.baseUrl}/api/tokens/mcp-generate`).json();\n }\n\n // ============================================================================\n // USERS\n // ============================================================================\n\n async getMe(): Promise<ResponseContent<paths['/api/users/me']['get']>> {\n return this.http.get(`${this.baseUrl}/api/users/me`).json();\n }\n\n async acceptTerms(): Promise<ResponseContent<paths['/api/users/accept-terms']['post']>> {\n return this.http.post(`${this.baseUrl}/api/users/accept-terms`).json();\n }\n\n async logout(): Promise<ResponseContent<paths['/api/users/logout']['post']>> {\n return this.http.post(`${this.baseUrl}/api/users/logout`).json();\n }\n\n // ============================================================================\n // RESOURCES\n // ============================================================================\n\n /**\n * Create a new resource with binary content support\n *\n * @param data - Resource creation data\n * @param data.name - Resource name\n * @param data.file - File object or Buffer with binary content\n * @param data.format - MIME type (e.g., 'text/markdown', 'image/png')\n * @param data.entityTypes - Optional array of entity types\n * @param data.language - Optional ISO 639-1 language code\n * @param data.creationMethod - Optional creation method\n * @param data.sourceAnnotationId - Optional source annotation ID\n * @param data.sourceResourceId - Optional source resource ID\n */\n async createResource(data: {\n name: string;\n file: File | Buffer;\n format: string;\n entityTypes?: string[];\n language?: string;\n creationMethod?: string;\n sourceAnnotationId?: string;\n sourceResourceId?: string;\n }): Promise<ResponseContent<paths['/resources']['post']>> {\n // Build FormData\n const formData = new FormData();\n formData.append('name', data.name);\n formData.append('format', data.format);\n\n // Handle File or Buffer\n if (data.file instanceof File) {\n formData.append('file', data.file);\n } else if (Buffer.isBuffer(data.file)) {\n // Node.js environment: convert Buffer to Blob\n const blob = new Blob([data.file], { type: data.format });\n formData.append('file', blob, data.name);\n } else {\n throw new Error('file must be a File or Buffer');\n }\n\n // Optional fields\n if (data.entityTypes && data.entityTypes.length > 0) {\n formData.append('entityTypes', JSON.stringify(data.entityTypes));\n }\n if (data.language) {\n formData.append('language', data.language);\n }\n if (data.creationMethod) {\n formData.append('creationMethod', data.creationMethod);\n }\n if (data.sourceAnnotationId) {\n formData.append('sourceAnnotationId', data.sourceAnnotationId);\n }\n if (data.sourceResourceId) {\n formData.append('sourceResourceId', data.sourceResourceId);\n }\n\n // POST with multipart/form-data (ky automatically sets Content-Type)\n return this.http.post(`${this.baseUrl}/resources`, { body: formData }).json();\n }\n\n async getResource(resourceUri: ResourceUri): Promise<ResponseContent<paths['/resources/{id}']['get']>> {\n // resourceUri is already a full URI, use it directly\n return this.http.get(resourceUri).json();\n }\n\n /**\n * Get resource representation using W3C content negotiation\n * Returns raw binary content (images, PDFs, text, etc.) with content type\n *\n * @param resourceUri - Full resource URI\n * @param options - Options including Accept header for content negotiation\n * @returns Object with data (ArrayBuffer) and contentType (string)\n *\n * @example\n * ```typescript\n * // Get markdown representation\n * const { data, contentType } = await client.getResourceRepresentation(rUri, { accept: 'text/markdown' });\n * const markdown = new TextDecoder().decode(data);\n *\n * // Get image representation\n * const { data, contentType } = await client.getResourceRepresentation(rUri, { accept: 'image/png' });\n * const blob = new Blob([data], { type: contentType });\n *\n * // Get PDF representation\n * const { data, contentType } = await client.getResourceRepresentation(rUri, { accept: 'application/pdf' });\n * ```\n */\n async getResourceRepresentation(\n resourceUri: ResourceUri,\n options?: { accept?: ContentFormat }\n ): Promise<{ data: ArrayBuffer; contentType: string }> {\n // resourceUri is already a full URI, use it directly with Accept header\n const response = await this.http.get(resourceUri, {\n headers: {\n Accept: options?.accept || 'text/plain'\n }\n });\n\n const contentType = response.headers.get('content-type') || 'application/octet-stream';\n const data = await response.arrayBuffer();\n\n return { data, contentType };\n }\n\n /**\n * Get resource representation as a stream using W3C content negotiation\n * Returns streaming binary content (for large files: videos, large PDFs, etc.)\n *\n * Use this for large files to avoid loading entire content into memory.\n * The stream is consumed incrementally and the backend connection stays open\n * until the stream is fully consumed or closed.\n *\n * @param resourceUri - Full resource URI\n * @param options - Options including Accept header for content negotiation\n * @returns Object with stream (ReadableStream) and contentType (string)\n *\n * @example\n * ```typescript\n * // Stream large file\n * const { stream, contentType } = await client.getResourceRepresentationStream(rUri, {\n * accept: 'video/mp4'\n * });\n *\n * // Consume stream chunk by chunk (never loads entire file into memory)\n * for await (const chunk of stream) {\n * // Process chunk\n * console.log(`Received ${chunk.length} bytes`);\n * }\n *\n * // Or pipe to a file in Node.js\n * const fileStream = fs.createWriteStream('output.mp4');\n * const reader = stream.getReader();\n * while (true) {\n * const { done, value } = await reader.read();\n * if (done) break;\n * fileStream.write(value);\n * }\n * ```\n */\n async getResourceRepresentationStream(\n resourceUri: ResourceUri,\n options?: { accept?: ContentFormat }\n ): Promise<{ stream: ReadableStream<Uint8Array>; contentType: string }> {\n // resourceUri is already a full URI, use it directly with Accept header\n const response = await this.http.get(resourceUri, {\n headers: {\n Accept: options?.accept || 'text/plain'\n }\n });\n\n const contentType = response.headers.get('content-type') || 'application/octet-stream';\n\n if (!response.body) {\n throw new Error('Response body is null - cannot create stream');\n }\n\n return { stream: response.body, contentType };\n }\n\n async listResources(\n limit?: number,\n archived?: boolean,\n query?: SearchQuery\n ): Promise<ResponseContent<paths['/resources']['get']>> {\n const searchParams = new URLSearchParams();\n if (limit) searchParams.append('limit', limit.toString());\n if (archived !== undefined) searchParams.append('archived', archived.toString());\n if (query) searchParams.append('q', query);\n\n return this.http.get(`${this.baseUrl}/resources`, { searchParams }).json();\n }\n\n async updateResource(\n resourceUri: ResourceUri,\n data: RequestContent<paths['/resources/{id}']['patch']>\n ): Promise<ResponseContent<paths['/resources/{id}']['patch']>> {\n // resourceUri is already a full URI, use it directly\n return this.http.patch(resourceUri, { json: data }).json();\n }\n\n async getResourceEvents(resourceUri: ResourceUri): Promise<{ events: any[] }> {\n // resourceUri is already a full URI, use it directly\n return this.http.get(`${resourceUri}/events`).json();\n }\n\n async getResourceAnnotations(\n resourceUri: ResourceUri\n ): Promise<ResponseContent<paths['/resources/{id}/annotations']['get']>> {\n // resourceUri is already a full URI, use it directly\n return this.http.get(`${resourceUri}/annotations`).json();\n }\n\n async getAnnotationLLMContext(\n resourceUri: ResourceUri,\n annotationId: string,\n options?: { contextWindow?: number }\n ): Promise<ResponseContent<paths['/resources/{resourceId}/annotations/{annotationId}/llm-context']['get']>> {\n const searchParams = new URLSearchParams();\n if (options?.contextWindow) {\n searchParams.append('contextWindow', options.contextWindow.toString());\n }\n // resourceUri is already a full URI, use it directly\n return this.http.get(\n `${resourceUri}/annotations/${annotationId}/llm-context`,\n { searchParams }\n ).json();\n }\n\n async getResourceReferencedBy(resourceUri: ResourceUri): Promise<{ referencedBy: any[] }> {\n // resourceUri is already a full URI, use it directly\n return this.http.get(`${resourceUri}/referenced-by`).json();\n }\n\n async generateCloneToken(resourceUri: ResourceUri): Promise<ResponseContent<paths['/resources/{id}/clone-with-token']['post']>> {\n // resourceUri is already a full URI, use it directly\n return this.http.post(`${resourceUri}/clone-with-token`).json();\n }\n\n async getResourceByToken(token: CloneToken): Promise<ResponseContent<paths['/api/resources/token/{token}']['get']>> {\n return this.http.get(`${this.baseUrl}/api/resources/token/${token}`).json();\n }\n\n async createResourceFromToken(\n data: RequestContent<paths['/api/resources/create-from-token']['post']>\n ): Promise<ResponseContent<paths['/api/resources/create-from-token']['post']>> {\n return this.http.post(`${this.baseUrl}/api/resources/create-from-token`, { json: data }).json();\n }\n\n // ============================================================================\n // ANNOTATIONS\n // ============================================================================\n\n async createAnnotation(\n resourceUri: ResourceUri,\n data: RequestContent<paths['/resources/{id}/annotations']['post']>\n ): Promise<ResponseContent<paths['/resources/{id}/annotations']['post']>> {\n // resourceUri is already a full URI, use it directly\n return this.http.post(`${resourceUri}/annotations`, { json: data }).json();\n }\n\n async getAnnotation(annotationUri: AnnotationUri): Promise<ResponseContent<paths['/annotations/{id}']['get']>> {\n // annotationUri is already a full URI, use it directly\n return this.http.get(annotationUri).json();\n }\n\n async getResourceAnnotation(annotationUri: ResourceAnnotationUri): Promise<ResponseContent<paths['/resources/{resourceId}/annotations/{annotationId}']['get']>> {\n // annotationUri is already a full URI, use it directly\n return this.http.get(annotationUri).json();\n }\n\n async listAnnotations(\n resourceUri: ResourceUri,\n motivation?: Motivation\n ): Promise<ResponseContent<paths['/resources/{id}/annotations']['get']>> {\n const searchParams = new URLSearchParams();\n if (motivation) searchParams.append('motivation', motivation);\n\n // resourceUri is already a full URI, use it directly\n return this.http.get(`${resourceUri}/annotations`, { searchParams }).json();\n }\n\n async deleteAnnotation(annotationUri: ResourceAnnotationUri): Promise<void> {\n // annotationUri is already a full URI, use it directly\n await this.http.delete(annotationUri);\n }\n\n async updateAnnotationBody(\n annotationUri: ResourceAnnotationUri,\n data: RequestContent<paths['/resources/{resourceId}/annotations/{annotationId}/body']['put']>\n ): Promise<ResponseContent<paths['/resources/{resourceId}/annotations/{annotationId}/body']['put']>> {\n // annotationUri is already a full URI, use it directly\n return this.http.put(`${annotationUri}/body`, {\n json: data,\n }).json();\n }\n\n async getAnnotationHistory(\n annotationUri: ResourceAnnotationUri\n ): Promise<ResponseContent<paths['/resources/{resourceId}/annotations/{annotationId}/history']['get']>> {\n // annotationUri is already a full URI, use it directly\n return this.http.get(`${annotationUri}/history`).json();\n }\n\n // ============================================================================\n // ENTITY TYPES\n // ============================================================================\n\n async addEntityType(type: EntityType): Promise<ResponseContent<paths['/api/entity-types']['post']>> {\n return this.http.post(`${this.baseUrl}/api/entity-types`, { json: { type } }).json();\n }\n\n async addEntityTypesBulk(types: EntityType[]): Promise<ResponseContent<paths['/api/entity-types/bulk']['post']>> {\n return this.http.post(`${this.baseUrl}/api/entity-types/bulk`, { json: { tags: types } }).json();\n }\n\n async listEntityTypes(): Promise<ResponseContent<paths['/api/entity-types']['get']>> {\n return this.http.get(`${this.baseUrl}/api/entity-types`).json();\n }\n\n // ============================================================================\n // ADMIN\n // ============================================================================\n\n async listUsers(): Promise<ResponseContent<paths['/api/admin/users']['get']>> {\n return this.http.get(`${this.baseUrl}/api/admin/users`).json();\n }\n\n async getUserStats(): Promise<ResponseContent<paths['/api/admin/users/stats']['get']>> {\n return this.http.get(`${this.baseUrl}/api/admin/users/stats`).json();\n }\n\n /**\n * Update a user by ID\n * Note: Users use DID identifiers (did:web:domain:users:id), not HTTP URIs.\n */\n async updateUser(\n id: UserDID,\n data: RequestContent<paths['/api/admin/users/{id}']['patch']>\n ): Promise<ResponseContent<paths['/api/admin/users/{id}']['patch']>> {\n return this.http.patch(`${this.baseUrl}/api/admin/users/${id}`, { json: data }).json();\n }\n\n async getOAuthConfig(): Promise<ResponseContent<paths['/api/admin/oauth/config']['get']>> {\n return this.http.get(`${this.baseUrl}/api/admin/oauth/config`).json();\n }\n\n // ============================================================================\n // JOB STATUS\n // ============================================================================\n\n async getJobStatus(id: JobId): Promise<ResponseContent<paths['/api/jobs/{id}']['get']>> {\n return this.http.get(`${this.baseUrl}/api/jobs/${id}`).json();\n }\n\n /**\n * Poll a job until it completes or fails\n * @param id - The job ID to poll\n * @param options - Polling options\n * @returns The final job status\n */\n async pollJobUntilComplete(\n id: JobId,\n options?: {\n interval?: number; // Milliseconds between polls (default: 1000)\n timeout?: number; // Total timeout in milliseconds (default: 60000)\n onProgress?: (status: ResponseContent<paths['/api/jobs/{id}']['get']>) => void;\n }\n ): Promise<ResponseContent<paths['/api/jobs/{id}']['get']>> {\n const interval = options?.interval ?? 1000;\n const timeout = options?.timeout ?? 60000;\n const startTime = Date.now();\n\n while (true) {\n const status = await this.getJobStatus(id);\n\n // Call progress callback if provided\n if (options?.onProgress) {\n options.onProgress(status);\n }\n\n // Check if job is in a terminal state\n if (status.status === 'complete' || status.status === 'failed' || status.status === 'cancelled') {\n return status;\n }\n\n // Check timeout\n if (Date.now() - startTime > timeout) {\n throw new Error(`Job polling timeout after ${timeout}ms`);\n }\n\n // Wait before next poll\n await new Promise(resolve => setTimeout(resolve, interval));\n }\n }\n\n // ============================================================================\n // LLM CONTEXT\n // ============================================================================\n\n async getResourceLLMContext(\n resourceUri: ResourceUri,\n options?: {\n depth?: number;\n maxResources?: number;\n includeContent?: boolean;\n includeSummary?: boolean;\n }\n ): Promise<ResponseContent<paths['/resources/{id}/llm-context']['get']>> {\n const searchParams = new URLSearchParams();\n if (options?.depth !== undefined) searchParams.append('depth', options.depth.toString());\n if (options?.maxResources !== undefined) searchParams.append('maxResources', options.maxResources.toString());\n if (options?.includeContent !== undefined) searchParams.append('includeContent', options.includeContent.toString());\n if (options?.includeSummary !== undefined) searchParams.append('includeSummary', options.includeSummary.toString());\n\n return this.http.get(`${resourceUri}/llm-context`, { searchParams }).json();\n }\n\n // ============================================================================\n // SYSTEM STATUS\n // ============================================================================\n\n async healthCheck(): Promise<ResponseContent<paths['/api/health']['get']>> {\n return this.http.get(`${this.baseUrl}/api/health`).json();\n }\n\n async getStatus(): Promise<ResponseContent<paths['/api/status']['get']>> {\n return this.http.get(`${this.baseUrl}/api/status`).json();\n }\n}\n","/**\n * Branded string types for compile-time type safety\n *\n * These types are zero-cost at runtime but prevent mixing\n * different string types at compile time.\n */\n\nimport type { components } from './types';\n\n// ============================================================================\n// OPENAPI-GENERATED TYPES (use directly from spec)\n// ============================================================================\n\nexport type Motivation = components['schemas']['Motivation'];\nexport type ContentFormat = components['schemas']['ContentFormat'];\n\n// ============================================================================\n// AUTHENTICATION & TOKENS\n// ============================================================================\n\nexport type Email = string & { readonly __brand: 'Email' };\nexport type AuthCode = string & { readonly __brand: 'AuthCode' };\nexport type GoogleCredential = string & { readonly __brand: 'GoogleCredential' };\nexport type AccessToken = string & { readonly __brand: 'AccessToken' };\nexport type RefreshToken = string & { readonly __brand: 'RefreshToken' };\nexport type MCPToken = string & { readonly __brand: 'MCPToken' };\nexport type CloneToken = string & { readonly __brand: 'CloneToken' };\n\n// ============================================================================\n// SYSTEM IDENTIFIERS\n// ============================================================================\n\nexport type JobId = string & { readonly __brand: 'JobId' };\nexport type UserDID = string & { readonly __brand: 'UserDID' };\nexport type EntityType = string & { readonly __brand: 'EntityType' };\nexport type SearchQuery = string & { readonly __brand: 'SearchQuery' };\nexport type BaseUrl = string & { readonly __brand: 'BaseUrl' };\n\n// ============================================================================\n// HELPER FUNCTIONS (minimal validation, just branding)\n// ============================================================================\n\nexport function email(value: string): Email { return value as Email; }\nexport function authCode(value: string): AuthCode { return value as AuthCode; }\nexport function googleCredential(value: string): GoogleCredential { return value as GoogleCredential; }\nexport function accessToken(value: string): AccessToken { return value as AccessToken; }\nexport function refreshToken(value: string): RefreshToken { return value as RefreshToken; }\nexport function mcpToken(value: string): MCPToken { return value as MCPToken; }\nexport function cloneToken(value: string): CloneToken { return value as CloneToken; }\nexport function jobId(value: string): JobId { return value as JobId; }\nexport function userDID(value: string): UserDID { return value as UserDID; }\nexport function entityType(value: string): EntityType { return value as EntityType; }\nexport function searchQuery(value: string): SearchQuery { return value as SearchQuery; }\nexport function baseUrl(value: string): BaseUrl { return value as BaseUrl; }\n\n// Motivation and ContentFormat use OpenAPI enums - no helpers needed\n// Use the enum values directly from the OpenAPI spec\n\n// ============================================================================\n// HTTP URI TYPES\n// ============================================================================\n\n// Branded type definitions for HTTP URIs returned by the API\nexport type ResourceUri = string & { readonly __brand: 'ResourceUri' };\n\n// W3C flat format for content negotiation: http://localhost:4000/annotations/{id}\nexport type AnnotationUri = string & { readonly __brand: 'AnnotationUri' };\n\n// Nested format for CRUD operations: http://localhost:4000/resources/{resourceId}/annotations/{annotationId}\nexport type ResourceAnnotationUri = string & { readonly __brand: 'ResourceAnnotationUri' };\n\n// Factory functions with runtime validation\nexport function resourceUri(uri: string): ResourceUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected ResourceUri, got: ${uri}`);\n }\n return uri as ResourceUri;\n}\n\nexport function annotationUri(uri: string): AnnotationUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected AnnotationUri, got: ${uri}`);\n }\n return uri as AnnotationUri;\n}\n\nexport function resourceAnnotationUri(uri: string): ResourceAnnotationUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected ResourceAnnotationUri, got: ${uri}`);\n }\n // Additional validation: must contain /resources/ and /annotations/\n if (!uri.includes('/resources/') || !uri.includes('/annotations/')) {\n throw new TypeError(`Expected nested ResourceAnnotationUri format, got: ${uri}`);\n }\n return uri as ResourceAnnotationUri;\n}\n","/**\n * Annotation and Selector Utilities\n *\n * Pure TypeScript utilities for working with W3C Web Annotations.\n * No React dependencies - safe to use in any JavaScript environment.\n *\n * Body is either empty array (stub) or single SpecificResource (resolved)\n * Body can be array of TextualBody (tagging) + SpecificResource (linking)\n * Target can be simple string IRI or object with source and optional selector\n */\n\nimport type { components } from '../types';\nimport type { ResourceUri } from '../branded-types';\nimport { resourceUri } from '../branded-types';\n\ntype Annotation = components['schemas']['Annotation'];\ntype HighlightAnnotation = Annotation;\ntype ReferenceAnnotation = Annotation;\ntype TextPositionSelector = components['schemas']['TextPositionSelector'];\ntype TextQuoteSelector = components['schemas']['TextQuoteSelector'];\ntype SvgSelector = components['schemas']['SvgSelector'];\ntype Selector = TextPositionSelector | TextQuoteSelector | SvgSelector;\n\n// Re-export selector types for convenience\nexport type { TextPositionSelector, TextQuoteSelector, SvgSelector, Selector };\n\n/**\n * Get the source from an annotation body (null if stub)\n * Search for SpecificResource in body array\n */\nexport function getBodySource(body: Annotation['body']): ResourceUri | null {\n if (Array.isArray(body)) {\n // Search for SpecificResource with source\n for (const item of body) {\n if (\n typeof item === 'object' &&\n item !== null &&\n 'type' in item &&\n 'source' in item\n ) {\n const itemType = (item as { type: unknown }).type;\n const itemSource = (item as { source: unknown }).source;\n\n if (itemType === 'SpecificResource' && typeof itemSource === 'string') {\n return resourceUri(itemSource);\n }\n }\n }\n return null; // No SpecificResource found = stub\n }\n\n // Single body object (SpecificResource)\n if (\n typeof body === 'object' &&\n body !== null &&\n 'type' in body &&\n 'source' in body\n ) {\n const bodyType = (body as { type: unknown }).type;\n const bodySource = (body as { source: unknown }).source;\n\n if (bodyType === 'SpecificResource' && typeof bodySource === 'string') {\n return resourceUri(bodySource);\n }\n }\n\n return null;\n}\n\n/**\n * Get the type from an annotation body (returns first body type in array)\n */\nexport function getBodyType(body: Annotation['body']): 'TextualBody' | 'SpecificResource' | null {\n if (Array.isArray(body)) {\n if (body.length === 0) {\n return null;\n }\n // Return type of first body item\n if (typeof body[0] === 'object' && body[0] !== null && 'type' in body[0]) {\n const firstType = (body[0] as { type: unknown }).type;\n if (firstType === 'TextualBody' || firstType === 'SpecificResource') {\n return firstType;\n }\n }\n return null;\n }\n\n // Single body object\n if (typeof body === 'object' && body !== null && 'type' in body) {\n const bodyType = (body as { type: unknown }).type;\n if (bodyType === 'TextualBody' || bodyType === 'SpecificResource') {\n return bodyType;\n }\n }\n\n return null;\n}\n\n/**\n * Check if body is resolved (has a source)\n * Check for SpecificResource in body array\n */\nexport function isBodyResolved(body: Annotation['body']): boolean {\n return getBodySource(body) !== null;\n}\n\n/**\n * Get the source IRI from target (handles both string and object forms)\n */\nexport function getTargetSource(target: Annotation['target']): ResourceUri {\n if (typeof target === 'string') {\n return resourceUri(target);\n }\n return resourceUri(target.source);\n}\n\n/**\n * Get the selector from target (undefined if string or no selector)\n */\nexport function getTargetSelector(target: Annotation['target']) {\n if (typeof target === 'string') {\n return undefined;\n }\n return target.selector;\n}\n\n/**\n * Check if target has a selector\n */\nexport function hasTargetSelector(target: Annotation['target']): boolean {\n return typeof target !== 'string' && target.selector !== undefined;\n}\n\n/**\n * Type guard to check if an annotation is a highlight\n */\nexport function isHighlight(annotation: Annotation): annotation is HighlightAnnotation {\n return annotation.motivation === 'highlighting';\n}\n\n/**\n * Type guard to check if an annotation is a reference (linking)\n */\nexport function isReference(annotation: Annotation): annotation is ReferenceAnnotation {\n return annotation.motivation === 'linking';\n}\n\n/**\n * Type guard to check if an annotation is an assessment\n */\nexport function isAssessment(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'assessing';\n}\n\n/**\n * Type guard to check if an annotation is a comment\n */\nexport function isComment(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'commenting';\n}\n\n/**\n * Type guard to check if an annotation is a tag\n */\nexport function isTag(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'tagging';\n}\n\n/**\n * Extract comment text from a comment annotation's body\n * @param annotation - The annotation to extract comment text from\n * @returns The comment text, or undefined if not a comment or no text found\n */\nexport function getCommentText(annotation: Annotation): string | undefined {\n if (!isComment(annotation)) return undefined;\n const body = Array.isArray(annotation.body) ? annotation.body[0] : annotation.body;\n if (body && 'value' in body) {\n return body.value;\n }\n return undefined;\n}\n\n/**\n * Type guard to check if a reference annotation is a stub (unresolved)\n * Stub if no SpecificResource in body array\n */\nexport function isStubReference(annotation: Annotation): boolean {\n return isReference(annotation) && !isBodyResolved(annotation.body);\n}\n\n/**\n * Type guard to check if a reference annotation is resolved\n * Resolved if SpecificResource exists in body array\n */\nexport function isResolvedReference(annotation: Annotation): annotation is ReferenceAnnotation {\n return isReference(annotation) && isBodyResolved(annotation.body);\n}\n\n// =============================================================================\n// SELECTOR UTILITIES\n// =============================================================================\n\n/**\n * Get the exact text from a selector (single or array)\n *\n * When selector is an array, tries to find a TextQuoteSelector (which has exact text).\n * TextPositionSelector does not have exact text, only character offsets.\n * Handles undefined selector (when target is a string IRI with no selector)\n */\nexport function getExactText(selector: Selector | Selector[] | undefined): string {\n if (!selector) {\n return ''; // No selector means entire resource\n }\n const selectors = Array.isArray(selector) ? selector : [selector];\n\n // Try to find TextQuoteSelector (has exact text)\n const quoteSelector = selectors.find(s => s.type === 'TextQuoteSelector') as TextQuoteSelector | undefined;\n if (quoteSelector) {\n return quoteSelector.exact;\n }\n\n // No TextQuoteSelector found\n return '';\n}\n\n/**\n * Get the exact text from an annotation's target selector\n * Uses getTargetSelector helper to safely get selector\n */\nexport function getAnnotationExactText(annotation: Annotation): string {\n const selector = getTargetSelector(annotation.target);\n return getExactText(selector as Selector | Selector[] | undefined);\n}\n\n/**\n * Get the primary selector from a selector (single or array)\n *\n * When selector is an array, returns the first selector.\n * When selector is a single object, returns it as-is.\n */\nexport function getPrimarySelector(selector: Selector | Selector[]): Selector {\n if (Array.isArray(selector)) {\n if (selector.length === 0) {\n throw new Error('Empty selector array');\n }\n const first = selector[0];\n if (!first) {\n throw new Error('Invalid selector array');\n }\n return first;\n }\n return selector;\n}\n\n/**\n * Get TextPositionSelector from a selector (single or array)\n *\n * Returns the first TextPositionSelector found, or null if none exists.\n * Handles undefined selector (when target is a string IRI with no selector)\n */\nexport function getTextPositionSelector(selector: Selector | Selector[] | undefined): TextPositionSelector | null {\n if (!selector) return null; // No selector means entire resource\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'TextPositionSelector');\n if (!found) return null;\n return found.type === 'TextPositionSelector' ? found : null;\n}\n\n/**\n * Get TextQuoteSelector from a selector (single or array)\n *\n * Returns the first TextQuoteSelector found, or null if none exists.\n */\nexport function getTextQuoteSelector(selector: Selector | Selector[]): TextQuoteSelector | null {\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'TextQuoteSelector');\n if (!found) return null;\n return found.type === 'TextQuoteSelector' ? found : null;\n}\n\n/**\n * Get SvgSelector from a selector (single or array)\n *\n * Returns the first SvgSelector found, or null if none exists.\n */\nexport function getSvgSelector(selector: Selector | Selector[] | undefined): SvgSelector | null {\n if (!selector) return null;\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'SvgSelector');\n if (!found) return null;\n return found.type === 'SvgSelector' ? found : null;\n}\n\n/**\n * Validate SVG markup for W3C compliance\n *\n * Checks that:\n * - SVG contains xmlns attribute\n * - SVG is well-formed XML\n * - SVG contains at least one shape element\n *\n * @returns null if valid, error message if invalid\n */\nexport function validateSvgMarkup(svg: string): string | null {\n // Check for xmlns attribute (required by W3C spec)\n if (!svg.includes('xmlns=\"http://www.w3.org/2000/svg\"')) {\n return 'SVG must include xmlns=\"http://www.w3.org/2000/svg\" attribute';\n }\n\n // Check for basic SVG tag structure\n if (!svg.includes('<svg') || !svg.includes('</svg>')) {\n return 'SVG must have opening and closing tags';\n }\n\n // Check for at least one shape element\n const shapeElements = ['rect', 'circle', 'ellipse', 'polygon', 'polyline', 'path', 'line'];\n const hasShape = shapeElements.some(shape =>\n svg.includes(`<${shape}`) || svg.includes(`<${shape} `)\n );\n\n if (!hasShape) {\n return 'SVG must contain at least one shape element (rect, circle, ellipse, polygon, polyline, path, or line)';\n }\n\n return null; // Valid\n}\n\n/**\n * Extract bounding box from SVG markup\n *\n * Attempts to extract x, y, width, height from the SVG viewBox or root element.\n * Returns null if bounding box cannot be determined.\n */\nexport function extractBoundingBox(svg: string): { x: number; y: number; width: number; height: number } | null {\n // Try to extract viewBox attribute from SVG element\n const viewBoxMatch = svg.match(/<svg[^>]*viewBox=\"([^\"]+)\"/);\n if (viewBoxMatch) {\n const values = viewBoxMatch[1].split(/\\s+/).map(parseFloat);\n if (values.length === 4 && values.every(v => !isNaN(v))) {\n return {\n x: values[0],\n y: values[1],\n width: values[2],\n height: values[3]\n };\n }\n }\n\n // Try to extract width/height attributes from SVG element (assume x=0, y=0)\n const svgTagMatch = svg.match(/<svg[^>]*>/);\n if (svgTagMatch) {\n const svgTag = svgTagMatch[0];\n const widthMatch = svgTag.match(/width=\"([^\"]+)\"/);\n const heightMatch = svgTag.match(/height=\"([^\"]+)\"/);\n\n if (widthMatch && heightMatch) {\n const width = parseFloat(widthMatch[1]);\n const height = parseFloat(heightMatch[1]);\n\n if (!isNaN(width) && !isNaN(height)) {\n return { x: 0, y: 0, width, height };\n }\n }\n }\n\n return null;\n}\n","/**\n * Event Utilities\n *\n * Pure TypeScript utilities for working with resource events.\n * No React dependencies - safe to use in any JavaScript environment.\n */\n\nimport type { paths, components } from '../types';\nimport { AnnotationUri } from '../branded-types';\nimport { getExactText, getTargetSelector } from './annotations';\n\n// Extract StoredEvent type from events endpoint response\ntype EventsResponse = paths['/resources/{id}/events']['get']['responses'][200]['content']['application/json'];\nexport type StoredEvent = EventsResponse['events'][number];\nexport type ResourceEvent = StoredEvent['event'];\nexport type EventMetadata = StoredEvent['metadata'];\ntype Annotation = components['schemas']['Annotation'];\n\n// Event types\nexport type ResourceEventType =\n | 'resource.created'\n | 'resource.cloned'\n | 'resource.archived'\n | 'resource.unarchived'\n | 'annotation.added'\n | 'annotation.removed'\n | 'annotation.body.updated'\n | 'entitytag.added'\n | 'entitytag.removed'\n | 'entitytype.added' // Global entity type collection\n | 'job.started'\n | 'job.progress'\n | 'job.completed'\n | 'job.failed';\n\ntype TranslateFn = (key: string, params?: Record<string, string | number>) => string;\n\n// =============================================================================\n// EVENT TYPE GUARDS AND EXTRACTION\n// =============================================================================\n\n/**\n * Extract annotation ID from event payload\n * Returns null if event is not annotation-related\n *\n * For annotation.added: extracts full URI from payload.annotation.id\n * For annotation.removed/body.updated: constructs full URI from payload.annotationId (UUID) + resourceId\n */\nexport function getAnnotationUriFromEvent(event: StoredEvent): AnnotationUri | null {\n const eventData = event.event;\n const payload = eventData.payload as any;\n\n if (!payload) {\n return null;\n }\n\n switch (eventData.type) {\n case 'annotation.added':\n // annotation.added has the full annotation object with id as full URI\n return payload.annotation?.id || null;\n\n case 'annotation.removed':\n case 'annotation.body.updated':\n // These events have annotationId (UUID only), need to construct full URI\n // Extract base URL from resourceId (format: http://host/resources/id)\n if (payload.annotationId && eventData.resourceId) {\n try {\n const resourceUri = eventData.resourceId;\n // Extract base URL by removing the /resources/{id} part\n const baseUrl = resourceUri.substring(0, resourceUri.lastIndexOf('/resources/'));\n return `${baseUrl}/annotations/${payload.annotationId}` as AnnotationUri;\n } catch (e) {\n return null;\n }\n }\n return null;\n\n default:\n return null;\n }\n}\n\n/**\n * Check if an event is related to a specific annotation\n */\nexport function isEventRelatedToAnnotation(event: StoredEvent, annotationUri: AnnotationUri): boolean {\n const eventAnnotationUri = getAnnotationUriFromEvent(event);\n return eventAnnotationUri === annotationUri;\n}\n\n/**\n * Type guard to check if event is a resource event\n */\nexport function isResourceEvent(event: any): event is StoredEvent {\n return event &&\n typeof event.event === 'object' &&\n typeof event.event.id === 'string' &&\n typeof event.event.timestamp === 'string' &&\n typeof event.event.resourceId === 'string' &&\n typeof event.event.type === 'string' &&\n typeof event.metadata === 'object' &&\n typeof event.metadata.sequenceNumber === 'number';\n}\n\n// =============================================================================\n// EVENT FORMATTING AND DISPLAY\n// =============================================================================\n\n/**\n * Format event type for display with i18n support\n */\nexport function formatEventType(type: ResourceEventType, t: TranslateFn, payload?: any): string {\n switch (type) {\n case 'resource.created':\n return t('resourceCreated');\n case 'resource.cloned':\n return t('resourceCloned');\n case 'resource.archived':\n return t('resourceArchived');\n case 'resource.unarchived':\n return t('resourceUnarchived');\n\n case 'annotation.added': {\n const motivation = payload?.annotation?.motivation;\n if (motivation === 'highlighting') return t('highlightAdded');\n if (motivation === 'linking') return t('referenceCreated');\n if (motivation === 'assessing') return t('assessmentAdded');\n return t('annotationAdded');\n }\n case 'annotation.removed': {\n return t('annotationRemoved');\n }\n case 'annotation.body.updated': {\n return t('annotationBodyUpdated');\n }\n\n case 'entitytag.added':\n return t('entitytagAdded');\n case 'entitytag.removed':\n return t('entitytagRemoved');\n case 'entitytype.added':\n return t('entitytypeAdded');\n\n case 'job.completed':\n case 'job.started':\n case 'job.progress':\n case 'job.failed':\n return t('jobEvent');\n\n default:\n const _exhaustiveCheck: never = type;\n return _exhaustiveCheck;\n }\n}\n\n/**\n * Get emoji for event type\n * For unified annotation events, pass the payload to determine motivation\n */\nexport function getEventEmoji(type: ResourceEventType, payload?: any): string {\n switch (type) {\n case 'resource.created':\n case 'resource.cloned':\n case 'resource.archived':\n case 'resource.unarchived':\n return '📄';\n\n case 'annotation.added': {\n const motivation = payload?.annotation?.motivation;\n if (motivation === 'highlighting') return '🟡';\n if (motivation === 'linking') return '🔵';\n if (motivation === 'assessing') return '🔴';\n return '📝';\n }\n case 'annotation.removed': {\n return '🗑️';\n }\n case 'annotation.body.updated': {\n return '✏️';\n }\n\n case 'entitytag.added':\n case 'entitytag.removed':\n return '🏷️';\n case 'entitytype.added':\n return '🏷️'; // Same emoji as entitytag (global entity type collection)\n\n case 'job.completed':\n return '🔗'; // Link emoji for linked document creation\n case 'job.started':\n case 'job.progress':\n return '⚙️'; // Gear for job processing\n case 'job.failed':\n return '❌'; // X mark for failed jobs\n\n default:\n const _exhaustiveCheck: never = type;\n return _exhaustiveCheck;\n }\n}\n\n/**\n * Format timestamp as relative time with i18n support\n */\nexport function formatRelativeTime(timestamp: string, t: TranslateFn): string {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return t('justNow');\n if (diffMins < 60) return t('minutesAgo', { count: diffMins });\n if (diffHours < 24) return t('hoursAgo', { count: diffHours });\n if (diffDays < 7) return t('daysAgo', { count: diffDays });\n\n return date.toLocaleDateString();\n}\n\n/**\n * Helper to truncate text for display\n */\nfunction truncateText(text: string, maxLength = 50): string {\n const trimmed = text.trim();\n return trimmed.length > maxLength ? trimmed.substring(0, maxLength) + '...' : trimmed;\n}\n\n/**\n * Get display content from event payload - complete implementation\n */\nexport function getEventDisplayContent(\n event: StoredEvent,\n annotations: Annotation[], // Unified annotations array (all types)\n allEvents: StoredEvent[]\n): { exact: string; isQuoted: boolean; isTag: boolean } | null {\n const eventData = event.event;\n const payload = eventData.payload as any;\n\n // Use type discriminators instead of runtime typeof checks\n switch (eventData.type) {\n case 'resource.created':\n case 'resource.cloned': {\n return { exact: payload.name, isQuoted: false, isTag: false };\n }\n\n // Unified annotation events\n case 'annotation.body.updated': {\n // Find current annotation to get its text\n // payload.annotationId is just the UUID, but annotation.id is the full URI\n const annotation = annotations.find(a =>\n a.id.endsWith(`/annotations/${payload.annotationId}`)\n );\n\n if (annotation?.target) {\n try {\n const targetSelector = getTargetSelector(annotation.target);\n const exact = getExactText(targetSelector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, continue to return null\n }\n }\n return null;\n }\n\n case 'annotation.removed': {\n // Find the original annotation.added event to get the text\n // payload.annotationId is just the UUID, but annotation.id in the added event is the full URI\n const addedEvent = allEvents.find(e =>\n e.event.type === 'annotation.added' &&\n (e.event.payload as any).annotation?.id?.endsWith(`/annotations/${payload.annotationId}`)\n );\n if (addedEvent) {\n const addedPayload = addedEvent.event.payload as any;\n try {\n const exact = getExactText(addedPayload.annotation.target.selector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, return null\n }\n }\n return null;\n }\n\n case 'annotation.added': {\n // New unified event structure - annotation is in payload\n try {\n const exact = getExactText(payload.annotation.target.selector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, return null\n }\n return null;\n }\n\n case 'entitytag.added':\n case 'entitytag.removed': {\n return { exact: payload.entityType, isQuoted: false, isTag: true };\n }\n\n case 'job.completed': {\n // Find the annotation that was used to generate the resource\n if (payload.annotationUri) {\n const annotation = annotations.find(a =>\n a.id === payload.annotationUri\n );\n\n if (annotation?.target) {\n try {\n const targetSelector = getTargetSelector(annotation.target);\n const exact = getExactText(targetSelector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, continue to return null\n }\n }\n }\n return null;\n }\n\n default:\n return null;\n }\n}\n\n/**\n * Get entity types from event payload\n */\nexport function getEventEntityTypes(event: StoredEvent): string[] {\n const eventData = event.event;\n\n if (eventData.type === 'annotation.added') {\n const payload = eventData.payload as any;\n const motivation = payload?.annotation?.motivation;\n if (motivation === 'linking') {\n return payload.annotation?.body?.entityTypes ?? [];\n }\n }\n\n return [];\n}\n\n/**\n * Resource creation details\n */\nexport interface ResourceCreationDetails {\n type: 'created' | 'cloned';\n method: string;\n userId?: string;\n sourceDocId?: string; // For cloned resources\n parentResourceId?: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * Get resource creation details from event\n */\nexport function getResourceCreationDetails(event: StoredEvent): ResourceCreationDetails | null {\n const eventData = event.event;\n const payload = eventData.payload as any;\n\n if (eventData.type === 'resource.created') {\n return {\n type: 'created',\n method: payload.creationMethod || 'unknown',\n userId: eventData.userId,\n metadata: payload.metadata,\n };\n }\n\n if (eventData.type === 'resource.cloned') {\n return {\n type: 'cloned',\n method: payload.creationMethod || 'clone',\n userId: eventData.userId,\n sourceDocId: payload.parentResourceId,\n parentResourceId: payload.parentResourceId,\n metadata: payload.metadata,\n };\n }\n\n return null;\n}\n","/**\n * Fuzzy Anchoring for W3C Web Annotation TextQuoteSelector\n *\n * Uses prefix/suffix context to disambiguate when the same text appears multiple times.\n * Implements fuzzy matching as specified in the W3C Web Annotation Data Model.\n *\n * @see https://www.w3.org/TR/annotation-model/#text-quote-selector\n */\n\nexport interface TextPosition {\n start: number;\n end: number;\n}\n\n/**\n * Find text using exact match with optional prefix/suffix context\n *\n * When the exact text appears multiple times in the content, prefix and suffix\n * are used to disambiguate and find the correct occurrence.\n *\n * @param content - Full text content to search within\n * @param exact - The exact text to find\n * @param prefix - Optional text that should appear immediately before the match\n * @param suffix - Optional text that should appear immediately after the match\n * @returns Position of the matched text, or null if not found\n *\n * @example\n * ```typescript\n * const content = \"The cat sat. The cat ran.\";\n * // Find second \"The cat\" occurrence\n * const pos = findTextWithContext(content, \"The cat\", \"sat. \", \" ran\");\n * // Returns { start: 13, end: 20 }\n * ```\n */\nexport function findTextWithContext(\n content: string,\n exact: string,\n prefix?: string,\n suffix?: string\n): TextPosition | null {\n if (!exact) return null;\n\n // Find all occurrences of exact text\n const occurrences: number[] = [];\n let index = content.indexOf(exact);\n while (index !== -1) {\n occurrences.push(index);\n index = content.indexOf(exact, index + 1);\n }\n\n // No matches found\n if (occurrences.length === 0) {\n console.warn(`[FuzzyAnchor] Text not found: \"${exact.substring(0, 50)}...\"`);\n return null;\n }\n\n // Only one match - no need for prefix/suffix disambiguation\n if (occurrences.length === 1) {\n const pos = occurrences[0]!; // Safe: length === 1 means first element exists\n return { start: pos, end: pos + exact.length };\n }\n\n // Multiple matches - use prefix/suffix to disambiguate\n if (prefix || suffix) {\n for (const pos of occurrences) {\n // Extract actual prefix from content\n const actualPrefixStart = Math.max(0, pos - (prefix?.length || 0));\n const actualPrefix = content.substring(actualPrefixStart, pos);\n\n // Extract actual suffix from content\n const actualSuffixEnd = Math.min(content.length, pos + exact.length + (suffix?.length || 0));\n const actualSuffix = content.substring(pos + exact.length, actualSuffixEnd);\n\n // Check if prefix matches\n const prefixMatch = !prefix || actualPrefix.endsWith(prefix);\n\n // Check if suffix matches\n const suffixMatch = !suffix || actualSuffix.startsWith(suffix);\n\n if (prefixMatch && suffixMatch) {\n return { start: pos, end: pos + exact.length };\n }\n }\n\n // No match with exact prefix/suffix - try fuzzy matching\n console.warn(\n `[FuzzyAnchor] Multiple matches found but none match prefix/suffix exactly. ` +\n `Exact: \"${exact.substring(0, 30)}...\", ` +\n `Prefix: \"${prefix?.substring(0, 20) || 'none'}\", ` +\n `Suffix: \"${suffix?.substring(0, 20) || 'none'}\"`\n );\n\n // Fallback: try partial prefix/suffix match\n for (const pos of occurrences) {\n const actualPrefix = content.substring(Math.max(0, pos - (prefix?.length || 0)), pos);\n const actualSuffix = content.substring(pos + exact.length, pos + exact.length + (suffix?.length || 0));\n\n // Fuzzy match: check if prefix/suffix are substrings (handles whitespace variations)\n const fuzzyPrefixMatch = !prefix || actualPrefix.includes(prefix.trim());\n const fuzzySuffixMatch = !suffix || actualSuffix.includes(suffix.trim());\n\n if (fuzzyPrefixMatch && fuzzySuffixMatch) {\n console.warn(`[FuzzyAnchor] Using fuzzy match at position ${pos}`);\n return { start: pos, end: pos + exact.length };\n }\n }\n }\n\n // Fallback: return first occurrence if no prefix/suffix or no match\n console.warn(\n `[FuzzyAnchor] Multiple matches but no context match. Using first occurrence. ` +\n `Exact: \"${exact.substring(0, 30)}...\"`\n );\n const pos = occurrences[0]!; // Safe: we checked length > 0 earlier\n return { start: pos, end: pos + exact.length };\n}\n\n/**\n * Verify that a position correctly points to the exact text\n * Useful for debugging and validation\n */\nexport function verifyPosition(\n content: string,\n position: TextPosition,\n expectedExact: string\n): boolean {\n const actualText = content.substring(position.start, position.end);\n return actualText === expectedExact;\n}\n","/**\n * Locale information\n * Copied from SDK for frontend use\n */\n\nexport interface LocaleInfo {\n code: string;\n nativeName: string;\n englishName: string;\n}\n\nexport const LOCALES: readonly LocaleInfo[] = [\n { code: 'ar', nativeName: 'العربية', englishName: 'Arabic' },\n { code: 'bn', nativeName: 'বাংলা', englishName: 'Bengali' },\n { code: 'cs', nativeName: 'Čeština', englishName: 'Czech' },\n { code: 'da', nativeName: 'Dansk', englishName: 'Danish' },\n { code: 'de', nativeName: 'Deutsch', englishName: 'German' },\n { code: 'el', nativeName: 'Ελληνικά', englishName: 'Greek' },\n { code: 'en', nativeName: 'English', englishName: 'English' },\n { code: 'es', nativeName: 'Español', englishName: 'Spanish' },\n { code: 'fa', nativeName: 'فارسی', englishName: 'Persian' },\n { code: 'fi', nativeName: 'Suomi', englishName: 'Finnish' },\n { code: 'fr', nativeName: 'Français', englishName: 'French' },\n { code: 'he', nativeName: 'עברית', englishName: 'Hebrew' },\n { code: 'hi', nativeName: 'हिन्दी', englishName: 'Hindi' },\n { code: 'id', nativeName: 'Bahasa Indonesia', englishName: 'Indonesian' },\n { code: 'it', nativeName: 'Italiano', englishName: 'Italian' },\n { code: 'ja', nativeName: '日本語', englishName: 'Japanese' },\n { code: 'ko', nativeName: '한국어', englishName: 'Korean' },\n { code: 'ms', nativeName: 'Bahasa Melayu', englishName: 'Malay' },\n { code: 'nl', nativeName: 'Nederlands', englishName: 'Dutch' },\n { code: 'no', nativeName: 'Norsk', englishName: 'Norwegian' },\n { code: 'pl', nativeName: 'Polski', englishName: 'Polish' },\n { code: 'pt', nativeName: 'Português', englishName: 'Portuguese' },\n { code: 'ro', nativeName: 'Română', englishName: 'Romanian' },\n { code: 'sv', nativeName: 'Svenska', englishName: 'Swedish' },\n { code: 'th', nativeName: 'ไทย', englishName: 'Thai' },\n { code: 'tr', nativeName: 'Türkçe', englishName: 'Turkish' },\n { code: 'uk', nativeName: 'Українська', englishName: 'Ukrainian' },\n { code: 'vi', nativeName: 'Tiếng Việt', englishName: 'Vietnamese' },\n { code: 'zh', nativeName: '中文', englishName: 'Chinese' },\n] as const;\n\n// Create lookup map for efficient access\nconst localeByCode = new Map<string, LocaleInfo>(\n LOCALES.map(locale => [locale.code.toLowerCase(), locale])\n);\n\n/**\n * Get locale information by code\n */\nexport function getLocaleInfo(code: string | undefined): LocaleInfo | undefined {\n if (!code) return undefined;\n return localeByCode.get(code.toLowerCase());\n}\n\n/**\n * Get the native name of a language by its locale code\n */\nexport function getLocaleNativeName(code: string | undefined): string | undefined {\n return getLocaleInfo(code)?.nativeName;\n}\n\n/**\n * Get the English name of a language by its locale code\n */\nexport function getLocaleEnglishName(code: string | undefined): string | undefined {\n return getLocaleInfo(code)?.englishName;\n}\n\n/**\n * Format locale code for display as \"Native Name (code)\"\n */\nexport function formatLocaleDisplay(code: string | undefined): string | undefined {\n if (!code) return undefined;\n\n const info = getLocaleInfo(code);\n if (!info) return code;\n\n return `${info.nativeName} (${code.toLowerCase()})`;\n}\n\n/**\n * Get all supported locale codes\n */\nexport function getAllLocaleCodes(): readonly string[] {\n return LOCALES.map(l => l.code);\n}\n","/**\n * Helper functions for working with W3C ResourceDescriptor\n */\n\nimport type { components } from '../types';\n\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\ntype Representation = components['schemas']['Representation'];\n\n/**\n * Get the resource ID from @id property\n *\n * For internal resources: extracts UUID from \"http://localhost:4000/resources/{uuid}\"\n * For external resources: returns undefined\n *\n * This is used for routing - the frontend URL should contain only the resource ID,\n * not the full HTTP URI.\n */\nexport function getResourceId(resource: ResourceDescriptor | undefined): string | undefined {\n if (!resource) return undefined;\n\n const fullId = resource['@id'];\n\n // For internal resources, extract the last path segment\n // http://localhost:4000/resources/{uuid} -> {uuid}\n if (fullId.includes('/resources/')) {\n const parts = fullId.split('/resources/');\n const lastPart = parts[parts.length - 1];\n return lastPart || undefined;\n }\n\n // For external resources, cannot extract ID\n return undefined;\n}\n\n/**\n * Get the primary representation (first or only representation)\n */\nexport function getPrimaryRepresentation(resource: ResourceDescriptor | undefined): Representation | undefined {\n if (!resource?.representations) return undefined;\n const reps = Array.isArray(resource.representations)\n ? resource.representations\n : [resource.representations];\n return reps[0];\n}\n\n/**\n * Get the media type from the primary representation\n */\nexport function getPrimaryMediaType(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.mediaType;\n}\n\n/**\n * Get the checksum from the primary representation\n */\nexport function getChecksum(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.checksum;\n}\n\n/**\n * Get the language from the primary representation\n */\nexport function getLanguage(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.language;\n}\n\n/**\n * Get storage URI from primary representation\n *\n * @param resource - ResourceDescriptor\n * @returns Storage URI or undefined\n */\nexport function getStorageUri(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.storageUri;\n}\n\n/**\n * Get creator agent from wasAttributedTo\n * Handles both single agent and array of agents\n *\n * @param resource - ResourceDescriptor\n * @returns First agent or undefined\n */\nexport function getCreator(resource: ResourceDescriptor | undefined): components['schemas']['Agent'] | undefined {\n if (!resource?.wasAttributedTo) return undefined;\n\n return Array.isArray(resource.wasAttributedTo)\n ? resource.wasAttributedTo[0]\n : resource.wasAttributedTo;\n}\n\n/**\n * Get derived-from URI\n * Handles both single URI and array of URIs\n *\n * @param resource - ResourceDescriptor\n * @returns First derivation URI or undefined\n */\nexport function getDerivedFrom(resource: ResourceDescriptor | undefined): string | undefined {\n if (!resource?.wasDerivedFrom) return undefined;\n\n return Array.isArray(resource.wasDerivedFrom)\n ? resource.wasDerivedFrom[0]\n : resource.wasDerivedFrom;\n}\n\n/**\n * Check if resource is archived (application-specific field)\n *\n * @param resource - ResourceDescriptor\n * @returns True if archived, false otherwise\n */\nexport function isArchived(resource: ResourceDescriptor | undefined): boolean {\n return resource?.archived === true;\n}\n\n/**\n * Get entity types from resource (application-specific field)\n *\n * @param resource - ResourceDescriptor\n * @returns Array of entity types, empty if not set\n */\nexport function getResourceEntityTypes(resource: ResourceDescriptor | undefined): string[] {\n return resource?.entityTypes || [];\n}\n\n/**\n * Check if resource is a draft (application-specific field)\n *\n * @param resource - ResourceDescriptor\n * @returns True if draft, false otherwise\n */\nexport function isDraft(resource: ResourceDescriptor | undefined): boolean {\n return resource?.isDraft === true;\n}\n\n/**\n * Map charset names to Node.js Buffer encoding names\n * Node.js Buffer.toString() supports: 'utf8', 'utf16le', 'latin1', 'base64', 'hex', 'ascii', 'binary', 'ucs2'\n *\n * @param charset - Charset name (e.g., \"UTF-8\", \"ISO-8859-1\", \"Windows-1252\")\n * @returns Node.js BufferEncoding\n */\nexport function getNodeEncoding(charset: string): BufferEncoding {\n const normalized = charset.toLowerCase().replace(/[-_]/g, '');\n\n // Map common charset names to Node.js encodings\n const charsetMap: Record<string, BufferEncoding> = {\n 'utf8': 'utf8',\n 'iso88591': 'latin1',\n 'latin1': 'latin1',\n 'ascii': 'ascii',\n 'usascii': 'ascii',\n 'utf16le': 'utf16le',\n 'ucs2': 'ucs2',\n 'binary': 'binary',\n 'windows1252': 'latin1', // Windows-1252 is a superset of Latin-1\n 'cp1252': 'latin1',\n };\n\n return charsetMap[normalized] || 'utf8';\n}\n\n/**\n * Decode a representation buffer to string using the correct charset\n * Extracts charset from media type and uses appropriate encoding\n *\n * @param buffer - The raw representation data\n * @param mediaType - Media type with optional charset (e.g., \"text/plain; charset=iso-8859-1\")\n * @returns Decoded string\n *\n * @example\n * ```typescript\n * const content = decodeRepresentation(buffer, \"text/plain; charset=utf-8\");\n * const legacy = decodeRepresentation(buffer, \"text/plain; charset=windows-1252\");\n * ```\n */\nexport function decodeRepresentation(buffer: Buffer, mediaType: string): string {\n // Extract charset from mediaType (e.g., \"text/plain; charset=iso-8859-1\")\n const charsetMatch = mediaType.match(/charset=([^\\s;]+)/i);\n const charset = (charsetMatch?.[1] || 'utf-8').toLowerCase();\n\n // Map to Node.js encoding\n const encoding = getNodeEncoding(charset);\n\n return buffer.toString(encoding);\n}\n","/**\n * SVG Utility Functions\n *\n * Utilities for creating, parsing, and manipulating W3C-compliant SVG selectors\n * for image annotation.\n */\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface BoundingBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Create W3C-compliant SVG rectangle selector\n */\nexport function createRectangleSvg(start: Point, end: Point): string {\n const x = Math.min(start.x, end.x);\n const y = Math.min(start.y, end.y);\n const width = Math.abs(end.x - start.x);\n const height = Math.abs(end.y - start.y);\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"${x}\" y=\"${y}\" width=\"${width}\" height=\"${height}\"/></svg>`;\n}\n\n/**\n * Create W3C-compliant SVG polygon selector\n */\nexport function createPolygonSvg(points: Point[]): string {\n if (points.length < 3) {\n throw new Error('Polygon requires at least 3 points');\n }\n\n const pointsStr = points.map(p => `${p.x},${p.y}`).join(' ');\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"${pointsStr}\"/></svg>`;\n}\n\n/**\n * Create W3C-compliant SVG circle selector\n */\nexport function createCircleSvg(center: Point, radius: number): string {\n if (radius <= 0) {\n throw new Error('Circle radius must be positive');\n }\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"${center.x}\" cy=\"${center.y}\" r=\"${radius}\"/></svg>`;\n}\n\n/**\n * Parse SVG selector to extract shape type and data\n */\nexport function parseSvgSelector(svg: string): {\n type: 'rect' | 'polygon' | 'circle' | 'path';\n data: any;\n} | null {\n // Extract rectangle\n const rectMatch = svg.match(/<rect\\s+([^>]+)\\/>/);\n if (rectMatch && rectMatch[1]) {\n const attrs = rectMatch[1];\n const x = parseFloat(attrs.match(/x=\"([^\"]+)\"/)?.[1] || '0');\n const y = parseFloat(attrs.match(/y=\"([^\"]+)\"/)?.[1] || '0');\n const width = parseFloat(attrs.match(/width=\"([^\"]+)\"/)?.[1] || '0');\n const height = parseFloat(attrs.match(/height=\"([^\"]+)\"/)?.[1] || '0');\n\n return {\n type: 'rect',\n data: { x, y, width, height }\n };\n }\n\n // Extract polygon\n const polygonMatch = svg.match(/<polygon\\s+points=\"([^\"]+)\"/);\n if (polygonMatch && polygonMatch[1]) {\n const pointsStr = polygonMatch[1];\n const points = pointsStr.split(/\\s+/).map(pair => {\n const [x, y] = pair.split(',').map(parseFloat);\n return { x, y };\n });\n\n return {\n type: 'polygon',\n data: { points }\n };\n }\n\n // Extract circle\n const circleMatch = svg.match(/<circle\\s+([^>]+)\\/>/);\n if (circleMatch && circleMatch[1]) {\n const attrs = circleMatch[1];\n const cx = parseFloat(attrs.match(/cx=\"([^\"]+)\"/)?.[1] || '0');\n const cy = parseFloat(attrs.match(/cy=\"([^\"]+)\"/)?.[1] || '0');\n const r = parseFloat(attrs.match(/r=\"([^\"]+)\"/)?.[1] || '0');\n\n return {\n type: 'circle',\n data: { cx, cy, r }\n };\n }\n\n return null;\n}\n\n/**\n * Normalize coordinates from display space to image native resolution\n */\nexport function normalizeCoordinates(\n point: Point,\n displayWidth: number,\n displayHeight: number,\n imageWidth: number,\n imageHeight: number\n): Point {\n return {\n x: (point.x / displayWidth) * imageWidth,\n y: (point.y / displayHeight) * imageHeight\n };\n}\n\n/**\n * Scale entire SVG selector from display space to image native resolution\n */\nexport function scaleSvgToNative(\n svg: string,\n displayWidth: number,\n displayHeight: number,\n imageWidth: number,\n imageHeight: number\n): string {\n const parsed = parseSvgSelector(svg);\n if (!parsed) return svg;\n\n const scaleX = imageWidth / displayWidth;\n const scaleY = imageHeight / displayHeight;\n\n switch (parsed.type) {\n case 'rect': {\n const { x, y, width, height } = parsed.data;\n return createRectangleSvg(\n { x: x * scaleX, y: y * scaleY },\n { x: (x + width) * scaleX, y: (y + height) * scaleY }\n );\n }\n\n case 'circle': {\n const { cx, cy, r } = parsed.data;\n return createCircleSvg(\n { x: cx * scaleX, y: cy * scaleY },\n r * Math.min(scaleX, scaleY)\n );\n }\n\n case 'polygon': {\n const points = parsed.data.points.map((p: Point) => ({\n x: p.x * scaleX,\n y: p.y * scaleY\n }));\n return createPolygonSvg(points);\n }\n }\n\n return svg;\n}\n","/**\n * Text context extraction utilities for W3C Web Annotation TextQuoteSelector\n *\n * Provides robust prefix/suffix context extraction with word boundary detection\n * to ensure fuzzy anchoring works correctly when the same text appears multiple times.\n *\n * Also provides AI offset validation and correction for handling AI-generated annotations\n * where the model may return slightly incorrect character offsets.\n *\n * @see https://www.w3.org/TR/annotation-model/#text-quote-selector\n */\n\n/**\n * Extract prefix and suffix context for TextQuoteSelector\n *\n * Extracts up to 64 characters before and after the selected text,\n * extending to word boundaries to avoid cutting words in half.\n * This ensures prefix/suffix are meaningful context for fuzzy anchoring.\n *\n * @param content - Full text content\n * @param start - Start offset of selection\n * @param end - End offset of selection\n * @returns Object with prefix and suffix (undefined if at boundaries)\n *\n * @example\n * ```typescript\n * const content = \"The United States Congress...\";\n * const context = extractContext(content, 4, 17); // \"United States\"\n * // Returns: { prefix: \"The \", suffix: \" Congress...\" }\n * // NOT: { prefix: \"nited \", suffix: \"gress...\" }\n * ```\n */\nexport function extractContext(\n content: string,\n start: number,\n end: number\n): { prefix?: string; suffix?: string } {\n const CONTEXT_LENGTH = 64;\n const MAX_EXTENSION = 32; // Maximum additional chars to extend for word boundary\n\n // Extract prefix (up to CONTEXT_LENGTH chars before start, extended to word boundary)\n let prefix: string | undefined;\n if (start > 0) {\n let prefixStart = Math.max(0, start - CONTEXT_LENGTH);\n\n // Extend backward to word boundary (whitespace or punctuation)\n // Stop if we hit start of content or exceed MAX_EXTENSION\n let extensionCount = 0;\n while (prefixStart > 0 && extensionCount < MAX_EXTENSION) {\n const char = content[prefixStart - 1];\n // Break on whitespace, punctuation, or common delimiters\n if (!char || /[\\s.,;:!?'\"()\\[\\]{}<>\\/\\\\]/.test(char)) {\n break;\n }\n prefixStart--;\n extensionCount++;\n }\n\n prefix = content.substring(prefixStart, start);\n }\n\n // Extract suffix (up to CONTEXT_LENGTH chars after end, extended to word boundary)\n let suffix: string | undefined;\n if (end < content.length) {\n let suffixEnd = Math.min(content.length, end + CONTEXT_LENGTH);\n\n // Extend forward to word boundary (whitespace or punctuation)\n // Stop if we hit end of content or exceed MAX_EXTENSION\n let extensionCount = 0;\n while (suffixEnd < content.length && extensionCount < MAX_EXTENSION) {\n const char = content[suffixEnd];\n // Break on whitespace, punctuation, or common delimiters\n if (!char || /[\\s.,;:!?'\"()\\[\\]{}<>\\/\\\\]/.test(char)) {\n break;\n }\n suffixEnd++;\n extensionCount++;\n }\n\n suffix = content.substring(end, suffixEnd);\n }\n\n return { prefix, suffix };\n}\n\n/**\n * Result of validating and correcting AI-provided annotation offsets\n */\nexport interface ValidatedAnnotation {\n start: number;\n end: number;\n exact: string;\n prefix?: string;\n suffix?: string;\n corrected: boolean; // True if offsets were adjusted from AI's original values\n fuzzyMatched?: boolean; // True if we had to use fuzzy matching (minor text differences)\n matchQuality?: 'exact' | 'case-insensitive' | 'fuzzy'; // How we found the match\n}\n\n/**\n * Calculate Levenshtein distance between two strings\n * Used for fuzzy matching when exact text doesn't match\n */\nfunction levenshteinDistance(str1: string, str2: string): number {\n const len1 = str1.length;\n const len2 = str2.length;\n const matrix: number[][] = [];\n\n // Initialize matrix\n for (let i = 0; i <= len1; i++) {\n matrix[i] = [i];\n }\n for (let j = 0; j <= len2; j++) {\n matrix[0]![j] = j;\n }\n\n // Fill matrix\n for (let i = 1; i <= len1; i++) {\n for (let j = 1; j <= len2; j++) {\n const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;\n const deletion = matrix[i - 1]![j]! + 1;\n const insertion = matrix[i]![j - 1]! + 1;\n const substitution = matrix[i - 1]![j - 1]! + cost;\n matrix[i]![j] = Math.min(deletion, insertion, substitution);\n }\n }\n\n return matrix[len1]![len2]!;\n}\n\n/**\n * Find best match for text in content using various strategies\n * Returns { start, end, matchQuality } or null if no acceptable match found\n */\nfunction findBestMatch(\n content: string,\n searchText: string,\n aiStart: number,\n aiEnd: number\n): { start: number; end: number; matchQuality: 'exact' | 'case-insensitive' | 'fuzzy' } | null {\n const maxFuzzyDistance = Math.max(5, Math.floor(searchText.length * 0.05)); // 5% tolerance or minimum 5 chars\n\n // Strategy 1: Exact match (case-sensitive)\n const exactIndex = content.indexOf(searchText);\n if (exactIndex !== -1) {\n return {\n start: exactIndex,\n end: exactIndex + searchText.length,\n matchQuality: 'exact'\n };\n }\n\n console.log('[findBestMatch] Exact match failed, trying case-insensitive...');\n\n // Strategy 2: Case-insensitive match\n const lowerContent = content.toLowerCase();\n const lowerSearch = searchText.toLowerCase();\n const caseInsensitiveIndex = lowerContent.indexOf(lowerSearch);\n if (caseInsensitiveIndex !== -1) {\n console.log('[findBestMatch] Found case-insensitive match');\n return {\n start: caseInsensitiveIndex,\n end: caseInsensitiveIndex + searchText.length,\n matchQuality: 'case-insensitive'\n };\n }\n\n console.log('[findBestMatch] Case-insensitive failed, trying fuzzy match...');\n\n // Strategy 3: Fuzzy match using sliding window\n // Search near AI's suggested position first, then expand outward\n const windowSize = searchText.length;\n const searchRadius = Math.min(500, content.length); // Search within 500 chars of AI position\n const searchStart = Math.max(0, aiStart - searchRadius);\n const searchEnd = Math.min(content.length, aiEnd + searchRadius);\n\n let bestMatch: { start: number; distance: number } | null = null;\n\n // Scan through content with sliding window\n for (let i = searchStart; i <= searchEnd - windowSize; i++) {\n const candidate = content.substring(i, i + windowSize);\n const distance = levenshteinDistance(searchText, candidate);\n\n if (distance <= maxFuzzyDistance) {\n if (!bestMatch || distance < bestMatch.distance) {\n bestMatch = { start: i, distance };\n console.log(`[findBestMatch] Found fuzzy match at ${i} with distance ${distance}`);\n }\n }\n }\n\n if (bestMatch) {\n return {\n start: bestMatch.start,\n end: bestMatch.start + windowSize,\n matchQuality: 'fuzzy'\n };\n }\n\n console.log('[findBestMatch] No acceptable match found');\n return null;\n}\n\n/**\n * Validate and correct AI-provided annotation offsets with fuzzy matching tolerance\n *\n * AI models sometimes return offsets that don't match the actual text position,\n * or provide text with minor variations (case differences, whitespace, typos).\n *\n * This function uses a multi-strategy approach:\n * 1. Check if AI's offsets are exactly correct\n * 2. Try exact case-sensitive search\n * 3. Try case-insensitive search\n * 4. Try fuzzy matching with Levenshtein distance (5% tolerance)\n *\n * This ensures we're maximally tolerant of AI errors while still maintaining\n * annotation quality and logging what corrections were made.\n *\n * @param content - Full text content\n * @param aiStart - Start offset from AI\n * @param aiEnd - End offset from AI\n * @param exact - The exact text that should be at this position (from AI)\n * @returns Validated annotation with corrected offsets and context\n * @throws Error if no acceptable match can be found\n *\n * @example\n * ```typescript\n * // AI said start=1143, but actual text is at 1161\n * const result = validateAndCorrectOffsets(\n * content,\n * 1143,\n * 1289,\n * \"the question \\\"whether...\"\n * );\n * // Returns: { start: 1161, end: 1303, exact: \"...\", corrected: true, matchQuality: 'exact', ... }\n * ```\n */\nexport function validateAndCorrectOffsets(\n content: string,\n aiStart: number,\n aiEnd: number,\n exact: string\n): ValidatedAnnotation {\n const exactPreview = exact.length > 50 ? exact.substring(0, 50) + '...' : exact;\n\n // First, check if AI's offsets are correct\n const textAtOffset = content.substring(aiStart, aiEnd);\n\n if (textAtOffset === exact) {\n // AI got it right! Just add proper context\n console.log(`[validateAndCorrectOffsets] ✓ Offsets correct for: \"${exactPreview}\"`);\n const context = extractContext(content, aiStart, aiEnd);\n return {\n start: aiStart,\n end: aiEnd,\n exact,\n prefix: context.prefix,\n suffix: context.suffix,\n corrected: false,\n matchQuality: 'exact'\n };\n }\n\n // AI's offsets are wrong - try to find the text using multiple strategies\n const foundPreview = textAtOffset.length > 50 ? textAtOffset.substring(0, 50) + '...' : textAtOffset;\n\n console.warn(\n '[validateAndCorrectOffsets] ⚠ AI offset mismatch:\\n' +\n ` Expected text: \"${exactPreview}\"\\n` +\n ` Found at AI offset (${aiStart}-${aiEnd}): \"${foundPreview}\"\\n` +\n ` Attempting multi-strategy search...`\n );\n\n const match = findBestMatch(content, exact, aiStart, aiEnd);\n\n if (!match) {\n const exactLong = exact.length > 100 ? exact.substring(0, 100) + '...' : exact;\n console.error(\n '[validateAndCorrectOffsets] ✗ No acceptable match found:\\n' +\n ` AI offsets: start=${aiStart}, end=${aiEnd}\\n` +\n ` AI text: \"${exactLong}\"\\n` +\n ` Text at AI offset: \"${foundPreview}\"\\n` +\n ' All search strategies (exact, case-insensitive, fuzzy) failed.\\n' +\n ' This suggests the AI hallucinated text that doesn\\'t exist in the document.'\n );\n throw new Error(\n 'Cannot find acceptable match for text in content. ' +\n 'All search strategies failed. Text may be hallucinated.'\n );\n }\n\n // Found a match! Extract the actual text from content\n const actualText = content.substring(match.start, match.end);\n const actualPreview = actualText.length > 50 ? actualText.substring(0, 50) + '...' : actualText;\n\n const offsetDelta = match.start - aiStart;\n const matchSymbol = match.matchQuality === 'exact' ? '✓' : match.matchQuality === 'case-insensitive' ? '≈' : '~';\n\n console.warn(\n `[validateAndCorrectOffsets] ${matchSymbol} Found ${match.matchQuality} match:\\n` +\n ` AI offsets: start=${aiStart}, end=${aiEnd}\\n` +\n ` Corrected: start=${match.start}, end=${match.end}\\n` +\n ` Offset delta: ${offsetDelta} characters\\n` +\n ` Actual text: \"${actualPreview}\"`\n );\n\n // If fuzzy match, log the difference for debugging\n if (match.matchQuality === 'fuzzy') {\n console.warn(\n '[validateAndCorrectOffsets] Fuzzy match details:\\n' +\n ` AI provided: \"${exactPreview}\"\\n` +\n ` Found in doc: \"${actualPreview}\"\\n` +\n ' Minor text differences detected - using document version'\n );\n }\n\n // Extract context using corrected offsets\n const context = extractContext(content, match.start, match.end);\n\n return {\n start: match.start,\n end: match.end,\n exact: actualText, // Use actual text from document, not AI's version\n prefix: context.prefix,\n suffix: context.suffix,\n corrected: true,\n fuzzyMatched: match.matchQuality !== 'exact',\n matchQuality: match.matchQuality\n };\n}\n","/**\n * Text encoding utilities for consistent charset handling\n *\n * Ensures frontend decoding matches backend decoding by respecting\n * charset parameters in mediaType (e.g., \"text/plain; charset=iso-8859-1\")\n */\n\n/**\n * Extract charset from mediaType parameter\n *\n * @param mediaType - Media type with optional charset (e.g., \"text/plain; charset=utf-8\")\n * @returns Charset name in lowercase (defaults to \"utf-8\")\n *\n * @example\n * extractCharset(\"text/plain; charset=iso-8859-1\") // \"iso-8859-1\"\n * extractCharset(\"text/plain\") // \"utf-8\"\n */\nexport function extractCharset(mediaType: string): string {\n const charsetMatch = mediaType.match(/charset=([^\\s;]+)/i);\n return (charsetMatch?.[1] || 'utf-8').toLowerCase();\n}\n\n/**\n * Decode ArrayBuffer to string using charset from mediaType\n *\n * Uses TextDecoder with the charset extracted from mediaType parameter.\n * This ensures the same character space is used for both annotation creation\n * (backend) and rendering (frontend).\n *\n * @param buffer - Binary data to decode\n * @param mediaType - Media type with optional charset parameter\n * @returns Decoded string in the original character space\n *\n * @example\n * const buffer = new Uint8Array([...]);\n * const text = decodeWithCharset(buffer, \"text/plain; charset=iso-8859-1\");\n */\nexport function decodeWithCharset(buffer: ArrayBuffer, mediaType: string): string {\n const charset = extractCharset(mediaType);\n\n // TextDecoder supports standard charset names\n // Common mappings that work in browsers:\n // - utf-8, utf-16, utf-16le, utf-16be\n // - iso-8859-1 through iso-8859-15\n // - windows-1252, windows-1251, etc.\n const decoder = new TextDecoder(charset);\n return decoder.decode(buffer);\n}\n","/**\n * Generic validation utilities for @semiont/api-client\n *\n * Pure TypeScript validation with no external dependencies.\n * Safe to use in any JavaScript environment (Node.js, browser, Deno, etc.)\n */\n\n/**\n * Validation result types\n */\nexport type ValidationSuccess<T> = { success: true; data: T };\nexport type ValidationFailure = { success: false; error: string; details?: string[] };\nexport type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;\n\n/**\n * JWT Token validation\n *\n * Validates JWT token format (header.payload.signature).\n * Does not verify signature - use for format validation only.\n */\nexport const JWTTokenSchema = {\n parse(token: unknown): string {\n if (typeof token !== 'string') {\n throw new Error('Token must be a string');\n }\n if (!token || token.length === 0) {\n throw new Error('Token is required');\n }\n // JWT format: header.payload.signature\n const jwtRegex = /^[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]*$/;\n if (!jwtRegex.test(token)) {\n throw new Error('Invalid JWT token format');\n }\n return token;\n },\n\n safeParse(token: unknown): ValidationResult<string> {\n try {\n const validated = this.parse(token);\n return { success: true, data: validated };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Invalid JWT token',\n };\n }\n },\n};\n\n/**\n * Generic validation helper with error formatting\n *\n * Wraps any schema's parse method with try/catch and returns ValidationResult.\n *\n * @example\n * ```typescript\n * const result = validateData(JWTTokenSchema, 'eyJ...');\n * if (result.success) {\n * console.log('Valid token:', result.data);\n * } else {\n * console.error('Invalid:', result.error);\n * }\n * ```\n */\nexport function validateData<T>(\n schema: { parse(data: unknown): T },\n data: unknown\n): ValidationResult<T> {\n try {\n const validated = schema.parse(data);\n return { success: true, data: validated };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Validation failed',\n };\n }\n}\n\n/**\n * Email validation helper\n *\n * Validates email format using RFC 5322 simplified regex.\n *\n * @param email - Email address to validate\n * @returns true if valid email format\n */\nexport function isValidEmail(email: string): boolean {\n if (email.length < 1 || email.length > 255) {\n return false;\n }\n // RFC 5322 simplified email regex\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n}\n","/**\n * MIME type utilities for Semiont\n *\n * Initial support for:\n * - text/plain\n * - text/markdown\n * - image/png\n * - image/jpeg\n */\n\n/**\n * Map MIME type to file extension\n */\nexport function getExtensionForMimeType(mimeType: string): string {\n const map: Record<string, string> = {\n 'text/plain': 'txt',\n 'text/markdown': 'md',\n 'image/png': 'png',\n 'image/jpeg': 'jpg',\n };\n\n return map[mimeType] || 'dat'; // fallback to .dat for unknown types\n}\n\n/**\n * Detect if MIME type is an image (png or jpeg only for now)\n */\nexport function isImageMimeType(mimeType: string): boolean {\n return mimeType === 'image/png' || mimeType === 'image/jpeg';\n}\n\n/**\n * Detect if MIME type is text-based (plain or markdown only for now)\n */\nexport function isTextMimeType(mimeType: string): boolean {\n return mimeType === 'text/plain' || mimeType === 'text/markdown';\n}\n\n/**\n * Get category for MIME type (for routing to appropriate viewer)\n */\nexport type MimeCategory = 'text' | 'image' | 'unsupported';\n\nexport function getMimeCategory(mimeType: string): MimeCategory {\n if (isTextMimeType(mimeType)) {\n return 'text';\n }\n if (isImageMimeType(mimeType)) {\n return 'image';\n }\n return 'unsupported';\n}\n"]}