{"version":3,"file":"schema.mjs","names":["#vectorDef","#pushField","#fields","#spec","#executor"],"sources":["../../../src/batteries/vector/schema.ts"],"sourcesContent":["/**\n * Knex-style schema builder for the vector battery.\n *\n * @module @nhtio/adk/batteries/vector/schema\n */\n\nimport type { DistanceMetric } from './types'\nimport type { CollectionSpec, CollectionFieldSpec } from './plan'\n\n/**\n * The backend side of the schema builder — the adapter operations a {@link VectorSchemaBuilder}\n * drains its compiled {@link CollectionSpec}s and DDL calls into.\n */\nexport interface SchemaExecutor {\n  /** Create a collection from `spec`; `ifNotExists` suppresses the already-exists error. */\n  createCollection(spec: CollectionSpec, ifNotExists: boolean): Promise<void>\n  /** Drop a collection; `ifExists` suppresses the not-found error. */\n  dropCollection(collection: string, ifExists: boolean): Promise<void>\n  /** Resolve `true` if the collection exists. */\n  hasCollection(collection: string): Promise<boolean>\n  /** Rename a collection from `from` to `to`. */\n  renameCollection(from: string, to: string): Promise<void>\n}\n\n/**\n * Chainable builder for a single collection definition — declares the vector column and the typed\n * metadata fields, compiled to a {@link CollectionSpec} by {@link CollectionBuilder.build}.\n */\nexport class CollectionBuilder {\n  #vectorDef?: { dimensions: number; metric: DistanceMetric }\n  #fields: CollectionFieldSpec[] = []\n\n  /** Declare the vector column's dimensionality and (optionally) its distance metric (default `'cosine'`). */\n  vector(def: { dimensions: number; metric?: DistanceMetric }): this {\n    this.#vectorDef = {\n      dimensions: def.dimensions,\n      metric: def.metric ?? 'cosine',\n    }\n    return this\n  }\n\n  /** Declare a string metadata field; returns a {@link FieldChain} for `.index()`/`.nullable()`. */\n  string(name: string): FieldChain {\n    return this.#pushField(name, 'string')\n  }\n\n  /** Declare an integer metadata field; returns a {@link FieldChain} for `.index()`/`.nullable()`. */\n  integer(name: string): FieldChain {\n    return this.#pushField(name, 'integer')\n  }\n\n  /** Declare a number metadata field; returns a {@link FieldChain} for `.index()`/`.nullable()`. */\n  number(name: string): FieldChain {\n    return this.#pushField(name, 'number')\n  }\n\n  /** Declare a boolean metadata field; returns a {@link FieldChain} for `.index()`/`.nullable()`. */\n  boolean(name: string): FieldChain {\n    return this.#pushField(name, 'boolean')\n  }\n\n  /** Declare a JSON metadata field; returns a {@link FieldChain} for `.index()`/`.nullable()`. */\n  json(name: string): FieldChain {\n    return this.#pushField(name, 'json')\n  }\n\n  #pushField(name: string, type: CollectionFieldSpec['type']): FieldChain {\n    const spec: CollectionFieldSpec = {\n      name,\n      type,\n      index: false,\n      nullable: false,\n    }\n    this.#fields.push(spec)\n    return new FieldChainImpl(spec)\n  }\n\n  /**\n   * Compile the accumulated definition into a {@link CollectionSpec}.\n   *\n   * @throws when no {@link CollectionBuilder.vector} definition was declared.\n   */\n  build(collection: string): CollectionSpec {\n    if (!this.#vectorDef) {\n      throw new Error('a collection requires a vector() definition')\n    }\n    return {\n      collection,\n      vector: this.#vectorDef,\n      fields: this.#fields,\n    }\n  }\n}\n\n/** Post-declaration chain for a metadata field, toggling indexing and nullability. */\nexport interface FieldChain {\n  /** Mark the field as indexed for filtering. */\n  index(): FieldChain\n  /** Mark the field as nullable. */\n  nullable(): FieldChain\n}\n\nclass FieldChainImpl implements FieldChain {\n  #spec: CollectionFieldSpec\n\n  constructor(spec: CollectionFieldSpec) {\n    this.#spec = spec\n  }\n\n  index(): FieldChain {\n    this.#spec.index = true\n    return this\n  }\n\n  nullable(): FieldChain {\n    this.#spec.nullable = true\n    return this\n  }\n}\n\n/**\n * Knex-style schema facade exposing collection DDL (create/drop/rename/has) over a\n * {@link SchemaExecutor}. Returned by a vector store's `schema()` accessor.\n */\nexport class VectorSchemaBuilder {\n  #executor: SchemaExecutor\n\n  /**\n   * @param executor - The adapter-backed executor the DDL calls are drained into.\n   */\n  constructor(executor: SchemaExecutor) {\n    this.#executor = executor\n  }\n\n  /** Create a collection, defining it via the `cb` builder. Errors if it already exists. */\n  async createCollection(collection: string, cb: (c: CollectionBuilder) => void): Promise<void> {\n    const builder = new CollectionBuilder()\n    cb(builder)\n    const spec = builder.build(collection)\n    await this.#executor.createCollection(spec, false)\n  }\n\n  /** Create a collection only if absent; a no-op if it already exists. */\n  async createCollectionIfNotExists(\n    collection: string,\n    cb: (c: CollectionBuilder) => void\n  ): Promise<void> {\n    const builder = new CollectionBuilder()\n    cb(builder)\n    const spec = builder.build(collection)\n    await this.#executor.createCollection(spec, true)\n  }\n\n  /** Drop a collection. Errors if it does not exist. */\n  async dropCollection(collection: string): Promise<void> {\n    await this.#executor.dropCollection(collection, false)\n  }\n\n  /** Drop a collection only if present; a no-op if it does not exist. */\n  async dropCollectionIfExists(collection: string): Promise<void> {\n    await this.#executor.dropCollection(collection, true)\n  }\n\n  /** Resolve `true` if the collection exists. */\n  async hasCollection(collection: string): Promise<boolean> {\n    return this.#executor.hasCollection(collection)\n  }\n\n  /** Rename a collection from `from` to `to`. */\n  async renameCollection(from: string, to: string): Promise<void> {\n    await this.#executor.renameCollection(from, to)\n  }\n}\n"],"mappings":";;;;;AA4BA,IAAa,oBAAb,MAA+B;CAC7B;CACA,UAAiC,CAAC;;CAGlC,OAAO,KAA4D;EACjE,KAAKA,aAAa;GAChB,YAAY,IAAI;GAChB,QAAQ,IAAI,UAAU;EACxB;EACA,OAAO;CACT;;CAGA,OAAO,MAA0B;EAC/B,OAAO,KAAKC,WAAW,MAAM,QAAQ;CACvC;;CAGA,QAAQ,MAA0B;EAChC,OAAO,KAAKA,WAAW,MAAM,SAAS;CACxC;;CAGA,OAAO,MAA0B;EAC/B,OAAO,KAAKA,WAAW,MAAM,QAAQ;CACvC;;CAGA,QAAQ,MAA0B;EAChC,OAAO,KAAKA,WAAW,MAAM,SAAS;CACxC;;CAGA,KAAK,MAA0B;EAC7B,OAAO,KAAKA,WAAW,MAAM,MAAM;CACrC;CAEA,WAAW,MAAc,MAA+C;EACtE,MAAM,OAA4B;GAChC;GACA;GACA,OAAO;GACP,UAAU;EACZ;EACA,KAAKC,QAAQ,KAAK,IAAI;EACtB,OAAO,IAAI,eAAe,IAAI;CAChC;;;;;;CAOA,MAAM,YAAoC;EACxC,IAAI,CAAC,KAAKF,YACR,MAAM,IAAI,MAAM,6CAA6C;EAE/D,OAAO;GACL;GACA,QAAQ,KAAKA;GACb,QAAQ,KAAKE;EACf;CACF;AACF;AAUA,IAAM,iBAAN,MAA2C;CACzC;CAEA,YAAY,MAA2B;EACrC,KAAKC,QAAQ;CACf;CAEA,QAAoB;EAClB,KAAKA,MAAM,QAAQ;EACnB,OAAO;CACT;CAEA,WAAuB;EACrB,KAAKA,MAAM,WAAW;EACtB,OAAO;CACT;AACF;;;;;AAMA,IAAa,sBAAb,MAAiC;CAC/B;;;;CAKA,YAAY,UAA0B;EACpC,KAAKC,YAAY;CACnB;;CAGA,MAAM,iBAAiB,YAAoB,IAAmD;EAC5F,MAAM,UAAU,IAAI,kBAAkB;EACtC,GAAG,OAAO;EACV,MAAM,OAAO,QAAQ,MAAM,UAAU;EACrC,MAAM,KAAKA,UAAU,iBAAiB,MAAM,KAAK;CACnD;;CAGA,MAAM,4BACJ,YACA,IACe;EACf,MAAM,UAAU,IAAI,kBAAkB;EACtC,GAAG,OAAO;EACV,MAAM,OAAO,QAAQ,MAAM,UAAU;EACrC,MAAM,KAAKA,UAAU,iBAAiB,MAAM,IAAI;CAClD;;CAGA,MAAM,eAAe,YAAmC;EACtD,MAAM,KAAKA,UAAU,eAAe,YAAY,KAAK;CACvD;;CAGA,MAAM,uBAAuB,YAAmC;EAC9D,MAAM,KAAKA,UAAU,eAAe,YAAY,IAAI;CACtD;;CAGA,MAAM,cAAc,YAAsC;EACxD,OAAO,KAAKA,UAAU,cAAc,UAAU;CAChD;;CAGA,MAAM,iBAAiB,MAAc,IAA2B;EAC9D,MAAM,KAAKA,UAAU,iBAAiB,MAAM,EAAE;CAChD;AACF"}