UNPKG

mcard-js

Version:

MCard - Content-addressable storage with cryptographic hashing, handle resolution, and vector search for Node.js and browsers

253 lines 9.13 kB
/** * Semantic Versioning API for MCards * * High-level API functions for managing MCard versions linked to handles * with semantic similarity detection. * * This module provides a simplified interface for: * - Linking MCards to handles * - Retrieving version history with semantic info * - Comparing versions by semantic similarity * - Searching within a handle's version history * * @module mcard-js/rag/semanticVersioning */ import { HandleVectorStore } from './HandleVectorStore'; // Default store instance (lazy-initialized) let _defaultStore = null; /** * Get the default HandleVectorStore instance. * * @param dbPath Path to SQLite database (undefined = in-memory) * @param config RAG configuration * @param reinitialize Force re-initialization of the store * @returns HandleVectorStore instance */ export function getStore(dbPath, config, reinitialize = false) { if (_defaultStore === null || reinitialize) { _defaultStore = new HandleVectorStore(dbPath ?? ':memory:', config); } return _defaultStore; } /** * Reset the default store (useful for testing). */ export function resetStore() { if (_defaultStore) { _defaultStore.close(); _defaultStore = null; } } // ───────────────────────────────────────────────────────────────────────────── // Core API Functions // ───────────────────────────────────────────────────────────────────────────── /** * Link an MCard to a handle with semantic embedding. * * This function: * 1. Indexes the MCard content with vector embeddings * 2. Associates the MCard with the specified handle * 3. Computes semantic delta from previous version (if exists) * 4. Classifies the upgrade type based on similarity * * @param mcard MCard to link * @param handle Handle name (stable identifier) * @param isCurrent Whether this becomes the current version * @param store Optional custom HandleVectorStore instance * @returns True if successful, false if indexing failed * * @example * ```typescript * import { MCard } from 'mcard-js'; * import { linkMCardToHandle } from 'mcard-js/rag'; * * const doc = await MCard.create('Introduction to Machine Learning...'); * await linkMCardToHandle(doc, 'ml_intro'); * ``` */ export async function linkMCardToHandle(mcard, handle, isCurrent = true, store) { const s = store ?? getStore(); const indexed = await s.indexWithHandle(mcard, handle, isCurrent); return indexed > 0; } /** * Get version history for a handle with semantic info. * * @param handle Handle name to query * @param store Optional custom HandleVectorStore instance * @returns List of version objects with hash, order, timestamps, embedding status, and upgrade type * * @example * ```typescript * const history = getHandleVersionHistory('ml_intro'); * for (const v of history) { * console.log(`v${v.versionOrder}: ${v.hash.slice(0, 8)} (${v.upgradeType})`); * } * ``` */ export function getHandleVersionHistory(handle, store) { const s = store ?? getStore(); const versions = s.getHandleVersions(handle); return versions.map(v => ({ hash: v.hash, versionOrder: v.versionOrder, isCurrent: v.isCurrent, createdAt: v.createdAt, hasEmbedding: v.embeddingId !== undefined, parentHash: v.parentHash, semanticDelta: v.semanticDelta, upgradeType: v.upgradeType, })); } /** * Compare all versions of a handle by semantic similarity. * * This is useful for: * - Understanding how content has evolved * - Finding which version is most similar to current * - Identifying major semantic drift points * * @param handle Handle name * @param referenceHash Compare to this hash (default: current version) * @param metric 'cosine' (higher = more similar) or 'euclidean' (lower = closer) * @param store Optional custom HandleVectorStore instance * @returns Versions sorted by similarity to reference * * @example * ```typescript * const results = compareVersionsBySimilarity('ml_intro'); * for (const r of results) { * console.log(`v${r.versionOrder}: sim=${r.similarityToCurrent.toFixed(4)}`); * } * ``` */ export function compareVersionsBySimilarity(handle, referenceHash, metric = 'cosine', store) { const s = store ?? getStore(); return s.getVersionsBySimilarity(handle, referenceHash, metric); } /** * Search semantically within a handle's version history. * * Useful for finding which version of a document best matches * a specific concept, topic, or query. * * @param handle Handle name to filter by * @param query Search query text * @param k Number of results to return * @param store Optional custom HandleVectorStore instance * @returns Matching versions sorted by query similarity * * @example * ```typescript * const results = await searchWithinHandle('ml_intro', 'neural networks'); * for (const r of results) { * console.log(`v${r.versionOrder}: query_sim=${r.similarityToQuery?.toFixed(4)}`); * } * ``` */ export async function searchWithinHandle(handle, query, k = 10, store) { const s = store ?? getStore(); return s.searchHandleVersions(handle, query, k); } /** * Compute pairwise semantic distances between all versions. * * Returns a Map mapping "hash_a:hash_b" string keys to their cosine similarity scores. * * @param handle Handle name * @param cache Whether to cache computed similarities * @param store Optional custom HandleVectorStore instance * @returns Map of hash pair keys to cosine similarity [-1, 1] * * @example * ```typescript * const distances = getVersionDistances('ml_intro'); * distances.forEach((sim, key) => { * console.log(`${key}: ${sim.toFixed(4)}`); * }); * ``` */ export function getVersionDistances(handle, cache = true, store) { const s = store ?? getStore(); return s.computeVersionDistances(handle, cache); } /** * Find the version most similar to a query. * * @param handle Handle name * @param query Search query text * @param store Optional custom HandleVectorStore instance * @returns Most similar version, or undefined if no versions exist */ export async function findMostSimilarVersion(handle, query, store) { const results = await searchWithinHandle(handle, query, 1, store); return results.length > 0 ? results[0] : undefined; } /** * Get the semantic evolution of a handle's versions. * * Returns version history annotated with semantic deltas, * showing how content has evolved over time. * * @param handle Handle name * @param store Optional custom HandleVectorStore instance * @returns List of version objects with evolution info */ export function getSemanticEvolution(handle, store) { const s = store ?? getStore(); const versions = s.getHandleVersions(handle); return versions.map(v => { let interpretation; if (v.parentHash && v.semanticDelta !== undefined) { if (v.semanticDelta >= 0.95) { interpretation = 'Nearly identical to parent'; } else if (v.semanticDelta >= 0.85) { interpretation = 'Minor changes from parent'; } else if (v.semanticDelta >= 0.70) { interpretation = 'Significant changes from parent'; } else { interpretation = 'Major semantic shift from parent'; } } else { interpretation = 'Initial version (no parent)'; } return { hash: v.hash, version: v.versionOrder, isCurrent: v.isCurrent, createdAt: v.createdAt, parentHash: v.parentHash, semanticDelta: v.semanticDelta, upgradeType: v.upgradeType, interpretation, }; }); } // ───────────────────────────────────────────────────────────────────────────── // Utility Functions // ───────────────────────────────────────────────────────────────────────────── /** * List all handles with indexed versions. * * @param store Optional custom HandleVectorStore instance * @returns List of handle names */ export function listHandles(store) { const s = store ?? getStore(); return s.listHandles(); } /** * Get information about the vector store. * * @param store Optional custom HandleVectorStore instance * @returns Object with store statistics */ export function getStoreInfo(store) { const s = store ?? getStore(); return s.getInfo(); } //# sourceMappingURL=semanticVersioning.js.map