{"version":3,"file":"meilisearch.cjs","names":["#opts","#client","#ensure","#wait","#dims","#unwrapVector","#project","#parseMeta"],"sources":["../../../src/batteries/vector/meilisearch/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/batteries/vector/meilisearch\n *\n * Meilisearch adapter. Each collection is a Meilisearch index with a `userProvided` embedder\n * (BYO vectors under `_vectors.<embedder>`); KNN uses semantic search (`vector` +\n * `hybrid.semanticRatio = 1`). Metadata is stored as a JSON string field and filtered with the\n * neutral filter tree's JS reference evaluator for exact cross-adapter parity. Meilisearch\n * returns `_rankingScore` already normalized to [0,1] (higher = closer).\n *\n * Requires the `vectorStore` experimental feature, which the adapter enables on connect.\n * Driver: `meilisearch` (pure JS).\n */\n\nimport { evaluateFilter } from '../filters'\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_CONNECTION_FAILED,\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} from '../types'\n\nconst EMBEDDER = 'default'\n\nexport interface MeilisearchVectorStoreOptions extends BaseVectorStoreOptions {\n  /** Connection and authentication parameters for the backend. */\n  connection?: { host?: string; apiKey?: string }\n}\n\nconst getMeilisearch = async () => {\n  try {\n    const mod = await import('meilisearch')\n    return mod.Meilisearch\n  } catch {\n    throw new E_VECTOR_STORE_DRIVER_UNAVAILABLE(['meilisearch'])\n  }\n}\n\nexport class MeilisearchVectorStore extends BaseVectorStore {\n  readonly capabilities: VectorStoreCapabilities = {\n    transactions: false,\n    namedVectors: false,\n    rename: false,\n    rawSql: false,\n    builtInEncoding: false,\n    // Writes are awaited to task completion (waitForTask) before resolving — strongly\n    // consistent for the next search. The option is a no-op.\n    consistency: { configurable: false, default: 'strong', modes: ['strong'] },\n  }\n\n  #client: any | null = null\n  #dims: Map<string, number> = new Map()\n\n  get #opts(): MeilisearchVectorStoreOptions {\n    return this.options as MeilisearchVectorStoreOptions\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.#client) return\n    const Meilisearch = await getMeilisearch()\n    const c = this.#opts.connection || {}\n    const host = c.host ?? 'http://localhost:7700'\n    try {\n      this.#client = new Meilisearch({ host, apiKey: c.apiKey })\n      // Enable the vector store experimental feature (no-op / stable on newer versions).\n      await fetch(`${host.replace(/\\/$/, '')}/experimental-features`, {\n        method: 'PATCH',\n        headers: {\n          'Content-Type': 'application/json',\n          ...(c.apiKey ? { Authorization: `Bearer ${c.apiKey}` } : {}),\n        },\n        body: JSON.stringify({ vectorStore: true }),\n      }).catch(() => undefined)\n    } catch (err) {\n      throw new E_VECTOR_STORE_CONNECTION_FAILED([String(err)])\n    }\n  }\n\n  async close(): Promise<void> {\n    this.#client = null\n  }\n\n  async #ensure(): Promise<any> {\n    if (!this.#client) await this.connect()\n    return this.#client!\n  }\n\n  async #wait(task: any): Promise<void> {\n    const uid = task?.taskUid ?? task?.uid\n    if (uid === undefined) return\n    await this.#client.tasks.waitForTask(uid)\n  }\n\n  async createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void> {\n    const client = await this.#ensure()\n    this.#dims.set(spec.collection, spec.vector.dimensions)\n    if (ifNotExists && (await this.hasCollection(spec.collection))) return\n    try {\n      await this.#wait(await client.createIndex(spec.collection, { primaryKey: 'id' }))\n      const idx = client.index(spec.collection)\n      await this.#wait(\n        await idx.updateEmbedders({\n          [EMBEDDER]: { source: 'userProvided', dimensions: spec.vector.dimensions },\n        })\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    const client = await this.#ensure()\n    if (ifExists && !(await this.hasCollection(collection))) return\n    try {\n      await this.#wait(await client.deleteIndex(collection))\n      this.#dims.delete(collection)\n    } catch (err) {\n      throw new E_VECTOR_STORE_COLLECTION_FAILED(['dropCollection', String(err)])\n    }\n  }\n\n  async hasCollection(collection: string): Promise<boolean> {\n    const client = await this.#ensure()\n    try {\n      await client.index(collection).getRawInfo()\n      return true\n    } catch {\n      return false\n    }\n  }\n\n  async renameCollection(_from: string, _to: string): Promise<void> {\n    throw new E_VECTOR_STORE_UNSUPPORTED_OPERATION(['renameCollection', 'meilisearch'])\n  }\n\n  async executeUpsert(plan: UpsertPlan): Promise<void> {\n    if (plan.records.length === 0) return\n    validateRecords(plan.records)\n    const client = await this.#ensure()\n    const expected = this.#opts.dimensions ?? this.#dims.get(plan.collection)\n    try {\n      const docs: any[] = []\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        docs.push({\n          id: r.id,\n          document: r.document ?? '',\n          metadata: r.metadata ? JSON.stringify(r.metadata) : '{}',\n          _vectors: { [EMBEDDER]: vector },\n        })\n      }\n      await this.#wait(await client.index(plan.collection).addDocuments(docs))\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    const client = await this.#ensure()\n    const idx = client.index(plan.collection)\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        try {\n          const doc = await idx.getDocument(plan.near.id, { retrieveVectors: true })\n          queryVector = this.#unwrapVector(doc?._vectors?.[EMBEDDER])\n        } catch {\n          queryVector = undefined\n        }\n        if (!queryVector) {\n          throw new E_VECTOR_STORE_SEARCH_FAILED(['Referenced id not found: ' + plan.near.id])\n        }\n      }\n    }\n\n    const offset = plan.offset ?? 0\n    try {\n      const over = plan.filter ? 250 : plan.topK + offset\n      let hits: any[]\n      if (queryVector) {\n        const res = await idx.search('', {\n          vector: queryVector,\n          hybrid: { embedder: EMBEDDER, semanticRatio: 1.0 },\n          limit: Math.max(over, plan.topK + offset),\n          showRankingScore: true,\n          retrieveVectors: true,\n        })\n        hits = res.hits ?? []\n      } else {\n        const res = await idx.search('', {\n          limit: Math.max(over, plan.topK + offset),\n          retrieveVectors: true,\n        })\n        hits = res.hits ?? []\n      }\n      const mapped = hits.map((hit) => ({\n        match: this.#project(hit, plan, !!queryVector),\n        meta: this.#parseMeta(hit.metadata),\n      }))\n      const filtered = plan.filter\n        ? mapped.filter((m) => evaluateFilter(plan.filter!, m.meta))\n        : mapped\n      return filtered.slice(offset, offset + plan.topK).map((m) => m.match)\n    } catch (err) {\n      throw new E_VECTOR_STORE_SEARCH_FAILED([String(err)])\n    }\n  }\n\n  #unwrapVector(v: unknown): number[] | undefined {\n    // Meilisearch returns _vectors.default as { embeddings: number[][] } or number[][] or number[].\n    if (!v) return undefined\n    if (Array.isArray(v)) {\n      return Array.isArray(v[0]) ? (v[0] as number[]) : (v as number[])\n    }\n    const emb = (v as any).embeddings\n    if (Array.isArray(emb)) return Array.isArray(emb[0]) ? (emb[0] as number[]) : (emb as number[])\n    return undefined\n  }\n\n  #parseMeta(val: unknown): VectorMetadata {\n    if (typeof val === 'string') {\n      try {\n        return JSON.parse(val) as VectorMetadata\n      } catch {\n        return {}\n      }\n    }\n    if (val && typeof val === 'object') return val as VectorMetadata\n    return {}\n  }\n\n  #project(hit: any, plan: SearchPlan, isKnn: boolean): VectorMatch {\n    const proj = plan.projection\n    const out: VectorMatch = {}\n    if (proj.id) out.id = hit.id as string\n    if (proj.vector) {\n      const v = this.#unwrapVector(hit._vectors?.[EMBEDDER])\n      if (v) out.vector = v\n    }\n    if (proj.document) out.document = (hit.document ?? undefined) as string | undefined\n    if (proj.metadata) out.metadata = this.#parseMeta(hit.metadata)\n    if (isKnn && typeof hit._rankingScore === 'number') {\n      // Meilisearch _rankingScore is already in [0,1], higher = closer.\n      out.score = hit._rankingScore\n    }\n    return out\n  }\n\n  async executeDelete(plan: DeletePlan): Promise<void> {\n    const client = await this.#ensure()\n    const idx = client.index(plan.collection)\n    try {\n      if (plan.ids && plan.ids.length > 0) {\n        await this.#wait(await idx.deleteDocuments(plan.ids))\n      } else if (plan.filter) {\n        // Resolve ids via a scan + JS evaluator, then delete by id.\n        const res = await idx.search('', { limit: 1000 })\n        const targets = (res.hits ?? [])\n          .filter((hit: any) => evaluateFilter(plan.filter!, this.#parseMeta(hit.metadata)))\n          .map((hit: any) => hit.id as string)\n        if (targets.length > 0) await this.#wait(await idx.deleteDocuments(targets))\n      } else {\n        await this.#wait(await idx.deleteAllDocuments())\n      }\n    } catch (err) {\n      throw new E_VECTOR_STORE_DELETE_FAILED([String(err)])\n    }\n  }\n}\n"],"mappings":"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"}