UNPKG

@langchain/community

Version:
1 lines 7.24 kB
{"version":3,"file":"upstash_redis.cjs","names":["BaseStore","UpstashRedis"],"sources":["../../src/storage/upstash_redis.ts"],"sourcesContent":["import { Redis as UpstashRedis, type RedisConfigNodejs } from \"@upstash/redis\";\n\nimport { BaseStore } from \"@langchain/core/stores\";\n\n/**\n * Type definition for the input parameters required to initialize an\n * instance of the UpstashStoreInput class.\n */\nexport interface UpstashRedisStoreInput {\n sessionTTL?: number;\n config?: RedisConfigNodejs;\n client?: UpstashRedis;\n /**\n * The amount of keys to retrieve per batch when yielding keys.\n * @default 1000\n */\n yieldKeysScanBatchSize?: number;\n /**\n * The namespace to use for the keys in the database.\n */\n namespace?: string;\n}\n\n/**\n * Class that extends the BaseStore class to interact with an Upstash Redis\n * database. It provides methods for getting, setting, and deleting data,\n * as well as yielding keys from the database.\n * @example\n * ```typescript\n * const store = new UpstashRedisStore({\n * client: new Redis({\n * url: \"your-upstash-redis-url\",\n * token: \"your-upstash-redis-token\",\n * }),\n * });\n * await store.mset([\n * [\"message:id:0\", \"encoded-ai-message\"],\n * [\"message:id:1\", \"encoded-human-message\"],\n * ]);\n * const retrievedMessages = await store.mget([\"message:id:0\", \"message:id:1\"]);\n * const yieldedKeys = [];\n * for await (const key of store.yieldKeys(\"message:id\")) {\n * yieldedKeys.push(key);\n * }\n * await store.mdelete(yieldedKeys);\n * ```\n */\nexport class UpstashRedisStore extends BaseStore<string, Uint8Array> {\n lc_namespace = [\"langchain\", \"storage\"];\n\n protected client: UpstashRedis;\n\n protected namespace?: string;\n\n protected yieldKeysScanBatchSize = 1000;\n\n private sessionTTL?: number;\n\n constructor(fields: UpstashRedisStoreInput) {\n super(fields);\n if (fields.client) {\n this.client = fields.client;\n } else if (fields.config) {\n this.client = new UpstashRedis(fields.config);\n } else {\n throw new Error(\n `Upstash Redis store requires either a config object or a pre-configured client.`\n );\n }\n this.sessionTTL = fields.sessionTTL;\n this.yieldKeysScanBatchSize =\n fields.yieldKeysScanBatchSize ?? this.yieldKeysScanBatchSize;\n this.namespace = fields.namespace;\n }\n\n _getPrefixedKey(key: string) {\n if (this.namespace) {\n const delimiter = \"/\";\n return `${this.namespace}${delimiter}${key}`;\n }\n return key;\n }\n\n _getDeprefixedKey(key: string) {\n if (this.namespace) {\n const delimiter = \"/\";\n return key.slice(this.namespace.length + delimiter.length);\n }\n return key;\n }\n\n /**\n * Gets multiple keys from the Upstash Redis database.\n * @param keys Array of keys to be retrieved.\n * @returns An array of retrieved values.\n */\n async mget(keys: string[]) {\n const encoder = new TextEncoder();\n\n const prefixedKeys = keys.map(this._getPrefixedKey.bind(this));\n const retrievedValues = await this.client.mget<Uint8Array[]>(\n ...prefixedKeys\n );\n return retrievedValues.map((value) => {\n if (!value) {\n return undefined;\n } else if (typeof value === \"object\") {\n return encoder.encode(JSON.stringify(value));\n } else {\n return encoder.encode(value);\n }\n });\n }\n\n /**\n * Sets multiple keys in the Upstash Redis database.\n * @param keyValuePairs Array of key-value pairs to be set.\n * @returns Promise that resolves when all keys have been set.\n */\n async mset(keyValuePairs: [string, Uint8Array][]): Promise<void> {\n const decoder = new TextDecoder();\n const encodedKeyValuePairs = keyValuePairs.map(([key, value]) => [\n this._getPrefixedKey(key),\n decoder.decode(value),\n ]);\n const pipeline = this.client.pipeline();\n for (const [key, value] of encodedKeyValuePairs) {\n if (this.sessionTTL) {\n pipeline.setex(key, this.sessionTTL, value);\n } else {\n pipeline.set(key, value);\n }\n }\n await pipeline.exec();\n }\n\n /**\n * Deletes multiple keys from the Upstash Redis database.\n * @param keys Array of keys to be deleted.\n * @returns Promise that resolves when all keys have been deleted.\n */\n async mdelete(keys: string[]): Promise<void> {\n await this.client.del(...keys.map(this._getPrefixedKey.bind(this)));\n }\n\n /**\n * Yields keys from the Upstash Redis database.\n * @param prefix Optional prefix to filter the keys. A wildcard (*) is always appended to the end.\n * @returns An AsyncGenerator that yields keys from the Upstash Redis database.\n */\n async *yieldKeys(prefix?: string): AsyncGenerator<string> {\n let pattern;\n if (prefix) {\n const wildcardPrefix = prefix.endsWith(\"*\") ? prefix : `${prefix}*`;\n pattern = `${this._getPrefixedKey(wildcardPrefix)}*`;\n } else {\n pattern = this._getPrefixedKey(\"*\");\n }\n let [cursor, batch] = await this.client.scan(0, {\n match: pattern,\n count: this.yieldKeysScanBatchSize,\n });\n for (const key of batch) {\n yield this._getDeprefixedKey(key);\n }\n while (cursor !== \"0\") {\n [cursor, batch] = await this.client.scan(cursor, {\n match: pattern,\n count: this.yieldKeysScanBatchSize,\n });\n for (const key of batch) {\n yield this._getDeprefixedKey(key);\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,IAAa,oBAAb,cAAuCA,uBAAAA,UAA8B;CACnE,eAAe,CAAC,aAAa,UAAU;CAEvC;CAEA;CAEA,yBAAmC;CAEnC;CAEA,YAAY,QAAgC;AAC1C,QAAM,OAAO;AACb,MAAI,OAAO,OACT,MAAK,SAAS,OAAO;WACZ,OAAO,OAChB,MAAK,SAAS,IAAIC,eAAAA,MAAa,OAAO,OAAO;MAE7C,OAAM,IAAI,MACR,kFACD;AAEH,OAAK,aAAa,OAAO;AACzB,OAAK,yBACH,OAAO,0BAA0B,KAAK;AACxC,OAAK,YAAY,OAAO;;CAG1B,gBAAgB,KAAa;AAC3B,MAAI,KAAK,UAEP,QAAO,GAAG,KAAK,UAAA,GAAwB;AAEzC,SAAO;;CAGT,kBAAkB,KAAa;AAC7B,MAAI,KAAK,UAEP,QAAO,IAAI,MAAM,KAAK,UAAU,SAAS,EAAiB;AAE5D,SAAO;;;;;;;CAQT,MAAM,KAAK,MAAgB;EACzB,MAAM,UAAU,IAAI,aAAa;EAEjC,MAAM,eAAe,KAAK,IAAI,KAAK,gBAAgB,KAAK,KAAK,CAAC;AAI9D,UAHwB,MAAM,KAAK,OAAO,KACxC,GAAG,aACJ,EACsB,KAAK,UAAU;AACpC,OAAI,CAAC,MACH;YACS,OAAO,UAAU,SAC1B,QAAO,QAAQ,OAAO,KAAK,UAAU,MAAM,CAAC;OAE5C,QAAO,QAAQ,OAAO,MAAM;IAE9B;;;;;;;CAQJ,MAAM,KAAK,eAAsD;EAC/D,MAAM,UAAU,IAAI,aAAa;EACjC,MAAM,uBAAuB,cAAc,KAAK,CAAC,KAAK,WAAW,CAC/D,KAAK,gBAAgB,IAAI,EACzB,QAAQ,OAAO,MAAM,CACtB,CAAC;EACF,MAAM,WAAW,KAAK,OAAO,UAAU;AACvC,OAAK,MAAM,CAAC,KAAK,UAAU,qBACzB,KAAI,KAAK,WACP,UAAS,MAAM,KAAK,KAAK,YAAY,MAAM;MAE3C,UAAS,IAAI,KAAK,MAAM;AAG5B,QAAM,SAAS,MAAM;;;;;;;CAQvB,MAAM,QAAQ,MAA+B;AAC3C,QAAM,KAAK,OAAO,IAAI,GAAG,KAAK,IAAI,KAAK,gBAAgB,KAAK,KAAK,CAAC,CAAC;;;;;;;CAQrE,OAAO,UAAU,QAAyC;EACxD,IAAI;AACJ,MAAI,QAAQ;GACV,MAAM,iBAAiB,OAAO,SAAS,IAAI,GAAG,SAAS,GAAG,OAAO;AACjE,aAAU,GAAG,KAAK,gBAAgB,eAAe,CAAC;QAElD,WAAU,KAAK,gBAAgB,IAAI;EAErC,IAAI,CAAC,QAAQ,SAAS,MAAM,KAAK,OAAO,KAAK,GAAG;GAC9C,OAAO;GACP,OAAO,KAAK;GACb,CAAC;AACF,OAAK,MAAM,OAAO,MAChB,OAAM,KAAK,kBAAkB,IAAI;AAEnC,SAAO,WAAW,KAAK;AACrB,IAAC,QAAQ,SAAS,MAAM,KAAK,OAAO,KAAK,QAAQ;IAC/C,OAAO;IACP,OAAO,KAAK;IACb,CAAC;AACF,QAAK,MAAM,OAAO,MAChB,OAAM,KAAK,kBAAkB,IAAI"}