{"version":3,"file":"hnswlib.mjs","names":["#opts","#lib","#collections","#ensureLib","#coll","#ensureCapacity","#project"],"sources":["../../../src/batteries/vector/hnswlib/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/hnswlib\n *\n * Embedded HNSWLib adapter (in-process, no server — like in_memory/sqlite_vec/duckdb). hnswlib is\n * a pure ANN index keyed by integer labels and holding ONLY vectors, so this adapter pairs the\n * index with a JS sidecar that owns id↔label mapping plus the document/metadata records. KNN runs\n * through the HNSW index; metadata filtering, filter-scans, projection and delete are served from\n * the sidecar via the neutral filter tree's JS reference evaluator (exact cross-adapter parity).\n *\n * Driver: `hnswlib-node` (native addon; requires the build to be approved — see\n * pnpm-workspace.yaml `allowBuilds`). Persistence is in-memory per process; pass a fresh store per\n * use. (The index supports writeIndex/readIndex on disk, but the sidecar would need its own\n * persistence — out of scope for the in-memory contract here.)\n */\n\nimport { evaluateFilter } from '../filters'\nimport { normalizeScore } from '../helpers'\nimport { BaseVectorStore } from '../contract'\nimport { validateRecords } from '../validation'\nimport { isInstanceOf } from '@nhtio/adk/guards'\nimport {\n  E_VECTOR_STORE_DRIVER_UNAVAILABLE,\n  E_VECTOR_STORE_COLLECTION_FAILED,\n  E_VECTOR_STORE_UPSERT_FAILED,\n  E_VECTOR_STORE_SEARCH_FAILED,\n  E_VECTOR_STORE_DELETE_FAILED,\n  E_VECTOR_STORE_DIMENSION_MISMATCH,\n  E_VECTOR_STORE_UNSUPPORTED_OPERATION,\n} from '../exceptions'\nimport type { SearchPlan, UpsertPlan, DeletePlan, CollectionSpec } from '../plan'\nimport type {\n  VectorMatch,\n  VectorStoreCapabilities,\n  BaseVectorStoreOptions,\n  VectorMetadata,\n  DistanceMetric,\n} from '../types'\n\nexport interface HnswlibVectorStoreOptions extends BaseVectorStoreOptions {\n  /** Initial index capacity per collection; grows automatically via `resizeIndex`. Default 1024. */\n  initialCapacity?: number\n}\n\ninterface StoredRecord {\n  id: string\n  label: number\n  vector: number[]\n  document?: string\n  metadata?: VectorMetadata\n}\n\ninterface Collection {\n  index: any\n  dims: number\n  metric: DistanceMetric\n  byId: Map<string, StoredRecord>\n  idByLabel: Map<number, string>\n  nextLabel: number\n  capacity: number\n}\n\nconst getHnswlib = async () => {\n  try {\n    const mod = await import('hnswlib-node')\n    return (mod as any).default ?? mod\n  } catch {\n    throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['hnswlib-node'])\n  }\n}\n\nconst spaceFor = (metric: DistanceMetric): string =>\n  metric === 'euclidean' ? 'l2' : metric === 'dot' ? 'ip' : 'cosine'\n\nexport class HnswlibVectorStore extends BaseVectorStore {\n  readonly capabilities: VectorStoreCapabilities = {\n    transactions: false,\n    namedVectors: false,\n    rename: true,\n    rawSql: false,\n    builtInEncoding: false,\n    // In-process and synchronous: a write is visible on resolve. The option is a no-op.\n    consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n  }\n\n  #lib: any | null = null\n  #collections: Map<string, Collection> = new Map()\n\n  get #opts(): HnswlibVectorStoreOptions {\n    return this.options as HnswlibVectorStoreOptions\n  }\n\n  /** Static availability probe: whether this adapter's runtime driver can load in the current environment. */\n  static isAvailable(): boolean {\n    return typeof process !== 'undefined'\n  }\n  isAvailable(): boolean {\n    return typeof process !== 'undefined'\n  }\n\n  async connect(): Promise<void> {\n    if (this.#lib) return\n    this.#lib = await getHnswlib()\n  }\n\n  async close(): Promise<void> {\n    this.#collections.clear()\n    this.#lib = null\n  }\n\n  async #ensureLib(): Promise<any> {\n    if (!this.#lib) await this.connect()\n    return this.#lib!\n  }\n\n  #coll(collection: string): Collection {\n    const c = this.#collections.get(collection)\n    if (!c) {\n      throw new E_VECTOR_STORE_COLLECTION_FAILED([\n        'collection',\n        'unknown collection: ' + collection,\n      ])\n    }\n    return c\n  }\n\n  async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n    const lib = await this.#ensureLib()\n    if (this.#collections.has(spec.collection)) {\n      if (ifNotExists) return\n      this.#collections.delete(spec.collection)\n    }\n    try {\n      const capacity = this.#opts.initialCapacity ?? 1024\n      const index = new lib.HierarchicalNSW(spaceFor(spec.vector.metric), spec.vector.dimensions)\n      index.initIndex(capacity)\n      this.#collections.set(spec.collection, {\n        index,\n        dims: spec.vector.dimensions,\n        metric: spec.vector.metric,\n        byId: new Map(),\n        idByLabel: new Map(),\n        nextLabel: 0,\n        capacity,\n      })\n    } catch (err) {\n      throw new E_VECTOR_STORE_COLLECTION_FAILED(['createCollection', String(err)])\n    }\n  }\n\n  async dropCollection(collection: string, ifExists: boolean): Promise<void> {\n    if (!this.#collections.has(collection)) {\n      if (ifExists) return\n      throw new E_VECTOR_STORE_COLLECTION_FAILED(['dropCollection', 'unknown collection'])\n    }\n    this.#collections.delete(collection)\n  }\n\n  async hasCollection(collection: string): Promise<boolean> {\n    return this.#collections.has(collection)\n  }\n\n  async renameCollection(from: string, to: string): Promise<void> {\n    const c = this.#collections.get(from)\n    if (!c) throw new E_VECTOR_STORE_UNSUPPORTED_OPERATION(['renameCollection', 'unknown: ' + from])\n    this.#collections.set(to, c)\n    this.#collections.delete(from)\n  }\n\n  #ensureCapacity(c: Collection, additional: number): void {\n    const needed = c.byId.size + additional\n    if (needed > c.capacity) {\n      const next = Math.max(needed, c.capacity * 2)\n      c.index.resizeIndex(next)\n      c.capacity = next\n    }\n  }\n\n  async executeUpsert(plan: UpsertPlan): Promise<void> {\n    if (plan.records.length === 0) return\n    validateRecords(plan.records)\n    await this.#ensureLib()\n    const c = this.#coll(plan.collection)\n    const expected = this.#opts.dimensions ?? c.dims\n    try {\n      this.#ensureCapacity(c, plan.records.length)\n      for (const r of plan.records) {\n        let vector = r.vector\n        if (!vector && r.document) {\n          const [v] = await this.encode([r.document], 'document')\n          vector = v\n        }\n        if (!vector) {\n          throw new E_VECTOR_STORE_UPSERT_FAILED(['Record missing vector and document'])\n        }\n        if (expected !== undefined && vector.length !== expected) {\n          throw new E_VECTOR_STORE_DIMENSION_MISMATCH([expected, vector.length])\n        }\n        // Reuse the existing label on update (mark the old point deleted, then re-add under a\n        // fresh label so the vector value actually changes — hnswlib has no in-place update).\n        const existing = c.byId.get(r.id)\n        if (existing) {\n          try {\n            c.index.markDelete(existing.label)\n          } catch {\n            // already gone — ignore\n          }\n        }\n        this.#ensureCapacity(c, 1)\n        const label = c.nextLabel++\n        c.index.addPoint(vector, label)\n        c.idByLabel.set(label, r.id)\n        c.byId.set(r.id, { id: r.id, label, vector, document: r.document, metadata: r.metadata })\n      }\n    } catch (err) {\n      if (\n        isInstanceOf(err, 'E_VECTOR_STORE_DIMENSION_MISMATCH', E_VECTOR_STORE_DIMENSION_MISMATCH) ||\n        isInstanceOf(err, 'E_VECTOR_STORE_UPSERT_FAILED', E_VECTOR_STORE_UPSERT_FAILED)\n      ) {\n        throw err\n      }\n      throw new E_VECTOR_STORE_UPSERT_FAILED([String(err)])\n    }\n  }\n\n  async executeSearch(plan: SearchPlan): Promise<VectorMatch[]> {\n    await this.#ensureLib()\n    const c = this.#coll(plan.collection)\n    const metric = this.#opts.metric ?? c.metric\n    let queryVector: number[] | undefined\n    if (plan.near) {\n      if ('vector' in plan.near) {\n        queryVector = plan.near.vector\n      } else if ('serverText' in plan.near) {\n        const [v] = await this.encode([plan.near.serverText], 'query')\n        queryVector = v\n      } else if ('id' in plan.near) {\n        const rec = c.byId.get(plan.near.id)\n        if (!rec) {\n          throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n        }\n        queryVector = rec.vector\n      }\n    }\n\n    const offset = plan.offset ?? 0\n    try {\n      if (queryVector) {\n        // Over-fetch when filtering (and to absorb deleted points), then JS-filter for parity.\n        const live = c.byId.size\n        if (live === 0) return []\n        const want = plan.filter ? live : Math.min(plan.topK + offset, live)\n        const k = Math.min(Math.max(want, 1), live)\n        const res = c.index.searchKnn(queryVector, k)\n        const hits: Array<{ rec: StoredRecord; dist: number }> = []\n        for (let i = 0; i < res.neighbors.length; i++) {\n          const id = c.idByLabel.get(res.neighbors[i])\n          if (id === undefined) continue\n          const rec = c.byId.get(id)\n          if (rec) hits.push({ rec, dist: res.distances[i] })\n        }\n        const filtered = plan.filter\n          ? hits.filter((h) => evaluateFilter(plan.filter!, h.rec.metadata ?? {}))\n          : hits\n        return filtered\n          .slice(offset, offset + plan.topK)\n          .map((h) => this.#project(h.rec, plan, metric, h.dist))\n      } else {\n        // Filter-scan: serve from the sidecar (insertion order), JS-filter, no score.\n        const rows = [...c.byId.values()]\n        const filtered = plan.filter\n          ? rows.filter((rec) => evaluateFilter(plan.filter!, rec.metadata ?? {}))\n          : rows\n        return filtered\n          .slice(offset, offset + plan.topK)\n          .map((rec) => this.#project(rec, plan, metric, undefined))\n      }\n    } catch (err) {\n      throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n    }\n  }\n\n  #project(\n    rec: StoredRecord,\n    plan: SearchPlan,\n    metric: string,\n    dist: number | undefined\n  ): VectorMatch {\n    const proj = plan.projection\n    const out: VectorMatch = {}\n    if (proj.id) out.id = rec.id\n    if (proj.vector) out.vector = rec.vector.slice()\n    if (proj.document) out.document = rec.document\n    if (proj.metadata) out.metadata = rec.metadata ?? {}\n    if (dist !== undefined) {\n      out.score = normalizeScore(dist, metric as DistanceMetric, 'distance')\n    }\n    return out\n  }\n\n  async executeDelete(plan: DeletePlan): Promise<void> {\n    await this.#ensureLib()\n    const c = this.#coll(plan.collection)\n    try {\n      let targets: string[]\n      if (plan.ids && plan.ids.length > 0) {\n        targets = plan.ids\n      } else if (plan.filter) {\n        targets = [...c.byId.values()]\n          .filter((rec) => evaluateFilter(plan.filter!, rec.metadata ?? {}))\n          .map((rec) => rec.id)\n      } else {\n        targets = [...c.byId.keys()]\n      }\n      for (const id of targets) {\n        const rec = c.byId.get(id)\n        if (!rec) continue\n        try {\n          c.index.markDelete(rec.label)\n        } catch {\n          // already deleted — ignore\n        }\n        c.idByLabel.delete(rec.label)\n        c.byId.delete(id)\n      }\n    } catch (err) {\n      throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n    }\n  }\n}\n"],"mappings":"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"}