{"version":3,"file":"serialization.cjs","sources":["../../../src/core/serialization.ts"],"sourcesContent":["/**\n * Index Serialization\n * Save and load fuzzy search indices for 100x faster startup\n */\n\nimport type { FuzzyIndex } from \"./types.js\";\nimport { SearchCache } from \"./cache.js\";\n\n/**\n * Serializable index format (JSON-compatible)\n */\ninterface SerializedIndex {\n  version: string;\n  base: string[];\n  variantToBase: [string, string[]][];\n  phoneticToBase: [string, string[]][];\n  ngramIndex: [string, string[]][];\n  synonymMap: [string, string[]][];\n  config: any;\n  languageProcessorNames: string[];\n  invertedIndex?: any;\n  documents?: any[];\n}\n\n/**\n * Serialize a FuzzyIndex to JSON string\n */\nexport function serializeIndex(index: FuzzyIndex): string {\n  const serialized: SerializedIndex = {\n    version: \"1.0\",\n    base: index.base,\n    variantToBase: Array.from(index.variantToBase.entries()).map(([k, v]) => [k, Array.from(v)]),\n    phoneticToBase: Array.from(index.phoneticToBase.entries()).map(([k, v]) => [k, Array.from(v)]),\n    ngramIndex: Array.from(index.ngramIndex.entries()).map(([k, v]) => [k, Array.from(v)]),\n    synonymMap: Array.from(index.synonymMap.entries()).map(([k, v]) => [k, Array.from(v)]),\n    config: index.config,\n    languageProcessorNames: Array.from(index.languageProcessors.keys()),\n  };\n\n  // Serialize inverted index if present\n  if (index.invertedIndex) {\n    serialized.invertedIndex = {\n      termToPostings: Array.from(index.invertedIndex.termToPostings.entries()),\n      phoneticToPostings: Array.from(index.invertedIndex.phoneticToPostings.entries()),\n      ngramToPostings: Array.from(index.invertedIndex.ngramToPostings.entries()),\n      synonymToPostings: Array.from(index.invertedIndex.synonymToPostings.entries()),\n      totalDocs: index.invertedIndex.totalDocs,\n      avgDocLength: index.invertedIndex.avgDocLength,\n    };\n  }\n\n  // Serialize documents if present\n  if (index.documents) {\n    serialized.documents = index.documents;\n  }\n\n  return JSON.stringify(serialized);\n}\n\n/**\n * Deserialize a FuzzyIndex from JSON string\n */\nexport async function deserializeIndex(json: string): Promise<FuzzyIndex> {\n  const data: SerializedIndex = JSON.parse(json);\n\n  // Reconstruct Maps from arrays\n  const variantToBase = new Map(data.variantToBase.map(([k, v]) => [k, new Set(v)]));\n  const phoneticToBase = new Map(data.phoneticToBase.map(([k, v]) => [k, new Set(v)]));\n  const ngramIndex = new Map(data.ngramIndex.map(([k, v]) => [k, new Set(v)]));\n  const synonymMap = new Map(data.synonymMap.map(([k, v]) => [k, new Set(v)]));\n\n  // Reconstruct language processors (need to import them)\n  const { LanguageRegistry } = await import(\"../languages/index.js\");\n  const languageProcessors = new Map();\n  for (const langName of data.languageProcessorNames) {\n    const processor = LanguageRegistry.getProcessor(langName);\n    if (processor) {\n      languageProcessors.set(langName, processor);\n    }\n  }\n\n  const index: FuzzyIndex = {\n    base: data.base,\n    variantToBase,\n    phoneticToBase,\n    ngramIndex,\n    synonymMap,\n    languageProcessors,\n    config: data.config,\n  };\n\n  // Reconstruct inverted index if present\n  if (data.invertedIndex) {\n    index.invertedIndex = {\n      termToPostings: new Map(data.invertedIndex.termToPostings),\n      phoneticToPostings: new Map(data.invertedIndex.phoneticToPostings),\n      ngramToPostings: new Map(data.invertedIndex.ngramToPostings),\n      synonymToPostings: new Map(data.invertedIndex.synonymToPostings),\n      totalDocs: data.invertedIndex.totalDocs,\n      avgDocLength: data.invertedIndex.avgDocLength,\n    };\n  }\n\n  // Reconstruct documents if present\n  if (data.documents) {\n    index.documents = data.documents;\n  }\n\n  // Reconstruct cache if enabled in config\n  if (data.config.enableCache !== false) {\n    const cacheSize = data.config.cacheSize || 100;\n    index._cache = new SearchCache(cacheSize);\n  }\n\n  return index;\n}\n\n/**\n * Save index to localStorage (browser)\n */\nexport function saveIndexToLocalStorage(index: FuzzyIndex, key: string = \"fuzzy-search-index\"): void {\n  if (typeof localStorage === \"undefined\") {\n    throw new Error(\"localStorage is not available\");\n  }\n  const serialized = serializeIndex(index);\n  localStorage.setItem(key, serialized);\n}\n\n/**\n * Load index from localStorage (browser)\n */\nexport async function loadIndexFromLocalStorage(key: string = \"fuzzy-search-index\"): Promise<FuzzyIndex | null> {\n  if (typeof localStorage === \"undefined\") {\n    throw new Error(\"localStorage is not available\");\n  }\n  const serialized = localStorage.getItem(key);\n  if (!serialized) {\n    return null;\n  }\n  return await deserializeIndex(serialized);\n}\n\n/**\n * Get serialized index size in bytes\n */\nexport function getSerializedSize(index: FuzzyIndex): number {\n  const serialized = serializeIndex(index);\n  return new Blob([serialized]).size;\n}\n"],"names":["SearchCache"],"mappings":"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"}