@localmode/core 1.0.0
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/README.md +611 -0
- package/dist/index.cjs +114 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +11206 -0
- package/dist/index.d.ts +11206 -0
- package/dist/index.js +114 -0
- package/dist/index.js.map +1 -0
- package/dist/worker/index.d.ts +2 -0
- package/dist/worker/index.js +2 -0
- package/dist/worker/index.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/hnsw/distance.ts","../src/hnsw/index.ts","../src/storage/schema.ts","../src/storage/wal.ts","../src/storage/migrations.ts","../src/storage/indexeddb.ts","../src/storage/memory.ts","../src/storage/index.ts","../src/query/filter.ts","../src/sync/locks.ts","../src/sync/broadcast.ts","../src/db.ts","../src/worker/proxy.ts","../src/embeddings/embed.ts","../src/embeddings/semantic-search.ts","../src/embeddings/middleware.ts","../src/classification/classify.ts","../src/classification/extract-entities.ts","../src/classification/rerank.ts","../src/vision/classify-image.ts","../src/vision/caption-image.ts","../src/vision/segment-image.ts","../src/vision/detect-objects.ts","../src/vision/extract-features.ts","../src/vision/image-to-image.ts","../src/audio/transcribe.ts","../src/audio/synthesize-speech.ts","../src/generation/generate-text.ts","../src/generation/stream-text.ts","../src/translation/translate.ts","../src/summarization/summarize.ts","../src/fill-mask/fill-mask.ts","../src/question-answering/answer-question.ts","../src/ocr/extract-text.ts","../src/document/ask-document.ts","../src/document/ask-table.ts","../src/rag/types.ts","../src/rag/chunkers/recursive.ts","../src/rag/chunkers/markdown.ts","../src/rag/chunkers/code.ts","../src/rag/chunkers/index.ts","../src/rag/bm25.ts","../src/rag/hybrid.ts","../src/rag/ingest.ts","../src/security/crypto.ts","../src/security/keystore.ts","../src/security/pii.ts","../src/security/encryption-middleware.ts","../src/loaders/text.ts","../src/loaders/json.ts","../src/loaders/csv.ts","../src/loaders/html.ts","../src/loaders/index.ts","../src/middleware/vectordb.ts","../src/middleware/caching.ts","../src/middleware/logging.ts","../src/middleware/validation.ts","../src/middleware/retry.ts","../src/middleware/rate-limit.ts","../src/storage/quota.ts","../src/storage/cleanup.ts","../src/utils/network.ts","../src/events/index.ts","../src/capabilities/features.ts","../src/capabilities/device.ts","../src/capabilities/detect.ts","../src/capabilities/report.ts","../src/network/logger.ts","../src/network/fetch-wrapper.ts","../src/errors/format.ts","../src/errors/index.ts","../src/testing/index.ts"],"names":["DEFAULT_CONFIG","DEFAULT_COLLECTION","cosineSimilarity","a","b","dotProduct","normA","normB","magnitude","cosineDistance","euclideanDistance","sum","i","diff","normalize","v","norm","result","getDistanceFunction","type","distanceToScore","distance","MinHeap","candidate","min","last","index","parentIndex","length","leftChild","rightChild","smallest","MaxHeap","max","largest","HNSWIndex","_HNSWIndex","dimensions","options","ef","level","id","vector","node","l","currNodeId","neighbors","selectedNeighbors","nodeConnections","neighbor","neighborNode","neighborConnections","maxConnections","query","k","c","connections","neighborId","entryId","visited","entryVector","entryDist","candidates","results","current","currentNode","neighborVector","neighborDist","_query","nodeId","nodeVector","scored","connId","connVector","newConnections","nodes","conns","data","vectors","nodeData","STORE_NAMES","WAL_STORE_NAME","createWALSchema","db","walStore","generateWALId","WAL","maxSequence","resolve","reject","request","cursor","entry","tx","status","store","getRequest","putRequest","transactionId","entries","executor","pending","completed","error","maxAgeMs","cutoff","deleted","withWAL","wal","operation","createReplayExecutor","storage","MIGRATIONS","docStore","getCurrentVersion","m","getMigrationsToRun","fromVersion","toVersion","runMigrations","transaction","oldVersion","newVersion","migrations","migration","MigrationManager","dbName","record","version","stored","currentVersion","event","IndexedDBStorage","name","pendingCount","replayed","doc","collectionId","records","r","vec","map","collection","storeNames","ids","d","vecStore","MemoryStorage","docs","count","size","createStorage","matchesFilter","metadata","filter","key","condition","value","matchesCondition","ops","shouldExist","exists","applyFilter","items","item","LockManager","_LockManager","resource","callback","lockName","lockOptions","timeoutId","abortController","combineSignals","mode","lock","state","prefix","signals","controller","signal","defaultLockManager","getLockManager","generateTabId","Broadcaster","_Broadcaster","message","typeListeners","listener","wildcardListeners","documentId","documentIds","electionKey","now","tabId","timestamp","createBroadcaster","VectorDBImpl","_VectorDBImpl","config","collectionName","existingStorage","syncConfig","savedIndex","serialized","storedDoc","batchSize","total","batch","threshold","includeVectors","searchK","rawResults","searchResult","updates","existingDoc","collectionDb","target","prop","args","collections","totalCount","col","sizeBytes","format","exportData","allCollections","targetCollections","colData","docData","text","importData","createVectorDB","VectorDBWorkerProxy","_VectorDBWorkerProxy","worker","response","payload","onProgress","buffer","createVectorDBWithWorker","workerUrl","proxy","globalProviderRegistry","setGlobalEmbeddingProvider","providers","separator","sepIndex","providerName","modelId","provider","resolveModel","modelOrId","embed","abortSignal","maxRetries","headers","providerOptions","model","lastError","attempt","embedMany","values","embedWithRetry","allEmbeddings","totalTokens","lastResponse","streamEmbedMany","onBatch","j","semanticSearch","embedStartTime","embedding","embedUsage","embedDurationMs","searchStartTime","dbResults","searchDurationMs","extractText","textFields","field","streamSemanticSearch","wrapEmbeddingModel","middleware","embedOptions","doEmbed","composeEmbeddingMiddleware","middlewares","params","mw","currentDoEmbed","reversed","prevDoEmbed","globalClassificationRegistry","setGlobalClassificationProvider","resolveClassificationModel","resolveZeroShotModel","classify","classifyMany","texts","classifyWithRetry","classifyZeroShot","candidateLabels","multiLabel","globalNERRegistry","setGlobalNERProvider","resolveNERModel","extractEntities","extractEntitiesMany","extractWithRetry","globalRerankerRegistry","setGlobalRerankerProvider","resolveRerankerModel","rerank","documents","topK","globalImageClassificationRegistry","setGlobalImageClassificationProvider","resolveImageClassificationModel","resolveZeroShotImageModel","classifyImage","image","classifyImageZeroShot","globalImageCaptionRegistry","setGlobalImageCaptionProvider","resolveImageCaptionModel","captionImage","maxLength","globalSegmentationProvider","setGlobalSegmentationProvider","segmentImage","startTime","durationMs","delay","globalObjectDetectionProvider","setGlobalObjectDetectionProvider","detectObjects","globalImageFeatureProvider","setGlobalImageFeatureProvider","extractImageFeatures","globalImageToImageProvider","setGlobalImageToImageProvider","upscaleImage","scale","imageToImage","globalSTTRegistry","setGlobalSTTProvider","resolveSTTModel","transcribe","audio","language","task","returnTimestamps","globalTTSProvider","setGlobalTTSProvider","synthesizeSpeech","voice","speed","pitch","globalLanguageModelProvider","setGlobalLanguageModelProvider","generateText","prompt","systemPrompt","messages","maxTokens","temperature","topP","stopSequences","streamText","onChunk","streamOptions","innerStream","accumulatedText","finalUsage","resolveText","rejectText","resolveUsage","rejectUsage","textPromise","usagePromise","wrappedStream","chunk","globalTranslationProvider","setGlobalTranslationProvider","translate","sourceLanguage","targetLanguage","globalSummarizationProvider","setGlobalSummarizationProvider","summarize","minLength","globalFillMaskProvider","setGlobalFillMaskProvider","fillMask","globalQAProvider","setGlobalQuestionAnsweringProvider","answerQuestion","question","context","topAnswer","globalOCRProvider","setGlobalOCRProvider","languages","detectRegions","globalDocumentQAProvider","setGlobalDocumentQAProvider","askDocument","document","answer","askTable","table","DEFAULT_CHUNK_OPTIONS","DEFAULT_RECURSIVE_SEPARATORS","DEFAULT_BM25_OPTIONS","ENGLISH_STOP_WORDS","DEFAULT_HYBRID_OPTIONS","DEFAULT_INGEST_OPTIONS","recursiveChunk","overlap","minSize","trim","keepSeparators","separators","normalizedText","splits","splitRecursive","chunks","mergeWithOverlap","assignPositions","createFallbackChunks","step","chunkText","targetSize","currentStart","remainingSeparators","splitByCharacters","parts","splitBySeparator","position","part","subSplits","remaining","lastIndex","end","currentChunk","split","overlapBuffer","getOverlapText","trimmedFinal","overlapStart","wordBreak","normalizeChunkText","originalText","searchStart","start","findChunkPosition","firstPart","startFrom","pos","normalizedChunk","createRecursiveChunker","defaultOptions","markdownChunk","includeHeaders","maxHeaderLevel","preserveCodeBlocks","preserveTables","elements","parseMarkdown","buildChunks","lines","headerStack","line","lineStart","fence","codeStart","codeContent","headerMatch","headerText","tableStart","tableContent","quoteStart","quoteContent","listStart","listContent","nextLine","paraStart","paraContent","currentHeaders","chunkIndex","finalizeChunk","h","match","element","elementContent","allContent","e","headerPath","createMarkdownChunker","LANGUAGE_PATTERNS","codeChunk","detectLanguage","preserveBlocks","includeImports","maxLines","patterns","parseCode","importBlock","buildCodeChunks","content","importContent","importEnd","className","extractName","blockStart","blockContent","braceCount","countChar","indentLevel","getIndent","funcName","extractFunctionName","commentStart","commentContent","keyword","regex","str","char","currentScope","forceMetadata","codeElements","lineChunk","lineCount","createCodeChunker","strategy","createChunker","estimateChunkCount","effectiveSize","getChunkStats","sizes","totalSize","simpleStem","word","stem","suffixes","suffix","defaultTokenize","stemming","tokens","token","BM25","termFreqs","term","queryTokens","scores","N","score","tf","df","idf","numerator","denominator","createBM25","createBM25FromDocuments","bm25","HybridSearch","bm25Options","queryVector","queryText","vectorWeight","keywordWeight","normalizeScores","fetchK","vectorResults","bm25Results","fuseResults","vectorScores","keywordScores","metadataMap","vectorMap","allIds","normalizedVectorScores","normalizedKeywordScores","normalizeScoreMap","vScore","kScore","combinedScore","range","reciprocalRankFusion","rrfScores","vectorScoreMap","keywordScoreMap","rank","createHybridSearch","hybridFuse","useRRF","rrfK","generateChunkId","docId","generateDocId","ingest","chunking","idPrefix","generateEmbeddings","embedder","buildBM25Index","progress","reportProgress","allChunks","batchVectors","chunkIds","bm25Index","docsToAdd","chunkDocuments","ingestChunks","createIngestPipeline","estimateIngestion","totalChunks","totalCharacters","isCryptoSupported","getRandomBytes","bytes","arrayBufferToBase64","binary","base64ToArrayBuffer","base64","deriveKey","passphrase","salt","iterations","encoder","keyMaterial","encrypt","iv","plaintext","ciphertext","decrypt","encrypted","decryptString","encryptVector","decryptVector","encryptJSON","json","decryptJSON","hashPassphrase","hashBuffer","verifyPassphrase","hash","newHash","KEYSTORE_DB_NAME","KEYSTORE_VERSION","KEY_STORE_NAME","openKeystore","Keystore","_Keystore","isValid","oldPassphrase","newPassphrase","createKeystore","PII_PATTERNS","DEFAULT_PII_REPLACEMENTS","redactPII","emails","phones","ssn","creditCards","ipAddresses","dates","customPatterns","replacement","replacements","getReplacement","pattern","customReplacement","piiRedactionMiddleware","encryptionMiddleware","encryptVectors","encryptMetadata","encryptText","excludeFields","encryptedVectorCache","encryptFloat32Array","encryptedMetadata","encryptString","decryptFloat32Array","decryptedMetadata","isEncryptedString","decrypted","combined","paddedLength","padded","deriveEncryptionKey","password","saltBytes","generateId","TextLoader","source","customGenerateId","encoding","maxSize","createTextLoader","_options","getValueByPath","obj","path","extractAllStrings","maxDepth","strings","traverse","depth","trimmed","JSONLoader","extractAll","fieldSeparator","recordsPath","jsonString","commonFields","recordId","createJSONLoader","parseCSV","delimiter","rowDelimiter","rows","currentRow","currentField","inQuotes","nextChar","CSVLoader","textColumn","textColumns","columnSeparator","idColumn","columnDelimiter","hasHeader","skipEmpty","dataRows","textColumnIndices","idColumnIndex","row","idx","header","defaultFields","column","createCSVLoader","DEFAULT_IGNORE_TAGS","parseHTMLWithRegex","html","ignoreTags","titleMatch","title","metaRegex","metaMatch","selectorRegex","createSelectorRegex","selectorMatch","tag","tagRegex","decodeHTMLEntities","selector","entities","entity","_","num","hex","parseHTML","parseHTMLWithDOM","meta","el","HTMLLoader","extractMetadata","htmlMetadata","createHTMLLoader","LOADERS","loadDocument","loaderType","loaderOptions","getLoaderByType","loader","loadDocuments","sources","createLoaderRegistry","loaders","s","composeVectorDBMiddleware","q","opts","wrapVectorDB","handleError","addOptions","searchOptions","exportOptions","importOptions","LRUCache","ttlMs","firstKey","createSearchCacheKey","queryHash","filterHash","cachingMiddleware","maxSearchResults","cacheSearchResults","cacheDocuments","searchCache","documentCache","cached","createCachingMiddleware","loggingMiddleware","logger","timing","operations","formatter","shouldLog","op","log","timers","startTimer","getElapsed","elapsed","searchId","createLoggingMiddleware","validationMiddleware","validateValues","validateMetadata","maxMetadataSize","maxTextLength","customValidator","validateDocument","textContent","metadataSize","createValidationMiddleware","DEFAULT_RETRY_OPTIONS","retryMiddleware","jitterRange","sleep","createRetryMiddleware","ms","DEFAULT_RATE_LIMIT_OPTIONS","rateLimitMiddleware","requestTimestamps","requestQueue","processingQueue","getWaitTime","processQueue","waitTime","createRateLimitMiddleware","getStorageQuota","estimate","persisted","usedBytes","quotaBytes","requestPersistence","isStoragePersisted","checkQuotaWithWarnings","warnAt","criticalAt","onWarning","onCritical","quota","estimateRemainingCapacity","avgDocSizeBytes","formatBytes","units","startStorageMonitor","intervalMs","onStatusChange","lastStatus","intervalId","check","parseAge","duration","unit","multiplier","formatDuration","cleanup","maxAge","keepMinCount","targetUsagePercent","dryRun","toDelete","targetRemovePercent","removeCount","maxToDelete","freedBytes","deletedCount","batchIds","estimateCleanupSize","CleanupStrategies","getNetworkStatus","connection","isOffline","isOnline","onNetworkChange","handler","waitForOnline","timeout","unsubscribe","isConnectionSuitable","getConnectionRecommendation","EventEmitter","set","wrappedCallback","promises","createEventEmitter","globalEventBus","eventMiddleware","emitter","isWebGPUSupported","isWebNNSupported","isWASMSupported","module","isWASMSIMDSupported","simdModule","isWASMThreadsSupported","threadsModule","isIndexedDBSupported","isWebWorkersSupported","isSharedArrayBufferSupported","isCrossOriginIsolated","isOPFSSupported","isBroadcastChannelSupported","isWebLocksSupported","isServiceWorkerSupported","getDeviceInfo","getMemoryInfo","info","memory","getHardwareConcurrency","getStorageEstimate","detectBrowser","ua","detectOS","ntVersion","detectDeviceType","detectGPU","canvas","gl","debugInfo","detectCapabilities","browser","os","deviceType","gpu","webgpu","checkFeatureSupport","feature","getFeatureRecommendations","checkModelSupport","requirements","caps","storageAvailable","getModelFallbacks","memoryAvailable","recommendedDevice","MODEL_FALLBACKS","getRecommendedFallbacks","features","fallbacks","getBrowserRecommendations","allRecommendations","byBrowser","rec","existing","createCapabilityReport","capabilities","calculateScores","recommendations","generateRecommendations","issues","detectIssues","mlReadiness","storageCapacity","quotaGB","usedPercent","performancePotential","formatCapabilityReport","report","featureList","supported","icon","formatScore","issue","NetworkLogger","fullEntry","updated","failed","totalDownloadBytes","totalUploadBytes","totalDuration","byCategory","byStatus","oneMinuteAgo","recentRequests","parseDuration","globalLogger","createNetworkLogger","getGlobalLogger","getNetworkLogs","clearNetworkLogs","onNetworkRequest","getNetworkStats","multipliers","createLoggingFetch","category","logHeaders","categoryResolver","input","init","url","method","resolvedCategory","contentLength","responseSize","body","trackedResponse","trackProgress","loaded","reader","stream","done","originalFetch","wrapFetchWithLogging","loggingFetch","unwrapFetch","isFetchWrapped","formatErrorForUser","ModelNotFoundError","ModelLoadError","QuotaExceededError","IndexedDBBlockedError","DimensionMismatchError","OfflineError","NetworkError","FeatureNotSupportedError","EmbeddingError","ValidationError","StorageError","LocalModeError","formatErrorForConsole","formatted","red","yellow","cyan","reset","color","formatErrorAsHTML","bgColor","borderColor","textColor","escapeHTML","logError","logMethod","code","msg","ConfigError","hint","expected","received","InvalidOptionsError","option","cause","EmbeddingDimensionError","ModelError","InferenceError","DocumentNotFoundError","MigrationError","MiddlewareError","LoaderError","FilterError","SyncError","LockError","AudioError","VisionError","GenerationError","ContextLengthExceededError","actualLength","TranslationError","UnsupportedLanguageError","supportedLanguages","SummarizationError","FillMaskError","MissingMaskTokenError","expectedToken","QuestionAnsweringError","OCRError","ImageFormatError","DocumentQAError","TableQAError","InvalidTableFormatError","reason","SegmentationError","ObjectDetectionError","ImageUpscaleError","SpeechSynthesisError","EnvironmentError","createSeededRandom","seed","t","createTestVector","rng","createTestVectors","baseSeed","createMockEmbeddingModel","failCount","failError","onEmbed","failures","callCount","valueSeed","hashString","createMockClassificationModel","labels","defaultLabel","defaultScore","lower","label","allScores","createMockNERModel","entityTypes","createMockSpeechToTextModel","mockText","audioSize","audioDurationSec","words","segmentDuration","createMockStorage","createMockVectorDB","maybeDelay","docValue","opValue","createMockImageCaptionModel","mockCaption","images","createMockSegmentationModel","createMockObjectDetectionModel","createMockImageFeatureModel","createMockImageToImageModel","taskType","createMockTextToSpeechModel","sampleRate","durationSec","numSamples","audioData","createMockLanguageModel","mockResponse","contextLength","inputTokens","outputTokens","tokenText","isLast","createMockTranslationModel","translationPrefix","translations","createMockSummarizationModel","mockSummary","summaries","totalInputTokens","totalOutputTokens","summaryText","firstSentence","createMockFillMaskModel","mockPredictions","predictions","p","createMockQuestionAnsweringModel","questions","createMockOCRModel","regions","createMockDocumentQAModel","waitFor","interval","createDeferred","res","rej","createSpy","calls","spy"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Encryption configuration options.\n */\nexport interface EncryptionOptions {\n /** Enable encryption at rest */\n enabled: boolean;\n /** Passphrase for encryption (required if enabled) */\n passphrase?: string;\n /** Key derivation iterations (higher = more secure, slower). Default: 100000 */\n iterations?: number;\n}\n\n/**\n * Sync configuration options.\n */\nexport interface SyncOptions {\n /** Enable cross-tab locking with Web Locks API. Default: true */\n enableLocking?: boolean;\n /** Enable cross-tab notifications with BroadcastChannel. Default: true */\n enableBroadcast?: boolean;\n /** Enable Write-Ahead Log for crash recovery. Default: false */\n enableWAL?: boolean;\n}\n\n/**\n * Configuration options for creating a VectorDB instance.\n */\nexport interface VectorDBConfig {\n /** Database name (used for IndexedDB store name) */\n name: string;\n\n /** Number of dimensions for vectors */\n dimensions: number;\n\n /** Storage backend: 'indexeddb' for persistence, 'memory' for testing */\n storage?: 'indexeddb' | 'memory';\n\n /** HNSW index configuration options */\n indexOptions?: HNSWOptions;\n\n /** Encryption configuration */\n encryption?: EncryptionOptions;\n\n /** Sync and recovery options */\n sync?: SyncOptions;\n}\n\n/**\n * HNSW algorithm configuration options.\n */\nexport interface HNSWOptions {\n /** Maximum number of connections per node (default: 16) */\n m?: number;\n\n /** Size of dynamic candidate list during construction (default: 200) */\n efConstruction?: number;\n\n /** Size of dynamic candidate list during search (default: 50) */\n efSearch?: number;\n\n /** Distance metric to use (default: 'cosine') */\n distanceFunction?: 'cosine' | 'euclidean' | 'dot';\n}\n\n/**\n * A document to be stored in the vector database.\n */\nexport interface Document {\n /** Unique identifier for the document */\n id: string;\n\n /** Vector embedding (must match configured dimensions) */\n vector: Float32Array;\n\n /** Optional metadata associated with the document */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Options for search operations.\n */\nexport interface SearchOptions {\n /** Number of results to return (default: 10) */\n k?: number;\n\n /** Metadata filter to apply before/after search */\n filter?: FilterQuery;\n\n /** Minimum similarity threshold (0-1 for cosine, depends on metric) */\n threshold?: number;\n\n /** Whether to include vectors in results (default: false) */\n includeVectors?: boolean;\n}\n\n/**\n * A single search result.\n */\nexport interface SearchResult {\n /** Document ID */\n id: string;\n\n /** Similarity score (higher is more similar for cosine/dot, lower for euclidean) */\n score: number;\n\n /** Document metadata (if stored) */\n metadata?: Record<string, unknown>;\n\n /** Vector embedding (only if includeVectors was true) */\n vector?: Float32Array;\n}\n\n/**\n * Filter query for metadata filtering.\n * Supports exact match, $in (any of), $gt, $gte, $lt, $lte operators.\n */\nexport interface FilterQuery {\n [key: string]:\n | string\n | number\n | boolean\n | null\n | { $in: unknown[] }\n | { $nin: unknown[] }\n | { $gt: number }\n | { $gte: number }\n | { $lt: number }\n | { $lte: number }\n | { $ne: unknown }\n | { $exists: boolean };\n}\n\n/**\n * Options for batch add operations.\n */\nexport interface AddManyOptions {\n /** Progress callback called after each batch */\n onProgress?: (completed: number, total: number) => void;\n\n /** Batch size for processing (default: 100) */\n batchSize?: number;\n}\n\n/**\n * Options for import operations.\n */\nexport interface ImportOptions {\n /** How to handle existing data: 'merge' adds/updates, 'replace' clears first */\n mode?: 'merge' | 'replace';\n\n /** Progress callback */\n onProgress?: (completed: number, total: number) => void;\n}\n\n/**\n * Options for export operations.\n */\nexport interface ExportOptions {\n /** Export format */\n format?: 'json' | 'binary';\n\n /** Collections to export (default: all) */\n collections?: string[];\n\n /** Whether to include vectors (default: true) */\n includeVectors?: boolean;\n}\n\n/**\n * Database statistics.\n */\nexport interface DBStats {\n /** Total number of documents across all collections */\n count: number;\n\n /** List of collection names */\n collections: string[];\n\n /** Approximate size in bytes */\n sizeBytes: number;\n\n /** Database schema version */\n version: number;\n}\n\n/**\n * Internal document representation with collection info.\n */\nexport interface StoredDocument {\n id: string;\n collectionId: string;\n metadata?: Record<string, unknown>;\n createdAt: number;\n updatedAt: number;\n}\n\n/**\n * Internal vector storage representation.\n */\nexport interface StoredVector {\n id: string;\n collectionId: string;\n vector: Float32Array;\n}\n\n/**\n * Internal collection representation.\n */\nexport interface Collection {\n id: string;\n name: string;\n dimensions: number;\n createdAt: number;\n}\n\n/**\n * The main VectorDB interface.\n */\nexport interface VectorDB {\n /** Add a single document */\n add(doc: Document): Promise<void>;\n\n /** Add multiple documents with optional progress tracking */\n addMany(docs: Document[], options?: AddManyOptions): Promise<void>;\n\n /** Search for similar vectors */\n search(vector: Float32Array, options?: SearchOptions): Promise<SearchResult[]>;\n\n /** Get a document by ID */\n get(id: string): Promise<(Document & { metadata?: Record<string, unknown> }) | null>;\n\n /** Update a document's vector or metadata */\n update(id: string, updates: Partial<Omit<Document, 'id'>>): Promise<void>;\n\n /** Delete a document by ID */\n delete(id: string): Promise<void>;\n\n /** Delete multiple documents by ID */\n deleteMany(ids: string[]): Promise<void>;\n\n /** Delete documents matching a filter */\n deleteWhere(filter: FilterQuery): Promise<number>;\n\n /** Get a namespaced collection */\n collection(name: string): VectorDB;\n\n /** Get database statistics */\n stats(): Promise<DBStats>;\n\n /** Clear all data in the database */\n clear(): Promise<void>;\n\n /** Close the database connection */\n close(): Promise<void>;\n\n /** Export database data */\n export(options?: ExportOptions): Promise<Blob>;\n\n /** Import database data */\n import(data: Blob, options?: ImportOptions): Promise<void>;\n\n /** Get the lock manager (for advanced usage) */\n getLockManager(): unknown;\n\n /** Get the broadcaster (for advanced usage) */\n getBroadcaster(): unknown;\n}\n\n/**\n * Message types for worker communication.\n */\nexport type WorkerMessageType =\n | 'init'\n | 'add'\n | 'addMany'\n | 'search'\n | 'get'\n | 'update'\n | 'delete'\n | 'deleteMany'\n | 'deleteWhere'\n | 'stats'\n | 'clear'\n | 'close'\n | 'export'\n | 'import';\n\n/**\n * Worker request message structure.\n */\nexport interface WorkerRequest {\n id: number;\n type: WorkerMessageType;\n payload: unknown;\n collectionId?: string;\n}\n\n/**\n * Worker response message structure.\n */\nexport interface WorkerResponse {\n id: number;\n success: boolean;\n result?: unknown;\n error?: string;\n}\n\n/**\n * HNSW node in the graph.\n */\nexport interface HNSWNode {\n id: string;\n level: number;\n connections: Map<number, string[]>; // level -> connected node IDs\n}\n\n/**\n * Serialized HNSW index format.\n */\nexport interface SerializedHNSWIndex {\n version: number;\n dimensions: number;\n m: number;\n efConstruction: number;\n entryPointId: string | null;\n maxLevel: number;\n nodes: Array<{\n id: string;\n level: number;\n connections: Array<[number, string[]]>;\n }>;\n}\n\n/**\n * Default configuration values.\n */\nexport const DEFAULT_CONFIG = {\n storage: 'indexeddb' as const,\n indexOptions: {\n m: 16,\n efConstruction: 200,\n efSearch: 50,\n distanceFunction: 'cosine' as const,\n },\n sync: {\n enableLocking: true,\n enableBroadcast: true,\n enableWAL: false,\n },\n encryption: {\n enabled: false,\n iterations: 100000,\n },\n} as const;\n\n/**\n * Default collection name.\n */\nexport const DEFAULT_COLLECTION = 'default';\n","/**\n * Distance/similarity functions for vector comparison.\n */\n\n/**\n * Compute cosine similarity between two vectors.\n * Returns a value between -1 and 1, where 1 means identical direction.\n */\nexport function cosineSimilarity(a: Float32Array, b: Float32Array): number {\n if (a.length !== b.length) {\n throw new Error(`Vector dimension mismatch: ${a.length} vs ${b.length}`);\n }\n\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n\n const magnitude = Math.sqrt(normA) * Math.sqrt(normB);\n\n if (magnitude === 0) {\n return 0;\n }\n\n return dotProduct / magnitude;\n}\n\n/**\n * Compute cosine distance (1 - similarity).\n * Returns a value between 0 and 2, where 0 means identical direction.\n */\nexport function cosineDistance(a: Float32Array, b: Float32Array): number {\n return 1 - cosineSimilarity(a, b);\n}\n\n/**\n * Compute Euclidean (L2) distance between two vectors.\n */\nexport function euclideanDistance(a: Float32Array, b: Float32Array): number {\n if (a.length !== b.length) {\n throw new Error(`Vector dimension mismatch: ${a.length} vs ${b.length}`);\n }\n\n let sum = 0;\n\n for (let i = 0; i < a.length; i++) {\n const diff = a[i] - b[i];\n sum += diff * diff;\n }\n\n return Math.sqrt(sum);\n}\n\n/**\n * Compute dot product between two vectors.\n * Higher values mean more similar (for normalized vectors).\n */\nexport function dotProduct(a: Float32Array, b: Float32Array): number {\n if (a.length !== b.length) {\n throw new Error(`Vector dimension mismatch: ${a.length} vs ${b.length}`);\n }\n\n let sum = 0;\n\n for (let i = 0; i < a.length; i++) {\n sum += a[i] * b[i];\n }\n\n return sum;\n}\n\n/**\n * Normalize a vector to unit length.\n */\nexport function normalize(v: Float32Array): Float32Array {\n let norm = 0;\n\n for (let i = 0; i < v.length; i++) {\n norm += v[i] * v[i];\n }\n\n norm = Math.sqrt(norm);\n\n if (norm === 0) {\n return v;\n }\n\n const result = new Float32Array(v.length);\n\n for (let i = 0; i < v.length; i++) {\n result[i] = v[i] / norm;\n }\n\n return result;\n}\n\nexport type DistanceFunction = 'cosine' | 'euclidean' | 'dot';\n\n/**\n * Get the appropriate distance function.\n * For HNSW, we need a distance (lower = better) function.\n */\nexport function getDistanceFunction(\n type: DistanceFunction\n): (a: Float32Array, b: Float32Array) => number {\n switch (type) {\n case 'cosine':\n return cosineDistance;\n case 'euclidean':\n return euclideanDistance;\n case 'dot':\n // For dot product, we negate since HNSW expects lower = better\n return (a, b) => -dotProduct(a, b);\n default:\n return cosineDistance;\n }\n}\n\n/**\n * Convert distance to similarity score.\n * Higher score = more similar.\n */\nexport function distanceToScore(distance: number, type: DistanceFunction): number {\n switch (type) {\n case 'cosine':\n // cosine distance is 1 - similarity, so similarity = 1 - distance\n return 1 - distance;\n case 'euclidean':\n // Convert to a 0-1 range (approximate)\n return 1 / (1 + distance);\n case 'dot':\n // We negated for distance, so negate back\n return -distance;\n default:\n return 1 - distance;\n }\n}\n\n","/**\n * HNSW (Hierarchical Navigable Small World) index implementation.\n * Pure TypeScript, no external dependencies.\n *\n * Based on the paper: \"Efficient and robust approximate nearest neighbor search\n * using Hierarchical Navigable Small World graphs\" by Malkov & Yashunin (2016).\n */\n\nimport type { HNSWOptions, SerializedHNSWIndex } from '../types.js';\nimport { getDistanceFunction, distanceToScore, type DistanceFunction } from './distance.js';\n\ninterface HNSWNode {\n id: string;\n level: number;\n connections: Map<number, Set<string>>; // level -> connected node IDs\n}\n\ninterface SearchCandidate {\n id: string;\n distance: number;\n}\n\n/**\n * Priority queue for nearest neighbor search.\n * Min-heap implementation for efficient retrieval of closest elements.\n */\nclass MinHeap {\n private heap: SearchCandidate[] = [];\n\n get size(): number {\n return this.heap.length;\n }\n\n push(candidate: SearchCandidate): void {\n this.heap.push(candidate);\n this.bubbleUp(this.heap.length - 1);\n }\n\n pop(): SearchCandidate | undefined {\n if (this.heap.length === 0) return undefined;\n\n const min = this.heap[0];\n const last = this.heap.pop()!;\n\n if (this.heap.length > 0) {\n this.heap[0] = last;\n this.bubbleDown(0);\n }\n\n return min;\n }\n\n peek(): SearchCandidate | undefined {\n return this.heap[0];\n }\n\n private bubbleUp(index: number): void {\n while (index > 0) {\n const parentIndex = Math.floor((index - 1) / 2);\n if (this.heap[parentIndex].distance <= this.heap[index].distance) break;\n [this.heap[parentIndex], this.heap[index]] = [this.heap[index], this.heap[parentIndex]];\n index = parentIndex;\n }\n }\n\n private bubbleDown(index: number): void {\n const length = this.heap.length;\n\n while (true) {\n const leftChild = 2 * index + 1;\n const rightChild = 2 * index + 2;\n let smallest = index;\n\n if (leftChild < length && this.heap[leftChild].distance < this.heap[smallest].distance) {\n smallest = leftChild;\n }\n\n if (rightChild < length && this.heap[rightChild].distance < this.heap[smallest].distance) {\n smallest = rightChild;\n }\n\n if (smallest === index) break;\n\n [this.heap[smallest], this.heap[index]] = [this.heap[index], this.heap[smallest]];\n index = smallest;\n }\n }\n}\n\n/**\n * Max-heap for maintaining the furthest k candidates.\n */\nclass MaxHeap {\n private heap: SearchCandidate[] = [];\n\n get size(): number {\n return this.heap.length;\n }\n\n push(candidate: SearchCandidate): void {\n this.heap.push(candidate);\n this.bubbleUp(this.heap.length - 1);\n }\n\n pop(): SearchCandidate | undefined {\n if (this.heap.length === 0) return undefined;\n\n const max = this.heap[0];\n const last = this.heap.pop()!;\n\n if (this.heap.length > 0) {\n this.heap[0] = last;\n this.bubbleDown(0);\n }\n\n return max;\n }\n\n peek(): SearchCandidate | undefined {\n return this.heap[0];\n }\n\n toArray(): SearchCandidate[] {\n return [...this.heap].sort((a, b) => a.distance - b.distance);\n }\n\n private bubbleUp(index: number): void {\n while (index > 0) {\n const parentIndex = Math.floor((index - 1) / 2);\n if (this.heap[parentIndex].distance >= this.heap[index].distance) break;\n [this.heap[parentIndex], this.heap[index]] = [this.heap[index], this.heap[parentIndex]];\n index = parentIndex;\n }\n }\n\n private bubbleDown(index: number): void {\n const length = this.heap.length;\n\n while (true) {\n const leftChild = 2 * index + 1;\n const rightChild = 2 * index + 2;\n let largest = index;\n\n if (leftChild < length && this.heap[leftChild].distance > this.heap[largest].distance) {\n largest = leftChild;\n }\n\n if (rightChild < length && this.heap[rightChild].distance > this.heap[largest].distance) {\n largest = rightChild;\n }\n\n if (largest === index) break;\n\n [this.heap[largest], this.heap[index]] = [this.heap[index], this.heap[largest]];\n index = largest;\n }\n }\n}\n\nexport class HNSWIndex {\n private nodes: Map<string, HNSWNode> = new Map();\n private vectors: Map<string, Float32Array> = new Map();\n private entryPointId: string | null = null;\n private maxLevel = 0;\n\n private readonly m: number; // Max connections per node\n private readonly mMax: number; // Max connections for layer 0\n private readonly efConstruction: number;\n private efSearch: number;\n private readonly distanceType: DistanceFunction;\n private readonly distanceFn: (a: Float32Array, b: Float32Array) => number;\n\n constructor(private dimensions: number, options: HNSWOptions = {}) {\n this.m = options.m ?? 16;\n this.mMax = this.m * 2; // Layer 0 has 2x connections\n this.efConstruction = options.efConstruction ?? 200;\n this.efSearch = options.efSearch ?? 50;\n this.distanceType = options.distanceFunction ?? 'cosine';\n this.distanceFn = getDistanceFunction(this.distanceType);\n }\n\n /**\n * Get the number of vectors in the index.\n */\n get size(): number {\n return this.nodes.size;\n }\n\n /**\n * Set the efSearch parameter for queries.\n */\n setEfSearch(ef: number): void {\n this.efSearch = ef;\n }\n\n /**\n * Generate a random level for a new node.\n * Higher levels are exponentially less likely.\n */\n private randomLevel(): number {\n let level = 0;\n while (Math.random() < 1 / this.m && level < 32) {\n level++;\n }\n return level;\n }\n\n /**\n * Add a vector to the index.\n */\n add(id: string, vector: Float32Array): void {\n if (vector.length !== this.dimensions) {\n throw new Error(`Vector dimension mismatch: expected ${this.dimensions}, got ${vector.length}`);\n }\n\n // Check if already exists\n if (this.nodes.has(id)) {\n // Update existing vector\n this.vectors.set(id, vector);\n return;\n }\n\n const level = this.randomLevel();\n const node: HNSWNode = {\n id,\n level,\n connections: new Map(),\n };\n\n // Initialize connection sets for each level\n for (let l = 0; l <= level; l++) {\n node.connections.set(l, new Set());\n }\n\n this.nodes.set(id, node);\n this.vectors.set(id, vector);\n\n // First node becomes entry point\n if (this.entryPointId === null) {\n this.entryPointId = id;\n this.maxLevel = level;\n return;\n }\n\n let currNodeId = this.entryPointId;\n\n // Search from top layer to node's level + 1\n for (let l = this.maxLevel; l > level; l--) {\n currNodeId = this.searchLayer(vector, currNodeId, 1, l)[0]?.id ?? currNodeId;\n }\n\n // Insert into layers level down to 0\n for (let l = Math.min(level, this.maxLevel); l >= 0; l--) {\n const neighbors = this.searchLayer(vector, currNodeId, this.efConstruction, l);\n const selectedNeighbors = this.selectNeighbors(vector, neighbors, l === 0 ? this.mMax : this.m);\n\n // Connect new node to selected neighbors\n const nodeConnections = node.connections.get(l)!;\n for (const neighbor of selectedNeighbors) {\n nodeConnections.add(neighbor.id);\n\n // Connect neighbors back to new node\n const neighborNode = this.nodes.get(neighbor.id)!;\n let neighborConnections = neighborNode.connections.get(l);\n if (!neighborConnections) {\n neighborConnections = new Set();\n neighborNode.connections.set(l, neighborConnections);\n }\n neighborConnections.add(id);\n\n // Prune if necessary\n const maxConnections = l === 0 ? this.mMax : this.m;\n if (neighborConnections.size > maxConnections) {\n this.pruneConnections(neighbor.id, l, maxConnections);\n }\n }\n\n if (neighbors.length > 0) {\n currNodeId = neighbors[0].id;\n }\n }\n\n // Update entry point if new node has higher level\n if (level > this.maxLevel) {\n this.entryPointId = id;\n this.maxLevel = level;\n }\n }\n\n /**\n * Search for the k nearest neighbors.\n */\n search(query: Float32Array, k: number): Array<{ id: string; score: number }> {\n if (query.length !== this.dimensions) {\n throw new Error(`Query dimension mismatch: expected ${this.dimensions}, got ${query.length}`);\n }\n\n if (this.entryPointId === null) {\n return [];\n }\n\n let currNodeId = this.entryPointId;\n\n // Traverse from top layer to layer 1\n for (let l = this.maxLevel; l > 0; l--) {\n const result = this.searchLayer(query, currNodeId, 1, l);\n if (result.length > 0) {\n currNodeId = result[0].id;\n }\n }\n\n // Search layer 0 with efSearch candidates\n const candidates = this.searchLayer(query, currNodeId, Math.max(k, this.efSearch), 0);\n\n // Return top k results with scores\n return candidates.slice(0, k).map((c) => ({\n id: c.id,\n score: distanceToScore(c.distance, this.distanceType),\n }));\n }\n\n /**\n * Remove a vector from the index.\n * Uses tombstone approach - marks for deletion but doesn't remove connections.\n */\n delete(id: string): boolean {\n const node = this.nodes.get(id);\n if (!node) return false;\n\n // Remove from vectors (effectively marks as deleted)\n this.vectors.delete(id);\n this.nodes.delete(id);\n\n // Remove connections to this node from all neighbors\n for (const [level, connections] of node.connections) {\n for (const neighborId of connections) {\n const neighbor = this.nodes.get(neighborId);\n if (neighbor) {\n neighbor.connections.get(level)?.delete(id);\n }\n }\n }\n\n // If we deleted the entry point, find a new one\n if (this.entryPointId === id) {\n this.entryPointId = this.nodes.size > 0 ? this.nodes.keys().next().value ?? null : null;\n if (this.entryPointId) {\n this.maxLevel = this.nodes.get(this.entryPointId)!.level;\n } else {\n this.maxLevel = 0;\n }\n }\n\n return true;\n }\n\n /**\n * Check if a vector exists in the index.\n */\n has(id: string): boolean {\n return this.nodes.has(id);\n }\n\n /**\n * Get a vector by ID.\n */\n getVector(id: string): Float32Array | undefined {\n return this.vectors.get(id);\n }\n\n /**\n * Search a single layer of the graph.\n */\n private searchLayer(\n query: Float32Array,\n entryId: string,\n ef: number,\n level: number\n ): SearchCandidate[] {\n const visited = new Set<string>([entryId]);\n const entryVector = this.vectors.get(entryId);\n\n if (!entryVector) {\n return [];\n }\n\n const entryDist = this.distanceFn(query, entryVector);\n const candidates = new MinHeap();\n const results = new MaxHeap();\n\n candidates.push({ id: entryId, distance: entryDist });\n results.push({ id: entryId, distance: entryDist });\n\n while (candidates.size > 0) {\n const current = candidates.pop()!;\n\n // If current is further than the furthest result, we're done\n if (results.size >= ef && current.distance > results.peek()!.distance) {\n break;\n }\n\n const currentNode = this.nodes.get(current.id);\n if (!currentNode) continue;\n\n const connections = currentNode.connections.get(level);\n if (!connections) continue;\n\n for (const neighborId of connections) {\n if (visited.has(neighborId)) continue;\n visited.add(neighborId);\n\n const neighborVector = this.vectors.get(neighborId);\n if (!neighborVector) continue;\n\n const neighborDist = this.distanceFn(query, neighborVector);\n\n // Add to results if better than current worst or results not full\n if (results.size < ef || neighborDist < results.peek()!.distance) {\n candidates.push({ id: neighborId, distance: neighborDist });\n results.push({ id: neighborId, distance: neighborDist });\n\n // Keep only ef best results\n if (results.size > ef) {\n results.pop();\n }\n }\n }\n }\n\n return results.toArray();\n }\n\n /**\n * Select the best neighbors using simple distance-based selection.\n */\n private selectNeighbors(\n _query: Float32Array,\n candidates: SearchCandidate[],\n maxConnections: number\n ): SearchCandidate[] {\n // Simple selection: take the closest neighbors\n return candidates.slice(0, maxConnections);\n }\n\n /**\n * Prune connections for a node to maintain the max connections limit.\n */\n private pruneConnections(nodeId: string, level: number, maxConnections: number): void {\n const node = this.nodes.get(nodeId);\n if (!node) return;\n\n const connections = node.connections.get(level);\n if (!connections || connections.size <= maxConnections) return;\n\n const nodeVector = this.vectors.get(nodeId);\n if (!nodeVector) return;\n\n // Score all connections by distance and keep the best\n const scored: SearchCandidate[] = [];\n for (const connId of connections) {\n const connVector = this.vectors.get(connId);\n if (connVector) {\n scored.push({\n id: connId,\n distance: this.distanceFn(nodeVector, connVector),\n });\n }\n }\n\n scored.sort((a, b) => a.distance - b.distance);\n\n const newConnections = new Set<string>();\n for (let i = 0; i < Math.min(maxConnections, scored.length); i++) {\n newConnections.add(scored[i].id);\n }\n\n node.connections.set(level, newConnections);\n }\n\n /**\n * Serialize the index to a JSON-compatible object.\n */\n serialize(): SerializedHNSWIndex {\n const nodes: SerializedHNSWIndex['nodes'] = [];\n\n for (const [id, node] of this.nodes) {\n const connections: Array<[number, string[]]> = [];\n for (const [level, conns] of node.connections) {\n connections.push([level, Array.from(conns)]);\n }\n nodes.push({ id, level: node.level, connections });\n }\n\n return {\n version: 1,\n dimensions: this.dimensions,\n m: this.m,\n efConstruction: this.efConstruction,\n entryPointId: this.entryPointId,\n maxLevel: this.maxLevel,\n nodes,\n };\n }\n\n /**\n * Deserialize an index from a JSON object.\n */\n static deserialize(\n data: SerializedHNSWIndex,\n vectors: Map<string, Float32Array>,\n options?: HNSWOptions\n ): HNSWIndex {\n const index = new HNSWIndex(data.dimensions, {\n m: data.m,\n efConstruction: data.efConstruction,\n ...options,\n });\n\n index.entryPointId = data.entryPointId;\n index.maxLevel = data.maxLevel;\n index.vectors = vectors;\n\n for (const nodeData of data.nodes) {\n const node: HNSWNode = {\n id: nodeData.id,\n level: nodeData.level,\n connections: new Map(),\n };\n\n for (const [level, conns] of nodeData.connections) {\n node.connections.set(level, new Set(conns));\n }\n\n index.nodes.set(nodeData.id, node);\n }\n\n return index;\n }\n\n /**\n * Clear all data from the index.\n */\n clear(): void {\n this.nodes.clear();\n this.vectors.clear();\n this.entryPointId = null;\n this.maxLevel = 0;\n }\n}\n\n","/**\n * IndexedDB schema definitions.\n */\n\n// Note: This version is managed by the migrations system.\n// See migrations.ts for the actual version and upgrade logic.\nexport const DB_VERSION = 3;\n\nexport const STORE_NAMES = {\n DOCUMENTS: 'documents',\n VECTORS: 'vectors',\n INDEXES: 'indexes',\n COLLECTIONS: 'collections',\n META: 'meta',\n} as const;\n\n/**\n * Create the IndexedDB schema.\n */\nexport function createSchema(db: IDBDatabase): void {\n // Documents store: metadata for each document\n if (!db.objectStoreNames.contains(STORE_NAMES.DOCUMENTS)) {\n const docStore = db.createObjectStore(STORE_NAMES.DOCUMENTS, { keyPath: 'id' });\n docStore.createIndex('collectionId', 'collectionId', { unique: false });\n docStore.createIndex('collectionId_createdAt', ['collectionId', 'createdAt'], {\n unique: false,\n });\n }\n\n // Vectors store: raw vector data\n if (!db.objectStoreNames.contains(STORE_NAMES.VECTORS)) {\n const vecStore = db.createObjectStore(STORE_NAMES.VECTORS, { keyPath: 'id' });\n vecStore.createIndex('collectionId', 'collectionId', { unique: false });\n }\n\n // Indexes store: serialized HNSW graphs per collection\n if (!db.objectStoreNames.contains(STORE_NAMES.INDEXES)) {\n db.createObjectStore(STORE_NAMES.INDEXES, { keyPath: 'collectionId' });\n }\n\n // Collections store: collection metadata\n if (!db.objectStoreNames.contains(STORE_NAMES.COLLECTIONS)) {\n const collStore = db.createObjectStore(STORE_NAMES.COLLECTIONS, { keyPath: 'id' });\n collStore.createIndex('name', 'name', { unique: true });\n }\n\n // Meta store: database metadata\n if (!db.objectStoreNames.contains(STORE_NAMES.META)) {\n db.createObjectStore(STORE_NAMES.META, { keyPath: 'key' });\n }\n}\n\n/**\n * Document record as stored in IndexedDB.\n */\nexport interface DocumentRecord {\n id: string;\n collectionId: string;\n metadata?: Record<string, unknown>;\n createdAt: number;\n updatedAt: number;\n}\n\n/**\n * Vector record as stored in IndexedDB.\n */\nexport interface VectorRecord {\n id: string;\n collectionId: string;\n vector: Float32Array;\n}\n\n/**\n * Index record as stored in IndexedDB.\n */\nexport interface IndexRecord {\n collectionId: string;\n data: string; // JSON serialized HNSW index\n updatedAt: number;\n}\n\n/**\n * Collection record as stored in IndexedDB.\n */\nexport interface CollectionRecord {\n id: string;\n name: string;\n dimensions: number;\n createdAt: number;\n}\n\n/**\n * Meta record as stored in IndexedDB.\n */\nexport interface MetaRecord {\n key: string;\n value: unknown;\n}\n","/**\n * Write-Ahead Log (WAL) for crash recovery.\n * Ensures data consistency by logging operations before they are applied.\n */\n\n/**\n * WAL operation types.\n */\nexport type WALOperationType =\n | 'add_document'\n | 'update_document'\n | 'delete_document'\n | 'add_vector'\n | 'delete_vector'\n | 'save_index'\n | 'create_collection'\n | 'delete_collection'\n | 'clear_collection'\n | 'clear_database';\n\n/**\n * WAL entry representing a pending operation.\n */\nexport interface WALEntry {\n /** Unique operation ID */\n id: string;\n /** Sequence number for ordering */\n sequence: number;\n /** Operation type */\n type: WALOperationType;\n /** Operation data (serializable) */\n data: Record<string, unknown>;\n /** Timestamp when the operation was logged */\n timestamp: number;\n /** Status of the operation */\n status: 'pending' | 'committed' | 'rolled_back';\n /** Transaction ID for grouping related operations */\n transactionId?: string;\n}\n\n/**\n * WAL store name in IndexedDB.\n */\nexport const WAL_STORE_NAME = 'wal';\n\n/**\n * Add WAL store to the IndexedDB schema.\n */\nexport function createWALSchema(db: IDBDatabase): void {\n if (!db.objectStoreNames.contains(WAL_STORE_NAME)) {\n const walStore = db.createObjectStore(WAL_STORE_NAME, { keyPath: 'id' });\n walStore.createIndex('sequence', 'sequence', { unique: true });\n walStore.createIndex('status', 'status', { unique: false });\n walStore.createIndex('transactionId', 'transactionId', { unique: false });\n }\n}\n\n/**\n * Generate a unique ID for WAL entries.\n */\nfunction generateWALId(): string {\n return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\n/**\n * Write-Ahead Log manager.\n */\nexport class WAL {\n private db: IDBDatabase;\n private sequence = 0;\n private currentTransactionId: string | null = null;\n\n constructor(db: IDBDatabase) {\n this.db = db;\n }\n\n /**\n * Initialize WAL and recover any pending operations.\n */\n async initialize(): Promise<number> {\n // Get the max sequence number\n const maxSequence = await this.getMaxSequence();\n this.sequence = maxSequence;\n\n // Get count of pending operations\n const pendingCount = await this.getPendingCount();\n return pendingCount;\n }\n\n /**\n * Get the maximum sequence number in the log.\n */\n private async getMaxSequence(): Promise<number> {\n return new Promise((resolve, reject) => {\n const tx = this.db.transaction(WAL_STORE_NAME, 'readonly');\n const store = tx.objectStore(WAL_STORE_NAME);\n const index = store.index('sequence');\n\n const request = index.openCursor(null, 'prev');\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const cursor = request.result;\n if (cursor) {\n const entry = cursor.value as WALEntry;\n resolve(entry.sequence);\n } else {\n resolve(0);\n }\n };\n });\n }\n\n /**\n * Get count of pending operations.\n */\n private async getPendingCount(): Promise<number> {\n return new Promise((resolve, reject) => {\n const tx = this.db.transaction(WAL_STORE_NAME, 'readonly');\n const store = tx.objectStore(WAL_STORE_NAME);\n const index = store.index('status');\n\n const request = index.count('pending');\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve(request.result);\n });\n }\n\n /**\n * Start a new transaction.\n */\n beginTransaction(): string {\n this.currentTransactionId = generateWALId();\n return this.currentTransactionId;\n }\n\n /**\n * End the current transaction.\n */\n endTransaction(): void {\n this.currentTransactionId = null;\n }\n\n /**\n * Log an operation to the WAL.\n */\n async log(type: WALOperationType, data: Record<string, unknown>): Promise<string> {\n const entry: WALEntry = {\n id: generateWALId(),\n sequence: ++this.sequence,\n type,\n data,\n timestamp: Date.now(),\n status: 'pending',\n transactionId: this.currentTransactionId ?? undefined,\n };\n\n return new Promise((resolve, reject) => {\n const tx = this.db.transaction(WAL_STORE_NAME, 'readwrite');\n const store = tx.objectStore(WAL_STORE_NAME);\n const request = store.add(entry);\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve(entry.id);\n });\n }\n\n /**\n * Mark an operation as committed.\n */\n async commit(id: string): Promise<void> {\n return this.updateStatus(id, 'committed');\n }\n\n /**\n * Mark an operation as rolled back.\n */\n async rollback(id: string): Promise<void> {\n return this.updateStatus(id, 'rolled_back');\n }\n\n /**\n * Update the status of a WAL entry.\n */\n private async updateStatus(id: string, status: WALEntry['status']): Promise<void> {\n return new Promise((resolve, reject) => {\n const tx = this.db.transaction(WAL_STORE_NAME, 'readwrite');\n const store = tx.objectStore(WAL_STORE_NAME);\n const getRequest = store.get(id);\n\n getRequest.onerror = () => reject(getRequest.error);\n getRequest.onsuccess = () => {\n const entry = getRequest.result as WALEntry | undefined;\n if (!entry) {\n reject(new Error(`WAL entry not found: ${id}`));\n return;\n }\n\n entry.status = status;\n const putRequest = store.put(entry);\n putRequest.onerror = () => reject(putRequest.error);\n };\n\n tx.oncomplete = () => resolve();\n });\n }\n\n /**\n * Commit all operations in a transaction.\n */\n async commitTransaction(transactionId: string): Promise<void> {\n const entries = await this.getTransactionEntries(transactionId);\n\n return new Promise((resolve, reject) => {\n const tx = this.db.transaction(WAL_STORE_NAME, 'readwrite');\n const store = tx.objectStore(WAL_STORE_NAME);\n\n for (const entry of entries) {\n entry.status = 'committed';\n store.put(entry);\n }\n\n tx.onerror = () => reject(tx.error);\n tx.oncomplete = () => resolve();\n });\n }\n\n /**\n * Rollback all operations in a transaction.\n */\n async rollbackTransaction(transactionId: string): Promise<void> {\n const entries = await this.getTransactionEntries(transactionId);\n\n return new Promise((resolve, reject) => {\n const tx = this.db.transaction(WAL_STORE_NAME, 'readwrite');\n const store = tx.objectStore(WAL_STORE_NAME);\n\n for (const entry of entries) {\n entry.status = 'rolled_back';\n store.put(entry);\n }\n\n tx.onerror = () => reject(tx.error);\n tx.oncomplete = () => resolve();\n });\n }\n\n /**\n * Get all entries for a transaction.\n */\n private async getTransactionEntries(transactionId: string): Promise<WALEntry[]> {\n return new Promise((resolve, reject) => {\n const tx = this.db.transaction(WAL_STORE_NAME, 'readonly');\n const store = tx.objectStore(WAL_STORE_NAME);\n const index = store.index('transactionId');\n const request = index.getAll(transactionId);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve(request.result as WALEntry[]);\n });\n }\n\n /**\n * Get all pending operations for recovery.\n */\n async getPendingOperations(): Promise<WALEntry[]> {\n return new Promise((resolve, reject) => {\n const tx = this.db.transaction(WAL_STORE_NAME, 'readonly');\n const store = tx.objectStore(WAL_STORE_NAME);\n const index = store.index('status');\n const request = index.getAll('pending');\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const entries = request.result as WALEntry[];\n // Sort by sequence for proper ordering\n entries.sort((a, b) => a.sequence - b.sequence);\n resolve(entries);\n };\n });\n }\n\n /**\n * Replay pending operations (for crash recovery).\n */\n async replay(\n executor: (entry: WALEntry) => Promise<void>,\n options: { onProgress?: (completed: number, total: number) => void } = {}\n ): Promise<number> {\n const pending = await this.getPendingOperations();\n\n if (pending.length === 0) {\n return 0;\n }\n\n let completed = 0;\n\n for (const entry of pending) {\n try {\n await executor(entry);\n await this.commit(entry.id);\n completed++;\n options.onProgress?.(completed, pending.length);\n } catch (error) {\n console.error(`Failed to replay WAL entry ${entry.id}:`, error);\n // Mark as rolled back if we can't replay\n await this.rollback(entry.id);\n }\n }\n\n return completed;\n }\n\n /**\n * Clean up committed and rolled back entries older than the given age.\n */\n async cleanup(maxAgeMs: number = 24 * 60 * 60 * 1000): Promise<number> {\n const cutoff = Date.now() - maxAgeMs;\n\n return new Promise((resolve, reject) => {\n const tx = this.db.transaction(WAL_STORE_NAME, 'readwrite');\n const store = tx.objectStore(WAL_STORE_NAME);\n const request = store.openCursor();\n\n let deleted = 0;\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const cursor = request.result;\n if (cursor) {\n const entry = cursor.value as WALEntry;\n\n if (entry.status !== 'pending' && entry.timestamp < cutoff) {\n cursor.delete();\n deleted++;\n }\n\n cursor.continue();\n }\n };\n\n tx.oncomplete = () => resolve(deleted);\n });\n }\n\n /**\n * Clear all WAL entries (use with caution).\n */\n async clear(): Promise<void> {\n return new Promise((resolve, reject) => {\n const tx = this.db.transaction(WAL_STORE_NAME, 'readwrite');\n const store = tx.objectStore(WAL_STORE_NAME);\n const request = store.clear();\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => {\n this.sequence = 0;\n resolve();\n };\n });\n }\n}\n\n/**\n * WAL-enabled operation wrapper.\n * Logs the operation to WAL before executing, then commits on success.\n */\nexport async function withWAL<T>(\n wal: WAL,\n type: WALOperationType,\n data: Record<string, unknown>,\n operation: () => Promise<T>\n): Promise<T> {\n const entryId = await wal.log(type, data);\n\n try {\n const result = await operation();\n await wal.commit(entryId);\n return result;\n } catch (error) {\n await wal.rollback(entryId);\n throw error;\n }\n}\n\n/**\n * Create WAL replay executor for the storage layer.\n */\nexport function createReplayExecutor(storage: {\n addDocument: (doc: unknown) => Promise<void>;\n deleteDocument: (id: string) => Promise<void>;\n addVector: (vec: unknown) => Promise<void>;\n deleteVector: (id: string) => Promise<void>;\n saveIndex: (collectionId: string, data: unknown) => Promise<void>;\n createCollection: (collection: unknown) => Promise<void>;\n deleteCollection: (id: string) => Promise<void>;\n clearCollection: (collectionId: string) => Promise<void>;\n clear: () => Promise<void>;\n}): (entry: WALEntry) => Promise<void> {\n return async (entry: WALEntry) => {\n switch (entry.type) {\n case 'add_document':\n case 'update_document':\n await storage.addDocument(entry.data.document);\n break;\n\n case 'delete_document':\n await storage.deleteDocument(entry.data.id as string);\n break;\n\n case 'add_vector':\n await storage.addVector(entry.data.vector);\n break;\n\n case 'delete_vector':\n await storage.deleteVector(entry.data.id as string);\n break;\n\n case 'save_index':\n await storage.saveIndex(entry.data.collectionId as string, entry.data.index);\n break;\n\n case 'create_collection':\n await storage.createCollection(entry.data.collection);\n break;\n\n case 'delete_collection':\n await storage.deleteCollection(entry.data.id as string);\n break;\n\n case 'clear_collection':\n await storage.clearCollection(entry.data.collectionId as string);\n break;\n\n case 'clear_database':\n await storage.clear();\n break;\n\n default:\n console.warn(`Unknown WAL operation type: ${entry.type}`);\n }\n };\n}\n","/**\n * Database migrations system.\n * Handles schema upgrades between versions.\n */\n\nimport { STORE_NAMES } from './schema.js';\nimport { createWALSchema } from './wal.js';\n\n/**\n * Migration function signature.\n */\nexport type MigrationFn = (db: IDBDatabase, transaction: IDBTransaction) => void | Promise<void>;\n\n/**\n * Migration definition.\n */\nexport interface Migration {\n /** Version this migration upgrades TO */\n version: number;\n /** Human-readable description */\n description: string;\n /** Migration function */\n migrate: MigrationFn;\n}\n\n/**\n * All registered migrations.\n * Add new migrations here when schema changes are needed.\n */\nexport const MIGRATIONS: Migration[] = [\n {\n version: 1,\n description: 'Initial schema with documents, vectors, indexes, collections, and meta stores',\n migrate: (db: IDBDatabase) => {\n // Documents store: metadata for each document\n if (!db.objectStoreNames.contains(STORE_NAMES.DOCUMENTS)) {\n const docStore = db.createObjectStore(STORE_NAMES.DOCUMENTS, { keyPath: 'id' });\n docStore.createIndex('collectionId', 'collectionId', { unique: false });\n docStore.createIndex('collectionId_createdAt', ['collectionId', 'createdAt'], {\n unique: false,\n });\n }\n\n // Vectors store: raw vector data\n if (!db.objectStoreNames.contains(STORE_NAMES.VECTORS)) {\n const vecStore = db.createObjectStore(STORE_NAMES.VECTORS, { keyPath: 'id' });\n vecStore.createIndex('collectionId', 'collectionId', { unique: false });\n }\n\n // Indexes store: serialized HNSW graphs per collection\n if (!db.objectStoreNames.contains(STORE_NAMES.INDEXES)) {\n db.createObjectStore(STORE_NAMES.INDEXES, { keyPath: 'collectionId' });\n }\n\n // Collections store: collection metadata\n if (!db.objectStoreNames.contains(STORE_NAMES.COLLECTIONS)) {\n const collStore = db.createObjectStore(STORE_NAMES.COLLECTIONS, { keyPath: 'id' });\n collStore.createIndex('name', 'name', { unique: true });\n }\n\n // Meta store: database metadata\n if (!db.objectStoreNames.contains(STORE_NAMES.META)) {\n db.createObjectStore(STORE_NAMES.META, { keyPath: 'key' });\n }\n },\n },\n {\n version: 2,\n description: 'Add WAL store for crash recovery',\n migrate: (db: IDBDatabase) => {\n createWALSchema(db);\n },\n },\n {\n version: 3,\n description: 'Add encryption metadata to documents and vectors',\n migrate: (db: IDBDatabase) => {\n // Add encrypted flag store for tracking encrypted entries\n if (!db.objectStoreNames.contains('encryption')) {\n db.createObjectStore('encryption', { keyPath: 'key' });\n }\n },\n },\n];\n\n/**\n * Get the current database version.\n */\nexport function getCurrentVersion(): number {\n return MIGRATIONS.length > 0 ? Math.max(...MIGRATIONS.map((m) => m.version)) : 0;\n}\n\n/**\n * Get migrations needed to upgrade from one version to another.\n */\nexport function getMigrationsToRun(fromVersion: number, toVersion: number): Migration[] {\n return MIGRATIONS.filter((m) => m.version > fromVersion && m.version <= toVersion).sort(\n (a, b) => a.version - b.version\n );\n}\n\n/**\n * Run migrations during database upgrade.\n * This is called from the onupgradeneeded handler.\n */\nexport function runMigrations(\n db: IDBDatabase,\n transaction: IDBTransaction,\n oldVersion: number,\n newVersion: number\n): void {\n const migrations = getMigrationsToRun(oldVersion, newVersion);\n\n for (const migration of migrations) {\n console.log(`Running migration v${migration.version}: ${migration.description}`);\n\n try {\n const result = migration.migrate(db, transaction);\n\n // Handle async migrations (note: they should be sync in onupgradeneeded)\n if (result instanceof Promise) {\n console.warn(\n `Migration v${migration.version} is async, which may not work correctly in onupgradeneeded`\n );\n }\n } catch (error) {\n console.error(`Migration v${migration.version} failed:`, error);\n throw error;\n }\n }\n}\n\n/**\n * Migration manager for tracking and running migrations.\n */\nexport class MigrationManager {\n private db: IDBDatabase | null = null;\n private dbName: string;\n\n constructor(dbName: string) {\n this.dbName = dbName;\n }\n\n /**\n * Get the stored schema version.\n */\n async getStoredVersion(): Promise<number> {\n if (!this.db) {\n throw new Error('Database not open');\n }\n\n return new Promise((resolve, reject) => {\n const tx = this.db!.transaction(STORE_NAMES.META, 'readonly');\n const store = tx.objectStore(STORE_NAMES.META);\n const request = store.get('schema_version');\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const record = request.result;\n resolve(record?.value ?? 0);\n };\n });\n }\n\n /**\n * Set the stored schema version.\n */\n async setStoredVersion(version: number): Promise<void> {\n if (!this.db) {\n throw new Error('Database not open');\n }\n\n return new Promise((resolve, reject) => {\n const tx = this.db!.transaction(STORE_NAMES.META, 'readwrite');\n const store = tx.objectStore(STORE_NAMES.META);\n const request = store.put({ key: 'schema_version', value: version });\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve();\n });\n }\n\n /**\n * Check if migrations are needed.\n */\n async needsMigration(): Promise<boolean> {\n const stored = await this.getStoredVersion();\n const current = getCurrentVersion();\n return stored < current;\n }\n\n /**\n * Open database and handle migrations.\n */\n async open(): Promise<IDBDatabase> {\n const currentVersion = getCurrentVersion();\n\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(this.dbName, currentVersion);\n\n request.onerror = () => {\n reject(new Error(`Failed to open database: ${request.error?.message}`));\n };\n\n request.onsuccess = () => {\n this.db = request.result;\n resolve(this.db);\n };\n\n request.onupgradeneeded = (event) => {\n const db = request.result;\n const transaction = request.transaction!;\n const oldVersion = event.oldVersion;\n const newVersion = event.newVersion ?? currentVersion;\n\n runMigrations(db, transaction, oldVersion, newVersion);\n };\n\n request.onblocked = () => {\n console.warn('Database upgrade blocked. Please close other tabs.');\n };\n });\n }\n\n /**\n * Close the database connection.\n */\n close(): void {\n if (this.db) {\n this.db.close();\n this.db = null;\n }\n }\n\n /**\n * Get migration history (for debugging).\n */\n getMigrationHistory(): Array<{ version: number; description: string }> {\n return MIGRATIONS.map((m) => ({\n version: m.version,\n description: m.description,\n }));\n }\n}\n\n/**\n * Data migration utilities for complex migrations that need to transform data.\n */\nexport const DataMigrationUtils = {\n /**\n * Iterate over all records in a store and transform them.\n */\n async transformStore<T>(\n db: IDBDatabase,\n storeName: string,\n transform: (record: T) => T | null,\n options: { batchSize?: number; onProgress?: (done: number, total: number) => void } = {}\n ): Promise<number> {\n const batchSize = options.batchSize ?? 100;\n\n return new Promise((resolve, reject) => {\n const countTx = db.transaction(storeName, 'readonly');\n const countRequest = countTx.objectStore(storeName).count();\n\n countRequest.onerror = () => reject(countRequest.error);\n countRequest.onsuccess = () => {\n const total = countRequest.result;\n let processed = 0;\n let transformed = 0;\n\n const processBatch = (): void => {\n const tx = db.transaction(storeName, 'readwrite');\n const store = tx.objectStore(storeName);\n let batchCount = 0;\n\n const request = store.openCursor();\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const cursor = request.result;\n\n if (cursor && batchCount < batchSize) {\n const record = cursor.value as T;\n const newRecord = transform(record);\n\n if (newRecord === null) {\n cursor.delete();\n } else if (newRecord !== record) {\n cursor.update(newRecord);\n transformed++;\n }\n\n processed++;\n batchCount++;\n cursor.continue();\n }\n };\n\n tx.oncomplete = () => {\n options.onProgress?.(processed, total);\n\n if (processed < total) {\n // Process next batch\n setTimeout(processBatch, 0);\n } else {\n resolve(transformed);\n }\n };\n\n tx.onerror = () => reject(tx.error);\n };\n\n if (total > 0) {\n processBatch();\n } else {\n resolve(0);\n }\n };\n });\n },\n\n /**\n * Copy data from one store to another.\n */\n async copyStore(\n db: IDBDatabase,\n sourceStore: string,\n targetStore: string,\n transform?: (record: unknown) => unknown\n ): Promise<number> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction([sourceStore, targetStore], 'readwrite');\n const source = tx.objectStore(sourceStore);\n const target = tx.objectStore(targetStore);\n\n const request = source.openCursor();\n let copied = 0;\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const cursor = request.result;\n\n if (cursor) {\n const record = transform ? transform(cursor.value) : cursor.value;\n target.put(record);\n copied++;\n cursor.continue();\n }\n };\n\n tx.oncomplete = () => resolve(copied);\n tx.onerror = () => reject(tx.error);\n });\n },\n\n /**\n * Rename an object store (by copying data).\n */\n async renameStore(\n db: IDBDatabase,\n oldName: string,\n newName: string,\n keyPath: string | string[]\n ): Promise<void> {\n // Create new store\n if (!db.objectStoreNames.contains(newName)) {\n db.createObjectStore(newName, { keyPath });\n }\n\n // Copy data\n await this.copyStore(db, oldName, newName);\n\n // Delete old store\n db.deleteObjectStore(oldName);\n },\n};\n","/**\n * IndexedDB storage adapter.\n */\n\nimport type { StoredDocument, StoredVector, Collection, SerializedHNSWIndex } from '../types.js';\nimport {\n STORE_NAMES,\n type DocumentRecord,\n type VectorRecord,\n type IndexRecord,\n type CollectionRecord,\n} from './schema.js';\nimport { runMigrations, getCurrentVersion } from './migrations.js';\nimport { WAL, WAL_STORE_NAME, createReplayExecutor } from './wal.js';\n\nexport class IndexedDBStorage {\n private db: IDBDatabase | null = null;\n private dbName: string;\n private wal: WAL | null = null;\n private walEnabled: boolean;\n\n constructor(name: string, options: { enableWAL?: boolean } = {}) {\n this.dbName = `vectordb_${name}`;\n this.walEnabled = options.enableWAL ?? false;\n }\n\n /**\n * Open the database connection.\n */\n async open(): Promise<void> {\n if (this.db) return;\n\n const currentVersion = getCurrentVersion();\n\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(this.dbName, currentVersion);\n\n request.onerror = () => {\n reject(new Error(`Failed to open database: ${request.error?.message}`));\n };\n\n request.onsuccess = async () => {\n this.db = request.result;\n\n // Initialize WAL if enabled\n if (this.walEnabled && this.db.objectStoreNames.contains(WAL_STORE_NAME)) {\n this.wal = new WAL(this.db);\n const pendingCount = await this.wal.initialize();\n\n // Replay pending operations if any\n if (pendingCount > 0) {\n console.log(`Replaying ${pendingCount} pending WAL operations...`);\n const executor = createReplayExecutor(\n this as unknown as Parameters<typeof createReplayExecutor>[0]\n );\n const replayed = await this.wal.replay(executor);\n console.log(`Replayed ${replayed} WAL operations`);\n }\n }\n\n resolve();\n };\n\n request.onupgradeneeded = (event) => {\n const db = (event.target as IDBOpenDBRequest).result;\n const transaction = (event.target as IDBOpenDBRequest).transaction!;\n const oldVersion = event.oldVersion;\n const newVersion = event.newVersion ?? currentVersion;\n\n runMigrations(db, transaction, oldVersion, newVersion);\n };\n\n request.onblocked = () => {\n console.warn('Database upgrade blocked. Close other tabs using this database.');\n };\n });\n }\n\n /**\n * Get the WAL instance (if enabled).\n */\n getWAL(): WAL | null {\n return this.wal;\n }\n\n /**\n * Close the database connection.\n */\n async close(): Promise<void> {\n if (this.db) {\n this.db.close();\n this.db = null;\n }\n }\n\n /**\n * Ensure the database is open.\n */\n private ensureOpen(): IDBDatabase {\n if (!this.db) {\n throw new Error('Database not open. Call open() first.');\n }\n return this.db;\n }\n\n // ============================================\n // Document Operations\n // ============================================\n\n async addDocument(doc: StoredDocument): Promise<void> {\n const db = this.ensureOpen();\n const record: DocumentRecord = {\n id: doc.id,\n collectionId: doc.collectionId,\n metadata: doc.metadata,\n createdAt: doc.createdAt,\n updatedAt: doc.updatedAt,\n };\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.DOCUMENTS, 'readwrite');\n const store = tx.objectStore(STORE_NAMES.DOCUMENTS);\n const request = store.put(record);\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve();\n });\n }\n\n async getDocument(id: string): Promise<StoredDocument | null> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.DOCUMENTS, 'readonly');\n const store = tx.objectStore(STORE_NAMES.DOCUMENTS);\n const request = store.get(id);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const record = request.result as DocumentRecord | undefined;\n if (!record) {\n resolve(null);\n return;\n }\n resolve({\n id: record.id,\n collectionId: record.collectionId,\n metadata: record.metadata,\n createdAt: record.createdAt,\n updatedAt: record.updatedAt,\n });\n };\n });\n }\n\n async deleteDocument(id: string): Promise<void> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.DOCUMENTS, 'readwrite');\n const store = tx.objectStore(STORE_NAMES.DOCUMENTS);\n const request = store.delete(id);\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve();\n });\n }\n\n async getAllDocuments(collectionId: string): Promise<StoredDocument[]> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.DOCUMENTS, 'readonly');\n const store = tx.objectStore(STORE_NAMES.DOCUMENTS);\n const index = store.index('collectionId');\n const request = index.getAll(collectionId);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const records = request.result as DocumentRecord[];\n resolve(\n records.map((r) => ({\n id: r.id,\n collectionId: r.collectionId,\n metadata: r.metadata,\n createdAt: r.createdAt,\n updatedAt: r.updatedAt,\n }))\n );\n };\n });\n }\n\n async countDocuments(collectionId: string): Promise<number> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.DOCUMENTS, 'readonly');\n const store = tx.objectStore(STORE_NAMES.DOCUMENTS);\n const index = store.index('collectionId');\n const request = index.count(collectionId);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve(request.result);\n });\n }\n\n // ============================================\n // Vector Operations\n // ============================================\n\n async addVector(vec: StoredVector): Promise<void> {\n const db = this.ensureOpen();\n const record: VectorRecord = {\n id: vec.id,\n collectionId: vec.collectionId,\n vector: vec.vector,\n };\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.VECTORS, 'readwrite');\n const store = tx.objectStore(STORE_NAMES.VECTORS);\n const request = store.put(record);\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve();\n });\n }\n\n async getVector(id: string): Promise<Float32Array | null> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.VECTORS, 'readonly');\n const store = tx.objectStore(STORE_NAMES.VECTORS);\n const request = store.get(id);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const record = request.result as VectorRecord | undefined;\n resolve(record?.vector ?? null);\n };\n });\n }\n\n async deleteVector(id: string): Promise<void> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.VECTORS, 'readwrite');\n const store = tx.objectStore(STORE_NAMES.VECTORS);\n const request = store.delete(id);\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve();\n });\n }\n\n async getAllVectors(collectionId: string): Promise<Map<string, Float32Array>> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.VECTORS, 'readonly');\n const store = tx.objectStore(STORE_NAMES.VECTORS);\n const index = store.index('collectionId');\n const request = index.getAll(collectionId);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const records = request.result as VectorRecord[];\n const map = new Map<string, Float32Array>();\n for (const r of records) {\n map.set(r.id, r.vector);\n }\n resolve(map);\n };\n });\n }\n\n // ============================================\n // Index Operations\n // ============================================\n\n async saveIndex(collectionId: string, index: SerializedHNSWIndex): Promise<void> {\n const db = this.ensureOpen();\n const record: IndexRecord = {\n collectionId,\n data: JSON.stringify(index),\n updatedAt: Date.now(),\n };\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.INDEXES, 'readwrite');\n const store = tx.objectStore(STORE_NAMES.INDEXES);\n const request = store.put(record);\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve();\n });\n }\n\n async loadIndex(collectionId: string): Promise<SerializedHNSWIndex | null> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.INDEXES, 'readonly');\n const store = tx.objectStore(STORE_NAMES.INDEXES);\n const request = store.get(collectionId);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const record = request.result as IndexRecord | undefined;\n if (!record) {\n resolve(null);\n return;\n }\n try {\n resolve(JSON.parse(record.data) as SerializedHNSWIndex);\n } catch {\n resolve(null);\n }\n };\n });\n }\n\n async deleteIndex(collectionId: string): Promise<void> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.INDEXES, 'readwrite');\n const store = tx.objectStore(STORE_NAMES.INDEXES);\n const request = store.delete(collectionId);\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve();\n });\n }\n\n // ============================================\n // Collection Operations\n // ============================================\n\n async createCollection(collection: Collection): Promise<void> {\n const db = this.ensureOpen();\n const record: CollectionRecord = {\n id: collection.id,\n name: collection.name,\n dimensions: collection.dimensions,\n createdAt: collection.createdAt,\n };\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.COLLECTIONS, 'readwrite');\n const store = tx.objectStore(STORE_NAMES.COLLECTIONS);\n const request = store.put(record);\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve();\n });\n }\n\n async getCollection(id: string): Promise<Collection | null> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.COLLECTIONS, 'readonly');\n const store = tx.objectStore(STORE_NAMES.COLLECTIONS);\n const request = store.get(id);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const record = request.result as CollectionRecord | undefined;\n if (!record) {\n resolve(null);\n return;\n }\n resolve({\n id: record.id,\n name: record.name,\n dimensions: record.dimensions,\n createdAt: record.createdAt,\n });\n };\n });\n }\n\n async getCollectionByName(name: string): Promise<Collection | null> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.COLLECTIONS, 'readonly');\n const store = tx.objectStore(STORE_NAMES.COLLECTIONS);\n const index = store.index('name');\n const request = index.get(name);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const record = request.result as CollectionRecord | undefined;\n if (!record) {\n resolve(null);\n return;\n }\n resolve({\n id: record.id,\n name: record.name,\n dimensions: record.dimensions,\n createdAt: record.createdAt,\n });\n };\n });\n }\n\n async getAllCollections(): Promise<Collection[]> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.COLLECTIONS, 'readonly');\n const store = tx.objectStore(STORE_NAMES.COLLECTIONS);\n const request = store.getAll();\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const records = request.result as CollectionRecord[];\n resolve(\n records.map((r) => ({\n id: r.id,\n name: r.name,\n dimensions: r.dimensions,\n createdAt: r.createdAt,\n }))\n );\n };\n });\n }\n\n async deleteCollection(id: string): Promise<void> {\n const db = this.ensureOpen();\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAMES.COLLECTIONS, 'readwrite');\n const store = tx.objectStore(STORE_NAMES.COLLECTIONS);\n const request = store.delete(id);\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve();\n });\n }\n\n // ============================================\n // Utility Operations\n // ============================================\n\n async clear(): Promise<void> {\n const db = this.ensureOpen();\n\n const storeNames = [\n STORE_NAMES.DOCUMENTS,\n STORE_NAMES.VECTORS,\n STORE_NAMES.INDEXES,\n STORE_NAMES.COLLECTIONS,\n ];\n\n return new Promise((resolve, reject) => {\n const tx = db.transaction(storeNames, 'readwrite');\n\n for (const name of storeNames) {\n tx.objectStore(name).clear();\n }\n\n tx.onerror = () => reject(tx.error);\n tx.oncomplete = () => resolve();\n });\n }\n\n async clearCollection(collectionId: string): Promise<void> {\n const db = this.ensureOpen();\n\n // Get all document IDs for this collection\n const docs = await this.getAllDocuments(collectionId);\n const ids = docs.map((d) => d.id);\n\n // Delete documents and vectors\n const tx = db.transaction([STORE_NAMES.DOCUMENTS, STORE_NAMES.VECTORS], 'readwrite');\n const docStore = tx.objectStore(STORE_NAMES.DOCUMENTS);\n const vecStore = tx.objectStore(STORE_NAMES.VECTORS);\n\n for (const id of ids) {\n docStore.delete(id);\n vecStore.delete(id);\n }\n\n await new Promise<void>((resolve, reject) => {\n tx.onerror = () => reject(tx.error);\n tx.oncomplete = () => resolve();\n });\n\n // Delete the index\n await this.deleteIndex(collectionId);\n }\n\n /**\n * Estimate storage size in bytes.\n */\n async estimateSize(): Promise<number> {\n if (navigator.storage && navigator.storage.estimate) {\n const estimate = await navigator.storage.estimate();\n return estimate.usage ?? 0;\n }\n return 0;\n }\n}\n","/**\n * In-memory storage adapter for testing.\n */\n\nimport type { StoredDocument, StoredVector, Collection, SerializedHNSWIndex } from '../types.js';\n\nexport class MemoryStorage {\n private documents: Map<string, StoredDocument> = new Map();\n private vectors: Map<string, StoredVector> = new Map();\n private indexes: Map<string, SerializedHNSWIndex> = new Map();\n private collections: Map<string, Collection> = new Map();\n\n async open(): Promise<void> {\n // No-op for memory storage\n }\n\n async close(): Promise<void> {\n // No-op for memory storage\n }\n\n // ============================================\n // Document Operations\n // ============================================\n\n async addDocument(doc: StoredDocument): Promise<void> {\n this.documents.set(doc.id, { ...doc });\n }\n\n async getDocument(id: string): Promise<StoredDocument | null> {\n const doc = this.documents.get(id);\n return doc ? { ...doc } : null;\n }\n\n async deleteDocument(id: string): Promise<void> {\n this.documents.delete(id);\n }\n\n async getAllDocuments(collectionId: string): Promise<StoredDocument[]> {\n const docs: StoredDocument[] = [];\n for (const doc of this.documents.values()) {\n if (doc.collectionId === collectionId) {\n docs.push({ ...doc });\n }\n }\n return docs;\n }\n\n async countDocuments(collectionId: string): Promise<number> {\n let count = 0;\n for (const doc of this.documents.values()) {\n if (doc.collectionId === collectionId) {\n count++;\n }\n }\n return count;\n }\n\n // ============================================\n // Vector Operations\n // ============================================\n\n async addVector(vec: StoredVector): Promise<void> {\n this.vectors.set(vec.id, {\n id: vec.id,\n collectionId: vec.collectionId,\n vector: new Float32Array(vec.vector),\n });\n }\n\n async getVector(id: string): Promise<Float32Array | null> {\n const vec = this.vectors.get(id);\n return vec ? new Float32Array(vec.vector) : null;\n }\n\n async deleteVector(id: string): Promise<void> {\n this.vectors.delete(id);\n }\n\n async getAllVectors(collectionId: string): Promise<Map<string, Float32Array>> {\n const result = new Map<string, Float32Array>();\n for (const vec of this.vectors.values()) {\n if (vec.collectionId === collectionId) {\n result.set(vec.id, new Float32Array(vec.vector));\n }\n }\n return result;\n }\n\n // ============================================\n // Index Operations\n // ============================================\n\n async saveIndex(collectionId: string, index: SerializedHNSWIndex): Promise<void> {\n this.indexes.set(collectionId, JSON.parse(JSON.stringify(index)));\n }\n\n async loadIndex(collectionId: string): Promise<SerializedHNSWIndex | null> {\n const index = this.indexes.get(collectionId);\n return index ? JSON.parse(JSON.stringify(index)) : null;\n }\n\n async deleteIndex(collectionId: string): Promise<void> {\n this.indexes.delete(collectionId);\n }\n\n // ============================================\n // Collection Operations\n // ============================================\n\n async createCollection(collection: Collection): Promise<void> {\n this.collections.set(collection.id, { ...collection });\n }\n\n async getCollection(id: string): Promise<Collection | null> {\n const collection = this.collections.get(id);\n return collection ? { ...collection } : null;\n }\n\n async getCollectionByName(name: string): Promise<Collection | null> {\n for (const collection of this.collections.values()) {\n if (collection.name === name) {\n return { ...collection };\n }\n }\n return null;\n }\n\n async getAllCollections(): Promise<Collection[]> {\n return Array.from(this.collections.values()).map((c) => ({ ...c }));\n }\n\n async deleteCollection(id: string): Promise<void> {\n this.collections.delete(id);\n }\n\n // ============================================\n // Utility Operations\n // ============================================\n\n async clear(): Promise<void> {\n this.documents.clear();\n this.vectors.clear();\n this.indexes.clear();\n this.collections.clear();\n }\n\n async clearCollection(collectionId: string): Promise<void> {\n // Delete documents\n for (const [id, doc] of this.documents) {\n if (doc.collectionId === collectionId) {\n this.documents.delete(id);\n }\n }\n\n // Delete vectors\n for (const [id, vec] of this.vectors) {\n if (vec.collectionId === collectionId) {\n this.vectors.delete(id);\n }\n }\n\n // Delete index\n this.indexes.delete(collectionId);\n }\n\n async estimateSize(): Promise<number> {\n // Rough estimate\n let size = 0;\n for (const vec of this.vectors.values()) {\n size += vec.vector.byteLength;\n }\n return size;\n }\n}\n\n","/**\n * Storage exports.\n */\n\nexport { IndexedDBStorage } from './indexeddb.js';\nexport { MemoryStorage } from './memory.js';\nexport * from './schema.js';\nexport {\n WAL,\n WAL_STORE_NAME,\n createWALSchema,\n withWAL,\n createReplayExecutor,\n type WALOperationType,\n type WALEntry,\n} from './wal.js';\nexport {\n MigrationManager,\n MIGRATIONS,\n getCurrentVersion,\n getMigrationsToRun,\n runMigrations,\n DataMigrationUtils,\n type Migration,\n type MigrationFn,\n} from './migrations.js';\n\nimport { IndexedDBStorage } from './indexeddb.js';\nimport { MemoryStorage } from './memory.js';\n\nexport type Storage = IndexedDBStorage | MemoryStorage;\n\nexport function createStorage(type: 'indexeddb' | 'memory', name: string): Storage {\n if (type === 'memory') {\n return new MemoryStorage();\n }\n return new IndexedDBStorage(name);\n}\n","/**\n * Metadata filtering logic.\n */\n\nimport type { FilterQuery } from '../types.js';\n\n/**\n * Check if a document's metadata matches a filter query.\n */\nexport function matchesFilter(\n metadata: Record<string, unknown> | undefined,\n filter: FilterQuery\n): boolean {\n if (!filter || Object.keys(filter).length === 0) {\n return true;\n }\n\n if (!metadata) {\n return false;\n }\n\n for (const [key, condition] of Object.entries(filter)) {\n const value = metadata[key];\n\n if (!matchesCondition(value, condition)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Check if a value matches a single condition.\n */\nfunction matchesCondition(value: unknown, condition: unknown): boolean {\n // Null condition check\n if (condition === null) {\n return value === null;\n }\n\n // Operator objects\n if (typeof condition === 'object' && condition !== null) {\n const ops = condition as Record<string, unknown>;\n\n // $in: value must be in the array\n if ('$in' in ops) {\n const inArray = ops.$in as unknown[];\n return inArray.includes(value);\n }\n\n // $nin: value must not be in the array\n if ('$nin' in ops) {\n const ninArray = ops.$nin as unknown[];\n return !ninArray.includes(value);\n }\n\n // $gt: value must be greater than\n if ('$gt' in ops) {\n return typeof value === 'number' && value > (ops.$gt as number);\n }\n\n // $gte: value must be greater than or equal\n if ('$gte' in ops) {\n return typeof value === 'number' && value >= (ops.$gte as number);\n }\n\n // $lt: value must be less than\n if ('$lt' in ops) {\n return typeof value === 'number' && value < (ops.$lt as number);\n }\n\n // $lte: value must be less than or equal\n if ('$lte' in ops) {\n return typeof value === 'number' && value <= (ops.$lte as number);\n }\n\n // $ne: value must not equal\n if ('$ne' in ops) {\n return value !== ops.$ne;\n }\n\n // $exists: field must exist (or not)\n if ('$exists' in ops) {\n const shouldExist = ops.$exists as boolean;\n const exists = value !== undefined;\n return shouldExist ? exists : !exists;\n }\n\n // Unknown operator or nested object - treat as exact match\n return JSON.stringify(value) === JSON.stringify(condition);\n }\n\n // Exact match for primitives\n return value === condition;\n}\n\n/**\n * Apply a filter to an array of items.\n */\nexport function applyFilter<T extends { metadata?: Record<string, unknown> }>(\n items: T[],\n filter: FilterQuery | undefined\n): T[] {\n if (!filter || Object.keys(filter).length === 0) {\n return items;\n }\n\n return items.filter((item) => matchesFilter(item.metadata, filter));\n}\n\n","/**\n * Cross-tab locking using the Web Locks API.\n * Ensures write operations are synchronized across browser tabs.\n */\n\n/**\n * Web Locks API types (for environments that don't have them).\n */\ninterface LockRequestOptionsInternal {\n mode: 'exclusive' | 'shared';\n ifAvailable?: boolean;\n steal?: boolean;\n signal?: AbortSignal;\n}\n\ninterface LockInfoInternal {\n name?: string;\n mode?: 'exclusive' | 'shared';\n clientId?: string;\n}\n\ninterface LockManagerSnapshot {\n held?: LockInfoInternal[];\n pending?: LockInfoInternal[];\n}\n\n/**\n * Lock mode for database operations.\n */\nexport type LockMode = 'shared' | 'exclusive';\n\n/**\n * Lock options for acquiring locks.\n */\nexport interface LockOptions {\n /** Lock mode: 'shared' for reads, 'exclusive' for writes */\n mode?: LockMode;\n /** Timeout in milliseconds (0 = no timeout) */\n timeout?: number;\n /** If true, fail immediately if lock is not available */\n ifAvailable?: boolean;\n /** Signal to abort the lock request */\n signal?: AbortSignal;\n}\n\n/**\n * Lock manager for cross-tab synchronization.\n */\nexport class LockManager {\n private dbName: string;\n private lockPrefix: string;\n\n constructor(dbName: string) {\n this.dbName = dbName;\n this.lockPrefix = `vectordb_${dbName}_`;\n }\n\n /**\n * Check if Web Locks API is available.\n */\n static isSupported(): boolean {\n return typeof navigator !== 'undefined' && 'locks' in navigator;\n }\n\n /**\n * Get the full lock name for a resource.\n */\n private getLockName(resource: string): string {\n return `${this.lockPrefix}${resource}`;\n }\n\n /**\n * Acquire a lock and execute a callback.\n * Falls back to immediate execution if Web Locks is not available.\n */\n async withLock<T>(\n resource: string,\n callback: () => Promise<T>,\n options: LockOptions = {}\n ): Promise<T> {\n if (!LockManager.isSupported()) {\n // Fallback: execute without locking\n return callback();\n }\n\n const lockName = this.getLockName(resource);\n const mode = options.mode ?? 'exclusive';\n\n // Build lock options\n const lockOptions: LockRequestOptionsInternal = {\n mode,\n ifAvailable: options.ifAvailable,\n signal: options.signal,\n };\n\n return new Promise<T>((resolve, reject) => {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n let abortController: AbortController | null = null;\n\n // Handle timeout\n if (options.timeout && options.timeout > 0) {\n abortController = new AbortController();\n lockOptions.signal = lockOptions.signal\n ? combineSignals(lockOptions.signal, abortController.signal)\n : abortController.signal;\n\n timeoutId = setTimeout(() => {\n abortController?.abort();\n reject(new Error(`Lock timeout: ${resource}`));\n }, options.timeout);\n }\n\n navigator.locks\n .request(lockName, lockOptions, async () => {\n try {\n const result = await callback();\n resolve(result);\n } catch (error) {\n reject(error);\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n })\n .catch((error: Error) => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n // Handle specific lock errors\n if (error.name === 'AbortError') {\n if (options.ifAvailable) {\n reject(new Error(`Lock not available: ${resource}`));\n } else {\n reject(new Error(`Lock aborted: ${resource}`));\n }\n } else {\n reject(error);\n }\n });\n });\n }\n\n /**\n * Acquire a read lock (shared).\n */\n async withReadLock<T>(resource: string, callback: () => Promise<T>): Promise<T> {\n return this.withLock(resource, callback, { mode: 'shared' });\n }\n\n /**\n * Acquire a write lock (exclusive).\n */\n async withWriteLock<T>(resource: string, callback: () => Promise<T>): Promise<T> {\n return this.withLock(resource, callback, { mode: 'exclusive' });\n }\n\n /**\n * Try to acquire a lock immediately, returning null if not available.\n */\n async tryLock<T>(\n resource: string,\n callback: () => Promise<T>,\n mode: LockMode = 'exclusive'\n ): Promise<T | null> {\n if (!LockManager.isSupported()) {\n return callback();\n }\n\n const lockName = this.getLockName(resource);\n\n return new Promise<T | null>((resolve, reject) => {\n navigator.locks\n .request(lockName, { mode, ifAvailable: true }, async (lock) => {\n if (!lock) {\n resolve(null);\n return;\n }\n\n try {\n const result = await callback();\n resolve(result);\n } catch (error) {\n reject(error);\n }\n })\n .catch(reject);\n });\n }\n\n /**\n * Get information about held locks (for debugging).\n */\n async getLockState(): Promise<{ held: string[]; pending: string[] }> {\n if (!LockManager.isSupported()) {\n return { held: [], pending: [] };\n }\n\n const state = (await navigator.locks.query()) as LockManagerSnapshot;\n const prefix = this.lockPrefix;\n\n return {\n held: (state.held ?? [])\n .filter((lock) => lock.name?.startsWith(prefix))\n .map((lock) => (lock.name ?? '').replace(prefix, '')),\n pending: (state.pending ?? [])\n .filter((lock) => lock.name?.startsWith(prefix))\n .map((lock) => (lock.name ?? '').replace(prefix, '')),\n };\n }\n}\n\n/**\n * Combine multiple AbortSignals into one.\n */\nfunction combineSignals(...signals: AbortSignal[]): AbortSignal {\n const controller = new AbortController();\n\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort();\n break;\n }\n signal.addEventListener('abort', () => controller.abort(), { once: true });\n }\n\n return controller.signal;\n}\n\n/**\n * Default lock manager instance (lazily created).\n */\nlet defaultLockManager: LockManager | null = null;\n\n/**\n * Get or create the default lock manager for a database.\n */\nexport function getLockManager(dbName: string): LockManager {\n if (!defaultLockManager || defaultLockManager['dbName'] !== dbName) {\n defaultLockManager = new LockManager(dbName);\n }\n return defaultLockManager;\n}\n","/**\n * Cross-tab communication using BroadcastChannel.\n * Notifies other tabs of database changes for cache invalidation.\n */\n\n/**\n * Message types for cross-tab communication.\n */\nexport type BroadcastMessageType =\n | 'document_added'\n | 'document_updated'\n | 'document_deleted'\n | 'documents_deleted'\n | 'collection_cleared'\n | 'database_cleared'\n | 'index_updated'\n | 'leader_elected'\n | 'leader_ping';\n\n/**\n * Message payload for broadcast events.\n */\nexport interface BroadcastMessage {\n type: BroadcastMessageType;\n dbName: string;\n collectionId?: string;\n documentId?: string;\n documentIds?: string[];\n timestamp: number;\n tabId: string;\n}\n\n/**\n * Listener callback type.\n */\nexport type BroadcastListener = (message: BroadcastMessage) => void;\n\n/**\n * Generate a unique tab ID.\n */\nfunction generateTabId(): string {\n return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Cross-tab broadcaster for database change notifications.\n */\nexport class Broadcaster {\n private channel: BroadcastChannel | null = null;\n private dbName: string;\n private tabId: string;\n private listeners: Map<BroadcastMessageType | '*', Set<BroadcastListener>> = new Map();\n private isLeader = false;\n private leaderHeartbeatInterval: ReturnType<typeof setInterval> | null = null;\n\n constructor(dbName: string) {\n this.dbName = dbName;\n this.tabId = generateTabId();\n\n if (typeof BroadcastChannel !== 'undefined') {\n this.channel = new BroadcastChannel(`vectordb_${dbName}`);\n this.channel.onmessage = this.handleMessage.bind(this);\n }\n }\n\n /**\n * Check if BroadcastChannel is supported.\n */\n static isSupported(): boolean {\n return typeof BroadcastChannel !== 'undefined';\n }\n\n /**\n * Get this tab's unique ID.\n */\n getTabId(): string {\n return this.tabId;\n }\n\n /**\n * Check if this tab is the leader.\n */\n getIsLeader(): boolean {\n return this.isLeader;\n }\n\n /**\n * Handle incoming broadcast messages.\n */\n private handleMessage(event: MessageEvent<BroadcastMessage>): void {\n const message = event.data;\n\n // Ignore messages from self\n if (message.tabId === this.tabId) {\n return;\n }\n\n // Notify type-specific listeners\n const typeListeners = this.listeners.get(message.type);\n if (typeListeners) {\n for (const listener of typeListeners) {\n try {\n listener(message);\n } catch (error) {\n console.error('Broadcast listener error:', error);\n }\n }\n }\n\n // Notify wildcard listeners\n const wildcardListeners = this.listeners.get('*');\n if (wildcardListeners) {\n for (const listener of wildcardListeners) {\n try {\n listener(message);\n } catch (error) {\n console.error('Broadcast listener error:', error);\n }\n }\n }\n }\n\n /**\n * Send a broadcast message to other tabs.\n */\n private send(type: BroadcastMessageType, data: Partial<BroadcastMessage> = {}): void {\n if (!this.channel) return;\n\n const message: BroadcastMessage = {\n type,\n dbName: this.dbName,\n timestamp: Date.now(),\n tabId: this.tabId,\n ...data,\n };\n\n this.channel.postMessage(message);\n }\n\n /**\n * Subscribe to broadcast messages.\n */\n on(type: BroadcastMessageType | '*', listener: BroadcastListener): () => void {\n if (!this.listeners.has(type)) {\n this.listeners.set(type, new Set());\n }\n this.listeners.get(type)!.add(listener);\n\n // Return unsubscribe function\n return () => {\n this.listeners.get(type)?.delete(listener);\n };\n }\n\n /**\n * Subscribe to all messages (alias for on('*', ...)).\n */\n onAny(listener: BroadcastListener): () => void {\n return this.on('*', listener);\n }\n\n // ============================================\n // Notification Methods\n // ============================================\n\n /**\n * Notify other tabs that a document was added.\n */\n notifyDocumentAdded(collectionId: string, documentId: string): void {\n this.send('document_added', { collectionId, documentId });\n }\n\n /**\n * Notify other tabs that a document was updated.\n */\n notifyDocumentUpdated(collectionId: string, documentId: string): void {\n this.send('document_updated', { collectionId, documentId });\n }\n\n /**\n * Notify other tabs that a document was deleted.\n */\n notifyDocumentDeleted(collectionId: string, documentId: string): void {\n this.send('document_deleted', { collectionId, documentId });\n }\n\n /**\n * Notify other tabs that multiple documents were deleted.\n */\n notifyDocumentsDeleted(collectionId: string, documentIds: string[]): void {\n this.send('documents_deleted', { collectionId, documentIds });\n }\n\n /**\n * Notify other tabs that a collection was cleared.\n */\n notifyCollectionCleared(collectionId: string): void {\n this.send('collection_cleared', { collectionId });\n }\n\n /**\n * Notify other tabs that the database was cleared.\n */\n notifyDatabaseCleared(): void {\n this.send('database_cleared');\n }\n\n /**\n * Notify other tabs that an index was updated.\n */\n notifyIndexUpdated(collectionId: string): void {\n this.send('index_updated', { collectionId });\n }\n\n // ============================================\n // Leader Election\n // ============================================\n\n /**\n * Start leader election.\n * The first tab to claim leadership wins.\n */\n async electLeader(): Promise<boolean> {\n if (!Broadcaster.isSupported()) {\n // Single tab mode, always leader\n this.isLeader = true;\n return true;\n }\n\n // Try to become leader using a simple timestamp-based approach\n // In a real implementation, you might use Web Locks for more robust election\n const electionKey = `vectordb_${this.dbName}_leader`;\n\n try {\n const stored = localStorage.getItem(electionKey);\n const now = Date.now();\n\n if (!stored) {\n // No leader, claim it\n localStorage.setItem(electionKey, JSON.stringify({ tabId: this.tabId, timestamp: now }));\n this.isLeader = true;\n } else {\n const { tabId, timestamp } = JSON.parse(stored);\n\n // If leader hasn't pinged in 10 seconds, take over\n if (now - timestamp > 10000) {\n localStorage.setItem(electionKey, JSON.stringify({ tabId: this.tabId, timestamp: now }));\n this.isLeader = true;\n } else if (tabId === this.tabId) {\n this.isLeader = true;\n }\n }\n\n if (this.isLeader) {\n this.startLeaderHeartbeat();\n this.send('leader_elected');\n }\n\n return this.isLeader;\n } catch {\n // localStorage might not be available\n this.isLeader = true;\n return true;\n }\n }\n\n /**\n * Start the leader heartbeat to maintain leadership.\n */\n private startLeaderHeartbeat(): void {\n if (this.leaderHeartbeatInterval) return;\n\n const electionKey = `vectordb_${this.dbName}_leader`;\n\n this.leaderHeartbeatInterval = setInterval(() => {\n if (this.isLeader) {\n try {\n localStorage.setItem(\n electionKey,\n JSON.stringify({ tabId: this.tabId, timestamp: Date.now() })\n );\n this.send('leader_ping');\n } catch {\n // Ignore localStorage errors\n }\n }\n }, 5000);\n }\n\n /**\n * Resign from leadership.\n */\n resignLeadership(): void {\n if (!this.isLeader) return;\n\n this.isLeader = false;\n\n if (this.leaderHeartbeatInterval) {\n clearInterval(this.leaderHeartbeatInterval);\n this.leaderHeartbeatInterval = null;\n }\n\n const electionKey = `vectordb_${this.dbName}_leader`;\n try {\n const stored = localStorage.getItem(electionKey);\n if (stored) {\n const { tabId } = JSON.parse(stored);\n if (tabId === this.tabId) {\n localStorage.removeItem(electionKey);\n }\n }\n } catch {\n // Ignore localStorage errors\n }\n }\n\n /**\n * Close the broadcaster and clean up resources.\n */\n close(): void {\n this.resignLeadership();\n\n if (this.channel) {\n this.channel.close();\n this.channel = null;\n }\n\n this.listeners.clear();\n }\n}\n\n/**\n * Create a new broadcaster for a database.\n */\nexport function createBroadcaster(dbName: string): Broadcaster {\n return new Broadcaster(dbName);\n}\n","/**\n * Main VectorDB implementation.\n */\n\nimport type {\n VectorDB,\n VectorDBConfig,\n Document,\n SearchOptions,\n SearchResult,\n AddManyOptions,\n ExportOptions,\n ImportOptions,\n DBStats,\n FilterQuery,\n StoredDocument,\n} from './types.js';\nimport { DEFAULT_CONFIG } from './types.js';\nimport { HNSWIndex } from './hnsw/index.js';\nimport { createStorage, type Storage } from './storage/index.js';\nimport { matchesFilter } from './query/filter.js';\nimport { LockManager } from './sync/locks.js';\nimport { Broadcaster } from './sync/broadcast.js';\n\n/**\n * Internal VectorDB implementation.\n */\nexport class VectorDBImpl implements VectorDB {\n private storage: Storage;\n private index: HNSWIndex | null = null;\n private collectionId: string;\n private collectionName: string;\n private dimensions: number;\n private config: VectorDBConfig;\n private initialized = false;\n private lockManager: LockManager | null = null;\n private broadcaster: Broadcaster | null = null;\n\n constructor(config: VectorDBConfig, collectionName = 'default', existingStorage?: Storage) {\n this.config = config;\n this.dimensions = config.dimensions;\n this.collectionName = collectionName;\n this.collectionId = collectionName; // Use name as ID for simplicity\n this.storage = existingStorage ?? createStorage(config.storage ?? 'indexeddb', config.name);\n\n // Initialize sync features\n const syncConfig = { ...DEFAULT_CONFIG.sync, ...config.sync };\n if (syncConfig.enableLocking && config.storage !== 'memory') {\n this.lockManager = new LockManager(config.name);\n }\n if (syncConfig.enableBroadcast && config.storage !== 'memory') {\n this.broadcaster = new Broadcaster(config.name);\n }\n }\n\n /**\n * Initialize the database and load the index.\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n await this.storage.open();\n\n // Check if collection exists, create if not\n let collection = await this.storage.getCollectionByName(this.collectionName);\n if (!collection) {\n collection = {\n id: this.collectionId,\n name: this.collectionName,\n dimensions: this.dimensions,\n createdAt: Date.now(),\n };\n await this.storage.createCollection(collection);\n } else {\n this.collectionId = collection.id;\n // Validate dimensions match\n if (collection.dimensions !== this.dimensions) {\n throw new Error(\n `Dimension mismatch: expected ${this.dimensions}, stored collection has ${collection.dimensions}`\n );\n }\n }\n\n // Load or create index\n const savedIndex = await this.storage.loadIndex(this.collectionId);\n const vectors = await this.storage.getAllVectors(this.collectionId);\n\n if (savedIndex) {\n this.index = HNSWIndex.deserialize(savedIndex, vectors, this.config.indexOptions);\n } else {\n this.index = new HNSWIndex(this.dimensions, this.config.indexOptions);\n // Add any existing vectors to the index\n for (const [id, vector] of vectors) {\n this.index.add(id, vector);\n }\n }\n\n this.initialized = true;\n }\n\n /**\n * Ensure the database is initialized.\n */\n private ensureInitialized(): void {\n if (!this.initialized) {\n throw new Error('Database not initialized. Call initialize() or use createVectorDB().');\n }\n }\n\n /**\n * Save the index to storage.\n */\n private async saveIndex(): Promise<void> {\n if (!this.index) return;\n const serialized = this.index.serialize();\n await this.storage.saveIndex(this.collectionId, serialized);\n }\n\n // ============================================\n // Public API\n // ============================================\n\n async add(doc: Document): Promise<void> {\n this.ensureInitialized();\n\n if (!doc.id) {\n throw new Error('Document must have an id');\n }\n\n if (!doc.vector || !(doc.vector instanceof Float32Array)) {\n throw new Error('Document must have a Float32Array vector');\n }\n\n if (doc.vector.length !== this.dimensions) {\n throw new Error(\n `Vector dimension mismatch: expected ${this.dimensions}, got ${doc.vector.length}`\n );\n }\n\n const operation = async (): Promise<void> => {\n const now = Date.now();\n\n // Store document metadata\n const storedDoc: StoredDocument = {\n id: doc.id,\n collectionId: this.collectionId,\n metadata: doc.metadata,\n createdAt: now,\n updatedAt: now,\n };\n await this.storage.addDocument(storedDoc);\n\n // Store vector\n await this.storage.addVector({\n id: doc.id,\n collectionId: this.collectionId,\n vector: doc.vector,\n });\n\n // Add to index\n this.index!.add(doc.id, doc.vector);\n\n // Save index periodically (could optimize with batching)\n await this.saveIndex();\n\n // Notify other tabs\n this.broadcaster?.notifyDocumentAdded(this.collectionId, doc.id);\n };\n\n // Use write lock if available\n if (this.lockManager) {\n await this.lockManager.withWriteLock(this.collectionId, operation);\n } else {\n await operation();\n }\n }\n\n async addMany(docs: Document[], options?: AddManyOptions): Promise<void> {\n this.ensureInitialized();\n\n const batchSize = options?.batchSize ?? 100;\n const total = docs.length;\n let completed = 0;\n\n for (let i = 0; i < docs.length; i += batchSize) {\n const batch = docs.slice(i, i + batchSize);\n\n for (const doc of batch) {\n if (!doc.id) {\n throw new Error('All documents must have an id');\n }\n\n if (!doc.vector || !(doc.vector instanceof Float32Array)) {\n throw new Error('All documents must have a Float32Array vector');\n }\n\n if (doc.vector.length !== this.dimensions) {\n throw new Error(\n `Vector dimension mismatch: expected ${this.dimensions}, got ${doc.vector.length}`\n );\n }\n\n const now = Date.now();\n\n // Store document metadata\n await this.storage.addDocument({\n id: doc.id,\n collectionId: this.collectionId,\n metadata: doc.metadata,\n createdAt: now,\n updatedAt: now,\n });\n\n // Store vector\n await this.storage.addVector({\n id: doc.id,\n collectionId: this.collectionId,\n vector: doc.vector,\n });\n\n // Add to index\n this.index!.add(doc.id, doc.vector);\n }\n\n completed += batch.length;\n options?.onProgress?.(completed, total);\n }\n\n // Save index after all additions\n await this.saveIndex();\n }\n\n async search(vector: Float32Array, options?: SearchOptions): Promise<SearchResult[]> {\n this.ensureInitialized();\n\n if (vector.length !== this.dimensions) {\n throw new Error(\n `Query vector dimension mismatch: expected ${this.dimensions}, got ${vector.length}`\n );\n }\n\n const k = options?.k ?? 10;\n const threshold = options?.threshold;\n const filter = options?.filter;\n const includeVectors = options?.includeVectors ?? false;\n\n // If we have a filter, we need to search more candidates and filter\n const searchK = filter ? k * 10 : k;\n const rawResults = this.index!.search(vector, searchK);\n\n const results: SearchResult[] = [];\n\n for (const result of rawResults) {\n // Apply threshold\n if (threshold !== undefined && result.score < threshold) {\n continue;\n }\n\n // Get document metadata\n const doc = await this.storage.getDocument(result.id);\n if (!doc) continue;\n\n // Apply filter\n if (filter && !matchesFilter(doc.metadata, filter)) {\n continue;\n }\n\n const searchResult: SearchResult = {\n id: result.id,\n score: result.score,\n metadata: doc.metadata,\n };\n\n if (includeVectors) {\n searchResult.vector = (await this.storage.getVector(result.id)) ?? undefined;\n }\n\n results.push(searchResult);\n\n // Stop if we have enough results\n if (results.length >= k) {\n break;\n }\n }\n\n return results;\n }\n\n async get(id: string): Promise<(Document & { metadata?: Record<string, unknown> }) | null> {\n this.ensureInitialized();\n\n const doc = await this.storage.getDocument(id);\n if (!doc || doc.collectionId !== this.collectionId) {\n return null;\n }\n\n const vector = await this.storage.getVector(id);\n if (!vector) {\n return null;\n }\n\n return {\n id: doc.id,\n vector,\n metadata: doc.metadata,\n };\n }\n\n async update(id: string, updates: Partial<Omit<Document, 'id'>>): Promise<void> {\n this.ensureInitialized();\n\n const operation = async (): Promise<void> => {\n const existingDoc = await this.storage.getDocument(id);\n if (!existingDoc || existingDoc.collectionId !== this.collectionId) {\n throw new Error(`Document not found: ${id}`);\n }\n\n const now = Date.now();\n\n // Update metadata\n if (updates.metadata !== undefined) {\n await this.storage.addDocument({\n ...existingDoc,\n metadata: updates.metadata,\n updatedAt: now,\n });\n }\n\n // Update vector\n if (updates.vector !== undefined) {\n if (updates.vector.length !== this.dimensions) {\n throw new Error(\n `Vector dimension mismatch: expected ${this.dimensions}, got ${updates.vector.length}`\n );\n }\n\n await this.storage.addVector({\n id,\n collectionId: this.collectionId,\n vector: updates.vector,\n });\n\n // Update index\n this.index!.add(id, updates.vector);\n await this.saveIndex();\n }\n\n // Notify other tabs\n this.broadcaster?.notifyDocumentUpdated(this.collectionId, id);\n };\n\n if (this.lockManager) {\n await this.lockManager.withWriteLock(this.collectionId, operation);\n } else {\n await operation();\n }\n }\n\n async delete(id: string): Promise<void> {\n this.ensureInitialized();\n\n const operation = async (): Promise<void> => {\n await this.storage.deleteDocument(id);\n await this.storage.deleteVector(id);\n this.index!.delete(id);\n await this.saveIndex();\n\n // Notify other tabs\n this.broadcaster?.notifyDocumentDeleted(this.collectionId, id);\n };\n\n if (this.lockManager) {\n await this.lockManager.withWriteLock(this.collectionId, operation);\n } else {\n await operation();\n }\n }\n\n async deleteMany(ids: string[]): Promise<void> {\n this.ensureInitialized();\n\n for (const id of ids) {\n await this.storage.deleteDocument(id);\n await this.storage.deleteVector(id);\n this.index!.delete(id);\n }\n\n await this.saveIndex();\n }\n\n async deleteWhere(filter: FilterQuery): Promise<number> {\n this.ensureInitialized();\n\n const docs = await this.storage.getAllDocuments(this.collectionId);\n let deleted = 0;\n\n for (const doc of docs) {\n if (matchesFilter(doc.metadata, filter)) {\n await this.storage.deleteDocument(doc.id);\n await this.storage.deleteVector(doc.id);\n this.index!.delete(doc.id);\n deleted++;\n }\n }\n\n if (deleted > 0) {\n await this.saveIndex();\n }\n\n return deleted;\n }\n\n collection(name: string): VectorDB {\n // Create a new VectorDB instance for the collection\n const collectionDb = new VectorDBImpl(this.config, name, this.storage);\n // Note: The collection needs to be initialized before use\n // This is a sync method, so we return an uninitialized instance\n // The user should await operations which will trigger initialization\n return new Proxy(collectionDb as VectorDB, {\n get: (target, prop: string | symbol) => {\n const targetAny = target as unknown as Record<string | symbol, unknown>;\n const value = targetAny[prop];\n if (typeof value === 'function' && prop !== 'collection') {\n return async (...args: unknown[]) => {\n await collectionDb.initialize();\n return (value as (...a: unknown[]) => unknown).apply(target, args);\n };\n }\n return value;\n },\n });\n }\n\n async stats(): Promise<DBStats> {\n this.ensureInitialized();\n\n const collections = await this.storage.getAllCollections();\n let totalCount = 0;\n\n for (const col of collections) {\n totalCount += await this.storage.countDocuments(col.id);\n }\n\n const sizeBytes = await this.storage.estimateSize();\n\n return {\n count: totalCount,\n collections: collections.map((c) => c.name),\n sizeBytes,\n version: 1,\n };\n }\n\n async clear(): Promise<void> {\n this.ensureInitialized();\n\n const operation = async (): Promise<void> => {\n await this.storage.clearCollection(this.collectionId);\n this.index = new HNSWIndex(this.dimensions, this.config.indexOptions);\n\n // Notify other tabs\n this.broadcaster?.notifyCollectionCleared(this.collectionId);\n };\n\n if (this.lockManager) {\n await this.lockManager.withWriteLock(this.collectionId, operation);\n } else {\n await operation();\n }\n }\n\n async close(): Promise<void> {\n if (this.index) {\n await this.saveIndex();\n }\n await this.storage.close();\n\n // Clean up sync resources\n this.broadcaster?.close();\n this.broadcaster = null;\n\n this.initialized = false;\n }\n\n /**\n * Get the lock manager (for advanced usage).\n */\n getLockManager(): LockManager | null {\n return this.lockManager;\n }\n\n /**\n * Get the broadcaster (for advanced usage).\n */\n getBroadcaster(): Broadcaster | null {\n return this.broadcaster;\n }\n\n async export(options?: ExportOptions): Promise<Blob> {\n this.ensureInitialized();\n\n const format = options?.format ?? 'json';\n const collections = options?.collections;\n const includeVectors = options?.includeVectors ?? true;\n\n const exportData: {\n version: number;\n collections: Array<{\n name: string;\n dimensions: number;\n documents: Array<{\n id: string;\n metadata?: Record<string, unknown>;\n vector?: number[];\n }>;\n }>;\n } = {\n version: 1,\n collections: [],\n };\n\n const allCollections = await this.storage.getAllCollections();\n const targetCollections = collections\n ? allCollections.filter((c) => collections.includes(c.name))\n : allCollections;\n\n for (const col of targetCollections) {\n const docs = await this.storage.getAllDocuments(col.id);\n const colData: (typeof exportData.collections)[0] = {\n name: col.name,\n dimensions: col.dimensions,\n documents: [],\n };\n\n for (const doc of docs) {\n const docData: (typeof colData.documents)[0] = {\n id: doc.id,\n metadata: doc.metadata,\n };\n\n if (includeVectors) {\n const vector = await this.storage.getVector(doc.id);\n if (vector) {\n docData.vector = Array.from(vector);\n }\n }\n\n colData.documents.push(docData);\n }\n\n exportData.collections.push(colData);\n }\n\n if (format === 'json') {\n return new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });\n } else {\n // Binary format (MessagePack or similar could be used here)\n // For now, just use JSON\n return new Blob([JSON.stringify(exportData)], { type: 'application/octet-stream' });\n }\n }\n\n async import(data: Blob, options?: ImportOptions): Promise<void> {\n this.ensureInitialized();\n\n const mode = options?.mode ?? 'merge';\n const text = await data.text();\n const importData = JSON.parse(text) as {\n version: number;\n collections: Array<{\n name: string;\n dimensions: number;\n documents: Array<{\n id: string;\n metadata?: Record<string, unknown>;\n vector?: number[];\n }>;\n }>;\n };\n\n if (mode === 'replace') {\n await this.storage.clear();\n this.index = new HNSWIndex(this.dimensions, this.config.indexOptions);\n }\n\n let completed = 0;\n let total = 0;\n for (const col of importData.collections) {\n total += col.documents.length;\n }\n\n for (const colData of importData.collections) {\n // Create collection if it doesn't exist\n let collection = await this.storage.getCollectionByName(colData.name);\n if (!collection) {\n collection = {\n id: colData.name,\n name: colData.name,\n dimensions: colData.dimensions,\n createdAt: Date.now(),\n };\n await this.storage.createCollection(collection);\n }\n\n // Import documents\n for (const docData of colData.documents) {\n if (docData.vector) {\n const vector = new Float32Array(docData.vector);\n const now = Date.now();\n\n await this.storage.addDocument({\n id: docData.id,\n collectionId: collection.id,\n metadata: docData.metadata,\n createdAt: now,\n updatedAt: now,\n });\n\n await this.storage.addVector({\n id: docData.id,\n collectionId: collection.id,\n vector,\n });\n\n // Add to index if this is the current collection\n if (collection.id === this.collectionId) {\n this.index!.add(docData.id, vector);\n }\n }\n\n completed++;\n options?.onProgress?.(completed, total);\n }\n }\n\n await this.saveIndex();\n }\n}\n\n/**\n * Create a new VectorDB instance.\n */\nexport async function createVectorDB(config: VectorDBConfig): Promise<VectorDB> {\n const db = new VectorDBImpl({\n ...config,\n storage: config.storage ?? DEFAULT_CONFIG.storage,\n indexOptions: {\n ...DEFAULT_CONFIG.indexOptions,\n ...config.indexOptions,\n },\n });\n\n await db.initialize();\n return db;\n}\n","/**\n * Main thread proxy for the VectorDB worker.\n * Provides an async API that communicates with the worker.\n */\n\nimport type {\n VectorDB,\n VectorDBConfig,\n Document,\n SearchOptions,\n SearchResult,\n AddManyOptions,\n ExportOptions,\n ImportOptions,\n DBStats,\n FilterQuery,\n WorkerRequest,\n WorkerResponse,\n WorkerMessageType,\n} from '../types.js';\n\n/**\n * Proxy class that communicates with the VectorDB worker.\n */\nexport class VectorDBWorkerProxy implements VectorDB {\n private worker: Worker;\n private messageId = 0;\n private pendingRequests = new Map<\n number,\n {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n onProgress?: (completed: number, total: number) => void;\n }\n >();\n private collectionId?: string;\n\n constructor(worker: Worker, collectionId?: string) {\n this.worker = worker;\n this.collectionId = collectionId;\n\n this.worker.onmessage = (\n event: MessageEvent<\n | WorkerResponse\n | { id: number; type: 'progress'; payload: { completed: number; total: number } }\n >\n ) => {\n const message = event.data;\n\n // Handle progress updates\n if ('type' in message && message.type === 'progress') {\n const pending = this.pendingRequests.get(message.id);\n if (pending?.onProgress) {\n pending.onProgress(message.payload.completed, message.payload.total);\n }\n return;\n }\n\n const response = message as WorkerResponse;\n const pending = this.pendingRequests.get(response.id);\n\n if (pending) {\n this.pendingRequests.delete(response.id);\n\n if (response.success) {\n pending.resolve(response.result);\n } else {\n pending.reject(new Error(response.error ?? 'Unknown error'));\n }\n }\n };\n\n this.worker.onerror = (event) => {\n console.error('Worker error:', event);\n };\n }\n\n /**\n * Send a message to the worker and wait for a response.\n */\n private async send<T>(\n type: WorkerMessageType,\n payload: unknown,\n onProgress?: (completed: number, total: number) => void\n ): Promise<T> {\n const id = ++this.messageId;\n\n return new Promise((resolve, reject) => {\n this.pendingRequests.set(id, {\n resolve: resolve as (v: unknown) => void,\n reject,\n onProgress,\n });\n\n const request: WorkerRequest = {\n id,\n type,\n payload,\n collectionId: this.collectionId,\n };\n\n this.worker.postMessage(request);\n });\n }\n\n /**\n * Initialize the database in the worker.\n */\n async initialize(config: VectorDBConfig): Promise<void> {\n await this.send('init', config);\n }\n\n async add(doc: Document): Promise<void> {\n await this.send('add', {\n id: doc.id,\n vector: Array.from(doc.vector),\n metadata: doc.metadata,\n });\n }\n\n async addMany(docs: Document[], options?: AddManyOptions): Promise<void> {\n await this.send(\n 'addMany',\n {\n documents: docs.map((doc) => ({\n id: doc.id,\n vector: Array.from(doc.vector),\n metadata: doc.metadata,\n })),\n options: options ? { batchSize: options.batchSize } : undefined,\n },\n options?.onProgress\n );\n }\n\n async search(vector: Float32Array, options?: SearchOptions): Promise<SearchResult[]> {\n return this.send('search', {\n vector: Array.from(vector),\n options,\n });\n }\n\n async get(id: string): Promise<(Document & { metadata?: Record<string, unknown> }) | null> {\n const result = await this.send<{\n id: string;\n vector: number[];\n metadata?: Record<string, unknown>;\n } | null>('get', id);\n\n if (!result) return null;\n\n return {\n id: result.id,\n vector: new Float32Array(result.vector),\n metadata: result.metadata,\n };\n }\n\n async update(id: string, updates: Partial<Omit<Document, 'id'>>): Promise<void> {\n await this.send('update', {\n docId: id,\n updates: {\n vector: updates.vector ? Array.from(updates.vector) : undefined,\n metadata: updates.metadata,\n },\n });\n }\n\n async delete(id: string): Promise<void> {\n await this.send('delete', id);\n }\n\n async deleteMany(ids: string[]): Promise<void> {\n await this.send('deleteMany', ids);\n }\n\n async deleteWhere(filter: FilterQuery): Promise<number> {\n return this.send('deleteWhere', filter);\n }\n\n collection(name: string): VectorDB {\n // Return a new proxy for the collection\n return new VectorDBWorkerProxy(this.worker, name);\n }\n\n async stats(): Promise<DBStats> {\n return this.send('stats', null);\n }\n\n async clear(): Promise<void> {\n await this.send('clear', null);\n }\n\n async close(): Promise<void> {\n await this.send('close', null);\n this.worker.terminate();\n }\n\n async export(options?: ExportOptions): Promise<Blob> {\n const result = await this.send<{ buffer: ArrayBuffer; type: string }>('export', options);\n return new Blob([result.buffer], { type: result.type });\n }\n\n async import(data: Blob, options?: ImportOptions): Promise<void> {\n const buffer = await data.arrayBuffer();\n await this.send('import', {\n buffer,\n type: data.type,\n options,\n });\n }\n\n /**\n * Get the lock manager.\n * Note: Locking is not available in worker mode.\n */\n getLockManager(): null {\n return null;\n }\n\n /**\n * Get the broadcaster.\n * Note: Broadcasting is not available in worker mode.\n */\n getBroadcaster(): null {\n return null;\n }\n}\n\n/**\n * Create a VectorDB instance that runs in a Web Worker.\n */\nexport async function createVectorDBWithWorker(\n config: VectorDBConfig,\n workerUrl: string | URL\n): Promise<VectorDB> {\n const worker = new Worker(workerUrl, { type: 'module' });\n const proxy = new VectorDBWorkerProxy(worker);\n await proxy.initialize(config);\n return proxy;\n}\n","/**\n * Embedding Functions\n *\n * Core embed(), embedMany(), and streamEmbedMany() functions.\n * These functions accept EmbeddingModel interface - implementations come from provider packages.\n *\n * @packageDocumentation\n */\n\nimport type {\n EmbeddingModel,\n EmbedOptions,\n EmbedResult,\n EmbedManyOptions,\n EmbedManyResult,\n StreamEmbedManyOptions,\n StreamEmbedResult,\n} from './types.js';\n\n// Re-export for completeness (EmbedProgress is used in StreamEmbedManyOptions.onBatch)\nexport type { EmbedProgress } from './types.js';\n\n// Global provider registry for string model ID resolution\nlet globalProviderRegistry: GlobalProviderRegistry | null = null;\n\ninterface GlobalProviderRegistry {\n resolve(id: string): EmbeddingModel;\n}\n\n/**\n * Set the global provider registry for string model ID resolution.\n * Call this once at app initialization.\n *\n * @example\n * ```ts\n * import { setGlobalEmbeddingProvider } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * setGlobalEmbeddingProvider({\n * transformers,\n * });\n *\n * // Now string model IDs work\n * const { embedding } = await embed({\n * model: 'transformers:Xenova/all-MiniLM-L6-v2',\n * value: 'Hello',\n * });\n * ```\n */\nexport function setGlobalEmbeddingProvider(\n providers: Record<string, { embedding: (modelId: string) => EmbeddingModel }>,\n options?: { separator?: string }\n): void {\n const separator = options?.separator ?? ':';\n\n globalProviderRegistry = {\n resolve(id: string): EmbeddingModel {\n const sepIndex = id.indexOf(separator);\n if (sepIndex === -1) {\n throw new Error(\n `Invalid model ID format: \"${id}\". Expected \"provider${separator}modelId\" format.`\n );\n }\n\n const providerName = id.slice(0, sepIndex);\n const modelId = id.slice(sepIndex + 1);\n\n const provider = providers[providerName];\n if (!provider) {\n throw new Error(\n `Unknown provider: \"${providerName}\". Available providers: ${Object.keys(providers).join(', ')}`\n );\n }\n\n return provider.embedding(modelId);\n },\n };\n}\n\n/**\n * Resolve a model from string ID or return the model object as-is.\n */\nfunction resolveModel(modelOrId: EmbeddingModel | string): EmbeddingModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalProviderRegistry) {\n throw new Error(\n 'No global provider configured. Call setGlobalEmbeddingProvider() first, or pass a model object instead of a string.'\n );\n }\n\n return globalProviderRegistry.resolve(modelOrId);\n}\n\n/**\n * Embed a single value using the specified model.\n *\n * This function is in @localmode/core - model implementations are in provider packages.\n *\n * @param options - Embedding options\n * @returns Promise with embedding, usage, and response information\n *\n * @example Basic usage\n * ```ts\n * import { embed } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { embedding, usage, response } = await embed({\n * model: transformers.embedding('Xenova/all-MiniLM-L6-v2'),\n * value: 'Hello world',\n * });\n *\n * console.log(embedding.length); // 384\n * console.log(usage.tokens); // 3\n * ```\n *\n * @example With string model ID (requires global provider setup)\n * ```ts\n * const { embedding } = await embed({\n * model: 'transformers:Xenova/all-MiniLM-L6-v2',\n * value: 'Hello world',\n * });\n * ```\n *\n * @example With AbortSignal\n * ```ts\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 5000);\n *\n * const { embedding } = await embed({\n * model: transformers.embedding('Xenova/all-MiniLM-L6-v2'),\n * value: 'Hello world',\n * abortSignal: controller.signal,\n * });\n * ```\n *\n * @throws {Error} If embedding fails after all retries\n * @throws {Error} If aborted via AbortSignal\n *\n * @see {@link embedMany} for batch embedding\n * @see {@link semanticSearch} for embedding + search\n */\nexport async function embed(options: EmbedOptions): Promise<EmbedResult> {\n const {\n model: modelOrId,\n value,\n abortSignal,\n maxRetries = 2,\n headers,\n providerOptions,\n } = options;\n\n // Resolve string model ID to model object\n const model = resolveModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Check before each retry\n abortSignal?.throwIfAborted();\n\n try {\n const result = await model.doEmbed({\n values: [value],\n abortSignal,\n headers,\n providerOptions,\n });\n\n return {\n embedding: result.embeddings[0],\n usage: result.usage,\n response: result.response,\n };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry if aborted\n if (abortSignal?.aborted) {\n throw new Error('Embedding was cancelled', { cause: lastError });\n }\n\n // Don't retry on the last attempt\n if (attempt === maxRetries) {\n break;\n }\n\n // TODO: Add exponential backoff delay here if needed\n }\n }\n\n throw new Error(`Embedding failed after ${maxRetries + 1} attempts`, {\n cause: lastError,\n });\n}\n\n/**\n * Embed multiple values using the specified model.\n *\n * Batches requests if the model has maxEmbeddingsPerCall limit.\n *\n * @param options - Embedding options\n * @returns Promise with embeddings array, usage, and response information\n *\n * @example\n * ```ts\n * import { embedMany } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { embeddings, usage } = await embedMany({\n * model: transformers.embedding('Xenova/all-MiniLM-L6-v2'),\n * values: ['Hello', 'World', 'Test'],\n * });\n *\n * console.log(embeddings.length); // 3\n * console.log(embeddings[0].length); // 384\n * ```\n *\n * @see {@link embed} for single value embedding\n * @see {@link streamEmbedMany} for streaming with progress\n */\nexport async function embedMany(options: EmbedManyOptions): Promise<EmbedManyResult> {\n const {\n model: modelOrId,\n values,\n abortSignal,\n maxRetries = 2,\n headers,\n providerOptions,\n } = options;\n\n // Resolve string model ID to model object\n const model = resolveModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n // If no max limit or all values fit in one call\n if (!model.maxEmbeddingsPerCall || values.length <= model.maxEmbeddingsPerCall) {\n const result = await embedWithRetry(model, values, {\n abortSignal,\n maxRetries,\n headers,\n providerOptions,\n });\n\n return {\n embeddings: result.embeddings,\n usage: result.usage,\n response: result.response,\n };\n }\n\n // Batch processing for large value arrays\n const allEmbeddings: Float32Array[] = [];\n let totalTokens = 0;\n let lastResponse = { modelId: model.modelId, timestamp: new Date() };\n\n const batchSize = model.maxEmbeddingsPerCall;\n\n for (let i = 0; i < values.length; i += batchSize) {\n // Check for cancellation before each batch\n abortSignal?.throwIfAborted();\n\n const batch = values.slice(i, i + batchSize);\n const result = await embedWithRetry(model, batch, {\n abortSignal,\n maxRetries,\n headers,\n providerOptions,\n });\n\n allEmbeddings.push(...result.embeddings);\n totalTokens += result.usage.tokens;\n lastResponse = result.response;\n }\n\n return {\n embeddings: allEmbeddings,\n usage: { tokens: totalTokens },\n response: lastResponse,\n };\n}\n\n/**\n * Stream embeddings for large value arrays with progress tracking.\n *\n * Yields embeddings one at a time as they're generated, allowing\n * for progress tracking and early processing.\n *\n * @param options - Streaming embed options\n * @yields StreamEmbedResult with embedding and index\n *\n * @example\n * ```ts\n * import { streamEmbedMany } from '@localmode/core';\n *\n * for await (const { embedding, index } of streamEmbedMany({\n * model: transformers.embedding('Xenova/all-MiniLM-L6-v2'),\n * values: largeTextArray,\n * batchSize: 32,\n * onBatch: ({ index, count, total }) => {\n * console.log(`Progress: ${index + count}/${total}`);\n * },\n * })) {\n * await db.add({ id: `doc-${index}`, vector: embedding });\n * }\n * ```\n *\n * @see {@link embedMany} for non-streaming batch embedding\n */\nexport async function* streamEmbedMany(\n options: StreamEmbedManyOptions\n): AsyncGenerator<StreamEmbedResult> {\n const {\n model: modelOrId,\n values,\n batchSize = 32,\n abortSignal,\n maxRetries = 2,\n headers,\n providerOptions,\n onBatch,\n } = options;\n\n // Resolve string model ID to model object\n const model = resolveModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n const total = values.length;\n\n for (let i = 0; i < values.length; i += batchSize) {\n // Check for cancellation before each batch\n abortSignal?.throwIfAborted();\n\n const batch = values.slice(i, i + batchSize);\n const result = await embedWithRetry(model, batch, {\n abortSignal,\n maxRetries,\n headers,\n providerOptions,\n });\n\n // Yield each embedding individually\n for (let j = 0; j < result.embeddings.length; j++) {\n yield {\n embedding: result.embeddings[j],\n index: i + j,\n };\n }\n\n // Call progress callback\n onBatch?.({\n index: i,\n count: result.embeddings.length,\n total,\n usage: result.usage,\n });\n }\n}\n\n/**\n * Helper function to embed with retry logic.\n */\nasync function embedWithRetry(\n model: EmbeddingModel,\n values: string[],\n options: {\n abortSignal?: AbortSignal;\n maxRetries: number;\n headers?: Record<string, string>;\n providerOptions?: Record<string, Record<string, unknown>>;\n }\n): Promise<{\n embeddings: Float32Array[];\n usage: { tokens: number };\n response: { id?: string; modelId: string; timestamp: Date };\n}> {\n const { abortSignal, maxRetries, headers, providerOptions } = options;\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n return await model.doEmbed({\n values,\n abortSignal,\n headers,\n providerOptions,\n });\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw new Error('Embedding was cancelled', { cause: lastError });\n }\n\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n throw new Error(`Embedding failed after ${maxRetries + 1} attempts`, {\n cause: lastError,\n });\n}\n","/**\n * Semantic Search Function\n *\n * Combines embedding generation with vector database search.\n *\n * @packageDocumentation\n */\n\nimport { embed } from './embed.js';\nimport type {\n SemanticSearchOptions,\n SemanticSearchResult,\n SemanticSearchResultItem,\n} from './types.js';\n\n/**\n * Perform semantic search by embedding the query and searching the vector database.\n *\n * This is a convenience function that combines embed() and db.search().\n *\n * @param options - Semantic search options\n * @returns Promise with search results and usage information\n *\n * @example\n * ```ts\n * import { semanticSearch, createVectorDB } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const db = await createVectorDB({ name: 'docs', dimensions: 384 });\n * const model = transformers.embedding('Xenova/all-MiniLM-L6-v2');\n *\n * const { results, usage } = await semanticSearch({\n * db,\n * model,\n * query: 'How to configure authentication?',\n * k: 5,\n * });\n *\n * for (const result of results) {\n * console.log(`${result.id}: ${result.score.toFixed(3)} - ${result.text}`);\n * }\n * ```\n *\n * @example With filter\n * ```ts\n * const { results } = await semanticSearch({\n * db,\n * model,\n * query: 'authentication',\n * k: 10,\n * filter: { category: 'security' },\n * });\n * ```\n *\n * @see {@link embed} for embedding only\n */\nexport async function semanticSearch(\n options: SemanticSearchOptions\n): Promise<SemanticSearchResult> {\n const {\n db,\n model,\n query,\n k = 10,\n filter,\n threshold,\n abortSignal,\n headers,\n providerOptions,\n } = options;\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n // Embed the query\n const embedStartTime = performance.now();\n const { embedding, usage: embedUsage } = await embed({\n model,\n value: query,\n abortSignal,\n headers,\n providerOptions,\n });\n const embedDurationMs = performance.now() - embedStartTime;\n\n // Search the database\n const searchStartTime = performance.now();\n const dbResults = await db.search(embedding, {\n k,\n filter,\n threshold,\n });\n const searchDurationMs = performance.now() - searchStartTime;\n\n // Transform results\n const results: SemanticSearchResultItem[] = dbResults.map((r) => ({\n id: r.id,\n score: r.score,\n text: extractText(r.metadata),\n metadata: r.metadata,\n }));\n\n return {\n results,\n usage: {\n embeddingTokens: embedUsage.tokens,\n embedDurationMs,\n searchDurationMs,\n },\n };\n}\n\n/**\n * Extract text from metadata if available.\n * Looks for common text field names.\n */\nfunction extractText(metadata?: Record<string, unknown>): string | undefined {\n if (!metadata) return undefined;\n\n // Common text field names\n const textFields = ['text', 'content', 'body', '__text', 'pageContent'];\n\n for (const field of textFields) {\n const value = metadata[field];\n if (typeof value === 'string') {\n return value;\n }\n }\n\n return undefined;\n}\n\n/**\n * Stream semantic search results for large queries or real-time updates.\n *\n * @param options - Semantic search options\n * @yields Search results as they become available\n *\n * @example\n * ```ts\n * for await (const result of streamSemanticSearch({\n * db,\n * model,\n * query: 'authentication',\n * k: 100,\n * })) {\n * console.log(result.id, result.score);\n * }\n * ```\n */\nexport async function* streamSemanticSearch(\n options: SemanticSearchOptions\n): AsyncGenerator<SemanticSearchResultItem> {\n // For now, this is a simple implementation that yields all results\n // In the future, this could be enhanced to stream from the database\n const { results } = await semanticSearch(options);\n\n for (const result of results) {\n yield result;\n }\n}\n","/**\n * Embedding Model Middleware\n *\n * Wrap embedding models with middleware for caching, logging, retry, etc.\n *\n * @packageDocumentation\n */\n\nimport type {\n EmbeddingModel,\n EmbeddingModelMiddleware,\n DoEmbedOptions,\n DoEmbedResult,\n} from './types.js';\n\n/**\n * Wrap an embedding model with middleware.\n *\n * Middleware can transform parameters before embedding and wrap the\n * embed call for caching, logging, retry, rate limiting, etc.\n *\n * @param options - The model and middleware to apply\n * @returns A wrapped embedding model\n *\n * @example Caching middleware\n * ```ts\n * const cache = new Map<string, Float32Array>();\n *\n * const cachingMiddleware: EmbeddingModelMiddleware = {\n * wrapEmbed: async ({ doEmbed, values }) => {\n * const key = values.join('|||');\n * const cached = cache.get(key);\n * if (cached) {\n * return { embeddings: [cached], usage: { tokens: 0 }, response: { modelId: 'cached', timestamp: new Date() } };\n * }\n * const result = await doEmbed();\n * cache.set(key, result.embeddings[0]);\n * return result;\n * },\n * };\n *\n * const cachedModel = wrapEmbeddingModel({\n * model: transformers.embedding('Xenova/all-MiniLM-L6-v2'),\n * middleware: cachingMiddleware,\n * });\n * ```\n *\n * @example Logging middleware\n * ```ts\n * const loggingMiddleware: EmbeddingModelMiddleware = {\n * wrapEmbed: async ({ doEmbed, values, model }) => {\n * console.log(`Embedding ${values.length} values with ${model.modelId}`);\n * const start = Date.now();\n * const result = await doEmbed();\n * console.log(`Completed in ${Date.now() - start}ms`);\n * return result;\n * },\n * };\n * ```\n *\n * @example PII redaction middleware\n * ```ts\n * const piiMiddleware: EmbeddingModelMiddleware = {\n * transformParams: ({ values }) => ({\n * values: values.map(v => redactPII(v)),\n * }),\n * };\n * ```\n *\n * @see {@link EmbeddingModelMiddleware} for middleware interface\n */\nexport function wrapEmbeddingModel(options: {\n model: EmbeddingModel;\n middleware: EmbeddingModelMiddleware;\n}): EmbeddingModel {\n const { model, middleware } = options;\n\n return {\n // Forward all readonly properties\n modelId: model.modelId,\n provider: model.provider,\n dimensions: model.dimensions,\n maxEmbeddingsPerCall: model.maxEmbeddingsPerCall,\n supportsParallelCalls: model.supportsParallelCalls,\n\n // Wrap doEmbed with middleware\n async doEmbed(embedOptions: DoEmbedOptions): Promise<DoEmbedResult> {\n let { values } = embedOptions;\n const { abortSignal, headers, providerOptions } = embedOptions;\n\n // Apply parameter transformation if provided\n if (middleware.transformParams) {\n const transformed = await middleware.transformParams({ values });\n values = transformed.values;\n }\n\n // Define the actual embed function\n const doEmbed = () =>\n model.doEmbed({\n values,\n abortSignal,\n headers,\n providerOptions,\n });\n\n // Apply wrap if provided, otherwise just call doEmbed\n if (middleware.wrapEmbed) {\n return middleware.wrapEmbed({\n doEmbed,\n values,\n model,\n });\n }\n\n return doEmbed();\n },\n };\n}\n\n/**\n * Compose multiple middleware into a single middleware.\n *\n * Middleware are applied in order: first middleware's transformParams runs first,\n * but first middleware's wrapEmbed wraps the outermost layer.\n *\n * @param middlewares - Array of middleware to compose\n * @returns A single composed middleware\n *\n * @example\n * ```ts\n * const composed = composeEmbeddingMiddleware([\n * piiRedactionMiddleware,\n * cachingMiddleware,\n * loggingMiddleware,\n * ]);\n *\n * const model = wrapEmbeddingModel({\n * model: baseModel,\n * middleware: composed,\n * });\n * ```\n */\nexport function composeEmbeddingMiddleware(\n middlewares: EmbeddingModelMiddleware[]\n): EmbeddingModelMiddleware {\n if (middlewares.length === 0) {\n return {};\n }\n\n if (middlewares.length === 1) {\n return middlewares[0];\n }\n\n return {\n // Chain transformParams: each middleware transforms in order\n transformParams: async (params) => {\n let current = params;\n for (const mw of middlewares) {\n if (mw.transformParams) {\n current = await mw.transformParams(current);\n }\n }\n return current;\n },\n\n // Chain wrapEmbed: first middleware wraps outermost\n wrapEmbed: async ({ doEmbed, values, model }) => {\n // Build the chain from inside out\n let currentDoEmbed = doEmbed;\n\n // Reverse so first middleware wraps outermost\n const reversed = [...middlewares].reverse();\n\n for (const mw of reversed) {\n if (mw.wrapEmbed) {\n const prevDoEmbed = currentDoEmbed;\n currentDoEmbed = () =>\n mw.wrapEmbed!({\n doEmbed: prevDoEmbed,\n values,\n model,\n });\n }\n }\n\n return currentDoEmbed();\n },\n };\n}\n\n","/**\n * Classification Functions\n *\n * Core classify(), classifyMany(), and classifyZeroShot() functions.\n * These functions accept ClassificationModel interface - implementations come from provider packages.\n *\n * @packageDocumentation\n */\n\nimport type {\n ClassificationModel,\n ZeroShotClassificationModel,\n ClassifyOptions,\n ClassifyResult,\n ClassifyManyOptions,\n ClassifyManyResult,\n ClassifyZeroShotOptions,\n ClassifyZeroShotResult,\n ClassificationResultItem,\n ClassificationUsage,\n} from './types.js';\n\n// Global provider registry for string model ID resolution\nlet globalClassificationRegistry: GlobalClassificationRegistry | null = null;\n\ninterface GlobalClassificationRegistry {\n resolveClassifier(id: string): ClassificationModel;\n resolveZeroShot(id: string): ZeroShotClassificationModel;\n}\n\n/**\n * Set the global classification provider registry for string model ID resolution.\n * Call this once at app initialization.\n *\n * @example\n * ```ts\n * import { setGlobalClassificationProvider } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * setGlobalClassificationProvider({\n * transformers,\n * });\n *\n * // Now string model IDs work\n * const { label } = await classify({\n * model: 'transformers:Xenova/distilbert-sst-2',\n * text: 'I love this!',\n * });\n * ```\n */\nexport function setGlobalClassificationProvider(\n providers: Record<\n string,\n {\n classifier: (modelId: string) => ClassificationModel;\n zeroShot: (modelId: string) => ZeroShotClassificationModel;\n }\n >,\n options?: { separator?: string }\n): void {\n const separator = options?.separator ?? ':';\n\n globalClassificationRegistry = {\n resolveClassifier(id: string): ClassificationModel {\n const sepIndex = id.indexOf(separator);\n if (sepIndex === -1) {\n throw new Error(\n `Invalid model ID format: \"${id}\". Expected \"provider${separator}modelId\" format.`\n );\n }\n\n const providerName = id.slice(0, sepIndex);\n const modelId = id.slice(sepIndex + 1);\n\n const provider = providers[providerName];\n if (!provider) {\n throw new Error(\n `Unknown provider: \"${providerName}\". Available providers: ${Object.keys(providers).join(', ')}`\n );\n }\n\n return provider.classifier(modelId);\n },\n\n resolveZeroShot(id: string): ZeroShotClassificationModel {\n const sepIndex = id.indexOf(separator);\n if (sepIndex === -1) {\n throw new Error(\n `Invalid model ID format: \"${id}\". Expected \"provider${separator}modelId\" format.`\n );\n }\n\n const providerName = id.slice(0, sepIndex);\n const modelId = id.slice(sepIndex + 1);\n\n const provider = providers[providerName];\n if (!provider) {\n throw new Error(\n `Unknown provider: \"${providerName}\". Available providers: ${Object.keys(providers).join(', ')}`\n );\n }\n\n return provider.zeroShot(modelId);\n },\n };\n}\n\n/**\n * Resolve a classification model from string ID or return the model object as-is.\n */\nfunction resolveClassificationModel(modelOrId: ClassificationModel | string): ClassificationModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalClassificationRegistry) {\n throw new Error(\n 'No global provider configured. Call setGlobalClassificationProvider() first, or pass a model object instead of a string.'\n );\n }\n\n return globalClassificationRegistry.resolveClassifier(modelOrId);\n}\n\n/**\n * Resolve a zero-shot model from string ID or return the model object as-is.\n */\nfunction resolveZeroShotModel(\n modelOrId: ZeroShotClassificationModel | string\n): ZeroShotClassificationModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalClassificationRegistry) {\n throw new Error(\n 'No global provider configured. Call setGlobalClassificationProvider() first, or pass a model object instead of a string.'\n );\n }\n\n return globalClassificationRegistry.resolveZeroShot(modelOrId);\n}\n\n/**\n * Classify a single text using the specified model.\n *\n * This function is in @localmode/core - model implementations are in provider packages.\n *\n * @param options - Classification options\n * @returns Promise with label, score, usage, and response information\n *\n * @example Basic usage\n * ```ts\n * import { classify } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { label, score, usage } = await classify({\n * model: transformers.classifier('Xenova/distilbert-base-uncased-finetuned-sst-2-english'),\n * text: 'I love this product!',\n * });\n *\n * console.log(label); // 'POSITIVE'\n * console.log(score); // 0.9998\n * ```\n *\n * @example With string model ID (requires global provider setup)\n * ```ts\n * const { label } = await classify({\n * model: 'transformers:Xenova/distilbert-sst-2',\n * text: 'This is terrible!',\n * });\n * ```\n *\n * @example With AbortSignal\n * ```ts\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 5000);\n *\n * const { label } = await classify({\n * model: transformers.classifier('Xenova/distilbert-sst-2'),\n * text: 'Hello world',\n * abortSignal: controller.signal,\n * });\n * ```\n *\n * @throws {Error} If classification fails after all retries\n * @throws {Error} If aborted via AbortSignal\n *\n * @see {@link classifyMany} for batch classification\n * @see {@link classifyZeroShot} for zero-shot classification\n */\nexport async function classify(options: ClassifyOptions): Promise<ClassifyResult> {\n const { model: modelOrId, text, abortSignal, maxRetries = 2, headers, providerOptions } = options;\n\n // Resolve string model ID to model object\n const model = resolveClassificationModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Check before each retry\n abortSignal?.throwIfAborted();\n\n try {\n const result = await model.doClassify({\n texts: [text],\n abortSignal,\n headers,\n providerOptions,\n });\n\n const item = result.results[0];\n\n return {\n label: item.label,\n score: item.score,\n allScores: item.allScores,\n usage: result.usage,\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry if aborted\n if (abortSignal?.aborted) {\n throw new Error('Classification was cancelled', { cause: lastError });\n }\n\n // Don't retry on the last attempt\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n throw new Error(`Classification failed after ${maxRetries + 1} attempts`, {\n cause: lastError,\n });\n}\n\n/**\n * Classify multiple texts using the specified model.\n *\n * @param options - Classification options\n * @returns Promise with results array, usage, and response information\n *\n * @example\n * ```ts\n * import { classifyMany } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { results, usage } = await classifyMany({\n * model: transformers.classifier('Xenova/distilbert-sst-2'),\n * texts: ['I love this!', 'This is terrible!', 'It is okay.'],\n * });\n *\n * results.forEach((r, i) => {\n * console.log(`Text ${i}: ${r.label} (${r.score.toFixed(2)})`);\n * });\n * ```\n *\n * @see {@link classify} for single text classification\n */\nexport async function classifyMany(options: ClassifyManyOptions): Promise<ClassifyManyResult> {\n const {\n model: modelOrId,\n texts,\n abortSignal,\n maxRetries = 2,\n headers,\n providerOptions,\n } = options;\n\n // Resolve string model ID to model object\n const model = resolveClassificationModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n const result = await classifyWithRetry(model, texts, {\n abortSignal,\n maxRetries,\n headers,\n providerOptions,\n });\n\n return {\n results: result.results,\n usage: result.usage,\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n}\n\n/**\n * Classify text into arbitrary labels using zero-shot classification.\n *\n * Zero-shot classification allows you to classify text into labels that\n * the model wasn't explicitly trained on.\n *\n * @param options - Zero-shot classification options\n * @returns Promise with labels, scores, usage, and response information\n *\n * @example\n * ```ts\n * import { classifyZeroShot } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { labels, scores } = await classifyZeroShot({\n * model: transformers.zeroShot('Xenova/bart-large-mnli'),\n * text: 'I just bought a new Tesla Model 3',\n * candidateLabels: ['automotive', 'technology', 'finance', 'sports'],\n * });\n *\n * console.log(labels[0]); // 'automotive'\n * console.log(scores[0]); // 0.87\n * ```\n *\n * @example With multi-label classification\n * ```ts\n * const { labels, scores } = await classifyZeroShot({\n * model: transformers.zeroShot('Xenova/bart-large-mnli'),\n * text: 'The new iPhone uses advanced AI for photography',\n * candidateLabels: ['technology', 'photography', 'smartphones'],\n * multiLabel: true,\n * });\n * // Multiple labels can have high scores\n * ```\n *\n * @see {@link classify} for standard classification with fixed labels\n */\nexport async function classifyZeroShot(\n options: ClassifyZeroShotOptions\n): Promise<ClassifyZeroShotResult> {\n const {\n model: modelOrId,\n text,\n candidateLabels,\n multiLabel,\n abortSignal,\n maxRetries = 2,\n headers,\n providerOptions,\n } = options;\n\n // Resolve string model ID to model object\n const model = resolveZeroShotModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Check before each retry\n abortSignal?.throwIfAborted();\n\n try {\n const result = await model.doClassifyZeroShot({\n texts: [text],\n candidateLabels,\n multiLabel,\n abortSignal,\n headers,\n providerOptions,\n });\n\n const item = result.results[0];\n\n return {\n labels: item.labels,\n scores: item.scores,\n usage: result.usage,\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry if aborted\n if (abortSignal?.aborted) {\n throw new Error('Zero-shot classification was cancelled', { cause: lastError });\n }\n\n // Don't retry on the last attempt\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n throw new Error(`Zero-shot classification failed after ${maxRetries + 1} attempts`, {\n cause: lastError,\n });\n}\n\n/**\n * Helper function to classify with retry logic.\n */\nasync function classifyWithRetry(\n model: ClassificationModel,\n texts: string[],\n options: {\n abortSignal?: AbortSignal;\n maxRetries: number;\n headers?: Record<string, string>;\n providerOptions?: Record<string, Record<string, unknown>>;\n }\n): Promise<{\n results: ClassificationResultItem[];\n usage: ClassificationUsage;\n}> {\n const { abortSignal, maxRetries, headers, providerOptions } = options;\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n return await model.doClassify({\n texts,\n abortSignal,\n headers,\n providerOptions,\n });\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw new Error('Classification was cancelled', { cause: lastError });\n }\n\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n throw new Error(`Classification failed after ${maxRetries + 1} attempts`, {\n cause: lastError,\n });\n}\n","/**\n * Named Entity Recognition (NER) Functions\n *\n * Core extractEntities() and extractEntitiesMany() functions.\n * These functions accept NERModel interface - implementations come from provider packages.\n *\n * @packageDocumentation\n */\n\nimport type {\n NERModel,\n ExtractEntitiesOptions,\n ExtractEntitiesResult,\n ExtractEntitiesManyOptions,\n ExtractEntitiesManyResult,\n NERResultItem,\n NERUsage,\n} from './types.js';\n\n// Global provider registry for string model ID resolution\nlet globalNERRegistry: GlobalNERRegistry | null = null;\n\ninterface GlobalNERRegistry {\n resolve(id: string): NERModel;\n}\n\n/**\n * Set the global NER provider registry for string model ID resolution.\n * Call this once at app initialization.\n *\n * @example\n * ```ts\n * import { setGlobalNERProvider } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * setGlobalNERProvider({\n * transformers,\n * });\n *\n * // Now string model IDs work\n * const { entities } = await extractEntities({\n * model: 'transformers:Xenova/bert-base-NER',\n * text: 'John works at Microsoft',\n * });\n * ```\n */\nexport function setGlobalNERProvider(\n providers: Record<string, { ner: (modelId: string) => NERModel }>,\n options?: { separator?: string }\n): void {\n const separator = options?.separator ?? ':';\n\n globalNERRegistry = {\n resolve(id: string): NERModel {\n const sepIndex = id.indexOf(separator);\n if (sepIndex === -1) {\n throw new Error(\n `Invalid model ID format: \"${id}\". Expected \"provider${separator}modelId\" format.`\n );\n }\n\n const providerName = id.slice(0, sepIndex);\n const modelId = id.slice(sepIndex + 1);\n\n const provider = providers[providerName];\n if (!provider) {\n throw new Error(\n `Unknown provider: \"${providerName}\". Available providers: ${Object.keys(providers).join(', ')}`\n );\n }\n\n return provider.ner(modelId);\n },\n };\n}\n\n/**\n * Resolve a NER model from string ID or return the model object as-is.\n */\nfunction resolveNERModel(modelOrId: NERModel | string): NERModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalNERRegistry) {\n throw new Error(\n 'No global provider configured. Call setGlobalNERProvider() first, or pass a model object instead of a string.'\n );\n }\n\n return globalNERRegistry.resolve(modelOrId);\n}\n\n/**\n * Extract named entities from a single text.\n *\n * Named Entity Recognition identifies and classifies named entities in text,\n * such as people, organizations, locations, dates, etc.\n *\n * This function is in @localmode/core - model implementations are in provider packages.\n *\n * @param options - NER options\n * @returns Promise with entities, usage, and response information\n *\n * @example Basic usage\n * ```ts\n * import { extractEntities } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { entities, usage } = await extractEntities({\n * model: transformers.ner('Xenova/bert-base-NER'),\n * text: 'John works at Microsoft in Seattle',\n * });\n *\n * // entities: [\n * // { text: 'John', type: 'PERSON', start: 0, end: 4, score: 0.99 },\n * // { text: 'Microsoft', type: 'ORG', start: 14, end: 23, score: 0.98 },\n * // { text: 'Seattle', type: 'LOC', start: 27, end: 34, score: 0.97 }\n * // ]\n * ```\n *\n * @example With string model ID (requires global provider setup)\n * ```ts\n * const { entities } = await extractEntities({\n * model: 'transformers:Xenova/bert-base-NER',\n * text: 'Apple announced new products today',\n * });\n * ```\n *\n * @example With AbortSignal\n * ```ts\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 5000);\n *\n * const { entities } = await extractEntities({\n * model: transformers.ner('Xenova/bert-base-NER'),\n * text: 'The CEO of Tesla is Elon Musk',\n * abortSignal: controller.signal,\n * });\n * ```\n *\n * @throws {Error} If extraction fails after all retries\n * @throws {Error} If aborted via AbortSignal\n *\n * @see {@link extractEntitiesMany} for batch entity extraction\n */\nexport async function extractEntities(\n options: ExtractEntitiesOptions\n): Promise<ExtractEntitiesResult> {\n const {\n model: modelOrId,\n text,\n abortSignal,\n maxRetries = 2,\n headers,\n providerOptions,\n } = options;\n\n // Resolve string model ID to model object\n const model = resolveNERModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Check before each retry\n abortSignal?.throwIfAborted();\n\n try {\n const result = await model.doExtract({\n texts: [text],\n abortSignal,\n headers,\n providerOptions,\n });\n\n const item = result.results[0];\n\n return {\n entities: item.entities,\n usage: result.usage,\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry if aborted\n if (abortSignal?.aborted) {\n throw new Error('Entity extraction was cancelled', { cause: lastError });\n }\n\n // Don't retry on the last attempt\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n throw new Error(`Entity extraction failed after ${maxRetries + 1} attempts`, {\n cause: lastError,\n });\n}\n\n/**\n * Extract named entities from multiple texts.\n *\n * @param options - NER options\n * @returns Promise with results array, usage, and response information\n *\n * @example\n * ```ts\n * import { extractEntitiesMany } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { results, usage } = await extractEntitiesMany({\n * model: transformers.ner('Xenova/bert-base-NER'),\n * texts: [\n * 'John works at Microsoft',\n * 'Apple is based in Cupertino',\n * 'The Eiffel Tower is in Paris',\n * ],\n * });\n *\n * results.forEach((r, i) => {\n * console.log(`Text ${i}:`, r.entities.map(e => `${e.text} (${e.type})`));\n * });\n * ```\n *\n * @see {@link extractEntities} for single text entity extraction\n */\nexport async function extractEntitiesMany(\n options: ExtractEntitiesManyOptions\n): Promise<ExtractEntitiesManyResult> {\n const {\n model: modelOrId,\n texts,\n abortSignal,\n maxRetries = 2,\n headers,\n providerOptions,\n } = options;\n\n // Resolve string model ID to model object\n const model = resolveNERModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n const result = await extractWithRetry(model, texts, {\n abortSignal,\n maxRetries,\n headers,\n providerOptions,\n });\n\n return {\n results: result.results,\n usage: result.usage,\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n}\n\n/**\n * Helper function to extract entities with retry logic.\n */\nasync function extractWithRetry(\n model: NERModel,\n texts: string[],\n options: {\n abortSignal?: AbortSignal;\n maxRetries: number;\n headers?: Record<string, string>;\n providerOptions?: Record<string, Record<string, unknown>>;\n }\n): Promise<{\n results: NERResultItem[];\n usage: NERUsage;\n}> {\n const { abortSignal, maxRetries, headers, providerOptions } = options;\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n return await model.doExtract({\n texts,\n abortSignal,\n headers,\n providerOptions,\n });\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw new Error('Entity extraction was cancelled', { cause: lastError });\n }\n\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n throw new Error(`Entity extraction failed after ${maxRetries + 1} attempts`, {\n cause: lastError,\n });\n}\n\n","/**\n * Reranking Functions\n *\n * Core rerank() function for reordering documents by relevance.\n * This function accepts RerankerModel interface - implementations come from provider packages.\n *\n * @packageDocumentation\n */\n\nimport type { RerankerModel, RerankOptions, RerankResult } from './types.js';\n\n// Global provider registry for string model ID resolution\nlet globalRerankerRegistry: GlobalRerankerRegistry | null = null;\n\ninterface GlobalRerankerRegistry {\n resolve(id: string): RerankerModel;\n}\n\n/**\n * Set the global reranker provider registry for string model ID resolution.\n * Call this once at app initialization.\n *\n * @example\n * ```ts\n * import { setGlobalRerankerProvider } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * setGlobalRerankerProvider({\n * transformers,\n * });\n *\n * // Now string model IDs work\n * const { results } = await rerank({\n * model: 'transformers:Xenova/ms-marco-MiniLM-L-6-v2',\n * query: 'What is machine learning?',\n * documents: ['ML is...', 'Cooking...'],\n * });\n * ```\n */\nexport function setGlobalRerankerProvider(\n providers: Record<string, { reranker: (modelId: string) => RerankerModel }>,\n options?: { separator?: string }\n): void {\n const separator = options?.separator ?? ':';\n\n globalRerankerRegistry = {\n resolve(id: string): RerankerModel {\n const sepIndex = id.indexOf(separator);\n if (sepIndex === -1) {\n throw new Error(\n `Invalid model ID format: \"${id}\". Expected \"provider${separator}modelId\" format.`\n );\n }\n\n const providerName = id.slice(0, sepIndex);\n const modelId = id.slice(sepIndex + 1);\n\n const provider = providers[providerName];\n if (!provider) {\n throw new Error(\n `Unknown provider: \"${providerName}\". Available providers: ${Object.keys(providers).join(', ')}`\n );\n }\n\n return provider.reranker(modelId);\n },\n };\n}\n\n/**\n * Resolve a reranker model from string ID or return the model object as-is.\n */\nfunction resolveRerankerModel(modelOrId: RerankerModel | string): RerankerModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalRerankerRegistry) {\n throw new Error(\n 'No global provider configured. Call setGlobalRerankerProvider() first, or pass a model object instead of a string.'\n );\n }\n\n return globalRerankerRegistry.resolve(modelOrId);\n}\n\n/**\n * Rerank documents by relevance to a query.\n *\n * Reranking is a crucial step in RAG (Retrieval-Augmented Generation) pipelines.\n * After initial retrieval (e.g., via vector search), reranking improves result\n * quality by scoring document-query pairs more precisely.\n *\n * This function is in @localmode/core - model implementations are in provider packages.\n *\n * @param options - Reranking options\n * @returns Promise with ranked results, usage, and response information\n *\n * @example Basic usage\n * ```ts\n * import { rerank } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { results } = await rerank({\n * model: transformers.reranker('Xenova/ms-marco-MiniLM-L-6-v2'),\n * query: 'What is machine learning?',\n * documents: [\n * 'Machine learning is a type of artificial intelligence...',\n * 'Cooking pasta requires boiling water...',\n * 'Deep learning is a subset of machine learning...',\n * ],\n * topK: 2,\n * });\n *\n * // results: [\n * // { index: 0, score: 0.95, text: 'Machine learning is a type of...' },\n * // { index: 2, score: 0.88, text: 'Deep learning is a subset of...' }\n * // ]\n * ```\n *\n * @example In a RAG pipeline\n * ```ts\n * // 1. Initial retrieval via vector search\n * const initialResults = await semanticSearch({\n * db,\n * model: embeddingModel,\n * query: 'What is machine learning?',\n * k: 20, // Get more candidates\n * });\n *\n * // 2. Rerank for better precision\n * const { results } = await rerank({\n * model: transformers.reranker('Xenova/ms-marco-MiniLM-L-6-v2'),\n * query: 'What is machine learning?',\n * documents: initialResults.results.map(r => r.document.text),\n * topK: 5, // Return top 5 after reranking\n * });\n * ```\n *\n * @example With string model ID (requires global provider setup)\n * ```ts\n * const { results } = await rerank({\n * model: 'transformers:Xenova/ms-marco-MiniLM-L-6-v2',\n * query: 'climate change effects',\n * documents: documentTexts,\n * });\n * ```\n *\n * @throws {Error} If reranking fails after all retries\n * @throws {Error} If aborted via AbortSignal\n *\n * @see {@link semanticSearch} for initial vector search\n * @see {@link hybridSearch} for hybrid search combining vector and keyword search\n */\nexport async function rerank(options: RerankOptions): Promise<RerankResult> {\n const {\n model: modelOrId,\n query,\n documents,\n topK,\n abortSignal,\n maxRetries = 2,\n headers,\n providerOptions,\n } = options;\n\n // Resolve string model ID to model object\n const model = resolveRerankerModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Check before each retry\n abortSignal?.throwIfAborted();\n\n try {\n const result = await model.doRerank({\n query,\n documents,\n topK,\n abortSignal,\n headers,\n providerOptions,\n });\n\n return {\n results: result.results,\n usage: result.usage,\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry if aborted\n if (abortSignal?.aborted) {\n throw new Error('Reranking was cancelled', { cause: lastError });\n }\n\n // Don't retry on the last attempt\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n throw new Error(`Reranking failed after ${maxRetries + 1} attempts`, {\n cause: lastError,\n });\n}\n","/**\n * Image Classification Functions\n *\n * Core classifyImage() and classifyImageZeroShot() functions.\n * These functions accept ImageClassificationModel interface - implementations come from provider packages.\n *\n * @packageDocumentation\n */\n\nimport type {\n ImageClassificationModel,\n ZeroShotImageClassificationModel,\n ClassifyImageOptions,\n ClassifyImageResult,\n ClassifyImageZeroShotOptions,\n ClassifyImageZeroShotResult,\n} from './types.js';\n\n// Global provider registry for string model ID resolution\nlet globalImageClassificationRegistry: GlobalImageClassificationRegistry | null = null;\n\ninterface GlobalImageClassificationRegistry {\n resolveClassifier(id: string): ImageClassificationModel;\n resolveZeroShot(id: string): ZeroShotImageClassificationModel;\n}\n\n/**\n * Set the global image classification provider registry for string model ID resolution.\n * Call this once at app initialization.\n *\n * @example\n * ```ts\n * import { setGlobalImageClassificationProvider } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * setGlobalImageClassificationProvider({\n * transformers,\n * });\n *\n * // Now string model IDs work\n * const { predictions } = await classifyImage({\n * model: 'transformers:Xenova/vit-base-patch16-224',\n * image: imageBlob,\n * });\n * ```\n */\nexport function setGlobalImageClassificationProvider(\n providers: Record<\n string,\n {\n imageClassifier: (modelId: string) => ImageClassificationModel;\n zeroShotImageClassifier: (modelId: string) => ZeroShotImageClassificationModel;\n }\n >,\n options?: { separator?: string }\n): void {\n const separator = options?.separator ?? ':';\n\n globalImageClassificationRegistry = {\n resolveClassifier(id: string): ImageClassificationModel {\n const sepIndex = id.indexOf(separator);\n if (sepIndex === -1) {\n throw new Error(\n `Invalid model ID format: \"${id}\". Expected \"provider${separator}modelId\" format.`\n );\n }\n\n const providerName = id.slice(0, sepIndex);\n const modelId = id.slice(sepIndex + 1);\n\n const provider = providers[providerName];\n if (!provider) {\n throw new Error(\n `Unknown provider: \"${providerName}\". Available providers: ${Object.keys(providers).join(', ')}`\n );\n }\n\n return provider.imageClassifier(modelId);\n },\n\n resolveZeroShot(id: string): ZeroShotImageClassificationModel {\n const sepIndex = id.indexOf(separator);\n if (sepIndex === -1) {\n throw new Error(\n `Invalid model ID format: \"${id}\". Expected \"provider${separator}modelId\" format.`\n );\n }\n\n const providerName = id.slice(0, sepIndex);\n const modelId = id.slice(sepIndex + 1);\n\n const provider = providers[providerName];\n if (!provider) {\n throw new Error(\n `Unknown provider: \"${providerName}\". Available providers: ${Object.keys(providers).join(', ')}`\n );\n }\n\n return provider.zeroShotImageClassifier(modelId);\n },\n };\n}\n\n/**\n * Resolve an image classification model from string ID or return the model object as-is.\n */\nfunction resolveImageClassificationModel(\n modelOrId: ImageClassificationModel | string\n): ImageClassificationModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalImageClassificationRegistry) {\n throw new Error(\n 'No global provider configured. Call setGlobalImageClassificationProvider() first, or pass a model object instead of a string.'\n );\n }\n\n return globalImageClassificationRegistry.resolveClassifier(modelOrId);\n}\n\n/**\n * Resolve a zero-shot image classification model from string ID or return the model object as-is.\n */\nfunction resolveZeroShotImageModel(\n modelOrId: ZeroShotImageClassificationModel | string\n): ZeroShotImageClassificationModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalImageClassificationRegistry) {\n throw new Error(\n 'No global provider configured. Call setGlobalImageClassificationProvider() first, or pass a model object instead of a string.'\n );\n }\n\n return globalImageClassificationRegistry.resolveZeroShot(modelOrId);\n}\n\n/**\n * Classify an image using the specified model.\n *\n * This function uses pre-trained image classification models to identify\n * objects, scenes, or concepts in images.\n *\n * This function is in @localmode/core - model implementations are in provider packages.\n *\n * @param options - Classification options\n * @returns Promise with predictions, usage, and response information\n *\n * @example Basic usage\n * ```ts\n * import { classifyImage } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { predictions, usage } = await classifyImage({\n * model: transformers.imageClassifier('Xenova/vit-base-patch16-224'),\n * image: imageBlob,\n * topK: 5,\n * });\n *\n * predictions.forEach(p => {\n * console.log(`${p.label}: ${(p.score * 100).toFixed(1)}%`);\n * });\n * // Output:\n * // golden retriever: 92.3%\n * // Labrador retriever: 4.1%\n * // ...\n * ```\n *\n * @example With string model ID (requires global provider setup)\n * ```ts\n * const { predictions } = await classifyImage({\n * model: 'transformers:Xenova/vit-base-patch16-224',\n * image: imageBlob,\n * });\n * ```\n *\n * @example With AbortSignal\n * ```ts\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 5000);\n *\n * const { predictions } = await classifyImage({\n * model: transformers.imageClassifier('Xenova/vit-base-patch16-224'),\n * image: imageBlob,\n * abortSignal: controller.signal,\n * });\n * ```\n *\n * @throws {Error} If classification fails after all retries\n * @throws {Error} If aborted via AbortSignal\n *\n * @see {@link classifyImageZeroShot} for zero-shot image classification\n */\nexport async function classifyImage(\n options: ClassifyImageOptions\n): Promise<ClassifyImageResult> {\n const {\n model: modelOrId,\n image,\n topK = 5,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n // Resolve string model ID to model object\n const model = resolveImageClassificationModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Check before each retry\n abortSignal?.throwIfAborted();\n\n try {\n const result = await model.doClassify({\n images: [image],\n topK,\n abortSignal,\n providerOptions,\n });\n\n return {\n predictions: result.results[0],\n usage: result.usage,\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry if aborted\n if (abortSignal?.aborted) {\n throw new Error('Image classification was cancelled', { cause: lastError });\n }\n\n // Don't retry on the last attempt\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n throw new Error(`Image classification failed after ${maxRetries + 1} attempts`, {\n cause: lastError,\n });\n}\n\n/**\n * Classify an image into arbitrary labels using zero-shot classification.\n *\n * Zero-shot image classification (e.g., using CLIP) allows you to classify images\n * into any set of labels without fine-tuning the model.\n *\n * @param options - Zero-shot classification options\n * @returns Promise with labels, scores, usage, and response information\n *\n * @example Basic usage\n * ```ts\n * import { classifyImageZeroShot } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { labels, scores } = await classifyImageZeroShot({\n * model: transformers.zeroShotImageClassifier('Xenova/clip-vit-base-patch32'),\n * image: imageBlob,\n * candidateLabels: ['cat', 'dog', 'bird', 'car', 'tree'],\n * });\n *\n * console.log(`Top prediction: ${labels[0]} (${(scores[0] * 100).toFixed(1)}%)`);\n * // Output: Top prediction: dog (87.2%)\n * ```\n *\n * @example Photo organization\n * ```ts\n * const { labels, scores } = await classifyImageZeroShot({\n * model: transformers.zeroShotImageClassifier('Xenova/clip-vit-base-patch32'),\n * image: vacationPhoto,\n * candidateLabels: ['beach', 'mountain', 'city', 'forest', 'desert'],\n * });\n *\n * // Use for automatic photo tagging\n * const tags = labels.filter((_, i) => scores[i] > 0.2);\n * ```\n *\n * @see {@link classifyImage} for standard image classification with fixed labels\n */\nexport async function classifyImageZeroShot(\n options: ClassifyImageZeroShotOptions\n): Promise<ClassifyImageZeroShotResult> {\n const {\n model: modelOrId,\n image,\n candidateLabels,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n // Resolve string model ID to model object\n const model = resolveZeroShotImageModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Check before each retry\n abortSignal?.throwIfAborted();\n\n try {\n const result = await model.doClassifyZeroShot({\n images: [image],\n candidateLabels,\n abortSignal,\n providerOptions,\n });\n\n const item = result.results[0];\n\n return {\n labels: item.labels,\n scores: item.scores,\n usage: result.usage,\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry if aborted\n if (abortSignal?.aborted) {\n throw new Error('Zero-shot image classification was cancelled', { cause: lastError });\n }\n\n // Don't retry on the last attempt\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n throw new Error(`Zero-shot image classification failed after ${maxRetries + 1} attempts`, {\n cause: lastError,\n });\n}\n\n","/**\n * Image Captioning Functions\n *\n * Core captionImage() function for generating image descriptions.\n * This function accepts ImageCaptionModel interface - implementations come from provider packages.\n *\n * @packageDocumentation\n */\n\nimport type {\n ImageCaptionModel,\n CaptionImageOptions,\n CaptionImageResult,\n} from './types.js';\n\n// Global provider registry for string model ID resolution\nlet globalImageCaptionRegistry: GlobalImageCaptionRegistry | null = null;\n\ninterface GlobalImageCaptionRegistry {\n resolve(id: string): ImageCaptionModel;\n}\n\n/**\n * Set the global image captioning provider registry for string model ID resolution.\n * Call this once at app initialization.\n *\n * @example\n * ```ts\n * import { setGlobalImageCaptionProvider } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * setGlobalImageCaptionProvider({\n * transformers,\n * });\n *\n * // Now string model IDs work\n * const { caption } = await captionImage({\n * model: 'transformers:Xenova/blip-image-captioning-base',\n * image: imageBlob,\n * });\n * ```\n */\nexport function setGlobalImageCaptionProvider(\n providers: Record<string, { captioner: (modelId: string) => ImageCaptionModel }>,\n options?: { separator?: string }\n): void {\n const separator = options?.separator ?? ':';\n\n globalImageCaptionRegistry = {\n resolve(id: string): ImageCaptionModel {\n const sepIndex = id.indexOf(separator);\n if (sepIndex === -1) {\n throw new Error(\n `Invalid model ID format: \"${id}\". Expected \"provider${separator}modelId\" format.`\n );\n }\n\n const providerName = id.slice(0, sepIndex);\n const modelId = id.slice(sepIndex + 1);\n\n const provider = providers[providerName];\n if (!provider) {\n throw new Error(\n `Unknown provider: \"${providerName}\". Available providers: ${Object.keys(providers).join(', ')}`\n );\n }\n\n return provider.captioner(modelId);\n },\n };\n}\n\n/**\n * Resolve an image captioning model from string ID or return the model object as-is.\n */\nfunction resolveImageCaptionModel(modelOrId: ImageCaptionModel | string): ImageCaptionModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalImageCaptionRegistry) {\n throw new Error(\n 'No global provider configured. Call setGlobalImageCaptionProvider() first, or pass a model object instead of a string.'\n );\n }\n\n return globalImageCaptionRegistry.resolve(modelOrId);\n}\n\n/**\n * Generate a caption for an image using the specified model.\n *\n * Image captioning models (like BLIP) automatically generate natural language\n * descriptions of image content. This is useful for accessibility, content\n * indexing, and image search.\n *\n * This function is in @localmode/core - model implementations are in provider packages.\n *\n * @param options - Captioning options\n * @returns Promise with caption, usage, and response information\n *\n * @example Basic usage\n * ```ts\n * import { captionImage } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { caption, usage } = await captionImage({\n * model: transformers.captioner('Xenova/blip-image-captioning-base'),\n * image: imageBlob,\n * });\n *\n * console.log(caption);\n * // Output: \"a golden retriever playing with a ball in a park\"\n * ```\n *\n * @example For accessibility\n * ```ts\n * // Generate alt text for images\n * const { caption } = await captionImage({\n * model: transformers.captioner('Xenova/blip-image-captioning-base'),\n * image: uploadedImage,\n * });\n *\n * img.alt = caption;\n * ```\n *\n * @example For image search\n * ```ts\n * // Index images by their captions for semantic search\n * for (const image of images) {\n * const { caption } = await captionImage({\n * model: captioningModel,\n * image,\n * });\n *\n * const { embedding } = await embed({\n * model: embeddingModel,\n * value: caption,\n * });\n *\n * await db.add({\n * id: image.id,\n * vector: embedding,\n * metadata: { caption, imagePath: image.path },\n * });\n * }\n * ```\n *\n * @example With string model ID (requires global provider setup)\n * ```ts\n * const { caption } = await captionImage({\n * model: 'transformers:Xenova/blip-image-captioning-base',\n * image: imageBlob,\n * });\n * ```\n *\n * @example With AbortSignal\n * ```ts\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 10000);\n *\n * const { caption } = await captionImage({\n * model: transformers.captioner('Xenova/blip-image-captioning-base'),\n * image: imageBlob,\n * abortSignal: controller.signal,\n * });\n * ```\n *\n * @throws {Error} If captioning fails after all retries\n * @throws {Error} If aborted via AbortSignal\n *\n * @see {@link classifyImage} for image classification\n */\nexport async function captionImage(options: CaptionImageOptions): Promise<CaptionImageResult> {\n const {\n model: modelOrId,\n image,\n maxLength,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n // Resolve string model ID to model object\n const model = resolveImageCaptionModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Check before each retry\n abortSignal?.throwIfAborted();\n\n try {\n const result = await model.doCaption({\n images: [image],\n maxLength,\n abortSignal,\n providerOptions,\n });\n\n return {\n caption: result.captions[0],\n usage: result.usage,\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry if aborted\n if (abortSignal?.aborted) {\n throw new Error('Image captioning was cancelled', { cause: lastError });\n }\n\n // Don't retry on the last attempt\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n throw new Error(`Image captioning failed after ${maxRetries + 1} attempts`, {\n cause: lastError,\n });\n}\n\n","/**\n * Image Segmentation Function\n *\n * Function-first API for image segmentation.\n *\n * @packageDocumentation\n */\n\nimport type {\n SegmentationModel,\n SegmentImageOptions,\n SegmentImageResult,\n SegmentationModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalSegmentationProvider: SegmentationModelFactory | null = null;\n\n/**\n * Set the global segmentation provider for string model ID resolution.\n *\n * @param provider - Factory function to create segmentation models from string IDs\n */\nexport function setGlobalSegmentationProvider(provider: SegmentationModelFactory | null): void {\n globalSegmentationProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: SegmentationModel | string): SegmentationModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalSegmentationProvider) {\n throw new Error(\n 'No global segmentation provider configured. ' +\n 'Either pass a SegmentationModel object or call setGlobalSegmentationProvider() first.'\n );\n }\n\n return globalSegmentationProvider(modelOrId);\n}\n\n/**\n * Segment an image into regions.\n *\n * @param options - Segmentation options including model and image\n * @returns Promise with segmentation masks and usage information\n *\n * @example Basic usage\n * ```ts\n * import { segmentImage } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { masks, usage } = await segmentImage({\n * model: transformers.segmenter('Xenova/segformer-b0-finetuned-ade-512-512'),\n * image: imageBlob,\n * });\n *\n * for (const mask of masks) {\n * console.log(`${mask.label}: ${(mask.score * 100).toFixed(1)}%`);\n * }\n * ```\n *\n * @example Background removal\n * ```ts\n * const { masks } = await segmentImage({\n * model: transformers.segmenter('briaai/RMBG-1.4'),\n * image: photoImage,\n * });\n *\n * // Apply the foreground mask\n * const foregroundMask = masks.find(m => m.label === 'foreground');\n * ```\n *\n * @throws {Error} If segmentation fails\n */\nexport async function segmentImage(options: SegmentImageOptions): Promise<SegmentImageResult> {\n const { model: modelOrId, image, abortSignal, maxRetries = 2, providerOptions } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doSegment({\n images: [image],\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n masks: result.results[0].masks,\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Image segmentation failed');\n}\n\n","/**\n * Object Detection Function\n *\n * Function-first API for object detection in images.\n *\n * @packageDocumentation\n */\n\nimport type {\n ObjectDetectionModel,\n DetectObjectsOptions,\n DetectObjectsResult,\n ObjectDetectionModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalObjectDetectionProvider: ObjectDetectionModelFactory | null = null;\n\n/**\n * Set the global object detection provider for string model ID resolution.\n *\n * @param provider - Factory function to create object detection models from string IDs\n */\nexport function setGlobalObjectDetectionProvider(\n provider: ObjectDetectionModelFactory | null\n): void {\n globalObjectDetectionProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: ObjectDetectionModel | string): ObjectDetectionModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalObjectDetectionProvider) {\n throw new Error(\n 'No global object detection provider configured. ' +\n 'Either pass an ObjectDetectionModel object or call setGlobalObjectDetectionProvider() first.'\n );\n }\n\n return globalObjectDetectionProvider(modelOrId);\n}\n\n/**\n * Detect objects in an image.\n *\n * @param options - Detection options including model and image\n * @returns Promise with detected objects and usage information\n *\n * @example Basic usage\n * ```ts\n * import { detectObjects } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { objects, usage } = await detectObjects({\n * model: transformers.objectDetector('Xenova/detr-resnet-50'),\n * image: imageBlob,\n * threshold: 0.7,\n * });\n *\n * for (const obj of objects) {\n * console.log(`${obj.label} at (${obj.box.x}, ${obj.box.y}): ${(obj.score * 100).toFixed(1)}%`);\n * }\n * ```\n *\n * @example Custom threshold\n * ```ts\n * const { objects } = await detectObjects({\n * model: transformers.objectDetector('Xenova/yolos-tiny'),\n * image: sceneImage,\n * threshold: 0.3, // Lower threshold for more detections\n * });\n * ```\n *\n * @throws {Error} If detection fails\n */\nexport async function detectObjects(options: DetectObjectsOptions): Promise<DetectObjectsResult> {\n const {\n model: modelOrId,\n image,\n threshold = 0.5,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doDetect({\n images: [image],\n threshold,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n objects: result.results[0].objects,\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Object detection failed');\n}\n\n","/**\n * Image Feature Extraction Function\n *\n * Function-first API for extracting feature vectors from images.\n *\n * @packageDocumentation\n */\n\nimport type {\n ImageFeatureModel,\n ExtractImageFeaturesOptions,\n ExtractImageFeaturesResult,\n ImageFeatureModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalImageFeatureProvider: ImageFeatureModelFactory | null = null;\n\n/**\n * Set the global image feature provider for string model ID resolution.\n *\n * @param provider - Factory function to create image feature models from string IDs\n */\nexport function setGlobalImageFeatureProvider(provider: ImageFeatureModelFactory | null): void {\n globalImageFeatureProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: ImageFeatureModel | string): ImageFeatureModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalImageFeatureProvider) {\n throw new Error(\n 'No global image feature provider configured. ' +\n 'Either pass an ImageFeatureModel object or call setGlobalImageFeatureProvider() first.'\n );\n }\n\n return globalImageFeatureProvider(modelOrId);\n}\n\n/**\n * Extract feature vectors from an image.\n *\n * Useful for image similarity search, reverse image search, and clustering.\n *\n * @param options - Feature extraction options including model and image\n * @returns Promise with feature vector and usage information\n *\n * @example Basic usage\n * ```ts\n * import { extractImageFeatures, cosineSimilarity } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const model = transformers.imageFeatures('Xenova/clip-vit-base-patch32');\n *\n * const { features: features1 } = await extractImageFeatures({\n * model,\n * image: image1,\n * });\n *\n * const { features: features2 } = await extractImageFeatures({\n * model,\n * image: image2,\n * });\n *\n * const similarity = cosineSimilarity(features1, features2);\n * console.log(`Image similarity: ${(similarity * 100).toFixed(1)}%`);\n * ```\n *\n * @example Store in vector database\n * ```ts\n * const { features } = await extractImageFeatures({\n * model: transformers.imageFeatures('Xenova/clip-vit-base-patch32'),\n * image: productImage,\n * });\n *\n * await vectorDB.add({\n * id: 'product-123',\n * vector: features,\n * metadata: { name: 'Product Name', imageUrl: '...' },\n * });\n * ```\n *\n * @throws {Error} If feature extraction fails\n */\nexport async function extractImageFeatures(\n options: ExtractImageFeaturesOptions\n): Promise<ExtractImageFeaturesResult> {\n const { model: modelOrId, image, abortSignal, maxRetries = 2, providerOptions } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doExtract({\n images: [image],\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n features: result.features[0],\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Image feature extraction failed');\n}\n\n","/**\n * Image-to-Image Transformation Function\n *\n * Function-first API for image transformation (super resolution, etc.).\n *\n * @packageDocumentation\n */\n\nimport type {\n ImageToImageModel,\n UpscaleImageOptions,\n UpscaleImageResult,\n ImageToImageModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalImageToImageProvider: ImageToImageModelFactory | null = null;\n\n/**\n * Set the global image-to-image provider for string model ID resolution.\n *\n * @param provider - Factory function to create image-to-image models from string IDs\n */\nexport function setGlobalImageToImageProvider(provider: ImageToImageModelFactory | null): void {\n globalImageToImageProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: ImageToImageModel | string): ImageToImageModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalImageToImageProvider) {\n throw new Error(\n 'No global image-to-image provider configured. ' +\n 'Either pass an ImageToImageModel object or call setGlobalImageToImageProvider() first.'\n );\n }\n\n return globalImageToImageProvider(modelOrId);\n}\n\n/**\n * Upscale an image using super resolution.\n *\n * @param options - Upscale options including model, image, and scale factor\n * @returns Promise with upscaled image and usage information\n *\n * @example Basic usage\n * ```ts\n * import { upscaleImage } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { image, usage } = await upscaleImage({\n * model: transformers.imageToImage('Xenova/swin2SR-classical-sr-x2-64'),\n * image: lowResImage,\n * scale: 2,\n * });\n *\n * console.log(`Upscaled in ${usage.durationMs}ms`);\n * ```\n *\n * @example 4x upscaling\n * ```ts\n * const { image } = await upscaleImage({\n * model: transformers.imageToImage('Xenova/swin2SR-realworld-sr-x4-64'),\n * image: thumbnailImage,\n * scale: 4,\n * });\n * ```\n *\n * @throws {Error} If upscaling fails\n */\nexport async function upscaleImage(options: UpscaleImageOptions): Promise<UpscaleImageResult> {\n const {\n model: modelOrId,\n image,\n scale = 2,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doTransform({\n images: [image],\n scale,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n image: result.images[0],\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Image upscaling failed');\n}\n\n/**\n * Alias for upscaleImage - transform an image using image-to-image models.\n *\n * @see {@link upscaleImage}\n */\nexport const imageToImage = upscaleImage;\n","/**\n * Speech-to-Text Functions\n *\n * Core transcribe() function for audio transcription.\n * This function accepts SpeechToTextModel interface - implementations come from provider packages.\n *\n * @packageDocumentation\n */\n\nimport type { SpeechToTextModel, TranscribeOptions, TranscribeResult } from './types.js';\n\n// Global provider registry for string model ID resolution\nlet globalSTTRegistry: GlobalSTTRegistry | null = null;\n\ninterface GlobalSTTRegistry {\n resolve(id: string): SpeechToTextModel;\n}\n\n/**\n * Set the global speech-to-text provider registry for string model ID resolution.\n * Call this once at app initialization.\n *\n * @example\n * ```ts\n * import { setGlobalSTTProvider } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * setGlobalSTTProvider({\n * transformers,\n * });\n *\n * // Now string model IDs work\n * const { text } = await transcribe({\n * model: 'transformers:Xenova/whisper-tiny',\n * audio: audioBlob,\n * });\n * ```\n */\nexport function setGlobalSTTProvider(\n providers: Record<string, { speechToText: (modelId: string) => SpeechToTextModel }>,\n options?: { separator?: string }\n): void {\n const separator = options?.separator ?? ':';\n\n globalSTTRegistry = {\n resolve(id: string): SpeechToTextModel {\n const sepIndex = id.indexOf(separator);\n if (sepIndex === -1) {\n throw new Error(\n `Invalid model ID format: \"${id}\". Expected \"provider${separator}modelId\" format.`\n );\n }\n\n const providerName = id.slice(0, sepIndex);\n const modelId = id.slice(sepIndex + 1);\n\n const provider = providers[providerName];\n if (!provider) {\n throw new Error(\n `Unknown provider: \"${providerName}\". Available providers: ${Object.keys(providers).join(', ')}`\n );\n }\n\n return provider.speechToText(modelId);\n },\n };\n}\n\n/**\n * Resolve a speech-to-text model from string ID or return the model object as-is.\n */\nfunction resolveSTTModel(modelOrId: SpeechToTextModel | string): SpeechToTextModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalSTTRegistry) {\n throw new Error(\n 'No global provider configured. Call setGlobalSTTProvider() first, or pass a model object instead of a string.'\n );\n }\n\n return globalSTTRegistry.resolve(modelOrId);\n}\n\n/**\n * Transcribe audio to text using a speech-to-text model.\n *\n * This function supports Whisper and other ASR (Automatic Speech Recognition) models.\n * It can optionally return word-level or segment-level timestamps.\n *\n * This function is in @localmode/core - model implementations are in provider packages.\n *\n * @param options - Transcription options\n * @returns Promise with text, segments (if requested), usage, and response information\n *\n * @example Basic usage\n * ```ts\n * import { transcribe } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { text, usage } = await transcribe({\n * model: transformers.speechToText('Xenova/whisper-tiny'),\n * audio: audioBlob,\n * });\n *\n * console.log(text); // \"Hello, world!\"\n * console.log(usage.audioDurationSec); // 3.5\n * ```\n *\n * @example With timestamps\n * ```ts\n * const { text, segments } = await transcribe({\n * model: transformers.speechToText('Xenova/whisper-small'),\n * audio: audioBlob,\n * returnTimestamps: true,\n * });\n *\n * segments?.forEach(seg => {\n * console.log(`[${seg.start}s - ${seg.end}s] ${seg.text}`);\n * });\n * ```\n *\n * @example With language specification\n * ```ts\n * const { text, language } = await transcribe({\n * model: transformers.speechToText('Xenova/whisper-small'),\n * audio: germanAudioBlob,\n * language: 'de', // German\n * });\n *\n * console.log(text); // German transcription\n * console.log(language); // \"de\"\n * ```\n *\n * @example Translation mode (translate to English)\n * ```ts\n * const { text } = await transcribe({\n * model: transformers.speechToText('Xenova/whisper-small'),\n * audio: frenchAudioBlob,\n * task: 'translate', // Translates to English\n * });\n *\n * console.log(text); // English translation\n * ```\n *\n * @example With string model ID (requires global provider setup)\n * ```ts\n * const { text } = await transcribe({\n * model: 'transformers:Xenova/whisper-tiny',\n * audio: audioBlob,\n * });\n * ```\n *\n * @example With AbortSignal for cancellation\n * ```ts\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 30000); // 30s timeout\n *\n * const { text } = await transcribe({\n * model: transformers.speechToText('Xenova/whisper-small'),\n * audio: longAudioBlob,\n * abortSignal: controller.signal,\n * });\n * ```\n *\n * @throws {Error} If transcription fails after all retries\n * @throws {Error} If aborted via AbortSignal\n */\nexport async function transcribe(options: TranscribeOptions): Promise<TranscribeResult> {\n const {\n model: modelOrId,\n audio,\n language,\n task,\n returnTimestamps,\n abortSignal,\n maxRetries = 2,\n headers,\n providerOptions,\n } = options;\n\n // Resolve string model ID to model object\n const model = resolveSTTModel(modelOrId);\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Check before each retry\n abortSignal?.throwIfAborted();\n\n try {\n const result = await model.doTranscribe({\n audio,\n language,\n task,\n returnTimestamps,\n abortSignal,\n headers,\n providerOptions,\n });\n\n return {\n text: result.text,\n segments: result.segments,\n language: result.language,\n usage: result.usage,\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry if aborted\n if (abortSignal?.aborted) {\n throw new Error('Transcription was cancelled', { cause: lastError });\n }\n\n // Don't retry on the last attempt\n if (attempt === maxRetries) {\n break;\n }\n }\n }\n\n throw new Error(`Transcription failed after ${maxRetries + 1} attempts`, {\n cause: lastError,\n });\n}\n","/**\n * Text-to-Speech Function\n *\n * Function-first API for speech synthesis.\n *\n * @packageDocumentation\n */\n\nimport type {\n TextToSpeechModel,\n SynthesizeSpeechOptions,\n SynthesizeSpeechResult,\n TextToSpeechModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalTTSProvider: TextToSpeechModelFactory | null = null;\n\n/**\n * Set the global text-to-speech provider for string model ID resolution.\n *\n * @param provider - Factory function to create TTS models from string IDs\n *\n * @example\n * ```ts\n * import { setGlobalTTSProvider } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * setGlobalTTSProvider((modelId) => transformers.textToSpeech(modelId));\n *\n * // Now you can use string model IDs\n * const { audio } = await synthesizeSpeech({\n * model: 'Xenova/speecht5-tts',\n * text: 'Hello, world!',\n * });\n * ```\n */\nexport function setGlobalTTSProvider(provider: TextToSpeechModelFactory | null): void {\n globalTTSProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: TextToSpeechModel | string): TextToSpeechModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalTTSProvider) {\n throw new Error(\n 'No global TTS provider configured. ' +\n 'Either pass a TextToSpeechModel object or call setGlobalTTSProvider() first.'\n );\n }\n\n return globalTTSProvider(modelOrId);\n}\n\n/**\n * Synthesize speech from text using a text-to-speech model.\n *\n * @param options - Synthesis options including model, text, and voice settings\n * @returns Promise with generated audio and usage information\n *\n * @example Basic usage\n * ```ts\n * import { synthesizeSpeech } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { audio, sampleRate, usage } = await synthesizeSpeech({\n * model: transformers.textToSpeech('Xenova/speecht5-tts'),\n * text: 'Hello, how are you today?',\n * });\n *\n * // Play the audio\n * const audioContext = new AudioContext();\n * const audioBuffer = await audioContext.decodeAudioData(await audio.arrayBuffer());\n * const source = audioContext.createBufferSource();\n * source.buffer = audioBuffer;\n * source.connect(audioContext.destination);\n * source.start();\n *\n * console.log(`Generated ${usage.characterCount} characters in ${usage.durationMs}ms`);\n * ```\n *\n * @example With voice selection\n * ```ts\n * const { audio } = await synthesizeSpeech({\n * model: transformers.textToSpeech('Xenova/speecht5-tts'),\n * text: 'Welcome to the application.',\n * voice: 'speaker-1',\n * speed: 1.2, // Slightly faster\n * });\n * ```\n *\n * @example Create audio URL for playback\n * ```ts\n * const { audio } = await synthesizeSpeech({\n * model: transformers.textToSpeech('Xenova/speecht5-tts'),\n * text: 'This is a test.',\n * });\n *\n * const audioUrl = URL.createObjectURL(audio);\n * const audioElement = new Audio(audioUrl);\n * audioElement.play();\n * ```\n *\n * @throws {Error} If synthesis fails\n */\nexport async function synthesizeSpeech(\n options: SynthesizeSpeechOptions\n): Promise<SynthesizeSpeechResult> {\n const {\n model: modelOrId,\n text,\n voice,\n speed,\n pitch,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doSynthesize({\n text,\n voice,\n speed,\n pitch,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n audio: result.audio,\n sampleRate: result.sampleRate,\n usage: {\n characterCount: result.usage.characterCount,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Speech synthesis failed');\n}\n\n","/**\n * Text Generation Function\n *\n * Function-first API for generating text with language models.\n *\n * @packageDocumentation\n */\n\nimport type {\n LanguageModel,\n GenerateTextOptions,\n GenerateTextResult,\n LanguageModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalLanguageModelProvider: LanguageModelFactory | null = null;\n\n/**\n * Set the global language model provider for string model ID resolution.\n *\n * @param provider - Factory function to create language models from string IDs\n *\n * @example\n * ```ts\n * import { setGlobalLanguageModelProvider } from '@localmode/core';\n * import { webllm } from '@localmode/webllm';\n *\n * setGlobalLanguageModelProvider((modelId) => webllm.languageModel(modelId));\n *\n * // Now you can use string model IDs\n * const { text } = await generateText({\n * model: 'Llama-3.2-1B-Instruct-q4f16',\n * prompt: 'Hello',\n * });\n * ```\n */\nexport function setGlobalLanguageModelProvider(provider: LanguageModelFactory | null): void {\n globalLanguageModelProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: LanguageModel | string): LanguageModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalLanguageModelProvider) {\n throw new Error(\n 'No global language model provider configured. ' +\n 'Either pass a LanguageModel object or call setGlobalLanguageModelProvider() first.'\n );\n }\n\n return globalLanguageModelProvider(modelOrId);\n}\n\n/**\n * Generate text using a language model.\n *\n * @param options - Generation options including model, prompt, and parameters\n * @returns Promise with generated text and usage information\n *\n * @example Basic usage\n * ```ts\n * import { generateText } from '@localmode/core';\n * import { webllm } from '@localmode/webllm';\n *\n * const { text, usage } = await generateText({\n * model: webllm.languageModel('Llama-3.2-1B-Instruct-q4f16'),\n * prompt: 'Explain quantum computing',\n * maxTokens: 200,\n * });\n *\n * console.log(text);\n * console.log(`Generated ${usage.outputTokens} tokens in ${usage.durationMs}ms`);\n * ```\n *\n * @example With system prompt\n * ```ts\n * const { text } = await generateText({\n * model: webllm.languageModel('Llama-3.2-1B-Instruct-q4f16'),\n * systemPrompt: 'You are a helpful assistant.',\n * prompt: 'What is the capital of France?',\n * });\n * ```\n *\n * @example With cancellation\n * ```ts\n * const controller = new AbortController();\n *\n * const promise = generateText({\n * model: webllm.languageModel('Llama-3.2-1B-Instruct-q4f16'),\n * prompt: 'Write a long story',\n * maxTokens: 1000,\n * abortSignal: controller.signal,\n * });\n *\n * // Cancel after 5 seconds\n * setTimeout(() => controller.abort(), 5000);\n * ```\n *\n * @throws {Error} If no model is provided or generation fails\n */\nexport async function generateText(options: GenerateTextOptions): Promise<GenerateTextResult> {\n const {\n model: modelOrId,\n prompt,\n systemPrompt,\n messages,\n maxTokens = 256,\n temperature = 0.7,\n topP = 1.0,\n stopSequences,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n // Resolve the model\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n // Retry loop\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Check for cancellation before each attempt\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doGenerate({\n prompt,\n systemPrompt,\n messages,\n maxTokens,\n temperature,\n topP,\n stopSequences,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n text: result.text,\n finishReason: result.finishReason,\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry on abort\n if (abortSignal?.aborted) {\n throw error;\n }\n\n // Don't retry on last attempt\n if (attempt === maxRetries) {\n throw error;\n }\n\n // Wait before retry (exponential backoff)\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n // Should not reach here, but just in case\n throw lastError || new Error('Generation failed');\n}\n\n","/**\n * Streaming Text Generation Function\n *\n * Function-first API for streaming text generation with language models.\n *\n * @packageDocumentation\n */\n\nimport type {\n LanguageModel,\n StreamTextOptions,\n StreamTextResult,\n StreamChunk,\n GenerationUsage,\n LanguageModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalLanguageModelProvider: LanguageModelFactory | null = null;\n\n/**\n * Set the global language model provider for string model ID resolution.\n * This is shared with generateText().\n */\nexport function setGlobalLanguageModelProviderForStream(\n provider: LanguageModelFactory | null\n): void {\n globalLanguageModelProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: LanguageModel | string): LanguageModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalLanguageModelProvider) {\n throw new Error(\n 'No global language model provider configured. ' +\n 'Either pass a LanguageModel object or call setGlobalLanguageModelProvider() first.'\n );\n }\n\n return globalLanguageModelProvider(modelOrId);\n}\n\n/**\n * Stream text generation using a language model.\n *\n * Returns an object with a stream property that can be iterated,\n * plus promises for the full text and usage information.\n *\n * @param options - Stream options including model, prompt, and parameters\n * @returns Object with stream, text promise, usage promise, and response metadata\n *\n * @example Basic streaming\n * ```ts\n * import { streamText } from '@localmode/core';\n * import { webllm } from '@localmode/webllm';\n *\n * const result = await streamText({\n * model: webllm.languageModel('Llama-3.2-1B-Instruct-q4f16'),\n * prompt: 'Write a story about a robot',\n * maxTokens: 500,\n * });\n *\n * for await (const chunk of result.stream) {\n * process.stdout.write(chunk.text);\n * }\n *\n * const fullText = await result.text;\n * const usage = await result.usage;\n * console.log(`\\nGenerated ${usage.outputTokens} tokens`);\n * ```\n *\n * @example With onChunk callback\n * ```ts\n * const result = await streamText({\n * model: webllm.languageModel('Llama-3.2-1B-Instruct-q4f16'),\n * prompt: 'Explain AI',\n * onChunk: (chunk) => {\n * // Update UI in real-time\n * appendToOutput(chunk.text);\n * },\n * });\n * ```\n *\n * @throws {Error} If model doesn't support streaming or generation fails\n */\nexport async function streamText(options: StreamTextOptions): Promise<StreamTextResult> {\n const {\n model: modelOrId,\n prompt,\n systemPrompt,\n messages,\n maxTokens = 256,\n temperature = 0.7,\n topP = 1.0,\n stopSequences,\n abortSignal,\n providerOptions,\n onChunk,\n } = options;\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n // Resolve the model\n const model = resolveModel(modelOrId);\n\n // Check if model supports streaming\n if (!model.doStream) {\n throw new Error(\n `Model ${model.modelId} does not support streaming. Use generateText() instead.`\n );\n }\n\n // Create the stream\n const streamOptions = {\n prompt,\n systemPrompt,\n messages,\n maxTokens,\n temperature,\n topP,\n stopSequences,\n abortSignal,\n providerOptions,\n };\n\n const innerStream = model.doStream(streamOptions);\n\n // Track accumulated text and usage\n let accumulatedText = '';\n let finalUsage: GenerationUsage | null = null;\n let resolveText: (text: string) => void;\n let rejectText: (error: Error) => void;\n let resolveUsage: (usage: GenerationUsage) => void;\n let rejectUsage: (error: Error) => void;\n\n const textPromise = new Promise<string>((resolve, reject) => {\n resolveText = resolve;\n rejectText = reject;\n });\n\n const usagePromise = new Promise<GenerationUsage>((resolve, reject) => {\n resolveUsage = resolve;\n rejectUsage = reject;\n });\n\n // Create wrapped stream that tracks state\n async function* wrappedStream(): AsyncIterable<StreamChunk> {\n try {\n const startTime = performance.now();\n\n for await (const chunk of innerStream) {\n // Check for cancellation\n abortSignal?.throwIfAborted();\n\n accumulatedText += chunk.text;\n\n // Call onChunk callback if provided\n if (onChunk) {\n onChunk(chunk);\n }\n\n if (chunk.done && chunk.usage) {\n finalUsage = {\n ...chunk.usage,\n durationMs: performance.now() - startTime,\n };\n }\n\n yield chunk;\n\n if (chunk.done) {\n break;\n }\n }\n\n // Resolve promises\n resolveText(accumulatedText);\n if (finalUsage) {\n resolveUsage(finalUsage);\n } else {\n // Create approximate usage if not provided by model\n resolveUsage({\n inputTokens: Math.ceil(prompt.length / 4), // Rough estimate\n outputTokens: Math.ceil(accumulatedText.length / 4),\n totalTokens: Math.ceil((prompt.length + accumulatedText.length) / 4),\n durationMs: performance.now() - startTime,\n });\n }\n } catch (error) {\n rejectText(error as Error);\n rejectUsage(error as Error);\n throw error;\n }\n }\n\n return {\n stream: wrappedStream(),\n text: textPromise,\n usage: usagePromise,\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n}\n\n","/**\n * Translation Functions\n *\n * Function-first API for translating text.\n *\n * @packageDocumentation\n */\n\nimport type {\n TranslationModel,\n TranslateOptions,\n TranslateResult,\n TranslateManyOptions,\n TranslateManyResult,\n TranslationModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalTranslationProvider: TranslationModelFactory | null = null;\n\n/**\n * Set the global translation provider for string model ID resolution.\n *\n * @param provider - Factory function to create translation models from string IDs\n *\n * @example\n * ```ts\n * import { setGlobalTranslationProvider } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * setGlobalTranslationProvider((modelId) => transformers.translator(modelId));\n *\n * // Now you can use string model IDs\n * const { translation } = await translate({\n * model: 'Xenova/opus-mt-en-de',\n * text: 'Hello',\n * targetLanguage: 'de',\n * });\n * ```\n */\nexport function setGlobalTranslationProvider(provider: TranslationModelFactory | null): void {\n globalTranslationProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: TranslationModel | string): TranslationModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalTranslationProvider) {\n throw new Error(\n 'No global translation provider configured. ' +\n 'Either pass a TranslationModel object or call setGlobalTranslationProvider() first.'\n );\n }\n\n return globalTranslationProvider(modelOrId);\n}\n\n/**\n * Translate text using a translation model.\n *\n * @param options - Translation options including model, text, and target language\n * @returns Promise with translated text and usage information\n *\n * @example Basic usage\n * ```ts\n * import { translate } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { translation, usage } = await translate({\n * model: transformers.translator('Xenova/opus-mt-en-de'),\n * text: 'Hello, how are you?',\n * targetLanguage: 'de',\n * });\n *\n * console.log(translation); // \"Hallo, wie geht es dir?\"\n * console.log(`Translated in ${usage.durationMs}ms`);\n * ```\n *\n * @example With source language\n * ```ts\n * const { translation } = await translate({\n * model: transformers.translator('Xenova/nllb-200-distilled-600M'),\n * text: 'Bonjour le monde',\n * sourceLanguage: 'fra_Latn',\n * targetLanguage: 'eng_Latn',\n * });\n * ```\n *\n * @throws {Error} If translation fails\n */\nexport async function translate(options: TranslateOptions): Promise<TranslateResult> {\n const {\n model: modelOrId,\n text,\n sourceLanguage,\n targetLanguage,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n // Resolve the model\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n // Retry loop\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Check for cancellation before each attempt\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doTranslate({\n texts: [text],\n sourceLanguage,\n targetLanguage,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n translation: result.translations[0],\n detectedLanguage: result.detectedLanguage,\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry on abort\n if (abortSignal?.aborted) {\n throw error;\n }\n\n // Don't retry on last attempt\n if (attempt === maxRetries) {\n throw error;\n }\n\n // Wait before retry (exponential backoff)\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Translation failed');\n}\n\n/**\n * Translate multiple texts using a translation model.\n *\n * @param options - Translation options including model, texts, and target language\n * @returns Promise with translated texts and usage information\n *\n * @example\n * ```ts\n * const { translations } = await translateMany({\n * model: transformers.translator('Xenova/opus-mt-en-de'),\n * texts: ['Hello', 'Goodbye', 'Thank you'],\n * targetLanguage: 'de',\n * });\n *\n * console.log(translations); // [\"Hallo\", \"Auf Wiedersehen\", \"Danke\"]\n * ```\n */\nexport async function translateMany(options: TranslateManyOptions): Promise<TranslateManyResult> {\n const {\n model: modelOrId,\n texts,\n sourceLanguage,\n targetLanguage,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n // Resolve the model\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n // Retry loop\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n // Check for cancellation before each attempt\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doTranslate({\n texts,\n sourceLanguage,\n targetLanguage,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n translations: result.translations,\n detectedLanguage: result.detectedLanguage,\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry on abort\n if (abortSignal?.aborted) {\n throw error;\n }\n\n // Don't retry on last attempt\n if (attempt === maxRetries) {\n throw error;\n }\n\n // Wait before retry\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Translation failed');\n}\n\n","/**\n * Summarization Functions\n *\n * Function-first API for summarizing text.\n *\n * @packageDocumentation\n */\n\nimport type {\n SummarizationModel,\n SummarizeOptions,\n SummarizeResult,\n SummarizeManyOptions,\n SummarizeManyResult,\n SummarizationModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalSummarizationProvider: SummarizationModelFactory | null = null;\n\n/**\n * Set the global summarization provider for string model ID resolution.\n *\n * @param provider - Factory function to create summarization models from string IDs\n */\nexport function setGlobalSummarizationProvider(provider: SummarizationModelFactory | null): void {\n globalSummarizationProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: SummarizationModel | string): SummarizationModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalSummarizationProvider) {\n throw new Error(\n 'No global summarization provider configured. ' +\n 'Either pass a SummarizationModel object or call setGlobalSummarizationProvider() first.'\n );\n }\n\n return globalSummarizationProvider(modelOrId);\n}\n\n/**\n * Summarize text using a summarization model.\n *\n * @param options - Summarization options including model, text, and length constraints\n * @returns Promise with summary and usage information\n *\n * @example Basic usage\n * ```ts\n * import { summarize } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { summary, usage } = await summarize({\n * model: transformers.summarizer('Xenova/distilbart-cnn-12-6'),\n * text: longArticle,\n * maxLength: 100,\n * });\n *\n * console.log(summary);\n * console.log(`Summarized in ${usage.durationMs}ms`);\n * ```\n *\n * @throws {Error} If summarization fails\n */\nexport async function summarize(options: SummarizeOptions): Promise<SummarizeResult> {\n const {\n model: modelOrId,\n text,\n maxLength = 150,\n minLength = 30,\n mode,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n // Check for cancellation before starting\n abortSignal?.throwIfAborted();\n\n // Resolve the model\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n // Retry loop\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doSummarize({\n texts: [text],\n maxLength,\n minLength,\n mode,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n summary: result.summaries[0],\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Summarization failed');\n}\n\n/**\n * Summarize multiple texts using a summarization model.\n *\n * @param options - Summarization options including model and texts\n * @returns Promise with summaries and usage information\n *\n * @example\n * ```ts\n * const { summaries } = await summarizeMany({\n * model: transformers.summarizer('Xenova/distilbart-cnn-12-6'),\n * texts: [article1, article2, article3],\n * maxLength: 100,\n * });\n * ```\n */\nexport async function summarizeMany(options: SummarizeManyOptions): Promise<SummarizeManyResult> {\n const {\n model: modelOrId,\n texts,\n maxLength = 150,\n minLength = 30,\n mode,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doSummarize({\n texts,\n maxLength,\n minLength,\n mode,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n summaries: result.summaries,\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Summarization failed');\n}\n\n","/**\n * Fill-Mask Functions\n *\n * Function-first API for masked language modeling.\n *\n * @packageDocumentation\n */\n\nimport type {\n FillMaskModel,\n FillMaskOptions,\n FillMaskResult,\n FillMaskManyOptions,\n FillMaskManyResult,\n FillMaskModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalFillMaskProvider: FillMaskModelFactory | null = null;\n\n/**\n * Set the global fill-mask provider for string model ID resolution.\n *\n * @param provider - Factory function to create fill-mask models from string IDs\n */\nexport function setGlobalFillMaskProvider(provider: FillMaskModelFactory | null): void {\n globalFillMaskProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: FillMaskModel | string): FillMaskModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalFillMaskProvider) {\n throw new Error(\n 'No global fill-mask provider configured. ' +\n 'Either pass a FillMaskModel object or call setGlobalFillMaskProvider() first.'\n );\n }\n\n return globalFillMaskProvider(modelOrId);\n}\n\n/**\n * Fill in a masked token using a fill-mask model.\n *\n * @param options - Fill-mask options including model, text, and number of predictions\n * @returns Promise with predictions and usage information\n *\n * @example Basic usage\n * ```ts\n * import { fillMask } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { predictions, usage } = await fillMask({\n * model: transformers.fillMask('Xenova/bert-base-uncased'),\n * text: 'The capital of France is [MASK].',\n * topK: 5,\n * });\n *\n * console.log(predictions[0].token); // \"paris\"\n * console.log(predictions[0].score); // 0.95\n * console.log(`Completed in ${usage.durationMs}ms`);\n * ```\n *\n * @example Autocomplete\n * ```ts\n * const { predictions } = await fillMask({\n * model: transformers.fillMask('Xenova/bert-base-uncased'),\n * text: 'I want to eat [MASK] for dinner.',\n * topK: 10,\n * });\n *\n * const suggestions = predictions.map(p => p.token);\n * ```\n *\n * @throws {Error} If fill-mask fails\n */\nexport async function fillMask(options: FillMaskOptions): Promise<FillMaskResult> {\n const {\n model: modelOrId,\n text,\n topK = 5,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doFillMask({\n texts: [text],\n topK,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n predictions: result.results[0],\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Fill-mask failed');\n}\n\n/**\n * Fill in masked tokens for multiple texts.\n *\n * @param options - Fill-mask options including model and texts\n * @returns Promise with predictions for each text\n *\n * @example\n * ```ts\n * const { results } = await fillMaskMany({\n * model: transformers.fillMask('Xenova/bert-base-uncased'),\n * texts: [\n * 'The [MASK] is blue.',\n * 'I love [MASK] music.',\n * ],\n * topK: 3,\n * });\n *\n * console.log(results[0][0].token); // \"sky\"\n * console.log(results[1][0].token); // \"rock\"\n * ```\n */\nexport async function fillMaskMany(options: FillMaskManyOptions): Promise<FillMaskManyResult> {\n const {\n model: modelOrId,\n texts,\n topK = 5,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doFillMask({\n texts,\n topK,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n results: result.results,\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Fill-mask failed');\n}\n\n","/**\n * Question Answering Functions\n *\n * Function-first API for extractive question answering.\n *\n * @packageDocumentation\n */\n\nimport type {\n QuestionAnsweringModel,\n AnswerQuestionOptions,\n AnswerQuestionResult,\n AnswerQuestionManyOptions,\n AnswerQuestionManyResult,\n QuestionAnsweringModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalQAProvider: QuestionAnsweringModelFactory | null = null;\n\n/**\n * Set the global question answering provider for string model ID resolution.\n *\n * @param provider - Factory function to create QA models from string IDs\n */\nexport function setGlobalQuestionAnsweringProvider(\n provider: QuestionAnsweringModelFactory | null\n): void {\n globalQAProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: QuestionAnsweringModel | string): QuestionAnsweringModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalQAProvider) {\n throw new Error(\n 'No global question answering provider configured. ' +\n 'Either pass a QuestionAnsweringModel object or call setGlobalQuestionAnsweringProvider() first.'\n );\n }\n\n return globalQAProvider(modelOrId);\n}\n\n/**\n * Answer a question based on a context using a QA model.\n *\n * @param options - Question answering options including model, question, and context\n * @returns Promise with extracted answer and usage information\n *\n * @example Basic usage\n * ```ts\n * import { answerQuestion } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { answer, score, usage } = await answerQuestion({\n * model: transformers.questionAnswering('Xenova/distilbert-base-cased-distilled-squad'),\n * question: 'What is the capital of France?',\n * context: 'France is a country in Europe. Its capital is Paris, which is known for the Eiffel Tower.',\n * });\n *\n * console.log(answer); // \"Paris\"\n * console.log(`Confidence: ${(score * 100).toFixed(1)}%`);\n * ```\n *\n * @example Multiple answers\n * ```ts\n * const { answer, allAnswers } = await answerQuestion({\n * model: transformers.questionAnswering('Xenova/distilbert-base-cased-distilled-squad'),\n * question: 'Who invented the telephone?',\n * context: 'Alexander Graham Bell is credited with inventing the telephone. Some argue it was Antonio Meucci.',\n * topK: 3,\n * });\n *\n * console.log('Top answer:', answer);\n * console.log('All answers:', allAnswers);\n * ```\n *\n * @throws {Error} If question answering fails\n */\nexport async function answerQuestion(options: AnswerQuestionOptions): Promise<AnswerQuestionResult> {\n const {\n model: modelOrId,\n question,\n context,\n topK = 1,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doAnswer({\n questions: [{ question, context }],\n topK,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n const topAnswer = result.results[0][0];\n\n return {\n answer: topAnswer.answer,\n score: topAnswer.score,\n start: topAnswer.start,\n end: topAnswer.end,\n allAnswers: topK > 1 ? result.results[0] : undefined,\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Question answering failed');\n}\n\n/**\n * Answer multiple questions based on their contexts.\n *\n * @param options - Question answering options including model and questions\n * @returns Promise with answers for each question\n *\n * @example\n * ```ts\n * const { answers } = await answerQuestionMany({\n * model: transformers.questionAnswering('Xenova/distilbert-base-cased-distilled-squad'),\n * questions: [\n * { question: 'What is the capital?', context: 'The capital of France is Paris.' },\n * { question: 'Who is the president?', context: 'The president is Emmanuel Macron.' },\n * ],\n * });\n *\n * console.log(answers[0][0].answer); // \"Paris\"\n * console.log(answers[1][0].answer); // \"Emmanuel Macron\"\n * ```\n */\nexport async function answerQuestionMany(\n options: AnswerQuestionManyOptions\n): Promise<AnswerQuestionManyResult> {\n const {\n model: modelOrId,\n questions,\n topK = 1,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doAnswer({\n questions,\n topK,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n answers: result.results,\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Question answering failed');\n}\n\n","/**\n * OCR Functions\n *\n * Function-first API for optical character recognition.\n *\n * @packageDocumentation\n */\n\nimport type {\n OCRModel,\n ExtractTextOptions,\n ExtractTextResult,\n ExtractTextManyOptions,\n ExtractTextManyResult,\n OCRModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalOCRProvider: OCRModelFactory | null = null;\n\n/**\n * Set the global OCR provider for string model ID resolution.\n *\n * @param provider - Factory function to create OCR models from string IDs\n */\nexport function setGlobalOCRProvider(provider: OCRModelFactory | null): void {\n globalOCRProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: OCRModel | string): OCRModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalOCRProvider) {\n throw new Error(\n 'No global OCR provider configured. ' +\n 'Either pass an OCRModel object or call setGlobalOCRProvider() first.'\n );\n }\n\n return globalOCRProvider(modelOrId);\n}\n\n/**\n * Extract text from an image using an OCR model.\n *\n * @param options - OCR options including model and image\n * @returns Promise with extracted text and usage information\n *\n * @example Basic usage\n * ```ts\n * import { extractText } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { text, usage } = await extractText({\n * model: transformers.ocr('Xenova/trocr-base-handwritten'),\n * image: imageBlob,\n * });\n *\n * console.log(text);\n * console.log(`Extracted in ${usage.durationMs}ms`);\n * ```\n *\n * @example With region detection\n * ```ts\n * const { text, regions } = await extractText({\n * model: transformers.ocr('Xenova/trocr-base-printed'),\n * image: documentImage,\n * detectRegions: true,\n * });\n *\n * for (const region of regions || []) {\n * console.log(`Found: \"${region.text}\" at (${region.bbox?.x}, ${region.bbox?.y})`);\n * }\n * ```\n *\n * @throws {Error} If OCR fails\n */\nexport async function extractText(options: ExtractTextOptions): Promise<ExtractTextResult> {\n const {\n model: modelOrId,\n image,\n languages,\n detectRegions = false,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doOCR({\n images: [image],\n languages,\n detectRegions,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n text: result.texts[0],\n regions: result.regions?.[0],\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('OCR failed');\n}\n\n/**\n * Extract text from multiple images using an OCR model.\n *\n * @param options - OCR options including model and images\n * @returns Promise with extracted texts\n *\n * @example\n * ```ts\n * const { texts } = await extractTextMany({\n * model: transformers.ocr('Xenova/trocr-base-handwritten'),\n * images: [page1, page2, page3],\n * });\n *\n * const fullDocument = texts.join('\\n\\n');\n * ```\n */\nexport async function extractTextMany(\n options: ExtractTextManyOptions\n): Promise<ExtractTextManyResult> {\n const {\n model: modelOrId,\n images,\n languages,\n detectRegions = false,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doOCR({\n images,\n languages,\n detectRegions,\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n return {\n texts: result.texts,\n regions: result.regions,\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('OCR failed');\n}\n\n","/**\n * Document QA Functions\n *\n * Function-first API for document question answering.\n *\n * @packageDocumentation\n */\n\nimport type {\n DocumentQAModel,\n AskDocumentOptions,\n AskDocumentResult,\n DocumentQAModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalDocumentQAProvider: DocumentQAModelFactory | null = null;\n\n/**\n * Set the global document QA provider for string model ID resolution.\n *\n * @param provider - Factory function to create document QA models from string IDs\n */\nexport function setGlobalDocumentQAProvider(provider: DocumentQAModelFactory | null): void {\n globalDocumentQAProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: DocumentQAModel | string): DocumentQAModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalDocumentQAProvider) {\n throw new Error(\n 'No global document QA provider configured. ' +\n 'Either pass a DocumentQAModel object or call setGlobalDocumentQAProvider() first.'\n );\n }\n\n return globalDocumentQAProvider(modelOrId);\n}\n\n/**\n * Ask a question about a document image.\n *\n * @param options - Document QA options including model, document, and question\n * @returns Promise with answer and usage information\n *\n * @example Basic usage\n * ```ts\n * import { askDocument } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { answer, score, usage } = await askDocument({\n * model: transformers.documentQA('Xenova/donut-base-finetuned-docvqa'),\n * document: invoiceImage,\n * question: 'What is the total amount?',\n * });\n *\n * console.log(answer); // \"$1,234.56\"\n * console.log(`Confidence: ${(score * 100).toFixed(1)}%`);\n * ```\n *\n * @example Form extraction\n * ```ts\n * const { answer } = await askDocument({\n * model: transformers.documentQA('Xenova/donut-base-finetuned-docvqa'),\n * document: formImage,\n * question: 'What is the customer name?',\n * });\n * ```\n *\n * @throws {Error} If document QA fails\n */\nexport async function askDocument(options: AskDocumentOptions): Promise<AskDocumentResult> {\n const {\n model: modelOrId,\n document,\n question,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doAskDocument({\n document,\n questions: [question],\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n const answer = result.answers[0];\n\n return {\n answer: answer.answer,\n score: answer.score,\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Document QA failed');\n}\n","/**\n * Table QA Functions\n *\n * Function-first API for table question answering.\n *\n * @packageDocumentation\n */\n\nimport type {\n TableQAModel,\n AskTableOptions,\n AskTableResult,\n TableQAModelFactory,\n} from './types.js';\n\n// Global provider for string model ID resolution\nlet globalTableQAProvider: TableQAModelFactory | null = null;\n\n/**\n * Set the global table QA provider for string model ID resolution.\n *\n * @param provider - Factory function to create table QA models from string IDs\n */\nexport function setGlobalTableQAProvider(provider: TableQAModelFactory | null): void {\n globalTableQAProvider = provider;\n}\n\n/**\n * Resolve a model from string ID or return the model object.\n */\nfunction resolveModel(modelOrId: TableQAModel | string): TableQAModel {\n if (typeof modelOrId !== 'string') {\n return modelOrId;\n }\n\n if (!globalTableQAProvider) {\n throw new Error(\n 'No global table QA provider configured. ' +\n 'Either pass a TableQAModel object or call setGlobalTableQAProvider() first.'\n );\n }\n\n return globalTableQAProvider(modelOrId);\n}\n\n/**\n * Ask a question about tabular data.\n *\n * @param options - Table QA options including model, table, and question\n * @returns Promise with answer and usage information\n *\n * @example Basic usage\n * ```ts\n * import { askTable } from '@localmode/core';\n * import { transformers } from '@localmode/transformers';\n *\n * const { answer, cells, usage } = await askTable({\n * model: transformers.tableQA('Xenova/tapas-base-finetuned-wtq'),\n * table: {\n * headers: ['Name', 'Age', 'City'],\n * rows: [\n * ['Alice', '30', 'New York'],\n * ['Bob', '25', 'Los Angeles'],\n * ['Charlie', '35', 'Chicago'],\n * ],\n * },\n * question: 'Who is the oldest?',\n * });\n *\n * console.log(answer); // \"Charlie\"\n * ```\n *\n * @example Aggregation queries\n * ```ts\n * const { answer, aggregator } = await askTable({\n * model: transformers.tableQA('Xenova/tapas-base-finetuned-wtq'),\n * table: salesData,\n * question: 'What is the total revenue?',\n * });\n *\n * console.log(`${aggregator}: ${answer}`); // \"SUM: $10,000\"\n * ```\n *\n * @throws {Error} If table QA fails\n */\nexport async function askTable(options: AskTableOptions): Promise<AskTableResult> {\n const {\n model: modelOrId,\n table,\n question,\n abortSignal,\n maxRetries = 2,\n providerOptions,\n } = options;\n\n abortSignal?.throwIfAborted();\n\n const model = resolveModel(modelOrId);\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n abortSignal?.throwIfAborted();\n\n try {\n const startTime = performance.now();\n\n const result = await model.doAskTable({\n table,\n questions: [question],\n abortSignal,\n providerOptions,\n });\n\n const durationMs = performance.now() - startTime;\n\n const answer = result.answers[0];\n\n return {\n answer: answer.answer,\n cells: answer.cells,\n aggregator: answer.aggregator,\n score: answer.score,\n usage: {\n ...result.usage,\n durationMs,\n },\n response: {\n modelId: model.modelId,\n timestamp: new Date(),\n },\n };\n } catch (error) {\n lastError = error as Error;\n\n if (abortSignal?.aborted) {\n throw error;\n }\n\n if (attempt === maxRetries) {\n throw error;\n }\n\n const delay = Math.min(1000 * Math.pow(2, attempt), 10000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new Error('Table QA failed');\n}\n\n","/**\n * RAG (Retrieval-Augmented Generation) Domain Types\n *\n * Types for chunking, BM25 keyword search, hybrid search, and ingestion.\n * All types are zero-dependency and self-contained.\n *\n * @packageDocumentation\n */\n\nimport type { FilterQuery } from '../types.js';\n\n// ═══════════════════════════════════════════════════════════════\n// CHUNKING TYPES\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * Chunking strategy type.\n */\nexport type ChunkStrategy = 'recursive' | 'markdown' | 'code' | 'sentence' | 'paragraph';\n\n/**\n * Base configuration for all chunking strategies.\n */\nexport interface ChunkOptionsBase {\n /** Target size of each chunk in characters (default: 500) */\n size?: number;\n\n /** Overlap between chunks in characters (default: 50) */\n overlap?: number;\n\n /** Minimum chunk size - chunks smaller than this are merged (default: 50) */\n minSize?: number;\n\n /** Whether to trim whitespace from chunks (default: true) */\n trim?: boolean;\n\n /** Whether to keep separators in the chunks (default: false) */\n keepSeparators?: boolean;\n}\n\n/**\n * Configuration for recursive text splitting.\n */\nexport interface RecursiveChunkOptions extends ChunkOptionsBase {\n /** Custom separators in order of priority (default: ['\\n\\n', '\\n', '. ', ' ']) */\n separators?: string[];\n}\n\n/**\n * Configuration for markdown-aware chunking.\n */\nexport interface MarkdownChunkOptions extends ChunkOptionsBase {\n /** Whether to include headers in each chunk for context (default: true) */\n includeHeaders?: boolean;\n\n /** Maximum header level to track (1-6, default: 3) */\n maxHeaderLevel?: number;\n\n /** Whether to preserve code blocks as single chunks (default: true) */\n preserveCodeBlocks?: boolean;\n\n /** Whether to preserve tables as single chunks (default: true) */\n preserveTables?: boolean;\n}\n\n/**\n * Supported programming languages for code-aware chunking.\n */\nexport type CodeLanguage =\n | 'javascript'\n | 'typescript'\n | 'python'\n | 'java'\n | 'csharp'\n | 'cpp'\n | 'go'\n | 'rust'\n | 'ruby'\n | 'php'\n | 'swift'\n | 'kotlin'\n | 'generic';\n\n/**\n * Configuration for code-aware chunking.\n */\nexport interface CodeChunkOptions extends ChunkOptionsBase {\n /** Programming language (auto-detected if not specified) */\n language?: CodeLanguage;\n\n /** Whether to preserve function/class bodies as single chunks when possible */\n preserveBlocks?: boolean;\n\n /** Whether to include import statements in each chunk for context */\n includeImports?: boolean;\n\n /** Maximum lines per chunk (overrides size if specified) */\n maxLines?: number;\n}\n\n/**\n * Combined chunk options with strategy selection.\n */\nexport type ChunkOptions =\n | ({ strategy: 'recursive' } & RecursiveChunkOptions)\n | ({ strategy: 'markdown' } & MarkdownChunkOptions)\n | ({ strategy: 'code' } & CodeChunkOptions)\n | ({ strategy: 'sentence' } & ChunkOptionsBase)\n | ({ strategy: 'paragraph' } & ChunkOptionsBase);\n\n/**\n * A single chunk of text with metadata about its position.\n */\nexport interface Chunk {\n /** The chunk text content */\n text: string;\n\n /** Character offset of the chunk start in the original text */\n start: number;\n\n /** Character offset of the chunk end in the original text */\n end: number;\n\n /** Chunk index (0-based) */\n index: number;\n\n /** Additional metadata from the chunking process */\n metadata?: ChunkMetadata;\n}\n\n/**\n * Metadata attached to chunks during processing.\n */\nexport interface ChunkMetadata {\n /** For markdown: the header path (e.g., \"# Title > ## Section\") */\n headerPath?: string;\n\n /** For markdown: header levels present (e.g., [1, 2]) */\n headerLevels?: number[];\n\n /** For code: the language detected or specified */\n language?: CodeLanguage;\n\n /** For code: the function/class name if this chunk is within one */\n scopeName?: string;\n\n /** For code: the scope type (function, class, method, etc.) */\n scopeType?: string;\n\n /** Whether this chunk contains a code block */\n isCodeBlock?: boolean;\n\n /** Whether this chunk contains a table */\n isTable?: boolean;\n}\n\n/**\n * Interface for a text chunker.\n */\nexport interface Chunker {\n /** Chunk text into smaller pieces */\n chunk(text: string, options?: ChunkOptionsBase): Chunk[];\n\n /** Optional: Estimate chunk count without splitting */\n estimateChunks?(text: string, options?: ChunkOptionsBase): number;\n}\n\n// ═══════════════════════════════════════════════════════════════\n// BM25 / KEYWORD SEARCH TYPES\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * Configuration for BM25 scoring.\n */\nexport interface BM25Options {\n /** Term frequency saturation parameter (default: 1.2) */\n k1?: number;\n\n /** Document length normalization parameter (default: 0.75) */\n b?: number;\n\n /** Minimum token length to index (default: 2) */\n minTokenLength?: number;\n\n /** Stop words to exclude from indexing */\n stopWords?: Set<string> | string[];\n\n /** Custom tokenizer function */\n tokenize?: (text: string) => string[];\n\n /** Whether to stem tokens (default: false, uses simple lowercasing) */\n stemming?: boolean;\n}\n\n/**\n * A document indexed for BM25 search.\n */\nexport interface BM25Document {\n /** Document ID */\n id: string;\n\n /** Tokenized document content */\n tokens: string[];\n\n /** Token frequencies */\n termFreqs: Map<string, number>;\n\n /** Document length (number of tokens) */\n length: number;\n\n /** Original text (optional, for retrieval) */\n text?: string;\n}\n\n/**\n * BM25 index state for serialization.\n */\nexport interface BM25IndexState {\n /** Total number of documents */\n docCount: number;\n\n /** Average document length */\n avgDocLength: number;\n\n /** Document frequency for each term */\n docFreqs: Record<string, number>;\n\n /** All indexed documents */\n documents: Array<{\n id: string;\n tokens: string[];\n length: number;\n text?: string;\n }>;\n}\n\n/**\n * Result from BM25 search.\n */\nexport interface BM25Result {\n /** Document ID */\n id: string;\n\n /** BM25 score */\n score: number;\n\n /** Original text (if stored) */\n text?: string;\n}\n\n/**\n * Interface for BM25 index.\n */\nexport interface BM25Index {\n /** Add a document to the index */\n add(id: string, text: string): void;\n\n /** Add multiple documents */\n addMany(documents: Array<{ id: string; text: string }>): void;\n\n /** Search the index */\n search(query: string, k?: number): BM25Result[];\n\n /** Remove a document from the index */\n remove(id: string): void;\n\n /** Clear the index */\n clear(): void;\n\n /** Get index statistics */\n stats(): { docCount: number; avgDocLength: number; vocabularySize: number };\n\n /** Serialize the index to JSON */\n toJSON(): BM25IndexState;\n\n /** Load from serialized state */\n fromJSON(state: BM25IndexState): void;\n}\n\n// ═══════════════════════════════════════════════════════════════\n// HYBRID SEARCH TYPES\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * Result from vector search (for hybrid search input).\n */\nexport interface VectorSearchResult {\n /** Document ID */\n id: string;\n\n /** Similarity score (0-1) */\n score: number;\n\n /** Document metadata */\n metadata?: Record<string, unknown>;\n\n /** Document vector (if requested) */\n vector?: Float32Array;\n}\n\n/**\n * Configuration for hybrid search.\n */\nexport interface HybridSearchOptions {\n /** Number of results to return (default: 10) */\n k?: number;\n\n /** Weight for vector search scores (0-1, default: 0.7) */\n vectorWeight?: number;\n\n /** Weight for keyword/BM25 scores (0-1, default: 0.3) */\n keywordWeight?: number;\n\n /** Whether to normalize scores before combining (default: true) */\n normalizeScores?: boolean;\n\n /** Minimum score threshold for final results */\n threshold?: number;\n\n /** Metadata filter to apply */\n filter?: FilterQuery;\n\n /** Whether to include vectors in results (default: false) */\n includeVectors?: boolean;\n\n /** Number of candidates to fetch from each search before combining (default: k * 3) */\n fetchK?: number;\n\n /** BM25 configuration */\n bm25Options?: BM25Options;\n}\n\n/**\n * Result from hybrid search.\n */\nexport interface HybridSearchResult extends VectorSearchResult {\n /** Vector similarity score (before weighting) */\n vectorScore?: number;\n\n /** BM25/keyword score (before weighting) */\n keywordScore?: number;\n\n /** Text content (if stored) */\n text?: string;\n}\n\n/**\n * Options for the reciprocalRankFusion function.\n */\nexport interface RRFOptions {\n /** RRF constant k (default: 60) */\n k?: number;\n\n /** Number of results to return */\n topK?: number;\n}\n\n// ═══════════════════════════════════════════════════════════════\n// INGESTION TYPES\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * A source document for ingestion.\n */\nexport interface SourceDocument {\n /** Unique identifier (auto-generated if not provided) */\n id?: string;\n\n /** Text content to chunk and ingest */\n text: string;\n\n /** Metadata to attach to all chunks from this document */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Configuration for batch ingestion.\n */\nexport interface IngestOptions {\n /** Chunking configuration */\n chunking?: ChunkOptions | { strategy: ChunkStrategy };\n\n /** Batch size for database operations (default: 100) */\n batchSize?: number;\n\n /** Progress callback */\n onProgress?: (progress: IngestProgress) => void;\n\n /** ID prefix for generated chunk IDs */\n idPrefix?: string;\n\n /** Whether to generate embeddings */\n generateEmbeddings?: boolean;\n\n /** Custom embedder function (if generateEmbeddings is true) */\n embedder?: (texts: string[]) => Promise<Float32Array[]>;\n\n /** Whether to build BM25 index for hybrid search (default: false) */\n buildBM25Index?: boolean;\n\n /** BM25 configuration (if buildBM25Index is true) */\n bm25Options?: BM25Options;\n\n /** AbortSignal for cancellation */\n abortSignal?: AbortSignal;\n}\n\n/**\n * Progress information during ingestion.\n */\nexport interface IngestProgress {\n /** Current phase */\n phase: 'chunking' | 'embedding' | 'indexing' | 'complete';\n\n /** Documents processed so far */\n documentsProcessed: number;\n\n /** Total documents to process */\n totalDocuments: number;\n\n /** Chunks processed so far */\n chunksProcessed: number;\n\n /** Total chunks generated */\n totalChunks: number;\n\n /** Current batch number */\n currentBatch: number;\n\n /** Total batches */\n totalBatches: number;\n}\n\n/**\n * Result from ingestion.\n */\nexport interface IngestResult {\n /** Number of source documents processed */\n documentsProcessed: number;\n\n /** Number of chunks created */\n chunksCreated: number;\n\n /** IDs of created chunks */\n chunkIds: string[];\n\n /** BM25 index (if buildBM25Index was true) */\n bm25Index?: BM25Index;\n\n /** Time taken in milliseconds */\n duration: number;\n}\n\n// ═══════════════════════════════════════════════════════════════\n// DOCUMENT LOADER TYPES (Re-exported from loaders module)\n// ═══════════════════════════════════════════════════════════════\n\nexport type {\n LoaderSource,\n LoadedDocument,\n LoaderOptions,\n LoaderResult,\n DocumentLoader,\n} from '../loaders/types.js';\n\n// ═══════════════════════════════════════════════════════════════\n// DEFAULT CONFIGURATION\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * Default chunking options.\n */\nexport const DEFAULT_CHUNK_OPTIONS: Required<ChunkOptionsBase> = {\n size: 500,\n overlap: 50,\n minSize: 50,\n trim: true,\n keepSeparators: false,\n};\n\n/**\n * Default recursive chunking separators.\n */\nexport const DEFAULT_RECURSIVE_SEPARATORS = [\n '\\n\\n\\n', // Multiple blank lines\n '\\n\\n', // Paragraphs\n '\\n', // Lines\n '. ', // Sentences\n '? ', // Questions\n '! ', // Exclamations\n '; ', // Semicolons\n ', ', // Commas\n ' ', // Words\n '', // Characters (last resort)\n];\n\n/**\n * Default BM25 options.\n */\nexport const DEFAULT_BM25_OPTIONS: Required<Omit<BM25Options, 'tokenize' | 'stopWords'>> = {\n k1: 1.2,\n b: 0.75,\n minTokenLength: 2,\n stemming: false,\n};\n\n/**\n * Default English stop words.\n */\nexport const ENGLISH_STOP_WORDS = new Set([\n 'a',\n 'an',\n 'and',\n 'are',\n 'as',\n 'at',\n 'be',\n 'by',\n 'for',\n 'from',\n 'has',\n 'he',\n 'in',\n 'is',\n 'it',\n 'its',\n 'of',\n 'on',\n 'or',\n 'that',\n 'the',\n 'to',\n 'was',\n 'were',\n 'will',\n 'with',\n 'the',\n 'this',\n 'but',\n 'they',\n 'have',\n 'had',\n 'what',\n 'when',\n 'where',\n 'who',\n 'which',\n 'why',\n 'how',\n 'all',\n 'each',\n 'every',\n 'both',\n 'few',\n 'more',\n 'most',\n 'other',\n 'some',\n 'such',\n 'no',\n 'nor',\n 'not',\n 'only',\n 'own',\n 'same',\n 'so',\n 'than',\n 'too',\n 'very',\n 'can',\n 'just',\n 'should',\n 'now',\n 'i',\n 'you',\n 'your',\n 'we',\n 'our',\n 'my',\n 'me',\n 'him',\n 'her',\n]);\n\n/**\n * Default hybrid search options.\n */\nexport const DEFAULT_HYBRID_OPTIONS: Required<Omit<HybridSearchOptions, 'filter' | 'bm25Options'>> =\n {\n k: 10,\n vectorWeight: 0.7,\n keywordWeight: 0.3,\n normalizeScores: true,\n threshold: 0,\n includeVectors: false,\n fetchK: 30,\n };\n\n/**\n * Default ingest options.\n */\nexport const DEFAULT_INGEST_OPTIONS = {\n batchSize: 100,\n idPrefix: 'chunk',\n generateEmbeddings: false,\n buildBM25Index: false,\n};\n","/**\n * Recursive text splitter for chunking documents.\n *\n * Recursively splits text using a hierarchy of separators,\n * starting with the most meaningful (paragraphs, sentences)\n * and falling back to less meaningful ones (words, characters).\n *\n * @packageDocumentation\n */\n\nimport type { Chunk, RecursiveChunkOptions } from '../types.js';\nimport { DEFAULT_CHUNK_OPTIONS, DEFAULT_RECURSIVE_SEPARATORS } from '../types.js';\n\n/**\n * Split text recursively using a hierarchy of separators.\n *\n * @param text - The text to split\n * @param options - Chunking configuration\n * @returns Array of chunks with position metadata\n *\n * @example\n * ```typescript\n * const chunks = recursiveChunk(longText, {\n * size: 500,\n * overlap: 50,\n * separators: ['\\n\\n', '\\n', '. ', ' '],\n * });\n * ```\n */\nexport function recursiveChunk(text: string, options: RecursiveChunkOptions = {}): Chunk[] {\n const {\n size = DEFAULT_CHUNK_OPTIONS.size,\n overlap = DEFAULT_CHUNK_OPTIONS.overlap,\n minSize = DEFAULT_CHUNK_OPTIONS.minSize,\n trim = DEFAULT_CHUNK_OPTIONS.trim,\n keepSeparators = DEFAULT_CHUNK_OPTIONS.keepSeparators,\n separators = DEFAULT_RECURSIVE_SEPARATORS,\n } = options;\n\n if (!text || text.length === 0) {\n return [];\n }\n\n // Preserve paragraph structure by NOT collapsing newlines before splitting\n // Only trim leading/trailing whitespace to preserve internal structure\n const normalizedText = trim ? text.trim() : text;\n\n if (normalizedText.length === 0) {\n return [];\n }\n\n // If text is smaller than target size, return as single chunk\n // For small documents, we don't apply minSize filter (that's for merge filtering)\n if (normalizedText.length <= size) {\n return [\n {\n text: normalizedText,\n start: 0,\n end: text.length,\n index: 0,\n },\n ];\n }\n\n // Split recursively\n const splits = splitRecursive(normalizedText, separators, size, keepSeparators);\n\n // Merge splits into chunks with overlap\n const chunks = mergeWithOverlap(splits, size, overlap, minSize, trim);\n\n // Calculate positions and assign indices\n const result = assignPositions(normalizedText, chunks, trim);\n\n // Safety net: if no chunks created but we have text, create fallback chunks\n if (result.length === 0 && normalizedText.length > 0) {\n return createFallbackChunks(normalizedText, size, overlap);\n }\n\n return result;\n}\n\n/**\n * Create fallback chunks by simply splitting text at size boundaries.\n * Used when the recursive algorithm fails to produce chunks.\n */\nfunction createFallbackChunks(text: string, size: number, overlap: number): Chunk[] {\n const chunks: Chunk[] = [];\n const step = Math.max(size - overlap, 1);\n\n for (let i = 0; i < text.length; i += step) {\n const chunkText = text.slice(i, i + size).trim();\n if (chunkText.length > 0) {\n chunks.push({\n text: chunkText,\n start: i,\n end: Math.min(i + size, text.length),\n index: chunks.length,\n });\n }\n // Avoid infinite loop if step is 0\n if (step === 0) break;\n }\n\n return chunks;\n}\n\n/**\n * Internal split state tracking position.\n */\ninterface Split {\n text: string;\n start: number;\n}\n\n/**\n * Recursively split text using separators.\n */\nfunction splitRecursive(\n text: string,\n separators: string[],\n targetSize: number,\n keepSeparators: boolean,\n currentStart = 0\n): Split[] {\n if (text.length <= targetSize || separators.length === 0) {\n return [{ text, start: currentStart }];\n }\n\n const separator = separators[0];\n const remainingSeparators = separators.slice(1);\n\n // Handle empty separator (character-level split)\n if (separator === '') {\n return splitByCharacters(text, targetSize, currentStart);\n }\n\n const parts = splitBySeparator(text, separator, keepSeparators);\n\n // If no split occurred, try next separator\n if (parts.length <= 1) {\n return splitRecursive(text, remainingSeparators, targetSize, keepSeparators, currentStart);\n }\n\n // Calculate starting positions for each part\n const splits: Split[] = [];\n let position = currentStart;\n\n for (const part of parts) {\n if (part.length <= targetSize) {\n splits.push({ text: part, start: position });\n } else {\n // Recursively split this part\n const subSplits = splitRecursive(\n part,\n remainingSeparators,\n targetSize,\n keepSeparators,\n position\n );\n splits.push(...subSplits);\n }\n position += part.length + (keepSeparators ? 0 : separator.length);\n }\n\n return splits;\n}\n\n/**\n * Split text by a separator.\n */\nfunction splitBySeparator(text: string, separator: string, keepSeparators: boolean): string[] {\n if (keepSeparators) {\n // Keep separators at the end of each split\n const parts: string[] = [];\n let remaining = text;\n let lastIndex = 0;\n\n while (true) {\n const index = remaining.indexOf(separator, lastIndex);\n if (index === -1) {\n if (lastIndex < remaining.length) {\n parts.push(remaining.slice(lastIndex));\n }\n break;\n }\n parts.push(remaining.slice(lastIndex, index + separator.length));\n lastIndex = index + separator.length;\n }\n\n return parts;\n }\n\n return text.split(separator);\n}\n\n/**\n * Split by characters as a last resort.\n */\nfunction splitByCharacters(text: string, targetSize: number, currentStart: number): Split[] {\n const splits: Split[] = [];\n let position = 0;\n\n while (position < text.length) {\n const end = Math.min(position + targetSize, text.length);\n splits.push({\n text: text.slice(position, end),\n start: currentStart + position,\n });\n position = end;\n }\n\n return splits;\n}\n\n/**\n * Merge splits into chunks with overlap.\n */\nfunction mergeWithOverlap(\n splits: Split[],\n targetSize: number,\n overlap: number,\n minSize: number,\n trim: boolean\n): string[] {\n if (splits.length === 0) {\n return [];\n }\n\n const chunks: string[] = [];\n let currentChunk = '';\n\n for (const split of splits) {\n const text = trim ? split.text.trim() : split.text;\n\n if (!text) continue;\n\n // If adding this split would exceed target size\n if (currentChunk.length + text.length + 1 > targetSize && currentChunk.length > 0) {\n // Save current chunk\n chunks.push(currentChunk);\n\n // Start new chunk with overlap from previous\n if (overlap > 0) {\n const overlapBuffer = getOverlapText(currentChunk, overlap);\n currentChunk = overlapBuffer + (overlapBuffer ? ' ' : '') + text;\n } else {\n currentChunk = text;\n }\n } else {\n // Add to current chunk\n currentChunk += (currentChunk ? ' ' : '') + text;\n }\n }\n\n // Add final chunk - always add if there's content, regardless of minSize\n // minSize is meant for merging small intermediate chunks, not for rejecting content\n if (currentChunk) {\n const trimmedFinal = trim ? currentChunk.trim() : currentChunk;\n if (trimmedFinal.length > 0) {\n if (trimmedFinal.length < minSize && chunks.length > 0) {\n // Merge small final chunk with previous if it's too small\n chunks[chunks.length - 1] += ' ' + trimmedFinal;\n } else {\n chunks.push(trimmedFinal);\n }\n }\n }\n\n return chunks;\n}\n\n/**\n * Get overlap text from the end of a chunk.\n */\nfunction getOverlapText(chunk: string, overlap: number): string {\n if (chunk.length <= overlap) {\n return chunk;\n }\n\n // Try to break at a word boundary\n const overlapStart = chunk.length - overlap;\n const wordBreak = chunk.indexOf(' ', overlapStart);\n\n if (wordBreak !== -1 && wordBreak < chunk.length) {\n return chunk.slice(wordBreak + 1);\n }\n\n return chunk.slice(overlapStart);\n}\n\n/**\n * Normalize whitespace within a chunk text.\n * Collapses multiple spaces/newlines to single space while preserving readability.\n */\nfunction normalizeChunkText(text: string): string {\n return text.replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * Assign positions to chunks by finding them in the original text.\n */\nfunction assignPositions(originalText: string, chunks: string[], trim: boolean): Chunk[] {\n const result: Chunk[] = [];\n let searchStart = 0;\n\n for (let i = 0; i < chunks.length; i++) {\n // Normalize whitespace within each chunk for clean output\n const chunkText = trim ? normalizeChunkText(chunks[i]) : chunks[i];\n\n // Find the chunk in the original text\n // First try to find exact match\n let start = findChunkPosition(originalText, chunkText, searchStart);\n\n // If not found, try finding the first part of the chunk\n if (start === -1) {\n const firstPart = chunkText.slice(0, Math.min(50, chunkText.length));\n start = findChunkPosition(originalText, firstPart, searchStart);\n }\n\n // If still not found, use estimated position\n if (start === -1) {\n start = searchStart;\n }\n\n const end = Math.min(start + chunkText.length, originalText.length);\n\n result.push({\n text: chunkText,\n start,\n end,\n index: i,\n });\n\n // Move search start forward, accounting for overlap\n searchStart = Math.max(start + 1, end - chunkText.length / 2);\n }\n\n return result;\n}\n\n/**\n * Find the position of a chunk in the original text.\n */\nfunction findChunkPosition(text: string, chunk: string, startFrom: number): number {\n // First try exact match\n let pos = text.indexOf(chunk, startFrom);\n if (pos !== -1) {\n return pos;\n }\n\n // Try normalized match (collapse whitespace)\n const normalizedChunk = chunk.replace(/\\s+/g, ' ').trim();\n const normalizedText = text.slice(startFrom).replace(/\\s+/g, ' ');\n pos = normalizedText.indexOf(normalizedChunk);\n\n if (pos !== -1) {\n // Map back to original position (approximate)\n return startFrom + pos;\n }\n\n return -1;\n}\n\n/**\n * Create a recursive chunker function with preset options.\n */\nexport function createRecursiveChunker(\n defaultOptions: RecursiveChunkOptions = {}\n): (text: string, options?: RecursiveChunkOptions) => Chunk[] {\n return (text: string, options: RecursiveChunkOptions = {}) =>\n recursiveChunk(text, { ...defaultOptions, ...options });\n}\n","/**\n * Markdown-aware text chunker.\n *\n * Intelligently splits markdown documents while preserving:\n * - Header context (includes parent headers in chunks)\n * - Code blocks as single units\n * - Tables as single units\n * - List structure\n *\n * @packageDocumentation\n */\n\nimport type { Chunk, MarkdownChunkOptions, ChunkMetadata, CodeLanguage } from '../types.js';\nimport { DEFAULT_CHUNK_OPTIONS } from '../types.js';\n\n/**\n * Parsed markdown element types.\n */\ntype MarkdownElementType =\n | 'header'\n | 'paragraph'\n | 'code_block'\n | 'table'\n | 'list'\n | 'blockquote'\n | 'horizontal_rule'\n | 'blank';\n\n/**\n * A parsed markdown element.\n */\ninterface MarkdownElement {\n type: MarkdownElementType;\n content: string;\n start: number;\n end: number;\n level?: number; // For headers\n language?: string; // For code blocks\n headerPath?: string[]; // Current header context\n}\n\n/**\n * Split markdown text into chunks while preserving structure.\n *\n * @param text - Markdown text to split\n * @param options - Chunking configuration\n * @returns Array of chunks with markdown metadata\n *\n * @example\n * ```typescript\n * const chunks = markdownChunk(markdown, {\n * size: 500,\n * includeHeaders: true,\n * preserveCodeBlocks: true,\n * });\n *\n * // Chunks include header context:\n * // chunk.metadata.headerPath = \"# Main Title > ## Section\"\n * ```\n */\nexport function markdownChunk(text: string, options: MarkdownChunkOptions = {}): Chunk[] {\n const {\n size = DEFAULT_CHUNK_OPTIONS.size,\n overlap = DEFAULT_CHUNK_OPTIONS.overlap,\n minSize = DEFAULT_CHUNK_OPTIONS.minSize,\n trim = DEFAULT_CHUNK_OPTIONS.trim,\n includeHeaders = true,\n maxHeaderLevel = 3,\n preserveCodeBlocks = true,\n preserveTables = true,\n } = options;\n\n if (!text || text.length === 0) {\n return [];\n }\n\n // Parse markdown into elements\n const elements = parseMarkdown(text);\n\n // Build chunks respecting structure\n const chunks = buildChunks(elements, {\n size,\n overlap,\n minSize,\n trim,\n includeHeaders,\n maxHeaderLevel,\n preserveCodeBlocks,\n preserveTables,\n });\n\n return chunks;\n}\n\n/**\n * Parse markdown into structural elements.\n */\nfunction parseMarkdown(text: string): MarkdownElement[] {\n const elements: MarkdownElement[] = [];\n const lines = text.split('\\n');\n let position = 0;\n let i = 0;\n const headerStack: string[] = [];\n\n while (i < lines.length) {\n const line = lines[i];\n const lineStart = position;\n\n // Check for code blocks (fenced)\n if (line.startsWith('```') || line.startsWith('~~~')) {\n const fence = line.slice(0, 3);\n const language = line.slice(3).trim();\n const codeStart = position;\n let codeContent = line + '\\n';\n position += line.length + 1;\n i++;\n\n // Find closing fence\n while (i < lines.length && !lines[i].startsWith(fence)) {\n codeContent += lines[i] + '\\n';\n position += lines[i].length + 1;\n i++;\n }\n\n // Include closing fence\n if (i < lines.length) {\n codeContent += lines[i];\n position += lines[i].length + 1;\n i++;\n }\n\n elements.push({\n type: 'code_block',\n content: codeContent,\n start: codeStart,\n end: position,\n language,\n headerPath: [...headerStack],\n });\n continue;\n }\n\n // Check for headers\n const headerMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (headerMatch) {\n const level = headerMatch[1].length;\n const headerText = headerMatch[2];\n\n // Update header stack\n while (headerStack.length >= level) {\n headerStack.pop();\n }\n headerStack.push(`${'#'.repeat(level)} ${headerText}`);\n\n elements.push({\n type: 'header',\n content: line,\n start: lineStart,\n end: position + line.length,\n level,\n headerPath: [...headerStack],\n });\n\n position += line.length + 1;\n i++;\n continue;\n }\n\n // Check for tables\n if (line.includes('|') && i + 1 < lines.length && lines[i + 1].match(/^\\|?[\\s\\-:|]+\\|/)) {\n const tableStart = position;\n let tableContent = line + '\\n';\n position += line.length + 1;\n i++;\n\n // Include table rows\n while (i < lines.length && (lines[i].includes('|') || lines[i].match(/^\\|?[\\s\\-:|]+\\|/))) {\n tableContent += lines[i] + '\\n';\n position += lines[i].length + 1;\n i++;\n }\n\n elements.push({\n type: 'table',\n content: tableContent.trimEnd(),\n start: tableStart,\n end: position,\n headerPath: [...headerStack],\n });\n continue;\n }\n\n // Check for horizontal rules\n if (line.match(/^[-*_]{3,}\\s*$/)) {\n elements.push({\n type: 'horizontal_rule',\n content: line,\n start: lineStart,\n end: position + line.length,\n headerPath: [...headerStack],\n });\n position += line.length + 1;\n i++;\n continue;\n }\n\n // Check for blockquotes\n if (line.startsWith('>')) {\n const quoteStart = position;\n let quoteContent = line + '\\n';\n position += line.length + 1;\n i++;\n\n while (\n i < lines.length &&\n (lines[i].startsWith('>') || (lines[i].trim() && !lines[i].match(/^#+\\s/)))\n ) {\n if (!lines[i].startsWith('>') && lines[i].trim()) {\n break; // End of blockquote\n }\n quoteContent += lines[i] + '\\n';\n position += lines[i].length + 1;\n i++;\n }\n\n elements.push({\n type: 'blockquote',\n content: quoteContent.trimEnd(),\n start: quoteStart,\n end: position,\n headerPath: [...headerStack],\n });\n continue;\n }\n\n // Check for lists\n if (line.match(/^[\\s]*[-*+]\\s/) || line.match(/^[\\s]*\\d+\\.\\s/)) {\n const listStart = position;\n let listContent = line + '\\n';\n position += line.length + 1;\n i++;\n\n // Continue while we have list items or indented content\n while (i < lines.length) {\n const nextLine = lines[i];\n if (\n nextLine.match(/^[\\s]*[-*+]\\s/) ||\n nextLine.match(/^[\\s]*\\d+\\.\\s/) ||\n (nextLine.startsWith(' ') && listContent.endsWith('\\n'))\n ) {\n listContent += nextLine + '\\n';\n position += nextLine.length + 1;\n i++;\n } else if (nextLine.trim() === '') {\n // Blank line might continue the list\n if (\n i + 1 < lines.length &&\n (lines[i + 1].match(/^[\\s]*[-*+]\\s/) || lines[i + 1].match(/^[\\s]*\\d+\\.\\s/))\n ) {\n listContent += nextLine + '\\n';\n position += nextLine.length + 1;\n i++;\n } else {\n break;\n }\n } else {\n break;\n }\n }\n\n elements.push({\n type: 'list',\n content: listContent.trimEnd(),\n start: listStart,\n end: position,\n headerPath: [...headerStack],\n });\n continue;\n }\n\n // Check for blank lines\n if (line.trim() === '') {\n elements.push({\n type: 'blank',\n content: line,\n start: lineStart,\n end: position + line.length,\n headerPath: [...headerStack],\n });\n position += line.length + 1;\n i++;\n continue;\n }\n\n // Regular paragraph\n const paraStart = position;\n let paraContent = line + '\\n';\n position += line.length + 1;\n i++;\n\n // Continue paragraph until blank line or structural element\n while (i < lines.length) {\n const nextLine = lines[i];\n if (\n nextLine.trim() === '' ||\n nextLine.match(/^#{1,6}\\s/) ||\n nextLine.startsWith('```') ||\n nextLine.startsWith('~~~') ||\n nextLine.match(/^[-*_]{3,}\\s*$/) ||\n nextLine.startsWith('>') ||\n nextLine.match(/^[\\s]*[-*+]\\s/) ||\n nextLine.match(/^[\\s]*\\d+\\.\\s/) ||\n (nextLine.includes('|') && i + 1 < lines.length && lines[i + 1]?.match(/^\\|?[\\s\\-:|]+\\|/))\n ) {\n break;\n }\n paraContent += nextLine + '\\n';\n position += nextLine.length + 1;\n i++;\n }\n\n elements.push({\n type: 'paragraph',\n content: paraContent.trimEnd(),\n start: paraStart,\n end: position,\n headerPath: [...headerStack],\n });\n }\n\n return elements;\n}\n\n/**\n * Build chunks from parsed elements.\n */\nfunction buildChunks(\n elements: MarkdownElement[],\n options: {\n size: number;\n overlap: number;\n minSize: number;\n trim: boolean;\n includeHeaders: boolean;\n maxHeaderLevel: number;\n preserveCodeBlocks: boolean;\n preserveTables: boolean;\n }\n): Chunk[] {\n const chunks: Chunk[] = [];\n let currentChunk = '';\n let currentStart = -1;\n let currentHeaders: string[] = [];\n let chunkIndex = 0;\n\n const finalizeChunk = () => {\n if (currentChunk.length >= options.minSize) {\n const text = options.trim ? currentChunk.trim() : currentChunk;\n if (text.length >= options.minSize) {\n const metadata: ChunkMetadata = {};\n\n if (currentHeaders.length > 0) {\n metadata.headerPath = currentHeaders.join(' > ');\n metadata.headerLevels = currentHeaders.map((h) => {\n const match = h.match(/^(#+)/);\n return match ? match[1].length : 0;\n });\n }\n\n chunks.push({\n text,\n start: currentStart,\n end: currentStart + currentChunk.length,\n index: chunkIndex++,\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\n });\n }\n }\n currentChunk = '';\n currentStart = -1;\n };\n\n for (const element of elements) {\n // Skip blank lines\n if (element.type === 'blank') {\n continue;\n }\n\n // Update header context\n if (element.headerPath && element.headerPath.length > 0) {\n currentHeaders = element.headerPath.filter((h) => {\n const level = (h.match(/^(#+)/) || ['', ''])[1].length;\n return level <= options.maxHeaderLevel;\n });\n }\n\n // Handle elements that should be preserved as single units\n if (\n (element.type === 'code_block' && options.preserveCodeBlocks) ||\n (element.type === 'table' && options.preserveTables)\n ) {\n // Finalize current chunk first\n if (currentChunk) {\n finalizeChunk();\n }\n\n // Add as its own chunk (even if larger than target size)\n const metadata: ChunkMetadata = {\n headerPath: currentHeaders.length > 0 ? currentHeaders.join(' > ') : undefined,\n isCodeBlock: element.type === 'code_block',\n isTable: element.type === 'table',\n };\n\n if (element.type === 'code_block' && element.language) {\n metadata.language = element.language as CodeLanguage;\n }\n\n chunks.push({\n text: options.trim ? element.content.trim() : element.content,\n start: element.start,\n end: element.end,\n index: chunkIndex++,\n metadata,\n });\n continue;\n }\n\n // Headers start new chunks if includeHeaders is true\n if (element.type === 'header' && options.includeHeaders) {\n if (currentChunk) {\n finalizeChunk();\n }\n currentChunk = element.content;\n currentStart = element.start;\n continue;\n }\n\n // Check if adding this element would exceed target size\n const elementContent = element.content;\n const newLength = currentChunk.length + (currentChunk ? 2 : 0) + elementContent.length;\n\n if (newLength > options.size && currentChunk.length > 0) {\n // Finalize current chunk\n finalizeChunk();\n\n // Start new chunk with header context if enabled\n if (options.includeHeaders && currentHeaders.length > 0) {\n currentChunk = currentHeaders.join('\\n\\n') + '\\n\\n' + elementContent;\n } else {\n currentChunk = elementContent;\n }\n currentStart = element.start;\n } else {\n // Add to current chunk\n if (currentChunk) {\n currentChunk += '\\n\\n' + elementContent;\n } else {\n currentChunk = elementContent;\n currentStart = element.start;\n }\n }\n }\n\n // Finalize last chunk\n if (currentChunk) {\n finalizeChunk();\n }\n\n // Fallback: if no chunks were created but we had content, return the whole text as one chunk\n // This handles small documents that don't meet minSize but shouldn't be discarded\n if (chunks.length === 0 && elements.length > 0) {\n const allContent = elements\n .filter((e) => e.type !== 'blank')\n .map((e) => e.content)\n .join('\\n\\n');\n\n if (allContent.trim().length > 0) {\n const headerPath = elements.find((e) => e.headerPath && e.headerPath.length > 0)?.headerPath;\n const metadata: ChunkMetadata = {};\n\n if (headerPath && headerPath.length > 0) {\n metadata.headerPath = headerPath.join(' > ');\n }\n\n chunks.push({\n text: options.trim ? allContent.trim() : allContent,\n start: 0,\n end: allContent.length,\n index: 0,\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\n });\n }\n }\n\n return chunks;\n}\n\n/**\n * Create a markdown chunker with preset options.\n */\nexport function createMarkdownChunker(\n defaultOptions: MarkdownChunkOptions = {}\n): (text: string, options?: MarkdownChunkOptions) => Chunk[] {\n return (text: string, options: MarkdownChunkOptions = {}) =>\n markdownChunk(text, { ...defaultOptions, ...options });\n}\n","/**\n * Code-aware text chunker.\n *\n * Intelligently splits source code while preserving:\n * - Function/class boundaries\n * - Import statements\n * - Comment blocks\n * - Logical code structure\n *\n * @packageDocumentation\n */\n\nimport type { Chunk, CodeChunkOptions, CodeLanguage, ChunkMetadata } from '../types.js';\nimport { DEFAULT_CHUNK_OPTIONS } from '../types.js';\n\n/**\n * Language-specific patterns for code parsing.\n */\ninterface LanguagePatterns {\n /** Pattern to detect function definitions */\n functionPattern: RegExp;\n /** Pattern to detect class definitions */\n classPattern: RegExp;\n /** Pattern to detect import statements */\n importPattern: RegExp;\n /** Single-line comment prefix */\n singleLineComment: string;\n /** Multi-line comment start */\n multiLineCommentStart: string;\n /** Multi-line comment end */\n multiLineCommentEnd: string;\n /** Block delimiters */\n blockStart: string;\n blockEnd: string;\n}\n\n/**\n * Language patterns for supported languages.\n */\nconst LANGUAGE_PATTERNS: Record<CodeLanguage, LanguagePatterns> = {\n javascript: {\n functionPattern:\n /^[\\s]*(async\\s+)?function\\s+\\w+|^[\\s]*(const|let|var)\\s+\\w+\\s*=\\s*(async\\s+)?\\(|^[\\s]*(const|let|var)\\s+\\w+\\s*=\\s*(async\\s+)?function/,\n classPattern: /^[\\s]*class\\s+\\w+/,\n importPattern: /^[\\s]*(import|export)\\s+/,\n singleLineComment: '//',\n multiLineCommentStart: '/*',\n multiLineCommentEnd: '*/',\n blockStart: '{',\n blockEnd: '}',\n },\n typescript: {\n functionPattern:\n /^[\\s]*(async\\s+)?function\\s+\\w+|^[\\s]*(const|let|var)\\s+\\w+\\s*[:=]\\s*(async\\s+)?\\(|^[\\s]*(const|let|var)\\s+\\w+\\s*=\\s*(async\\s+)?function|^[\\s]*(public|private|protected)?\\s*(async\\s+)?\\w+\\s*\\(/,\n classPattern: /^[\\s]*(abstract\\s+)?class\\s+\\w+|^[\\s]*interface\\s+\\w+|^[\\s]*type\\s+\\w+\\s*=/,\n importPattern: /^[\\s]*(import|export)\\s+/,\n singleLineComment: '//',\n multiLineCommentStart: '/*',\n multiLineCommentEnd: '*/',\n blockStart: '{',\n blockEnd: '}',\n },\n python: {\n functionPattern: /^[\\s]*(async\\s+)?def\\s+\\w+/,\n classPattern: /^[\\s]*class\\s+\\w+/,\n importPattern: /^[\\s]*(import|from)\\s+/,\n singleLineComment: '#',\n multiLineCommentStart: '\"\"\"',\n multiLineCommentEnd: '\"\"\"',\n blockStart: ':',\n blockEnd: '', // Python uses indentation\n },\n java: {\n functionPattern: /^[\\s]*(public|private|protected)?\\s*(static)?\\s*\\w+\\s+\\w+\\s*\\(/,\n classPattern: /^[\\s]*(public|private|protected)?\\s*(abstract|final)?\\s*class\\s+\\w+/,\n importPattern: /^[\\s]*(import|package)\\s+/,\n singleLineComment: '//',\n multiLineCommentStart: '/*',\n multiLineCommentEnd: '*/',\n blockStart: '{',\n blockEnd: '}',\n },\n csharp: {\n functionPattern:\n /^[\\s]*(public|private|protected|internal)?\\s*(static|async|virtual|override)?\\s*\\w+\\s+\\w+\\s*\\(/,\n classPattern:\n /^[\\s]*(public|private|protected|internal)?\\s*(abstract|sealed|partial)?\\s*class\\s+\\w+/,\n importPattern: /^[\\s]*using\\s+/,\n singleLineComment: '//',\n multiLineCommentStart: '/*',\n multiLineCommentEnd: '*/',\n blockStart: '{',\n blockEnd: '}',\n },\n cpp: {\n functionPattern: /^[\\s]*(\\w+\\s+)+\\w+\\s*\\([^)]*\\)\\s*(const)?\\s*\\{?/,\n classPattern: /^[\\s]*(class|struct)\\s+\\w+/,\n importPattern: /^[\\s]*#include\\s+/,\n singleLineComment: '//',\n multiLineCommentStart: '/*',\n multiLineCommentEnd: '*/',\n blockStart: '{',\n blockEnd: '}',\n },\n go: {\n functionPattern: /^[\\s]*func\\s+(\\(\\w+\\s+\\*?\\w+\\)\\s+)?\\w+\\s*\\(/,\n classPattern: /^[\\s]*type\\s+\\w+\\s+(struct|interface)/,\n importPattern: /^[\\s]*(import|package)\\s+/,\n singleLineComment: '//',\n multiLineCommentStart: '/*',\n multiLineCommentEnd: '*/',\n blockStart: '{',\n blockEnd: '}',\n },\n rust: {\n functionPattern: /^[\\s]*(pub\\s+)?(async\\s+)?fn\\s+\\w+/,\n classPattern: /^[\\s]*(pub\\s+)?(struct|enum|trait|impl)\\s+\\w+/,\n importPattern: /^[\\s]*(use|mod)\\s+/,\n singleLineComment: '//',\n multiLineCommentStart: '/*',\n multiLineCommentEnd: '*/',\n blockStart: '{',\n blockEnd: '}',\n },\n ruby: {\n functionPattern: /^[\\s]*def\\s+\\w+/,\n classPattern: /^[\\s]*(class|module)\\s+\\w+/,\n importPattern: /^[\\s]*require\\s+/,\n singleLineComment: '#',\n multiLineCommentStart: '=begin',\n multiLineCommentEnd: '=end',\n blockStart: '',\n blockEnd: 'end',\n },\n php: {\n functionPattern: /^[\\s]*(public|private|protected)?\\s*(static)?\\s*function\\s+\\w+/,\n classPattern: /^[\\s]*(abstract|final)?\\s*class\\s+\\w+/,\n importPattern: /^[\\s]*(use|require|include|require_once|include_once)\\s+/,\n singleLineComment: '//',\n multiLineCommentStart: '/*',\n multiLineCommentEnd: '*/',\n blockStart: '{',\n blockEnd: '}',\n },\n swift: {\n functionPattern:\n /^[\\s]*(public|private|internal|fileprivate|open)?\\s*(static|class)?\\s*func\\s+\\w+/,\n classPattern:\n /^[\\s]*(public|private|internal|fileprivate|open)?\\s*(final)?\\s*(class|struct|enum|protocol)\\s+\\w+/,\n importPattern: /^[\\s]*import\\s+/,\n singleLineComment: '//',\n multiLineCommentStart: '/*',\n multiLineCommentEnd: '*/',\n blockStart: '{',\n blockEnd: '}',\n },\n kotlin: {\n functionPattern: /^[\\s]*(public|private|protected|internal)?\\s*(suspend)?\\s*fun\\s+\\w+/,\n classPattern:\n /^[\\s]*(public|private|protected|internal)?\\s*(abstract|open|data|sealed)?\\s*(class|interface|object)\\s+\\w+/,\n importPattern: /^[\\s]*(import|package)\\s+/,\n singleLineComment: '//',\n multiLineCommentStart: '/*',\n multiLineCommentEnd: '*/',\n blockStart: '{',\n blockEnd: '}',\n },\n generic: {\n functionPattern: /^[\\s]*(function|func|def|fn)\\s+\\w+/,\n classPattern: /^[\\s]*(class|struct|type|interface)\\s+\\w+/,\n importPattern: /^[\\s]*(import|include|require|use)\\s+/,\n singleLineComment: '//',\n multiLineCommentStart: '/*',\n multiLineCommentEnd: '*/',\n blockStart: '{',\n blockEnd: '}',\n },\n};\n\n/**\n * Code element types.\n */\ntype CodeElementType = 'import' | 'class' | 'function' | 'comment' | 'code';\n\n/**\n * Parsed code element.\n */\ninterface CodeElement {\n type: CodeElementType;\n content: string;\n start: number;\n end: number;\n name?: string;\n scopeType?: string;\n}\n\n/**\n * Split source code into chunks while preserving structure.\n *\n * @param text - Source code to split\n * @param options - Chunking configuration\n * @returns Array of chunks with code metadata\n *\n * @example\n * ```typescript\n * const chunks = codeChunk(sourceCode, {\n * size: 1000,\n * language: 'typescript',\n * preserveBlocks: true,\n * });\n *\n * // Chunks include scope information:\n * // chunk.metadata.scopeName = \"MyClass\"\n * // chunk.metadata.scopeType = \"class\"\n * ```\n */\nexport function codeChunk(text: string, options: CodeChunkOptions = {}): Chunk[] {\n const {\n size = DEFAULT_CHUNK_OPTIONS.size,\n overlap = DEFAULT_CHUNK_OPTIONS.overlap,\n minSize = DEFAULT_CHUNK_OPTIONS.minSize,\n trim = DEFAULT_CHUNK_OPTIONS.trim,\n language = detectLanguage(text),\n preserveBlocks = true,\n includeImports = true,\n maxLines,\n } = options;\n\n if (!text || text.length === 0) {\n return [];\n }\n\n const patterns = LANGUAGE_PATTERNS[language];\n const elements = parseCode(text, patterns);\n\n // Extract imports for context\n const imports = includeImports\n ? elements.filter((e) => e.type === 'import').map((e) => e.content)\n : [];\n const importBlock = imports.join('\\n');\n\n // Build chunks\n const chunks = buildCodeChunks(elements, {\n size,\n overlap,\n minSize,\n trim,\n preserveBlocks,\n importBlock: includeImports ? importBlock : '',\n maxLines,\n language,\n });\n\n return chunks;\n}\n\n/**\n * Detect programming language from code content.\n */\nfunction detectLanguage(text: string): CodeLanguage {\n const lines = text.split('\\n').slice(0, 50); // Check first 50 lines\n const content = lines.join('\\n').toLowerCase();\n\n // Check for language-specific patterns\n if (content.includes('import react') || content.includes('from \"react\"')) {\n return text.includes(': ') && (text.includes('interface ') || text.includes(': React.'))\n ? 'typescript'\n : 'javascript';\n }\n if (content.includes('package main') || content.includes('func main()')) return 'go';\n if (content.includes('fn main()') || content.includes('impl ')) return 'rust';\n if (content.includes('def __init__') || content.includes('import numpy')) return 'python';\n if (content.includes('public static void main') || content.includes('package ')) {\n if (content.includes('fun ') || content.includes('val ')) return 'kotlin';\n return 'java';\n }\n if (content.includes('namespace ') || content.includes('using System')) return 'csharp';\n if (content.includes('#include <')) return 'cpp';\n if (content.includes('<?php')) return 'php';\n if (content.includes('import Foundation') || content.includes('import UIKit')) return 'swift';\n if (content.includes('require ') && content.includes('end')) return 'ruby';\n\n // Check file patterns\n if (text.includes('interface ') || text.includes(': ')) return 'typescript';\n if (text.includes('function ') || text.includes('=>')) return 'javascript';\n if (text.includes('def ') || text.includes('class ')) return 'python';\n\n return 'generic';\n}\n\n/**\n * Parse code into structural elements.\n */\nfunction parseCode(text: string, patterns: LanguagePatterns): CodeElement[] {\n const elements: CodeElement[] = [];\n const lines = text.split('\\n');\n let position = 0;\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i];\n const lineStart = position;\n\n // Check for imports\n if (patterns.importPattern.test(line)) {\n let importContent = line;\n let importEnd = position + line.length;\n\n // Handle multi-line imports\n if (line.includes('{') && !line.includes('}')) {\n position += line.length + 1;\n i++;\n while (i < lines.length && !lines[i].includes('}')) {\n importContent += '\\n' + lines[i];\n importEnd = position + lines[i].length;\n position += lines[i].length + 1;\n i++;\n }\n if (i < lines.length) {\n importContent += '\\n' + lines[i];\n importEnd = position + lines[i].length;\n }\n }\n\n elements.push({\n type: 'import',\n content: importContent,\n start: lineStart,\n end: importEnd,\n });\n position += line.length + 1;\n i++;\n continue;\n }\n\n // Check for class definitions\n if (patterns.classPattern.test(line)) {\n const className =\n extractName(line, 'class') ||\n extractName(line, 'struct') ||\n extractName(line, 'interface') ||\n extractName(line, 'type') ||\n extractName(line, 'trait') ||\n extractName(line, 'impl');\n const blockStart = lineStart;\n let blockContent = line + '\\n';\n position += line.length + 1;\n i++;\n\n // Find the end of the class block\n let braceCount = countChar(line, '{') - countChar(line, '}');\n const indentLevel = getIndent(line);\n\n while (i < lines.length) {\n const nextLine = lines[i];\n blockContent += nextLine + '\\n';\n braceCount += countChar(nextLine, '{') - countChar(nextLine, '}');\n\n position += nextLine.length + 1;\n i++;\n\n // Check for block end\n if (patterns.blockEnd === '}' && braceCount <= 0 && nextLine.includes('}')) {\n break;\n }\n if (patterns.blockEnd === 'end' && nextLine.trim() === 'end') {\n break;\n }\n // Python: check indentation\n if (\n patterns.blockStart === ':' &&\n getIndent(nextLine) <= indentLevel &&\n nextLine.trim() !== ''\n ) {\n // Went back, include previous line only\n position -= nextLine.length + 1;\n blockContent = blockContent.slice(0, blockContent.length - nextLine.length - 1);\n i--;\n break;\n }\n }\n\n elements.push({\n type: 'class',\n content: blockContent.trimEnd(),\n start: blockStart,\n end: position,\n name: className,\n scopeType: 'class',\n });\n continue;\n }\n\n // Check for function definitions\n if (patterns.functionPattern.test(line)) {\n const funcName = extractFunctionName(line);\n const blockStart = lineStart;\n let blockContent = line + '\\n';\n position += line.length + 1;\n i++;\n\n // Find the end of the function block\n let braceCount = countChar(line, '{') - countChar(line, '}');\n const indentLevel = getIndent(line);\n\n while (i < lines.length) {\n const nextLine = lines[i];\n blockContent += nextLine + '\\n';\n braceCount += countChar(nextLine, '{') - countChar(nextLine, '}');\n\n position += nextLine.length + 1;\n i++;\n\n // Check for block end\n if (patterns.blockEnd === '}' && braceCount <= 0 && blockContent.includes('{')) {\n break;\n }\n if (patterns.blockEnd === 'end' && nextLine.trim() === 'end') {\n break;\n }\n // Python: check indentation\n if (\n patterns.blockStart === ':' &&\n getIndent(nextLine) <= indentLevel &&\n nextLine.trim() !== ''\n ) {\n position -= nextLine.length + 1;\n blockContent = blockContent.slice(0, blockContent.length - nextLine.length - 1);\n i--;\n break;\n }\n }\n\n elements.push({\n type: 'function',\n content: blockContent.trimEnd(),\n start: blockStart,\n end: position,\n name: funcName,\n scopeType: 'function',\n });\n continue;\n }\n\n // Check for multi-line comments\n if (\n line.includes(patterns.multiLineCommentStart) &&\n !line.includes(patterns.multiLineCommentEnd)\n ) {\n const commentStart = lineStart;\n let commentContent = line + '\\n';\n position += line.length + 1;\n i++;\n\n while (i < lines.length && !lines[i].includes(patterns.multiLineCommentEnd)) {\n commentContent += lines[i] + '\\n';\n position += lines[i].length + 1;\n i++;\n }\n\n if (i < lines.length) {\n commentContent += lines[i];\n position += lines[i].length + 1;\n i++;\n }\n\n elements.push({\n type: 'comment',\n content: commentContent.trimEnd(),\n start: commentStart,\n end: position,\n });\n continue;\n }\n\n // Regular code line\n elements.push({\n type: 'code',\n content: line,\n start: lineStart,\n end: position + line.length,\n });\n position += line.length + 1;\n i++;\n }\n\n return elements;\n}\n\n/**\n * Extract a name after a keyword.\n */\nfunction extractName(line: string, keyword: string): string | undefined {\n const regex = new RegExp(`${keyword}\\\\s+(\\\\w+)`);\n const match = line.match(regex);\n return match?.[1];\n}\n\n/**\n * Extract function name from a line.\n */\nfunction extractFunctionName(line: string): string | undefined {\n // Try various patterns\n let match = line.match(/function\\s+(\\w+)/);\n if (match) return match[1];\n\n match = line.match(/def\\s+(\\w+)/);\n if (match) return match[1];\n\n match = line.match(/fn\\s+(\\w+)/);\n if (match) return match[1];\n\n match = line.match(/func\\s+(?:\\([^)]+\\)\\s+)?(\\w+)/);\n if (match) return match[1];\n\n match = line.match(/(?:const|let|var)\\s+(\\w+)\\s*=/);\n if (match) return match[1];\n\n return undefined;\n}\n\n/**\n * Count occurrences of a character.\n */\nfunction countChar(str: string, char: string): number {\n let count = 0;\n for (const c of str) {\n if (c === char) count++;\n }\n return count;\n}\n\n/**\n * Get indentation level of a line.\n */\nfunction getIndent(line: string): number {\n const match = line.match(/^(\\s*)/);\n return match ? match[1].length : 0;\n}\n\n/**\n * Build chunks from code elements.\n */\nfunction buildCodeChunks(\n elements: CodeElement[],\n options: {\n size: number;\n overlap: number;\n minSize: number;\n trim: boolean;\n preserveBlocks: boolean;\n importBlock: string;\n maxLines?: number;\n language: CodeLanguage;\n }\n): Chunk[] {\n const chunks: Chunk[] = [];\n let currentChunk = '';\n let currentStart = -1;\n let currentScope: { name?: string; type?: string } = {};\n let chunkIndex = 0;\n\n const finalizeChunk = (forceMetadata?: ChunkMetadata) => {\n if (currentChunk.length >= options.minSize) {\n const text = options.trim ? currentChunk.trim() : currentChunk;\n if (text.length >= options.minSize) {\n const metadata: ChunkMetadata = forceMetadata || {\n language: options.language,\n };\n if (currentScope.name) metadata.scopeName = currentScope.name;\n if (currentScope.type) metadata.scopeType = currentScope.type;\n\n chunks.push({\n text,\n start: currentStart,\n end: currentStart + currentChunk.length,\n index: chunkIndex++,\n metadata,\n });\n }\n }\n currentChunk = '';\n currentStart = -1;\n currentScope = {};\n };\n\n // Skip imports (they'll be added as context)\n const codeElements = elements.filter((e) => e.type !== 'import');\n\n for (const element of codeElements) {\n // Handle classes and functions that should be preserved\n if (options.preserveBlocks && (element.type === 'class' || element.type === 'function')) {\n // Finalize current chunk\n if (currentChunk) {\n finalizeChunk();\n }\n\n // If the block fits in size limit, add as single chunk\n let content = element.content;\n if (options.importBlock && element.type === 'function') {\n // Add imports for context to standalone functions\n content = options.importBlock + '\\n\\n' + content;\n }\n\n if (content.length <= options.size || !options.maxLines) {\n chunks.push({\n text: options.trim ? content.trim() : content,\n start: element.start,\n end: element.end,\n index: chunkIndex++,\n metadata: {\n language: options.language,\n scopeName: element.name,\n scopeType: element.scopeType,\n },\n });\n } else {\n // Split large blocks by lines\n const lines = content.split('\\n');\n let lineChunk = '';\n let lineStart = element.start;\n let lineCount = 0;\n\n for (const line of lines) {\n if (\n (options.maxLines && lineCount >= options.maxLines) ||\n lineChunk.length + line.length > options.size\n ) {\n if (lineChunk.length >= options.minSize) {\n chunks.push({\n text: options.trim ? lineChunk.trim() : lineChunk,\n start: lineStart,\n end: lineStart + lineChunk.length,\n index: chunkIndex++,\n metadata: {\n language: options.language,\n scopeName: element.name,\n scopeType: element.scopeType,\n },\n });\n }\n lineChunk = line + '\\n';\n lineStart = element.start + content.indexOf(line);\n lineCount = 1;\n } else {\n lineChunk += line + '\\n';\n lineCount++;\n }\n }\n\n // Final line chunk\n if (lineChunk.length >= options.minSize) {\n chunks.push({\n text: options.trim ? lineChunk.trim() : lineChunk,\n start: lineStart,\n end: element.end,\n index: chunkIndex++,\n metadata: {\n language: options.language,\n scopeName: element.name,\n scopeType: element.scopeType,\n },\n });\n }\n }\n continue;\n }\n\n // Regular code - accumulate\n const newLength = currentChunk.length + element.content.length + 1;\n if (newLength > options.size && currentChunk.length > 0) {\n finalizeChunk();\n currentChunk = element.content;\n currentStart = element.start;\n } else {\n if (currentChunk) {\n currentChunk += '\\n' + element.content;\n } else {\n currentChunk = element.content;\n currentStart = element.start;\n }\n }\n }\n\n // Finalize last chunk\n if (currentChunk) {\n finalizeChunk();\n }\n\n return chunks;\n}\n\n/**\n * Create a code chunker with preset options.\n */\nexport function createCodeChunker(\n defaultOptions: CodeChunkOptions = {}\n): (text: string, options?: CodeChunkOptions) => Chunk[] {\n return (text: string, options: CodeChunkOptions = {}) =>\n codeChunk(text, { ...defaultOptions, ...options });\n}\n\n","/**\n * Text chunking utilities for RAG pipelines.\n *\n * Provides multiple chunking strategies:\n * - Recursive: General-purpose splitting with configurable separators\n * - Markdown: Structure-aware splitting for markdown documents\n * - Code: Language-aware splitting for source code\n *\n * @packageDocumentation\n */\n\nexport { recursiveChunk, createRecursiveChunker } from './recursive.js';\nexport { markdownChunk, createMarkdownChunker } from './markdown.js';\nexport { codeChunk, createCodeChunker } from './code.js';\n\nimport type {\n Chunk,\n ChunkOptions,\n RecursiveChunkOptions,\n MarkdownChunkOptions,\n CodeChunkOptions,\n} from '../types.js';\nimport { recursiveChunk } from './recursive.js';\nimport { markdownChunk } from './markdown.js';\nimport { codeChunk } from './code.js';\n\n/**\n * Split text into chunks using the specified strategy.\n *\n * This is the main entry point for chunking. It automatically routes to the\n * appropriate chunker based on the strategy option.\n *\n * @param text - Text to split into chunks\n * @param options - Chunking options including strategy\n * @returns Array of chunks\n *\n * @example\n * ```typescript\n * import { chunk } from '@localmode/core';\n *\n * // Default recursive chunking\n * const chunks = chunk(longDocument, { size: 500, overlap: 50 });\n *\n * // Markdown-aware chunking\n * const mdChunks = chunk(markdown, {\n * strategy: 'markdown',\n * size: 1000,\n * preserveHeadingHierarchy: true,\n * });\n *\n * // Code-aware chunking\n * const codeChunks = chunk(sourceCode, {\n * strategy: 'code',\n * language: 'typescript',\n * preserveBlocks: true,\n * });\n * ```\n */\nexport function chunk(text: string, options: ChunkOptions = { strategy: 'recursive' }): Chunk[] {\n const { strategy = 'recursive' } = options;\n\n switch (strategy) {\n case 'markdown':\n return markdownChunk(text, options as MarkdownChunkOptions);\n case 'code':\n return codeChunk(text, options as CodeChunkOptions);\n case 'recursive':\n case 'sentence':\n case 'paragraph':\n default:\n return recursiveChunk(text, options as RecursiveChunkOptions);\n }\n}\n\n/**\n * Create a reusable chunker function with preset options.\n *\n * @param defaultOptions - Default options for the chunker\n * @returns A chunker function that accepts text and optional overrides\n *\n * @example\n * ```typescript\n * import { createChunker } from '@localmode/core';\n *\n * // Create a chunker with preset options\n * const chunker = createChunker({\n * strategy: 'markdown',\n * size: 800,\n * overlap: 100,\n * });\n *\n * // Use the chunker\n * const chunks1 = chunker(document1);\n * const chunks2 = chunker(document2, { size: 500 }); // Override size\n * ```\n */\nexport function createChunker(\n defaultOptions: ChunkOptions\n): (text: string, options?: Partial<ChunkOptions>) => Chunk[] {\n return (text: string, options: Partial<ChunkOptions> = {}) =>\n chunk(text, { ...defaultOptions, ...options } as ChunkOptions);\n}\n\n/**\n * Estimate the number of chunks for a given text without actually chunking.\n *\n * @param text - Text to estimate\n * @param options - Chunking options\n * @returns Estimated number of chunks\n *\n * @example\n * ```typescript\n * const estimate = estimateChunkCount(longDocument, { size: 500 });\n * console.log(`Will produce approximately ${estimate} chunks`);\n * ```\n */\nexport function estimateChunkCount(\n text: string,\n options: ChunkOptions = { strategy: 'recursive' }\n): number {\n if (!text || text.length === 0) return 0;\n\n const { size = 500, overlap = 50 } = options;\n const effectiveSize = size - overlap;\n\n if (effectiveSize <= 0) return 1;\n\n return Math.ceil(text.length / effectiveSize);\n}\n\n/**\n * Get statistics about chunks.\n *\n * @param chunks - Array of chunks to analyze\n * @returns Statistics about the chunks\n *\n * @example\n * ```typescript\n * const stats = getChunkStats(chunks);\n * console.log(`Average chunk size: ${stats.averageSize} characters`);\n * ```\n */\nexport function getChunkStats(chunks: Chunk[]): {\n count: number;\n totalSize: number;\n averageSize: number;\n minSize: number;\n maxSize: number;\n sizes: number[];\n} {\n if (chunks.length === 0) {\n return {\n count: 0,\n totalSize: 0,\n averageSize: 0,\n minSize: 0,\n maxSize: 0,\n sizes: [],\n };\n }\n\n const sizes = chunks.map((c) => c.text.length);\n const totalSize = sizes.reduce((a, b) => a + b, 0);\n\n return {\n count: chunks.length,\n totalSize,\n averageSize: Math.round(totalSize / chunks.length),\n minSize: Math.min(...sizes),\n maxSize: Math.max(...sizes),\n sizes,\n };\n}\n\n","/**\n * BM25 (Best Matching 25) implementation for keyword-based search.\n *\n * BM25 is a probabilistic ranking function used to estimate the relevance\n * of documents to a given search query. It's commonly used alongside\n * vector search in hybrid retrieval systems.\n *\n * @packageDocumentation\n */\n\nimport type { BM25Options, BM25Document, BM25Result, BM25Index, BM25IndexState } from './types.js';\nimport { DEFAULT_BM25_OPTIONS, ENGLISH_STOP_WORDS } from './types.js';\n\n/**\n * Simple stemmer that reduces words to their base form.\n * This is a basic Porter-like stemmer for English.\n */\nfunction simpleStem(word: string): string {\n let stem = word.toLowerCase();\n\n // Remove common suffixes\n const suffixes = [\n 'ingly',\n 'edly',\n 'ness',\n 'ment',\n 'tion',\n 'sion',\n 'ious',\n 'eous',\n 'able',\n 'ible',\n 'less',\n 'ful',\n 'ing',\n 'ied',\n 'ies',\n 'ily',\n 'ers',\n 'est',\n 'ed',\n 'er',\n 'ly',\n 's',\n ];\n\n for (const suffix of suffixes) {\n if (stem.length > suffix.length + 2 && stem.endsWith(suffix)) {\n stem = stem.slice(0, -suffix.length);\n break;\n }\n }\n\n return stem;\n}\n\n/**\n * Default tokenizer function.\n * Splits text into tokens, lowercases, and optionally stems.\n */\nfunction defaultTokenize(\n text: string,\n options: { stemming?: boolean; minLength?: number } = {}\n): string[] {\n const { stemming = false, minLength = 2 } = options;\n\n // Split on non-alphanumeric characters\n const tokens = text\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((token) => token.length >= minLength);\n\n if (stemming) {\n return tokens.map(simpleStem);\n }\n\n return tokens;\n}\n\n/**\n * BM25 search index implementation.\n *\n * @example\n * ```typescript\n * import { BM25 } from '@localmode/core';\n *\n * const bm25 = new BM25();\n *\n * // Add documents\n * bm25.add('doc1', 'The quick brown fox jumps over the lazy dog');\n * bm25.add('doc2', 'A lazy cat sleeps all day');\n *\n * // Search\n * const results = bm25.search('lazy animal', 5);\n * // Returns: [{ id: 'doc1', score: 0.85 }, { id: 'doc2', score: 0.72 }]\n * ```\n */\nexport class BM25 implements BM25Index {\n private k1: number;\n private b: number;\n private minTokenLength: number;\n private stopWords: Set<string>;\n private tokenize: (text: string) => string[];\n private stemming: boolean;\n\n private documents: Map<string, BM25Document> = new Map();\n private docFreqs: Map<string, number> = new Map();\n private avgDocLength = 0;\n private totalDocLength = 0;\n\n /**\n * Create a new BM25 index.\n *\n * @param options - BM25 configuration options\n */\n constructor(options: BM25Options = {}) {\n this.k1 = options.k1 ?? DEFAULT_BM25_OPTIONS.k1;\n this.b = options.b ?? DEFAULT_BM25_OPTIONS.b;\n this.minTokenLength = options.minTokenLength ?? DEFAULT_BM25_OPTIONS.minTokenLength;\n this.stemming = options.stemming ?? DEFAULT_BM25_OPTIONS.stemming;\n\n // Handle stop words\n if (options.stopWords) {\n this.stopWords =\n options.stopWords instanceof Set ? options.stopWords : new Set(options.stopWords);\n } else {\n this.stopWords = ENGLISH_STOP_WORDS;\n }\n\n // Set up tokenizer\n if (options.tokenize) {\n this.tokenize = options.tokenize;\n } else {\n this.tokenize = (text: string) =>\n defaultTokenize(text, {\n stemming: this.stemming,\n minLength: this.minTokenLength,\n }).filter((token) => !this.stopWords.has(token));\n }\n }\n\n /**\n * Add a document to the index.\n *\n * @param id - Document ID\n * @param text - Document text content\n */\n add(id: string, text: string): void {\n // Remove if exists (for updates)\n if (this.documents.has(id)) {\n this.remove(id);\n }\n\n const tokens = this.tokenize(text);\n const termFreqs = new Map<string, number>();\n\n // Calculate term frequencies\n for (const token of tokens) {\n termFreqs.set(token, (termFreqs.get(token) || 0) + 1);\n }\n\n // Update document frequencies\n for (const term of termFreqs.keys()) {\n this.docFreqs.set(term, (this.docFreqs.get(term) || 0) + 1);\n }\n\n // Store document\n this.documents.set(id, {\n id,\n tokens,\n termFreqs,\n length: tokens.length,\n text,\n });\n\n // Update average document length\n this.totalDocLength += tokens.length;\n this.avgDocLength = this.totalDocLength / this.documents.size;\n }\n\n /**\n * Add multiple documents to the index.\n *\n * @param documents - Array of { id, text } objects\n */\n addMany(documents: Array<{ id: string; text: string }>): void {\n for (const doc of documents) {\n this.add(doc.id, doc.text);\n }\n }\n\n /**\n * Search the index for documents matching the query.\n *\n * @param query - Search query text\n * @param k - Number of results to return (default: 10)\n * @returns Sorted array of results with scores\n */\n search(query: string, k = 10): BM25Result[] {\n const queryTokens = this.tokenize(query);\n\n if (queryTokens.length === 0 || this.documents.size === 0) {\n return [];\n }\n\n const scores: Array<{ id: string; score: number; text?: string }> = [];\n const N = this.documents.size;\n\n for (const doc of this.documents.values()) {\n let score = 0;\n\n for (const term of queryTokens) {\n const tf = doc.termFreqs.get(term) || 0;\n if (tf === 0) continue;\n\n const df = this.docFreqs.get(term) || 0;\n const idf = Math.log((N - df + 0.5) / (df + 0.5) + 1);\n\n const numerator = tf * (this.k1 + 1);\n const denominator = tf + this.k1 * (1 - this.b + this.b * (doc.length / this.avgDocLength));\n\n score += idf * (numerator / denominator);\n }\n\n if (score > 0) {\n scores.push({ id: doc.id, score, text: doc.text });\n }\n }\n\n // Sort by score descending and return top k\n return scores.sort((a, b) => b.score - a.score).slice(0, k);\n }\n\n /**\n * Remove a document from the index.\n *\n * @param id - Document ID to remove\n */\n remove(id: string): void {\n const doc = this.documents.get(id);\n if (!doc) return;\n\n // Update document frequencies\n for (const term of doc.termFreqs.keys()) {\n const df = this.docFreqs.get(term) || 1;\n if (df <= 1) {\n this.docFreqs.delete(term);\n } else {\n this.docFreqs.set(term, df - 1);\n }\n }\n\n // Update average document length\n this.totalDocLength -= doc.length;\n this.documents.delete(id);\n this.avgDocLength = this.documents.size > 0 ? this.totalDocLength / this.documents.size : 0;\n }\n\n /**\n * Clear all documents from the index.\n */\n clear(): void {\n this.documents.clear();\n this.docFreqs.clear();\n this.avgDocLength = 0;\n this.totalDocLength = 0;\n }\n\n /**\n * Get index statistics.\n *\n * @returns Object with docCount, avgDocLength, and vocabularySize\n */\n stats(): { docCount: number; avgDocLength: number; vocabularySize: number } {\n return {\n docCount: this.documents.size,\n avgDocLength: this.avgDocLength,\n vocabularySize: this.docFreqs.size,\n };\n }\n\n /**\n * Serialize the index to JSON for persistence.\n *\n * @returns Serializable index state\n */\n toJSON(): BM25IndexState {\n const documents: BM25IndexState['documents'] = [];\n\n for (const doc of this.documents.values()) {\n documents.push({\n id: doc.id,\n tokens: doc.tokens,\n length: doc.length,\n text: doc.text,\n });\n }\n\n return {\n docCount: this.documents.size,\n avgDocLength: this.avgDocLength,\n docFreqs: Object.fromEntries(this.docFreqs),\n documents,\n };\n }\n\n /**\n * Load index from serialized state.\n *\n * @param state - Previously serialized index state\n */\n fromJSON(state: BM25IndexState): void {\n this.clear();\n\n this.avgDocLength = state.avgDocLength;\n this.docFreqs = new Map(Object.entries(state.docFreqs));\n\n for (const doc of state.documents) {\n // Rebuild term frequencies from tokens\n const termFreqs = new Map<string, number>();\n for (const token of doc.tokens) {\n termFreqs.set(token, (termFreqs.get(token) || 0) + 1);\n }\n\n this.documents.set(doc.id, {\n id: doc.id,\n tokens: doc.tokens,\n termFreqs,\n length: doc.length,\n text: doc.text,\n });\n\n this.totalDocLength += doc.length;\n }\n }\n\n /**\n * Check if a document exists in the index.\n *\n * @param id - Document ID\n * @returns true if document exists\n */\n has(id: string): boolean {\n return this.documents.has(id);\n }\n\n /**\n * Get document count.\n *\n * @returns Number of indexed documents\n */\n get size(): number {\n return this.documents.size;\n }\n}\n\n/**\n * Create a new BM25 index with the given options.\n *\n * @param options - BM25 configuration\n * @returns New BM25 index instance\n *\n * @example\n * ```typescript\n * import { createBM25 } from '@localmode/core';\n *\n * const bm25 = createBM25({\n * k1: 1.5,\n * b: 0.75,\n * stemming: true,\n * });\n * ```\n */\nexport function createBM25(options: BM25Options = {}): BM25 {\n return new BM25(options);\n}\n\n/**\n * Create a BM25 index from an array of documents.\n *\n * @param documents - Documents to index\n * @param options - BM25 configuration\n * @returns Populated BM25 index\n *\n * @example\n * ```typescript\n * import { createBM25FromDocuments } from '@localmode/core';\n *\n * const bm25 = createBM25FromDocuments([\n * { id: 'doc1', text: 'The quick brown fox' },\n * { id: 'doc2', text: 'A lazy dog sleeps' },\n * ]);\n *\n * const results = bm25.search('fox');\n * ```\n */\nexport function createBM25FromDocuments(\n documents: Array<{ id: string; text: string }>,\n options: BM25Options = {}\n): BM25 {\n const bm25 = new BM25(options);\n bm25.addMany(documents);\n return bm25;\n}\n\n","/**\n * Hybrid search combining vector similarity and BM25 keyword search.\n *\n * Hybrid search leverages the strengths of both approaches:\n * - Vector search finds semantically similar content\n * - BM25 finds exact keyword matches and handles rare terms\n *\n * The results are combined using Reciprocal Rank Fusion (RRF)\n * or weighted score combination.\n *\n * @packageDocumentation\n */\n\nimport type { VectorDB, SearchResult } from '../types.js';\nimport type { HybridSearchOptions, HybridSearchResult, BM25Options } from './types.js';\nimport { DEFAULT_HYBRID_OPTIONS } from './types.js';\nimport { BM25 } from './bm25.js';\n\n/**\n * Hybrid search manager that combines vector and keyword search.\n *\n * @example\n * ```typescript\n * import { HybridSearch } from '@localmode/core';\n *\n * const hybrid = new HybridSearch(vectorDb);\n *\n * // Add documents with text\n * await hybrid.add('doc1', 'The quick brown fox', embedding1);\n * await hybrid.add('doc2', 'A lazy dog sleeps', embedding2);\n *\n * // Hybrid search\n * const results = await hybrid.search(queryEmbedding, 'brown fox', { k: 10 });\n * ```\n */\nexport class HybridSearch {\n private db: VectorDB;\n private bm25: BM25;\n private textStore: Map<string, string> = new Map();\n\n /**\n * Create a new hybrid search instance.\n *\n * @param db - Vector database instance\n * @param bm25Options - BM25 configuration options\n */\n constructor(db: VectorDB, bm25Options: BM25Options = {}) {\n this.db = db;\n this.bm25 = new BM25(bm25Options);\n }\n\n /**\n * Add a document with both vector and text for hybrid search.\n *\n * @param id - Document ID\n * @param text - Document text content\n * @param vector - Document embedding vector\n * @param metadata - Optional metadata\n */\n async add(\n id: string,\n text: string,\n vector: Float32Array,\n metadata?: Record<string, unknown>\n ): Promise<void> {\n // Add to vector DB\n await this.db.add({ id, vector, metadata: { ...metadata, _text: text } });\n\n // Add to BM25 index\n this.bm25.add(id, text);\n this.textStore.set(id, text);\n }\n\n /**\n * Add multiple documents for hybrid search.\n *\n * @param documents - Array of documents with id, text, vector, and optional metadata\n */\n async addMany(\n documents: Array<{\n id: string;\n text: string;\n vector: Float32Array;\n metadata?: Record<string, unknown>;\n }>\n ): Promise<void> {\n // Add to vector DB\n await this.db.addMany(\n documents.map((doc) => ({\n id: doc.id,\n vector: doc.vector,\n metadata: { ...doc.metadata, _text: doc.text },\n }))\n );\n\n // Add to BM25 index\n for (const doc of documents) {\n this.bm25.add(doc.id, doc.text);\n this.textStore.set(doc.id, doc.text);\n }\n }\n\n /**\n * Perform hybrid search combining vector and keyword search.\n *\n * @param queryVector - Query embedding vector\n * @param queryText - Query text for keyword search\n * @param options - Search configuration\n * @returns Combined and ranked results\n */\n async search(\n queryVector: Float32Array,\n queryText: string,\n options: HybridSearchOptions = {}\n ): Promise<HybridSearchResult[]> {\n const {\n k = DEFAULT_HYBRID_OPTIONS.k,\n vectorWeight = DEFAULT_HYBRID_OPTIONS.vectorWeight,\n keywordWeight = DEFAULT_HYBRID_OPTIONS.keywordWeight,\n normalizeScores = DEFAULT_HYBRID_OPTIONS.normalizeScores,\n threshold = DEFAULT_HYBRID_OPTIONS.threshold,\n filter,\n includeVectors = DEFAULT_HYBRID_OPTIONS.includeVectors,\n fetchK = k * 3,\n } = options;\n\n // Perform both searches in parallel\n const [vectorResults, bm25Results] = await Promise.all([\n this.db.search(queryVector, { k: fetchK, filter, includeVectors }),\n Promise.resolve(this.bm25.search(queryText, fetchK)),\n ]);\n\n // Combine results using score fusion\n const combined = fuseResults(vectorResults, bm25Results, {\n vectorWeight,\n keywordWeight,\n normalizeScores,\n });\n\n // Apply threshold and limit\n const filtered = combined.filter((r) => r.score >= threshold).slice(0, k);\n\n // Add text content to results\n return filtered.map((result) => ({\n ...result,\n text: this.textStore.get(result.id),\n }));\n }\n\n /**\n * Remove a document from the hybrid index.\n *\n * @param id - Document ID to remove\n */\n async remove(id: string): Promise<void> {\n await this.db.delete(id);\n this.bm25.remove(id);\n this.textStore.delete(id);\n }\n\n /**\n * Clear all documents from the hybrid index.\n */\n async clear(): Promise<void> {\n await this.db.clear();\n this.bm25.clear();\n this.textStore.clear();\n }\n\n /**\n * Get the underlying BM25 index for advanced operations.\n */\n getBM25Index(): BM25 {\n return this.bm25;\n }\n\n /**\n * Get the underlying vector database.\n */\n getVectorDB(): VectorDB {\n return this.db;\n }\n\n /**\n * Export the BM25 index state for persistence.\n */\n exportBM25State(): ReturnType<BM25['toJSON']> {\n return this.bm25.toJSON();\n }\n\n /**\n * Import BM25 index state.\n */\n importBM25State(state: ReturnType<BM25['toJSON']>): void {\n this.bm25.fromJSON(state);\n\n // Rebuild text store from BM25 documents\n for (const doc of state.documents) {\n if (doc.text) {\n this.textStore.set(doc.id, doc.text);\n }\n }\n }\n}\n\n/**\n * Fuse vector and keyword search results using weighted combination.\n */\nfunction fuseResults(\n vectorResults: SearchResult[],\n bm25Results: Array<{ id: string; score: number }>,\n options: {\n vectorWeight: number;\n keywordWeight: number;\n normalizeScores: boolean;\n }\n): HybridSearchResult[] {\n const { vectorWeight, keywordWeight, normalizeScores } = options;\n\n // Create score maps\n const vectorScores = new Map<string, number>();\n const keywordScores = new Map<string, number>();\n const metadataMap = new Map<string, Record<string, unknown> | undefined>();\n const vectorMap = new Map<string, Float32Array | undefined>();\n\n // Collect vector scores\n for (const result of vectorResults) {\n vectorScores.set(result.id, result.score);\n metadataMap.set(result.id, result.metadata);\n vectorMap.set(result.id, result.vector);\n }\n\n // Collect keyword scores\n for (const result of bm25Results) {\n keywordScores.set(result.id, result.score);\n }\n\n // Get all unique IDs\n const allIds = new Set([...vectorScores.keys(), ...keywordScores.keys()]);\n\n // Normalize scores if requested\n let normalizedVectorScores = vectorScores;\n let normalizedKeywordScores = keywordScores;\n\n if (normalizeScores) {\n normalizedVectorScores = normalizeScoreMap(vectorScores);\n normalizedKeywordScores = normalizeScoreMap(keywordScores);\n }\n\n // Combine scores\n const results: HybridSearchResult[] = [];\n\n for (const id of allIds) {\n const vScore = normalizedVectorScores.get(id) || 0;\n const kScore = normalizedKeywordScores.get(id) || 0;\n\n const combinedScore = vScore * vectorWeight + kScore * keywordWeight;\n\n results.push({\n id,\n score: combinedScore,\n vectorScore: vectorScores.get(id),\n keywordScore: keywordScores.get(id),\n metadata: metadataMap.get(id),\n vector: vectorMap.get(id),\n });\n }\n\n // Sort by combined score\n return results.sort((a, b) => b.score - a.score);\n}\n\n/**\n * Normalize scores to [0, 1] range.\n */\nfunction normalizeScoreMap(scores: Map<string, number>): Map<string, number> {\n if (scores.size === 0) return scores;\n\n const values = Array.from(scores.values());\n const min = Math.min(...values);\n const max = Math.max(...values);\n const range = max - min;\n\n if (range === 0) {\n // All scores are the same\n return new Map(Array.from(scores.entries()).map(([id]) => [id, 1]));\n }\n\n return new Map(Array.from(scores.entries()).map(([id, score]) => [id, (score - min) / range]));\n}\n\n/**\n * Perform hybrid search using Reciprocal Rank Fusion (RRF).\n *\n * RRF combines rankings rather than scores, which can be more robust\n * when the score distributions differ significantly.\n *\n * @param vectorResults - Results from vector search\n * @param bm25Results - Results from BM25 search\n * @param k - Constant for RRF (default: 60)\n * @returns Fused results sorted by RRF score\n *\n * @example\n * ```typescript\n * import { reciprocalRankFusion } from '@localmode/core';\n *\n * const vectorResults = await db.search(queryVector, { k: 20 });\n * const bm25Results = bm25.search(queryText, 20);\n *\n * const fused = reciprocalRankFusion(vectorResults, bm25Results);\n * ```\n */\nexport function reciprocalRankFusion(\n vectorResults: SearchResult[],\n bm25Results: Array<{ id: string; score: number }>,\n k = 60\n): HybridSearchResult[] {\n const rrfScores = new Map<string, number>();\n const metadataMap = new Map<string, Record<string, unknown> | undefined>();\n const vectorScoreMap = new Map<string, number>();\n const keywordScoreMap = new Map<string, number>();\n\n // Add RRF scores from vector results\n for (let i = 0; i < vectorResults.length; i++) {\n const result = vectorResults[i];\n const rank = i + 1;\n rrfScores.set(result.id, (rrfScores.get(result.id) || 0) + 1 / (k + rank));\n metadataMap.set(result.id, result.metadata);\n vectorScoreMap.set(result.id, result.score);\n }\n\n // Add RRF scores from BM25 results\n for (let i = 0; i < bm25Results.length; i++) {\n const result = bm25Results[i];\n const rank = i + 1;\n rrfScores.set(result.id, (rrfScores.get(result.id) || 0) + 1 / (k + rank));\n keywordScoreMap.set(result.id, result.score);\n }\n\n // Build results\n const results: HybridSearchResult[] = Array.from(rrfScores.entries()).map(([id, score]) => ({\n id,\n score,\n vectorScore: vectorScoreMap.get(id),\n keywordScore: keywordScoreMap.get(id),\n metadata: metadataMap.get(id),\n }));\n\n return results.sort((a, b) => b.score - a.score);\n}\n\n/**\n * Create a hybrid search instance from a vector database.\n *\n * @param db - Vector database instance\n * @param bm25Options - BM25 configuration\n * @returns Hybrid search instance\n *\n * @example\n * ```typescript\n * import { createHybridSearch, createVectorDB } from '@localmode/core';\n *\n * const db = await createVectorDB({ name: 'docs', dimensions: 384 });\n * const hybrid = createHybridSearch(db);\n *\n * await hybrid.add('doc1', 'The quick brown fox', embedding);\n * ```\n */\nexport function createHybridSearch(db: VectorDB, bm25Options: BM25Options = {}): HybridSearch {\n return new HybridSearch(db, bm25Options);\n}\n\n/**\n * Perform a one-off hybrid search without maintaining state.\n *\n * This function is useful when you already have separate vector and BM25 results\n * and just want to combine them.\n *\n * @param vectorResults - Results from vector search\n * @param bm25Results - Results from BM25 search\n * @param options - Fusion options\n * @returns Combined results\n *\n * @example\n * ```typescript\n * import { hybridFuse } from '@localmode/core';\n *\n * const vectorResults = await db.search(queryVector, { k: 20 });\n * const bm25Results = bm25.search(queryText, 20);\n *\n * const combined = hybridFuse(vectorResults, bm25Results, {\n * vectorWeight: 0.7,\n * keywordWeight: 0.3,\n * });\n * ```\n */\nexport function hybridFuse(\n vectorResults: SearchResult[],\n bm25Results: Array<{ id: string; score: number }>,\n options: {\n vectorWeight?: number;\n keywordWeight?: number;\n normalizeScores?: boolean;\n useRRF?: boolean;\n rrfK?: number;\n } = {}\n): HybridSearchResult[] {\n const {\n vectorWeight = DEFAULT_HYBRID_OPTIONS.vectorWeight,\n keywordWeight = DEFAULT_HYBRID_OPTIONS.keywordWeight,\n normalizeScores = DEFAULT_HYBRID_OPTIONS.normalizeScores,\n useRRF = false,\n rrfK = 60,\n } = options;\n\n if (useRRF) {\n return reciprocalRankFusion(vectorResults, bm25Results, rrfK);\n }\n\n return fuseResults(vectorResults, bm25Results, {\n vectorWeight,\n keywordWeight,\n normalizeScores,\n });\n}\n\n","/**\n * Batch ingestion utilities for RAG pipelines.\n *\n * Provides high-level helpers for ingesting documents into\n * a vector database with chunking, embedding, and progress tracking.\n *\n * @packageDocumentation\n */\n\nimport type { VectorDB, Document } from '../types.js';\nimport type {\n SourceDocument,\n IngestOptions,\n IngestProgress,\n IngestResult,\n ChunkOptions,\n BM25Index,\n} from './types.js';\nimport { DEFAULT_INGEST_OPTIONS } from './types.js';\nimport { chunk } from './chunkers/index.js';\nimport { BM25 } from './bm25.js';\n\n/**\n * Generate a unique ID for a chunk.\n */\nfunction generateChunkId(docId: string, chunkIndex: number, prefix: string): string {\n return `${prefix}_${docId}_${chunkIndex}`;\n}\n\n/**\n * Generate a document ID if not provided.\n */\nfunction generateDocId(): string {\n return `doc_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n}\n\n/**\n * Ingest documents into a vector database with chunking and optional embedding.\n *\n * This is the main high-level function for RAG ingestion pipelines.\n *\n * @param db - Vector database instance\n * @param documents - Source documents to ingest\n * @param options - Ingestion configuration\n * @returns Ingestion result with statistics\n *\n * @example\n * ```typescript\n * import { createVectorDB, ingest } from '@localmode/core';\n *\n * const db = await createVectorDB({ name: 'docs', dimensions: 384 });\n *\n * // Simple ingestion with vectors already computed\n * const result = await ingest(db, documents, {\n * chunking: { strategy: 'recursive', size: 500 },\n * onProgress: (p) => console.log(`${p.phase}: ${p.chunksProcessed}/${p.totalChunks}`),\n * });\n *\n * // With embedding generation\n * const result = await ingest(db, documents, {\n * generateEmbeddings: true,\n * embedder: async (texts) => embedModel.embed(texts),\n * });\n * ```\n */\nexport async function ingest(\n db: VectorDB,\n documents: SourceDocument[],\n options: IngestOptions = {}\n): Promise<IngestResult> {\n const startTime = Date.now();\n const {\n chunking = { strategy: 'recursive' },\n batchSize = DEFAULT_INGEST_OPTIONS.batchSize,\n onProgress,\n idPrefix = DEFAULT_INGEST_OPTIONS.idPrefix,\n generateEmbeddings = DEFAULT_INGEST_OPTIONS.generateEmbeddings,\n embedder,\n buildBM25Index = DEFAULT_INGEST_OPTIONS.buildBM25Index,\n bm25Options,\n } = options;\n\n // Validate options\n if (generateEmbeddings && !embedder) {\n throw new Error('embedder function is required when generateEmbeddings is true');\n }\n\n // Progress tracking\n const progress: IngestProgress = {\n phase: 'chunking',\n documentsProcessed: 0,\n totalDocuments: documents.length,\n chunksProcessed: 0,\n totalChunks: 0,\n currentBatch: 0,\n totalBatches: 0,\n };\n\n const reportProgress = () => {\n if (onProgress) {\n onProgress({ ...progress });\n }\n };\n\n // Phase 1: Chunking\n reportProgress();\n\n const allChunks: Array<{\n id: string;\n text: string;\n metadata: Record<string, unknown>;\n sourceDocId: string;\n chunkIndex: number;\n }> = [];\n\n for (const doc of documents) {\n const docId = doc.id || generateDocId();\n const chunks = chunk(doc.text, chunking as ChunkOptions);\n\n for (let i = 0; i < chunks.length; i++) {\n const c = chunks[i];\n allChunks.push({\n id: generateChunkId(docId, i, idPrefix),\n text: c.text,\n metadata: {\n ...doc.metadata,\n sourceDocId: docId,\n chunkIndex: i,\n chunkStart: c.start,\n chunkEnd: c.end,\n ...c.metadata,\n },\n sourceDocId: docId,\n chunkIndex: i,\n });\n }\n\n progress.documentsProcessed++;\n reportProgress();\n }\n\n progress.totalChunks = allChunks.length;\n progress.totalBatches = Math.ceil(allChunks.length / batchSize);\n\n // Phase 2: Embedding (if requested)\n let vectors: Float32Array[] = [];\n\n if (generateEmbeddings && embedder) {\n progress.phase = 'embedding';\n reportProgress();\n\n // Process in batches\n for (let i = 0; i < allChunks.length; i += batchSize) {\n const batch = allChunks.slice(i, i + batchSize);\n const texts = batch.map((c) => c.text);\n\n const batchVectors = await embedder(texts);\n vectors.push(...batchVectors);\n\n progress.chunksProcessed = Math.min(i + batchSize, allChunks.length);\n progress.currentBatch = Math.floor(i / batchSize) + 1;\n reportProgress();\n }\n }\n\n // Phase 3: Indexing\n progress.phase = 'indexing';\n progress.chunksProcessed = 0;\n progress.currentBatch = 0;\n reportProgress();\n\n const chunkIds: string[] = [];\n let bm25Index: BM25 | undefined;\n\n // Build BM25 index if requested\n if (buildBM25Index) {\n bm25Index = new BM25(bm25Options);\n for (const c of allChunks) {\n bm25Index.add(c.id, c.text);\n }\n }\n\n // If we have vectors, add to database\n if (vectors.length > 0) {\n const docsToAdd: Document[] = allChunks.map((c, i) => ({\n id: c.id,\n vector: vectors[i],\n metadata: { ...c.metadata, _text: c.text },\n }));\n\n // Add in batches\n for (let i = 0; i < docsToAdd.length; i += batchSize) {\n const batch = docsToAdd.slice(i, i + batchSize);\n await db.addMany(batch);\n\n chunkIds.push(...batch.map((d) => d.id));\n progress.chunksProcessed = Math.min(i + batchSize, docsToAdd.length);\n progress.currentBatch = Math.floor(i / batchSize) + 1;\n reportProgress();\n }\n } else {\n // Just track chunk IDs without adding to DB (user will add vectors later)\n for (const c of allChunks) {\n chunkIds.push(c.id);\n }\n progress.chunksProcessed = allChunks.length;\n progress.currentBatch = progress.totalBatches;\n reportProgress();\n }\n\n // Complete\n progress.phase = 'complete';\n reportProgress();\n\n return {\n documentsProcessed: documents.length,\n chunksCreated: allChunks.length,\n chunkIds,\n bm25Index,\n duration: Date.now() - startTime,\n };\n}\n\n/**\n * Chunk documents without ingesting into the database.\n *\n * Useful when you want to prepare chunks for manual processing.\n *\n * @param documents - Source documents\n * @param options - Chunking options\n * @returns Array of chunks with metadata\n *\n * @example\n * ```typescript\n * import { chunkDocuments } from '@localmode/core';\n *\n * const chunks = chunkDocuments(documents, {\n * chunking: { strategy: 'markdown', size: 500 },\n * });\n *\n * // Process chunks manually\n * for (const chunk of chunks) {\n * const embedding = await embedder.embed(chunk.text);\n * // ...\n * }\n * ```\n */\nexport function chunkDocuments(\n documents: SourceDocument[],\n options: { chunking?: ChunkOptions; idPrefix?: string } = {}\n): Array<{\n id: string;\n text: string;\n sourceDocId: string;\n chunkIndex: number;\n start: number;\n end: number;\n metadata?: Record<string, unknown>;\n}> {\n const { chunking = { strategy: 'recursive' }, idPrefix = 'chunk' } = options;\n\n const allChunks: Array<{\n id: string;\n text: string;\n sourceDocId: string;\n chunkIndex: number;\n start: number;\n end: number;\n metadata?: Record<string, unknown>;\n }> = [];\n\n for (const doc of documents) {\n const docId = doc.id || generateDocId();\n const chunks = chunk(doc.text, chunking);\n\n for (let i = 0; i < chunks.length; i++) {\n const c = chunks[i];\n allChunks.push({\n id: generateChunkId(docId, i, idPrefix),\n text: c.text,\n sourceDocId: docId,\n chunkIndex: i,\n start: c.start,\n end: c.end,\n metadata: {\n ...doc.metadata,\n ...c.metadata,\n },\n });\n }\n }\n\n return allChunks;\n}\n\n/**\n * Ingest pre-chunked and embedded documents.\n *\n * Use this when you've already processed chunks and embeddings externally.\n *\n * @param db - Vector database instance\n * @param chunks - Pre-processed chunks with vectors\n * @param options - Ingestion options\n * @returns Ingestion result\n *\n * @example\n * ```typescript\n * import { ingestChunks } from '@localmode/core';\n *\n * // Chunks with pre-computed embeddings\n * const chunks = [\n * { id: 'chunk1', text: 'Hello world', vector: embedding1 },\n * { id: 'chunk2', text: 'Goodbye world', vector: embedding2 },\n * ];\n *\n * await ingestChunks(db, chunks, {\n * buildBM25Index: true,\n * });\n * ```\n */\nexport async function ingestChunks(\n db: VectorDB,\n chunks: Array<{\n id: string;\n text: string;\n vector: Float32Array;\n metadata?: Record<string, unknown>;\n }>,\n options: {\n batchSize?: number;\n onProgress?: (completed: number, total: number) => void;\n buildBM25Index?: boolean;\n bm25Options?: IngestOptions['bm25Options'];\n } = {}\n): Promise<{\n chunksCreated: number;\n chunkIds: string[];\n bm25Index?: BM25Index;\n duration: number;\n}> {\n const startTime = Date.now();\n const { batchSize = 100, onProgress, buildBM25Index = false, bm25Options } = options;\n\n const chunkIds: string[] = [];\n let bm25Index: BM25 | undefined;\n\n // Build BM25 index if requested\n if (buildBM25Index) {\n bm25Index = new BM25(bm25Options);\n for (const c of chunks) {\n bm25Index.add(c.id, c.text);\n }\n }\n\n // Add to database in batches\n const docsToAdd: Document[] = chunks.map((c) => ({\n id: c.id,\n vector: c.vector,\n metadata: { ...c.metadata, _text: c.text },\n }));\n\n for (let i = 0; i < docsToAdd.length; i += batchSize) {\n const batch = docsToAdd.slice(i, i + batchSize);\n await db.addMany(batch);\n\n chunkIds.push(...batch.map((d) => d.id));\n\n if (onProgress) {\n onProgress(Math.min(i + batchSize, docsToAdd.length), docsToAdd.length);\n }\n }\n\n return {\n chunksCreated: chunks.length,\n chunkIds,\n bm25Index,\n duration: Date.now() - startTime,\n };\n}\n\n/**\n * Create an ingestion pipeline with preset options.\n *\n * @param db - Vector database instance\n * @param defaultOptions - Default ingestion options\n * @returns Configured ingest function\n *\n * @example\n * ```typescript\n * import { createIngestPipeline } from '@localmode/core';\n *\n * const pipeline = createIngestPipeline(db, {\n * chunking: { strategy: 'markdown', size: 1000 },\n * generateEmbeddings: true,\n * embedder: myEmbedder,\n * });\n *\n * // Now ingest multiple batches with same config\n * await pipeline(batch1);\n * await pipeline(batch2);\n * ```\n */\nexport function createIngestPipeline(\n db: VectorDB,\n defaultOptions: IngestOptions = {}\n): (documents: SourceDocument[], options?: Partial<IngestOptions>) => Promise<IngestResult> {\n return async (documents: SourceDocument[], options: Partial<IngestOptions> = {}) =>\n ingest(db, documents, { ...defaultOptions, ...options });\n}\n\n/**\n * Estimate ingestion statistics without actually ingesting.\n *\n * @param documents - Source documents\n * @param options - Chunking options\n * @returns Estimated statistics\n *\n * @example\n * ```typescript\n * import { estimateIngestion } from '@localmode/core';\n *\n * const estimate = estimateIngestion(documents, {\n * chunking: { strategy: 'recursive', size: 500 },\n * });\n *\n * console.log(`Will create ${estimate.estimatedChunks} chunks`);\n * ```\n */\nexport function estimateIngestion(\n documents: SourceDocument[],\n options: { chunking?: ChunkOptions } = {}\n): {\n totalDocuments: number;\n estimatedChunks: number;\n totalCharacters: number;\n avgChunkSize: number;\n} {\n const { chunking = { strategy: 'recursive' } } = options;\n\n let totalChunks = 0;\n let totalCharacters = 0;\n\n for (const doc of documents) {\n const chunks = chunk(doc.text, chunking);\n totalChunks += chunks.length;\n totalCharacters += chunks.reduce((sum, c) => sum + c.text.length, 0);\n }\n\n return {\n totalDocuments: documents.length,\n estimatedChunks: totalChunks,\n totalCharacters,\n avgChunkSize: totalChunks > 0 ? Math.round(totalCharacters / totalChunks) : 0,\n };\n}\n\n","/**\n * Encryption utilities using Web Crypto API.\n * Provides AES-GCM encryption for data at rest.\n */\n\n/**\n * Encryption configuration.\n */\nexport interface EncryptionConfig {\n /** Enable encryption */\n enabled: boolean;\n /** Key derivation iterations (higher = more secure, slower) */\n iterations?: number;\n}\n\n/**\n * Encrypted data format.\n */\nexport interface EncryptedData {\n /** Base64-encoded encrypted data */\n ciphertext: string;\n /** Base64-encoded IV */\n iv: string;\n /** Key derivation salt */\n salt: string;\n /** Algorithm identifier */\n algorithm: 'AES-GCM';\n /** Version for future compatibility */\n version: 1;\n}\n\n/**\n * Default PBKDF2 iterations for key derivation.\n */\nconst DEFAULT_ITERATIONS = 100000;\n\n/**\n * Check if Web Crypto API is available.\n */\nexport function isCryptoSupported(): boolean {\n return (\n typeof crypto !== 'undefined' &&\n typeof crypto.subtle !== 'undefined' &&\n typeof crypto.getRandomValues === 'function'\n );\n}\n\n/**\n * Generate random bytes.\n */\nfunction getRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n crypto.getRandomValues(bytes);\n return bytes;\n}\n\n/**\n * Convert ArrayBuffer to base64 string.\n */\nfunction arrayBufferToBase64(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Convert base64 string to ArrayBuffer.\n */\nfunction base64ToArrayBuffer(base64: string): ArrayBuffer {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes.buffer;\n}\n\n/**\n * Derive an encryption key from a passphrase using PBKDF2.\n */\nasync function deriveKey(\n passphrase: string,\n salt: Uint8Array,\n iterations: number\n): Promise<CryptoKey> {\n // Import passphrase as key material\n const encoder = new TextEncoder();\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(passphrase),\n { name: 'PBKDF2' },\n false,\n ['deriveKey']\n );\n\n // Derive AES-GCM key\n return crypto.subtle.deriveKey(\n {\n name: 'PBKDF2',\n salt: salt.buffer as ArrayBuffer,\n iterations,\n hash: 'SHA-256',\n },\n keyMaterial,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\n/**\n * Encrypt data using AES-GCM.\n */\nexport async function encrypt(\n data: string | ArrayBuffer,\n passphrase: string,\n iterations: number = DEFAULT_ITERATIONS\n): Promise<EncryptedData> {\n if (!isCryptoSupported()) {\n throw new Error('Web Crypto API not supported');\n }\n\n // Generate salt and IV\n const salt = getRandomBytes(16);\n const iv = getRandomBytes(12);\n\n // Derive key from passphrase\n const key = await deriveKey(passphrase, salt, iterations);\n\n // Convert data to ArrayBuffer if string\n let plaintext: ArrayBuffer;\n if (typeof data === 'string') {\n const encoder = new TextEncoder();\n plaintext = encoder.encode(data).buffer;\n } else {\n plaintext = data;\n }\n\n // Encrypt\n const ciphertext = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv: iv.buffer as ArrayBuffer },\n key,\n plaintext\n );\n\n return {\n ciphertext: arrayBufferToBase64(ciphertext),\n iv: arrayBufferToBase64(iv.buffer as ArrayBuffer),\n salt: arrayBufferToBase64(salt.buffer as ArrayBuffer),\n algorithm: 'AES-GCM',\n version: 1,\n };\n}\n\n/**\n * Decrypt data using AES-GCM.\n */\nexport async function decrypt(\n encrypted: EncryptedData,\n passphrase: string,\n iterations: number = DEFAULT_ITERATIONS\n): Promise<ArrayBuffer> {\n if (!isCryptoSupported()) {\n throw new Error('Web Crypto API not supported');\n }\n\n if (encrypted.algorithm !== 'AES-GCM') {\n throw new Error(`Unsupported algorithm: ${encrypted.algorithm}`);\n }\n\n // Decode salt and IV\n const salt = new Uint8Array(base64ToArrayBuffer(encrypted.salt));\n const iv = new Uint8Array(base64ToArrayBuffer(encrypted.iv));\n const ciphertext = base64ToArrayBuffer(encrypted.ciphertext);\n\n // Derive key from passphrase\n const key = await deriveKey(passphrase, salt, iterations);\n\n // Decrypt\n try {\n return await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: iv.buffer as ArrayBuffer },\n key,\n ciphertext\n );\n } catch {\n throw new Error('Decryption failed: invalid passphrase or corrupted data');\n }\n}\n\n/**\n * Decrypt data as a string.\n */\nexport async function decryptString(\n encrypted: EncryptedData,\n passphrase: string,\n iterations: number = DEFAULT_ITERATIONS\n): Promise<string> {\n const plaintext = await decrypt(encrypted, passphrase, iterations);\n const decoder = new TextDecoder();\n return decoder.decode(plaintext);\n}\n\n/**\n * Encrypt a Float32Array (for vectors).\n */\nexport async function encryptVector(\n vector: Float32Array,\n passphrase: string,\n iterations: number = DEFAULT_ITERATIONS\n): Promise<EncryptedData> {\n return encrypt(vector.buffer as ArrayBuffer, passphrase, iterations);\n}\n\n/**\n * Decrypt a Float32Array (for vectors).\n */\nexport async function decryptVector(\n encrypted: EncryptedData,\n passphrase: string,\n iterations: number = DEFAULT_ITERATIONS\n): Promise<Float32Array> {\n const buffer = await decrypt(encrypted, passphrase, iterations);\n return new Float32Array(buffer);\n}\n\n/**\n * Encrypt a JSON-serializable object.\n */\nexport async function encryptJSON(\n data: unknown,\n passphrase: string,\n iterations: number = DEFAULT_ITERATIONS\n): Promise<EncryptedData> {\n const json = JSON.stringify(data);\n return encrypt(json, passphrase, iterations);\n}\n\n/**\n * Decrypt a JSON object.\n */\nexport async function decryptJSON<T = unknown>(\n encrypted: EncryptedData,\n passphrase: string,\n iterations: number = DEFAULT_ITERATIONS\n): Promise<T> {\n const json = await decryptString(encrypted, passphrase, iterations);\n return JSON.parse(json) as T;\n}\n\n/**\n * Hash a passphrase for verification (not for encryption key).\n */\nexport async function hashPassphrase(passphrase: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(passphrase);\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n return arrayBufferToBase64(hashBuffer);\n}\n\n/**\n * Verify a passphrase against a stored hash.\n */\nexport async function verifyPassphrase(passphrase: string, hash: string): Promise<boolean> {\n const newHash = await hashPassphrase(passphrase);\n // Constant-time comparison to prevent timing attacks\n if (newHash.length !== hash.length) {\n return false;\n }\n let result = 0;\n for (let i = 0; i < newHash.length; i++) {\n result |= newHash.charCodeAt(i) ^ hash.charCodeAt(i);\n }\n return result === 0;\n}\n","/**\n * Key storage and management.\n * Handles secure storage of encryption keys in IndexedDB.\n */\n\nimport { hashPassphrase, verifyPassphrase, isCryptoSupported } from './crypto.js';\n\n/**\n * Key metadata stored in IndexedDB.\n */\nexport interface KeyMetadata {\n /** Database this key is for */\n dbName: string;\n /** Hash of the passphrase for verification */\n passphraseHash: string;\n /** When the key was created */\n createdAt: number;\n /** When the key was last used */\n lastUsedAt: number;\n /** Number of key derivation iterations */\n iterations: number;\n /** Whether encryption is currently enabled */\n enabled: boolean;\n}\n\n/**\n * Store name for key metadata.\n */\nconst KEYSTORE_DB_NAME = 'vectordb_keystore';\nconst KEYSTORE_VERSION = 1;\nconst KEY_STORE_NAME = 'keys';\n\n/**\n * Open the keystore database.\n */\nasync function openKeystore(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(KEYSTORE_DB_NAME, KEYSTORE_VERSION);\n\n request.onerror = () => reject(new Error(`Failed to open keystore: ${request.error?.message}`));\n\n request.onsuccess = () => resolve(request.result);\n\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(KEY_STORE_NAME)) {\n db.createObjectStore(KEY_STORE_NAME, { keyPath: 'dbName' });\n }\n };\n });\n}\n\n/**\n * Keystore manager for encryption keys.\n */\nexport class Keystore {\n private passphrase: string | null = null;\n private iterations: number = 100000;\n\n /**\n * Check if encryption is supported.\n */\n static isSupported(): boolean {\n return isCryptoSupported();\n }\n\n /**\n * Initialize encryption for a database with a passphrase.\n * This stores the passphrase hash for verification.\n */\n async initialize(dbName: string, passphrase: string, iterations: number = 100000): Promise<void> {\n if (!Keystore.isSupported()) {\n throw new Error('Web Crypto API not supported');\n }\n\n const db = await openKeystore();\n\n try {\n const hash = await hashPassphrase(passphrase);\n\n const metadata: KeyMetadata = {\n dbName,\n passphraseHash: hash,\n createdAt: Date.now(),\n lastUsedAt: Date.now(),\n iterations,\n enabled: true,\n };\n\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(KEY_STORE_NAME, 'readwrite');\n const store = tx.objectStore(KEY_STORE_NAME);\n const request = store.put(metadata);\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve();\n });\n\n this.passphrase = passphrase;\n this.iterations = iterations;\n } finally {\n db.close();\n }\n }\n\n /**\n * Unlock encryption for a database by verifying the passphrase.\n */\n async unlock(dbName: string, passphrase: string): Promise<boolean> {\n if (!Keystore.isSupported()) {\n throw new Error('Web Crypto API not supported');\n }\n\n const metadata = await this.getMetadata(dbName);\n\n if (!metadata) {\n throw new Error(`No encryption configured for database: ${dbName}`);\n }\n\n const isValid = await verifyPassphrase(passphrase, metadata.passphraseHash);\n\n if (isValid) {\n this.passphrase = passphrase;\n this.iterations = metadata.iterations;\n await this.updateLastUsed(dbName);\n }\n\n return isValid;\n }\n\n /**\n * Lock encryption (clear the passphrase from memory).\n */\n lock(): void {\n this.passphrase = null;\n }\n\n /**\n * Check if encryption is unlocked.\n */\n isUnlocked(): boolean {\n return this.passphrase !== null;\n }\n\n /**\n * Get the current passphrase (throws if locked).\n */\n getPassphrase(): string {\n if (!this.passphrase) {\n throw new Error('Encryption is locked. Call unlock() first.');\n }\n return this.passphrase;\n }\n\n /**\n * Get the key derivation iterations.\n */\n getIterations(): number {\n return this.iterations;\n }\n\n /**\n * Get key metadata for a database.\n */\n async getMetadata(dbName: string): Promise<KeyMetadata | null> {\n const db = await openKeystore();\n\n try {\n return await new Promise((resolve, reject) => {\n const tx = db.transaction(KEY_STORE_NAME, 'readonly');\n const store = tx.objectStore(KEY_STORE_NAME);\n const request = store.get(dbName);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve(request.result ?? null);\n });\n } finally {\n db.close();\n }\n }\n\n /**\n * Check if a database has encryption configured.\n */\n async hasEncryption(dbName: string): Promise<boolean> {\n const metadata = await this.getMetadata(dbName);\n return metadata?.enabled ?? false;\n }\n\n /**\n * Update the last used timestamp.\n */\n private async updateLastUsed(dbName: string): Promise<void> {\n const db = await openKeystore();\n\n try {\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(KEY_STORE_NAME, 'readwrite');\n const store = tx.objectStore(KEY_STORE_NAME);\n const getRequest = store.get(dbName);\n\n getRequest.onerror = () => reject(getRequest.error);\n getRequest.onsuccess = () => {\n const metadata = getRequest.result as KeyMetadata | undefined;\n if (metadata) {\n metadata.lastUsedAt = Date.now();\n store.put(metadata);\n }\n };\n\n tx.oncomplete = () => resolve();\n });\n } finally {\n db.close();\n }\n }\n\n /**\n * Change the encryption passphrase.\n * Note: This only updates the stored hash, not re-encrypted data.\n */\n async changePassphrase(\n dbName: string,\n oldPassphrase: string,\n newPassphrase: string\n ): Promise<boolean> {\n // Verify old passphrase\n const isValid = await this.unlock(dbName, oldPassphrase);\n if (!isValid) {\n return false;\n }\n\n // Update with new passphrase\n const db = await openKeystore();\n\n try {\n const newHash = await hashPassphrase(newPassphrase);\n\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(KEY_STORE_NAME, 'readwrite');\n const store = tx.objectStore(KEY_STORE_NAME);\n const getRequest = store.get(dbName);\n\n getRequest.onerror = () => reject(getRequest.error);\n getRequest.onsuccess = () => {\n const metadata = getRequest.result as KeyMetadata | undefined;\n if (metadata) {\n metadata.passphraseHash = newHash;\n metadata.lastUsedAt = Date.now();\n store.put(metadata);\n }\n };\n\n tx.oncomplete = () => resolve();\n });\n\n this.passphrase = newPassphrase;\n return true;\n } finally {\n db.close();\n }\n }\n\n /**\n * Disable encryption for a database.\n */\n async disable(dbName: string, passphrase: string): Promise<boolean> {\n // Verify passphrase first\n const isValid = await this.unlock(dbName, passphrase);\n if (!isValid) {\n return false;\n }\n\n const db = await openKeystore();\n\n try {\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(KEY_STORE_NAME, 'readwrite');\n const store = tx.objectStore(KEY_STORE_NAME);\n const getRequest = store.get(dbName);\n\n getRequest.onerror = () => reject(getRequest.error);\n getRequest.onsuccess = () => {\n const metadata = getRequest.result as KeyMetadata | undefined;\n if (metadata) {\n metadata.enabled = false;\n metadata.lastUsedAt = Date.now();\n store.put(metadata);\n }\n };\n\n tx.oncomplete = () => resolve();\n });\n\n this.lock();\n return true;\n } finally {\n db.close();\n }\n }\n\n /**\n * Delete key metadata for a database.\n */\n async delete(dbName: string): Promise<void> {\n const db = await openKeystore();\n\n try {\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(KEY_STORE_NAME, 'readwrite');\n const store = tx.objectStore(KEY_STORE_NAME);\n const request = store.delete(dbName);\n\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve();\n });\n\n this.lock();\n } finally {\n db.close();\n }\n }\n}\n\n/**\n * Create a new keystore instance.\n */\nexport function createKeystore(): Keystore {\n return new Keystore();\n}\n","/**\n * PII (Personally Identifiable Information) Redaction Utilities\n *\n * Provides utilities for detecting and redacting PII from text data\n * before embedding or storing in the vector database.\n *\n * @packageDocumentation\n */\n\nimport type { EmbeddingModelMiddleware } from '../embeddings/types.js';\nimport type { VectorDBMiddleware } from '../middleware/types.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Options for PII redaction.\n */\nexport interface PIIRedactionOptions {\n /** Redact email addresses (default: true) */\n emails?: boolean;\n\n /** Redact phone numbers (default: true) */\n phones?: boolean;\n\n /** Redact SSN patterns (default: true) */\n ssn?: boolean;\n\n /** Redact credit card numbers (default: true) */\n creditCards?: boolean;\n\n /** Redact IP addresses (default: false) */\n ipAddresses?: boolean;\n\n /** Redact dates (default: false) */\n dates?: boolean;\n\n /** Custom patterns to redact */\n customPatterns?: Array<{ pattern: RegExp; replacement: string }>;\n\n /** Replacement text for redacted content (default: '[REDACTED]') */\n replacement?: string;\n\n /** Category-specific replacements */\n replacements?: {\n email?: string;\n phone?: string;\n ssn?: string;\n creditCard?: string;\n ipAddress?: string;\n date?: string;\n };\n}\n\n/**\n * Result of PII detection.\n */\nexport interface PIIDetectionResult {\n /** Whether any PII was detected */\n hasPII: boolean;\n\n /** Detected PII types and their positions */\n detections: PIIDetection[];\n\n /** Redacted text (if applicable) */\n redactedText?: string;\n}\n\n/**\n * A single PII detection.\n */\nexport interface PIIDetection {\n /** Type of PII detected */\n type: PIIType;\n\n /** Start position in the text */\n start: number;\n\n /** End position in the text */\n end: number;\n\n /** Original matched text (masked for security) */\n maskedMatch: string;\n}\n\n/**\n * Types of PII that can be detected.\n */\nexport type PIIType = 'email' | 'phone' | 'ssn' | 'creditCard' | 'ipAddress' | 'date' | 'custom';\n\n// ============================================================================\n// PII Patterns\n// ============================================================================\n\n/**\n * Regular expression patterns for common PII types.\n */\nexport const PII_PATTERNS = {\n /**\n * Email address pattern.\n * Matches: user@domain.com, first.last@company.co.uk\n */\n email: /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b/g,\n\n /**\n * Phone number patterns (US-focused, with international prefix).\n * Matches: 555-123-4567, (555) 123-4567, +1-555-123-4567, 5551234567\n */\n phone: /\\b(?:\\+1[-.\\s]?)?(?:\\(?[0-9]{3}\\)?[-.\\s]?)?[0-9]{3}[-.\\s]?[0-9]{4}\\b/g,\n\n /**\n * Social Security Number pattern.\n * Matches: 123-45-6789\n */\n ssn: /\\b\\d{3}-\\d{2}-\\d{4}\\b/g,\n\n /**\n * Credit card number patterns.\n * Matches: 1234 5678 9012 3456, 1234-5678-9012-3456, 1234567890123456\n */\n creditCard: /\\b(?:\\d{4}[-\\s]?){3}\\d{4}\\b/g,\n\n /**\n * IPv4 address pattern.\n * Matches: 192.168.1.1\n */\n ipAddress: /\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b/g,\n\n /**\n * Common date patterns.\n * Matches: 01/15/2024, 2024-01-15, January 15, 2024\n */\n date: /\\b(?:\\d{1,2}[\\/\\-]\\d{1,2}[\\/\\-]\\d{2,4}|\\d{4}[\\/\\-]\\d{1,2}[\\/\\-]\\d{1,2}|(?:January|February|March|April|May|June|July|August|September|October|November|December)\\s+\\d{1,2},?\\s+\\d{4})\\b/gi,\n} as const;\n\n/**\n * Default replacement strings for different PII types.\n */\nexport const DEFAULT_PII_REPLACEMENTS = {\n email: '[EMAIL_REDACTED]',\n phone: '[PHONE_REDACTED]',\n ssn: '[SSN_REDACTED]',\n creditCard: '[CARD_REDACTED]',\n ipAddress: '[IP_REDACTED]',\n date: '[DATE_REDACTED]',\n custom: '[REDACTED]',\n} as const;\n\n// ============================================================================\n// Core Functions\n// ============================================================================\n\n/**\n * Redact PII from text.\n *\n * @param text - The text to redact PII from\n * @param options - Redaction options\n * @returns Redacted text\n *\n * @example\n * ```typescript\n * import { redactPII } from '@localmode/core';\n *\n * const text = 'Contact john@example.com or call 555-123-4567';\n * const redacted = redactPII(text);\n * // 'Contact [EMAIL_REDACTED] or call [PHONE_REDACTED]'\n *\n * // Custom replacement\n * const masked = redactPII(text, { replacement: '***' });\n * // 'Contact *** or call ***'\n * ```\n */\nexport function redactPII(text: string, options: PIIRedactionOptions = {}): string {\n const {\n emails = true,\n phones = true,\n ssn = true,\n creditCards = true,\n ipAddresses = false,\n dates = false,\n customPatterns = [],\n replacement,\n replacements = {},\n } = options;\n\n let result = text;\n\n // Create a function to get the replacement for a PII type\n const getReplacement = (type: PIIType): string => {\n if (replacement) return replacement;\n if (type in replacements) {\n return replacements[type as keyof typeof replacements] ?? DEFAULT_PII_REPLACEMENTS[type];\n }\n return DEFAULT_PII_REPLACEMENTS[type] ?? DEFAULT_PII_REPLACEMENTS.custom;\n };\n\n // Apply redactions in order\n if (emails) {\n result = result.replace(PII_PATTERNS.email, getReplacement('email'));\n }\n\n if (phones) {\n result = result.replace(PII_PATTERNS.phone, getReplacement('phone'));\n }\n\n if (ssn) {\n result = result.replace(PII_PATTERNS.ssn, getReplacement('ssn'));\n }\n\n if (creditCards) {\n result = result.replace(PII_PATTERNS.creditCard, getReplacement('creditCard'));\n }\n\n if (ipAddresses) {\n result = result.replace(PII_PATTERNS.ipAddress, getReplacement('ipAddress'));\n }\n\n if (dates) {\n result = result.replace(PII_PATTERNS.date, getReplacement('date'));\n }\n\n // Apply custom patterns\n for (const { pattern, replacement: customReplacement } of customPatterns) {\n result = result.replace(pattern, customReplacement);\n }\n\n return result;\n}\n\n/**\n * Detect PII in text without redacting.\n *\n * @param text - The text to scan for PII\n * @param options - Detection options (same as redaction options)\n * @returns Detection result with positions and types of PII found\n *\n * @example\n * ```typescript\n * import { detectPII } from '@localmode/core';\n *\n * const result = detectPII('Email: john@example.com');\n * console.log(result.hasPII); // true\n * console.log(result.detections[0].type); // 'email'\n * ```\n */\nexport function detectPII(text: string, options: PIIRedactionOptions = {}): PIIDetectionResult {\n const {\n emails = true,\n phones = true,\n ssn = true,\n creditCards = true,\n ipAddresses = false,\n dates = false,\n customPatterns = [],\n } = options;\n\n const detections: PIIDetection[] = [];\n\n const detectPattern = (pattern: RegExp, type: PIIType) => {\n // Create a new regex to avoid shared state issues\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(text)) !== null) {\n detections.push({\n type,\n start: match.index,\n end: match.index + match[0].length,\n maskedMatch: maskPII(match[0], type),\n });\n }\n };\n\n if (emails) detectPattern(PII_PATTERNS.email, 'email');\n if (phones) detectPattern(PII_PATTERNS.phone, 'phone');\n if (ssn) detectPattern(PII_PATTERNS.ssn, 'ssn');\n if (creditCards) detectPattern(PII_PATTERNS.creditCard, 'creditCard');\n if (ipAddresses) detectPattern(PII_PATTERNS.ipAddress, 'ipAddress');\n if (dates) detectPattern(PII_PATTERNS.date, 'date');\n\n // Custom patterns\n for (const { pattern } of customPatterns) {\n detectPattern(pattern, 'custom');\n }\n\n // Sort by position\n detections.sort((a, b) => a.start - b.start);\n\n return {\n hasPII: detections.length > 0,\n detections,\n redactedText: detections.length > 0 ? redactPII(text, options) : text,\n };\n}\n\n/**\n * Mask a PII match for safe logging/display.\n * Shows first and last characters with masked middle.\n */\nfunction maskPII(match: string, type: PIIType): string {\n if (match.length <= 4) {\n return '*'.repeat(match.length);\n }\n\n switch (type) {\n case 'email': {\n const atIndex = match.indexOf('@');\n if (atIndex > 2) {\n return match[0] + '*'.repeat(atIndex - 2) + match.slice(atIndex - 1);\n }\n return '*'.repeat(match.length);\n }\n case 'creditCard':\n // Show last 4 digits\n return '*'.repeat(match.length - 4) + match.slice(-4);\n case 'phone':\n // Show last 4 digits\n return '*'.repeat(match.length - 4) + match.slice(-4);\n case 'ssn':\n // Show last 4 digits\n return '***-**-' + match.slice(-4);\n default:\n // Generic masking\n return match[0] + '*'.repeat(match.length - 2) + match[match.length - 1];\n }\n}\n\n// ============================================================================\n// Middleware Functions\n// ============================================================================\n\n/**\n * Create an embedding model middleware that redacts PII before embedding.\n *\n * @param options - PII redaction options\n * @returns Embedding model middleware\n *\n * @example\n * ```typescript\n * import { embed, wrapEmbeddingModel, piiRedactionMiddleware } from '@localmode/core';\n *\n * const safeModel = wrapEmbeddingModel({\n * model: transformers.embedding('Xenova/all-MiniLM-L6-v2'),\n * middleware: piiRedactionMiddleware({ emails: true, phones: true }),\n * });\n *\n * await embed({\n * model: safeModel,\n * value: 'Contact john@example.com at 555-123-4567',\n * });\n * // Embeds: 'Contact [EMAIL_REDACTED] at [PHONE_REDACTED]'\n * ```\n */\nexport function piiRedactionMiddleware(\n options: PIIRedactionOptions = {}\n): EmbeddingModelMiddleware {\n return {\n transformParams: ({ values }) => {\n return {\n values: values.map((v) => (typeof v === 'string' ? redactPII(v, options) : v)),\n };\n },\n };\n}\n\n/**\n * Create a VectorDB middleware that redacts PII from document text before storage.\n *\n * @param options - PII redaction options\n * @returns VectorDB middleware\n *\n * @example\n * ```typescript\n * import { createVectorDB, wrapVectorDB, piiRedactionVectorDBMiddleware } from '@localmode/core';\n *\n * const db = await createVectorDB({ name: 'safe-db', dimensions: 384 });\n * const safeDb = wrapVectorDB({\n * db,\n * middleware: piiRedactionVectorDBMiddleware({ emails: true }),\n * });\n * ```\n */\nexport function piiRedactionVectorDBMiddleware(\n options: PIIRedactionOptions = {}\n): VectorDBMiddleware {\n return {\n beforeAdd: (document) => {\n // Redact PII from metadata text fields\n if (document.metadata) {\n const redactedMetadata = { ...document.metadata };\n\n for (const [key, value] of Object.entries(redactedMetadata)) {\n if (typeof value === 'string') {\n redactedMetadata[key] = redactPII(value, options);\n }\n }\n\n return { ...document, metadata: redactedMetadata };\n }\n\n return document;\n },\n };\n}\n\n/**\n * Check if text contains any PII.\n *\n * @param text - Text to check\n * @param options - Detection options\n * @returns true if PII is detected\n *\n * @example\n * ```typescript\n * if (hasPII(userInput)) {\n * console.warn('Input contains PII');\n * }\n * ```\n */\nexport function hasPII(text: string, options: PIIRedactionOptions = {}): boolean {\n return detectPII(text, options).hasPII;\n}\n\n","/**\n * Encryption Middleware for VectorDB\n *\n * Provides encryption-at-rest for vectors and metadata stored in VectorDB.\n *\n * @packageDocumentation\n */\n\nimport type { VectorDBMiddleware, EncryptionMiddlewareOptions } from '../middleware/types.js';\nimport type { Document } from '../types.js';\n\n// ============================================================================\n// Encryption Middleware\n// ============================================================================\n\n/**\n * Create a VectorDB middleware that encrypts/decrypts documents.\n *\n * Uses AES-GCM encryption via the Web Crypto API.\n *\n * @param options - Encryption options including the CryptoKey\n * @returns VectorDB middleware\n *\n * @example\n * ```typescript\n * import { createVectorDB, wrapVectorDB, encryptionMiddleware, deriveKey } from '@localmode/core';\n *\n * // Derive a key from user password\n * const key = await deriveEncryptionKey('user-password');\n *\n * // Create encrypted database\n * const db = await createVectorDB({ name: 'encrypted-db', dimensions: 384 });\n * const encryptedDb = wrapVectorDB({\n * db,\n * middleware: encryptionMiddleware({ key }),\n * });\n *\n * // Data is encrypted before storage, decrypted on retrieval\n * await encryptedDb.add({ id: '1', vector, metadata: { secret: 'data' } });\n * ```\n */\nexport function encryptionMiddleware(options: EncryptionMiddlewareOptions): VectorDBMiddleware {\n const {\n key,\n encryptVectors = true,\n encryptMetadata = true,\n encryptText = true,\n excludeFields = [],\n } = options;\n\n // Cache for encrypted vectors (to avoid re-encrypting on search)\n const encryptedVectorCache = new Map<string, Float32Array>();\n\n return {\n beforeAdd: async (document: Document): Promise<Document> => {\n const result: Document = {\n id: document.id,\n vector: document.vector,\n metadata: document.metadata ? { ...document.metadata } : undefined,\n };\n\n // Encrypt vector\n if (encryptVectors && result.vector) {\n const encrypted = await encryptFloat32Array(result.vector, key);\n // Store encrypted as Float32Array (actually encrypted bytes)\n result.vector = encrypted;\n encryptedVectorCache.set(document.id, encrypted);\n }\n\n // Encrypt metadata fields\n if (encryptMetadata && result.metadata) {\n const encryptedMetadata: Record<string, unknown> = {};\n\n for (const [field, value] of Object.entries(result.metadata)) {\n if (excludeFields.includes(field)) {\n encryptedMetadata[field] = value;\n } else if (typeof value === 'string' && encryptText) {\n encryptedMetadata[field] = await encryptString(value, key);\n } else if (value !== null && typeof value === 'object') {\n encryptedMetadata[field] = await encryptJSON(value, key);\n } else {\n // Primitives (numbers, booleans) - encrypt as string\n encryptedMetadata[field] = await encryptString(JSON.stringify(value), key);\n }\n }\n\n result.metadata = encryptedMetadata;\n }\n\n return result;\n },\n\n afterGet: async (document: Document | undefined): Promise<Document | undefined> => {\n if (!document) return undefined;\n\n const result: Document = {\n id: document.id,\n vector: document.vector,\n metadata: document.metadata ? { ...document.metadata } : undefined,\n };\n\n // Decrypt vector\n if (encryptVectors && result.vector) {\n try {\n result.vector = await decryptFloat32Array(result.vector, key);\n } catch {\n // If decryption fails, vector might not be encrypted (migration case)\n // Keep original\n }\n }\n\n // Decrypt metadata fields\n if (encryptMetadata && result.metadata) {\n const decryptedMetadata: Record<string, unknown> = {};\n\n for (const [field, value] of Object.entries(result.metadata)) {\n if (excludeFields.includes(field)) {\n decryptedMetadata[field] = value;\n } else if (isEncryptedString(value)) {\n try {\n const decrypted = await decryptString(value as EncryptedString, key);\n // Try to parse as JSON for complex types\n try {\n decryptedMetadata[field] = JSON.parse(decrypted);\n } catch {\n decryptedMetadata[field] = decrypted;\n }\n } catch {\n // Decryption failed, keep original\n decryptedMetadata[field] = value;\n }\n } else {\n decryptedMetadata[field] = value;\n }\n }\n\n result.metadata = decryptedMetadata;\n }\n\n return result;\n },\n\n afterSearch: async (results) => {\n // Decrypt metadata in search results\n if (!encryptMetadata) return results;\n\n return Promise.all(\n results.map(async (result) => {\n if (!result.metadata) return result;\n\n const decryptedMetadata: Record<string, unknown> = {};\n\n for (const [field, value] of Object.entries(result.metadata)) {\n if (excludeFields.includes(field)) {\n decryptedMetadata[field] = value;\n } else if (isEncryptedString(value)) {\n try {\n const decrypted = await decryptString(value as EncryptedString, key);\n try {\n decryptedMetadata[field] = JSON.parse(decrypted);\n } catch {\n decryptedMetadata[field] = decrypted;\n }\n } catch {\n decryptedMetadata[field] = value;\n }\n } else {\n decryptedMetadata[field] = value;\n }\n }\n\n return { ...result, metadata: decryptedMetadata };\n })\n );\n },\n };\n}\n\n// ============================================================================\n// Encryption Helpers\n// ============================================================================\n\n/**\n * Encrypted string format (stored as JSON string).\n */\ninterface EncryptedString {\n __encrypted: true;\n ciphertext: string;\n iv: string;\n}\n\n/**\n * Check if a value is an encrypted string.\n */\nfunction isEncryptedString(value: unknown): value is EncryptedString {\n return (\n typeof value === 'object' &&\n value !== null &&\n '__encrypted' in value &&\n (value as EncryptedString).__encrypted === true\n );\n}\n\n/**\n * Encrypt a string using AES-GCM.\n */\nasync function encryptString(text: string, key: CryptoKey): Promise<EncryptedString> {\n const encoder = new TextEncoder();\n const data = encoder.encode(text);\n const iv = crypto.getRandomValues(new Uint8Array(12));\n\n const ciphertext = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, data);\n\n return {\n __encrypted: true,\n ciphertext: arrayBufferToBase64(ciphertext),\n iv: arrayBufferToBase64(iv.buffer),\n };\n}\n\n/**\n * Decrypt an encrypted string.\n */\nasync function decryptString(encrypted: EncryptedString, key: CryptoKey): Promise<string> {\n const ciphertext = base64ToArrayBuffer(encrypted.ciphertext);\n const iv = base64ToArrayBuffer(encrypted.iv);\n\n const decrypted = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: new Uint8Array(iv) }, key, ciphertext);\n\n const decoder = new TextDecoder();\n return decoder.decode(decrypted);\n}\n\n/**\n * Encrypt a JSON object.\n */\nasync function encryptJSON(data: unknown, key: CryptoKey): Promise<EncryptedString> {\n return encryptString(JSON.stringify(data), key);\n}\n\n/**\n * Encrypt a Float32Array.\n */\nasync function encryptFloat32Array(vector: Float32Array, key: CryptoKey): Promise<Float32Array> {\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const ciphertext = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv },\n key,\n vector.buffer as ArrayBuffer\n );\n\n // Combine IV and ciphertext into a single array\n const combined = new Uint8Array(iv.length + ciphertext.byteLength);\n combined.set(iv, 0);\n combined.set(new Uint8Array(ciphertext), iv.length);\n\n // Return as Float32Array for storage compatibility\n // Pad to multiple of 4 bytes\n const paddedLength = Math.ceil(combined.length / 4) * 4;\n const padded = new Uint8Array(paddedLength);\n padded.set(combined);\n\n return new Float32Array(padded.buffer);\n}\n\n/**\n * Decrypt a Float32Array.\n */\nasync function decryptFloat32Array(encrypted: Float32Array, key: CryptoKey): Promise<Float32Array> {\n // Convert back to Uint8Array\n const combined = new Uint8Array(encrypted.buffer);\n\n // Extract IV (first 12 bytes)\n const iv = combined.slice(0, 12);\n const ciphertext = combined.slice(12);\n\n const decrypted = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, ciphertext);\n\n return new Float32Array(decrypted);\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Convert ArrayBuffer to base64 string.\n */\nfunction arrayBufferToBase64(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Convert base64 string to ArrayBuffer.\n */\nfunction base64ToArrayBuffer(base64: string): ArrayBuffer {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes.buffer;\n}\n\n// ============================================================================\n// Key Derivation\n// ============================================================================\n\n/**\n * Derive an AES-GCM encryption key from a password.\n *\n * @param password - The password to derive the key from\n * @param salt - Optional salt (will be generated if not provided)\n * @param iterations - PBKDF2 iterations (default: 100000)\n * @returns The derived CryptoKey and salt used\n *\n * @example\n * ```typescript\n * const { key, salt } = await deriveEncryptionKey('user-password');\n * // Store salt securely for later key derivation\n * localStorage.setItem('encryption-salt', salt);\n * ```\n */\nexport async function deriveEncryptionKey(\n password: string,\n salt?: string | Uint8Array,\n iterations: number = 100000\n): Promise<{ key: CryptoKey; salt: string }> {\n const encoder = new TextEncoder();\n let saltBytes: Uint8Array;\n \n if (!salt) {\n saltBytes = crypto.getRandomValues(new Uint8Array(16));\n } else if (salt instanceof Uint8Array) {\n saltBytes = salt;\n } else {\n saltBytes = new Uint8Array(base64ToArrayBuffer(salt));\n }\n\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(password),\n { name: 'PBKDF2' },\n false,\n ['deriveKey']\n );\n\n const key = await crypto.subtle.deriveKey(\n {\n name: 'PBKDF2',\n salt: saltBytes as BufferSource,\n iterations,\n hash: 'SHA-256',\n },\n keyMaterial,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt']\n );\n\n return {\n key,\n salt: arrayBufferToBase64(saltBytes.buffer as ArrayBuffer),\n };\n}\n\n/**\n * Alias for deriveEncryptionKey for backward compatibility.\n * \n * @deprecated Use deriveEncryptionKey instead\n */\nexport const deriveKey = deriveEncryptionKey;\n\n","/**\n * Text Document Loader\n *\n * Loader for plain text documents.\n * Zero external dependencies.\n *\n * @packageDocumentation\n */\n\nimport type { DocumentLoader, LoaderSource, LoadedDocument, LoadedDocumentMetadata, TextLoaderOptions } from './types.js';\n\n/**\n * Generate a unique document ID.\n */\nfunction generateId(): string {\n return `doc_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n}\n\n/**\n * Text document loader.\n *\n * Loads plain text documents from strings, files, or blobs.\n *\n * @example\n * ```typescript\n * import { TextLoader } from '@localmode/core';\n *\n * const loader = new TextLoader();\n * const docs = await loader.load('Hello, world!');\n * console.log(docs[0].text); // 'Hello, world!'\n *\n * // With separator (splits into multiple documents)\n * const multiLoader = new TextLoader({ separator: '\\n\\n' });\n * const paragraphs = await multiLoader.load('Para 1\\n\\nPara 2');\n * console.log(paragraphs.length); // 2\n * ```\n */\nexport class TextLoader implements DocumentLoader<TextLoaderOptions> {\n readonly supports = ['.txt', '.text', 'text/plain'];\n\n /**\n * Check if this loader can handle the source.\n */\n canLoad(source: LoaderSource): boolean {\n if (typeof source === 'string') {\n return true;\n }\n if (source instanceof File) {\n return (\n source.name.endsWith('.txt') ||\n source.name.endsWith('.text') ||\n source.type === 'text/plain'\n );\n }\n if (source instanceof Blob) {\n return source.type === 'text/plain' || source.type === '';\n }\n return false;\n }\n\n /**\n * Load documents from text source.\n */\n async load(source: LoaderSource, options: TextLoaderOptions = {}): Promise<LoadedDocument[]> {\n const { generateId: customGenerateId, separator, trim = true, abortSignal } = options;\n\n // Check for cancellation\n abortSignal?.throwIfAborted();\n\n // Get text content\n let text = await this.getText(source, options);\n\n // Apply trimming\n if (trim) {\n text = text.trim();\n }\n\n if (!text) {\n return [];\n }\n\n // Split if separator is provided\n if (separator) {\n const parts = text.split(separator);\n const documents: LoadedDocument[] = [];\n\n for (let index = 0; index < parts.length; index++) {\n const content = trim ? parts[index].trim() : parts[index];\n if (!content) continue;\n\n const id = customGenerateId ? customGenerateId(source, index) : generateId();\n const metadata: LoadedDocumentMetadata = {\n source: this.getSourceName(source),\n mimeType: 'text/plain',\n partIndex: index,\n totalParts: parts.length,\n };\n\n documents.push({ id, text: content, metadata });\n }\n\n return documents;\n }\n\n // Single document\n const id = customGenerateId ? customGenerateId(source, 0) : generateId();\n const metadata: LoadedDocumentMetadata = {\n source: this.getSourceName(source),\n mimeType: 'text/plain',\n length: text.length,\n };\n\n return [{ id, text, metadata }];\n }\n\n /**\n * Get text content from source.\n */\n private async getText(source: LoaderSource, options: TextLoaderOptions): Promise<string> {\n const { encoding = 'utf-8', maxSize, abortSignal } = options;\n\n if (typeof source === 'string') {\n if (maxSize && source.length > maxSize) {\n throw new Error(`Text exceeds maximum size: ${source.length} > ${maxSize}`);\n }\n return source;\n }\n\n if (source instanceof Blob || source instanceof File) {\n if (maxSize && source.size > maxSize) {\n throw new Error(`File exceeds maximum size: ${source.size} > ${maxSize}`);\n }\n return source.text();\n }\n\n if (source instanceof ArrayBuffer) {\n if (maxSize && source.byteLength > maxSize) {\n throw new Error(`Buffer exceeds maximum size: ${source.byteLength} > ${maxSize}`);\n }\n const decoder = new TextDecoder(encoding);\n return decoder.decode(source);\n }\n\n if (typeof source === 'object' && 'type' in source && source.type === 'url') {\n const response = await fetch(source.url, { signal: abortSignal });\n if (!response.ok) {\n throw new Error(`Failed to fetch URL: ${response.status} ${response.statusText}`);\n }\n return response.text();\n }\n\n throw new Error('Unsupported source type for TextLoader');\n }\n\n /**\n * Get source name for metadata.\n */\n private getSourceName(source: LoaderSource): string {\n if (typeof source === 'string') return 'text-string';\n if (source instanceof File) return source.name;\n if (source instanceof Blob) return 'text-blob';\n if (typeof source === 'object' && 'type' in source && source.type === 'url') {\n return source.url;\n }\n return 'text';\n }\n}\n\n/**\n * Create a text loader with default options.\n */\nexport function createTextLoader(_options?: TextLoaderOptions): TextLoader {\n return new TextLoader();\n}\n","/**\n * JSON Document Loader\n *\n * Loader for JSON documents, extracting text from specified fields.\n * Zero external dependencies.\n *\n * @packageDocumentation\n */\n\nimport type { DocumentLoader, LoaderSource, LoadedDocument, LoadedDocumentMetadata, JSONLoaderOptions } from './types.js';\n\n/**\n * Generate a unique document ID.\n */\nfunction generateId(): string {\n return `doc_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n}\n\n/**\n * Get a value from an object using a dot-notation path.\n */\nfunction getValueByPath(obj: unknown, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = obj;\n\n for (const part of parts) {\n if (current === null || current === undefined) {\n return undefined;\n }\n\n if (typeof current === 'object' && !Array.isArray(current)) {\n current = (current as Record<string, unknown>)[part];\n } else if (Array.isArray(current)) {\n const index = parseInt(part, 10);\n if (!isNaN(index) && index >= 0 && index < current.length) {\n current = current[index];\n } else {\n return undefined;\n }\n } else {\n return undefined;\n }\n }\n\n return current;\n}\n\n/**\n * Extract all string values from an object recursively.\n */\nfunction extractAllStrings(obj: unknown, maxDepth = 10): string[] {\n const strings: string[] = [];\n\n function traverse(value: unknown, depth: number): void {\n if (depth > maxDepth) return;\n\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed && trimmed.length > 0) {\n strings.push(trimmed);\n }\n } else if (Array.isArray(value)) {\n for (const item of value) {\n traverse(item, depth + 1);\n }\n } else if (value !== null && typeof value === 'object') {\n for (const key of Object.keys(value as Record<string, unknown>)) {\n traverse((value as Record<string, unknown>)[key], depth + 1);\n }\n }\n }\n\n traverse(obj, 0);\n return strings;\n}\n\n/**\n * JSON document loader.\n *\n * Loads documents from JSON, extracting text from specified fields.\n *\n * @example\n * ```typescript\n * import { JSONLoader } from '@localmode/core';\n *\n * // Extract from specific fields\n * const loader = new JSONLoader({\n * textFields: ['content', 'description'],\n * });\n * const docs = await loader.load(jsonString);\n *\n * // Load array of records\n * const arrayLoader = new JSONLoader({\n * recordsPath: 'data.items',\n * textFields: ['text'],\n * });\n *\n * // Extract all strings\n * const allStringsLoader = new JSONLoader({\n * extractAllStrings: true,\n * });\n * ```\n */\nexport class JSONLoader implements DocumentLoader<JSONLoaderOptions> {\n readonly supports = ['.json', 'application/json', 'text/json'];\n\n /**\n * Check if this loader can handle the source.\n */\n canLoad(source: LoaderSource): boolean {\n if (typeof source === 'string') {\n // Basic heuristic: starts with { or [\n const trimmed = source.trim();\n return trimmed.startsWith('{') || trimmed.startsWith('[');\n }\n if (source instanceof File) {\n return source.name.endsWith('.json') || source.type === 'application/json';\n }\n if (source instanceof Blob) {\n return source.type === 'application/json' || source.type === 'text/json';\n }\n return false;\n }\n\n /**\n * Load documents from JSON source.\n */\n async load(source: LoaderSource, options: JSONLoaderOptions = {}): Promise<LoadedDocument[]> {\n const {\n generateId: customGenerateId,\n textFields,\n extractAllStrings: extractAll = false,\n fieldSeparator = '\\n',\n recordsPath,\n abortSignal,\n } = options;\n\n // Check for cancellation\n abortSignal?.throwIfAborted();\n\n // Get JSON content\n const jsonString = await this.getText(source, options);\n\n // Parse JSON\n let data: unknown;\n try {\n data = JSON.parse(jsonString);\n } catch (error) {\n throw new Error(`Invalid JSON: ${error instanceof Error ? error.message : String(error)}`);\n }\n\n // If recordsPath is provided, navigate to that path\n let records: unknown[];\n if (recordsPath) {\n const value = getValueByPath(data, recordsPath);\n if (Array.isArray(value)) {\n records = value;\n } else if (value !== undefined) {\n records = [value];\n } else {\n records = [];\n }\n } else if (Array.isArray(data)) {\n records = data;\n } else {\n records = [data];\n }\n\n // Process each record\n const documents: LoadedDocument[] = [];\n\n for (let i = 0; i < records.length; i++) {\n const record = records[i];\n\n // Extract text\n let text: string;\n if (extractAll) {\n const strings = extractAllStrings(record);\n text = strings.join(fieldSeparator);\n } else if (textFields && textFields.length > 0) {\n const values: string[] = [];\n for (const field of textFields) {\n const value = getValueByPath(record, field);\n if (typeof value === 'string') {\n values.push(value.trim());\n } else if (value !== undefined && value !== null) {\n values.push(String(value));\n }\n }\n text = values.filter(Boolean).join(fieldSeparator);\n } else {\n // Default: look for common text fields\n const commonFields = ['text', 'content', 'body', 'description', 'message', 'title'];\n const values: string[] = [];\n for (const field of commonFields) {\n const value = getValueByPath(record, field);\n if (typeof value === 'string' && value.trim()) {\n values.push(value.trim());\n break; // Use first found\n }\n }\n if (values.length === 0) {\n // Fall back to stringifying the record\n text = JSON.stringify(record, null, 2);\n } else {\n text = values.join(fieldSeparator);\n }\n }\n\n if (!text.trim()) {\n continue;\n }\n\n // Generate ID\n let id: string;\n if (customGenerateId) {\n id = customGenerateId(source, i);\n } else {\n // Try to use 'id' field from record\n const recordId = typeof record === 'object' && record !== null \n ? (record as Record<string, unknown>).id ?? (record as Record<string, unknown>)._id\n : undefined;\n if (typeof recordId === 'string' || typeof recordId === 'number') {\n id = String(recordId);\n } else {\n id = generateId();\n }\n }\n\n // Build metadata\n const metadata: LoadedDocumentMetadata = {\n source: this.getSourceName(source),\n mimeType: 'application/json',\n recordIndex: i,\n };\n\n // Add some record fields to metadata (excluding large text)\n if (typeof record === 'object' && record !== null) {\n for (const [key, value] of Object.entries(record as Record<string, unknown>)) {\n if (\n !textFields?.includes(key) &&\n key !== 'text' &&\n key !== 'content' &&\n key !== 'body' &&\n (typeof value === 'string' ? value.length < 200 : true) &&\n (typeof value !== 'object' || value === null)\n ) {\n metadata[key] = value;\n }\n }\n }\n\n documents.push({\n id,\n text: text.trim(),\n metadata,\n });\n }\n\n return documents;\n }\n\n /**\n * Get text content from source.\n */\n private async getText(source: LoaderSource, options: JSONLoaderOptions): Promise<string> {\n const { encoding = 'utf-8', maxSize, abortSignal } = options;\n\n if (typeof source === 'string') {\n if (maxSize && source.length > maxSize) {\n throw new Error(`JSON exceeds maximum size: ${source.length} > ${maxSize}`);\n }\n return source;\n }\n\n if (source instanceof Blob || source instanceof File) {\n if (maxSize && source.size > maxSize) {\n throw new Error(`File exceeds maximum size: ${source.size} > ${maxSize}`);\n }\n return source.text();\n }\n\n if (source instanceof ArrayBuffer) {\n if (maxSize && source.byteLength > maxSize) {\n throw new Error(`Buffer exceeds maximum size: ${source.byteLength} > ${maxSize}`);\n }\n const decoder = new TextDecoder(encoding);\n return decoder.decode(source);\n }\n\n if (typeof source === 'object' && 'type' in source && source.type === 'url') {\n const response = await fetch(source.url, { signal: abortSignal });\n if (!response.ok) {\n throw new Error(`Failed to fetch URL: ${response.status} ${response.statusText}`);\n }\n return response.text();\n }\n\n throw new Error('Unsupported source type for JSONLoader');\n }\n\n /**\n * Get source name for metadata.\n */\n private getSourceName(source: LoaderSource): string {\n if (typeof source === 'string') return 'json-string';\n if (source instanceof File) return source.name;\n if (source instanceof Blob) return 'json-blob';\n if (typeof source === 'object' && 'type' in source && source.type === 'url') {\n return source.url;\n }\n return 'json';\n }\n}\n\n/**\n * Create a JSON loader with default options.\n */\nexport function createJSONLoader(_options?: JSONLoaderOptions): JSONLoader {\n return new JSONLoader();\n}\n","/**\n * CSV Document Loader\n *\n * Loader for CSV documents, converting rows to documents.\n * Zero external dependencies.\n *\n * @packageDocumentation\n */\n\nimport type { DocumentLoader, LoaderSource, LoadedDocument, LoadedDocumentMetadata, CSVLoaderOptions } from './types.js';\n\n/**\n * Generate a unique document ID.\n */\nfunction generateId(): string {\n return `doc_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n}\n\n/**\n * Simple CSV parser that handles quoted fields and escaped quotes.\n */\nfunction parseCSV(text: string, delimiter = ',', rowDelimiter = '\\n'): string[][] {\n const rows: string[][] = [];\n let currentRow: string[] = [];\n let currentField = '';\n let inQuotes = false;\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n const nextChar = text[i + 1];\n\n if (inQuotes) {\n if (char === '\"') {\n if (nextChar === '\"') {\n // Escaped quote\n currentField += '\"';\n i++;\n } else {\n // End of quoted field\n inQuotes = false;\n }\n } else {\n currentField += char;\n }\n } else {\n if (char === '\"') {\n inQuotes = true;\n } else if (char === delimiter) {\n currentRow.push(currentField);\n currentField = '';\n } else if (char === '\\r' && nextChar === '\\n') {\n // Windows line ending\n currentRow.push(currentField);\n rows.push(currentRow);\n currentRow = [];\n currentField = '';\n i++; // Skip \\n\n } else if (char === rowDelimiter || (char === '\\r' && rowDelimiter === '\\n')) {\n currentRow.push(currentField);\n rows.push(currentRow);\n currentRow = [];\n currentField = '';\n } else {\n currentField += char;\n }\n }\n }\n\n // Add last field and row\n if (currentField || currentRow.length > 0) {\n currentRow.push(currentField);\n rows.push(currentRow);\n }\n\n return rows;\n}\n\n/**\n * CSV document loader.\n *\n * Loads documents from CSV, converting each row to a document.\n *\n * @example\n * ```typescript\n * import { CSVLoader } from '@localmode/core';\n *\n * // Load with text column specified\n * const loader = new CSVLoader({ textColumn: 'content' });\n * const docs = await loader.load(csvText);\n *\n * // Combine multiple columns\n * const multiLoader = new CSVLoader({\n * textColumns: ['title', 'description'],\n * columnSeparator: ' - ',\n * });\n *\n * // Use column index\n * const indexLoader = new CSVLoader({ textColumn: 2 });\n * ```\n */\nexport class CSVLoader implements DocumentLoader<CSVLoaderOptions> {\n readonly supports = ['.csv', 'text/csv', 'application/csv'];\n\n /**\n * Check if this loader can handle the source.\n */\n canLoad(source: LoaderSource): boolean {\n if (typeof source === 'string') {\n // Basic heuristic: contains comma and newline\n return source.includes(',') && source.includes('\\n');\n }\n if (source instanceof File) {\n return source.name.endsWith('.csv');\n }\n if (source instanceof Blob) {\n return source.type === 'text/csv' || source.type === 'application/csv';\n }\n return false;\n }\n\n /**\n * Load documents from CSV source.\n */\n async load(source: LoaderSource, options: CSVLoaderOptions = {}): Promise<LoadedDocument[]> {\n const {\n generateId: customGenerateId,\n abortSignal,\n textColumn,\n textColumns,\n columnSeparator = ' ',\n idColumn,\n columnDelimiter = ',',\n rowDelimiter = '\\n',\n hasHeader = true,\n skipEmpty = true,\n } = options;\n\n // Check for cancellation\n abortSignal?.throwIfAborted();\n\n // Get CSV text\n const text = await this.getText(source, options);\n\n // Parse CSV\n const rows = parseCSV(text, columnDelimiter, rowDelimiter);\n\n if (rows.length === 0) {\n return [];\n }\n\n // Get headers\n let headers: string[] | undefined;\n let dataRows: string[][];\n\n if (hasHeader) {\n headers = rows[0];\n dataRows = rows.slice(1);\n } else {\n dataRows = rows;\n }\n\n // Determine text column indices\n const textColumnIndices = this.getColumnIndices(textColumn, textColumns, headers);\n const idColumnIndex = this.getColumnIndex(idColumn, headers);\n\n // Create documents\n const documents: LoadedDocument[] = [];\n\n for (let i = 0; i < dataRows.length; i++) {\n const row = dataRows[i];\n\n // Extract text\n const texts: string[] = [];\n for (const idx of textColumnIndices) {\n if (idx >= 0 && idx < row.length) {\n const value = row[idx]?.trim();\n if (value) {\n texts.push(value);\n }\n }\n }\n\n const text = texts.join(columnSeparator);\n\n if (skipEmpty && !text.trim()) {\n continue;\n }\n\n // Extract ID\n let id: string;\n if (customGenerateId) {\n id = customGenerateId(source, i);\n } else if (idColumnIndex !== undefined && idColumnIndex >= 0 && row[idColumnIndex]) {\n id = row[idColumnIndex].trim();\n } else {\n id = generateId();\n }\n\n // Build metadata\n const metadata: LoadedDocumentMetadata = {\n source: this.getSourceName(source),\n mimeType: 'text/csv',\n rowIndex: hasHeader ? i + 1 : i,\n };\n\n // Add all columns as metadata if headers exist\n if (headers) {\n for (let j = 0; j < headers.length; j++) {\n const header = headers[j]?.trim();\n if (header && row[j] !== undefined) {\n metadata[header] = row[j].trim();\n }\n }\n }\n\n documents.push({\n id,\n text: text.trim(),\n metadata,\n });\n }\n\n return documents;\n }\n\n /**\n * Get text content from source.\n */\n private async getText(source: LoaderSource, options: CSVLoaderOptions): Promise<string> {\n const { encoding = 'utf-8', maxSize, abortSignal } = options;\n\n if (typeof source === 'string') {\n if (maxSize && source.length > maxSize) {\n throw new Error(`CSV exceeds maximum size: ${source.length} > ${maxSize}`);\n }\n return source;\n }\n\n if (source instanceof Blob || source instanceof File) {\n if (maxSize && source.size > maxSize) {\n throw new Error(`File exceeds maximum size: ${source.size} > ${maxSize}`);\n }\n return source.text();\n }\n\n if (source instanceof ArrayBuffer) {\n if (maxSize && source.byteLength > maxSize) {\n throw new Error(`Buffer exceeds maximum size: ${source.byteLength} > ${maxSize}`);\n }\n const decoder = new TextDecoder(encoding);\n return decoder.decode(source);\n }\n\n if (typeof source === 'object' && 'type' in source && source.type === 'url') {\n const response = await fetch(source.url, { signal: abortSignal });\n if (!response.ok) {\n throw new Error(`Failed to fetch URL: ${response.status} ${response.statusText}`);\n }\n return response.text();\n }\n\n throw new Error('Unsupported source type for CSVLoader');\n }\n\n /**\n * Get column indices for text extraction.\n */\n private getColumnIndices(\n textColumn: string | number | undefined,\n textColumns: (string | number)[] | undefined,\n headers?: string[]\n ): number[] {\n // Use textColumns if provided\n if (textColumns && textColumns.length > 0) {\n return textColumns.map((col) => this.getColumnIndex(col, headers) ?? -1).filter((i) => i >= 0);\n }\n\n // Use textColumn if provided\n if (textColumn !== undefined) {\n const idx = this.getColumnIndex(textColumn, headers);\n if (idx !== undefined) {\n return [idx];\n }\n }\n\n // Default: use first column or 'text', 'content', 'body' if headers exist\n if (headers) {\n const defaultFields = ['text', 'content', 'body', 'description', 'message'];\n for (const field of defaultFields) {\n const idx = headers.findIndex((h) => h.toLowerCase().trim() === field);\n if (idx >= 0) {\n return [idx];\n }\n }\n }\n\n // Fallback to first column\n return [0];\n }\n\n /**\n * Get single column index.\n */\n private getColumnIndex(\n column: string | number | undefined,\n headers?: string[]\n ): number | undefined {\n if (column === undefined) return undefined;\n\n if (typeof column === 'number') {\n return column;\n }\n\n if (headers) {\n return headers.findIndex((h) => h.toLowerCase().trim() === column.toLowerCase());\n }\n\n return undefined;\n }\n\n /**\n * Get source name for metadata.\n */\n private getSourceName(source: LoaderSource): string {\n if (typeof source === 'string') return 'csv-string';\n if (source instanceof File) return source.name;\n if (source instanceof Blob) return 'csv-blob';\n if (typeof source === 'object' && 'type' in source && source.type === 'url') {\n return source.url;\n }\n return 'csv';\n }\n}\n\n/**\n * Create a CSV loader with default options.\n */\nexport function createCSVLoader(_options?: CSVLoaderOptions): CSVLoader {\n return new CSVLoader();\n}\n\n","/**\n * HTML Document Loader\n *\n * Loader for HTML documents, extracting text content.\n * Zero external dependencies - uses DOMParser in browser and regex fallback.\n *\n * @packageDocumentation\n */\n\nimport type { DocumentLoader, LoaderSource, LoadedDocument, LoadedDocumentMetadata, HTMLLoaderOptions } from './types.js';\n\n/**\n * Generate a unique document ID.\n */\nfunction generateId(): string {\n return `doc_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n}\n\n/**\n * Default tags to ignore (scripts, styles, etc.)\n */\nconst DEFAULT_IGNORE_TAGS = [\n 'script',\n 'style',\n 'noscript',\n 'iframe',\n 'svg',\n 'canvas',\n 'video',\n 'audio',\n 'object',\n 'embed',\n 'applet',\n 'head',\n 'meta',\n 'link',\n 'template',\n];\n\n/**\n * Simple HTML parser for environments without DOM.\n * Strips tags and extracts text content.\n */\nfunction parseHTMLWithRegex(\n html: string,\n options: {\n selector?: string;\n ignoreTags?: string[];\n preserveFormatting?: boolean;\n }\n): { text: string; title?: string; metadata: Record<string, string> } {\n const ignoreTags = options.ignoreTags ?? DEFAULT_IGNORE_TAGS;\n\n // Extract title\n const titleMatch = html.match(/<title[^>]*>([\\s\\S]*?)<\\/title>/i);\n const title = titleMatch ? titleMatch[1].trim() : undefined;\n\n // Extract meta tags for metadata\n const metadata: Record<string, string> = {};\n const metaRegex = /<meta\\s+(?:[^>]*?\\s+)?(?:name|property)=[\"']([^\"']+)[\"'][^>]*?content=[\"']([^\"']+)[\"'][^>]*>/gi;\n let metaMatch;\n while ((metaMatch = metaRegex.exec(html)) !== null) {\n metadata[metaMatch[1]] = metaMatch[2];\n }\n\n // If selector is provided, try to extract that content\n let content = html;\n if (options.selector) {\n // Simple selector support: id, class, or tag\n const selectorRegex = createSelectorRegex(options.selector);\n if (selectorRegex) {\n const selectorMatch = html.match(selectorRegex);\n if (selectorMatch) {\n content = selectorMatch[0];\n }\n }\n }\n\n // Remove ignored tags and their content\n for (const tag of ignoreTags) {\n const tagRegex = new RegExp(`<${tag}[^>]*>[\\\\s\\\\S]*?<\\\\/${tag}>`, 'gi');\n content = content.replace(tagRegex, '');\n // Also remove self-closing versions\n content = content.replace(new RegExp(`<${tag}[^>]*\\\\/>`, 'gi'), '');\n }\n\n // Remove comments\n content = content.replace(/<!--[\\s\\S]*?-->/g, '');\n\n // Handle formatting preservation\n if (options.preserveFormatting) {\n // Replace block elements with newlines\n content = content.replace(/<\\/(p|div|h[1-6]|li|tr|br|hr)[^>]*>/gi, '\\n');\n content = content.replace(/<br\\s*\\/?>/gi, '\\n');\n content = content.replace(/<hr\\s*\\/?>/gi, '\\n---\\n');\n content = content.replace(/<li[^>]*>/gi, '\\n• ');\n }\n\n // Remove all remaining HTML tags\n content = content.replace(/<[^>]+>/g, ' ');\n\n // Decode HTML entities\n content = decodeHTMLEntities(content);\n\n // Normalize whitespace\n if (options.preserveFormatting) {\n // Preserve paragraph breaks but normalize spaces within lines\n content = content\n .split('\\n')\n .map((line) => line.replace(/\\s+/g, ' ').trim())\n .filter((line) => line)\n .join('\\n');\n } else {\n content = content.replace(/\\s+/g, ' ').trim();\n }\n\n return { text: content, title, metadata };\n}\n\n/**\n * Create a regex to match an HTML element by selector.\n */\nfunction createSelectorRegex(selector: string): RegExp | null {\n // ID selector: #id\n if (selector.startsWith('#')) {\n const id = selector.slice(1);\n return new RegExp(`<[^>]+\\\\s+id=[\"']${id}[\"'][^>]*>[\\\\s\\\\S]*?<\\\\/[^>]+>`, 'i');\n }\n\n // Class selector: .class\n if (selector.startsWith('.')) {\n const className = selector.slice(1);\n return new RegExp(\n `<[^>]+\\\\s+class=[\"'][^\"']*\\\\b${className}\\\\b[^\"']*[\"'][^>]*>[\\\\s\\\\S]*?<\\\\/[^>]+>`,\n 'i'\n );\n }\n\n // Tag selector\n return new RegExp(`<${selector}[^>]*>[\\\\s\\\\S]*?<\\\\/${selector}>`, 'i');\n}\n\n/**\n * Decode common HTML entities.\n */\nfunction decodeHTMLEntities(text: string): string {\n const entities: Record<string, string> = {\n ' ': ' ',\n '&': '&',\n '<': '<',\n '>': '>',\n '"': '\"',\n ''': \"'\",\n ''': \"'\",\n '–': '–',\n '—': '—',\n '‘': '\\u2018',\n '’': '\\u2019',\n '“': '\\u201C',\n '”': '\\u201D',\n '…': '…',\n '©': '©',\n '®': '®',\n '™': '™',\n '€': '€',\n '£': '£',\n '¥': '¥',\n '¢': '¢',\n };\n\n let result = text;\n for (const [entity, char] of Object.entries(entities)) {\n result = result.replace(new RegExp(entity, 'gi'), char);\n }\n\n // Decode numeric entities\n result = result.replace(/&#(\\d+);/g, (_, num) => String.fromCharCode(parseInt(num, 10)));\n result = result.replace(/&#x([a-fA-F0-9]+);/g, (_, hex) =>\n String.fromCharCode(parseInt(hex, 16))\n );\n\n return result;\n}\n\n/**\n * Parse HTML using DOMParser if available, otherwise use regex.\n */\nfunction parseHTML(\n html: string,\n options: HTMLLoaderOptions\n): { text: string; title?: string; metadata: Record<string, string> } {\n // Try to use DOMParser if available (browser environment)\n if (typeof DOMParser !== 'undefined') {\n try {\n return parseHTMLWithDOM(html, options);\n } catch {\n // Fall back to regex if DOMParser fails\n }\n }\n\n return parseHTMLWithRegex(html, options);\n}\n\n/**\n * Parse HTML using DOMParser (browser).\n */\nfunction parseHTMLWithDOM(\n html: string,\n options: HTMLLoaderOptions\n): { text: string; title?: string; metadata: Record<string, string> } {\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, 'text/html');\n\n // Extract title\n const title = doc.querySelector('title')?.textContent?.trim();\n\n // Extract metadata from meta tags\n const metadata: Record<string, string> = {};\n const metaTags = doc.querySelectorAll('meta[name], meta[property]');\n metaTags.forEach((meta) => {\n const name =\n meta.getAttribute('name') || meta.getAttribute('property');\n const content = meta.getAttribute('content');\n if (name && content) {\n metadata[name] = content;\n }\n });\n\n // Remove ignored tags\n const ignoreTags = options.ignoreTags ?? DEFAULT_IGNORE_TAGS;\n for (const tag of ignoreTags) {\n const elements = doc.querySelectorAll(tag);\n elements.forEach((el) => el.remove());\n }\n\n // Get content from selector or body\n let content: string;\n if (options.selector) {\n const element = doc.querySelector(options.selector);\n content = element?.textContent ?? '';\n } else if (options.selectors && options.selectors.length > 0) {\n const texts: string[] = [];\n for (const selector of options.selectors) {\n const element = doc.querySelector(selector);\n if (element?.textContent) {\n texts.push(element.textContent);\n }\n }\n content = texts.join('\\n\\n');\n } else {\n content = doc.body?.textContent ?? '';\n }\n\n // Normalize whitespace\n if (options.preserveFormatting) {\n content = content\n .split('\\n')\n .map((line) => line.replace(/\\s+/g, ' ').trim())\n .filter((line) => line)\n .join('\\n');\n } else {\n content = content.replace(/\\s+/g, ' ').trim();\n }\n\n return { text: content, title, metadata };\n}\n\n/**\n * HTML document loader.\n *\n * Loads documents from HTML, extracting text content.\n * Supports CSS selectors for targeting specific content.\n *\n * @example\n * ```typescript\n * import { HTMLLoader } from '@localmode/core';\n *\n * // Load entire page\n * const loader = new HTMLLoader();\n * const docs = await loader.load(htmlText);\n *\n * // Extract specific content\n * const articleLoader = new HTMLLoader({\n * selector: 'article.content',\n * preserveFormatting: true,\n * });\n *\n * // Extract metadata\n * const metaLoader = new HTMLLoader({\n * extractMetadata: true,\n * });\n * ```\n */\nexport class HTMLLoader implements DocumentLoader<HTMLLoaderOptions> {\n readonly supports = ['.html', '.htm', 'text/html', 'application/xhtml+xml'];\n\n /**\n * Check if this loader can handle the source.\n */\n canLoad(source: LoaderSource): boolean {\n if (typeof source === 'string') {\n // Check for HTML tags\n return /<html|<!doctype|<head|<body/i.test(source);\n }\n if (source instanceof File) {\n return source.name.endsWith('.html') || source.name.endsWith('.htm');\n }\n if (source instanceof Blob) {\n return source.type === 'text/html' || source.type === 'application/xhtml+xml';\n }\n return false;\n }\n\n /**\n * Load documents from HTML source.\n */\n async load(source: LoaderSource, options: HTMLLoaderOptions = {}): Promise<LoadedDocument[]> {\n const { generateId: customGenerateId, abortSignal, extractMetadata = true } = options;\n\n // Check for cancellation\n abortSignal?.throwIfAborted();\n\n // Get HTML text\n const html = await this.getText(source, options);\n\n // Parse HTML\n const { text, title, metadata: htmlMetadata } = parseHTML(html, options);\n\n if (!text.trim()) {\n return [];\n }\n\n // Generate ID\n let id: string;\n if (customGenerateId) {\n id = customGenerateId(source, 0);\n } else if (title) {\n // Create slug from title\n id = title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 50);\n } else {\n id = generateId();\n }\n\n // Build metadata\n const metadata: LoadedDocumentMetadata = {\n source: this.getSourceName(source),\n mimeType: 'text/html',\n };\n\n if (title) {\n metadata.title = title;\n }\n\n if (extractMetadata) {\n // Add common meta fields\n if (htmlMetadata.description) {\n metadata.description = htmlMetadata.description;\n }\n if (htmlMetadata['og:title']) {\n metadata.ogTitle = htmlMetadata['og:title'];\n }\n if (htmlMetadata['og:description']) {\n metadata.ogDescription = htmlMetadata['og:description'];\n }\n if (htmlMetadata['og:image']) {\n metadata.ogImage = htmlMetadata['og:image'];\n }\n if (htmlMetadata.author) {\n metadata.author = htmlMetadata.author;\n }\n if (htmlMetadata.keywords) {\n metadata.keywords = htmlMetadata.keywords;\n }\n }\n\n return [{ id, text, metadata }];\n }\n\n /**\n * Get text content from source.\n */\n private async getText(source: LoaderSource, options: HTMLLoaderOptions): Promise<string> {\n const { encoding = 'utf-8', maxSize, abortSignal } = options;\n\n if (typeof source === 'string') {\n if (maxSize && source.length > maxSize) {\n throw new Error(`HTML exceeds maximum size: ${source.length} > ${maxSize}`);\n }\n return source;\n }\n\n if (source instanceof Blob || source instanceof File) {\n if (maxSize && source.size > maxSize) {\n throw new Error(`File exceeds maximum size: ${source.size} > ${maxSize}`);\n }\n return source.text();\n }\n\n if (source instanceof ArrayBuffer) {\n if (maxSize && source.byteLength > maxSize) {\n throw new Error(`Buffer exceeds maximum size: ${source.byteLength} > ${maxSize}`);\n }\n const decoder = new TextDecoder(encoding);\n return decoder.decode(source);\n }\n\n if (typeof source === 'object' && 'type' in source && source.type === 'url') {\n const response = await fetch(source.url, { signal: abortSignal });\n if (!response.ok) {\n throw new Error(`Failed to fetch URL: ${response.status} ${response.statusText}`);\n }\n return response.text();\n }\n\n throw new Error('Unsupported source type for HTMLLoader');\n }\n\n /**\n * Get source name for metadata.\n */\n private getSourceName(source: LoaderSource): string {\n if (typeof source === 'string') return 'html-string';\n if (source instanceof File) return source.name;\n if (source instanceof Blob) return 'html-blob';\n if (typeof source === 'object' && 'type' in source && source.type === 'url') {\n return source.url;\n }\n return 'html';\n }\n}\n\n/**\n * Create an HTML loader with default options.\n */\nexport function createHTMLLoader(_options?: HTMLLoaderOptions): HTMLLoader {\n return new HTMLLoader();\n}\n\n","/**\n * Document Loaders\n *\n * Production-essential document loading utilities.\n * Zero external dependencies.\n *\n * @packageDocumentation\n */\n\n// Export all types\nexport * from './types.js';\n\n// Export loaders\nexport { TextLoader, createTextLoader } from './text.js';\nexport { JSONLoader, createJSONLoader } from './json.js';\nexport { CSVLoader, createCSVLoader } from './csv.js';\nexport { HTMLLoader, createHTMLLoader } from './html.js';\n\nimport type { LoaderSource, LoadedDocument, DocumentLoader, LoaderOptions } from './types.js';\nimport { TextLoader } from './text.js';\nimport { JSONLoader } from './json.js';\nimport { CSVLoader } from './csv.js';\nimport { HTMLLoader } from './html.js';\n\n/**\n * Registry of built-in loaders.\n */\nconst LOADERS: DocumentLoader<LoaderOptions>[] = [\n new TextLoader(),\n new JSONLoader(),\n new CSVLoader(),\n new HTMLLoader(),\n];\n\n/**\n * Auto-detect and load a document using the appropriate loader.\n *\n * @example\n * ```typescript\n * import { loadDocument } from '@localmode/core';\n *\n * // Auto-detect loader based on content/type\n * const docs = await loadDocument(fileOrString);\n *\n * // With specific options\n * const docs = await loadDocument(csvFile, {\n * loader: 'csv',\n * textColumn: 'content',\n * });\n * ```\n */\nexport async function loadDocument(\n source: LoaderSource,\n options?: LoaderOptions & { loader?: 'text' | 'json' | 'csv' | 'html' }\n): Promise<LoadedDocument[]> {\n const { loader: loaderType, ...loaderOptions } = options ?? {};\n\n // Use specified loader if provided\n if (loaderType) {\n const loader = getLoaderByType(loaderType);\n return loader.load(source, loaderOptions);\n }\n\n // Auto-detect loader\n for (const loader of LOADERS) {\n if (loader.canLoad?.(source)) {\n return loader.load(source, loaderOptions);\n }\n }\n\n // Default to text loader\n return new TextLoader().load(source, loaderOptions);\n}\n\n/**\n * Load multiple documents from multiple sources.\n */\nexport async function loadDocuments(\n sources: LoaderSource[],\n options?: LoaderOptions & { loader?: 'text' | 'json' | 'csv' | 'html' }\n): Promise<LoadedDocument[]> {\n const results = await Promise.all(sources.map((source) => loadDocument(source, options)));\n return results.flat();\n}\n\n/**\n * Get a loader by type name.\n */\nfunction getLoaderByType(type: 'text' | 'json' | 'csv' | 'html'): DocumentLoader<LoaderOptions> {\n switch (type) {\n case 'text':\n return new TextLoader();\n case 'json':\n return new JSONLoader();\n case 'csv':\n return new CSVLoader();\n case 'html':\n return new HTMLLoader();\n default:\n throw new Error(`Unknown loader type: ${type}`);\n }\n}\n\n/**\n * Create a custom loader registry.\n *\n * @example\n * ```typescript\n * import { createLoaderRegistry, TextLoader, JSONLoader } from '@localmode/core';\n *\n * const registry = createLoaderRegistry([\n * new TextLoader(),\n * new JSONLoader(),\n * // Add custom loaders\n * new MyPDFLoader(),\n * ]);\n *\n * const docs = await registry.load(source);\n * ```\n */\nexport function createLoaderRegistry(loaders: DocumentLoader<LoaderOptions>[]): {\n load: (source: LoaderSource, options?: LoaderOptions) => Promise<LoadedDocument[]>;\n loadMany: (sources: LoaderSource[], options?: LoaderOptions) => Promise<LoadedDocument[]>;\n getLoader: (source: LoaderSource) => DocumentLoader<LoaderOptions> | undefined;\n loaders: DocumentLoader<LoaderOptions>[];\n} {\n return {\n loaders,\n\n getLoader(source: LoaderSource): DocumentLoader<LoaderOptions> | undefined {\n return loaders.find((loader) => loader.canLoad?.(source));\n },\n\n async load(source: LoaderSource, options?: LoaderOptions): Promise<LoadedDocument[]> {\n const loader = this.getLoader(source);\n if (!loader) {\n throw new Error('No loader found for source');\n }\n return loader.load(source, options);\n },\n\n async loadMany(sources: LoaderSource[], options?: LoaderOptions): Promise<LoadedDocument[]> {\n const results = await Promise.all(sources.map((s) => this.load(s, options)));\n return results.flat();\n },\n };\n}\n","/**\n * VectorDB Middleware Wrapper\n *\n * Wrap a VectorDB instance with middleware for extensibility.\n *\n * @packageDocumentation\n */\n\nimport type {\n VectorDB,\n Document,\n SearchOptions,\n SearchResult,\n FilterQuery,\n AddManyOptions,\n ExportOptions,\n ImportOptions,\n DBStats,\n} from '../types.js';\nimport type { VectorDBMiddleware } from './types.js';\n\n/**\n * Options for wrapping a VectorDB with middleware.\n */\nexport interface WrapVectorDBOptions {\n /** The VectorDB instance to wrap */\n db: VectorDB;\n\n /** Middleware to apply */\n middleware: VectorDBMiddleware | VectorDBMiddleware[];\n}\n\n/**\n * Compose multiple middleware into a single middleware.\n *\n * @example\n * ```typescript\n * import { composeVectorDBMiddleware, loggingMiddleware, cachingMiddleware } from '@localmode/core';\n *\n * const middleware = composeVectorDBMiddleware([\n * loggingMiddleware({ level: 'info' }),\n * cachingMiddleware({ ttlMs: 60000 }),\n * ]);\n * ```\n */\nexport function composeVectorDBMiddleware(\n middlewares: VectorDBMiddleware[]\n): VectorDBMiddleware {\n return {\n beforeAdd: async (doc: Document) => {\n let result = doc;\n for (const mw of middlewares) {\n if (mw.beforeAdd) {\n result = await mw.beforeAdd(result);\n }\n }\n return result;\n },\n\n afterAdd: async (doc: Document) => {\n for (const mw of middlewares) {\n if (mw.afterAdd) {\n await mw.afterAdd(doc);\n }\n }\n },\n\n afterGet: async (doc: Document | undefined) => {\n let result = doc;\n for (const mw of middlewares) {\n if (mw.afterGet) {\n result = await mw.afterGet(result);\n }\n }\n return result;\n },\n\n beforeDelete: async (id: string) => {\n for (const mw of middlewares) {\n if (mw.beforeDelete) {\n const allowed = await mw.beforeDelete(id);\n if (!allowed) return false;\n }\n }\n return true;\n },\n\n afterDelete: async (id: string) => {\n for (const mw of middlewares) {\n if (mw.afterDelete) {\n await mw.afterDelete(id);\n }\n }\n },\n\n beforeSearch: async (query: Float32Array, options: SearchOptions) => {\n let q = query;\n let opts = options;\n for (const mw of middlewares) {\n if (mw.beforeSearch) {\n const result = await mw.beforeSearch(q, opts);\n q = result.query;\n opts = result.options;\n }\n }\n return { query: q, options: opts };\n },\n\n afterSearch: async (results: SearchResult[]) => {\n let r = results;\n for (const mw of middlewares) {\n if (mw.afterSearch) {\n r = await mw.afterSearch(r);\n }\n }\n return r;\n },\n\n beforeClear: async () => {\n for (const mw of middlewares) {\n if (mw.beforeClear) {\n const allowed = await mw.beforeClear();\n if (!allowed) return false;\n }\n }\n return true;\n },\n\n afterClear: async () => {\n for (const mw of middlewares) {\n if (mw.afterClear) {\n await mw.afterClear();\n }\n }\n },\n\n onError: async (error: Error, operation: string) => {\n for (const mw of middlewares) {\n if (mw.onError) {\n const suppress = await mw.onError(error, operation);\n if (suppress) return true;\n }\n }\n return false;\n },\n };\n}\n\n/**\n * Wrap a VectorDB with middleware.\n *\n * Creates a proxy that intercepts operations and applies middleware.\n *\n * @example\n * ```typescript\n * import { createVectorDB, wrapVectorDB } from '@localmode/core';\n *\n * const db = await createVectorDB({ name: 'my-db', dimensions: 384 });\n *\n * const wrappedDb = wrapVectorDB({\n * db,\n * middleware: {\n * beforeAdd: (doc) => {\n * console.log('Adding document:', doc.id);\n * return doc;\n * },\n * afterSearch: (results) => {\n * console.log('Found', results.length, 'results');\n * return results;\n * },\n * },\n * });\n * ```\n */\nexport function wrapVectorDB(options: WrapVectorDBOptions): VectorDB {\n const { db } = options;\n const middleware = Array.isArray(options.middleware)\n ? composeVectorDBMiddleware(options.middleware)\n : options.middleware;\n\n // Helper to handle errors\n const handleError = async (error: Error, operation: string): Promise<never> => {\n if (middleware.onError) {\n await middleware.onError(error, operation);\n }\n throw error;\n };\n\n // Create wrapped DB object\n const wrapped: VectorDB = {\n // Wrap add with middleware\n async add(document: Document): Promise<void> {\n try {\n let doc = document;\n if (middleware.beforeAdd) {\n doc = await middleware.beforeAdd(doc);\n }\n await db.add(doc);\n if (middleware.afterAdd) {\n await middleware.afterAdd(doc);\n }\n } catch (error) {\n await handleError(error as Error, 'add');\n }\n },\n\n // Wrap addMany with middleware\n async addMany(documents: Document[], addOptions?: AddManyOptions): Promise<void> {\n try {\n let docs = documents;\n if (middleware.beforeAdd) {\n docs = [];\n for (const d of documents) {\n docs.push(await middleware.beforeAdd(d));\n }\n }\n await db.addMany(docs, addOptions);\n if (middleware.afterAdd) {\n for (const d of docs) {\n await middleware.afterAdd(d);\n }\n }\n } catch (error) {\n await handleError(error as Error, 'addMany');\n }\n },\n\n // Wrap get with middleware\n async get(id: string): Promise<(Document & { metadata?: Record<string, unknown> }) | null> {\n try {\n const result = await db.get(id);\n if (middleware.afterGet && result) {\n const processed = await middleware.afterGet(result as Document);\n return (processed as (Document & { metadata?: Record<string, unknown> })) ?? null;\n }\n return result;\n } catch (error) {\n return handleError(error as Error, 'get');\n }\n },\n\n // Wrap update (pass-through)\n async update(id: string, updates: Partial<Omit<Document, 'id'>>): Promise<void> {\n try {\n await db.update(id, updates);\n } catch (error) {\n await handleError(error as Error, 'update');\n }\n },\n\n // Wrap delete with middleware\n async delete(id: string): Promise<void> {\n try {\n if (middleware.beforeDelete) {\n const allowed = await middleware.beforeDelete(id);\n if (!allowed) return;\n }\n await db.delete(id);\n if (middleware.afterDelete) {\n await middleware.afterDelete(id);\n }\n } catch (error) {\n await handleError(error as Error, 'delete');\n }\n },\n\n // Wrap deleteMany (pass-through)\n async deleteMany(ids: string[]): Promise<void> {\n try {\n if (middleware.beforeDelete) {\n for (const id of ids) {\n const allowed = await middleware.beforeDelete(id);\n if (!allowed) {\n // Skip this id - for simplicity we process all or none\n return;\n }\n }\n }\n await db.deleteMany(ids);\n if (middleware.afterDelete) {\n for (const id of ids) {\n await middleware.afterDelete(id);\n }\n }\n } catch (error) {\n await handleError(error as Error, 'deleteMany');\n }\n },\n\n // Wrap deleteWhere (pass-through)\n async deleteWhere(filter: FilterQuery): Promise<number> {\n return db.deleteWhere(filter);\n },\n\n // Wrap search with middleware\n async search(query: Float32Array, searchOptions?: SearchOptions): Promise<SearchResult[]> {\n try {\n let q = query;\n let opts = searchOptions ?? {};\n\n if (middleware.beforeSearch) {\n const result = await middleware.beforeSearch(q, opts);\n q = result.query;\n opts = result.options;\n }\n\n let results = await db.search(q, opts);\n\n if (middleware.afterSearch) {\n results = await middleware.afterSearch(results);\n }\n\n return results;\n } catch (error) {\n return handleError(error as Error, 'search');\n }\n },\n\n // Wrap collection (pass-through)\n collection(name: string): VectorDB {\n return db.collection(name);\n },\n\n // Wrap stats (pass-through)\n async stats(): Promise<DBStats> {\n return db.stats();\n },\n\n // Wrap clear with middleware\n async clear(): Promise<void> {\n try {\n if (middleware.beforeClear) {\n const allowed = await middleware.beforeClear();\n if (!allowed) return;\n }\n await db.clear();\n if (middleware.afterClear) {\n await middleware.afterClear();\n }\n } catch (error) {\n await handleError(error as Error, 'clear');\n }\n },\n\n // Wrap close (pass-through)\n async close(): Promise<void> {\n return db.close();\n },\n\n // Wrap export (pass-through)\n async export(exportOptions?: ExportOptions): Promise<Blob> {\n return db.export(exportOptions);\n },\n\n // Wrap import (pass-through)\n async import(data: Blob, importOptions?: ImportOptions): Promise<void> {\n return db.import(data, importOptions);\n },\n\n // Pass-through for lock manager\n getLockManager() {\n return db.getLockManager();\n },\n\n // Pass-through for broadcaster\n getBroadcaster() {\n return db.getBroadcaster();\n },\n };\n\n return wrapped;\n}\n","/**\n * Caching Middleware\n *\n * Cache search results and document retrievals for improved performance.\n *\n * @packageDocumentation\n */\n\nimport type { Document, SearchResult, SearchOptions } from '../types.js';\nimport type { VectorDBMiddleware, CachingMiddlewareOptions } from './types.js';\n\n/**\n * Simple LRU cache implementation.\n */\nclass LRUCache<K, V> {\n private cache = new Map<K, { value: V; expiry: number }>();\n private maxSize: number;\n private ttlMs: number;\n\n constructor(maxSize: number, ttlMs: number) {\n this.maxSize = maxSize;\n this.ttlMs = ttlMs;\n }\n\n get(key: K): V | undefined {\n const entry = this.cache.get(key);\n if (!entry) return undefined;\n\n if (Date.now() > entry.expiry) {\n this.cache.delete(key);\n return undefined;\n }\n\n // Move to end (most recently used)\n this.cache.delete(key);\n this.cache.set(key, entry);\n return entry.value;\n }\n\n set(key: K, value: V): void {\n // Delete if exists to refresh position\n this.cache.delete(key);\n\n // Evict oldest if at capacity\n if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n if (firstKey !== undefined) {\n this.cache.delete(firstKey);\n }\n }\n\n this.cache.set(key, {\n value,\n expiry: Date.now() + this.ttlMs,\n });\n }\n\n delete(key: K): void {\n this.cache.delete(key);\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n has(key: K): boolean {\n const entry = this.cache.get(key);\n if (!entry) return false;\n if (Date.now() > entry.expiry) {\n this.cache.delete(key);\n return false;\n }\n return true;\n }\n}\n\n/**\n * Create a cache key from search parameters.\n */\nfunction createSearchCacheKey(query: Float32Array, options: SearchOptions): string {\n // Use first few elements + k + filter hash\n const queryHash = Array.from(query.slice(0, 8))\n .map((v) => v.toFixed(4))\n .join(',');\n const k = options.k ?? 10;\n const filterHash = options.filter ? JSON.stringify(options.filter) : '';\n return `search:${queryHash}:${k}:${filterHash}`;\n}\n\n/**\n * Create caching middleware for VectorDB.\n *\n * @example\n * ```typescript\n * import { createVectorDB, wrapVectorDB, cachingMiddleware } from '@localmode/core';\n *\n * const db = await createVectorDB({ name: 'my-db', dimensions: 384 });\n *\n * const cachedDb = wrapVectorDB({\n * db,\n * middleware: cachingMiddleware({\n * maxSearchResults: 100,\n * ttlMs: 60000, // 1 minute\n * }),\n * });\n * ```\n */\nexport function cachingMiddleware(options: CachingMiddlewareOptions = {}): VectorDBMiddleware {\n const {\n maxSearchResults = 100,\n ttlMs = 60000,\n cacheSearchResults = true,\n cacheDocuments = true,\n } = options;\n\n const searchCache = new LRUCache<string, SearchResult[]>(maxSearchResults, ttlMs);\n const documentCache = new LRUCache<string, Document>(maxSearchResults, ttlMs);\n\n return {\n // Cache document after get\n afterGet: async (doc: Document | undefined) => {\n if (cacheDocuments && doc) {\n documentCache.set(doc.id, doc);\n }\n return doc;\n },\n\n // Invalidate cache on add\n afterAdd: async (doc: Document) => {\n // Invalidate search cache as new document might affect results\n searchCache.clear();\n // Cache the new document\n if (cacheDocuments) {\n documentCache.set(doc.id, doc);\n }\n },\n\n // Invalidate cache on delete\n afterDelete: async (id: string) => {\n searchCache.clear();\n documentCache.delete(id);\n },\n\n // Check cache before search\n beforeSearch: async (query: Float32Array, searchOptions: SearchOptions) => {\n if (!cacheSearchResults) {\n return { query, options: searchOptions };\n }\n\n const key = createSearchCacheKey(query, searchOptions);\n const cached = searchCache.get(key);\n\n if (cached) {\n // Store in options for afterSearch to detect\n (searchOptions as Record<string, unknown>).__cacheHit = true;\n (searchOptions as Record<string, unknown>).__cachedResults = cached;\n }\n\n return { query, options: searchOptions };\n },\n\n // Return cached results or cache new results\n afterSearch: async (results: SearchResult[]) => {\n // This is a simplified implementation\n // In a real implementation, we'd need to intercept before the actual search\n return results;\n },\n\n // Clear all caches on clear\n afterClear: async () => {\n searchCache.clear();\n documentCache.clear();\n },\n };\n}\n\n/**\n * Alias for cachingMiddleware.\n */\nexport const createCachingMiddleware = cachingMiddleware;\n\n","/**\n * Logging Middleware\n *\n * Log VectorDB operations for debugging and monitoring.\n *\n * @packageDocumentation\n */\n\nimport type { Document, SearchResult, SearchOptions } from '../types.js';\nimport type { VectorDBMiddleware, LoggingMiddlewareOptions } from './types.js';\n\n/**\n * Create logging middleware for VectorDB.\n *\n * @example\n * ```typescript\n * import { createVectorDB, wrapVectorDB, loggingMiddleware } from '@localmode/core';\n *\n * const db = await createVectorDB({ name: 'my-db', dimensions: 384 });\n *\n * const loggedDb = wrapVectorDB({\n * db,\n * middleware: loggingMiddleware({\n * level: 'info',\n * timing: true,\n * }),\n * });\n * ```\n */\nexport function loggingMiddleware(options: LoggingMiddlewareOptions = {}): VectorDBMiddleware {\n const {\n logger = console.log,\n level = 'info',\n timing = true,\n operations = ['add', 'get', 'delete', 'search', 'clear'],\n formatter,\n } = options;\n\n const shouldLog = (op: string): boolean => operations.includes(op as never);\n\n const log = (operation: string, data: Record<string, unknown>): void => {\n if (formatter) {\n logger(formatter(operation, data));\n } else {\n const prefix = `[VectorDB:${level.toUpperCase()}]`;\n logger(prefix, operation, data);\n }\n };\n\n const timers = new Map<string, number>();\n\n const startTimer = (id: string): void => {\n if (timing) {\n timers.set(id, performance.now());\n }\n };\n\n const getElapsed = (id: string): number | undefined => {\n const start = timers.get(id);\n timers.delete(id);\n if (start === undefined) return undefined;\n return performance.now() - start;\n };\n\n return {\n beforeAdd: async (doc: Document) => {\n if (shouldLog('add')) {\n startTimer(`add:${doc.id}`);\n log('add:start', { id: doc.id, hasVector: !!doc.vector, hasMetadata: !!doc.metadata });\n }\n return doc;\n },\n\n afterAdd: async (doc: Document) => {\n if (shouldLog('add')) {\n const elapsed = getElapsed(`add:${doc.id}`);\n log('add:complete', { id: doc.id, durationMs: elapsed });\n }\n },\n\n afterGet: async (doc: Document | undefined) => {\n if (shouldLog('get')) {\n log('get', { id: doc?.id, found: !!doc });\n }\n return doc;\n },\n\n beforeDelete: async (id: string) => {\n if (shouldLog('delete')) {\n startTimer(`delete:${id}`);\n log('delete:start', { id });\n }\n return true;\n },\n\n afterDelete: async (id: string) => {\n if (shouldLog('delete')) {\n const elapsed = getElapsed(`delete:${id}`);\n log('delete:complete', { id, durationMs: elapsed });\n }\n },\n\n beforeSearch: async (query: Float32Array, searchOptions: SearchOptions) => {\n if (shouldLog('search')) {\n const searchId = `search:${Date.now()}`;\n startTimer(searchId);\n (searchOptions as Record<string, unknown>).__searchId = searchId;\n log('search:start', {\n k: searchOptions.k ?? 10,\n hasFilter: !!searchOptions.filter,\n dimensions: query.length,\n });\n }\n return { query, options: searchOptions };\n },\n\n afterSearch: async (results: SearchResult[]) => {\n if (shouldLog('search')) {\n log('search:complete', {\n resultCount: results.length,\n topScore: results[0]?.score,\n });\n }\n return results;\n },\n\n beforeClear: async () => {\n if (shouldLog('clear')) {\n startTimer('clear');\n log('clear:start', {});\n }\n return true;\n },\n\n afterClear: async () => {\n if (shouldLog('clear')) {\n const elapsed = getElapsed('clear');\n log('clear:complete', { durationMs: elapsed });\n }\n },\n\n onError: async (error: Error, operation: string) => {\n log('error', { operation, message: error.message, name: error.name });\n return false; // Don't suppress errors\n },\n };\n}\n\n/**\n * Alias for loggingMiddleware.\n */\nexport const createLoggingMiddleware = loggingMiddleware;\n\n","/**\n * Validation Middleware\n *\n * Validate documents before adding to VectorDB.\n *\n * @packageDocumentation\n */\n\nimport type { Document } from '../types.js';\nimport type { VectorDBMiddleware, ValidationMiddlewareOptions } from './types.js';\n\n/**\n * Create validation middleware for VectorDB.\n *\n * @example\n * ```typescript\n * import { createVectorDB, wrapVectorDB, validationMiddleware } from '@localmode/core';\n *\n * const db = await createVectorDB({ name: 'my-db', dimensions: 384 });\n *\n * const validatedDb = wrapVectorDB({\n * db,\n * middleware: validationMiddleware({\n * dimensions: 384,\n * validateValues: true,\n * maxTextLength: 100000,\n * }),\n * });\n * ```\n */\nexport function validationMiddleware(options: ValidationMiddlewareOptions = {}): VectorDBMiddleware {\n const {\n dimensions,\n validateValues = true,\n validateMetadata = true,\n maxMetadataSize = 1024 * 1024, // 1MB\n maxTextLength = 100 * 1024, // 100KB\n customValidator,\n } = options;\n\n const validateDocument = (doc: Document): void => {\n // Validate ID\n if (!doc.id || typeof doc.id !== 'string') {\n throw new Error('Document must have a valid string ID');\n }\n\n // Validate vector dimensions\n if (dimensions !== undefined && doc.vector) {\n if (doc.vector.length !== dimensions) {\n throw new Error(\n `Vector dimension mismatch: expected ${dimensions}, got ${doc.vector.length}`\n );\n }\n }\n\n // Validate vector values (no NaN or Infinity)\n if (validateValues && doc.vector) {\n for (let i = 0; i < doc.vector.length; i++) {\n const value = doc.vector[i];\n if (!Number.isFinite(value)) {\n throw new Error(`Invalid vector value at index ${i}: ${value}`);\n }\n }\n }\n\n // Validate text length (if metadata contains __text field)\n const textContent = doc.metadata?.['__text'];\n if (typeof textContent === 'string' && textContent.length > maxTextLength) {\n throw new Error(\n `Text content exceeds maximum length: ${textContent.length} > ${maxTextLength}`\n );\n }\n\n // Validate metadata size\n if (validateMetadata && doc.metadata) {\n const metadataSize = new Blob([JSON.stringify(doc.metadata)]).size;\n if (metadataSize > maxMetadataSize) {\n throw new Error(\n `Metadata exceeds maximum size: ${metadataSize} > ${maxMetadataSize}`\n );\n }\n }\n\n // Custom validation\n if (customValidator) {\n const result = customValidator(doc);\n if (typeof result === 'string') {\n throw new Error(`Custom validation failed: ${result}`);\n }\n if (result === false) {\n throw new Error('Custom validation failed');\n }\n }\n };\n\n return {\n beforeAdd: async (doc: Document) => {\n validateDocument(doc);\n return doc;\n },\n };\n}\n\n/**\n * Alias for validationMiddleware.\n */\nexport const createValidationMiddleware = validationMiddleware;\n\n","/**\n * Retry Middleware\n *\n * Provides retry logic with exponential backoff for transient failures.\n *\n * @packageDocumentation\n */\n\nimport type { EmbeddingModelMiddleware } from '../embeddings/types.js';\nimport type { RetryMiddlewareOptions } from './types.js';\n\n// ============================================================================\n// Retry Middleware for Embedding Models\n// ============================================================================\n\n/**\n * Default retry options.\n */\nexport const DEFAULT_RETRY_OPTIONS: Required<RetryMiddlewareOptions> = {\n maxRetries: 3,\n initialDelayMs: 100,\n maxDelayMs: 5000,\n backoffMultiplier: 2,\n jitter: true,\n shouldRetry: () => true,\n};\n\n/**\n * Create a retry middleware for embedding models.\n *\n * Automatically retries failed embedding operations with exponential backoff.\n *\n * @param options - Retry configuration\n * @returns Embedding model middleware\n *\n * @example\n * ```typescript\n * import { wrapEmbeddingModel, retryMiddleware } from '@localmode/core';\n *\n * const resilientModel = wrapEmbeddingModel({\n * model: transformers.embedding('Xenova/all-MiniLM-L6-v2'),\n * middleware: retryMiddleware({\n * maxRetries: 3,\n * initialDelayMs: 100,\n * shouldRetry: (error) => error.message.includes('timeout'),\n * }),\n * });\n * ```\n */\nexport function retryMiddleware(\n options: RetryMiddlewareOptions = {}\n): EmbeddingModelMiddleware {\n const config = { ...DEFAULT_RETRY_OPTIONS, ...options };\n\n return {\n wrapEmbed: async ({ doEmbed }) => {\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= config.maxRetries; attempt++) {\n try {\n return await doEmbed();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Check if we should retry\n if (attempt === config.maxRetries || !config.shouldRetry(lastError, attempt + 1)) {\n throw lastError;\n }\n\n // Calculate delay with exponential backoff\n let delay = config.initialDelayMs * Math.pow(config.backoffMultiplier, attempt);\n delay = Math.min(delay, config.maxDelayMs);\n\n // Add jitter if enabled (±25%)\n if (config.jitter) {\n const jitterRange = delay * 0.25;\n delay = delay - jitterRange + Math.random() * jitterRange * 2;\n }\n\n // Wait before retry\n await sleep(delay);\n }\n }\n\n // Should never reach here, but TypeScript needs this\n throw lastError ?? new Error('Retry failed');\n },\n };\n}\n\n/**\n * Create a retry middleware with custom configuration.\n */\nexport function createRetryMiddleware(\n options: RetryMiddlewareOptions = {}\n): EmbeddingModelMiddleware {\n return retryMiddleware(options);\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Sleep for a specified number of milliseconds.\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Common retry predicates.\n */\nexport const RetryPredicates = {\n /**\n * Retry on network errors.\n */\n networkErrors: (error: Error): boolean => {\n const message = error.message.toLowerCase();\n return (\n message.includes('network') ||\n message.includes('timeout') ||\n message.includes('fetch') ||\n message.includes('connection')\n );\n },\n\n /**\n * Retry on rate limit errors (429 status).\n */\n rateLimitErrors: (error: Error): boolean => {\n return error.message.includes('429') || error.message.toLowerCase().includes('rate limit');\n },\n\n /**\n * Retry on server errors (5xx status).\n */\n serverErrors: (error: Error): boolean => {\n const message = error.message;\n return /\\b5\\d{2}\\b/.test(message) || message.toLowerCase().includes('server error');\n },\n\n /**\n * Retry on all recoverable errors.\n */\n recoverableErrors: (error: Error): boolean => {\n return (\n RetryPredicates.networkErrors(error) ||\n RetryPredicates.rateLimitErrors(error) ||\n RetryPredicates.serverErrors(error)\n );\n },\n\n /**\n * Never retry (for testing).\n */\n never: (): boolean => false,\n\n /**\n * Always retry.\n */\n always: (): boolean => true,\n} as const;\n\n","/**\n * Rate Limit Middleware\n *\n * Provides rate limiting to prevent overwhelming APIs or local resources.\n *\n * @packageDocumentation\n */\n\nimport type { EmbeddingModelMiddleware } from '../embeddings/types.js';\nimport type { RateLimitMiddlewareOptions } from './types.js';\n\n// ============================================================================\n// Rate Limit Middleware\n// ============================================================================\n\n/**\n * Default rate limit options.\n */\nexport const DEFAULT_RATE_LIMIT_OPTIONS: Required<Omit<RateLimitMiddlewareOptions, 'onRateLimit'>> = {\n maxRequests: 100,\n windowMs: 1000,\n queue: false,\n maxQueueSize: 1000,\n};\n\n/**\n * Create a rate limiting middleware for embedding models.\n *\n * Limits the number of requests within a time window to prevent overloading.\n *\n * @param options - Rate limit configuration\n * @returns Embedding model middleware\n *\n * @example\n * ```typescript\n * import { wrapEmbeddingModel, rateLimitMiddleware } from '@localmode/core';\n *\n * const rateLimitedModel = wrapEmbeddingModel({\n * model: transformers.embedding('Xenova/all-MiniLM-L6-v2'),\n * middleware: rateLimitMiddleware({\n * maxRequests: 10,\n * windowMs: 1000, // 10 requests per second\n * onRateLimit: (waitMs) => {\n * console.log(`Rate limited, waiting ${waitMs}ms`);\n * },\n * }),\n * });\n * ```\n */\nexport function rateLimitMiddleware(\n options: RateLimitMiddlewareOptions = {}\n): EmbeddingModelMiddleware {\n const config = { ...DEFAULT_RATE_LIMIT_OPTIONS, ...options };\n\n // Track request timestamps\n const requestTimestamps: number[] = [];\n const requestQueue: Array<{\n resolve: () => void;\n reject: (error: Error) => void;\n }> = [];\n\n let processingQueue = false;\n\n const getWaitTime = (): number => {\n const now = Date.now();\n\n // Remove old timestamps outside the window\n while (requestTimestamps.length > 0 && requestTimestamps[0] < now - config.windowMs) {\n requestTimestamps.shift();\n }\n\n if (requestTimestamps.length < config.maxRequests) {\n return 0;\n }\n\n // Calculate wait time until oldest request expires\n return requestTimestamps[0] + config.windowMs - now;\n };\n\n const processQueue = async () => {\n if (processingQueue || requestQueue.length === 0) return;\n processingQueue = true;\n\n while (requestQueue.length > 0) {\n const waitTime = getWaitTime();\n\n if (waitTime > 0) {\n await sleep(waitTime);\n }\n\n const request = requestQueue.shift();\n if (request) {\n requestTimestamps.push(Date.now());\n request.resolve();\n }\n }\n\n processingQueue = false;\n };\n\n return {\n wrapEmbed: async ({ doEmbed }) => {\n const waitTime = getWaitTime();\n\n if (waitTime > 0) {\n if (config.queue) {\n // Queue the request\n if (requestQueue.length >= config.maxQueueSize) {\n throw new Error('Rate limit queue full');\n }\n\n options.onRateLimit?.(waitTime);\n\n await new Promise<void>((resolve, reject) => {\n requestQueue.push({ resolve, reject });\n processQueue();\n });\n } else {\n // Wait inline\n options.onRateLimit?.(waitTime);\n await sleep(waitTime);\n }\n }\n\n // Record this request\n requestTimestamps.push(Date.now());\n\n return doEmbed();\n },\n };\n}\n\n/**\n * Create a rate limit middleware with custom configuration.\n */\nexport function createRateLimitMiddleware(\n options: RateLimitMiddlewareOptions = {}\n): EmbeddingModelMiddleware {\n return rateLimitMiddleware(options);\n}\n\n// ============================================================================\n// Token Bucket Rate Limiter\n// ============================================================================\n\n/**\n * Token bucket rate limiter options.\n */\nexport interface TokenBucketOptions {\n /** Maximum tokens in the bucket */\n maxTokens: number;\n\n /** Tokens added per interval */\n refillRate: number;\n\n /** Interval in milliseconds */\n refillIntervalMs: number;\n}\n\n/**\n * A token bucket rate limiter.\n *\n * Provides smooth rate limiting with burst capacity.\n *\n * @example\n * ```typescript\n * const bucket = new TokenBucket({\n * maxTokens: 100,\n * refillRate: 10,\n * refillIntervalMs: 1000, // 10 tokens per second, max 100\n * });\n *\n * if (bucket.tryConsume(1)) {\n * // Proceed with operation\n * } else {\n * // Rate limited\n * }\n * ```\n */\nexport class TokenBucket {\n private tokens: number;\n private lastRefill: number;\n private readonly options: TokenBucketOptions;\n\n constructor(options: TokenBucketOptions) {\n this.options = options;\n this.tokens = options.maxTokens;\n this.lastRefill = Date.now();\n }\n\n /**\n * Refill tokens based on elapsed time.\n */\n private refill(): void {\n const now = Date.now();\n const elapsed = now - this.lastRefill;\n const intervalsElapsed = Math.floor(elapsed / this.options.refillIntervalMs);\n\n if (intervalsElapsed > 0) {\n this.tokens = Math.min(\n this.options.maxTokens,\n this.tokens + intervalsElapsed * this.options.refillRate\n );\n this.lastRefill = now;\n }\n }\n\n /**\n * Try to consume tokens from the bucket.\n *\n * @param count - Number of tokens to consume\n * @returns true if tokens were consumed, false if not enough tokens\n */\n tryConsume(count: number = 1): boolean {\n this.refill();\n\n if (this.tokens >= count) {\n this.tokens -= count;\n return true;\n }\n\n return false;\n }\n\n /**\n * Wait until tokens are available, then consume.\n *\n * @param count - Number of tokens to consume\n * @param timeout - Maximum time to wait in milliseconds\n * @returns Promise that resolves when tokens are consumed\n */\n async consume(count: number = 1, timeout?: number): Promise<void> {\n const startTime = Date.now();\n\n while (!this.tryConsume(count)) {\n if (timeout && Date.now() - startTime >= timeout) {\n throw new Error('Token bucket timeout');\n }\n\n // Wait for next refill interval\n await sleep(this.options.refillIntervalMs);\n }\n }\n\n /**\n * Get the current number of tokens.\n */\n getTokens(): number {\n this.refill();\n return this.tokens;\n }\n\n /**\n * Check if tokens are available without consuming.\n */\n hasTokens(count: number = 1): boolean {\n this.refill();\n return this.tokens >= count;\n }\n\n /**\n * Get estimated wait time for tokens.\n */\n getWaitTime(count: number = 1): number {\n this.refill();\n\n if (this.tokens >= count) {\n return 0;\n }\n\n const needed = count - this.tokens;\n const intervalsNeeded = Math.ceil(needed / this.options.refillRate);\n return intervalsNeeded * this.options.refillIntervalMs;\n }\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Sleep for a specified number of milliseconds.\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n","/**\n * Storage Quota Utilities\n *\n * Provides utilities for monitoring browser storage quota and managing data lifecycle.\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Storage quota information.\n */\nexport interface StorageQuota {\n /** Used storage in bytes */\n usedBytes: number;\n\n /** Total quota in bytes */\n quotaBytes: number;\n\n /** Percentage of quota used (0-100) */\n percentUsed: number;\n\n /** Whether storage is persisted (won't be evicted) */\n isPersisted: boolean;\n\n /** Available storage in bytes */\n availableBytes: number;\n}\n\n/**\n * Configuration for quota warnings.\n */\nexport interface QuotaWarningConfig {\n /** Warn at this usage percentage (default: 80) */\n warnAt?: number;\n\n /** Critical at this percentage (default: 95) */\n criticalAt?: number;\n\n /** Callback when warning threshold reached */\n onWarning?: (quota: StorageQuota) => void;\n\n /** Callback when critical threshold reached */\n onCritical?: (quota: StorageQuota) => void;\n}\n\n/**\n * Options for cleanup operations.\n */\nexport interface CleanupOptions {\n /** Delete documents older than this (e.g., '30d', '1w', '24h') */\n maxAge?: string;\n\n /** Keep at least this many documents */\n keepMinCount?: number;\n\n /** Target storage usage percentage after cleanup */\n targetUsage?: number;\n\n /** Collections to clean (default: all) */\n collections?: string[];\n\n /** Dry run - report what would be deleted without deleting */\n dryRun?: boolean;\n}\n\n/**\n * Result of a cleanup operation.\n */\nexport interface CleanupResult {\n /** Number of documents deleted */\n deletedCount: number;\n\n /** Estimated bytes freed */\n freedBytes: number;\n\n /** Documents that would have been deleted (dry run only) */\n toDelete?: string[];\n}\n\n// ============================================================================\n// Storage Quota Functions\n// ============================================================================\n\n/**\n * Get current storage quota information.\n *\n * @returns Storage quota info or null if API not available\n *\n * @example\n * ```typescript\n * import { getStorageQuota } from '@localmode/core';\n *\n * const quota = await getStorageQuota();\n * if (quota) {\n * console.log(`Using ${quota.percentUsed.toFixed(1)}% of storage`);\n * console.log(`${(quota.availableBytes / 1024 / 1024).toFixed(1)} MB available`);\n * }\n * ```\n */\nexport async function getStorageQuota(): Promise<StorageQuota | null> {\n if (typeof navigator === 'undefined' || !navigator.storage?.estimate) {\n return null;\n }\n\n try {\n const estimate = await navigator.storage.estimate();\n const persisted = await navigator.storage.persisted?.() ?? false;\n\n const usedBytes = estimate.usage ?? 0;\n const quotaBytes = estimate.quota ?? 0;\n\n return {\n usedBytes,\n quotaBytes,\n percentUsed: quotaBytes > 0 ? (usedBytes / quotaBytes) * 100 : 0,\n isPersisted: persisted,\n availableBytes: Math.max(0, quotaBytes - usedBytes),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Request persistent storage to prevent data eviction.\n *\n * Browsers may evict IndexedDB data under storage pressure.\n * Requesting persistence tells the browser to keep the data.\n *\n * @returns true if persistence was granted\n *\n * @example\n * ```typescript\n * import { requestPersistence } from '@localmode/core';\n *\n * const granted = await requestPersistence();\n * if (granted) {\n * console.log('Storage will not be evicted');\n * } else {\n * console.log('Persistence not granted - data may be evicted under pressure');\n * }\n * ```\n */\nexport async function requestPersistence(): Promise<boolean> {\n if (typeof navigator === 'undefined' || !navigator.storage?.persist) {\n return false;\n }\n\n try {\n return await navigator.storage.persist();\n } catch {\n return false;\n }\n}\n\n/**\n * Check if storage is persisted.\n *\n * @returns true if storage is persisted\n */\nexport async function isStoragePersisted(): Promise<boolean> {\n if (typeof navigator === 'undefined' || !navigator.storage?.persisted) {\n return false;\n }\n\n try {\n return await navigator.storage.persisted();\n } catch {\n return false;\n }\n}\n\n/**\n * Check storage quota and invoke callbacks based on thresholds.\n *\n * @param config - Warning configuration\n * @returns 'ok' | 'warning' | 'critical' based on current usage\n *\n * @example\n * ```typescript\n * import { checkQuotaWithWarnings } from '@localmode/core';\n *\n * const status = await checkQuotaWithWarnings({\n * warnAt: 80,\n * criticalAt: 95,\n * onWarning: (quota) => {\n * console.warn(`Storage at ${quota.percentUsed.toFixed(1)}%`);\n * },\n * onCritical: (quota) => {\n * console.error('Storage critical! Cleanup required.');\n * showCleanupDialog();\n * },\n * });\n * ```\n */\nexport async function checkQuotaWithWarnings(\n config: QuotaWarningConfig = {}\n): Promise<'ok' | 'warning' | 'critical'> {\n const { warnAt = 80, criticalAt = 95, onWarning, onCritical } = config;\n\n const quota = await getStorageQuota();\n if (!quota) return 'ok';\n\n if (quota.percentUsed >= criticalAt) {\n onCritical?.(quota);\n return 'critical';\n }\n\n if (quota.percentUsed >= warnAt) {\n onWarning?.(quota);\n return 'warning';\n }\n\n return 'ok';\n}\n\n/**\n * Estimate how many documents can be stored with remaining quota.\n *\n * @param avgDocSizeBytes - Average document size in bytes\n * @returns Estimated number of documents that can be stored\n */\nexport async function estimateRemainingCapacity(avgDocSizeBytes: number): Promise<number> {\n const quota = await getStorageQuota();\n if (!quota || avgDocSizeBytes <= 0) return 0;\n\n return Math.floor(quota.availableBytes / avgDocSizeBytes);\n}\n\n// ============================================================================\n// Age Parsing Utilities\n// ============================================================================\n\n/**\n * Parse an age string into milliseconds.\n *\n * @param age - Age string like '30d', '1w', '24h', '60m'\n * @returns Milliseconds\n *\n * @example\n * ```typescript\n * parseAge('30d'); // 30 days in ms\n * parseAge('1w'); // 1 week in ms\n * parseAge('24h'); // 24 hours in ms\n * ```\n */\nexport function parseAge(age: string): number {\n const match = age.match(/^(\\d+)\\s*(d|w|h|m|s)$/i);\n if (!match) {\n throw new Error(`Invalid age format: ${age}. Use format like '30d', '1w', '24h', '60m', '30s'`);\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2].toLowerCase();\n\n const multipliers: Record<string, number> = {\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n w: 7 * 24 * 60 * 60 * 1000,\n };\n\n return value * (multipliers[unit] ?? 0);\n}\n\n/**\n * Format bytes into a human-readable string.\n *\n * @param bytes - Number of bytes\n * @returns Formatted string like '1.5 MB'\n */\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n\n const units = ['B', 'KB', 'MB', 'GB', 'TB'];\n const k = 1024;\n const i = Math.floor(Math.log(Math.abs(bytes)) / Math.log(k));\n\n return `${(bytes / Math.pow(k, i)).toFixed(1)} ${units[i]}`;\n}\n\n// ============================================================================\n// Storage Monitoring\n// ============================================================================\n\n/**\n * Options for storage monitoring.\n */\nexport interface StorageMonitorOptions {\n /** Check interval in milliseconds (default: 60000 = 1 minute) */\n intervalMs?: number;\n\n /** Warning threshold percentage (default: 80) */\n warnAt?: number;\n\n /** Critical threshold percentage (default: 95) */\n criticalAt?: number;\n\n /** Callback when status changes */\n onStatusChange?: (status: 'ok' | 'warning' | 'critical', quota: StorageQuota) => void;\n}\n\n/**\n * Start monitoring storage quota.\n *\n * @param options - Monitoring options\n * @returns Function to stop monitoring\n *\n * @example\n * ```typescript\n * const stopMonitoring = startStorageMonitor({\n * intervalMs: 30000, // Check every 30 seconds\n * onStatusChange: (status, quota) => {\n * if (status === 'critical') {\n * showStorageWarning();\n * }\n * },\n * });\n *\n * // Later, stop monitoring\n * stopMonitoring();\n * ```\n */\nexport function startStorageMonitor(options: StorageMonitorOptions = {}): () => void {\n const {\n intervalMs = 60000,\n warnAt = 80,\n criticalAt = 95,\n onStatusChange,\n } = options;\n\n let lastStatus: 'ok' | 'warning' | 'critical' = 'ok';\n let intervalId: ReturnType<typeof setInterval> | null = null;\n\n const check = async () => {\n const quota = await getStorageQuota();\n if (!quota) return;\n\n let status: 'ok' | 'warning' | 'critical' = 'ok';\n if (quota.percentUsed >= criticalAt) {\n status = 'critical';\n } else if (quota.percentUsed >= warnAt) {\n status = 'warning';\n }\n\n if (status !== lastStatus) {\n lastStatus = status;\n onStatusChange?.(status, quota);\n }\n };\n\n // Initial check\n check();\n\n // Start interval\n intervalId = setInterval(check, intervalMs);\n\n // Return cleanup function\n return () => {\n if (intervalId) {\n clearInterval(intervalId);\n intervalId = null;\n }\n };\n}\n\n","/**\n * Storage Cleanup Utilities\n *\n * Provides lifecycle management for VectorDB data including\n * cleanup strategies based on age, count, and storage usage.\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Options for cleanup operations.\n */\nexport interface CleanupOptions {\n /**\n * Delete documents older than this duration.\n * Supports formats like '30d', '24h', '1w', '2m'.\n */\n maxAge?: string;\n\n /**\n * Keep at least this many documents (most recent).\n * Applied after maxAge filter.\n */\n keepMinCount?: number;\n\n /**\n * Target storage usage percentage (0-100).\n * Will delete oldest documents until this target is reached.\n */\n targetUsagePercent?: number;\n\n /**\n * Collections to clean (default: all).\n */\n collections?: string[];\n\n /**\n * Dry run - calculate what would be deleted without actually deleting.\n */\n dryRun?: boolean;\n\n /**\n * Batch size for deletion operations.\n */\n batchSize?: number;\n\n /**\n * Progress callback.\n */\n onProgress?: (progress: CleanupProgress) => void;\n}\n\n/**\n * Progress information during cleanup.\n */\nexport interface CleanupProgress {\n phase: 'analyzing' | 'deleting' | 'complete';\n current: number;\n total: number;\n deletedCount: number;\n freedBytes: number;\n}\n\n/**\n * Result of a cleanup operation.\n */\nexport interface CleanupResult {\n /** Number of documents deleted */\n deletedCount: number;\n\n /** Estimated bytes freed */\n freedBytes: number;\n\n /** Documents that would be deleted (dry run only) */\n deletedIds?: string[];\n\n /** Duration of the cleanup operation in ms */\n durationMs: number;\n}\n\n/**\n * Options for estimating cleanup size.\n */\nexport interface EstimateCleanupOptions {\n /** Same as CleanupOptions but for estimation */\n maxAge?: string;\n keepMinCount?: number;\n targetUsagePercent?: number;\n collections?: string[];\n}\n\n/**\n * Result of cleanup size estimation.\n */\nexport interface CleanupEstimate {\n /** Number of documents that would be deleted */\n documentCount: number;\n\n /** Estimated bytes that would be freed */\n estimatedBytes: number;\n\n /** Percentage of total documents that would be deleted */\n percentageOfTotal: number;\n}\n\n// ============================================================================\n// Duration Parsing\n// ============================================================================\n\n/**\n * Parse a duration string into milliseconds.\n *\n * @param duration - Duration string like '30d', '24h', '1w'\n * @returns Duration in milliseconds\n *\n * @example\n * ```typescript\n * parseAge('30d') // 30 days in ms\n * parseAge('24h') // 24 hours in ms\n * parseAge('1w') // 1 week in ms\n * parseAge('2m') // 2 months in ms (approximate)\n * ```\n */\nexport function parseAge(duration: string): number {\n const match = duration.match(/^(\\d+(?:\\.\\d+)?)\\s*(s|m|h|d|w|M|y)$/);\n\n if (!match) {\n throw new Error(\n `Invalid duration format: \"${duration}\". Expected format like '30d', '24h', '1w', etc.`\n );\n }\n\n const value = parseFloat(match[1]);\n const unit = match[2];\n\n const multipliers: Record<string, number> = {\n s: 1000, // seconds\n m: 60 * 1000, // minutes\n h: 60 * 60 * 1000, // hours\n d: 24 * 60 * 60 * 1000, // days\n w: 7 * 24 * 60 * 60 * 1000, // weeks\n M: 30 * 24 * 60 * 60 * 1000, // months (approximate)\n y: 365 * 24 * 60 * 60 * 1000, // years (approximate)\n };\n\n const multiplier = multipliers[unit];\n if (multiplier === undefined) {\n throw new Error(`Unknown duration unit: \"${unit}\"`);\n }\n\n return value * multiplier;\n}\n\n/**\n * Format milliseconds as a human-readable duration.\n *\n * @param ms - Duration in milliseconds\n * @returns Human-readable string\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n if (ms < 3600000) return `${(ms / 60000).toFixed(1)}m`;\n if (ms < 86400000) return `${(ms / 3600000).toFixed(1)}h`;\n return `${(ms / 86400000).toFixed(1)}d`;\n}\n\n// ============================================================================\n// Cleanup Interface (to be implemented by VectorDB)\n// ============================================================================\n\n/**\n * Interface for VectorDB cleanup operations.\n * VectorDB implementations should implement these methods.\n */\nexport interface CleanupableDB {\n /** Get all document IDs with their creation timestamps */\n getDocumentsWithTimestamps(): Promise<Array<{ id: string; createdAt: number; sizeBytes?: number }>>;\n\n /** Delete multiple documents by ID */\n deleteMany(ids: string[]): Promise<void>;\n\n /** Get the total document count */\n count(): Promise<number>;\n}\n\n// ============================================================================\n// Cleanup Functions\n// ============================================================================\n\n/**\n * Perform cleanup on a VectorDB.\n *\n * @param db - VectorDB instance with cleanup methods\n * @param options - Cleanup configuration\n * @returns Cleanup result\n *\n * @example\n * ```typescript\n * import { cleanup } from '@localmode/core';\n *\n * // Delete documents older than 30 days\n * const result = await cleanup(db, { maxAge: '30d' });\n * console.log(`Deleted ${result.deletedCount} documents`);\n *\n * // Dry run to see what would be deleted\n * const dryResult = await cleanup(db, { maxAge: '7d', dryRun: true });\n * console.log(`Would delete ${dryResult.deletedCount} documents`);\n *\n * // Keep storage under 80% usage\n * await cleanup(db, { targetUsagePercent: 80 });\n * ```\n */\nexport async function cleanup(\n db: CleanupableDB,\n options: CleanupOptions = {}\n): Promise<CleanupResult> {\n const startTime = performance.now();\n const {\n maxAge,\n keepMinCount = 0,\n targetUsagePercent,\n batchSize = 100,\n dryRun = false,\n onProgress,\n } = options;\n\n onProgress?.({\n phase: 'analyzing',\n current: 0,\n total: 0,\n deletedCount: 0,\n freedBytes: 0,\n });\n\n // Get all documents with timestamps\n const documents = await db.getDocumentsWithTimestamps();\n const totalCount = documents.length;\n\n // Sort by creation time (oldest first)\n documents.sort((a, b) => a.createdAt - b.createdAt);\n\n // Determine which documents to delete\n let toDelete: Array<{ id: string; sizeBytes?: number }> = [];\n\n if (maxAge) {\n const maxAgeMs = parseAge(maxAge);\n const cutoff = Date.now() - maxAgeMs;\n\n toDelete = documents.filter((doc) => doc.createdAt < cutoff);\n } else if (targetUsagePercent !== undefined) {\n // Storage-based cleanup (simplified - would need storage quota info)\n // For now, just mark oldest documents for deletion proportionally\n const targetRemovePercent = Math.max(0, 100 - targetUsagePercent);\n const removeCount = Math.floor(totalCount * (targetRemovePercent / 100));\n toDelete = documents.slice(0, removeCount);\n }\n\n // Respect keepMinCount\n const maxToDelete = Math.max(0, totalCount - keepMinCount);\n if (toDelete.length > maxToDelete) {\n toDelete = toDelete.slice(0, maxToDelete);\n }\n\n // Calculate estimated freed bytes\n const freedBytes = toDelete.reduce(\n (sum, doc) => sum + (doc.sizeBytes ?? 1024), // Estimate 1KB if unknown\n 0\n );\n\n // If dry run, return without deleting\n if (dryRun) {\n return {\n deletedCount: toDelete.length,\n freedBytes,\n deletedIds: toDelete.map((d) => d.id),\n durationMs: performance.now() - startTime,\n };\n }\n\n // Delete in batches\n let deletedCount = 0;\n\n for (let i = 0; i < toDelete.length; i += batchSize) {\n const batch = toDelete.slice(i, i + batchSize);\n const batchIds = batch.map((d) => d.id);\n\n await db.deleteMany(batchIds);\n deletedCount += batch.length;\n\n onProgress?.({\n phase: 'deleting',\n current: deletedCount,\n total: toDelete.length,\n deletedCount,\n freedBytes: batch.reduce((sum, d) => sum + (d.sizeBytes ?? 1024), 0),\n });\n }\n\n onProgress?.({\n phase: 'complete',\n current: deletedCount,\n total: deletedCount,\n deletedCount,\n freedBytes,\n });\n\n return {\n deletedCount,\n freedBytes,\n durationMs: performance.now() - startTime,\n };\n}\n\n/**\n * Estimate cleanup size without performing deletion.\n *\n * @param db - VectorDB instance\n * @param options - Estimation options\n * @returns Estimated cleanup impact\n */\nexport async function estimateCleanupSize(\n db: CleanupableDB,\n options: EstimateCleanupOptions\n): Promise<CleanupEstimate> {\n const result = await cleanup(db, { ...options, dryRun: true });\n const totalCount = await db.count();\n\n return {\n documentCount: result.deletedCount,\n estimatedBytes: result.freedBytes,\n percentageOfTotal: totalCount > 0 ? (result.deletedCount / totalCount) * 100 : 0,\n };\n}\n\n/**\n * Common cleanup strategies.\n */\nexport const CleanupStrategies = {\n /**\n * Delete documents older than 30 days.\n */\n monthly: { maxAge: '30d' } as CleanupOptions,\n\n /**\n * Delete documents older than 7 days.\n */\n weekly: { maxAge: '7d' } as CleanupOptions,\n\n /**\n * Delete documents older than 24 hours.\n */\n daily: { maxAge: '24h' } as CleanupOptions,\n\n /**\n * Keep storage under 80%, preserve at least 100 documents.\n */\n conservative: { targetUsagePercent: 80, keepMinCount: 100 } as CleanupOptions,\n\n /**\n * Keep storage under 50%, preserve at least 50 documents.\n */\n aggressive: { targetUsagePercent: 50, keepMinCount: 50 } as CleanupOptions,\n} as const;\n\n","/**\n * Network Status Utilities\n *\n * Provides utilities for detecting and monitoring network connectivity.\n * Essential for offline-first applications.\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Network connection status.\n */\nexport interface NetworkStatus {\n /** Whether the browser is online */\n isOnline: boolean;\n\n /** Connection type if available (wifi, cellular, etc.) */\n connectionType?: string;\n\n /** Effective connection type if available (slow-2g, 2g, 3g, 4g) */\n effectiveType?: '4g' | '3g' | '2g' | 'slow-2g';\n\n /** Downlink speed in Mbps if available */\n downlink?: number;\n\n /** Round-trip time in ms if available */\n rtt?: number;\n\n /** Whether the user has requested reduced data usage */\n saveData?: boolean;\n}\n\n/**\n * Network change event callback.\n */\nexport type NetworkChangeCallback = (status: NetworkStatus) => void;\n\n// ============================================================================\n// Network Status Functions\n// ============================================================================\n\n/**\n * Get the current network status.\n *\n * @returns Current network status\n *\n * @example\n * ```typescript\n * import { getNetworkStatus } from '@localmode/core';\n *\n * const status = getNetworkStatus();\n * if (!status.isOnline) {\n * console.log('App is offline');\n * }\n *\n * if (status.effectiveType === 'slow-2g') {\n * console.log('Slow connection - using smaller models');\n * }\n * ```\n */\nexport function getNetworkStatus(): NetworkStatus {\n // Check if we're in a browser environment\n if (typeof navigator === 'undefined') {\n return { isOnline: true }; // Assume online in non-browser environments\n }\n\n const connection = (navigator as NavigatorWithConnection).connection;\n\n return {\n isOnline: navigator.onLine,\n connectionType: connection?.type,\n effectiveType: connection?.effectiveType as NetworkStatus['effectiveType'],\n downlink: connection?.downlink,\n rtt: connection?.rtt,\n saveData: connection?.saveData,\n };\n}\n\n/**\n * Check if the browser is currently offline.\n *\n * @returns true if offline\n *\n * @example\n * ```typescript\n * if (isOffline()) {\n * showOfflineIndicator();\n * }\n * ```\n */\nexport function isOffline(): boolean {\n if (typeof navigator === 'undefined') {\n return false;\n }\n return !navigator.onLine;\n}\n\n/**\n * Check if the browser is currently online.\n *\n * @returns true if online\n */\nexport function isOnline(): boolean {\n if (typeof navigator === 'undefined') {\n return true;\n }\n return navigator.onLine;\n}\n\n/**\n * Subscribe to network status changes.\n *\n * @param callback - Function to call when network status changes\n * @returns Unsubscribe function\n *\n * @example\n * ```typescript\n * import { onNetworkChange } from '@localmode/core';\n *\n * const unsubscribe = onNetworkChange((status) => {\n * if (status.isOnline) {\n * console.log('Back online - syncing data');\n * syncPendingChanges();\n * } else {\n * console.log('Went offline - enabling offline mode');\n * enableOfflineMode();\n * }\n * });\n *\n * // Later, stop listening\n * unsubscribe();\n * ```\n */\nexport function onNetworkChange(callback: NetworkChangeCallback): () => void {\n if (typeof window === 'undefined') {\n return () => {}; // No-op in non-browser environments\n }\n\n const handler = () => callback(getNetworkStatus());\n\n // Listen for online/offline events\n window.addEventListener('online', handler);\n window.addEventListener('offline', handler);\n\n // Listen for connection changes if available\n const connection = (navigator as NavigatorWithConnection).connection;\n if (connection) {\n connection.addEventListener('change', handler);\n }\n\n // Return cleanup function\n return () => {\n window.removeEventListener('online', handler);\n window.removeEventListener('offline', handler);\n if (connection) {\n connection.removeEventListener('change', handler);\n }\n };\n}\n\n/**\n * Wait for the network to come back online.\n *\n * @param timeout - Optional timeout in milliseconds\n * @returns Promise that resolves when online, rejects on timeout\n *\n * @example\n * ```typescript\n * try {\n * await waitForOnline(30000); // Wait up to 30 seconds\n * console.log('Network restored');\n * } catch {\n * console.log('Timeout waiting for network');\n * }\n * ```\n */\nexport function waitForOnline(timeout?: number): Promise<void> {\n return new Promise((resolve, reject) => {\n if (isOnline()) {\n resolve();\n return;\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n let unsubscribe: (() => void) | undefined;\n\n const cleanup = () => {\n if (timeoutId) clearTimeout(timeoutId);\n if (unsubscribe) unsubscribe();\n };\n\n unsubscribe = onNetworkChange((status) => {\n if (status.isOnline) {\n cleanup();\n resolve();\n }\n });\n\n if (timeout) {\n timeoutId = setTimeout(() => {\n cleanup();\n reject(new Error('Timeout waiting for network'));\n }, timeout);\n }\n });\n}\n\n/**\n * Check if the connection is suitable for large operations.\n *\n * Returns false for slow connections (2g, slow-2g) or when saveData is enabled.\n *\n * @returns true if connection is suitable for large operations\n *\n * @example\n * ```typescript\n * if (isConnectionSuitable()) {\n * await downloadLargeModel();\n * } else {\n * await downloadSmallModel();\n * }\n * ```\n */\nexport function isConnectionSuitable(): boolean {\n const status = getNetworkStatus();\n\n if (!status.isOnline) return false;\n if (status.saveData) return false;\n\n if (status.effectiveType === 'slow-2g' || status.effectiveType === '2g') {\n return false;\n }\n\n return true;\n}\n\n/**\n * Get a recommendation for which resources to load based on connection.\n *\n * @returns Recommendation object\n *\n * @example\n * ```typescript\n * const rec = getConnectionRecommendation();\n * if (rec.useLargeModels) {\n * loadModel('whisper-large');\n * } else {\n * loadModel('whisper-tiny');\n * }\n * ```\n */\nexport function getConnectionRecommendation(): {\n useLargeModels: boolean;\n preloadAssets: boolean;\n downloadInBackground: boolean;\n} {\n const status = getNetworkStatus();\n\n if (!status.isOnline) {\n return {\n useLargeModels: false,\n preloadAssets: false,\n downloadInBackground: false,\n };\n }\n\n if (status.saveData) {\n return {\n useLargeModels: false,\n preloadAssets: false,\n downloadInBackground: false,\n };\n }\n\n if (status.effectiveType === 'slow-2g' || status.effectiveType === '2g') {\n return {\n useLargeModels: false,\n preloadAssets: false,\n downloadInBackground: false,\n };\n }\n\n if (status.effectiveType === '3g') {\n return {\n useLargeModels: false,\n preloadAssets: true,\n downloadInBackground: true,\n };\n }\n\n // 4g or unknown (assume good connection)\n return {\n useLargeModels: true,\n preloadAssets: true,\n downloadInBackground: true,\n };\n}\n\n// ============================================================================\n// Type Augmentation for Network Information API\n// ============================================================================\n\n/**\n * Network Information API connection interface.\n */\ninterface NetworkInformation extends EventTarget {\n readonly type?: string;\n readonly effectiveType?: string;\n readonly downlink?: number;\n readonly rtt?: number;\n readonly saveData?: boolean;\n}\n\n/**\n * Navigator with connection property.\n */\ninterface NavigatorWithConnection extends Navigator {\n readonly connection?: NetworkInformation;\n}\n\n","/**\n * Event System\n *\n * Provides event emission and subscription for VectorDB lifecycle events.\n * Enables reactive updates in UI frameworks.\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Callback function for event handlers.\n */\nexport type EventCallback<T = unknown> = (data: T) => void | Promise<void>;\n\n/**\n * Unsubscribe function returned when subscribing to events.\n */\nexport type Unsubscribe = () => void;\n\n/**\n * VectorDB event types.\n */\nexport interface VectorDBEvents extends Record<string, unknown> {\n /** Emitted when a document is added */\n add: { id: string; collection?: string };\n\n /** Emitted when multiple documents are added */\n addMany: { ids: string[]; collection?: string };\n\n /** Emitted after a document is retrieved */\n get: { id: string; found: boolean };\n\n /** Emitted when a document is updated */\n update: { id: string; collection?: string };\n\n /** Emitted when a document is deleted */\n delete: { id: string };\n\n /** Emitted when multiple documents are deleted */\n deleteMany: { ids: string[] };\n\n /** Emitted after a search operation */\n search: { resultsCount: number; k: number; durationMs: number };\n\n /** Emitted when the database is cleared */\n clear: { documentCount: number };\n\n /** Emitted on any error */\n error: { operation: string; error: Error };\n\n /** Emitted when database is opened */\n open: { name: string };\n\n /** Emitted when database is closed */\n close: { name: string };\n\n /** Index signature for Record<string, unknown> compatibility */\n [key: string]: unknown;\n}\n\n/**\n * Embedding model event types.\n */\nexport interface EmbeddingEvents {\n /** Emitted before embedding starts */\n embedStart: { valueCount: number };\n\n /** Emitted after embedding completes */\n embedComplete: { valueCount: number; durationMs: number; tokens: number };\n\n /** Emitted on embedding error */\n embedError: { error: Error };\n\n /** Emitted when model is loaded */\n modelLoad: { modelId: string; durationMs: number };\n\n /** Emitted when model loading fails */\n modelLoadError: { modelId: string; error: Error };\n}\n\n// ============================================================================\n// Event Emitter Implementation\n// ============================================================================\n\n/**\n * Type-safe event emitter.\n *\n * @example\n * ```typescript\n * import { EventEmitter, VectorDBEvents } from '@localmode/core';\n *\n * const emitter = new EventEmitter<VectorDBEvents>();\n *\n * // Subscribe to events\n * const unsubscribe = emitter.on('add', ({ id }) => {\n * console.log('Document added:', id);\n * });\n *\n * // Emit events\n * emitter.emit('add', { id: 'doc-1' });\n *\n * // Unsubscribe when done\n * unsubscribe();\n * ```\n */\nexport class EventEmitter<Events extends Record<string, unknown>> {\n private listeners: Map<keyof Events, Set<EventCallback>> = new Map();\n\n /**\n * Subscribe to an event.\n *\n * @param event - Event name to subscribe to\n * @param callback - Function to call when event is emitted\n * @returns Unsubscribe function\n */\n on<K extends keyof Events>(event: K, callback: EventCallback<Events[K]>): Unsubscribe {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n\n set.add(callback as EventCallback);\n\n return () => {\n set?.delete(callback as EventCallback);\n if (set?.size === 0) {\n this.listeners.delete(event);\n }\n };\n }\n\n /**\n * Subscribe to an event for a single emission.\n *\n * @param event - Event name to subscribe to\n * @param callback - Function to call when event is emitted\n * @returns Unsubscribe function\n */\n once<K extends keyof Events>(event: K, callback: EventCallback<Events[K]>): Unsubscribe {\n const wrappedCallback: EventCallback<Events[K]> = (data) => {\n unsubscribe();\n callback(data);\n };\n const unsubscribe = this.on(event, wrappedCallback);\n return unsubscribe;\n }\n\n /**\n * Emit an event.\n *\n * @param event - Event name to emit\n * @param data - Event data\n */\n emit<K extends keyof Events>(event: K, data: Events[K]): void {\n const set = this.listeners.get(event);\n if (set) {\n for (const callback of set) {\n try {\n callback(data);\n } catch (error) {\n console.error(`Error in event handler for \"${String(event)}\":`, error);\n }\n }\n }\n }\n\n /**\n * Emit an event and wait for all async handlers.\n *\n * @param event - Event name to emit\n * @param data - Event data\n */\n async emitAsync<K extends keyof Events>(event: K, data: Events[K]): Promise<void> {\n const set = this.listeners.get(event);\n if (set) {\n const promises: Promise<void>[] = [];\n for (const callback of set) {\n try {\n const result = callback(data);\n if (result instanceof Promise) {\n promises.push(result);\n }\n } catch (error) {\n console.error(`Error in event handler for \"${String(event)}\":`, error);\n }\n }\n await Promise.all(promises);\n }\n }\n\n /**\n * Remove all listeners for an event.\n *\n * @param event - Event name to clear (optional, clears all if not specified)\n */\n off<K extends keyof Events>(event?: K): void {\n if (event !== undefined) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n\n /**\n * Get the number of listeners for an event.\n *\n * @param event - Event name\n * @returns Number of listeners\n */\n listenerCount<K extends keyof Events>(event: K): number {\n return this.listeners.get(event)?.size ?? 0;\n }\n\n /**\n * Check if there are any listeners for an event.\n *\n * @param event - Event name\n * @returns true if there are listeners\n */\n hasListeners<K extends keyof Events>(event: K): boolean {\n return this.listenerCount(event) > 0;\n }\n\n /**\n * Get all event names with listeners.\n *\n * @returns Array of event names\n */\n eventNames(): Array<keyof Events> {\n return Array.from(this.listeners.keys());\n }\n}\n\n/**\n * Create a new event emitter.\n *\n * @returns New EventEmitter instance\n *\n * @example\n * ```typescript\n * import { createEventEmitter, VectorDBEvents } from '@localmode/core';\n *\n * const events = createEventEmitter<VectorDBEvents>();\n *\n * events.on('add', ({ id }) => {\n * console.log('Added:', id);\n * });\n * ```\n */\nexport function createEventEmitter<\n Events extends Record<string, unknown> = VectorDBEvents\n>(): EventEmitter<Events> {\n return new EventEmitter<Events>();\n}\n\n// ============================================================================\n// Event Bus (Shared Events Across Instances)\n// ============================================================================\n\n/**\n * Global event bus for cross-instance communication.\n *\n * Useful for:\n * - Synchronizing state across multiple VectorDB instances\n * - Notifying UI components of database changes\n * - Debugging and logging\n *\n * @example\n * ```typescript\n * import { globalEventBus } from '@localmode/core';\n *\n * // Subscribe to all database changes\n * globalEventBus.on('add', ({ id }) => {\n * console.log('Document added somewhere:', id);\n * });\n * ```\n */\nexport const globalEventBus = createEventEmitter<VectorDBEvents>();\n\n// ============================================================================\n// Event Middleware\n// ============================================================================\n\n/**\n * Create event-emitting middleware for VectorDB.\n *\n * @param emitter - Event emitter to use\n * @returns VectorDB middleware\n *\n * @example\n * ```typescript\n * import { wrapVectorDB, createEventEmitter, eventMiddleware } from '@localmode/core';\n *\n * const events = createEventEmitter();\n *\n * // Subscribe to events\n * events.on('add', ({ id }) => console.log('Added:', id));\n * events.on('delete', ({ id }) => console.log('Deleted:', id));\n *\n * // Create DB with event middleware\n * const db = wrapVectorDB({\n * db: baseDb,\n * middleware: eventMiddleware(events),\n * });\n * ```\n */\nexport function eventMiddleware(\n emitter: EventEmitter<VectorDBEvents>\n): {\n afterAdd: (doc: { id: string; metadata?: { collection?: string } }) => void;\n afterDelete: (id: string) => void;\n afterClear: () => void;\n} {\n return {\n afterAdd: (doc) => {\n emitter.emit('add', {\n id: doc.id,\n collection: doc.metadata?.collection,\n });\n },\n afterDelete: (id) => {\n emitter.emit('delete', { id });\n },\n afterClear: () => {\n emitter.emit('clear', { documentCount: 0 });\n },\n };\n}\n\n// Types are exported inline at the top of the file\n\n","/**\n * Feature Detection Utilities\n *\n * Detect browser and device feature support for ML workloads.\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// Core Feature Detection\n// ============================================================================\n\n/**\n * Check if WebGPU is supported.\n *\n * @returns Promise resolving to true if WebGPU is available\n */\nexport async function isWebGPUSupported(): Promise<boolean> {\n if (typeof navigator === 'undefined') return false;\n if (!('gpu' in navigator)) return false;\n\n try {\n const adapter = await (navigator as any).gpu?.requestAdapter();\n return !!adapter;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if WebNN is supported.\n *\n * @returns true if WebNN is available\n */\nexport function isWebNNSupported(): boolean {\n if (typeof navigator === 'undefined') return false;\n return 'ml' in navigator;\n}\n\n/**\n * Check if WebAssembly is supported.\n *\n * @returns true if WASM is available\n */\nexport function isWASMSupported(): boolean {\n try {\n if (typeof WebAssembly === 'object') {\n // Test instantiation\n if (typeof WebAssembly.instantiate === 'function') {\n const module = new WebAssembly.Module(\n Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00)\n );\n if (module instanceof WebAssembly.Module) {\n const instance = new WebAssembly.Instance(module);\n return instance instanceof WebAssembly.Instance;\n }\n }\n }\n } catch {\n // WASM not supported\n }\n return false;\n}\n\n/**\n * Check if WASM SIMD is supported.\n *\n * @returns true if WASM SIMD is available\n */\nexport function isWASMSIMDSupported(): boolean {\n try {\n // SIMD detection via feature detection\n // This is a minimal SIMD module\n const simdModule = new Uint8Array([\n 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x05, 0x01, 0x60,\n 0x00, 0x01, 0x7b, 0x03, 0x02, 0x01, 0x00, 0x0a, 0x0a, 0x01, 0x08, 0x00,\n 0x41, 0x00, 0xfd, 0x0f, 0x00, 0x00, 0x0b,\n ]);\n new WebAssembly.Module(simdModule);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if WASM threads are supported.\n *\n * @returns true if WASM threads are available\n */\nexport function isWASMThreadsSupported(): boolean {\n try {\n // Threads require SharedArrayBuffer\n if (typeof SharedArrayBuffer === 'undefined') return false;\n\n // Test for atomics\n if (typeof Atomics === 'undefined') return false;\n\n // Test for WASM threads support\n const threadsModule = new Uint8Array([\n 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x60,\n 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x05, 0x04, 0x01, 0x03, 0x01, 0x01,\n 0x0a, 0x0b, 0x01, 0x09, 0x00, 0x41, 0x00, 0xfe, 0x10, 0x02, 0x00, 0x1a,\n 0x0b,\n ]);\n new WebAssembly.Module(threadsModule);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if IndexedDB is supported.\n *\n * @returns true if IndexedDB is available\n */\nexport function isIndexedDBSupported(): boolean {\n try {\n return typeof indexedDB !== 'undefined';\n } catch {\n return false;\n }\n}\n\n/**\n * Check if Web Workers are supported.\n *\n * @returns true if Web Workers are available\n */\nexport function isWebWorkersSupported(): boolean {\n return typeof Worker !== 'undefined';\n}\n\n/**\n * Check if SharedArrayBuffer is supported.\n *\n * @returns true if SharedArrayBuffer is available\n */\nexport function isSharedArrayBufferSupported(): boolean {\n return typeof SharedArrayBuffer !== 'undefined';\n}\n\n/**\n * Check if the page is cross-origin isolated.\n *\n * Required for SharedArrayBuffer in modern browsers.\n *\n * @returns true if cross-origin isolated\n */\nexport function isCrossOriginIsolated(): boolean {\n return typeof crossOriginIsolated !== 'undefined' && crossOriginIsolated;\n}\n\n/**\n * Check if Origin Private File System is supported.\n *\n * @returns true if OPFS is available\n */\nexport function isOPFSSupported(): boolean {\n return typeof navigator !== 'undefined' && 'storage' in navigator;\n}\n\n/**\n * Check if BroadcastChannel is supported.\n *\n * @returns true if BroadcastChannel is available\n */\nexport function isBroadcastChannelSupported(): boolean {\n return typeof BroadcastChannel !== 'undefined';\n}\n\n/**\n * Check if Web Locks API is supported.\n *\n * @returns true if Web Locks are available\n */\nexport function isWebLocksSupported(): boolean {\n return typeof navigator !== 'undefined' && 'locks' in navigator;\n}\n\n/**\n * Check if Service Workers are supported.\n *\n * @returns true if Service Workers are available\n */\nexport function isServiceWorkerSupported(): boolean {\n return typeof navigator !== 'undefined' && 'serviceWorker' in navigator;\n}\n\n/**\n * Check if Web Crypto API is supported.\n *\n * @returns true if Web Crypto is available\n */\nexport function isWebCryptoSupported(): boolean {\n return typeof crypto !== 'undefined' && 'subtle' in crypto;\n}\n\n// ============================================================================\n// Feature Object (Quick Access)\n// ============================================================================\n\n/**\n * Quick access to all feature detection results.\n *\n * Note: WebGPU detection is async and not included here.\n * Use isWebGPUSupported() for async detection.\n */\nexport const features = {\n get wasm() {\n return isWASMSupported();\n },\n get simd() {\n return isWASMSIMDSupported();\n },\n get threads() {\n return isWASMThreadsSupported();\n },\n get indexeddb() {\n return isIndexedDBSupported();\n },\n get webworkers() {\n return isWebWorkersSupported();\n },\n get sharedarraybuffer() {\n return isSharedArrayBufferSupported();\n },\n get crossOriginisolated() {\n return isCrossOriginIsolated();\n },\n get opfs() {\n return isOPFSSupported();\n },\n get broadcastchannel() {\n return isBroadcastChannelSupported();\n },\n get weblocks() {\n return isWebLocksSupported();\n },\n get serviceworker() {\n return isServiceWorkerSupported();\n },\n get webcrypto() {\n return isWebCryptoSupported();\n },\n get webnn() {\n return isWebNNSupported();\n },\n} as const;\n\n/**\n * Runtime environment detection.\n */\nexport const runtime = {\n get isBrowser() {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n },\n get isNode() {\n return typeof process !== 'undefined' && process.versions?.node !== undefined;\n },\n get isElectron() {\n return typeof process !== 'undefined' && process.versions?.electron !== undefined;\n },\n get isWebWorker() {\n return typeof self !== 'undefined' && typeof (self as any).WorkerGlobalScope !== 'undefined';\n },\n get isServiceWorker() {\n return typeof ServiceWorkerGlobalScope !== 'undefined';\n },\n get isDeno() {\n return typeof (globalThis as any).Deno !== 'undefined';\n },\n get isBun() {\n return typeof (globalThis as any).Bun !== 'undefined';\n },\n} as const;\n\n","/**\n * Device Detection Utilities\n *\n * Detect device, browser, and hardware information.\n *\n * @packageDocumentation\n */\n\nimport type { DeviceInfo, MemoryInfo } from './types.js';\n\n// ============================================================================\n// Device Information\n// ============================================================================\n\n/**\n * Get device information.\n *\n * @returns Device information object\n */\nexport function getDeviceInfo(): DeviceInfo {\n if (typeof navigator === 'undefined') {\n return {\n userAgent: '',\n platform: 'node',\n hardwareConcurrency: 1,\n maxTouchPoints: 0,\n };\n }\n\n return {\n userAgent: navigator.userAgent,\n platform: navigator.platform,\n hardwareConcurrency: navigator.hardwareConcurrency || 1,\n deviceMemory: (navigator as any).deviceMemory,\n maxTouchPoints: navigator.maxTouchPoints || 0,\n };\n}\n\n/**\n * Get memory information (Chrome only).\n *\n * @returns Memory information if available\n */\nexport function getMemoryInfo(): MemoryInfo {\n const info: MemoryInfo = {};\n\n if (typeof navigator !== 'undefined') {\n info.deviceMemory = (navigator as any).deviceMemory;\n }\n\n if (typeof performance !== 'undefined' && (performance as any).memory) {\n const memory = (performance as any).memory;\n info.totalJSHeapSize = memory.totalJSHeapSize;\n info.usedJSHeapSize = memory.usedJSHeapSize;\n info.jsHeapSizeLimit = memory.jsHeapSizeLimit;\n }\n\n return info;\n}\n\n/**\n * Get hardware concurrency (number of logical CPU cores).\n *\n * @returns Number of logical CPU cores\n */\nexport function getHardwareConcurrency(): number {\n if (typeof navigator !== 'undefined' && navigator.hardwareConcurrency) {\n return navigator.hardwareConcurrency;\n }\n return 1;\n}\n\n/**\n * Get storage estimate from the browser.\n *\n * @returns Storage estimate with quota and usage\n */\nexport async function getStorageEstimate(): Promise<{\n quota: number;\n usage: number;\n persisted: boolean;\n} | null> {\n if (typeof navigator === 'undefined' || !navigator.storage) {\n return null;\n }\n\n try {\n const [estimate, persisted] = await Promise.all([\n navigator.storage.estimate(),\n navigator.storage.persisted(),\n ]);\n\n return {\n quota: estimate.quota ?? 0,\n usage: estimate.usage ?? 0,\n persisted,\n };\n } catch {\n return null;\n }\n}\n\n// ============================================================================\n// Browser Detection\n// ============================================================================\n\n/**\n * Detect browser name and version from user agent.\n *\n * @returns Browser information\n */\nexport function detectBrowser(): { name: string; version: string; engine: string } {\n if (typeof navigator === 'undefined') {\n return { name: 'unknown', version: '0', engine: 'unknown' };\n }\n\n const ua = navigator.userAgent;\n\n // Chrome\n if (ua.includes('Chrome/') && !ua.includes('Edg/')) {\n const match = ua.match(/Chrome\\/(\\d+(?:\\.\\d+)*)/);\n return {\n name: 'Chrome',\n version: match?.[1] ?? 'unknown',\n engine: 'Blink',\n };\n }\n\n // Edge\n if (ua.includes('Edg/')) {\n const match = ua.match(/Edg\\/(\\d+(?:\\.\\d+)*)/);\n return {\n name: 'Edge',\n version: match?.[1] ?? 'unknown',\n engine: 'Blink',\n };\n }\n\n // Firefox\n if (ua.includes('Firefox/')) {\n const match = ua.match(/Firefox\\/(\\d+(?:\\.\\d+)*)/);\n return {\n name: 'Firefox',\n version: match?.[1] ?? 'unknown',\n engine: 'Gecko',\n };\n }\n\n // Safari\n if (ua.includes('Safari/') && !ua.includes('Chrome')) {\n const match = ua.match(/Version\\/(\\d+(?:\\.\\d+)*)/);\n return {\n name: 'Safari',\n version: match?.[1] ?? 'unknown',\n engine: 'WebKit',\n };\n }\n\n return { name: 'unknown', version: '0', engine: 'unknown' };\n}\n\n/**\n * Detect operating system and version.\n *\n * @returns OS information\n */\nexport function detectOS(): { name: string; version: string } {\n if (typeof navigator === 'undefined') {\n if (typeof process !== 'undefined') {\n return { name: process.platform, version: process.version };\n }\n return { name: 'unknown', version: '0' };\n }\n\n const ua = navigator.userAgent;\n\n // Windows\n if (ua.includes('Windows')) {\n const match = ua.match(/Windows NT (\\d+(?:\\.\\d+)*)/);\n const ntVersion = match?.[1] ?? '10';\n const version = ntVersion === '10.0' ? '10/11' : ntVersion;\n return { name: 'Windows', version };\n }\n\n // macOS\n if (ua.includes('Mac OS X')) {\n const match = ua.match(/Mac OS X (\\d+[._]\\d+(?:[._]\\d+)?)/);\n const version = match?.[1]?.replace(/_/g, '.') ?? 'unknown';\n return { name: 'macOS', version };\n }\n\n // iOS\n if (ua.includes('iPhone') || ua.includes('iPad')) {\n const match = ua.match(/OS (\\d+[._]\\d+(?:[._]\\d+)?)/);\n const version = match?.[1]?.replace(/_/g, '.') ?? 'unknown';\n return { name: 'iOS', version };\n }\n\n // Android\n if (ua.includes('Android')) {\n const match = ua.match(/Android (\\d+(?:\\.\\d+)*)/);\n return { name: 'Android', version: match?.[1] ?? 'unknown' };\n }\n\n // Linux\n if (ua.includes('Linux')) {\n return { name: 'Linux', version: 'unknown' };\n }\n\n return { name: 'unknown', version: '0' };\n}\n\n/**\n * Detect device type (desktop, mobile, tablet).\n *\n * @returns Device type\n */\nexport function detectDeviceType(): 'desktop' | 'mobile' | 'tablet' | 'unknown' {\n if (typeof navigator === 'undefined') {\n return 'unknown';\n }\n\n const ua = navigator.userAgent;\n\n // Check for tablet first (iPads, Android tablets)\n if (ua.includes('iPad') || (ua.includes('Android') && !ua.includes('Mobile'))) {\n return 'tablet';\n }\n\n // Check for mobile devices\n if (\n ua.includes('iPhone') ||\n ua.includes('iPod') ||\n (ua.includes('Android') && ua.includes('Mobile')) ||\n ua.includes('webOS') ||\n ua.includes('BlackBerry') ||\n ua.includes('IEMobile') ||\n ua.includes('Opera Mini')\n ) {\n return 'mobile';\n }\n\n // Check for touch capability on tablets that might not identify as such\n if (navigator.maxTouchPoints > 0) {\n // Could be a touch laptop or tablet\n // Use screen size as additional heuristic\n if (typeof screen !== 'undefined' && screen.width < 1024) {\n return 'tablet';\n }\n }\n\n return 'desktop';\n}\n\n// ============================================================================\n// GPU Detection\n// ============================================================================\n\n/**\n * Detect GPU information via WebGL.\n *\n * @returns GPU vendor and renderer if available\n */\nexport function detectGPU(): { vendor: string; renderer: string } | null {\n if (typeof document === 'undefined') return null;\n\n try {\n const canvas = document.createElement('canvas');\n const gl =\n canvas.getContext('webgl2') ||\n canvas.getContext('webgl') ||\n canvas.getContext('experimental-webgl');\n\n if (!gl) return null;\n\n const debugInfo = (gl as WebGLRenderingContext).getExtension('WEBGL_debug_renderer_info');\n if (!debugInfo) return null;\n\n return {\n vendor: (gl as WebGLRenderingContext).getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) ?? 'unknown',\n renderer: (gl as WebGLRenderingContext).getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) ?? 'unknown',\n };\n } catch {\n return null;\n }\n}\n\n","/**\n * Capability Detection\n *\n * Comprehensive device and browser capability detection for ML workloads.\n *\n * @packageDocumentation\n */\n\nimport type {\n DeviceCapabilities,\n FeatureSupportResult,\n ModelSupportResult,\n ModelRequirements,\n FallbackRecommendation,\n BrowserRecommendation,\n} from './types.js';\nimport {\n isWebGPUSupported,\n isWebNNSupported,\n isWASMSupported,\n isWASMSIMDSupported,\n isWASMThreadsSupported,\n isIndexedDBSupported,\n isOPFSSupported,\n isWebWorkersSupported,\n isSharedArrayBufferSupported,\n isCrossOriginIsolated,\n isServiceWorkerSupported,\n isBroadcastChannelSupported,\n isWebLocksSupported,\n} from './features.js';\nimport {\n detectBrowser,\n detectOS,\n detectDeviceType,\n getHardwareConcurrency,\n getStorageEstimate,\n detectGPU,\n} from './device.js';\n\n// ============================================================================\n// Comprehensive Capability Detection\n// ============================================================================\n\n/**\n * Detect all device and browser capabilities.\n *\n * @returns Comprehensive capability information\n *\n * @example\n * ```typescript\n * import { detectCapabilities } from '@localmode/core';\n *\n * const caps = await detectCapabilities();\n *\n * console.log('Browser:', caps.browser.name, caps.browser.version);\n * console.log('Device:', caps.device.type, caps.device.os);\n * console.log('WebGPU:', caps.features.webgpu);\n * console.log('Storage available:', caps.storage.availableBytes);\n * ```\n */\nexport async function detectCapabilities(): Promise<DeviceCapabilities> {\n const browser = detectBrowser();\n const os = detectOS();\n const deviceType = detectDeviceType();\n const gpu = detectGPU();\n const storage = await getStorageEstimate();\n const webgpu = await isWebGPUSupported();\n\n return {\n browser,\n device: {\n type: deviceType,\n os: os.name,\n osVersion: os.version,\n },\n hardware: {\n cores: getHardwareConcurrency(),\n memory: typeof navigator !== 'undefined' ? (navigator as any).deviceMemory : undefined,\n gpu: gpu?.renderer,\n },\n features: {\n webgpu,\n webnn: isWebNNSupported(),\n wasm: isWASMSupported(),\n simd: isWASMSIMDSupported(),\n threads: isWASMThreadsSupported(),\n indexeddb: isIndexedDBSupported(),\n opfs: isOPFSSupported(),\n webworkers: isWebWorkersSupported(),\n sharedarraybuffer: isSharedArrayBufferSupported(),\n crossOriginisolated: isCrossOriginIsolated(),\n serviceworker: isServiceWorkerSupported(),\n broadcastchannel: isBroadcastChannelSupported(),\n weblocks: isWebLocksSupported(),\n },\n storage: {\n quotaBytes: storage?.quota ?? 0,\n usedBytes: storage?.usage ?? 0,\n availableBytes: (storage?.quota ?? 0) - (storage?.usage ?? 0),\n isPersisted: storage?.persisted ?? false,\n },\n };\n}\n\n// ============================================================================\n// Feature Support Checking\n// ============================================================================\n\n/**\n * Check if a specific feature is supported with recommendations.\n *\n * @param feature - Feature name to check\n * @returns Feature support result with fallbacks\n *\n * @example\n * ```typescript\n * import { checkFeatureSupport } from '@localmode/core';\n *\n * const result = await checkFeatureSupport('webgpu');\n * if (!result.supported) {\n * console.log('WebGPU not supported:', result.reason);\n * console.log('Fallbacks:', result.fallbacks);\n * }\n * ```\n */\nexport async function checkFeatureSupport(\n feature:\n | 'webgpu'\n | 'webnn'\n | 'wasm'\n | 'simd'\n | 'threads'\n | 'indexeddb'\n | 'sharedarraybuffer'\n | 'opfs'\n | 'serviceworker'\n): Promise<FeatureSupportResult> {\n const featureChecks: Record<string, () => Promise<boolean> | boolean> = {\n webgpu: isWebGPUSupported,\n webnn: isWebNNSupported,\n wasm: isWASMSupported,\n simd: isWASMSIMDSupported,\n threads: isWASMThreadsSupported,\n indexeddb: isIndexedDBSupported,\n sharedarraybuffer: isSharedArrayBufferSupported,\n opfs: isOPFSSupported,\n serviceworker: isServiceWorkerSupported,\n };\n\n const check = featureChecks[feature];\n if (!check) {\n return { supported: false, reason: `Unknown feature: ${feature}` };\n }\n\n const supported = await check();\n\n if (supported) {\n return { supported: true };\n }\n\n // Provide specific recommendations based on feature\n return getFeatureRecommendations(feature);\n}\n\n/**\n * Get recommendations for unsupported features.\n */\nfunction getFeatureRecommendations(feature: string): FeatureSupportResult {\n const recommendations: Record<string, FeatureSupportResult> = {\n webgpu: {\n supported: false,\n reason: 'WebGPU is not available in this browser',\n fallbacks: [\n {\n feature: 'webgpu',\n alternative: 'wasm',\n reason: 'WebAssembly is widely supported',\n tradeoffs: ['2-5x slower inference', 'Higher CPU usage'],\n },\n ],\n browserRecommendations: [\n { browser: 'Chrome', minVersion: '113', features: ['WebGPU'] },\n { browser: 'Edge', minVersion: '113', features: ['WebGPU'] },\n {\n browser: 'Firefox',\n minVersion: '118',\n features: ['WebGPU'],\n note: 'Behind flag in about:config',\n },\n { browser: 'Safari', minVersion: '18', features: ['WebGPU'], note: 'macOS 15+ / iOS 18+' },\n ],\n },\n webnn: {\n supported: false,\n reason: 'WebNN is not available in this browser',\n fallbacks: [\n {\n feature: 'webnn',\n alternative: 'webgpu',\n reason: 'WebGPU provides GPU acceleration',\n tradeoffs: ['May have higher overhead'],\n },\n {\n feature: 'webnn',\n alternative: 'wasm',\n reason: 'WebAssembly is widely supported',\n tradeoffs: ['No hardware acceleration'],\n },\n ],\n browserRecommendations: [\n {\n browser: 'Chrome',\n minVersion: '119',\n features: ['WebNN'],\n note: 'Behind flag, limited support',\n },\n ],\n },\n sharedarraybuffer: {\n supported: false,\n reason: isCrossOriginIsolated()\n ? 'SharedArrayBuffer not available'\n : 'Cross-origin isolation headers not set',\n fallbacks: [\n {\n feature: 'sharedarraybuffer',\n alternative: 'single-threaded',\n reason: 'Run without multi-threading',\n tradeoffs: ['Slower processing', 'May block UI during heavy operations'],\n },\n ],\n browserRecommendations: [\n {\n browser: 'All',\n minVersion: 'N/A',\n features: ['SharedArrayBuffer'],\n note:\n 'Requires headers: Cross-Origin-Opener-Policy: same-origin, Cross-Origin-Embedder-Policy: require-corp',\n },\n ],\n },\n indexeddb: {\n supported: false,\n reason: 'IndexedDB is not available (possibly private browsing mode)',\n fallbacks: [\n {\n feature: 'indexeddb',\n alternative: 'memory',\n reason: 'In-memory storage for session',\n tradeoffs: ['Data not persisted', 'Lost on page refresh'],\n },\n ],\n },\n wasm: {\n supported: false,\n reason: 'WebAssembly is not supported in this browser',\n browserRecommendations: [\n { browser: 'Chrome', minVersion: '57', features: ['WebAssembly'] },\n { browser: 'Firefox', minVersion: '52', features: ['WebAssembly'] },\n { browser: 'Safari', minVersion: '11', features: ['WebAssembly'] },\n { browser: 'Edge', minVersion: '16', features: ['WebAssembly'] },\n ],\n },\n simd: {\n supported: false,\n reason: 'WebAssembly SIMD is not supported',\n fallbacks: [\n {\n feature: 'simd',\n alternative: 'scalar',\n reason: 'Fall back to scalar operations',\n tradeoffs: ['2-4x slower for vector operations'],\n },\n ],\n browserRecommendations: [\n { browser: 'Chrome', minVersion: '91', features: ['WASM SIMD'] },\n { browser: 'Firefox', minVersion: '89', features: ['WASM SIMD'] },\n { browser: 'Safari', minVersion: '16.4', features: ['WASM SIMD'] },\n ],\n },\n threads: {\n supported: false,\n reason: 'WebAssembly threads are not supported',\n fallbacks: [\n {\n feature: 'threads',\n alternative: 'single-threaded',\n reason: 'Run without multi-threading',\n tradeoffs: ['Cannot utilize multiple CPU cores'],\n },\n ],\n },\n opfs: {\n supported: false,\n reason: 'Origin Private File System is not available',\n fallbacks: [\n {\n feature: 'opfs',\n alternative: 'indexeddb',\n reason: 'Use IndexedDB for storage',\n tradeoffs: ['Slower for large files', 'Less efficient binary storage'],\n },\n ],\n },\n serviceworker: {\n supported: false,\n reason: 'Service Workers are not available',\n fallbacks: [\n {\n feature: 'serviceworker',\n alternative: 'none',\n reason: 'Operate without offline caching',\n tradeoffs: ['No offline support', 'Models must be re-downloaded'],\n },\n ],\n },\n };\n\n return recommendations[feature] ?? { supported: false, reason: `Feature not supported: ${feature}` };\n}\n\n// ============================================================================\n// Model Support Checking\n// ============================================================================\n\n/**\n * Check if a model can run on this device.\n *\n * @param requirements - Model requirements\n * @returns Model support result with recommendations\n *\n * @example\n * ```typescript\n * import { checkModelSupport } from '@localmode/core';\n *\n * const result = await checkModelSupport({\n * modelId: 'Xenova/whisper-large-v3',\n * estimatedMemory: 3_000_000_000, // 3GB\n * estimatedStorage: 1_500_000_000, // 1.5GB\n * });\n *\n * if (!result.supported) {\n * console.log('Model not supported:', result.reason);\n * console.log('Try these instead:', result.fallbackModels);\n * }\n * ```\n */\nexport async function checkModelSupport(\n requirements: ModelRequirements\n): Promise<ModelSupportResult> {\n const caps = await detectCapabilities();\n\n // Check storage\n const storageAvailable = caps.storage.availableBytes;\n if (requirements.estimatedStorage > storageAvailable) {\n return {\n supported: false,\n reason: `Insufficient storage. Required: ${formatBytes(requirements.estimatedStorage)}, Available: ${formatBytes(storageAvailable)}`,\n memoryRequired: requirements.estimatedMemory,\n storageRequired: requirements.estimatedStorage,\n storageAvailable,\n recommendedDevice: 'wasm',\n fallbackModels: getModelFallbacks(requirements.modelId),\n };\n }\n\n // Check memory (if available)\n const memoryAvailable = caps.hardware.memory\n ? caps.hardware.memory * 1024 * 1024 * 1024\n : undefined;\n\n if (memoryAvailable && requirements.estimatedMemory > memoryAvailable * 0.7) {\n return {\n supported: false,\n reason: `Insufficient memory. Required: ${formatBytes(requirements.estimatedMemory)}, Available: ~${formatBytes(memoryAvailable)}`,\n memoryRequired: requirements.estimatedMemory,\n memoryAvailable,\n storageRequired: requirements.estimatedStorage,\n storageAvailable,\n recommendedDevice: 'wasm',\n fallbackModels: getModelFallbacks(requirements.modelId),\n };\n }\n\n // Check CPU cores for large models\n if (requirements.minCores && caps.hardware.cores < requirements.minCores) {\n return {\n supported: false,\n reason: `Insufficient CPU cores. Required: ${requirements.minCores}, Available: ${caps.hardware.cores}`,\n memoryRequired: requirements.estimatedMemory,\n memoryAvailable,\n storageRequired: requirements.estimatedStorage,\n storageAvailable,\n recommendedDevice: 'wasm',\n fallbackModels: getModelFallbacks(requirements.modelId),\n };\n }\n\n // Determine recommended device\n let recommendedDevice: 'webgpu' | 'wasm' | 'cpu' = 'wasm';\n\n if (requirements.prefersWebGPU !== false && caps.features.webgpu) {\n recommendedDevice = 'webgpu';\n } else if (caps.features.wasm) {\n recommendedDevice = 'wasm';\n } else {\n recommendedDevice = 'cpu';\n }\n\n return {\n supported: true,\n memoryRequired: requirements.estimatedMemory,\n memoryAvailable,\n storageRequired: requirements.estimatedStorage,\n storageAvailable,\n recommendedDevice,\n };\n}\n\n// ============================================================================\n// Fallback Recommendations\n// ============================================================================\n\n/**\n * Built-in model fallback registry.\n */\nconst MODEL_FALLBACKS: Record<string, Array<{ modelId: string; memoryRequired: number; reason: string }>> = {\n // Whisper models\n 'Xenova/whisper-large-v3': [\n { modelId: 'Xenova/whisper-medium', memoryRequired: 1500, reason: 'Better accuracy than small' },\n { modelId: 'Xenova/whisper-small', memoryRequired: 500, reason: 'Good balance of speed and accuracy' },\n { modelId: 'Xenova/whisper-tiny', memoryRequired: 150, reason: 'Fastest, suitable for real-time' },\n ],\n 'Xenova/whisper-medium': [\n { modelId: 'Xenova/whisper-small', memoryRequired: 500, reason: 'Smaller with good accuracy' },\n { modelId: 'Xenova/whisper-tiny', memoryRequired: 150, reason: 'Fastest option' },\n ],\n // Embedding models\n 'Xenova/all-mpnet-base-v2': [\n { modelId: 'Xenova/all-MiniLM-L6-v2', memoryRequired: 90, reason: 'Smaller with good quality' },\n { modelId: 'Xenova/paraphrase-MiniLM-L3-v2', memoryRequired: 60, reason: 'Fastest embedding model' },\n ],\n // LLMs\n 'Llama-3.2-3B-Instruct-q4f16': [\n { modelId: 'Llama-3.2-1B-Instruct-q4f16', memoryRequired: 800, reason: 'Smaller but capable' },\n { modelId: 'SmolLM2-360M-Instruct-q4f16', memoryRequired: 300, reason: 'Very small, basic tasks' },\n ],\n};\n\n/**\n * Get fallback models for a given model.\n */\nfunction getModelFallbacks(\n modelId: string\n): Array<{ modelId: string; memoryRequired: number; reason: string }> {\n return MODEL_FALLBACKS[modelId] ?? [];\n}\n\n/**\n * Get recommended fallbacks for unsupported features.\n *\n * @param features - List of unsupported features\n * @returns List of fallback recommendations\n */\nexport function getRecommendedFallbacks(features: string[]): FallbackRecommendation[] {\n const fallbacks: FallbackRecommendation[] = [];\n\n for (const feature of features) {\n const result = getFeatureRecommendations(feature);\n if (result.fallbacks) {\n fallbacks.push(...result.fallbacks);\n }\n }\n\n return fallbacks;\n}\n\n/**\n * Get browser recommendations for optimal feature support.\n *\n * @param options - Options for recommendations\n * @returns List of browser recommendations\n */\nexport async function getBrowserRecommendations(options: {\n features: string[];\n}): Promise<BrowserRecommendation[]> {\n const allRecommendations: BrowserRecommendation[] = [];\n\n for (const feature of options.features) {\n const result = await checkFeatureSupport(feature as any);\n if (result.browserRecommendations) {\n allRecommendations.push(...result.browserRecommendations);\n }\n }\n\n // Deduplicate by browser\n const byBrowser = new Map<string, BrowserRecommendation>();\n\n for (const rec of allRecommendations) {\n const existing = byBrowser.get(rec.browser);\n if (existing) {\n // Merge features\n const features = new Set([...existing.features, ...rec.features]);\n existing.features = Array.from(features);\n // Keep higher version\n if (rec.minVersion > existing.minVersion) {\n existing.minVersion = rec.minVersion;\n }\n // Append notes\n if (rec.note && !existing.note?.includes(rec.note)) {\n existing.note = existing.note ? `${existing.note}; ${rec.note}` : rec.note;\n }\n } else {\n byBrowser.set(rec.browser, { ...rec });\n }\n }\n\n return Array.from(byBrowser.values());\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Format bytes as human-readable string.\n */\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n\n","/**\n * Capability Reporting\n *\n * Generate comprehensive capability reports for debugging and diagnostics.\n *\n * @packageDocumentation\n */\n\nimport type { CapabilityReport, DeviceCapabilities } from './types.js';\nimport { detectCapabilities } from './detect.js';\n\n// ============================================================================\n// Report Generation\n// ============================================================================\n\n/**\n * Create a comprehensive capability report.\n *\n * Useful for debugging issues and providing support information.\n *\n * @returns Detailed capability report\n *\n * @example\n * ```typescript\n * import { createCapabilityReport, formatCapabilityReport } from '@localmode/core';\n *\n * const report = await createCapabilityReport();\n * console.log(formatCapabilityReport(report));\n * ```\n */\nexport async function createCapabilityReport(): Promise<CapabilityReport> {\n const capabilities = await detectCapabilities();\n\n // Calculate scores\n const scores = calculateScores(capabilities);\n\n // Generate recommendations\n const recommendations = generateRecommendations(capabilities);\n\n // Detect issues\n const issues = detectIssues(capabilities);\n\n return {\n timestamp: new Date(),\n capabilities,\n scores,\n recommendations,\n issues,\n };\n}\n\n/**\n * Calculate capability scores.\n */\nfunction calculateScores(caps: DeviceCapabilities): CapabilityReport['scores'] {\n // ML Readiness Score (0-100)\n let mlReadiness = 0;\n if (caps.features.wasm) mlReadiness += 20;\n if (caps.features.simd) mlReadiness += 15;\n if (caps.features.threads) mlReadiness += 10;\n if (caps.features.webgpu) mlReadiness += 30;\n if (caps.features.webnn) mlReadiness += 10;\n if (caps.hardware.cores >= 4) mlReadiness += 10;\n if (caps.hardware.memory && caps.hardware.memory >= 4) mlReadiness += 5;\n\n // Storage Capacity Score (0-100)\n let storageCapacity = 0;\n const quotaGB = caps.storage.quotaBytes / (1024 * 1024 * 1024);\n const usedPercent = (caps.storage.usedBytes / caps.storage.quotaBytes) * 100;\n\n if (quotaGB >= 10) storageCapacity += 40;\n else if (quotaGB >= 5) storageCapacity += 30;\n else if (quotaGB >= 1) storageCapacity += 20;\n else storageCapacity += 10;\n\n if (usedPercent < 50) storageCapacity += 30;\n else if (usedPercent < 80) storageCapacity += 20;\n else storageCapacity += 10;\n\n if (caps.storage.isPersisted) storageCapacity += 20;\n if (caps.features.opfs) storageCapacity += 10;\n\n // Performance Potential Score (0-100)\n let performancePotential = 0;\n if (caps.features.webgpu) performancePotential += 40;\n else if (caps.features.wasm) performancePotential += 20;\n\n if (caps.features.simd) performancePotential += 20;\n if (caps.features.threads && caps.hardware.cores >= 4) performancePotential += 20;\n if (caps.hardware.cores >= 8) performancePotential += 10;\n else if (caps.hardware.cores >= 4) performancePotential += 5;\n\n if (caps.hardware.gpu?.toLowerCase().includes('nvidia')) performancePotential += 10;\n else if (caps.hardware.gpu?.toLowerCase().includes('amd')) performancePotential += 8;\n else if (caps.hardware.gpu?.toLowerCase().includes('apple')) performancePotential += 8;\n\n return {\n mlReadiness: Math.min(100, mlReadiness),\n storageCapacity: Math.min(100, storageCapacity),\n performancePotential: Math.min(100, performancePotential),\n };\n}\n\n/**\n * Generate recommendations based on capabilities.\n */\nfunction generateRecommendations(caps: DeviceCapabilities): string[] {\n const recommendations: string[] = [];\n\n // Browser recommendations\n if (!caps.features.webgpu && caps.browser.name === 'Firefox') {\n recommendations.push(\n 'Enable WebGPU in Firefox: about:config → dom.webgpu.enabled = true'\n );\n }\n\n if (!caps.features.webgpu && caps.browser.name !== 'Chrome' && caps.browser.name !== 'Edge') {\n recommendations.push(\n 'For best performance, use Chrome 113+ or Edge 113+ for WebGPU support'\n );\n }\n\n // CORS isolation\n if (!caps.features.crossOriginisolated && caps.features.sharedarraybuffer === false) {\n recommendations.push(\n 'Enable cross-origin isolation for multi-threading: Add COOP and COEP headers'\n );\n }\n\n // Storage\n if (!caps.storage.isPersisted) {\n recommendations.push(\n 'Request persistent storage to prevent data loss: navigator.storage.persist()'\n );\n }\n\n if (caps.storage.usedBytes / caps.storage.quotaBytes > 0.8) {\n recommendations.push(\n 'Storage is over 80% full. Consider cleaning up old data.'\n );\n }\n\n // Memory\n if (caps.hardware.memory && caps.hardware.memory < 4) {\n recommendations.push(\n 'Low device memory detected. Use smaller models (e.g., whisper-tiny instead of whisper-large)'\n );\n }\n\n // Performance\n if (!caps.features.simd) {\n recommendations.push(\n 'WASM SIMD not available. Vector operations will be slower.'\n );\n }\n\n return recommendations;\n}\n\n/**\n * Detect issues in capabilities.\n */\nfunction detectIssues(\n caps: DeviceCapabilities\n): CapabilityReport['issues'] {\n const issues: CapabilityReport['issues'] = [];\n\n // Critical issues\n if (!caps.features.wasm) {\n issues.push({\n severity: 'error',\n message: 'WebAssembly is not supported',\n suggestion: 'Use a modern browser (Chrome 57+, Firefox 52+, Safari 11+)',\n });\n }\n\n if (!caps.features.indexeddb) {\n issues.push({\n severity: 'error',\n message: 'IndexedDB is not available',\n suggestion: 'Disable private browsing mode or use a different browser',\n });\n }\n\n // Warnings\n if (!caps.features.webworkers) {\n issues.push({\n severity: 'warning',\n message: 'Web Workers not available',\n suggestion: 'Heavy operations will block the UI',\n });\n }\n\n if (!caps.features.webgpu && !caps.features.webnn) {\n issues.push({\n severity: 'warning',\n message: 'No GPU acceleration available',\n suggestion: 'ML inference will use CPU only, which is slower',\n });\n }\n\n if (caps.hardware.cores < 2) {\n issues.push({\n severity: 'warning',\n message: 'Single-core device detected',\n suggestion: 'Performance may be limited for ML workloads',\n });\n }\n\n // Info\n if (caps.device.type === 'mobile') {\n issues.push({\n severity: 'info',\n message: 'Mobile device detected',\n suggestion: 'Use smaller models for better performance and battery life',\n });\n }\n\n if (!caps.features.opfs) {\n issues.push({\n severity: 'info',\n message: 'Origin Private File System not available',\n suggestion: 'Large file storage will use IndexedDB instead',\n });\n }\n\n return issues;\n}\n\n// ============================================================================\n// Report Formatting\n// ============================================================================\n\n/**\n * Format a capability report as a human-readable string.\n *\n * @param report - Capability report to format\n * @returns Formatted string\n */\nexport function formatCapabilityReport(report: CapabilityReport): string {\n const lines: string[] = [];\n const { capabilities: caps, scores, recommendations, issues } = report;\n\n lines.push('═══════════════════════════════════════════════════════════════');\n lines.push(' CAPABILITY REPORT ');\n lines.push('═══════════════════════════════════════════════════════════════');\n lines.push('');\n lines.push(`Generated: ${report.timestamp.toISOString()}`);\n lines.push('');\n\n // Browser & Device\n lines.push('┌─────────────────────────────────────────────────────────────┐');\n lines.push('│ BROWSER & DEVICE │');\n lines.push('└─────────────────────────────────────────────────────────────┘');\n lines.push(` Browser: ${caps.browser.name} ${caps.browser.version} (${caps.browser.engine})`);\n lines.push(` Device: ${caps.device.type} - ${caps.device.os} ${caps.device.osVersion}`);\n lines.push(` Cores: ${caps.hardware.cores}`);\n lines.push(` Memory: ${caps.hardware.memory ? `${caps.hardware.memory} GB` : 'unknown'}`);\n lines.push(` GPU: ${caps.hardware.gpu ?? 'unknown'}`);\n lines.push('');\n\n // Features\n lines.push('┌─────────────────────────────────────────────────────────────┐');\n lines.push('│ FEATURES │');\n lines.push('└─────────────────────────────────────────────────────────────┘');\n\n const featureList: Array<[string, boolean]> = [\n ['WebGPU', caps.features.webgpu],\n ['WebNN', caps.features.webnn],\n ['WebAssembly', caps.features.wasm],\n ['WASM SIMD', caps.features.simd],\n ['WASM Threads', caps.features.threads],\n ['IndexedDB', caps.features.indexeddb],\n ['OPFS', caps.features.opfs],\n ['Web Workers', caps.features.webworkers],\n ['SharedArrayBuffer', caps.features.sharedarraybuffer],\n ['Cross-Origin Isolated', caps.features.crossOriginisolated],\n ['Service Worker', caps.features.serviceworker],\n ['BroadcastChannel', caps.features.broadcastchannel],\n ['Web Locks', caps.features.weblocks],\n ];\n\n for (const [name, supported] of featureList) {\n const icon = supported ? '✓' : '✗';\n const status = supported ? 'supported' : 'not available';\n lines.push(` ${icon} ${name.padEnd(22)} ${status}`);\n }\n lines.push('');\n\n // Storage\n lines.push('┌─────────────────────────────────────────────────────────────┐');\n lines.push('│ STORAGE │');\n lines.push('└─────────────────────────────────────────────────────────────┘');\n lines.push(` Quota: ${formatBytes(caps.storage.quotaBytes)}`);\n lines.push(` Used: ${formatBytes(caps.storage.usedBytes)}`);\n lines.push(` Available: ${formatBytes(caps.storage.availableBytes)}`);\n lines.push(` Persisted: ${caps.storage.isPersisted ? 'yes' : 'no'}`);\n lines.push('');\n\n // Scores\n lines.push('┌─────────────────────────────────────────────────────────────┐');\n lines.push('│ SCORES │');\n lines.push('└─────────────────────────────────────────────────────────────┘');\n lines.push(` ML Readiness: ${formatScore(scores.mlReadiness)}`);\n lines.push(` Storage Capacity: ${formatScore(scores.storageCapacity)}`);\n lines.push(` Performance Potential: ${formatScore(scores.performancePotential)}`);\n lines.push('');\n\n // Issues\n if (issues.length > 0) {\n lines.push('┌─────────────────────────────────────────────────────────────┐');\n lines.push('│ ISSUES │');\n lines.push('└─────────────────────────────────────────────────────────────┘');\n for (const issue of issues) {\n const icon = issue.severity === 'error' ? '❌' : issue.severity === 'warning' ? '⚠️' : 'ℹ️';\n lines.push(` ${icon} [${issue.severity.toUpperCase()}] ${issue.message}`);\n if (issue.suggestion) {\n lines.push(` → ${issue.suggestion}`);\n }\n }\n lines.push('');\n }\n\n // Recommendations\n if (recommendations.length > 0) {\n lines.push('┌─────────────────────────────────────────────────────────────┐');\n lines.push('│ RECOMMENDATIONS │');\n lines.push('└─────────────────────────────────────────────────────────────┘');\n for (const rec of recommendations) {\n lines.push(` • ${rec}`);\n }\n lines.push('');\n }\n\n lines.push('═══════════════════════════════════════════════════════════════');\n\n return lines.join('\\n');\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n\nfunction formatScore(score: number): string {\n const bar = '█'.repeat(Math.floor(score / 10)) + '░'.repeat(10 - Math.floor(score / 10));\n return `${bar} ${score}%`;\n}\n\n","/**\n * Network Logger\n *\n * Comprehensive logging for network requests including model downloads.\n *\n * @packageDocumentation\n */\n\nimport type {\n NetworkLogEntry,\n NetworkStats,\n NetworkLoggerConfig,\n NetworkLogFilter,\n NetworkRequestCallback,\n} from './types.js';\n\n// ============================================================================\n// Network Logger Class\n// ============================================================================\n\n/**\n * Network request logger.\n *\n * Tracks all network requests with progress, timing, and error information.\n *\n * @example\n * ```typescript\n * import { createNetworkLogger, onNetworkRequest } from '@localmode/core';\n *\n * const logger = createNetworkLogger({ maxEntries: 500 });\n *\n * // Subscribe to network requests\n * const unsubscribe = onNetworkRequest((entry) => {\n * if (entry.state === 'in-progress') {\n * console.log(`Downloading: ${entry.url} (${entry.progress}%)`);\n * }\n * });\n *\n * // Get logs\n * const logs = await getNetworkLogs({ category: 'model' });\n * ```\n */\nexport class NetworkLogger {\n private logs: NetworkLogEntry[] = [];\n private listeners: Set<NetworkRequestCallback> = new Set();\n private config: Required<NetworkLoggerConfig>;\n\n constructor(config: NetworkLoggerConfig = {}) {\n this.config = {\n maxEntries: config.maxEntries ?? 1000,\n persistLogs: config.persistLogs ?? false,\n logHeaders: config.logHeaders ?? false,\n logBody: config.logBody ?? false,\n categories: config.categories ?? [],\n minLevel: config.minLevel ?? 'info',\n filter: config.filter ?? (() => true),\n };\n }\n\n /**\n * Log a network request.\n */\n log(entry: Omit<NetworkLogEntry, 'id' | 'timestamp'>): NetworkLogEntry {\n const fullEntry: NetworkLogEntry = {\n id: generateId(),\n timestamp: new Date(),\n ...entry,\n };\n\n // Apply filter\n if (!this.config.filter(fullEntry)) {\n return fullEntry;\n }\n\n // Check category filter\n if (\n this.config.categories.length > 0 &&\n !this.config.categories.includes(entry.category)\n ) {\n return fullEntry;\n }\n\n // Add to logs\n this.logs.push(fullEntry);\n\n // Trim if over limit\n if (this.logs.length > this.config.maxEntries) {\n this.logs = this.logs.slice(-this.config.maxEntries);\n }\n\n // Notify listeners\n this.notifyListeners(fullEntry);\n\n return fullEntry;\n }\n\n /**\n * Update an existing log entry.\n */\n update(id: string, updates: Partial<NetworkLogEntry>): NetworkLogEntry | null {\n const index = this.logs.findIndex((log) => log.id === id);\n if (index === -1) return null;\n\n const updated = { ...this.logs[index], ...updates };\n this.logs[index] = updated;\n\n // Notify listeners\n this.notifyListeners(updated);\n\n return updated;\n }\n\n /**\n * Get logs matching the filter.\n */\n getLogs(filter: NetworkLogFilter = {}): NetworkLogEntry[] {\n let result = [...this.logs];\n\n // Apply filters\n if (filter.category) {\n result = result.filter((log) => log.category === filter.category);\n }\n\n if (filter.state) {\n result = result.filter((log) => log.state === filter.state);\n }\n\n if (filter.urlPattern) {\n const pattern =\n typeof filter.urlPattern === 'string'\n ? new RegExp(filter.urlPattern)\n : filter.urlPattern;\n result = result.filter((log) => pattern.test(log.url));\n }\n\n if (filter.since) {\n result = result.filter((log) => log.timestamp >= filter.since!);\n }\n\n if (filter.until) {\n result = result.filter((log) => log.timestamp <= filter.until!);\n }\n\n // Sort\n result.sort((a, b) => {\n const order = filter.order === 'asc' ? 1 : -1;\n return order * (a.timestamp.getTime() - b.timestamp.getTime());\n });\n\n // Limit\n if (filter.limit) {\n result = result.slice(0, filter.limit);\n }\n\n return result;\n }\n\n /**\n * Get network statistics.\n */\n getStats(): NetworkStats {\n const completed = this.logs.filter((log) => log.state === 'completed');\n const failed = this.logs.filter((log) => log.state === 'failed');\n\n const totalDownloadBytes = completed.reduce(\n (sum, log) => sum + (log.responseSize ?? 0),\n 0\n );\n const totalUploadBytes = completed.reduce(\n (sum, log) => sum + (log.requestSize ?? 0),\n 0\n );\n const totalDuration = completed.reduce(\n (sum, log) => sum + (log.duration ?? 0),\n 0\n );\n\n // Group by category\n const byCategory: NetworkStats['byCategory'] = {};\n for (const log of this.logs) {\n if (!byCategory[log.category]) {\n byCategory[log.category] = { requests: 0, downloadBytes: 0, uploadBytes: 0 };\n }\n byCategory[log.category].requests++;\n byCategory[log.category].downloadBytes += log.responseSize ?? 0;\n byCategory[log.category].uploadBytes += log.requestSize ?? 0;\n }\n\n // Group by status\n const byStatus: Record<number, number> = {};\n for (const log of completed) {\n if (log.status) {\n byStatus[log.status] = (byStatus[log.status] ?? 0) + 1;\n }\n }\n\n // Calculate requests per minute\n const now = Date.now();\n const oneMinuteAgo = now - 60000;\n const recentRequests = this.logs.filter(\n (log) => log.timestamp.getTime() >= oneMinuteAgo\n );\n\n return {\n totalRequests: this.logs.length,\n completedRequests: completed.length,\n failedRequests: failed.length,\n totalDownloadBytes,\n totalUploadBytes,\n totalDuration,\n averageSpeed: totalDuration > 0 ? (totalDownloadBytes / totalDuration) * 1000 : 0,\n byCategory,\n byStatus,\n requestsPerMinute: recentRequests.length,\n };\n }\n\n /**\n * Clear logs.\n */\n clear(filter?: { olderThan?: string | Date }): void {\n if (!filter?.olderThan) {\n this.logs = [];\n return;\n }\n\n let cutoff: Date;\n if (typeof filter.olderThan === 'string') {\n // Parse duration string like '7d', '24h'\n cutoff = new Date(Date.now() - parseDuration(filter.olderThan));\n } else {\n cutoff = filter.olderThan;\n }\n\n this.logs = this.logs.filter((log) => log.timestamp >= cutoff);\n }\n\n /**\n * Subscribe to network request events.\n */\n subscribe(callback: NetworkRequestCallback): () => void {\n this.listeners.add(callback);\n return () => this.listeners.delete(callback);\n }\n\n /**\n * Notify all listeners of an update.\n */\n private notifyListeners(entry: NetworkLogEntry): void {\n for (const listener of this.listeners) {\n try {\n listener(entry);\n } catch (error) {\n console.error('Error in network logger listener:', error);\n }\n }\n }\n}\n\n// ============================================================================\n// Global Logger Instance\n// ============================================================================\n\nlet globalLogger: NetworkLogger | null = null;\n\n/**\n * Create a network logger.\n *\n * @param config - Logger configuration\n * @returns Network logger instance\n */\nexport function createNetworkLogger(config?: NetworkLoggerConfig): NetworkLogger {\n const logger = new NetworkLogger(config);\n\n // Set as global if none exists\n if (!globalLogger) {\n globalLogger = logger;\n }\n\n return logger;\n}\n\n/**\n * Get the global network logger.\n *\n * Creates one if it doesn't exist.\n */\nexport function getGlobalLogger(): NetworkLogger {\n if (!globalLogger) {\n globalLogger = new NetworkLogger();\n }\n return globalLogger;\n}\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Get network logs from the global logger.\n *\n * @param filter - Optional filter\n * @returns Array of log entries\n */\nexport function getNetworkLogs(filter?: NetworkLogFilter): NetworkLogEntry[] {\n return getGlobalLogger().getLogs(filter);\n}\n\n/**\n * Clear network logs from the global logger.\n *\n * @param options - Clear options\n */\nexport function clearNetworkLogs(options?: { olderThan?: string | Date }): void {\n getGlobalLogger().clear(options);\n}\n\n/**\n * Subscribe to network request events.\n *\n * @param callback - Callback function\n * @returns Unsubscribe function\n *\n * @example\n * ```typescript\n * import { onNetworkRequest } from '@localmode/core';\n *\n * const unsubscribe = onNetworkRequest((entry) => {\n * if (entry.category === 'model' && entry.state === 'in-progress') {\n * updateProgressBar(entry.progress);\n * }\n * });\n *\n * // Later:\n * unsubscribe();\n * ```\n */\nexport function onNetworkRequest(callback: NetworkRequestCallback): () => void {\n return getGlobalLogger().subscribe(callback);\n}\n\n/**\n * Get network statistics from the global logger.\n *\n * @returns Network statistics\n */\nexport function getNetworkStats(): NetworkStats {\n return getGlobalLogger().getStats();\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Generate a unique ID.\n */\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n}\n\n/**\n * Parse a duration string into milliseconds.\n */\nfunction parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+(?:\\.\\d+)?)\\s*(s|m|h|d|w)$/);\n if (!match) return 0;\n\n const value = parseFloat(match[1]);\n const unit = match[2];\n\n const multipliers: Record<string, number> = {\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n w: 7 * 24 * 60 * 60 * 1000,\n };\n\n return value * (multipliers[unit] ?? 0);\n}\n\n","/**\n * Fetch Wrapper with Logging\n *\n * Wrap fetch to automatically log all network requests.\n *\n * @packageDocumentation\n */\n\nimport type { NetworkLogEntry, ProgressCallback } from './types.js';\nimport { getGlobalLogger } from './logger.js';\n\n// ============================================================================\n// Logging Fetch\n// ============================================================================\n\n/**\n * Options for creating a logging fetch function.\n */\nexport interface LoggingFetchOptions {\n /** Category for all requests made with this fetch */\n category?: string;\n\n /** Progress callback for download/upload progress */\n onProgress?: ProgressCallback;\n\n /** Whether to log request headers */\n logHeaders?: boolean;\n\n /** Custom category resolver based on URL */\n categoryResolver?: (url: string) => string;\n}\n\n/**\n * Create a fetch function that logs all requests.\n *\n * @param options - Logging options\n * @returns Fetch function with logging\n *\n * @example\n * ```typescript\n * import { createLoggingFetch } from '@localmode/core';\n *\n * const modelFetch = createLoggingFetch({\n * category: 'model',\n * onProgress: (loaded, total, url) => {\n * console.log(`${url}: ${(loaded / total * 100).toFixed(1)}%`);\n * },\n * });\n *\n * const response = await modelFetch('https://huggingface.co/model.bin');\n * ```\n */\nexport function createLoggingFetch(\n options: LoggingFetchOptions = {}\n): typeof fetch {\n const { category = 'other', onProgress, logHeaders = false, categoryResolver } = options;\n\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;\n const method = (init?.method ?? 'GET').toUpperCase() as NetworkLogEntry['method'];\n const resolvedCategory = categoryResolver ? categoryResolver(url) : category;\n\n const logger = getGlobalLogger();\n const startTime = performance.now();\n\n // Log the request start\n const entry = logger.log({\n type: method === 'GET' || method === 'HEAD' ? 'download' : 'upload',\n url,\n method,\n state: 'pending',\n category: resolvedCategory,\n requestHeaders: logHeaders && init?.headers\n ? Object.fromEntries(new Headers(init.headers).entries())\n : undefined,\n requestSize: init?.body\n ? (typeof init.body === 'string' ? init.body.length : 0)\n : undefined,\n });\n\n try {\n // Update to in-progress\n logger.update(entry.id, { state: 'in-progress' });\n\n const response = await fetch(input, init);\n\n // Get response size if possible\n const contentLength = response.headers.get('content-length');\n const responseSize = contentLength ? parseInt(contentLength, 10) : undefined;\n\n // For progress tracking, we need to consume the body\n if (onProgress && responseSize) {\n const body = response.body;\n if (body) {\n const trackedResponse = trackProgress(\n response,\n body,\n responseSize,\n (loaded, total) => {\n logger.update(entry.id, {\n progress: Math.round((loaded / total) * 100),\n });\n onProgress(loaded, total, url);\n }\n );\n\n // Update final state\n const duration = performance.now() - startTime;\n logger.update(entry.id, {\n state: 'completed',\n status: response.status,\n statusText: response.statusText,\n responseSize,\n duration,\n progress: 100,\n responseHeaders: logHeaders\n ? Object.fromEntries(response.headers.entries())\n : undefined,\n });\n\n return trackedResponse;\n }\n }\n\n // Update with response info\n const duration = performance.now() - startTime;\n logger.update(entry.id, {\n state: 'completed',\n status: response.status,\n statusText: response.statusText,\n responseSize,\n duration,\n progress: 100,\n responseHeaders: logHeaders\n ? Object.fromEntries(response.headers.entries())\n : undefined,\n });\n\n return response;\n } catch (error) {\n const duration = performance.now() - startTime;\n logger.update(entry.id, {\n state: 'failed',\n error: error instanceof Error ? error.message : String(error),\n duration,\n });\n throw error;\n }\n };\n}\n\n/**\n * Track progress of a streaming response.\n */\nfunction trackProgress(\n response: Response,\n body: ReadableStream<Uint8Array>,\n total: number,\n onProgress: (loaded: number, total: number) => void\n): Response {\n let loaded = 0;\n\n const reader = body.getReader();\n const stream = new ReadableStream({\n async start(controller) {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n controller.close();\n break;\n }\n\n loaded += value.length;\n onProgress(loaded, total);\n controller.enqueue(value);\n }\n },\n });\n\n return new Response(stream, {\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n });\n}\n\n// ============================================================================\n// Global Fetch Wrapper\n// ============================================================================\n\nlet originalFetch: typeof fetch | null = null;\n\n/**\n * Wrap the global fetch with logging.\n *\n * @param options - Category mapping and options\n *\n * @example\n * ```typescript\n * import { wrapFetchWithLogging } from '@localmode/core';\n *\n * wrapFetchWithLogging({\n * categories: {\n * 'huggingface.co': 'model',\n * 'cdn.example.com': 'data',\n * },\n * });\n *\n * // Now all fetch calls are logged\n * const response = await fetch('https://huggingface.co/model.bin');\n * ```\n */\nexport function wrapFetchWithLogging(options: {\n categories?: Record<string, string>;\n onProgress?: ProgressCallback;\n logHeaders?: boolean;\n} = {}): void {\n if (typeof globalThis.fetch === 'undefined') return;\n if (originalFetch) return; // Already wrapped\n\n originalFetch = globalThis.fetch;\n\n const categoryResolver = options.categories\n ? (url: string) => {\n for (const [pattern, category] of Object.entries(options.categories!)) {\n if (url.includes(pattern)) return category;\n }\n return 'other';\n }\n : undefined;\n\n const loggingFetch = createLoggingFetch({\n category: 'other',\n categoryResolver,\n onProgress: options.onProgress,\n logHeaders: options.logHeaders,\n });\n\n globalThis.fetch = loggingFetch as typeof fetch;\n}\n\n/**\n * Restore the original fetch function.\n */\nexport function unwrapFetch(): void {\n if (originalFetch) {\n globalThis.fetch = originalFetch;\n originalFetch = null;\n }\n}\n\n/**\n * Check if fetch is currently wrapped.\n */\nexport function isFetchWrapped(): boolean {\n return originalFetch !== null;\n}\n\n","/**\n * Error Formatting Utilities\n *\n * Format errors for display to end users.\n *\n * @packageDocumentation\n */\n\nimport {\n LocalModeError,\n EmbeddingError,\n ModelNotFoundError,\n ModelLoadError,\n StorageError,\n QuotaExceededError,\n IndexedDBBlockedError,\n ValidationError,\n DimensionMismatchError,\n NetworkError,\n OfflineError,\n FeatureNotSupportedError,\n} from './index.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Formatted error for UI display.\n */\nexport interface FormattedError {\n /** User-friendly title */\n title: string;\n\n /** User-friendly message */\n message: string;\n\n /** Actionable hint (if available) */\n hint?: string;\n\n /** Whether the operation can be retried */\n isRetryable: boolean;\n\n /** Error code for programmatic handling */\n code?: string;\n\n /** Severity level */\n severity: 'error' | 'warning' | 'info';\n\n /** Original error (for debugging) */\n originalError?: Error;\n}\n\n// ============================================================================\n// Error Formatting\n// ============================================================================\n\n/**\n * Format an error for display to end users.\n *\n * Returns a structured object suitable for UI display.\n *\n * @param error - Error to format\n * @returns Formatted error object\n *\n * @example\n * ```typescript\n * import { formatErrorForUser } from '@localmode/core';\n *\n * try {\n * await embed({ model, value: 'text' });\n * } catch (error) {\n * const formatted = formatErrorForUser(error);\n *\n * showErrorDialog({\n * title: formatted.title,\n * message: formatted.message,\n * hint: formatted.hint,\n * showRetryButton: formatted.isRetryable,\n * });\n * }\n * ```\n */\nexport function formatErrorForUser(error: unknown): FormattedError {\n // Model not found\n if (error instanceof ModelNotFoundError) {\n return {\n title: 'Model Not Found',\n message: `The embedding model \"${error.modelId}\" could not be found.`,\n hint: 'Check the model ID and ensure it exists on Hugging Face.',\n isRetryable: false,\n code: error.code,\n severity: 'error',\n originalError: error,\n };\n }\n\n // Model load error\n if (error instanceof ModelLoadError) {\n return {\n title: 'Model Loading Failed',\n message: `Could not load the model \"${error.modelId}\".`,\n hint: error.hint ?? 'Check your network connection and try again.',\n isRetryable: true,\n code: error.code,\n severity: 'error',\n originalError: error,\n };\n }\n\n // Quota exceeded\n if (error instanceof QuotaExceededError) {\n return {\n title: 'Storage Full',\n message: 'Your browser storage is full.',\n hint: 'Clear old data or use a different browser profile.',\n isRetryable: false,\n code: error.code,\n severity: 'error',\n originalError: error,\n };\n }\n\n // IndexedDB blocked\n if (error instanceof IndexedDBBlockedError) {\n return {\n title: 'Storage Blocked',\n message: 'Cannot access browser storage.',\n hint: 'You may be in private browsing mode. Try using a regular browser window.',\n isRetryable: false,\n code: error.code,\n severity: 'error',\n originalError: error,\n };\n }\n\n // Dimension mismatch\n if (error instanceof DimensionMismatchError) {\n return {\n title: 'Dimension Mismatch',\n message: `Vector dimension mismatch: expected ${error.expected}, got ${error.received}.`,\n hint: 'Ensure you are using the same embedding model for all operations.',\n isRetryable: false,\n code: 'DIMENSION_MISMATCH',\n severity: 'error',\n originalError: error,\n };\n }\n\n // Offline error\n if (error instanceof OfflineError) {\n return {\n title: 'Offline',\n message: 'This operation requires an internet connection.',\n hint: 'Check your network connection and try again.',\n isRetryable: true,\n code: error.code,\n severity: 'warning',\n originalError: error,\n };\n }\n\n // Network error\n if (error instanceof NetworkError) {\n return {\n title: 'Network Error',\n message: error.message,\n hint: error.hint ?? 'Check your network connection and try again.',\n isRetryable: true,\n code: error.code,\n severity: 'error',\n originalError: error,\n };\n }\n\n // Feature not supported\n if (error instanceof FeatureNotSupportedError) {\n return {\n title: 'Feature Not Supported',\n message: `${error.feature} is not available in this browser.`,\n hint: error.hint,\n isRetryable: false,\n code: error.code,\n severity: 'warning',\n originalError: error,\n };\n }\n\n // Embedding error\n if (error instanceof EmbeddingError) {\n return {\n title: 'Embedding Error',\n message: error.message,\n hint: error.hint,\n isRetryable: true,\n code: error.code,\n severity: 'error',\n originalError: error,\n };\n }\n\n // Validation error\n if (error instanceof ValidationError) {\n return {\n title: 'Validation Error',\n message: error.message,\n hint: error.hint,\n isRetryable: false,\n code: error.code,\n severity: 'error',\n originalError: error,\n };\n }\n\n // Storage error\n if (error instanceof StorageError) {\n return {\n title: 'Storage Error',\n message: error.message,\n hint: error.hint,\n isRetryable: true,\n code: error.code,\n severity: 'error',\n originalError: error,\n };\n }\n\n // Generic LocalModeError\n if (error instanceof LocalModeError) {\n return {\n title: 'Error',\n message: error.message,\n hint: error.hint,\n isRetryable: true,\n code: error.code,\n severity: 'error',\n originalError: error,\n };\n }\n\n // Standard Error\n if (error instanceof Error) {\n // Check for common error patterns\n const message = error.message.toLowerCase();\n\n if (message.includes('network') || message.includes('fetch')) {\n return {\n title: 'Network Error',\n message: 'A network error occurred.',\n hint: 'Check your internet connection and try again.',\n isRetryable: true,\n severity: 'error',\n originalError: error,\n };\n }\n\n if (message.includes('timeout')) {\n return {\n title: 'Timeout',\n message: 'The operation timed out.',\n hint: 'The server may be slow. Try again later.',\n isRetryable: true,\n severity: 'warning',\n originalError: error,\n };\n }\n\n if (message.includes('abort') || message.includes('cancel')) {\n return {\n title: 'Cancelled',\n message: 'The operation was cancelled.',\n isRetryable: true,\n severity: 'info',\n originalError: error,\n };\n }\n\n return {\n title: 'Error',\n message: error.message,\n isRetryable: true,\n severity: 'error',\n originalError: error,\n };\n }\n\n // Unknown error\n return {\n title: 'Unexpected Error',\n message: 'Something went wrong.',\n hint: 'Please try again. If the problem persists, contact support.',\n isRetryable: true,\n severity: 'error',\n };\n}\n\n// ============================================================================\n// Error Display Helpers\n// ============================================================================\n\n/**\n * Format error for console logging with colors.\n *\n * @param error - Error to format\n * @returns Formatted string with ANSI colors\n */\nexport function formatErrorForConsole(error: unknown): string {\n const formatted = formatErrorForUser(error);\n\n const lines: string[] = [];\n const red = '\\x1b[31m';\n const yellow = '\\x1b[33m';\n const cyan = '\\x1b[36m';\n const reset = '\\x1b[0m';\n\n const color = formatted.severity === 'error' ? red : formatted.severity === 'warning' ? yellow : cyan;\n\n lines.push(`${color}[${formatted.code ?? 'ERROR'}] ${formatted.title}${reset}`);\n lines.push(` ${formatted.message}`);\n\n if (formatted.hint) {\n lines.push(` 💡 ${formatted.hint}`);\n }\n\n if (formatted.originalError?.stack) {\n lines.push('');\n lines.push(` Stack trace:`);\n lines.push(` ${formatted.originalError.stack.split('\\n').slice(1).join('\\n ')}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format error as HTML for web display.\n *\n * @param error - Error to format\n * @returns HTML string\n */\nexport function formatErrorAsHTML(error: unknown): string {\n const formatted = formatErrorForUser(error);\n\n const bgColor =\n formatted.severity === 'error'\n ? '#fee2e2'\n : formatted.severity === 'warning'\n ? '#fef3c7'\n : '#dbeafe';\n const borderColor =\n formatted.severity === 'error'\n ? '#fca5a5'\n : formatted.severity === 'warning'\n ? '#fcd34d'\n : '#93c5fd';\n const textColor =\n formatted.severity === 'error'\n ? '#b91c1c'\n : formatted.severity === 'warning'\n ? '#92400e'\n : '#1e40af';\n\n let html = `\n <div style=\"\n background: ${bgColor};\n border: 1px solid ${borderColor};\n border-radius: 8px;\n padding: 16px;\n font-family: system-ui, -apple-system, sans-serif;\n \">\n <h3 style=\"margin: 0 0 8px; color: ${textColor}; font-size: 16px;\">\n ${escapeHTML(formatted.title)}\n </h3>\n <p style=\"margin: 0 0 8px; color: #374151;\">\n ${escapeHTML(formatted.message)}\n </p>\n `;\n\n if (formatted.hint) {\n html += `\n <p style=\"margin: 0; color: #6b7280; font-size: 14px;\">\n 💡 ${escapeHTML(formatted.hint)}\n </p>\n `;\n }\n\n if (formatted.isRetryable) {\n html += `\n <p style=\"margin: 8px 0 0; color: #059669; font-size: 14px;\">\n ↻ This operation can be retried\n </p>\n `;\n }\n\n html += '</div>';\n\n return html;\n}\n\n/**\n * Escape HTML special characters.\n */\nfunction escapeHTML(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n// ============================================================================\n// Error Logging\n// ============================================================================\n\n/**\n * Log an error with appropriate formatting.\n *\n * @param error - Error to log\n * @param context - Additional context\n */\nexport function logError(error: unknown, context?: Record<string, unknown>): void {\n const formatted = formatErrorForUser(error);\n\n const logMethod =\n formatted.severity === 'error'\n ? console.error\n : formatted.severity === 'warning'\n ? console.warn\n : console.info;\n\n logMethod(`[${formatted.code ?? 'ERROR'}] ${formatted.title}`);\n logMethod(` ${formatted.message}`);\n\n if (formatted.hint) {\n logMethod(` 💡 ${formatted.hint}`);\n }\n\n if (context) {\n logMethod(' Context:', context);\n }\n\n if (formatted.originalError?.stack) {\n logMethod(formatted.originalError.stack);\n }\n}\n\n","/**\n * Error Classes\n *\n * Comprehensive error classes with helpful hints for debugging.\n *\n * @packageDocumentation\n */\n\n// Re-export formatting utilities\nexport {\n formatErrorForUser,\n formatErrorForConsole,\n formatErrorAsHTML,\n logError,\n type FormattedError,\n} from './format.js';\n\n// ============================================================================\n// Base Error\n// ============================================================================\n\n/**\n * Base error class for all @localmode errors.\n *\n * Provides structured error information with:\n * - Error code for programmatic handling\n * - User-actionable hint for resolution\n * - Additional context for debugging\n * - Original cause error\n */\nexport class LocalModeError extends Error {\n /** Error code for programmatic handling */\n readonly code: string;\n\n /** User-actionable hint to resolve the error */\n readonly hint?: string;\n\n /** Additional context for debugging */\n readonly context?: Record<string, unknown>;\n\n /** Original error that caused this one */\n readonly cause?: Error;\n\n constructor(\n message: string,\n code: string,\n options?: {\n hint?: string;\n context?: Record<string, unknown>;\n cause?: Error;\n }\n ) {\n super(message, { cause: options?.cause });\n this.name = 'LocalModeError';\n this.code = code;\n this.hint = options?.hint;\n this.context = options?.context;\n this.cause = options?.cause;\n }\n\n /** Format error for console output */\n toString(): string {\n let msg = `[${this.code}] ${this.message}`;\n if (this.hint) {\n msg += `\\n\\n💡 Hint: ${this.hint}`;\n }\n return msg;\n }\n\n /** Convert to JSON-serializable object */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n hint: this.hint,\n context: this.context,\n cause: this.cause?.message,\n };\n }\n}\n\n// ============================================================================\n// Configuration Errors\n// ============================================================================\n\n/**\n * Error for invalid configuration.\n */\nexport class ConfigError extends LocalModeError {\n constructor(message: string, hint?: string) {\n super(message, 'CONFIG_ERROR', { hint });\n this.name = 'ConfigError';\n }\n}\n\n// ============================================================================\n// Validation Errors\n// ============================================================================\n\n/**\n * Error for validation failures.\n */\nexport class ValidationError extends LocalModeError {\n constructor(message: string, hint?: string) {\n super(message, 'VALIDATION_ERROR', { hint });\n this.name = 'ValidationError';\n }\n}\n\n/**\n * Error for vector dimension mismatches.\n */\nexport class DimensionMismatchError extends ValidationError {\n readonly expected: number;\n readonly received: number;\n\n constructor(expected: number, received: number) {\n super(\n `Vector dimension mismatch: expected ${expected}, got ${received}`,\n `Ensure all vectors have ${expected} dimensions. Check that you're using the same embedding model.`\n );\n this.name = 'DimensionMismatchError';\n this.expected = expected;\n this.received = received;\n }\n}\n\n/**\n * Error for invalid options.\n */\nexport class InvalidOptionsError extends ValidationError {\n readonly option: string;\n\n constructor(option: string, received: unknown, expected: string) {\n super(\n `Invalid option '${option}': expected ${expected}, got ${typeof received}`,\n `Check the API documentation for correct option types.`\n );\n this.name = 'InvalidOptionsError';\n this.option = option;\n }\n}\n\n// ============================================================================\n// Embedding Errors\n// ============================================================================\n\n/**\n * Base error for embedding operations.\n */\nexport class EmbeddingError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'EMBEDDING_ERROR', options);\n this.name = 'EmbeddingError';\n }\n}\n\n/**\n * Error when a model is not found.\n */\nexport class ModelNotFoundError extends EmbeddingError {\n readonly modelId: string;\n\n constructor(modelId: string) {\n super(`Embedding model not found: ${modelId}`, {\n hint: `Check that the model ID is correct. Popular models include:\n• Xenova/all-MiniLM-L6-v2 (384 dimensions)\n• Xenova/bge-small-en-v1.5 (384 dimensions)\n• Xenova/all-mpnet-base-v2 (768 dimensions)\n\nSee https://huggingface.co/models?library=transformers.js for available models.`,\n });\n this.name = 'ModelNotFoundError';\n this.modelId = modelId;\n }\n}\n\n/**\n * Error when model fails to load.\n */\nexport class ModelLoadError extends EmbeddingError {\n readonly modelId: string;\n\n constructor(modelId: string, cause?: Error) {\n super(`Failed to load embedding model: ${modelId}`, {\n hint: `Model loading failed. Try:\n1. Check your network connection (first load downloads the model)\n2. Ensure sufficient storage space for model cache\n3. Try a smaller model: Xenova/all-MiniLM-L6-v2\n4. Check browser console for detailed error messages`,\n cause,\n });\n this.name = 'ModelLoadError';\n this.modelId = modelId;\n }\n}\n\n/**\n * Error for embedding dimension issues.\n */\nexport class EmbeddingDimensionError extends EmbeddingError {\n readonly expected: number;\n readonly received: number;\n\n constructor(expected: number, received: number, modelId?: string) {\n super(`Embedding dimension mismatch: expected ${expected}, got ${received}`, {\n hint: modelId\n ? `Model '${modelId}' produces ${received}-dimensional embeddings, but database expects ${expected}. Either use a different model or create a new database with the correct dimensions.`\n : `Ensure your embedding model outputs ${expected}-dimensional vectors.`,\n });\n this.name = 'EmbeddingDimensionError';\n this.expected = expected;\n this.received = received;\n }\n}\n\n// ============================================================================\n// Model Errors\n// ============================================================================\n\n/**\n * Base error for model operations.\n */\nexport class ModelError extends LocalModeError {\n readonly modelId?: string;\n\n constructor(message: string, options?: { modelId?: string; hint?: string; cause?: Error }) {\n super(message, 'MODEL_ERROR', options);\n this.name = 'ModelError';\n this.modelId = options?.modelId;\n }\n}\n\n/**\n * Error when model inference fails.\n */\nexport class InferenceError extends ModelError {\n constructor(message: string, options?: { modelId?: string; hint?: string; cause?: Error }) {\n super(message, { ...options, hint: options?.hint ?? 'Check input data and model compatibility.' });\n this.name = 'InferenceError';\n }\n}\n\n// ============================================================================\n// Storage Errors\n// ============================================================================\n\n/**\n * Base error for storage operations.\n */\nexport class StorageError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'STORAGE_ERROR', options);\n this.name = 'StorageError';\n }\n}\n\n/**\n * Error when storage quota is exceeded.\n */\nexport class QuotaExceededError extends StorageError {\n readonly usedBytes?: number;\n readonly quotaBytes?: number;\n\n constructor(options?: { usedBytes?: number; quotaBytes?: number }) {\n super('Storage quota exceeded', {\n hint: `Your browser storage is full. Try:\n1. Clear old data: await db.cleanup({ maxAge: '30d' })\n2. Request persistent storage: await navigator.storage.persist()\n3. Export and delete old collections\n4. Use smaller models to reduce cache size`,\n });\n this.name = 'QuotaExceededError';\n this.usedBytes = options?.usedBytes;\n this.quotaBytes = options?.quotaBytes;\n }\n}\n\n/**\n * Error when IndexedDB access is blocked.\n */\nexport class IndexedDBBlockedError extends StorageError {\n constructor() {\n super('IndexedDB access is blocked', {\n hint: `IndexedDB may be blocked because:\n• You're in Safari/Firefox Private Browsing mode\n• IndexedDB is disabled in browser settings\n• Another tab has an outdated version open (refresh all tabs)\n\nSolution: Use in-memory storage for private browsing:\n createVectorDB({ storage: new MemoryStorage() })`,\n });\n this.name = 'IndexedDBBlockedError';\n }\n}\n\n/**\n * Error when a document is not found.\n */\nexport class DocumentNotFoundError extends StorageError {\n readonly documentId: string;\n\n constructor(documentId: string) {\n super(`Document not found: ${documentId}`, {\n hint: 'Check that the document ID is correct and the document exists in the database.',\n });\n this.name = 'DocumentNotFoundError';\n this.documentId = documentId;\n }\n}\n\n/**\n * Error for migration failures.\n */\nexport class MigrationError extends StorageError {\n readonly fromVersion: number;\n readonly toVersion: number;\n\n constructor(fromVersion: number, toVersion: number, cause?: Error) {\n super(`Migration failed from version ${fromVersion} to ${toVersion}`, {\n hint: 'Database migration failed. You may need to export data and recreate the database.',\n cause,\n });\n this.name = 'MigrationError';\n this.fromVersion = fromVersion;\n this.toVersion = toVersion;\n }\n}\n\n// ============================================================================\n// Middleware Errors\n// ============================================================================\n\n/**\n * Error in middleware execution.\n */\nexport class MiddlewareError extends LocalModeError {\n readonly middlewareName?: string;\n\n constructor(message: string, options?: { middlewareName?: string; hint?: string; cause?: Error }) {\n super(message, 'MIDDLEWARE_ERROR', options);\n this.name = 'MiddlewareError';\n this.middlewareName = options?.middlewareName;\n }\n}\n\n// ============================================================================\n// Loader Errors\n// ============================================================================\n\n/**\n * Error in document loading.\n */\nexport class LoaderError extends LocalModeError {\n readonly source?: string;\n\n constructor(message: string, options?: { source?: string; hint?: string; cause?: Error }) {\n super(message, 'LOADER_ERROR', options);\n this.name = 'LoaderError';\n this.source = options?.source;\n }\n}\n\n// ============================================================================\n// Filter Errors\n// ============================================================================\n\n/**\n * Error in filter evaluation.\n */\nexport class FilterError extends LocalModeError {\n readonly operator?: string;\n\n constructor(message: string, options?: { operator?: string; hint?: string }) {\n super(message, 'FILTER_ERROR', options);\n this.name = 'FilterError';\n this.operator = options?.operator;\n }\n}\n\n// ============================================================================\n// Sync Errors\n// ============================================================================\n\n/**\n * Error in synchronization.\n */\nexport class SyncError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'SYNC_ERROR', options);\n this.name = 'SyncError';\n }\n}\n\n/**\n * Error when a lock cannot be acquired.\n */\nexport class LockError extends SyncError {\n readonly lockName: string;\n\n constructor(lockName: string) {\n super(`Failed to acquire lock: ${lockName}`, {\n hint: 'Another tab or process may be holding this lock. Try again later.',\n });\n this.name = 'LockError';\n this.lockName = lockName;\n }\n}\n\n// ============================================================================\n// Audio/Vision Errors\n// ============================================================================\n\n/**\n * Error in audio processing.\n */\nexport class AudioError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'AUDIO_ERROR', options);\n this.name = 'AudioError';\n }\n}\n\n/**\n * Error in vision/image processing.\n */\nexport class VisionError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'VISION_ERROR', options);\n this.name = 'VisionError';\n }\n}\n\n// ============================================================================\n// P2 Domain Errors\n// ============================================================================\n\n/**\n * Error in text generation.\n */\nexport class GenerationError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'GENERATION_ERROR', options);\n this.name = 'GenerationError';\n }\n}\n\n/**\n * Error when context length is exceeded.\n */\nexport class ContextLengthExceededError extends GenerationError {\n readonly maxLength: number;\n readonly actualLength: number;\n\n constructor(maxLength: number, actualLength: number) {\n super(`Context length exceeded: ${actualLength} tokens (max: ${maxLength})`, {\n hint: `Your prompt is too long. Try:\n1. Shorten your prompt or system prompt\n2. Use a model with longer context (e.g., Llama-3.2)\n3. Summarize or chunk your input text`,\n });\n this.name = 'ContextLengthExceededError';\n this.maxLength = maxLength;\n this.actualLength = actualLength;\n }\n}\n\n/**\n * Error in translation.\n */\nexport class TranslationError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'TRANSLATION_ERROR', options);\n this.name = 'TranslationError';\n }\n}\n\n/**\n * Error when a language is not supported.\n */\nexport class UnsupportedLanguageError extends TranslationError {\n readonly language: string;\n readonly supportedLanguages?: string[];\n\n constructor(language: string, supportedLanguages?: string[]) {\n const hint = supportedLanguages\n ? `Supported languages: ${supportedLanguages.slice(0, 10).join(', ')}${supportedLanguages.length > 10 ? '...' : ''}`\n : 'Check the model documentation for supported language pairs.';\n super(`Language not supported: ${language}`, { hint });\n this.name = 'UnsupportedLanguageError';\n this.language = language;\n this.supportedLanguages = supportedLanguages;\n }\n}\n\n/**\n * Error in summarization.\n */\nexport class SummarizationError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'SUMMARIZATION_ERROR', options);\n this.name = 'SummarizationError';\n }\n}\n\n/**\n * Error in fill-mask operations.\n */\nexport class FillMaskError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'FILL_MASK_ERROR', options);\n this.name = 'FillMaskError';\n }\n}\n\n/**\n * Error when mask token is missing.\n */\nexport class MissingMaskTokenError extends FillMaskError {\n readonly expectedToken: string;\n\n constructor(expectedToken: string) {\n super(`No mask token found in input. Expected: ${expectedToken}`, {\n hint: `Add the mask token to your text where you want predictions. Example: \"The capital of France is ${expectedToken}.\"`,\n });\n this.name = 'MissingMaskTokenError';\n this.expectedToken = expectedToken;\n }\n}\n\n/**\n * Error in question answering.\n */\nexport class QuestionAnsweringError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'QUESTION_ANSWERING_ERROR', options);\n this.name = 'QuestionAnsweringError';\n }\n}\n\n/**\n * Error in OCR.\n */\nexport class OCRError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'OCR_ERROR', options);\n this.name = 'OCRError';\n }\n}\n\n/**\n * Error when image format is unsupported.\n */\nexport class ImageFormatError extends VisionError {\n readonly format?: string;\n\n constructor(format?: string) {\n super(`Unsupported image format${format ? `: ${format}` : ''}`, {\n hint: 'Supported formats: JPEG, PNG, WebP, GIF. Ensure the image is not corrupted.',\n });\n this.name = 'ImageFormatError';\n this.format = format;\n }\n}\n\n/**\n * Error in document QA.\n */\nexport class DocumentQAError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'DOCUMENT_QA_ERROR', options);\n this.name = 'DocumentQAError';\n }\n}\n\n/**\n * Error in table QA.\n */\nexport class TableQAError extends LocalModeError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, 'TABLE_QA_ERROR', options);\n this.name = 'TableQAError';\n }\n}\n\n/**\n * Error when table format is invalid.\n */\nexport class InvalidTableFormatError extends TableQAError {\n constructor(reason: string) {\n super(`Invalid table format: ${reason}`, {\n hint: 'Table must have headers and rows arrays. Example: { headers: [\"Name\", \"Age\"], rows: [[\"John\", \"30\"]] }',\n });\n this.name = 'InvalidTableFormatError';\n }\n}\n\n/**\n * Error in image segmentation.\n */\nexport class SegmentationError extends VisionError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, options);\n this.name = 'SegmentationError';\n }\n}\n\n/**\n * Error in object detection.\n */\nexport class ObjectDetectionError extends VisionError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, options);\n this.name = 'ObjectDetectionError';\n }\n}\n\n/**\n * Error in image upscaling.\n */\nexport class ImageUpscaleError extends VisionError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, options);\n this.name = 'ImageUpscaleError';\n }\n}\n\n/**\n * Error in text-to-speech synthesis.\n */\nexport class SpeechSynthesisError extends AudioError {\n constructor(message: string, options?: { hint?: string; cause?: Error }) {\n super(message, options);\n this.name = 'SpeechSynthesisError';\n }\n}\n\n// ============================================================================\n// Network Errors\n// ============================================================================\n\n/**\n * Error in network operations.\n */\nexport class NetworkError extends LocalModeError {\n readonly url?: string;\n readonly status?: number;\n\n constructor(message: string, options?: { url?: string; status?: number; hint?: string; cause?: Error }) {\n super(message, 'NETWORK_ERROR', options);\n this.name = 'NetworkError';\n this.url = options?.url;\n this.status = options?.status;\n }\n}\n\n/**\n * Error when offline and network is required.\n */\nexport class OfflineError extends NetworkError {\n constructor(operation: string) {\n super(`Cannot ${operation}: offline`, {\n hint: 'This operation requires network access. Check your connection and try again.',\n });\n this.name = 'OfflineError';\n }\n}\n\n// ============================================================================\n// Capability Errors\n// ============================================================================\n\n/**\n * Error when a required feature is not supported.\n */\nexport class FeatureNotSupportedError extends LocalModeError {\n readonly feature: string;\n\n constructor(feature: string, hint?: string) {\n super(`Feature not supported: ${feature}`, 'FEATURE_NOT_SUPPORTED', {\n hint: hint ?? `This browser does not support ${feature}. Try using a modern browser like Chrome or Firefox.`,\n });\n this.name = 'FeatureNotSupportedError';\n this.feature = feature;\n }\n}\n\n/**\n * Error when trying to use a feature in wrong environment.\n */\nexport class EnvironmentError extends LocalModeError {\n constructor(message: string, hint?: string) {\n super(message, 'ENVIRONMENT_ERROR', { hint });\n this.name = 'EnvironmentError';\n }\n}\n\n","/**\n * Testing Utilities\n *\n * Mock implementations and helpers for testing @localmode applications.\n *\n * @packageDocumentation\n */\n\nimport type { EmbeddingModel } from '../embeddings/types.js';\nimport type { Document, SearchOptions, SearchResult, StoredDocument } from '../types.js';\nimport type { Entity } from '../classification/types.js';\n\n// ============================================================================\n// Seeded Random\n// ============================================================================\n\n/**\n * Create a seeded random number generator.\n *\n * Produces deterministic pseudo-random numbers for reproducible tests.\n *\n * @param seed - Initial seed value\n * @returns Function that returns random numbers between 0 and 1\n *\n * @example\n * ```typescript\n * import { createSeededRandom } from '@localmode/core';\n *\n * const rng = createSeededRandom(42);\n * const value = rng(); // Always produces the same sequence\n * ```\n */\nexport function createSeededRandom(seed: number): () => number {\n let state = seed;\n\n return function random(): number {\n // Mulberry32 PRNG\n let t = (state += 0x6d2b79f5);\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n// ============================================================================\n// Test Vectors\n// ============================================================================\n\n/**\n * Create a deterministic test vector.\n *\n * @param dimensions - Number of dimensions\n * @param seed - Seed for random generation\n * @param normalize - Whether to normalize the vector (default: true)\n * @returns Float32Array with deterministic values\n *\n * @example\n * ```typescript\n * import { createTestVector } from '@localmode/core';\n *\n * const vector1 = createTestVector(384, 42);\n * const vector2 = createTestVector(384, 42);\n * // vector1 and vector2 are identical\n * ```\n */\nexport function createTestVector(\n dimensions: number,\n seed: number = 42,\n normalize: boolean = true\n): Float32Array {\n const rng = createSeededRandom(seed);\n const vector = new Float32Array(dimensions);\n\n for (let i = 0; i < dimensions; i++) {\n vector[i] = rng() * 2 - 1; // Values between -1 and 1\n }\n\n if (normalize) {\n let magnitude = 0;\n for (let i = 0; i < dimensions; i++) {\n magnitude += vector[i] * vector[i];\n }\n magnitude = Math.sqrt(magnitude);\n if (magnitude > 0) {\n for (let i = 0; i < dimensions; i++) {\n vector[i] /= magnitude;\n }\n }\n }\n\n return vector;\n}\n\n/**\n * Create multiple test vectors.\n *\n * @param count - Number of vectors to create\n * @param dimensions - Number of dimensions per vector\n * @param baseSeed - Base seed (each vector gets baseSeed + index)\n * @returns Array of Float32Arrays\n */\nexport function createTestVectors(\n count: number,\n dimensions: number,\n baseSeed: number = 0\n): Float32Array[] {\n const vectors: Float32Array[] = [];\n for (let i = 0; i < count; i++) {\n vectors.push(createTestVector(dimensions, baseSeed + i));\n }\n return vectors;\n}\n\n// ============================================================================\n// Mock Embedding Model\n// ============================================================================\n\n/**\n * Options for creating a mock embedding model.\n */\nexport interface MockEmbeddingModelOptions {\n /** Number of dimensions (default: 384) */\n dimensions?: number;\n\n /** Delay in milliseconds before returning (default: 0) */\n delay?: number;\n\n /** Number of times to fail before succeeding (default: 0) */\n failCount?: number;\n\n /** Error to throw when failing */\n failError?: Error;\n\n /** Model ID (default: 'mock:test-model') */\n modelId?: string;\n\n /** Seed for deterministic embeddings */\n seed?: number;\n\n /** Callback to track embed calls */\n onEmbed?: (options: {\n values: string[];\n abortSignal?: AbortSignal;\n headers?: Record<string, string>;\n providerOptions?: Record<string, Record<string, unknown>>;\n }) => void;\n}\n\n/**\n * Create a mock embedding model for testing.\n *\n * @param options - Configuration options\n * @returns Mock EmbeddingModel instance\n *\n * @example\n * ```typescript\n * import { createMockEmbeddingModel, embed } from '@localmode/core';\n *\n * const model = createMockEmbeddingModel({ dimensions: 384 });\n *\n * const { embedding } = await embed({\n * model,\n * value: 'Hello world',\n * });\n * ```\n */\nexport function createMockEmbeddingModel(options: MockEmbeddingModelOptions = {}): EmbeddingModel {\n const {\n dimensions = 384,\n delay = 0,\n failCount = 0,\n failError = new Error('Mock embedding failed'),\n modelId = 'mock:test-model',\n seed = 42,\n onEmbed,\n } = options;\n\n let failures = 0;\n let callCount = 0;\n\n return {\n modelId,\n provider: 'mock',\n dimensions,\n maxEmbeddingsPerCall: 100,\n supportsParallelCalls: true,\n\n async doEmbed(embedOptions) {\n callCount++;\n\n // Call the callback if provided\n if (onEmbed) {\n onEmbed(embedOptions);\n }\n\n // Check for abort\n embedOptions.abortSignal?.throwIfAborted?.();\n\n // Simulate delay\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n embedOptions.abortSignal?.throwIfAborted?.();\n }\n\n // Simulate failures\n if (failures < failCount) {\n failures++;\n throw failError;\n }\n\n // Generate deterministic embeddings\n const embeddings = embedOptions.values.map((value, index) => {\n // Use hash of value + seed for deterministic results\n const valueSeed = seed + hashString(value) + index;\n return createTestVector(dimensions, valueSeed);\n });\n\n return {\n embeddings,\n usage: {\n tokens: embedOptions.values.reduce((sum, v) => sum + v.split(/\\s+/).length, 0),\n },\n response: {\n id: `mock-${callCount}`,\n modelId,\n timestamp: new Date(),\n },\n };\n },\n\n // Extension for testing\n get callCount() {\n return callCount;\n },\n resetCallCount() {\n callCount = 0;\n failures = 0;\n },\n } as EmbeddingModel & { callCount: number; resetCallCount: () => void };\n}\n\n/**\n * Simple string hash function.\n */\nfunction hashString(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash);\n}\n\n// ============================================================================\n// Mock Classification Model\n// ============================================================================\n\n/**\n * Options for creating a mock classification model.\n */\nexport interface MockClassificationModelOptions {\n /** Available labels (default: ['positive', 'negative', 'neutral']) */\n labels?: string[];\n\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n\n /** Default label to return */\n defaultLabel?: string;\n\n /** Default score (default: 0.9) */\n defaultScore?: number;\n}\n\n/**\n * Mock classification model interface.\n */\nexport interface MockClassificationModel {\n modelId: string;\n provider: string;\n labels: string[];\n\n doClassify(options: { texts: string[]; abortSignal?: AbortSignal }): Promise<{\n results: Array<{\n label: string;\n score: number;\n allScores?: Record<string, number>;\n }>;\n usage: { inputTokens: number; durationMs: number };\n }>;\n}\n\n/**\n * Create a mock classification model for testing.\n *\n * @param options - Configuration options\n * @returns Mock classification model\n */\nexport function createMockClassificationModel(\n options: MockClassificationModelOptions = {}\n): MockClassificationModel {\n const {\n labels = ['positive', 'negative', 'neutral'],\n delay = 0,\n defaultLabel,\n defaultScore = 0.9,\n } = options;\n\n return {\n modelId: 'mock:classifier',\n provider: 'mock',\n labels,\n\n async doClassify({ texts, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n\n const results = texts.map((text) => {\n // Simple heuristic for testing\n const lower = text.toLowerCase();\n let label = defaultLabel;\n let score = defaultScore;\n\n if (!label) {\n if (lower.includes('great') || lower.includes('good') || lower.includes('love')) {\n label = 'positive';\n score = 0.95;\n } else if (\n lower.includes('bad') ||\n lower.includes('terrible') ||\n lower.includes('hate')\n ) {\n label = 'negative';\n score = 0.92;\n } else {\n label = 'neutral';\n score = 0.88;\n }\n }\n\n // Generate all scores\n const allScores: Record<string, number> = {};\n labels.forEach((l) => {\n allScores[l] = l === label ? score : (1 - score) / (labels.length - 1);\n });\n\n return { label: label!, score, allScores };\n });\n\n return {\n results,\n usage: {\n inputTokens: texts.reduce((sum, t) => sum + t.split(/\\s+/).length, 0),\n durationMs: performance.now() - startTime,\n },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock NER Model\n// ============================================================================\n\n/**\n * Options for creating a mock NER model.\n */\nexport interface MockNERModelOptions {\n /** Entity types to detect (default: ['PERSON', 'ORG', 'LOC', 'DATE']) */\n entityTypes?: string[];\n\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n}\n\n// Re-export Entity from classification (canonical source)\nexport type { Entity } from '../classification/types.js';\n\n/**\n * Mock NER model interface.\n */\nexport interface MockNERModel {\n modelId: string;\n provider: string;\n entityTypes: string[];\n\n doExtract(options: { texts: string[]; abortSignal?: AbortSignal }): Promise<{\n results: Array<{ entities: Entity[] }>;\n usage: { inputTokens: number; durationMs: number };\n }>;\n}\n\n/**\n * Create a mock NER model for testing.\n *\n * @param options - Configuration options\n * @returns Mock NER model\n */\nexport function createMockNERModel(options: MockNERModelOptions = {}): MockNERModel {\n const { entityTypes = ['PERSON', 'ORG', 'LOC', 'DATE'], delay = 0 } = options;\n\n // Simple patterns for mock extraction\n const patterns: Record<string, RegExp> = {\n PERSON: /\\b(John|Jane|Bob|Alice|Mike|Sarah)\\b/gi,\n ORG: /\\b(Microsoft|Google|Apple|Amazon|OpenAI|Meta)\\b/gi,\n LOC: /\\b(Seattle|New York|London|Paris|Tokyo|Berlin)\\b/gi,\n DATE: /\\b(\\d{4}|\\d{1,2}\\/\\d{1,2}\\/\\d{2,4}|January|February|March|April|May|June|July|August|September|October|November|December)\\b/gi,\n };\n\n return {\n modelId: 'mock:ner',\n provider: 'mock',\n entityTypes,\n\n async doExtract({ texts, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n\n const results = texts.map((text) => {\n const entities: Entity[] = [];\n\n for (const type of entityTypes) {\n const pattern = patterns[type];\n if (!pattern) continue;\n\n let match;\n pattern.lastIndex = 0; // Reset regex state\n while ((match = pattern.exec(text)) !== null) {\n entities.push({\n text: match[0],\n type,\n start: match.index,\n end: match.index + match[0].length,\n score: 0.95,\n });\n }\n }\n\n // Sort by start position\n entities.sort((a, b) => a.start - b.start);\n\n return { entities };\n });\n\n return {\n results,\n usage: {\n inputTokens: texts.reduce((sum, t) => sum + t.split(/\\s+/).length, 0),\n durationMs: performance.now() - startTime,\n },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock Speech-to-Text Model\n// ============================================================================\n\n/**\n * Options for creating a mock speech-to-text model.\n */\nexport interface MockSpeechToTextModelOptions {\n /** Languages supported (default: ['en']) */\n languages?: string[];\n\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n\n /** Text to return */\n mockText?: string;\n}\n\n/**\n * Mock speech-to-text model interface.\n */\nexport interface MockSpeechToTextModel {\n modelId: string;\n provider: string;\n languages: string[];\n\n doTranscribe(options: {\n audio: Blob | ArrayBuffer | Float32Array;\n language?: string;\n task?: 'transcribe' | 'translate';\n returnTimestamps?: boolean;\n abortSignal?: AbortSignal;\n }): Promise<{\n text: string;\n segments?: Array<{ start: number; end: number; text: string }>;\n language?: string;\n usage: { audioDurationSec: number; durationMs: number };\n }>;\n}\n\n/**\n * Create a mock speech-to-text model for testing.\n *\n * @param options - Configuration options\n * @returns Mock speech-to-text model\n */\nexport function createMockSpeechToTextModel(\n options: MockSpeechToTextModelOptions = {}\n): MockSpeechToTextModel {\n const { languages = ['en'], delay = 0, mockText = 'This is a test transcription.' } = options;\n\n return {\n modelId: 'mock:whisper',\n provider: 'mock',\n languages,\n\n async doTranscribe({ audio, language = 'en', returnTimestamps = false, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n\n // Estimate audio duration from size\n let audioSize = 0;\n if (audio instanceof Blob) {\n audioSize = audio.size;\n } else if (audio instanceof ArrayBuffer) {\n audioSize = audio.byteLength;\n } else if (audio instanceof Float32Array) {\n audioSize = audio.byteLength;\n }\n\n // Rough estimate: 16kHz mono = 32KB/second\n const audioDurationSec = Math.max(1, audioSize / 32000);\n\n const result: Awaited<ReturnType<MockSpeechToTextModel['doTranscribe']>> = {\n text: mockText,\n language,\n usage: {\n audioDurationSec,\n durationMs: performance.now() - startTime,\n },\n };\n\n if (returnTimestamps) {\n const words = mockText.split(' ');\n const segmentDuration = audioDurationSec / words.length;\n result.segments = words.map((word, i) => ({\n start: i * segmentDuration,\n end: (i + 1) * segmentDuration,\n text: word,\n }));\n }\n\n return result;\n },\n };\n}\n\n// ============================================================================\n// Mock Storage\n// ============================================================================\n\n/**\n * Simple mock storage interface for testing.\n * This is a simplified version that doesn't require the full Storage implementation.\n */\nexport interface SimpleMockStorage {\n get(key: string): Promise<StoredDocument | undefined>;\n set(key: string, value: StoredDocument): Promise<void>;\n delete(key: string): Promise<void>;\n keys(): Promise<string[]>;\n clear(): Promise<void>;\n close(): Promise<void>;\n readonly size: number;\n getData(): Map<string, StoredDocument>;\n}\n\n/**\n * Create a mock storage for testing.\n *\n * @returns Simple mock storage instance\n *\n * @example\n * ```typescript\n * import { createMockStorage } from '@localmode/core';\n *\n * const storage = createMockStorage();\n * await storage.set('key', { id: 'doc1', ... });\n * const doc = await storage.get('key');\n * ```\n */\nexport function createMockStorage(): SimpleMockStorage {\n const data = new Map<string, StoredDocument>();\n\n return {\n async get(key: string): Promise<StoredDocument | undefined> {\n return data.get(key);\n },\n\n async set(key: string, value: StoredDocument): Promise<void> {\n data.set(key, value);\n },\n\n async delete(key: string): Promise<void> {\n data.delete(key);\n },\n\n async keys(): Promise<string[]> {\n return Array.from(data.keys());\n },\n\n async clear(): Promise<void> {\n data.clear();\n },\n\n async close(): Promise<void> {\n data.clear();\n },\n\n get size() {\n return data.size;\n },\n\n getData() {\n return new Map(data);\n },\n };\n}\n\n// ============================================================================\n// Mock VectorDB\n// ============================================================================\n\n/**\n * Options for creating a mock VectorDB.\n */\nexport interface MockVectorDBOptions {\n /** Database name (default: 'mock-db') */\n name?: string;\n\n /** Number of dimensions (default: 384) */\n dimensions?: number;\n\n /** Delay in milliseconds for operations (default: 0) */\n delay?: number;\n}\n\n/**\n * Simplified mock VectorDB interface for testing.\n * This doesn't implement the full VectorDB interface but provides\n * the most commonly used methods for testing.\n */\nexport interface SimpleMockVectorDB {\n readonly name: string;\n readonly dimensions: number;\n readonly documents: Map<string, Document>;\n add(doc: Document): Promise<void>;\n addMany(docs: Document[]): Promise<void>;\n get(id: string): Promise<Document | null>;\n getMany(ids: string[]): Promise<(Document | null)[]>;\n update(id: string, updates: Partial<Omit<Document, 'id' | 'vector'>>): Promise<void>;\n delete(id: string): Promise<void>;\n deleteMany(ids: string[]): Promise<void>;\n search(queryVector: Float32Array, options?: SearchOptions): Promise<SearchResult[]>;\n count(): Promise<number>;\n clear(): Promise<void>;\n close(): Promise<void>;\n}\n\n/**\n * Create a mock VectorDB for testing.\n *\n * @param options - Configuration options\n * @returns Mock VectorDB instance\n */\nexport function createMockVectorDB(options: MockVectorDBOptions = {}): SimpleMockVectorDB {\n const { name = 'mock-db', dimensions = 384, delay = 0 } = options;\n\n const documents = new Map<string, Document>();\n\n async function maybeDelay(): Promise<void> {\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n return {\n name,\n dimensions,\n documents,\n\n async add(doc: Document): Promise<void> {\n await maybeDelay();\n documents.set(doc.id, { ...doc });\n },\n\n async addMany(docs: Document[]): Promise<void> {\n await maybeDelay();\n for (const doc of docs) {\n documents.set(doc.id, { ...doc });\n }\n },\n\n async get(id: string): Promise<Document | null> {\n await maybeDelay();\n return documents.get(id) ?? null;\n },\n\n async getMany(ids: string[]): Promise<(Document | null)[]> {\n await maybeDelay();\n return ids.map((id) => documents.get(id) ?? null);\n },\n\n async update(id: string, updates: Partial<Omit<Document, 'id' | 'vector'>>): Promise<void> {\n await maybeDelay();\n const doc = documents.get(id);\n if (doc) {\n documents.set(id, { ...doc, ...updates });\n }\n },\n\n async delete(id: string): Promise<void> {\n await maybeDelay();\n documents.delete(id);\n },\n\n async deleteMany(ids: string[]): Promise<void> {\n await maybeDelay();\n for (const id of ids) {\n documents.delete(id);\n }\n },\n\n async search(queryVector: Float32Array, options: SearchOptions = {}): Promise<SearchResult[]> {\n await maybeDelay();\n const { k = 10, threshold = 0 } = options;\n\n const results: SearchResult[] = [];\n\n for (const doc of documents.values()) {\n // Apply filter if provided\n if (options.filter && !matchesFilter(doc, options.filter)) {\n continue;\n }\n\n // Calculate cosine similarity\n const score = cosineSimilarity(queryVector, doc.vector);\n\n if (score >= threshold) {\n results.push({\n id: doc.id,\n score,\n vector: doc.vector,\n metadata: doc.metadata,\n });\n }\n }\n\n // Sort by score and limit\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, k);\n },\n\n async count(): Promise<number> {\n return documents.size;\n },\n\n async clear(): Promise<void> {\n await maybeDelay();\n documents.clear();\n },\n\n async close(): Promise<void> {\n documents.clear();\n },\n };\n}\n\n/**\n * Calculate cosine similarity between two vectors.\n */\nfunction cosineSimilarity(a: Float32Array, b: Float32Array): number {\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n\n const magnitude = Math.sqrt(normA) * Math.sqrt(normB);\n if (magnitude === 0) return 0;\n\n return dotProduct / magnitude;\n}\n\n/**\n * Check if document matches filter.\n */\nfunction matchesFilter(doc: Document, filter: Record<string, unknown>): boolean {\n for (const [key, value] of Object.entries(filter)) {\n const docValue = doc.metadata?.[key];\n\n if (typeof value === 'object' && value !== null) {\n // Handle operators\n for (const [op, opValue] of Object.entries(value)) {\n switch (op) {\n case '$eq':\n if (docValue !== opValue) return false;\n break;\n case '$ne':\n if (docValue === opValue) return false;\n break;\n case '$gt':\n if (!((docValue as number) > (opValue as number))) return false;\n break;\n case '$gte':\n if (!((docValue as number) >= (opValue as number))) return false;\n break;\n case '$lt':\n if (!((docValue as number) < (opValue as number))) return false;\n break;\n case '$lte':\n if (!((docValue as number) <= (opValue as number))) return false;\n break;\n case '$in':\n if (!Array.isArray(opValue) || !opValue.includes(docValue)) return false;\n break;\n case '$nin':\n if (!Array.isArray(opValue) || opValue.includes(docValue)) return false;\n break;\n default:\n // Unknown operator, skip\n break;\n }\n }\n } else {\n // Direct equality\n if (docValue !== value) return false;\n }\n }\n\n return true;\n}\n\n// ============================================================================\n// Mock Image Caption Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock image caption model.\n */\nexport interface MockImageCaptionModelOptions {\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n\n /** Caption to return */\n mockCaption?: string;\n}\n\n/**\n * Mock image caption model interface.\n */\nexport interface MockImageCaptionModel {\n modelId: string;\n provider: string;\n\n doCaption(options: {\n images: Array<Blob | ImageData | string>;\n maxLength?: number;\n abortSignal?: AbortSignal;\n }): Promise<{\n captions: string[];\n usage: { durationMs: number };\n }>;\n}\n\n/**\n * Create a mock image caption model for testing.\n */\nexport function createMockImageCaptionModel(\n options: MockImageCaptionModelOptions = {}\n): MockImageCaptionModel {\n const { delay = 0, mockCaption = 'A photo showing test content.' } = options;\n\n return {\n modelId: 'mock:image-caption',\n provider: 'mock',\n\n async doCaption({ images, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n return {\n captions: images.map(() => mockCaption),\n usage: { durationMs: performance.now() - startTime },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock Segmentation Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock segmentation model.\n */\nexport interface MockSegmentationModelOptions {\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n}\n\n/**\n * Mock segmentation model interface.\n */\nexport interface MockSegmentationModel {\n modelId: string;\n provider: string;\n segmentationType: 'semantic' | 'instance' | 'panoptic';\n\n doSegment(options: {\n images: Array<Blob | ImageData | string>;\n abortSignal?: AbortSignal;\n providerOptions?: Record<string, Record<string, unknown>>;\n }): Promise<{\n results: Array<{\n masks: Array<{\n label: string;\n mask: ImageData | Uint8Array;\n score: number;\n }>;\n }>;\n usage: { durationMs: number };\n }>;\n}\n\n/**\n * Create a mock segmentation model for testing.\n */\nexport function createMockSegmentationModel(\n options: MockSegmentationModelOptions = {}\n): MockSegmentationModel {\n const { delay = 0 } = options;\n\n return {\n modelId: 'mock:segmentation',\n provider: 'mock',\n segmentationType: 'semantic',\n\n async doSegment({ images, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n return {\n results: images.map(() => ({\n masks: [\n { label: 'background', mask: new Uint8Array(100), score: 0.98 },\n { label: 'object', mask: new Uint8Array(100), score: 0.95 },\n ],\n })),\n usage: { durationMs: performance.now() - startTime },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock Object Detection Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock object detection model.\n */\nexport interface MockObjectDetectionModelOptions {\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n}\n\n/**\n * Mock object detection model interface.\n */\nexport interface MockObjectDetectionModel {\n modelId: string;\n provider: string;\n\n doDetect(options: {\n images: Array<Blob | ImageData | string>;\n threshold?: number;\n abortSignal?: AbortSignal;\n }): Promise<{\n results: Array<{\n objects: Array<{\n label: string;\n score: number;\n box: { x: number; y: number; width: number; height: number };\n }>;\n }>;\n usage: { imageCount: number; durationMs: number };\n }>;\n}\n\n/**\n * Create a mock object detection model for testing.\n */\nexport function createMockObjectDetectionModel(\n options: MockObjectDetectionModelOptions = {}\n): MockObjectDetectionModel {\n const { delay = 0 } = options;\n\n return {\n modelId: 'mock:object-detection',\n provider: 'mock',\n\n async doDetect({ images, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n return {\n results: images.map(() => ({\n objects: [\n { label: 'person', score: 0.95, box: { x: 10, y: 20, width: 100, height: 200 } },\n { label: 'dog', score: 0.88, box: { x: 150, y: 100, width: 80, height: 60 } },\n ],\n })),\n usage: { imageCount: images.length, durationMs: performance.now() - startTime },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock Image Feature Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock image feature model.\n */\nexport interface MockImageFeatureModelOptions {\n /** Feature dimensions (default: 512) */\n dimensions?: number;\n\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n\n /** Seed for deterministic features */\n seed?: number;\n}\n\n/**\n * Mock image feature model interface.\n */\nexport interface MockImageFeatureModel {\n modelId: string;\n provider: string;\n dimensions: number;\n\n doExtract(options: {\n images: Array<Blob | ImageData | string>;\n abortSignal?: AbortSignal;\n }): Promise<{\n features: Float32Array[];\n usage: { imageCount: number; durationMs: number };\n }>;\n}\n\n/**\n * Create a mock image feature model for testing.\n */\nexport function createMockImageFeatureModel(\n options: MockImageFeatureModelOptions = {}\n): MockImageFeatureModel {\n const { dimensions = 512, delay = 0, seed = 42 } = options;\n\n return {\n modelId: 'mock:image-feature',\n provider: 'mock',\n dimensions,\n\n async doExtract({ images, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n return {\n features: images.map((_, i) => createTestVector(dimensions, seed + i)),\n usage: { imageCount: images.length, durationMs: performance.now() - startTime },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock Image-to-Image Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock image-to-image model.\n */\nexport interface MockImageToImageModelOptions {\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n\n /** Task type (default: 'upscale') */\n taskType?: 'upscale' | 'style-transfer' | 'inpainting' | 'outpainting' | 'super-resolution';\n}\n\n/**\n * Mock image-to-image model interface.\n */\nexport interface MockImageToImageModel {\n modelId: string;\n provider: string;\n taskType: string;\n\n doTransform(options: {\n images: Array<Blob | ImageData | string>;\n prompt?: string;\n abortSignal?: AbortSignal;\n }): Promise<{\n images: Blob[];\n usage: { imageCount: number; durationMs: number };\n }>;\n}\n\n/**\n * Create a mock image-to-image model for testing.\n */\nexport function createMockImageToImageModel(\n options: MockImageToImageModelOptions = {}\n): MockImageToImageModel {\n const { delay = 0, taskType = 'upscale' } = options;\n\n return {\n modelId: 'mock:image-to-image',\n provider: 'mock',\n taskType,\n\n async doTransform({ images, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n // Return a simple blob for each input image\n return {\n images: images.map(() => new Blob(['mock image data'], { type: 'image/png' })),\n usage: { imageCount: images.length, durationMs: performance.now() - startTime },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock Text-to-Speech Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock text-to-speech model.\n */\nexport interface MockTextToSpeechModelOptions {\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n\n /** Sample rate (default: 16000) */\n sampleRate?: number;\n}\n\n/**\n * Mock text-to-speech model interface.\n */\nexport interface MockTextToSpeechModel {\n modelId: string;\n provider: string;\n sampleRate: number;\n\n doSynthesize(options: {\n text: string;\n voice?: string;\n speed?: number;\n pitch?: number;\n abortSignal?: AbortSignal;\n providerOptions?: Record<string, Record<string, unknown>>;\n }): Promise<{\n audio: Blob;\n sampleRate: number;\n usage: { characterCount: number; durationMs: number };\n }>;\n}\n\n/**\n * Create a mock text-to-speech model for testing.\n */\nexport function createMockTextToSpeechModel(\n options: MockTextToSpeechModelOptions = {}\n): MockTextToSpeechModel {\n const { delay = 0, sampleRate = 16000 } = options;\n\n return {\n modelId: 'mock:tts',\n provider: 'mock',\n sampleRate,\n\n async doSynthesize({ text, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n // Generate ~1 second of audio per 10 characters\n const durationSec = Math.max(0.5, text.length / 10);\n const numSamples = Math.floor(sampleRate * durationSec);\n\n // Create silent audio (zeros) as Float32Array then convert to Blob\n const audioData = new Float32Array(numSamples);\n const audio = new Blob([audioData.buffer], { type: 'audio/wav' });\n\n return {\n audio,\n sampleRate,\n usage: { characterCount: text.length, durationMs: performance.now() - startTime },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock Language Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock language model.\n */\nexport interface MockLanguageModelOptions {\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n\n /** Text to generate */\n mockResponse?: string;\n\n /** Context length (default: 4096) */\n contextLength?: number;\n}\n\n/**\n * Mock language model interface.\n */\nexport interface MockLanguageModel {\n modelId: string;\n provider: string;\n contextLength: number;\n\n doGenerate(options: {\n prompt: string;\n systemPrompt?: string;\n maxTokens?: number;\n temperature?: number;\n topP?: number;\n stopSequences?: string[];\n abortSignal?: AbortSignal;\n providerOptions?: Record<string, Record<string, unknown>>;\n }): Promise<{\n text: string;\n finishReason: 'stop' | 'length' | 'content_filter' | 'error';\n usage: { inputTokens: number; outputTokens: number; totalTokens: number; durationMs: number };\n }>;\n\n doStream?(options: {\n prompt: string;\n systemPrompt?: string;\n maxTokens?: number;\n temperature?: number;\n topP?: number;\n stopSequences?: string[];\n abortSignal?: AbortSignal;\n providerOptions?: Record<string, Record<string, unknown>>;\n }): AsyncIterable<{\n text: string;\n done: boolean;\n finishReason?: 'stop' | 'length' | 'content_filter' | 'error';\n usage?: { inputTokens: number; outputTokens: number; totalTokens: number; durationMs: number };\n }>;\n}\n\n/**\n * Create a mock language model for testing.\n */\nexport function createMockLanguageModel(options: MockLanguageModelOptions = {}): MockLanguageModel {\n const { delay = 0, mockResponse = 'This is a mock response.', contextLength = 4096 } = options;\n\n return {\n modelId: 'mock:llm',\n provider: 'mock',\n contextLength,\n\n async doGenerate({ prompt, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n const inputTokens = prompt.split(/\\s+/).length;\n const outputTokens = mockResponse.split(/\\s+/).length;\n\n return {\n text: mockResponse,\n finishReason: 'stop' as const,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n durationMs: performance.now() - startTime,\n },\n };\n },\n\n async *doStream({ prompt, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n const startTime = performance.now();\n const inputTokens = prompt.split(/\\s+/).length;\n const tokens = mockResponse.split(' ');\n\n for (let i = 0; i < tokens.length; i++) {\n abortSignal?.throwIfAborted?.();\n const tokenText = (i > 0 ? ' ' : '') + tokens[i];\n const isLast = i === tokens.length - 1;\n\n yield {\n text: tokenText,\n done: isLast,\n finishReason: isLast ? ('stop' as const) : undefined,\n usage: isLast\n ? {\n inputTokens,\n outputTokens: tokens.length,\n totalTokens: inputTokens + tokens.length,\n durationMs: performance.now() - startTime,\n }\n : undefined,\n };\n }\n },\n };\n}\n\n// ============================================================================\n// Mock Translation Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock translation model.\n */\nexport interface MockTranslationModelOptions {\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n\n /** Mock translation prefix (default: '[translated]') */\n translationPrefix?: string;\n}\n\n/**\n * Mock translation model interface.\n */\nexport interface MockTranslationModel {\n modelId: string;\n provider: string;\n\n doTranslate(options: {\n texts: string[];\n sourceLanguage?: string;\n targetLanguage?: string;\n abortSignal?: AbortSignal;\n providerOptions?: Record<string, Record<string, unknown>>;\n }): Promise<{\n translations: string[];\n detectedLanguage?: string;\n usage: { inputTokens: number; outputTokens: number; durationMs: number };\n }>;\n}\n\n/**\n * Create a mock translation model for testing.\n */\nexport function createMockTranslationModel(\n options: MockTranslationModelOptions = {}\n): MockTranslationModel {\n const { delay = 0, translationPrefix = '[translated]' } = options;\n\n return {\n modelId: 'mock:translation',\n provider: 'mock',\n\n async doTranslate({ texts, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n const translations = texts.map((text) => `${translationPrefix} ${text}`);\n const inputTokens = texts.join(' ').split(/\\s+/).length;\n const outputTokens = translations.join(' ').split(/\\s+/).length;\n\n return {\n translations,\n usage: {\n inputTokens,\n outputTokens,\n durationMs: performance.now() - startTime,\n },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock Summarization Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock summarization model.\n */\nexport interface MockSummarizationModelOptions {\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n\n /** Mock summary (default: takes first sentence) */\n mockSummary?: string;\n}\n\n/**\n * Mock summarization model interface.\n */\nexport interface MockSummarizationModel {\n modelId: string;\n provider: string;\n\n doSummarize(options: {\n texts: string[];\n maxLength?: number;\n minLength?: number;\n mode?: 'extractive' | 'abstractive';\n abortSignal?: AbortSignal;\n providerOptions?: Record<string, Record<string, unknown>>;\n }): Promise<{\n summaries: string[];\n usage: { inputTokens: number; outputTokens: number; durationMs: number };\n }>;\n}\n\n/**\n * Create a mock summarization model for testing.\n */\nexport function createMockSummarizationModel(\n options: MockSummarizationModelOptions = {}\n): MockSummarizationModel {\n const { delay = 0, mockSummary } = options;\n\n return {\n modelId: 'mock:summarization',\n provider: 'mock',\n\n async doSummarize({ texts, maxLength, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n const summaries: string[] = [];\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n\n for (const text of texts) {\n // Default: take first sentence or truncate\n let summaryText = mockSummary;\n if (!summaryText) {\n const firstSentence = text.split(/[.!?]/)[0] + '.';\n summaryText =\n maxLength && firstSentence.length > maxLength\n ? firstSentence.substring(0, maxLength) + '...'\n : firstSentence;\n }\n\n summaries.push(summaryText);\n totalInputTokens += text.split(/\\s+/).length;\n totalOutputTokens += summaryText.split(/\\s+/).length;\n }\n\n return {\n summaries,\n usage: {\n inputTokens: totalInputTokens,\n outputTokens: totalOutputTokens,\n durationMs: performance.now() - startTime,\n },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock Fill-Mask Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock fill-mask model.\n */\nexport interface MockFillMaskModelOptions {\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n\n /** Mock predictions */\n mockPredictions?: Array<{ token: string; score: number }>;\n}\n\n/**\n * Mock fill-mask model interface.\n */\nexport interface MockFillMaskModel {\n modelId: string;\n provider: string;\n\n doFillMask(options: {\n texts: string[];\n topK?: number;\n abortSignal?: AbortSignal;\n providerOptions?: Record<string, Record<string, unknown>>;\n }): Promise<{\n results: Array<Array<{ token: string; score: number; sequence: string }>>;\n usage: { inputTokens: number; durationMs: number };\n }>;\n}\n\n/**\n * Create a mock fill-mask model for testing.\n */\nexport function createMockFillMaskModel(options: MockFillMaskModelOptions = {}): MockFillMaskModel {\n const {\n delay = 0,\n mockPredictions = [\n { token: 'great', score: 0.85 },\n { token: 'wonderful', score: 0.1 },\n { token: 'fantastic', score: 0.05 },\n ],\n } = options;\n\n return {\n modelId: 'mock:fill-mask',\n provider: 'mock',\n\n async doFillMask({ texts, topK = 5, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n const inputTokens = texts.join(' ').split(/\\s+/).length;\n const predictions = mockPredictions.slice(0, topK).map((p) => ({\n ...p,\n sequence: texts[0]?.replace('[MASK]', p.token) || p.token,\n }));\n\n return {\n results: texts.map(() => predictions),\n usage: {\n inputTokens,\n durationMs: performance.now() - startTime,\n },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock Question Answering Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock question answering model.\n */\nexport interface MockQuestionAnsweringModelOptions {\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n}\n\n/**\n * Mock question answering model interface.\n */\nexport interface MockQuestionAnsweringModel {\n modelId: string;\n provider: string;\n maxContextLength?: number;\n\n doAnswer(options: {\n questions: Array<{ question: string; context: string }>;\n topK?: number;\n abortSignal?: AbortSignal;\n providerOptions?: Record<string, Record<string, unknown>>;\n }): Promise<{\n results: Array<Array<{ answer: string; score: number; start: number; end: number }>>;\n usage: { inputTokens: number; durationMs: number };\n }>;\n}\n\n/**\n * Create a mock question answering model for testing.\n */\nexport function createMockQuestionAnsweringModel(\n options: MockQuestionAnsweringModelOptions = {}\n): MockQuestionAnsweringModel {\n const { delay = 0 } = options;\n\n return {\n modelId: 'mock:qa',\n provider: 'mock',\n maxContextLength: 512,\n\n async doAnswer({ questions, topK = 1, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n const results: Array<Array<{ answer: string; score: number; start: number; end: number }>> =\n [];\n let totalInputTokens = 0;\n\n for (const { question, context } of questions) {\n // Find a substring that might answer the question\n const words = context.split(/\\s+/);\n const answer = words.slice(0, Math.min(10, words.length)).join(' ');\n const start = 0;\n const end = answer.length;\n\n totalInputTokens += question.split(/\\s+/).length + context.split(/\\s+/).length;\n\n results.push([{ answer, score: 0.92, start, end }].slice(0, topK));\n }\n\n return {\n results,\n usage: {\n inputTokens: totalInputTokens,\n durationMs: performance.now() - startTime,\n },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock OCR Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock OCR model.\n */\nexport interface MockOCRModelOptions {\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n\n /** Mock extracted text */\n mockText?: string;\n}\n\n/**\n * Mock OCR model interface.\n */\nexport interface MockOCRModel {\n modelId: string;\n provider: string;\n supportedLanguages?: string[];\n\n doOCR(options: {\n images: Array<Blob | ImageData | string>;\n languages?: string[];\n detectRegions?: boolean;\n abortSignal?: AbortSignal;\n providerOptions?: Record<string, Record<string, unknown>>;\n }): Promise<{\n texts: string[];\n regions?: Array<\n Array<{\n text: string;\n confidence: number;\n bbox?: { x: number; y: number; width: number; height: number };\n }>\n >;\n usage: { durationMs: number };\n }>;\n}\n\n/**\n * Create a mock OCR model for testing.\n */\nexport function createMockOCRModel(options: MockOCRModelOptions = {}): MockOCRModel {\n const { delay = 0, mockText = 'Sample extracted text from image.' } = options;\n\n return {\n modelId: 'mock:ocr',\n provider: 'mock',\n supportedLanguages: ['en', 'es', 'fr', 'de'],\n\n async doOCR({ images, detectRegions, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n const texts = images.map(() => mockText);\n const regions = detectRegions\n ? images.map(() => [\n { text: mockText, confidence: 0.95, bbox: { x: 10, y: 10, width: 200, height: 30 } },\n ])\n : undefined;\n\n return {\n texts,\n regions,\n usage: { durationMs: performance.now() - startTime },\n };\n },\n };\n}\n\n// ============================================================================\n// Mock Document QA Model (P2)\n// ============================================================================\n\n/**\n * Options for creating a mock document QA model.\n */\nexport interface MockDocumentQAModelOptions {\n /** Delay in milliseconds (default: 0) */\n delay?: number;\n}\n\n/**\n * Mock document QA model interface.\n */\nexport interface MockDocumentQAModel {\n modelId: string;\n provider: string;\n\n doAskDocument(options: {\n document: Blob | ImageData | string;\n questions: string[];\n abortSignal?: AbortSignal;\n providerOptions?: Record<string, Record<string, unknown>>;\n }): Promise<{\n answers: Array<{ answer: string; score: number }>;\n usage: { durationMs: number };\n }>;\n\n doAskTable(options: {\n table: { headers: string[]; rows: string[][] };\n questions: string[];\n abortSignal?: AbortSignal;\n providerOptions?: Record<string, Record<string, unknown>>;\n }): Promise<{\n answers: Array<{ answer: string; score: number; cells?: string[]; aggregator?: string }>;\n usage: { durationMs: number };\n }>;\n}\n\n/**\n * Create a mock document QA model for testing.\n */\nexport function createMockDocumentQAModel(\n options: MockDocumentQAModelOptions = {}\n): MockDocumentQAModel {\n const { delay = 0 } = options;\n\n return {\n modelId: 'mock:document-qa',\n provider: 'mock',\n\n async doAskDocument({ questions, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n\n return {\n answers: questions.map(() => ({ answer: 'Mock answer from document.', score: 0.88 })),\n usage: {\n durationMs: performance.now() - startTime,\n },\n };\n },\n\n async doAskTable({ questions, abortSignal }) {\n abortSignal?.throwIfAborted?.();\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n abortSignal?.throwIfAborted?.();\n }\n\n const startTime = performance.now();\n return {\n answers: questions.map(() => ({\n answer: 'Mock answer from table.',\n score: 0.9,\n cells: ['10'],\n aggregator: 'SUM',\n })),\n usage: {\n durationMs: performance.now() - startTime,\n },\n };\n },\n };\n}\n\n// ============================================================================\n// Test Helpers\n// ============================================================================\n\n/**\n * Wait for a condition to be true.\n *\n * @param condition - Function that returns true when condition is met\n * @param timeout - Maximum time to wait in milliseconds (default: 5000)\n * @param interval - Check interval in milliseconds (default: 50)\n * @returns Promise that resolves when condition is met\n */\nexport async function waitFor(\n condition: () => boolean | Promise<boolean>,\n timeout: number = 5000,\n interval: number = 50\n): Promise<void> {\n const start = Date.now();\n\n while (Date.now() - start < timeout) {\n if (await condition()) {\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n\n throw new Error(`waitFor timed out after ${timeout}ms`);\n}\n\n/**\n * Create a deferred promise for testing.\n *\n * @returns Object with promise and resolve/reject functions\n */\nexport function createDeferred<T = void>(): {\n promise: Promise<T>;\n resolve: (value: T) => void;\n reject: (error: Error) => void;\n} {\n let resolve!: (value: T) => void;\n let reject!: (error: Error) => void;\n\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n return { promise, resolve, reject };\n}\n\n/**\n * Create a spy function for testing.\n *\n * @returns Spy function with call tracking\n */\nexport function createSpy<T extends (...args: unknown[]) => unknown>(): T & {\n calls: Parameters<T>[];\n callCount: number;\n reset: () => void;\n} {\n const calls: Parameters<T>[] = [];\n\n const spy = ((...args: Parameters<T>) => {\n calls.push(args);\n }) as T & {\n calls: Parameters<T>[];\n callCount: number;\n reset: () => void;\n };\n\n Object.defineProperty(spy, 'calls', { get: () => calls });\n Object.defineProperty(spy, 'callCount', { get: () => calls.length });\n spy.reset = () => {\n calls.length = 0;\n };\n\n return spy;\n}\n"]}
|