@langchain/community
Version:
Third-party integrations for LangChain.js
119 lines (118 loc) • 4.11 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
let _vercel_kv = require("@vercel/kv");
let _langchain_core_stores = require("@langchain/core/stores");
//#region src/storage/vercel_kv.ts
var vercel_kv_exports = /* @__PURE__ */ require_runtime.__exportAll({ VercelKVStore: () => VercelKVStore });
/**
* Class that extends the BaseStore class to interact with a Vercel KV
* database. It provides methods for getting, setting, and deleting data,
* as well as yielding keys from the database.
* @example
* ```typescript
* const store = new VercelKVStore({
* client: getClient(),
* });
* await store.mset([
* { key: "message:id:0", value: "encoded message 0" },
* { key: "message:id:1", value: "encoded message 1" },
* ]);
* const retrievedMessages = await store.mget(["message:id:0", "message:id:1"]);
* const yieldedKeys = [];
* for await (const key of store.yieldKeys("message:id:")) {
* yieldedKeys.push(key);
* }
* await store.mdelete(yieldedKeys);
* ```
*/
var VercelKVStore = class extends _langchain_core_stores.BaseStore {
lc_namespace = ["langchain", "storage"];
client;
ttl;
namespace;
yieldKeysScanBatchSize = 1e3;
constructor(fields) {
super(fields);
this.client = fields?.client ?? _vercel_kv.kv;
this.ttl = fields?.ttl;
this.namespace = fields?.namespace;
this.yieldKeysScanBatchSize = fields?.yieldKeysScanBatchSize ?? this.yieldKeysScanBatchSize;
}
_getPrefixedKey(key) {
if (this.namespace) return `${this.namespace}/${key}`;
return key;
}
_getDeprefixedKey(key) {
if (this.namespace) return key.slice(this.namespace.length + 1);
return key;
}
/**
* Gets multiple keys from the Redis database.
* @param keys Array of keys to be retrieved.
* @returns An array of retrieved values.
*/
async mget(keys) {
const prefixedKeys = keys.map(this._getPrefixedKey.bind(this));
const retrievedValues = await this.client.mget(...prefixedKeys);
const encoder = new TextEncoder();
return retrievedValues.map((value) => {
if (value === void 0 || value === null) return;
else if (typeof value === "object") return encoder.encode(JSON.stringify(value));
else return encoder.encode(value);
});
}
/**
* Sets multiple keys in the Redis database.
* @param keyValuePairs Array of key-value pairs to be set.
* @returns Promise that resolves when all keys have been set.
*/
async mset(keyValuePairs) {
const decoder = new TextDecoder();
const decodedKeyValuePairs = keyValuePairs.map(([key, value]) => [this._getPrefixedKey(key), decoder.decode(value)]);
const pipeline = this.client.pipeline();
for (const [key, value] of decodedKeyValuePairs) if (this.ttl) pipeline.setex(key, this.ttl, value);
else pipeline.set(key, value);
await pipeline.exec();
}
/**
* Deletes multiple keys from the Redis database.
* @param keys Array of keys to be deleted.
* @returns Promise that resolves when all keys have been deleted.
*/
async mdelete(keys) {
await this.client.del(...keys.map(this._getPrefixedKey.bind(this)));
}
/**
* Yields keys from the Redis database.
* @param prefix Optional prefix to filter the keys.
* @returns An AsyncGenerator that yields keys from the Redis database.
*/
async *yieldKeys(prefix) {
let pattern;
if (prefix) {
const wildcardPrefix = prefix.endsWith("*") ? prefix : `${prefix}*`;
pattern = this._getPrefixedKey(wildcardPrefix);
} else pattern = this._getPrefixedKey("*");
let [cursor, batch] = await this.client.scan(0, {
match: pattern,
count: this.yieldKeysScanBatchSize
});
for (const key of batch) yield this._getDeprefixedKey(key);
while (String(cursor) !== "0") {
[cursor, batch] = await this.client.scan(cursor, {
match: pattern,
count: this.yieldKeysScanBatchSize
});
for (const key of batch) yield this._getDeprefixedKey(key);
}
}
};
//#endregion
exports.VercelKVStore = VercelKVStore;
Object.defineProperty(exports, "vercel_kv_exports", {
enumerable: true,
get: function() {
return vercel_kv_exports;
}
});
//# sourceMappingURL=vercel_kv.cjs.map