{"version":3,"file":"batch.cjs","names":["BaseStore"],"sources":["../../src/store/batch.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport {\n  BaseStore,\n  type Item,\n  type SearchOperation,\n  type PutOperation,\n  type GetOperation,\n  type Operation,\n  OperationResults,\n} from \"./base.js\";\n\n/**\n * Extracts and returns the underlying store from an `AsyncBatchedStore`,\n * or returns the input if it is not an `AsyncBatchedStore`.\n */\nconst extractStore = (input: BaseStore | AsyncBatchedStore): BaseStore => {\n  if (\"lg_name\" in input && input.lg_name === \"AsyncBatchedStore\") {\n    // @ts-expect-error is a protected property\n    return input.store;\n  }\n  return input;\n};\n\nexport class AsyncBatchedStore extends BaseStore {\n  lg_name = \"AsyncBatchedStore\";\n\n  protected store: BaseStore;\n\n  private queue: Map<\n    number,\n    {\n      operation: Operation;\n      resolve: (value: any) => void;\n      reject: (reason?: any) => void;\n    }\n  > = new Map();\n\n  private nextKey: number = 0;\n\n  private running = false;\n\n  private processingTask: Promise<void> | null = null;\n\n  constructor(store: BaseStore) {\n    super();\n    this.store = extractStore(store);\n  }\n\n  get isRunning(): boolean {\n    return this.running;\n  }\n\n  /**\n   * @ignore\n   * Batch is not implemented here as we're only extending `BaseStore`\n   * to allow it to be passed where `BaseStore` is expected, and implement\n   * the convenience methods (get, search, put, delete).\n   */\n  async batch<Op extends Operation[]>(\n    _operations: Op\n  ): Promise<OperationResults<Op>> {\n    throw new Error(\n      \"The `batch` method is not implemented on `AsyncBatchedStore`.\" +\n        \"\\n Instead, it calls the `batch` method on the wrapped store.\" +\n        \"\\n If you are seeing this error, something is wrong.\"\n    );\n  }\n\n  async get(namespace: string[], key: string): Promise<Item | null> {\n    return this.enqueueOperation({ namespace, key } as GetOperation);\n  }\n\n  async search(\n    namespacePrefix: string[],\n    options?: {\n      filter?: Record<string, any>;\n      limit?: number;\n      offset?: number;\n      query?: string;\n    }\n  ): Promise<Item[]> {\n    const { filter, limit = 10, offset = 0, query } = options || {};\n    return this.enqueueOperation({\n      namespacePrefix,\n      filter,\n      limit,\n      offset,\n      query,\n    } as SearchOperation);\n  }\n\n  async put(\n    namespace: string[],\n    key: string,\n    value: Record<string, any>\n  ): Promise<void> {\n    return this.enqueueOperation({ namespace, key, value } as PutOperation);\n  }\n\n  async delete(namespace: string[], key: string): Promise<void> {\n    return this.enqueueOperation({\n      namespace,\n      key,\n      value: null,\n    } as PutOperation);\n  }\n\n  start(): void {\n    if (!this.running) {\n      this.running = true;\n      this.processingTask = this.processBatchQueue();\n    }\n  }\n\n  async stop(): Promise<void> {\n    this.running = false;\n    if (this.processingTask) {\n      await this.processingTask;\n    }\n  }\n\n  private enqueueOperation<T>(operation: Operation): Promise<T> {\n    return new Promise<T>((resolve, reject) => {\n      const key = this.nextKey;\n      this.nextKey += 1;\n      this.queue.set(key, { operation, resolve, reject });\n    });\n  }\n\n  private async processBatchQueue(): Promise<void> {\n    while (this.running) {\n      await new Promise((resolve) => {\n        setTimeout(resolve, 0);\n      });\n      if (this.queue.size === 0) continue;\n\n      const batch = new Map(this.queue);\n      this.queue.clear();\n\n      try {\n        const operations = Array.from(batch.values()).map(\n          ({ operation }) => operation\n        );\n        const results = await this.store.batch(operations);\n\n        batch.forEach(({ resolve }, key) => {\n          const index = Array.from(batch.keys()).indexOf(key);\n          resolve(results[index]);\n        });\n      } catch (e) {\n        batch.forEach(({ reject }) => {\n          reject(e);\n        });\n      }\n    }\n  }\n\n  // AsyncBatchedStore is internal and gets passed as args into traced tasks\n  // some BaseStores contain circular references so just serialize without it\n  // as this causes warnings when tracing with LangSmith.\n  toJSON() {\n    return {\n      queue: this.queue,\n      nextKey: this.nextKey,\n      running: this.running,\n      store: \"[LangGraphStore]\",\n    };\n  }\n}\n"],"mappings":";;;;;;AAgBA,MAAM,gBAAgB,UAAoD;AACxE,KAAI,aAAa,SAAS,MAAM,YAAY,oBAE1C,QAAO,MAAM;AAEf,QAAO;;AAGT,IAAa,oBAAb,cAAuCA,aAAAA,UAAU;CAC/C,UAAU;CAEV;CAEA,wBAOI,IAAI,KAAK;CAEb,UAA0B;CAE1B,UAAkB;CAElB,iBAA+C;CAE/C,YAAY,OAAkB;AAC5B,SAAO;AACP,OAAK,QAAQ,aAAa,MAAM;;CAGlC,IAAI,YAAqB;AACvB,SAAO,KAAK;;;;;;;;CASd,MAAM,MACJ,aAC+B;AAC/B,QAAM,IAAI,MACR,iLAGD;;CAGH,MAAM,IAAI,WAAqB,KAAmC;AAChE,SAAO,KAAK,iBAAiB;GAAE;GAAW;GAAK,CAAiB;;CAGlE,MAAM,OACJ,iBACA,SAMiB;EACjB,MAAM,EAAE,QAAQ,QAAQ,IAAI,SAAS,GAAG,UAAU,WAAW,EAAE;AAC/D,SAAO,KAAK,iBAAiB;GAC3B;GACA;GACA;GACA;GACA;GACD,CAAoB;;CAGvB,MAAM,IACJ,WACA,KACA,OACe;AACf,SAAO,KAAK,iBAAiB;GAAE;GAAW;GAAK;GAAO,CAAiB;;CAGzE,MAAM,OAAO,WAAqB,KAA4B;AAC5D,SAAO,KAAK,iBAAiB;GAC3B;GACA;GACA,OAAO;GACR,CAAiB;;CAGpB,QAAc;AACZ,MAAI,CAAC,KAAK,SAAS;AACjB,QAAK,UAAU;AACf,QAAK,iBAAiB,KAAK,mBAAmB;;;CAIlD,MAAM,OAAsB;AAC1B,OAAK,UAAU;AACf,MAAI,KAAK,eACP,OAAM,KAAK;;CAIf,iBAA4B,WAAkC;AAC5D,SAAO,IAAI,SAAY,SAAS,WAAW;GACzC,MAAM,MAAM,KAAK;AACjB,QAAK,WAAW;AAChB,QAAK,MAAM,IAAI,KAAK;IAAE;IAAW;IAAS;IAAQ,CAAC;IACnD;;CAGJ,MAAc,oBAAmC;AAC/C,SAAO,KAAK,SAAS;AACnB,SAAM,IAAI,SAAS,YAAY;AAC7B,eAAW,SAAS,EAAE;KACtB;AACF,OAAI,KAAK,MAAM,SAAS,EAAG;GAE3B,MAAM,QAAQ,IAAI,IAAI,KAAK,MAAM;AACjC,QAAK,MAAM,OAAO;AAElB,OAAI;IACF,MAAM,aAAa,MAAM,KAAK,MAAM,QAAQ,CAAC,CAAC,KAC3C,EAAE,gBAAgB,UACpB;IACD,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM,WAAW;AAElD,UAAM,SAAS,EAAE,WAAW,QAAQ;AAElC,aAAQ,QADM,MAAM,KAAK,MAAM,MAAM,CAAC,CAAC,QAAQ,IAAI,EAC5B;MACvB;YACK,GAAG;AACV,UAAM,SAAS,EAAE,aAAa;AAC5B,YAAO,EAAE;MACT;;;;CAQR,SAAS;AACP,SAAO;GACL,OAAO,KAAK;GACZ,SAAS,KAAK;GACd,SAAS,KAAK;GACd,OAAO;GACR"}