{"version":3,"file":"vectorstores.cjs","names":["VectorStore","AsyncCaller","uuid","Document"],"sources":["../src/vectorstores.ts"],"sourcesContent":["import * as uuid from \"@langchain/core/utils/uuid\";\n\nimport type {\n  VectorizeIndex,\n  VectorizeVectorMetadata,\n  VectorizeVectorMetadataFilter,\n} from \"@cloudflare/workers-types\";\nimport type { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport { VectorStore } from \"@langchain/core/vectorstores\";\nimport { Document } from \"@langchain/core/documents\";\nimport {\n  AsyncCaller,\n  type AsyncCallerParams,\n} from \"@langchain/core/utils/async_caller\";\nimport { chunkArray } from \"@langchain/core/utils/chunk_array\";\n\nexport interface VectorizeLibArgs extends AsyncCallerParams {\n  index: VectorizeIndex;\n  textKey?: string;\n}\n\n/**\n * Type that defines the parameters for the delete operation in the\n * CloudflareVectorizeStore class. It includes ids, deleteAll flag, and namespace.\n */\nexport type VectorizeDeleteParams = {\n  ids: string[];\n};\n\n/**\n * Class that extends the VectorStore class and provides methods to\n * interact with the Cloudflare Vectorize vector database.\n */\nexport class CloudflareVectorizeStore extends VectorStore {\n  declare FilterType: VectorizeVectorMetadataFilter;\n\n  textKey: string;\n\n  namespace?: string;\n\n  index: VectorizeIndex;\n\n  caller: AsyncCaller;\n\n  _vectorstoreType(): string {\n    return \"cloudflare_vectorize\";\n  }\n\n  constructor(embeddings: EmbeddingsInterface, args: VectorizeLibArgs) {\n    super(embeddings, args);\n\n    this.embeddings = embeddings;\n    const { index, textKey, ...asyncCallerArgs } = args;\n    if (!index) {\n      throw new Error(\n        \"Must supply a Vectorize index binding, eg { index: env.VECTORIZE }\"\n      );\n    }\n    this.index = index;\n    this.textKey = textKey ?? \"text\";\n    this.caller = new AsyncCaller({\n      maxConcurrency: 6,\n      maxRetries: 0,\n      ...asyncCallerArgs,\n    });\n  }\n\n  /**\n   * Method that adds documents to the Vectorize database.\n   * @param documents Array of documents to add.\n   * @param options Optional ids for the documents.\n   * @returns Promise that resolves with the ids of the added documents.\n   */\n  async addDocuments(\n    documents: Document[],\n    options?: { ids?: string[] } | string[]\n  ) {\n    const texts = documents.map(({ pageContent }) => pageContent);\n    return this.addVectors(\n      await this.embeddings.embedDocuments(texts),\n      documents,\n      options\n    );\n  }\n\n  /**\n   * Method that adds vectors to the Vectorize database.\n   * @param vectors Array of vectors to add.\n   * @param documents Array of documents associated with the vectors.\n   * @param options Optional ids for the vectors.\n   * @returns Promise that resolves with the ids of the added vectors.\n   */\n  async addVectors(\n    vectors: number[][],\n    documents: Document[],\n    options?: { ids?: string[] } | string[]\n  ) {\n    const ids = Array.isArray(options) ? options : options?.ids;\n    const documentIds = ids == null ? documents.map(() => uuid.v4()) : ids;\n    const vectorizeVectors = vectors.map((values, idx) => {\n      const metadata: Record<string, VectorizeVectorMetadata> = {\n        ...documents[idx].metadata,\n        [this.textKey]: documents[idx].pageContent,\n      };\n      return {\n        id: documentIds[idx],\n        metadata,\n        values,\n      };\n    });\n\n    // Stick to a limit of 500 vectors per upsert request\n    const chunkSize = 500;\n    const chunkedVectors = chunkArray(vectorizeVectors, chunkSize);\n    const batchRequests = chunkedVectors.map((chunk) =>\n      this.caller.call(async () => this.index.upsert(chunk))\n    );\n\n    await Promise.all(batchRequests);\n\n    return documentIds;\n  }\n\n  /**\n   * Method that deletes vectors from the Vectorize database.\n   * @param params Parameters for the delete operation.\n   * @returns Promise that resolves when the delete operation is complete.\n   */\n  async delete(params: VectorizeDeleteParams): Promise<void> {\n    const batchSize = 1000;\n    const batchedIds = chunkArray(params.ids, batchSize);\n    const batchRequests = batchedIds.map((batchIds) =>\n      this.caller.call(async () => this.index.deleteByIds(batchIds))\n    );\n    await Promise.all(batchRequests);\n  }\n\n  /**\n   * Method that performs a similarity search in the Vectorize database and\n   * returns the results along with their scores.\n   * @param query Query vector for the similarity search.\n   * @param k Number of top results to return.\n   * @returns Promise that resolves with an array of documents and their scores.\n   */\n  async similaritySearchVectorWithScore(\n    query: number[],\n    k: number,\n    filter?: this[\"FilterType\"]\n  ): Promise<[Document, number][]> {\n    const results = await this.index.query(query, {\n      returnMetadata: true,\n      returnValues: true,\n      topK: k,\n      filter,\n    });\n\n    const result: [Document, number][] = [];\n\n    if (results.matches) {\n      for (const res of results.matches) {\n        const { [this.textKey]: pageContent, ...metadata } = res.metadata ?? {};\n        result.push([\n          new Document({ metadata, pageContent: pageContent as string }),\n          res.score,\n        ]);\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * Static method that creates a new instance of the CloudflareVectorizeStore class\n   * from texts.\n   * @param texts Array of texts to add to the Vectorize database.\n   * @param metadatas Metadata associated with the texts.\n   * @param embeddings Embeddings to use for the texts.\n   * @param dbConfig Configuration for the Vectorize database.\n   * @param options Optional ids for the vectors.\n   * @returns Promise that resolves with a new instance of the CloudflareVectorizeStore class.\n   */\n  static async fromTexts(\n    texts: string[],\n    metadatas:\n      | Record<string, VectorizeVectorMetadata>[]\n      | Record<string, VectorizeVectorMetadata>,\n    embeddings: EmbeddingsInterface,\n    dbConfig: VectorizeLibArgs\n  ): Promise<CloudflareVectorizeStore> {\n    const docs: Document[] = [];\n    for (let i = 0; i < texts.length; i += 1) {\n      const metadata = Array.isArray(metadatas) ? metadatas[i] : metadatas;\n      const newDoc = new Document({\n        pageContent: texts[i],\n        metadata,\n      });\n      docs.push(newDoc);\n    }\n    return CloudflareVectorizeStore.fromDocuments(docs, embeddings, dbConfig);\n  }\n\n  /**\n   * Static method that creates a new instance of the CloudflareVectorizeStore class\n   * from documents.\n   * @param docs Array of documents to add to the Vectorize database.\n   * @param embeddings Embeddings to use for the documents.\n   * @param dbConfig Configuration for the Vectorize database.\n   * @param options Optional ids for the vectors.\n   * @returns Promise that resolves with a new instance of the CloudflareVectorizeStore class.\n   */\n  static async fromDocuments(\n    docs: Document[],\n    embeddings: EmbeddingsInterface,\n    dbConfig: VectorizeLibArgs\n  ): Promise<CloudflareVectorizeStore> {\n    const instance = new this(embeddings, dbConfig);\n    await instance.addDocuments(docs);\n    return instance;\n  }\n\n  /**\n   * Static method that creates a new instance of the CloudflareVectorizeStore class\n   * from an existing index.\n   * @param embeddings Embeddings to use for the documents.\n   * @param dbConfig Configuration for the Vectorize database.\n   * @returns Promise that resolves with a new instance of the CloudflareVectorizeStore class.\n   */\n  static async fromExistingIndex(\n    embeddings: EmbeddingsInterface,\n    dbConfig: VectorizeLibArgs\n  ): Promise<CloudflareVectorizeStore> {\n    const instance = new this(embeddings, dbConfig);\n    return instance;\n  }\n}\n"],"mappings":";;;;;;;;;;;;AAiCA,IAAa,2BAAb,MAAa,iCAAiCA,6BAAAA,YAAY;CAGxD;CAEA;CAEA;CAEA;CAEA,mBAA2B;AACzB,SAAO;;CAGT,YAAY,YAAiC,MAAwB;AACnE,QAAM,YAAY,KAAK;AAEvB,OAAK,aAAa;EAClB,MAAM,EAAE,OAAO,SAAS,GAAG,oBAAoB;AAC/C,MAAI,CAAC,MACH,OAAM,IAAI,MACR,qEACD;AAEH,OAAK,QAAQ;AACb,OAAK,UAAU,WAAW;AAC1B,OAAK,SAAS,IAAIC,mCAAAA,YAAY;GAC5B,gBAAgB;GAChB,YAAY;GACZ,GAAG;GACJ,CAAC;;;;;;;;CASJ,MAAM,aACJ,WACA,SACA;EACA,MAAM,QAAQ,UAAU,KAAK,EAAE,kBAAkB,YAAY;AAC7D,SAAO,KAAK,WACV,MAAM,KAAK,WAAW,eAAe,MAAM,EAC3C,WACA,QACD;;;;;;;;;CAUH,MAAM,WACJ,SACA,WACA,SACA;EACA,MAAM,MAAM,MAAM,QAAQ,QAAQ,GAAG,UAAU,SAAS;EACxD,MAAM,cAAc,OAAO,OAAO,UAAU,UAAUC,2BAAK,IAAI,CAAC,GAAG;EAgBnE,MAAM,iBAAA,GAAA,kCAAA,YAfmB,QAAQ,KAAK,QAAQ,QAAQ;GACpD,MAAM,WAAoD;IACxD,GAAG,UAAU,KAAK;KACjB,KAAK,UAAU,UAAU,KAAK;IAChC;AACD,UAAO;IACL,IAAI,YAAY;IAChB;IACA;IACD;IAK+C,EAAE,IAChB,CAAC,KAAK,UACxC,KAAK,OAAO,KAAK,YAAY,KAAK,MAAM,OAAO,MAAM,CAAC,CACvD;AAED,QAAM,QAAQ,IAAI,cAAc;AAEhC,SAAO;;;;;;;CAQT,MAAM,OAAO,QAA8C;EAGzD,MAAM,iBAAA,GAAA,kCAAA,YADwB,OAAO,KAAK,IACV,CAAC,KAAK,aACpC,KAAK,OAAO,KAAK,YAAY,KAAK,MAAM,YAAY,SAAS,CAAC,CAC/D;AACD,QAAM,QAAQ,IAAI,cAAc;;;;;;;;;CAUlC,MAAM,gCACJ,OACA,GACA,QAC+B;EAC/B,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM,OAAO;GAC5C,gBAAgB;GAChB,cAAc;GACd,MAAM;GACN;GACD,CAAC;EAEF,MAAM,SAA+B,EAAE;AAEvC,MAAI,QAAQ,QACV,MAAK,MAAM,OAAO,QAAQ,SAAS;GACjC,MAAM,GAAG,KAAK,UAAU,aAAa,GAAG,aAAa,IAAI,YAAY,EAAE;AACvE,UAAO,KAAK,CACV,IAAIC,0BAAAA,SAAS;IAAE;IAAuB;IAAuB,CAAC,EAC9D,IAAI,MACL,CAAC;;AAIN,SAAO;;;;;;;;;;;;CAaT,aAAa,UACX,OACA,WAGA,YACA,UACmC;EACnC,MAAM,OAAmB,EAAE;AAC3B,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;GACxC,MAAM,WAAW,MAAM,QAAQ,UAAU,GAAG,UAAU,KAAK;GAC3D,MAAM,SAAS,IAAIA,0BAAAA,SAAS;IAC1B,aAAa,MAAM;IACnB;IACD,CAAC;AACF,QAAK,KAAK,OAAO;;AAEnB,SAAO,yBAAyB,cAAc,MAAM,YAAY,SAAS;;;;;;;;;;;CAY3E,aAAa,cACX,MACA,YACA,UACmC;EACnC,MAAM,WAAW,IAAI,KAAK,YAAY,SAAS;AAC/C,QAAM,SAAS,aAAa,KAAK;AACjC,SAAO;;;;;;;;;CAUT,aAAa,kBACX,YACA,UACmC;AAEnC,SAAO,IADc,KAAK,YAAY,SACvB"}