@langchain/langgraph-checkpoint
Advanced tools
| //#region rolldown:runtime | ||
| var __create = Object.create; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __getProtoOf = Object.getPrototypeOf; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { | ||
| key = keys[i]; | ||
| if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { | ||
| get: ((k) => from[k]).bind(null, key), | ||
| enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable | ||
| }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { | ||
| value: mod, | ||
| enumerable: true | ||
| }) : target, mod)); | ||
| //#endregion | ||
| exports.__toESM = __toESM; |
| {"version":3,"file":"base.cjs","names":["uuid6","JsonPlusSerializer","WRITES_IDX_MAP: Record<string, number>","ERROR","SCHEDULED","INTERRUPT","RESUME"],"sources":["../src/base.ts"],"sourcesContent":["import type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { SerializerProtocol } from \"./serde/base.js\";\nimport { uuid6 } from \"./id.js\";\nimport type {\n PendingWrite,\n CheckpointPendingWrite,\n CheckpointMetadata,\n} from \"./types.js\";\nimport { ERROR, INTERRUPT, RESUME, SCHEDULED } from \"./serde/types.js\";\nimport { JsonPlusSerializer } from \"./serde/jsonplus.js\";\n\n/** @inline */\ntype ChannelVersion = number | string;\n\nexport type ChannelVersions = Record<string, ChannelVersion>;\n\nexport interface Checkpoint<\n N extends string = string,\n C extends string = string\n> {\n /**\n * The version of the checkpoint format. Currently 4\n */\n v: number;\n /**\n * Checkpoint ID {uuid6}\n */\n id: string;\n /**\n * Timestamp {new Date().toISOString()}\n */\n ts: string;\n /**\n * @default {}\n */\n channel_values: Record<C, unknown>;\n /**\n * @default {}\n */\n channel_versions: Record<C, ChannelVersion>;\n /**\n * @default {}\n */\n versions_seen: Record<N, Record<C, ChannelVersion>>;\n}\n\nexport interface ReadonlyCheckpoint extends Readonly<Checkpoint> {\n readonly channel_values: Readonly<Record<string, unknown>>;\n readonly channel_versions: Readonly<Record<string, ChannelVersion>>;\n readonly versions_seen: Readonly<\n Record<string, Readonly<Record<string, ChannelVersion>>>\n >;\n}\n\nexport function deepCopy<T>(obj: T): T {\n if (typeof obj !== \"object\" || obj === null) {\n return obj;\n }\n\n const newObj = Array.isArray(obj) ? [] : {};\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n (newObj as Record<PropertyKey, unknown>)[key] = deepCopy(\n (obj as Record<string, unknown>)[key]\n );\n }\n }\n\n return newObj as T;\n}\n\n/** @hidden */\nexport function emptyCheckpoint(): Checkpoint {\n return {\n v: 4,\n id: uuid6(-2),\n ts: new Date().toISOString(),\n channel_values: {},\n channel_versions: {},\n versions_seen: {},\n };\n}\n\n/** @hidden */\nexport function copyCheckpoint(checkpoint: ReadonlyCheckpoint): Checkpoint {\n return {\n v: checkpoint.v,\n id: checkpoint.id,\n ts: checkpoint.ts,\n channel_values: { ...checkpoint.channel_values },\n channel_versions: { ...checkpoint.channel_versions },\n versions_seen: deepCopy(checkpoint.versions_seen),\n };\n}\n\nexport interface CheckpointTuple {\n config: RunnableConfig;\n checkpoint: Checkpoint;\n metadata?: CheckpointMetadata;\n parentConfig?: RunnableConfig;\n pendingWrites?: CheckpointPendingWrite[];\n}\n\nexport type CheckpointListOptions = {\n limit?: number;\n before?: RunnableConfig;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n filter?: Record<string, any>;\n};\n\nexport abstract class BaseCheckpointSaver<V extends string | number = number> {\n serde: SerializerProtocol = new JsonPlusSerializer();\n\n constructor(serde?: SerializerProtocol) {\n this.serde = serde || this.serde;\n }\n\n async get(config: RunnableConfig): Promise<Checkpoint | undefined> {\n const value = await this.getTuple(config);\n return value ? value.checkpoint : undefined;\n }\n\n abstract getTuple(\n config: RunnableConfig\n ): Promise<CheckpointTuple | undefined>;\n\n abstract list(\n config: RunnableConfig,\n options?: CheckpointListOptions\n ): AsyncGenerator<CheckpointTuple>;\n\n abstract put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata,\n newVersions: ChannelVersions\n ): Promise<RunnableConfig>;\n\n /**\n * Store intermediate writes linked to a checkpoint.\n */\n abstract putWrites(\n config: RunnableConfig,\n writes: PendingWrite[],\n taskId: string\n ): Promise<void>;\n\n /**\n * Delete all checkpoints and writes associated with a specific thread ID.\n * @param threadId The thread ID whose checkpoints should be deleted.\n */\n abstract deleteThread(threadId: string): Promise<void>;\n\n /**\n * Generate the next version ID for a channel.\n *\n * Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions,\n * as long as they are monotonically increasing.\n */\n getNextVersion(current: V | undefined): V {\n if (typeof current === \"string\") {\n throw new Error(\"Please override this method to use string versions.\");\n }\n return (\n current !== undefined && typeof current === \"number\" ? current + 1 : 1\n ) as V;\n }\n}\n\nexport function compareChannelVersions(\n a: ChannelVersion,\n b: ChannelVersion\n): number {\n if (typeof a === \"number\" && typeof b === \"number\") {\n return Math.sign(a - b);\n }\n\n return String(a).localeCompare(String(b));\n}\n\nexport function maxChannelVersion(\n ...versions: ChannelVersion[]\n): ChannelVersion {\n return versions.reduce((max, version, idx) => {\n if (idx === 0) return version;\n return compareChannelVersions(max, version) >= 0 ? max : version;\n });\n}\n\n/**\n * Mapping from error type to error index.\n * Regular writes just map to their index in the list of writes being saved.\n * Special writes (e.g. errors) map to negative indices, to avoid those writes from\n * conflicting with regular writes.\n * Each Checkpointer implementation should use this mapping in put_writes.\n */\nexport const WRITES_IDX_MAP: Record<string, number> = {\n [ERROR]: -1,\n [SCHEDULED]: -2,\n [INTERRUPT]: -3,\n [RESUME]: -4,\n};\n\nexport function getCheckpointId(config: RunnableConfig): string {\n return (\n config.configurable?.checkpoint_id || config.configurable?.thread_ts || \"\"\n );\n}\n"],"mappings":";;;;;AAsDA,SAAgB,SAAY,KAAW;AACrC,KAAI,OAAO,QAAQ,YAAY,QAAQ,KACrC,QAAO;CAGT,MAAM,SAAS,MAAM,QAAQ,OAAO,KAAK;AAEzC,MAAK,MAAM,OAAO,IAChB,KAAI,OAAO,UAAU,eAAe,KAAK,KAAK,KAC5C,CAAC,OAAwC,OAAO,SAC7C,IAAgC;AAKvC,QAAO;;;AAIT,SAAgB,kBAA8B;AAC5C,QAAO;EACL,GAAG;EACH,IAAIA,iBAAM;EACV,qBAAI,IAAI,QAAO;EACf,gBAAgB;EAChB,kBAAkB;EAClB,eAAe;;;;AAKnB,SAAgB,eAAe,YAA4C;AACzE,QAAO;EACL,GAAG,WAAW;EACd,IAAI,WAAW;EACf,IAAI,WAAW;EACf,gBAAgB,EAAE,GAAG,WAAW;EAChC,kBAAkB,EAAE,GAAG,WAAW;EAClC,eAAe,SAAS,WAAW;;;AAmBvC,IAAsB,sBAAtB,MAA8E;CAC5E,QAA4B,IAAIC;CAEhC,YAAY,OAA4B;AACtC,OAAK,QAAQ,SAAS,KAAK;;CAG7B,MAAM,IAAI,QAAyD;EACjE,MAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,SAAO,QAAQ,MAAM,aAAa;;;;;;;;CAwCpC,eAAe,SAA2B;AACxC,MAAI,OAAO,YAAY,SACrB,OAAM,IAAI,MAAM;AAElB,SACE,YAAY,UAAa,OAAO,YAAY,WAAW,UAAU,IAAI;;;AAK3E,SAAgB,uBACd,GACA,GACQ;AACR,KAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SACxC,QAAO,KAAK,KAAK,IAAI;AAGvB,QAAO,OAAO,GAAG,cAAc,OAAO;;AAGxC,SAAgB,kBACd,GAAG,UACa;AAChB,QAAO,SAAS,QAAQ,KAAK,SAAS,QAAQ;AAC5C,MAAI,QAAQ,EAAG,QAAO;AACtB,SAAO,uBAAuB,KAAK,YAAY,IAAI,MAAM;;;;;;;;;;AAW7D,MAAaC,iBAAyC;EACnDC,sBAAQ;EACRC,0BAAY;EACZC,0BAAY;EACZC,uBAAS;;AAGZ,SAAgB,gBAAgB,QAAgC;AAC9D,QACE,OAAO,cAAc,iBAAiB,OAAO,cAAc,aAAa"} |
| import { SerializerProtocol } from "./serde/base.cjs"; | ||
| import { CheckpointMetadata, CheckpointPendingWrite, PendingWrite } from "./types.cjs"; | ||
| import { RunnableConfig } from "@langchain/core/runnables"; | ||
| //#region src/base.d.ts | ||
| /** @inline */ | ||
| type ChannelVersion = number | string; | ||
| type ChannelVersions = Record<string, ChannelVersion>; | ||
| interface Checkpoint<N extends string = string, C extends string = string> { | ||
| /** | ||
| * The version of the checkpoint format. Currently 4 | ||
| */ | ||
| v: number; | ||
| /** | ||
| * Checkpoint ID {uuid6} | ||
| */ | ||
| id: string; | ||
| /** | ||
| * Timestamp {new Date().toISOString()} | ||
| */ | ||
| ts: string; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| channel_values: Record<C, unknown>; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| channel_versions: Record<C, ChannelVersion>; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| versions_seen: Record<N, Record<C, ChannelVersion>>; | ||
| } | ||
| interface ReadonlyCheckpoint extends Readonly<Checkpoint> { | ||
| readonly channel_values: Readonly<Record<string, unknown>>; | ||
| readonly channel_versions: Readonly<Record<string, ChannelVersion>>; | ||
| readonly versions_seen: Readonly<Record<string, Readonly<Record<string, ChannelVersion>>>>; | ||
| } | ||
| declare function deepCopy<T>(obj: T): T; | ||
| /** @hidden */ | ||
| declare function emptyCheckpoint(): Checkpoint; | ||
| /** @hidden */ | ||
| declare function copyCheckpoint(checkpoint: ReadonlyCheckpoint): Checkpoint; | ||
| interface CheckpointTuple { | ||
| config: RunnableConfig; | ||
| checkpoint: Checkpoint; | ||
| metadata?: CheckpointMetadata; | ||
| parentConfig?: RunnableConfig; | ||
| pendingWrites?: CheckpointPendingWrite[]; | ||
| } | ||
| type CheckpointListOptions = { | ||
| limit?: number; | ||
| before?: RunnableConfig; | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| filter?: Record<string, any>; | ||
| }; | ||
| declare abstract class BaseCheckpointSaver<V extends string | number = number> { | ||
| serde: SerializerProtocol; | ||
| constructor(serde?: SerializerProtocol); | ||
| get(config: RunnableConfig): Promise<Checkpoint | undefined>; | ||
| abstract getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>; | ||
| abstract list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>; | ||
| abstract put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, newVersions: ChannelVersions): Promise<RunnableConfig>; | ||
| /** | ||
| * Store intermediate writes linked to a checkpoint. | ||
| */ | ||
| abstract putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>; | ||
| /** | ||
| * Delete all checkpoints and writes associated with a specific thread ID. | ||
| * @param threadId The thread ID whose checkpoints should be deleted. | ||
| */ | ||
| abstract deleteThread(threadId: string): Promise<void>; | ||
| /** | ||
| * Generate the next version ID for a channel. | ||
| * | ||
| * Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions, | ||
| * as long as they are monotonically increasing. | ||
| */ | ||
| getNextVersion(current: V | undefined): V; | ||
| } | ||
| declare function compareChannelVersions(a: ChannelVersion, b: ChannelVersion): number; | ||
| declare function maxChannelVersion(...versions: ChannelVersion[]): ChannelVersion; | ||
| /** | ||
| * Mapping from error type to error index. | ||
| * Regular writes just map to their index in the list of writes being saved. | ||
| * Special writes (e.g. errors) map to negative indices, to avoid those writes from | ||
| * conflicting with regular writes. | ||
| * Each Checkpointer implementation should use this mapping in put_writes. | ||
| */ | ||
| declare const WRITES_IDX_MAP: Record<string, number>; | ||
| declare function getCheckpointId(config: RunnableConfig): string; | ||
| //#endregion | ||
| export { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointTuple, ReadonlyCheckpoint, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion }; | ||
| //# sourceMappingURL=base.d.cts.map |
| {"version":3,"file":"base.d.cts","names":["RunnableConfig","SerializerProtocol","PendingWrite","CheckpointPendingWrite","CheckpointMetadata","ChannelVersion","ChannelVersions","Record","Checkpoint","C","N","ReadonlyCheckpoint","Readonly","deepCopy","T","emptyCheckpoint","copyCheckpoint","CheckpointTuple","CheckpointListOptions","BaseCheckpointSaver","Promise","AsyncGenerator","V","compareChannelVersions","maxChannelVersion","WRITES_IDX_MAP","getCheckpointId"],"sources":["../src/base.d.ts"],"sourcesContent":["import type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { SerializerProtocol } from \"./serde/base.js\";\nimport type { PendingWrite, CheckpointPendingWrite, CheckpointMetadata } from \"./types.js\";\n/** @inline */\ntype ChannelVersion = number | string;\nexport type ChannelVersions = Record<string, ChannelVersion>;\nexport interface Checkpoint<N extends string = string, C extends string = string> {\n /**\n * The version of the checkpoint format. Currently 4\n */\n v: number;\n /**\n * Checkpoint ID {uuid6}\n */\n id: string;\n /**\n * Timestamp {new Date().toISOString()}\n */\n ts: string;\n /**\n * @default {}\n */\n channel_values: Record<C, unknown>;\n /**\n * @default {}\n */\n channel_versions: Record<C, ChannelVersion>;\n /**\n * @default {}\n */\n versions_seen: Record<N, Record<C, ChannelVersion>>;\n}\nexport interface ReadonlyCheckpoint extends Readonly<Checkpoint> {\n readonly channel_values: Readonly<Record<string, unknown>>;\n readonly channel_versions: Readonly<Record<string, ChannelVersion>>;\n readonly versions_seen: Readonly<Record<string, Readonly<Record<string, ChannelVersion>>>>;\n}\nexport declare function deepCopy<T>(obj: T): T;\n/** @hidden */\nexport declare function emptyCheckpoint(): Checkpoint;\n/** @hidden */\nexport declare function copyCheckpoint(checkpoint: ReadonlyCheckpoint): Checkpoint;\nexport interface CheckpointTuple {\n config: RunnableConfig;\n checkpoint: Checkpoint;\n metadata?: CheckpointMetadata;\n parentConfig?: RunnableConfig;\n pendingWrites?: CheckpointPendingWrite[];\n}\nexport type CheckpointListOptions = {\n limit?: number;\n before?: RunnableConfig;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n filter?: Record<string, any>;\n};\nexport declare abstract class BaseCheckpointSaver<V extends string | number = number> {\n serde: SerializerProtocol;\n constructor(serde?: SerializerProtocol);\n get(config: RunnableConfig): Promise<Checkpoint | undefined>;\n abstract getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;\n abstract list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>;\n abstract put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, newVersions: ChannelVersions): Promise<RunnableConfig>;\n /**\n * Store intermediate writes linked to a checkpoint.\n */\n abstract putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;\n /**\n * Delete all checkpoints and writes associated with a specific thread ID.\n * @param threadId The thread ID whose checkpoints should be deleted.\n */\n abstract deleteThread(threadId: string): Promise<void>;\n /**\n * Generate the next version ID for a channel.\n *\n * Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions,\n * as long as they are monotonically increasing.\n */\n getNextVersion(current: V | undefined): V;\n}\nexport declare function compareChannelVersions(a: ChannelVersion, b: ChannelVersion): number;\nexport declare function maxChannelVersion(...versions: ChannelVersion[]): ChannelVersion;\n/**\n * Mapping from error type to error index.\n * Regular writes just map to their index in the list of writes being saved.\n * Special writes (e.g. errors) map to negative indices, to avoid those writes from\n * conflicting with regular writes.\n * Each Checkpointer implementation should use this mapping in put_writes.\n */\nexport declare const WRITES_IDX_MAP: Record<string, number>;\nexport declare function getCheckpointId(config: RunnableConfig): string;\nexport {};\n"],"mappings":"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"} |
| {"version":3,"file":"base.d.ts","names":["RunnableConfig","SerializerProtocol","PendingWrite","CheckpointPendingWrite","CheckpointMetadata","ChannelVersion","ChannelVersions","Record","Checkpoint","C","N","ReadonlyCheckpoint","Readonly","deepCopy","T","emptyCheckpoint","copyCheckpoint","CheckpointTuple","CheckpointListOptions","BaseCheckpointSaver","Promise","AsyncGenerator","V","compareChannelVersions","maxChannelVersion","WRITES_IDX_MAP","getCheckpointId"],"sources":["../src/base.d.ts"],"sourcesContent":["import type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { SerializerProtocol } from \"./serde/base.js\";\nimport type { PendingWrite, CheckpointPendingWrite, CheckpointMetadata } from \"./types.js\";\n/** @inline */\ntype ChannelVersion = number | string;\nexport type ChannelVersions = Record<string, ChannelVersion>;\nexport interface Checkpoint<N extends string = string, C extends string = string> {\n /**\n * The version of the checkpoint format. Currently 4\n */\n v: number;\n /**\n * Checkpoint ID {uuid6}\n */\n id: string;\n /**\n * Timestamp {new Date().toISOString()}\n */\n ts: string;\n /**\n * @default {}\n */\n channel_values: Record<C, unknown>;\n /**\n * @default {}\n */\n channel_versions: Record<C, ChannelVersion>;\n /**\n * @default {}\n */\n versions_seen: Record<N, Record<C, ChannelVersion>>;\n}\nexport interface ReadonlyCheckpoint extends Readonly<Checkpoint> {\n readonly channel_values: Readonly<Record<string, unknown>>;\n readonly channel_versions: Readonly<Record<string, ChannelVersion>>;\n readonly versions_seen: Readonly<Record<string, Readonly<Record<string, ChannelVersion>>>>;\n}\nexport declare function deepCopy<T>(obj: T): T;\n/** @hidden */\nexport declare function emptyCheckpoint(): Checkpoint;\n/** @hidden */\nexport declare function copyCheckpoint(checkpoint: ReadonlyCheckpoint): Checkpoint;\nexport interface CheckpointTuple {\n config: RunnableConfig;\n checkpoint: Checkpoint;\n metadata?: CheckpointMetadata;\n parentConfig?: RunnableConfig;\n pendingWrites?: CheckpointPendingWrite[];\n}\nexport type CheckpointListOptions = {\n limit?: number;\n before?: RunnableConfig;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n filter?: Record<string, any>;\n};\nexport declare abstract class BaseCheckpointSaver<V extends string | number = number> {\n serde: SerializerProtocol;\n constructor(serde?: SerializerProtocol);\n get(config: RunnableConfig): Promise<Checkpoint | undefined>;\n abstract getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;\n abstract list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>;\n abstract put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, newVersions: ChannelVersions): Promise<RunnableConfig>;\n /**\n * Store intermediate writes linked to a checkpoint.\n */\n abstract putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;\n /**\n * Delete all checkpoints and writes associated with a specific thread ID.\n * @param threadId The thread ID whose checkpoints should be deleted.\n */\n abstract deleteThread(threadId: string): Promise<void>;\n /**\n * Generate the next version ID for a channel.\n *\n * Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions,\n * as long as they are monotonically increasing.\n */\n getNextVersion(current: V | undefined): V;\n}\nexport declare function compareChannelVersions(a: ChannelVersion, b: ChannelVersion): number;\nexport declare function maxChannelVersion(...versions: ChannelVersion[]): ChannelVersion;\n/**\n * Mapping from error type to error index.\n * Regular writes just map to their index in the list of writes being saved.\n * Special writes (e.g. errors) map to negative indices, to avoid those writes from\n * conflicting with regular writes.\n * Each Checkpointer implementation should use this mapping in put_writes.\n */\nexport declare const WRITES_IDX_MAP: Record<string, number>;\nexport declare function getCheckpointId(config: RunnableConfig): string;\nexport {};\n"],"mappings":"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"} |
| {"version":3,"file":"base.cjs","names":["JsonPlusSerializer"],"sources":["../../src/cache/base.ts"],"sourcesContent":["import { SerializerProtocol } from \"../serde/base.js\";\nimport { JsonPlusSerializer } from \"../serde/jsonplus.js\";\n\nexport type CacheNamespace = string[];\nexport type CacheFullKey = [namespace: CacheNamespace, key: string];\n\nexport abstract class BaseCache<V = unknown> {\n serde: SerializerProtocol = new JsonPlusSerializer();\n\n /**\n * Initialize the cache with a serializer.\n *\n * @param serde - The serializer to use.\n */\n constructor(serde?: SerializerProtocol) {\n this.serde = serde || this.serde;\n }\n\n /**\n * Get the cached values for the given keys.\n *\n * @param keys - The keys to get.\n */\n abstract get(\n keys: CacheFullKey[]\n ): Promise<{ key: CacheFullKey; value: V }[]>;\n\n /**\n * Set the cached values for the given keys and TTLs.\n *\n * @param pairs - The pairs to set.\n */\n abstract set(\n pairs: { key: CacheFullKey; value: V; ttl?: number }[]\n ): Promise<void>;\n\n /**\n * Delete the cached values for the given namespaces.\n * If no namespaces are provided, clear all cached values.\n *\n * @param namespaces - The namespaces to clear.\n */\n abstract clear(namespaces: CacheNamespace[]): Promise<void>;\n}\n"],"mappings":";;;AAMA,IAAsB,YAAtB,MAA6C;CAC3C,QAA4B,IAAIA;;;;;;CAOhC,YAAY,OAA4B;AACtC,OAAK,QAAQ,SAAS,KAAK"} |
| import { SerializerProtocol } from "../serde/base.cjs"; | ||
| //#region src/cache/base.d.ts | ||
| type CacheNamespace = string[]; | ||
| type CacheFullKey = [namespace: CacheNamespace, key: string]; | ||
| declare abstract class BaseCache<V = unknown> { | ||
| serde: SerializerProtocol; | ||
| /** | ||
| * Initialize the cache with a serializer. | ||
| * | ||
| * @param serde - The serializer to use. | ||
| */ | ||
| constructor(serde?: SerializerProtocol); | ||
| /** | ||
| * Get the cached values for the given keys. | ||
| * | ||
| * @param keys - The keys to get. | ||
| */ | ||
| abstract get(keys: CacheFullKey[]): Promise<{ | ||
| key: CacheFullKey; | ||
| value: V; | ||
| }[]>; | ||
| /** | ||
| * Set the cached values for the given keys and TTLs. | ||
| * | ||
| * @param pairs - The pairs to set. | ||
| */ | ||
| abstract set(pairs: { | ||
| key: CacheFullKey; | ||
| value: V; | ||
| ttl?: number; | ||
| }[]): Promise<void>; | ||
| /** | ||
| * Delete the cached values for the given namespaces. | ||
| * If no namespaces are provided, clear all cached values. | ||
| * | ||
| * @param namespaces - The namespaces to clear. | ||
| */ | ||
| abstract clear(namespaces: CacheNamespace[]): Promise<void>; | ||
| } | ||
| //#endregion | ||
| export { BaseCache, CacheFullKey, CacheNamespace }; | ||
| //# sourceMappingURL=base.d.cts.map |
| {"version":3,"file":"base.d.cts","names":["SerializerProtocol","CacheNamespace","CacheFullKey","BaseCache","V","Promise"],"sources":["../../src/cache/base.d.ts"],"sourcesContent":["import { SerializerProtocol } from \"../serde/base.js\";\nexport type CacheNamespace = string[];\nexport type CacheFullKey = [namespace: CacheNamespace, key: string];\nexport declare abstract class BaseCache<V = unknown> {\n serde: SerializerProtocol;\n /**\n * Initialize the cache with a serializer.\n *\n * @param serde - The serializer to use.\n */\n constructor(serde?: SerializerProtocol);\n /**\n * Get the cached values for the given keys.\n *\n * @param keys - The keys to get.\n */\n abstract get(keys: CacheFullKey[]): Promise<{\n key: CacheFullKey;\n value: V;\n }[]>;\n /**\n * Set the cached values for the given keys and TTLs.\n *\n * @param pairs - The pairs to set.\n */\n abstract set(pairs: {\n key: CacheFullKey;\n value: V;\n ttl?: number;\n }[]): Promise<void>;\n /**\n * Delete the cached values for the given namespaces.\n * If no namespaces are provided, clear all cached values.\n *\n * @param namespaces - The namespaces to clear.\n */\n abstract clear(namespaces: CacheNamespace[]): Promise<void>;\n}\n"],"mappings":";;;KACYC,cAAAA;KACAC,YAAAA,eAA2BD;AAD3BA,uBAEkBE,SAFJ,CAAA,IAAA,OAAA,CAAA,CAAA;EACdD,KAAAA,EAEDF,kBAFa;EACMG;;;;;aAcjBD,CAAAA,KAAAA,CAAAA,EAPWF,kBAOXE;;;;;;WAmBkBD,GAAAA,CAAAA,IAAAA,EApBRC,YAoBQD,EAAAA,CAAAA,EApBSI,OAoBTJ,CAAAA;IAAmBI,GAAAA,EAnBrCH,YAmBqCG;WAlBnCD;;;;;;;;SAQFF;WACEE;;QAELC;;;;;;;6BAOqBJ,mBAAmBI"} |
| {"version":3,"file":"base.d.ts","names":["SerializerProtocol","CacheNamespace","CacheFullKey","BaseCache","V","Promise"],"sources":["../../src/cache/base.d.ts"],"sourcesContent":["import { SerializerProtocol } from \"../serde/base.js\";\nexport type CacheNamespace = string[];\nexport type CacheFullKey = [namespace: CacheNamespace, key: string];\nexport declare abstract class BaseCache<V = unknown> {\n serde: SerializerProtocol;\n /**\n * Initialize the cache with a serializer.\n *\n * @param serde - The serializer to use.\n */\n constructor(serde?: SerializerProtocol);\n /**\n * Get the cached values for the given keys.\n *\n * @param keys - The keys to get.\n */\n abstract get(keys: CacheFullKey[]): Promise<{\n key: CacheFullKey;\n value: V;\n }[]>;\n /**\n * Set the cached values for the given keys and TTLs.\n *\n * @param pairs - The pairs to set.\n */\n abstract set(pairs: {\n key: CacheFullKey;\n value: V;\n ttl?: number;\n }[]): Promise<void>;\n /**\n * Delete the cached values for the given namespaces.\n * If no namespaces are provided, clear all cached values.\n *\n * @param namespaces - The namespaces to clear.\n */\n abstract clear(namespaces: CacheNamespace[]): Promise<void>;\n}\n"],"mappings":";;;KACYC,cAAAA;KACAC,YAAAA,eAA2BD;AAD3BA,uBAEkBE,SAFJ,CAAA,IAAA,OAAA,CAAA,CAAA;EACdD,KAAAA,EAEDF,kBAFa;EACMG;;;;;aAcjBD,CAAAA,KAAAA,CAAAA,EAPWF,kBAOXE;;;;;;WAmBkBD,GAAAA,CAAAA,IAAAA,EApBRC,YAoBQD,EAAAA,CAAAA,EApBSI,OAoBTJ,CAAAA;IAAmBI,GAAAA,EAnBrCH,YAmBqCG;WAlBnCD;;;;;;;;SAQFF;WACEE;;QAELC;;;;;;;6BAOqBJ,mBAAmBI"} |
| {"version":3,"file":"memory.cjs","names":["BaseCache"],"sources":["../../src/cache/memory.ts"],"sourcesContent":["import { BaseCache, type CacheFullKey, type CacheNamespace } from \"./base.js\";\n\nexport class InMemoryCache<V = unknown> extends BaseCache<V> {\n private cache: {\n [namespace: string]: {\n [key: string]: {\n enc: string;\n val: Uint8Array | string;\n exp: number | null;\n };\n };\n } = {};\n\n async get(keys: CacheFullKey[]): Promise<{ key: CacheFullKey; value: V }[]> {\n if (!keys.length) return [];\n const now = Date.now();\n return (\n await Promise.all(\n keys.map(\n async (fullKey): Promise<{ key: CacheFullKey; value: V }[]> => {\n const [namespace, key] = fullKey;\n const strNamespace = namespace.join(\",\");\n\n if (strNamespace in this.cache && key in this.cache[strNamespace]) {\n const cached = this.cache[strNamespace][key];\n if (cached.exp == null || now < cached.exp) {\n const value = await this.serde.loadsTyped(\n cached.enc,\n cached.val\n );\n return [{ key: fullKey, value }];\n } else {\n delete this.cache[strNamespace][key];\n }\n }\n\n return [];\n }\n )\n )\n ).flat();\n }\n\n async set(\n pairs: { key: CacheFullKey; value: V; ttl?: number }[]\n ): Promise<void> {\n const now = Date.now();\n for (const { key: fullKey, value, ttl } of pairs) {\n const [namespace, key] = fullKey;\n const strNamespace = namespace.join(\",\");\n const [enc, val] = await this.serde.dumpsTyped(value);\n const exp = ttl != null ? ttl * 1000 + now : null;\n\n this.cache[strNamespace] ??= {};\n this.cache[strNamespace][key] = { enc, val, exp };\n }\n }\n\n async clear(namespaces: CacheNamespace[]): Promise<void> {\n if (!namespaces.length) {\n this.cache = {};\n return;\n }\n\n for (const namespace of namespaces) {\n const strNamespace = namespace.join(\",\");\n if (strNamespace in this.cache) delete this.cache[strNamespace];\n }\n }\n}\n"],"mappings":";;;AAEA,IAAa,gBAAb,cAAgDA,uBAAa;CAC3D,AAAQ,QAQJ;CAEJ,MAAM,IAAI,MAAkE;AAC1E,MAAI,CAAC,KAAK,OAAQ,QAAO;EACzB,MAAM,MAAM,KAAK;AACjB,UACE,MAAM,QAAQ,IACZ,KAAK,IACH,OAAO,YAAwD;GAC7D,MAAM,CAAC,WAAW,OAAO;GACzB,MAAM,eAAe,UAAU,KAAK;AAEpC,OAAI,gBAAgB,KAAK,SAAS,OAAO,KAAK,MAAM,eAAe;IACjE,MAAM,SAAS,KAAK,MAAM,cAAc;AACxC,QAAI,OAAO,OAAO,QAAQ,MAAM,OAAO,KAAK;KAC1C,MAAM,QAAQ,MAAM,KAAK,MAAM,WAC7B,OAAO,KACP,OAAO;AAET,YAAO,CAAC;MAAE,KAAK;MAAS;;UAExB,QAAO,KAAK,MAAM,cAAc;;AAIpC,UAAO;OAIb;;CAGJ,MAAM,IACJ,OACe;EACf,MAAM,MAAM,KAAK;AACjB,OAAK,MAAM,EAAE,KAAK,SAAS,OAAO,SAAS,OAAO;GAChD,MAAM,CAAC,WAAW,OAAO;GACzB,MAAM,eAAe,UAAU,KAAK;GACpC,MAAM,CAAC,KAAK,OAAO,MAAM,KAAK,MAAM,WAAW;GAC/C,MAAM,MAAM,OAAO,OAAO,MAAM,MAAO,MAAM;AAE7C,QAAK,MAAM,kBAAkB;AAC7B,QAAK,MAAM,cAAc,OAAO;IAAE;IAAK;IAAK;;;;CAIhD,MAAM,MAAM,YAA6C;AACvD,MAAI,CAAC,WAAW,QAAQ;AACtB,QAAK,QAAQ;AACb;;AAGF,OAAK,MAAM,aAAa,YAAY;GAClC,MAAM,eAAe,UAAU,KAAK;AACpC,OAAI,gBAAgB,KAAK,MAAO,QAAO,KAAK,MAAM"} |
| import { BaseCache, CacheFullKey, CacheNamespace } from "./base.cjs"; | ||
| //#region src/cache/memory.d.ts | ||
| declare class InMemoryCache<V = unknown> extends BaseCache<V> { | ||
| private cache; | ||
| get(keys: CacheFullKey[]): Promise<{ | ||
| key: CacheFullKey; | ||
| value: V; | ||
| }[]>; | ||
| set(pairs: { | ||
| key: CacheFullKey; | ||
| value: V; | ||
| ttl?: number; | ||
| }[]): Promise<void>; | ||
| clear(namespaces: CacheNamespace[]): Promise<void>; | ||
| } | ||
| //#endregion | ||
| export { InMemoryCache }; | ||
| //# sourceMappingURL=memory.d.cts.map |
| {"version":3,"file":"memory.d.cts","names":["BaseCache","CacheFullKey","CacheNamespace","InMemoryCache","V","Promise"],"sources":["../../src/cache/memory.d.ts"],"sourcesContent":["import { BaseCache, type CacheFullKey, type CacheNamespace } from \"./base.js\";\nexport declare class InMemoryCache<V = unknown> extends BaseCache<V> {\n private cache;\n get(keys: CacheFullKey[]): Promise<{\n key: CacheFullKey;\n value: V;\n }[]>;\n set(pairs: {\n key: CacheFullKey;\n value: V;\n ttl?: number;\n }[]): Promise<void>;\n clear(namespaces: CacheNamespace[]): Promise<void>;\n}\n"],"mappings":";;;cACqBG,mCAAmCH,UAAUI;;EAA7CD,GAAAA,CAAAA,IAAAA,EAEPF,YAFoB,EAAA,CAAA,EAEHI,OAFG,CAAA;IAAA,GAAA,EAGrBJ,YAHqB;IAAgCG,KAAAA,EAInDA,CAJmDA;KAEpDH,CAAAA;KACDA,CAAAA,KAAAA,EAAAA;IACEG,GAAAA,EAGFH,YAHEG;IAFgBC,KAAAA,EAMhBD,CANgBC;IAKlBJ,GAAAA,CAAAA,EAAAA,MAAAA;KACEG,CAAAA,EAELC,OAFKD,CAAAA,IAAAA,CAAAA;OAELC,CAAAA,UAAAA,EACYH,cADZG,EAAAA,CAAAA,EAC+BA,OAD/BA,CAAAA,IAAAA,CAAAA"} |
| {"version":3,"file":"memory.d.ts","names":["BaseCache","CacheFullKey","CacheNamespace","InMemoryCache","V","Promise"],"sources":["../../src/cache/memory.d.ts"],"sourcesContent":["import { BaseCache, type CacheFullKey, type CacheNamespace } from \"./base.js\";\nexport declare class InMemoryCache<V = unknown> extends BaseCache<V> {\n private cache;\n get(keys: CacheFullKey[]): Promise<{\n key: CacheFullKey;\n value: V;\n }[]>;\n set(pairs: {\n key: CacheFullKey;\n value: V;\n ttl?: number;\n }[]): Promise<void>;\n clear(namespaces: CacheNamespace[]): Promise<void>;\n}\n"],"mappings":";;;cACqBG,mCAAmCH,UAAUI;;EAA7CD,GAAAA,CAAAA,IAAAA,EAEPF,YAFoB,EAAA,CAAA,EAEHI,OAFG,CAAA;IAAA,GAAA,EAGrBJ,YAHqB;IAAgCG,KAAAA,EAInDA,CAJmDA;KAEpDH,CAAAA;KACDA,CAAAA,KAAAA,EAAAA;IACEG,GAAAA,EAGFH,YAHEG;IAFgBC,KAAAA,EAMhBD,CANgBC;IAKlBJ,GAAAA,CAAAA,EAAAA,MAAAA;KACEG,CAAAA,EAELC,OAFKD,CAAAA,IAAAA,CAAAA;OAELC,CAAAA,UAAAA,EACYH,cADZG,EAAAA,CAAAA,EAC+BA,OAD/BA,CAAAA,IAAAA,CAAAA"} |
| {"version":3,"file":"id.cjs","names":[],"sources":["../src/id.ts"],"sourcesContent":["import { v5, v6 } from \"uuid\";\n\nexport function uuid6(clockseq: number): string {\n return v6({ clockseq });\n}\n\n// Skip UUID validation check, since UUID6s\n// generated with negative clockseq are not\n// technically compliant, but still work.\n// See: https://github.com/uuidjs/uuid/issues/511\nexport function uuid5(name: string, namespace: string): string {\n const namespaceBytes = namespace\n .replace(/-/g, \"\")\n .match(/.{2}/g)!\n .map((byte) => parseInt(byte, 16));\n return v5(name, new Uint8Array(namespaceBytes));\n}\n"],"mappings":";;;;AAEA,SAAgB,MAAM,UAA0B;AAC9C,qBAAU,EAAE;;AAOd,SAAgB,MAAM,MAAc,WAA2B;CAC7D,MAAM,iBAAiB,UACpB,QAAQ,MAAM,IACd,MAAM,SACN,KAAK,SAAS,SAAS,MAAM;AAChC,qBAAU,MAAM,IAAI,WAAW"} |
| //#region src/id.d.ts | ||
| declare function uuid6(clockseq: number): string; | ||
| // Skip UUID validation check, since UUID6s | ||
| // generated with negative clockseq are not | ||
| // technically compliant, but still work. | ||
| // See: https://github.com/uuidjs/uuid/issues/511 | ||
| declare function uuid5(name: string, namespace: string): string; | ||
| //#endregion | ||
| export { uuid5, uuid6 }; | ||
| //# sourceMappingURL=id.d.cts.map |
| {"version":3,"file":"id.d.cts","names":["uuid6","uuid5"],"sources":["../src/id.d.ts"],"sourcesContent":["export declare function uuid6(clockseq: number): string;\n// Skip UUID validation check, since UUID6s\n// generated with negative clockseq are not\n// technically compliant, but still work.\n// See: https://github.com/uuidjs/uuid/issues/511\nexport declare function uuid5(name: string, namespace: string): string;\n"],"mappings":";iBAAwBA,KAAAA;AAAxB;AAKA;;;iBAAwBC,KAAAA"} |
| {"version":3,"file":"id.d.ts","names":["uuid6","uuid5"],"sources":["../src/id.d.ts"],"sourcesContent":["export declare function uuid6(clockseq: number): string;\n// Skip UUID validation check, since UUID6s\n// generated with negative clockseq are not\n// technically compliant, but still work.\n// See: https://github.com/uuidjs/uuid/issues/511\nexport declare function uuid5(name: string, namespace: string): string;\n"],"mappings":";iBAAwBA,KAAAA;AAAxB;AAKA;;;iBAAwBC,KAAAA"} |
| import { SerializerProtocol } from "./serde/base.cjs"; | ||
| import { All, CheckpointMetadata, CheckpointPendingWrite, PendingWrite, PendingWriteValue } from "./types.cjs"; | ||
| import { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointTuple, ReadonlyCheckpoint, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion } from "./base.cjs"; | ||
| import { MemorySaver } from "./memory.cjs"; | ||
| import { uuid5, uuid6 } from "./id.cjs"; | ||
| import { ChannelProtocol, ERROR, INTERRUPT, RESUME, SCHEDULED, SendProtocol, TASKS } from "./serde/types.cjs"; | ||
| import { BaseStore, GetOperation, IndexConfig, InvalidNamespaceError, Item, ListNamespacesOperation, MatchCondition, NameSpacePath, NamespaceMatchType, Operation, OperationResults, PutOperation, SearchItem, SearchOperation, getTextAtPath, tokenizePath } from "./store/base.cjs"; | ||
| import { AsyncBatchedStore } from "./store/batch.cjs"; | ||
| import { InMemoryStore, MemoryStore } from "./store/memory.cjs"; | ||
| import { BaseCache, CacheFullKey, CacheNamespace } from "./cache/base.cjs"; | ||
| import { InMemoryCache } from "./cache/memory.cjs"; | ||
| export { All, AsyncBatchedStore, BaseCache, BaseCheckpointSaver, BaseStore, CacheFullKey, CacheNamespace, ChannelProtocol, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointMetadata, CheckpointPendingWrite, CheckpointTuple, ERROR, GetOperation, INTERRUPT, InMemoryCache, InMemoryStore, IndexConfig, InvalidNamespaceError, Item, ListNamespacesOperation, MatchCondition, MemorySaver, MemoryStore, NameSpacePath, NamespaceMatchType, Operation, OperationResults, PendingWrite, PendingWriteValue, PutOperation, RESUME, ReadonlyCheckpoint, SCHEDULED, SearchItem, SearchOperation, SendProtocol, SerializerProtocol, TASKS, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, getTextAtPath, maxChannelVersion, tokenizePath, uuid5, uuid6 }; |
| {"version":3,"file":"memory.cjs","names":["BaseCheckpointSaver","TASKS","maxChannelVersion","getCheckpointId","deserializedCheckpoint: Checkpoint","pendingWrites: CheckpointPendingWrite[]","checkpointTuple: CheckpointTuple","key","preparedCheckpoint: Partial<Checkpoint>","copyCheckpoint","innerKey: [string, number]","WRITES_IDX_MAP"],"sources":["../src/memory.ts"],"sourcesContent":["import type { RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n BaseCheckpointSaver,\n Checkpoint,\n CheckpointListOptions,\n CheckpointTuple,\n copyCheckpoint,\n getCheckpointId,\n maxChannelVersion,\n WRITES_IDX_MAP,\n} from \"./base.js\";\nimport { SerializerProtocol } from \"./serde/base.js\";\nimport {\n CheckpointMetadata,\n CheckpointPendingWrite,\n PendingWrite,\n} from \"./types.js\";\nimport { TASKS } from \"./serde/types.js\";\n\nfunction _generateKey(\n threadId: string,\n checkpointNamespace: string,\n checkpointId: string\n) {\n return JSON.stringify([threadId, checkpointNamespace, checkpointId]);\n}\n\nfunction _parseKey(key: string) {\n const [threadId, checkpointNamespace, checkpointId] = JSON.parse(key);\n return { threadId, checkpointNamespace, checkpointId };\n}\n\nexport class MemorySaver extends BaseCheckpointSaver {\n // thread ID -> checkpoint namespace -> checkpoint ID -> checkpoint mapping\n storage: Record<\n string,\n Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>\n > = {};\n\n writes: Record<string, Record<string, [string, string, Uint8Array]>> = {};\n\n constructor(serde?: SerializerProtocol) {\n super(serde);\n }\n\n /** @internal */\n async _migratePendingSends(\n mutableCheckpoint: Checkpoint,\n threadId: string,\n checkpointNs: string,\n parentCheckpointId: string\n ) {\n const deseriablizableCheckpoint = mutableCheckpoint;\n const parentKey = _generateKey(threadId, checkpointNs, parentCheckpointId);\n\n const pendingSends = await Promise.all(\n Object.values(this.writes[parentKey] ?? {})\n .filter(([_taskId, channel]) => channel === TASKS)\n .map(\n async ([_taskId, _channel, writes]) =>\n await this.serde.loadsTyped(\"json\", writes)\n )\n );\n\n deseriablizableCheckpoint.channel_values ??= {};\n deseriablizableCheckpoint.channel_values[TASKS] = pendingSends;\n\n deseriablizableCheckpoint.channel_versions ??= {};\n deseriablizableCheckpoint.channel_versions[TASKS] =\n Object.keys(deseriablizableCheckpoint.channel_versions).length > 0\n ? maxChannelVersion(\n ...Object.values(deseriablizableCheckpoint.channel_versions)\n )\n : this.getNextVersion(undefined);\n }\n\n async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {\n const thread_id = config.configurable?.thread_id;\n const checkpoint_ns = config.configurable?.checkpoint_ns ?? \"\";\n let checkpoint_id = getCheckpointId(config);\n\n if (checkpoint_id) {\n const saved = this.storage[thread_id]?.[checkpoint_ns]?.[checkpoint_id];\n if (saved !== undefined) {\n const [checkpoint, metadata, parentCheckpointId] = saved;\n const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id);\n const deserializedCheckpoint: Checkpoint = await this.serde.loadsTyped(\n \"json\",\n checkpoint\n );\n\n if (deserializedCheckpoint.v < 4 && parentCheckpointId !== undefined) {\n await this._migratePendingSends(\n deserializedCheckpoint,\n thread_id,\n checkpoint_ns,\n parentCheckpointId\n );\n }\n\n const pendingWrites: CheckpointPendingWrite[] = await Promise.all(\n Object.values(this.writes[key] || {}).map(\n async ([taskId, channel, value]) => {\n return [\n taskId,\n channel,\n await this.serde.loadsTyped(\"json\", value),\n ];\n }\n )\n );\n const checkpointTuple: CheckpointTuple = {\n config,\n checkpoint: deserializedCheckpoint,\n metadata: (await this.serde.loadsTyped(\n \"json\",\n metadata\n )) as CheckpointMetadata,\n pendingWrites,\n };\n if (parentCheckpointId !== undefined) {\n checkpointTuple.parentConfig = {\n configurable: {\n thread_id,\n checkpoint_ns,\n checkpoint_id: parentCheckpointId,\n },\n };\n }\n return checkpointTuple;\n }\n } else {\n const checkpoints = this.storage[thread_id]?.[checkpoint_ns];\n if (checkpoints !== undefined) {\n // eslint-disable-next-line prefer-destructuring\n checkpoint_id = Object.keys(checkpoints).sort((a, b) =>\n b.localeCompare(a)\n )[0];\n const saved = checkpoints[checkpoint_id];\n const [checkpoint, metadata, parentCheckpointId] = saved;\n const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id);\n const deserializedCheckpoint: Checkpoint = await this.serde.loadsTyped(\n \"json\",\n checkpoint\n );\n\n if (deserializedCheckpoint.v < 4 && parentCheckpointId !== undefined) {\n await this._migratePendingSends(\n deserializedCheckpoint,\n thread_id,\n checkpoint_ns,\n parentCheckpointId\n );\n }\n\n const pendingWrites: CheckpointPendingWrite[] = await Promise.all(\n Object.values(this.writes[key] || {}).map(\n async ([taskId, channel, value]) => {\n return [\n taskId,\n channel,\n await this.serde.loadsTyped(\"json\", value),\n ];\n }\n )\n );\n const checkpointTuple: CheckpointTuple = {\n config: {\n configurable: {\n thread_id,\n checkpoint_id,\n checkpoint_ns,\n },\n },\n checkpoint: deserializedCheckpoint,\n metadata: (await this.serde.loadsTyped(\n \"json\",\n metadata\n )) as CheckpointMetadata,\n pendingWrites,\n };\n if (parentCheckpointId !== undefined) {\n checkpointTuple.parentConfig = {\n configurable: {\n thread_id,\n checkpoint_ns,\n checkpoint_id: parentCheckpointId,\n },\n };\n }\n return checkpointTuple;\n }\n }\n\n return undefined;\n }\n\n async *list(\n config: RunnableConfig,\n options?: CheckpointListOptions\n ): AsyncGenerator<CheckpointTuple> {\n // eslint-disable-next-line prefer-const\n let { before, limit, filter } = options ?? {};\n const threadIds = config.configurable?.thread_id\n ? [config.configurable?.thread_id]\n : Object.keys(this.storage);\n const configCheckpointNamespace = config.configurable?.checkpoint_ns;\n const configCheckpointId = config.configurable?.checkpoint_id;\n\n for (const threadId of threadIds) {\n for (const checkpointNamespace of Object.keys(\n this.storage[threadId] ?? {}\n )) {\n if (\n configCheckpointNamespace !== undefined &&\n checkpointNamespace !== configCheckpointNamespace\n ) {\n continue;\n }\n const checkpoints = this.storage[threadId]?.[checkpointNamespace] ?? {};\n const sortedCheckpoints = Object.entries(checkpoints).sort((a, b) =>\n b[0].localeCompare(a[0])\n );\n\n for (const [\n checkpointId,\n [checkpoint, metadataStr, parentCheckpointId],\n ] of sortedCheckpoints) {\n // Filter by checkpoint ID from config\n if (configCheckpointId && checkpointId !== configCheckpointId) {\n continue;\n }\n\n // Filter by checkpoint ID from before config\n if (\n before &&\n before.configurable?.checkpoint_id &&\n checkpointId >= before.configurable.checkpoint_id\n ) {\n continue;\n }\n\n // Parse metadata\n const metadata = (await this.serde.loadsTyped(\n \"json\",\n metadataStr\n )) as CheckpointMetadata;\n\n if (\n filter &&\n !Object.entries(filter).every(\n ([key, value]) =>\n (metadata as unknown as Record<string, unknown>)[key] === value\n )\n ) {\n continue;\n }\n\n // Limit search results\n if (limit !== undefined) {\n if (limit <= 0) break;\n limit -= 1;\n }\n\n const key = _generateKey(threadId, checkpointNamespace, checkpointId);\n const writes = Object.values(this.writes[key] || {});\n\n const pendingWrites: CheckpointPendingWrite[] = await Promise.all(\n writes.map(async ([taskId, channel, value]) => {\n return [\n taskId,\n channel,\n await this.serde.loadsTyped(\"json\", value),\n ];\n })\n );\n\n const deserializedCheckpoint = await this.serde.loadsTyped(\n \"json\",\n checkpoint\n );\n\n if (\n deserializedCheckpoint.v < 4 &&\n parentCheckpointId !== undefined\n ) {\n await this._migratePendingSends(\n deserializedCheckpoint,\n threadId,\n checkpointNamespace,\n parentCheckpointId\n );\n }\n\n const checkpointTuple: CheckpointTuple = {\n config: {\n configurable: {\n thread_id: threadId,\n checkpoint_ns: checkpointNamespace,\n checkpoint_id: checkpointId,\n },\n },\n checkpoint: deserializedCheckpoint,\n metadata,\n pendingWrites,\n };\n if (parentCheckpointId !== undefined) {\n checkpointTuple.parentConfig = {\n configurable: {\n thread_id: threadId,\n checkpoint_ns: checkpointNamespace,\n checkpoint_id: parentCheckpointId,\n },\n };\n }\n yield checkpointTuple;\n }\n }\n }\n }\n\n async put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata\n ): Promise<RunnableConfig> {\n const preparedCheckpoint: Partial<Checkpoint> = copyCheckpoint(checkpoint);\n const threadId = config.configurable?.thread_id;\n const checkpointNamespace = config.configurable?.checkpoint_ns ?? \"\";\n if (threadId === undefined) {\n throw new Error(\n `Failed to put checkpoint. The passed RunnableConfig is missing a required \"thread_id\" field in its \"configurable\" property.`\n );\n }\n\n if (!this.storage[threadId]) {\n this.storage[threadId] = {};\n }\n if (!this.storage[threadId][checkpointNamespace]) {\n this.storage[threadId][checkpointNamespace] = {};\n }\n\n const [[, serializedCheckpoint], [, serializedMetadata]] =\n await Promise.all([\n this.serde.dumpsTyped(preparedCheckpoint),\n this.serde.dumpsTyped(metadata),\n ]);\n\n this.storage[threadId][checkpointNamespace][checkpoint.id] = [\n serializedCheckpoint,\n serializedMetadata,\n config.configurable?.checkpoint_id, // parent\n ];\n\n return {\n configurable: {\n thread_id: threadId,\n checkpoint_ns: checkpointNamespace,\n checkpoint_id: checkpoint.id,\n },\n };\n }\n\n async putWrites(\n config: RunnableConfig,\n writes: PendingWrite[],\n taskId: string\n ): Promise<void> {\n const threadId = config.configurable?.thread_id;\n const checkpointNamespace = config.configurable?.checkpoint_ns;\n const checkpointId = config.configurable?.checkpoint_id;\n if (threadId === undefined) {\n throw new Error(\n `Failed to put writes. The passed RunnableConfig is missing a required \"thread_id\" field in its \"configurable\" property`\n );\n }\n if (checkpointId === undefined) {\n throw new Error(\n `Failed to put writes. The passed RunnableConfig is missing a required \"checkpoint_id\" field in its \"configurable\" property.`\n );\n }\n const outerKey = _generateKey(threadId, checkpointNamespace, checkpointId);\n const outerWrites_ = this.writes[outerKey];\n if (this.writes[outerKey] === undefined) {\n this.writes[outerKey] = {};\n }\n\n await Promise.all(\n writes.map(async ([channel, value], idx) => {\n const [, serializedValue] = await this.serde.dumpsTyped(value);\n const innerKey: [string, number] = [\n taskId,\n WRITES_IDX_MAP[channel] || idx,\n ];\n const innerKeyStr = `${innerKey[0]},${innerKey[1]}`;\n if (innerKey[1] >= 0 && outerWrites_ && innerKeyStr in outerWrites_) {\n return;\n }\n this.writes[outerKey][innerKeyStr] = [taskId, channel, serializedValue];\n })\n );\n }\n\n async deleteThread(threadId: string): Promise<void> {\n delete this.storage[threadId];\n for (const key of Object.keys(this.writes)) {\n if (_parseKey(key).threadId === threadId) delete this.writes[key];\n }\n }\n}\n"],"mappings":"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"} |
| import { SerializerProtocol } from "./serde/base.cjs"; | ||
| import { CheckpointMetadata, PendingWrite } from "./types.cjs"; | ||
| import { BaseCheckpointSaver, Checkpoint, CheckpointListOptions, CheckpointTuple } from "./base.cjs"; | ||
| import { RunnableConfig } from "@langchain/core/runnables"; | ||
| //#region src/memory.d.ts | ||
| declare class MemorySaver extends BaseCheckpointSaver { | ||
| // thread ID -> checkpoint namespace -> checkpoint ID -> checkpoint mapping | ||
| storage: Record<string, Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>>; | ||
| writes: Record<string, Record<string, [string, string, Uint8Array]>>; | ||
| constructor(serde?: SerializerProtocol); | ||
| /** @internal */ | ||
| _migratePendingSends(mutableCheckpoint: Checkpoint, threadId: string, checkpointNs: string, parentCheckpointId: string): Promise<void>; | ||
| getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>; | ||
| list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>; | ||
| put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig>; | ||
| putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>; | ||
| deleteThread(threadId: string): Promise<void>; | ||
| } | ||
| //#endregion | ||
| export { MemorySaver }; | ||
| //# sourceMappingURL=memory.d.cts.map |
| {"version":3,"file":"memory.d.cts","names":["RunnableConfig","BaseCheckpointSaver","Checkpoint","CheckpointListOptions","CheckpointTuple","SerializerProtocol","CheckpointMetadata","PendingWrite","MemorySaver","Uint8Array","Record","Promise","AsyncGenerator"],"sources":["../src/memory.d.ts"],"sourcesContent":["import type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { BaseCheckpointSaver, Checkpoint, CheckpointListOptions, CheckpointTuple } from \"./base.js\";\nimport { SerializerProtocol } from \"./serde/base.js\";\nimport { CheckpointMetadata, PendingWrite } from \"./types.js\";\nexport declare class MemorySaver extends BaseCheckpointSaver {\n // thread ID -> checkpoint namespace -> checkpoint ID -> checkpoint mapping\n storage: Record<string, Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>>;\n writes: Record<string, Record<string, [string, string, Uint8Array]>>;\n constructor(serde?: SerializerProtocol);\n /** @internal */\n _migratePendingSends(mutableCheckpoint: Checkpoint, threadId: string, checkpointNs: string, parentCheckpointId: string): Promise<void>;\n getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;\n list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>;\n put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig>;\n putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;\n deleteThread(threadId: string): Promise<void>;\n}\n"],"mappings":";;;;;;cAIqBQ,WAAAA,SAAoBP,mBAAAA;;EAApBO,OAAAA,EAERE,MAFmB,CAAA,MAAA,EAEJA,MAFI,CAAA,MAAA,EAEWA,MAFX,CAAA,MAAA,EAAA,CAE2BD,UAF3B,EAEuCA,UAFvC,EAAA,MAAA,GAAA,SAAA,CAAA,CAAA,CAAA,CAAA;EAAA,MAAA,EAGpBC,MAHoB,CAAA,MAAA,EAGLA,MAHK,CAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAG2BD,UAH3B,CAAA,CAAA,CAAA;aAE2BA,CAAAA,KAAAA,CAAAA,EAEnCJ,kBAFmCI;;sBAAhBC,CAAAA,iBAAAA,EAICR,UAJDQ,EAAAA,QAAAA,EAAAA,MAAAA,EAAAA,YAAAA,EAAAA,MAAAA,EAAAA,kBAAAA,EAAAA,MAAAA,CAAAA,EAIkFC,OAJlFD,CAAAA,IAAAA,CAAAA;UAAfA,CAAAA,MAAAA,EAKPV,cALOU,CAAAA,EAKUC,OALVD,CAKkBN,eALlBM,GAAAA,SAAAA,CAAAA;MAAfA,CAAAA,MAAAA,EAMIV,cANJU,EAAAA,OAAAA,CAAAA,EAM8BP,qBAN9BO,CAAAA,EAMsDE,cANtDF,CAMqEN,eANrEM,CAAAA;KAC8CD,CAAAA,MAAAA,EAM3CT,cAN2CS,EAAAA,UAAAA,EAMfP,UANeO,EAAAA,QAAAA,EAMOH,kBANPG,CAAAA,EAM4BE,OAN5BF,CAMoCT,cANpCS,CAAAA;WAAhCC,CAAAA,MAAAA,EAOLV,cAPKU,EAAAA,MAAAA,EAOmBH,YAPnBG,EAAAA,EAAAA,MAAAA,EAAAA,MAAAA,CAAAA,EAOoDC,OAPpDD,CAAAA,IAAAA,CAAAA;cAAfA,CAAAA,QAAAA,EAAAA,MAAAA,CAAAA,EAQwBC,OARxBD,CAAAA,IAAAA,CAAAA"} |
| {"version":3,"file":"memory.d.ts","names":["RunnableConfig","BaseCheckpointSaver","Checkpoint","CheckpointListOptions","CheckpointTuple","SerializerProtocol","CheckpointMetadata","PendingWrite","MemorySaver","Uint8Array","Record","Promise","AsyncGenerator"],"sources":["../src/memory.d.ts"],"sourcesContent":["import type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { BaseCheckpointSaver, Checkpoint, CheckpointListOptions, CheckpointTuple } from \"./base.js\";\nimport { SerializerProtocol } from \"./serde/base.js\";\nimport { CheckpointMetadata, PendingWrite } from \"./types.js\";\nexport declare class MemorySaver extends BaseCheckpointSaver {\n // thread ID -> checkpoint namespace -> checkpoint ID -> checkpoint mapping\n storage: Record<string, Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>>;\n writes: Record<string, Record<string, [string, string, Uint8Array]>>;\n constructor(serde?: SerializerProtocol);\n /** @internal */\n _migratePendingSends(mutableCheckpoint: Checkpoint, threadId: string, checkpointNs: string, parentCheckpointId: string): Promise<void>;\n getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;\n list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>;\n put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig>;\n putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;\n deleteThread(threadId: string): Promise<void>;\n}\n"],"mappings":";;;;;;cAIqBQ,WAAAA,SAAoBP,mBAAAA;;EAApBO,OAAAA,EAERE,MAFmB,CAAA,MAAA,EAEJA,MAFI,CAAA,MAAA,EAEWA,MAFX,CAAA,MAAA,EAAA,CAE2BD,UAF3B,EAEuCA,UAFvC,EAAA,MAAA,GAAA,SAAA,CAAA,CAAA,CAAA,CAAA;EAAA,MAAA,EAGpBC,MAHoB,CAAA,MAAA,EAGLA,MAHK,CAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAG2BD,UAH3B,CAAA,CAAA,CAAA;aAE2BA,CAAAA,KAAAA,CAAAA,EAEnCJ,kBAFmCI;;sBAAhBC,CAAAA,iBAAAA,EAICR,UAJDQ,EAAAA,QAAAA,EAAAA,MAAAA,EAAAA,YAAAA,EAAAA,MAAAA,EAAAA,kBAAAA,EAAAA,MAAAA,CAAAA,EAIkFC,OAJlFD,CAAAA,IAAAA,CAAAA;UAAfA,CAAAA,MAAAA,EAKPV,cALOU,CAAAA,EAKUC,OALVD,CAKkBN,eALlBM,GAAAA,SAAAA,CAAAA;MAAfA,CAAAA,MAAAA,EAMIV,cANJU,EAAAA,OAAAA,CAAAA,EAM8BP,qBAN9BO,CAAAA,EAMsDE,cANtDF,CAMqEN,eANrEM,CAAAA;KAC8CD,CAAAA,MAAAA,EAM3CT,cAN2CS,EAAAA,UAAAA,EAMfP,UANeO,EAAAA,QAAAA,EAMOH,kBANPG,CAAAA,EAM4BE,OAN5BF,CAMoCT,cANpCS,CAAAA;WAAhCC,CAAAA,MAAAA,EAOLV,cAPKU,EAAAA,MAAAA,EAOmBH,YAPnBG,EAAAA,EAAAA,MAAAA,EAAAA,MAAAA,CAAAA,EAOoDC,OAPpDD,CAAAA,IAAAA,CAAAA;cAAfA,CAAAA,QAAAA,EAAAA,MAAAA,CAAAA,EAQwBC,OARxBD,CAAAA,IAAAA,CAAAA"} |
| //#region src/serde/base.d.ts | ||
| interface SerializerProtocol { | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| dumpsTyped(data: any): Promise<[string, Uint8Array]>; | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| loadsTyped(type: string, data: Uint8Array | string): Promise<any>; | ||
| } | ||
| //#endregion | ||
| export { SerializerProtocol }; | ||
| //# sourceMappingURL=base.d.cts.map |
| {"version":3,"file":"base.d.cts","names":["SerializerProtocol","Uint8Array","Promise"],"sources":["../../src/serde/base.d.ts"],"sourcesContent":["export interface SerializerProtocol {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n dumpsTyped(data: any): Promise<[string, Uint8Array]>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n loadsTyped(type: string, data: Uint8Array | string): Promise<any>;\n}\n"],"mappings":";UAAiBA,kBAAAA;EAAAA;EAAkB,UAAA,CAAA,IAAA,EAAA,GAAA,CAAA,EAERE,OAFQ,CAAA,CAAA,MAAA,EAESD,UAFT,CAAA,CAAA;;YAERC,CAAAA,IAAAA,EAAAA,MAAAA,EAAAA,IAAAA,EAEQD,UAFRC,GAAAA,MAAAA,CAAAA,EAE8BA,OAF9BA,CAAAA,GAAAA,CAAAA"} |
| {"version":3,"file":"base.d.ts","names":["SerializerProtocol","Uint8Array","Promise"],"sources":["../../src/serde/base.d.ts"],"sourcesContent":["export interface SerializerProtocol {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n dumpsTyped(data: any): Promise<[string, Uint8Array]>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n loadsTyped(type: string, data: Uint8Array | string): Promise<any>;\n}\n"],"mappings":";UAAiBA,kBAAAA;EAAAA;EAAkB,UAAA,CAAA,IAAA,EAAA,GAAA,CAAA,EAERE,OAFQ,CAAA,CAAA,MAAA,EAESD,UAFT,CAAA,CAAA;;YAERC,CAAAA,IAAAA,EAAAA,MAAAA,EAAAA,IAAAA,EAEQD,UAFRC,GAAAA,MAAAA,CAAAA,EAE8BA,OAF9BA,CAAAA,GAAAA,CAAAA"} |
| {"version":3,"file":"jsonplus.cjs","names":["revivedObj: any","constructor: any","stringify"],"sources":["../../src/serde/jsonplus.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable no-instanceof/no-instanceof */\nimport { load } from \"@langchain/core/load\";\nimport { SerializerProtocol } from \"./base.js\";\nimport { stringify } from \"./utils/fast-safe-stringify/index.js\";\n\nfunction isLangChainSerializedObject(value: Record<string, unknown>) {\n return (\n value !== null &&\n value.lc === 1 &&\n value.type === \"constructor\" &&\n Array.isArray(value.id)\n );\n}\n\n/**\n * The replacer in stringify does not allow delegation to built-in LangChain\n * serialization methods, and instead immediately calls `.toJSON()` and\n * continues to stringify subfields.\n *\n * We therefore must start from the most nested elements in the input and\n * deserialize upwards rather than top-down.\n */\nasync function _reviver(value: any): Promise<any> {\n if (value && typeof value === \"object\") {\n if (Array.isArray(value)) {\n const revivedArray = await Promise.all(\n value.map((item) => _reviver(item))\n );\n return revivedArray;\n } else {\n const revivedObj: any = {};\n for (const [k, v] of Object.entries(value)) {\n revivedObj[k] = await _reviver(v);\n }\n\n if (revivedObj.lc === 2 && revivedObj.type === \"undefined\") {\n return undefined;\n } else if (\n revivedObj.lc === 2 &&\n revivedObj.type === \"constructor\" &&\n Array.isArray(revivedObj.id)\n ) {\n try {\n const constructorName = revivedObj.id[revivedObj.id.length - 1];\n let constructor: any;\n\n switch (constructorName) {\n case \"Set\":\n constructor = Set;\n break;\n case \"Map\":\n constructor = Map;\n break;\n case \"RegExp\":\n constructor = RegExp;\n break;\n case \"Error\":\n constructor = Error;\n break;\n default:\n return revivedObj;\n }\n if (revivedObj.method) {\n return (constructor as any)[revivedObj.method](\n ...(revivedObj.args || [])\n );\n } else {\n return new (constructor as any)(...(revivedObj.args || []));\n }\n } catch (error) {\n return revivedObj;\n }\n } else if (isLangChainSerializedObject(revivedObj)) {\n return load(JSON.stringify(revivedObj));\n }\n\n return revivedObj;\n }\n }\n return value;\n}\n\nfunction _encodeConstructorArgs(\n // eslint-disable-next-line @typescript-eslint/ban-types\n constructor: Function,\n method?: string,\n args?: any[],\n kwargs?: Record<string, any>\n): object {\n return {\n lc: 2,\n type: \"constructor\",\n id: [constructor.name],\n method: method ?? null,\n args: args ?? [],\n kwargs: kwargs ?? {},\n };\n}\n\nfunction _default(obj: any): any {\n if (obj === undefined) {\n return {\n lc: 2,\n type: \"undefined\",\n };\n } else if (obj instanceof Set || obj instanceof Map) {\n return _encodeConstructorArgs(obj.constructor, undefined, [\n Array.from(obj),\n ]);\n } else if (obj instanceof RegExp) {\n return _encodeConstructorArgs(RegExp, undefined, [obj.source, obj.flags]);\n } else if (obj instanceof Error) {\n return _encodeConstructorArgs(obj.constructor, undefined, [obj.message]);\n // TODO: Remove special case\n } else if (obj?.lg_name === \"Send\") {\n return {\n node: obj.node,\n args: obj.args,\n };\n } else {\n return obj;\n }\n}\n\nexport class JsonPlusSerializer implements SerializerProtocol {\n protected _dumps(obj: any): Uint8Array {\n const encoder = new TextEncoder();\n return encoder.encode(\n stringify(obj, (_: string, value: any) => {\n return _default(value);\n })\n );\n }\n\n async dumpsTyped(obj: any): Promise<[string, Uint8Array]> {\n if (obj instanceof Uint8Array) {\n return [\"bytes\", obj];\n } else {\n return [\"json\", this._dumps(obj)];\n }\n }\n\n protected async _loads(data: string): Promise<any> {\n const parsed = JSON.parse(data);\n return _reviver(parsed);\n }\n\n async loadsTyped(type: string, data: Uint8Array | string): Promise<any> {\n if (type === \"bytes\") {\n return typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n } else if (type === \"json\") {\n return this._loads(\n typeof data === \"string\" ? data : new TextDecoder().decode(data)\n );\n } else {\n throw new Error(`Unknown serialization type: ${type}`);\n }\n }\n}\n"],"mappings":";;;;;AAMA,SAAS,4BAA4B,OAAgC;AACnE,QACE,UAAU,QACV,MAAM,OAAO,KACb,MAAM,SAAS,iBACf,MAAM,QAAQ,MAAM;;;;;;;;;;AAYxB,eAAe,SAAS,OAA0B;AAChD,KAAI,SAAS,OAAO,UAAU,SAC5B,KAAI,MAAM,QAAQ,QAAQ;EACxB,MAAM,eAAe,MAAM,QAAQ,IACjC,MAAM,KAAK,SAAS,SAAS;AAE/B,SAAO;QACF;EACL,MAAMA,aAAkB;AACxB,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,OAClC,YAAW,KAAK,MAAM,SAAS;AAGjC,MAAI,WAAW,OAAO,KAAK,WAAW,SAAS,YAC7C,QAAO;WAEP,WAAW,OAAO,KAClB,WAAW,SAAS,iBACpB,MAAM,QAAQ,WAAW,IAEzB,KAAI;GACF,MAAM,kBAAkB,WAAW,GAAG,WAAW,GAAG,SAAS;GAC7D,IAAIC;AAEJ,WAAQ,iBAAR;IACE,KAAK;AACH,mBAAc;AACd;IACF,KAAK;AACH,mBAAc;AACd;IACF,KAAK;AACH,mBAAc;AACd;IACF,KAAK;AACH,mBAAc;AACd;IACF,QACE,QAAO;;AAEX,OAAI,WAAW,OACb,QAAQ,YAAoB,WAAW,QACrC,GAAI,WAAW,QAAQ;OAGzB,QAAO,IAAK,YAAoB,GAAI,WAAW,QAAQ;WAElD,OAAO;AACd,UAAO;;WAEA,4BAA4B,YACrC,wCAAY,KAAK,UAAU;AAG7B,SAAO;;AAGX,QAAO;;AAGT,SAAS,uBAEP,aACA,QACA,MACA,QACQ;AACR,QAAO;EACL,IAAI;EACJ,MAAM;EACN,IAAI,CAAC,YAAY;EACjB,QAAQ,UAAU;EAClB,MAAM,QAAQ;EACd,QAAQ,UAAU;;;AAItB,SAAS,SAAS,KAAe;AAC/B,KAAI,QAAQ,OACV,QAAO;EACL,IAAI;EACJ,MAAM;;UAEC,eAAe,OAAO,eAAe,IAC9C,QAAO,uBAAuB,IAAI,aAAa,QAAW,CACxD,MAAM,KAAK;UAEJ,eAAe,OACxB,QAAO,uBAAuB,QAAQ,QAAW,CAAC,IAAI,QAAQ,IAAI;UACzD,eAAe,MACxB,QAAO,uBAAuB,IAAI,aAAa,QAAW,CAAC,IAAI;UAEtD,KAAK,YAAY,OAC1B,QAAO;EACL,MAAM,IAAI;EACV,MAAM,IAAI;;KAGZ,QAAO;;AAIX,IAAa,qBAAb,MAA8D;CAC5D,AAAU,OAAO,KAAsB;EACrC,MAAM,UAAU,IAAI;AACpB,SAAO,QAAQ,OACbC,wBAAU,MAAM,GAAW,UAAe;AACxC,UAAO,SAAS;;;CAKtB,MAAM,WAAW,KAAyC;AACxD,MAAI,eAAe,WACjB,QAAO,CAAC,SAAS;MAEjB,QAAO,CAAC,QAAQ,KAAK,OAAO;;CAIhC,MAAgB,OAAO,MAA4B;EACjD,MAAM,SAAS,KAAK,MAAM;AAC1B,SAAO,SAAS;;CAGlB,MAAM,WAAW,MAAc,MAAyC;AACtE,MAAI,SAAS,QACX,QAAO,OAAO,SAAS,WAAW,IAAI,cAAc,OAAO,QAAQ;WAC1D,SAAS,OAClB,QAAO,KAAK,OACV,OAAO,SAAS,WAAW,OAAO,IAAI,cAAc,OAAO;MAG7D,OAAM,IAAI,MAAM,+BAA+B"} |
| {"version":3,"file":"types.cjs","names":[],"sources":["../../src/serde/types.ts"],"sourcesContent":["export const TASKS = \"__pregel_tasks\";\nexport const ERROR = \"__error__\";\nexport const SCHEDULED = \"__scheduled__\";\nexport const INTERRUPT = \"__interrupt__\";\nexport const RESUME = \"__resume__\";\n\n// Mirrors BaseChannel in \"@langchain/langgraph\"\nexport interface ChannelProtocol<\n ValueType = unknown,\n UpdateType = unknown,\n CheckpointType = unknown\n> {\n ValueType: ValueType;\n\n UpdateType: UpdateType;\n\n /**\n * The name of the channel.\n */\n lc_graph_name: string;\n\n /**\n * Return a new identical channel, optionally initialized from a checkpoint.\n * Can be thought of as a \"restoration\" from a checkpoint which is a \"snapshot\" of the channel's state.\n *\n * @param {CheckpointType | undefined} checkpoint\n * @returns {this}\n */\n fromCheckpoint(checkpoint?: CheckpointType): this;\n\n /**\n * Update the channel's value with the given sequence of updates.\n * The order of the updates in the sequence is arbitrary.\n *\n * @throws {InvalidUpdateError} if the sequence of updates is invalid.\n * @param {Array<UpdateType>} values\n * @returns {void}\n */\n update(values: UpdateType[]): void;\n\n /**\n * Return the current value of the channel.\n *\n * @throws {EmptyChannelError} if the channel is empty (never updated yet).\n * @returns {ValueType}\n */\n get(): ValueType;\n\n /**\n * Return a string representation of the channel's current state.\n *\n * @throws {EmptyChannelError} if the channel is empty (never updated yet), or doesn't support checkpoints.\n * @returns {CheckpointType | undefined}\n */\n checkpoint(): CheckpointType | undefined;\n}\n\n// Mirrors SendInterface in \"@langchain/langgraph\"\nexport interface SendProtocol {\n node: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any;\n}\n"],"mappings":";;AAAA,MAAa,QAAQ;AACrB,MAAa,QAAQ;AACrB,MAAa,YAAY;AACzB,MAAa,YAAY;AACzB,MAAa,SAAS"} |
| //#region src/serde/types.d.ts | ||
| declare const TASKS = "__pregel_tasks"; | ||
| declare const ERROR = "__error__"; | ||
| declare const SCHEDULED = "__scheduled__"; | ||
| declare const INTERRUPT = "__interrupt__"; | ||
| declare const RESUME = "__resume__"; | ||
| // Mirrors BaseChannel in "@langchain/langgraph" | ||
| interface ChannelProtocol<ValueType = unknown, UpdateType = unknown, CheckpointType = unknown> { | ||
| ValueType: ValueType; | ||
| UpdateType: UpdateType; | ||
| /** | ||
| * The name of the channel. | ||
| */ | ||
| lc_graph_name: string; | ||
| /** | ||
| * Return a new identical channel, optionally initialized from a checkpoint. | ||
| * Can be thought of as a "restoration" from a checkpoint which is a "snapshot" of the channel's state. | ||
| * | ||
| * @param {CheckpointType | undefined} checkpoint | ||
| * @returns {this} | ||
| */ | ||
| fromCheckpoint(checkpoint?: CheckpointType): this; | ||
| /** | ||
| * Update the channel's value with the given sequence of updates. | ||
| * The order of the updates in the sequence is arbitrary. | ||
| * | ||
| * @throws {InvalidUpdateError} if the sequence of updates is invalid. | ||
| * @param {Array<UpdateType>} values | ||
| * @returns {void} | ||
| */ | ||
| update(values: UpdateType[]): void; | ||
| /** | ||
| * Return the current value of the channel. | ||
| * | ||
| * @throws {EmptyChannelError} if the channel is empty (never updated yet). | ||
| * @returns {ValueType} | ||
| */ | ||
| get(): ValueType; | ||
| /** | ||
| * Return a string representation of the channel's current state. | ||
| * | ||
| * @throws {EmptyChannelError} if the channel is empty (never updated yet), or doesn't support checkpoints. | ||
| * @returns {CheckpointType | undefined} | ||
| */ | ||
| checkpoint(): CheckpointType | undefined; | ||
| } | ||
| // Mirrors SendInterface in "@langchain/langgraph" | ||
| interface SendProtocol { | ||
| node: string; | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| args: any; | ||
| } | ||
| //#endregion | ||
| export { ChannelProtocol, ERROR, INTERRUPT, RESUME, SCHEDULED, SendProtocol, TASKS }; | ||
| //# sourceMappingURL=types.d.cts.map |
| {"version":3,"file":"types.d.cts","names":["TASKS","ERROR","SCHEDULED","INTERRUPT","RESUME","ChannelProtocol","ValueType","UpdateType","CheckpointType","SendProtocol"],"sources":["../../src/serde/types.d.ts"],"sourcesContent":["export declare const TASKS = \"__pregel_tasks\";\nexport declare const ERROR = \"__error__\";\nexport declare const SCHEDULED = \"__scheduled__\";\nexport declare const INTERRUPT = \"__interrupt__\";\nexport declare const RESUME = \"__resume__\";\n// Mirrors BaseChannel in \"@langchain/langgraph\"\nexport interface ChannelProtocol<ValueType = unknown, UpdateType = unknown, CheckpointType = unknown> {\n ValueType: ValueType;\n UpdateType: UpdateType;\n /**\n * The name of the channel.\n */\n lc_graph_name: string;\n /**\n * Return a new identical channel, optionally initialized from a checkpoint.\n * Can be thought of as a \"restoration\" from a checkpoint which is a \"snapshot\" of the channel's state.\n *\n * @param {CheckpointType | undefined} checkpoint\n * @returns {this}\n */\n fromCheckpoint(checkpoint?: CheckpointType): this;\n /**\n * Update the channel's value with the given sequence of updates.\n * The order of the updates in the sequence is arbitrary.\n *\n * @throws {InvalidUpdateError} if the sequence of updates is invalid.\n * @param {Array<UpdateType>} values\n * @returns {void}\n */\n update(values: UpdateType[]): void;\n /**\n * Return the current value of the channel.\n *\n * @throws {EmptyChannelError} if the channel is empty (never updated yet).\n * @returns {ValueType}\n */\n get(): ValueType;\n /**\n * Return a string representation of the channel's current state.\n *\n * @throws {EmptyChannelError} if the channel is empty (never updated yet), or doesn't support checkpoints.\n * @returns {CheckpointType | undefined}\n */\n checkpoint(): CheckpointType | undefined;\n}\n// Mirrors SendInterface in \"@langchain/langgraph\"\nexport interface SendProtocol {\n node: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any;\n}\n"],"mappings":";cAAqBA,KAAAA;AAAAA,cACAC,KAAAA,GADK,WAAA;AACLA,cACAC,SAAAA,GADK,eAAA;AACLA,cACAC,SAAAA,GADS,eAAA;AACTA,cACAC,MAAAA,GADS,YAAA;AAC9B;AAEiBC,UAAAA,eAAe,CAAA,YAAA,OAAA,EAAA,aAAA,OAAA,EAAA,iBAAA,OAAA,CAAA,CAAA;EAAA,SAAA,EACjBC,SADiB;YACjBA,EACCC,UADDD;;;;eA6BJA,EAAAA,MAAAA;;;AAUX;;;;;8BA1BgCE;;;;;;;;;iBASbD;;;;;;;SAORD;;;;;;;gBAOOE;;;UAGDC,YAAAA"} |
| {"version":3,"file":"types.d.ts","names":["TASKS","ERROR","SCHEDULED","INTERRUPT","RESUME","ChannelProtocol","ValueType","UpdateType","CheckpointType","SendProtocol"],"sources":["../../src/serde/types.d.ts"],"sourcesContent":["export declare const TASKS = \"__pregel_tasks\";\nexport declare const ERROR = \"__error__\";\nexport declare const SCHEDULED = \"__scheduled__\";\nexport declare const INTERRUPT = \"__interrupt__\";\nexport declare const RESUME = \"__resume__\";\n// Mirrors BaseChannel in \"@langchain/langgraph\"\nexport interface ChannelProtocol<ValueType = unknown, UpdateType = unknown, CheckpointType = unknown> {\n ValueType: ValueType;\n UpdateType: UpdateType;\n /**\n * The name of the channel.\n */\n lc_graph_name: string;\n /**\n * Return a new identical channel, optionally initialized from a checkpoint.\n * Can be thought of as a \"restoration\" from a checkpoint which is a \"snapshot\" of the channel's state.\n *\n * @param {CheckpointType | undefined} checkpoint\n * @returns {this}\n */\n fromCheckpoint(checkpoint?: CheckpointType): this;\n /**\n * Update the channel's value with the given sequence of updates.\n * The order of the updates in the sequence is arbitrary.\n *\n * @throws {InvalidUpdateError} if the sequence of updates is invalid.\n * @param {Array<UpdateType>} values\n * @returns {void}\n */\n update(values: UpdateType[]): void;\n /**\n * Return the current value of the channel.\n *\n * @throws {EmptyChannelError} if the channel is empty (never updated yet).\n * @returns {ValueType}\n */\n get(): ValueType;\n /**\n * Return a string representation of the channel's current state.\n *\n * @throws {EmptyChannelError} if the channel is empty (never updated yet), or doesn't support checkpoints.\n * @returns {CheckpointType | undefined}\n */\n checkpoint(): CheckpointType | undefined;\n}\n// Mirrors SendInterface in \"@langchain/langgraph\"\nexport interface SendProtocol {\n node: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any;\n}\n"],"mappings":";cAAqBA,KAAAA;AAAAA,cACAC,KAAAA,GADK,WAAA;AACLA,cACAC,SAAAA,GADK,eAAA;AACLA,cACAC,SAAAA,GADS,eAAA;AACTA,cACAC,MAAAA,GADS,YAAA;AAC9B;AAEiBC,UAAAA,eAAe,CAAA,YAAA,OAAA,EAAA,aAAA,OAAA,EAAA,iBAAA,OAAA,CAAA,CAAA;EAAA,SAAA,EACjBC,SADiB;YACjBA,EACCC,UADDD;;;;eA6BJA,EAAAA,MAAAA;;;AAUX;;;;;8BA1BgCE;;;;;;;;;iBASbD;;;;;;;SAORD;;;;;;;gBAOOE;;;UAGDC,YAAAA"} |
| {"version":3,"file":"index.cjs","names":[],"sources":["../../../../src/serde/utils/fast-safe-stringify/index.ts"],"sourcesContent":["/* eslint-disable */\n// @ts-nocheck\n\n// Stringify that can handle circular references.\n// Inlined due to ESM import issues\n// Source: https://www.npmjs.com/package/fast-safe-stringify\n\nvar LIMIT_REPLACE_NODE = \"[...]\";\nvar CIRCULAR_REPLACE_NODE = \"[Circular]\";\n\nvar arr = [];\nvar replacerStack = [];\n\nfunction defaultOptions() {\n return {\n depthLimit: Number.MAX_SAFE_INTEGER,\n edgesLimit: Number.MAX_SAFE_INTEGER,\n };\n}\n\n// Regular stringify\nexport function stringify(obj, replacer?, spacer?, options?) {\n if (typeof options === \"undefined\") {\n options = defaultOptions();\n }\n\n decirc(obj, \"\", 0, [], undefined, 0, options);\n var res;\n try {\n if (replacerStack.length === 0) {\n res = JSON.stringify(obj, replacer, spacer);\n } else {\n res = JSON.stringify(obj, replaceGetterValues(replacer), spacer);\n }\n } catch (_) {\n return JSON.stringify(\n \"[unable to serialize, circular reference is too complex to analyze]\"\n );\n } finally {\n while (arr.length !== 0) {\n var part = arr.pop();\n if (part.length === 4) {\n Object.defineProperty(part[0], part[1], part[3]);\n } else {\n part[0][part[1]] = part[2];\n }\n }\n }\n return res;\n}\n\nfunction setReplace(replace, val, k, parent) {\n var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k);\n if (propertyDescriptor.get !== undefined) {\n if (propertyDescriptor.configurable) {\n Object.defineProperty(parent, k, { value: replace });\n arr.push([parent, k, val, propertyDescriptor]);\n } else {\n replacerStack.push([val, k, replace]);\n }\n } else {\n parent[k] = replace;\n arr.push([parent, k, val]);\n }\n}\n\nfunction decirc(val, k, edgeIndex, stack, parent, depth, options) {\n depth += 1;\n var i;\n if (typeof val === \"object\" && val !== null) {\n for (i = 0; i < stack.length; i++) {\n if (stack[i] === val) {\n setReplace(CIRCULAR_REPLACE_NODE, val, k, parent);\n return;\n }\n }\n\n if (\n typeof options.depthLimit !== \"undefined\" &&\n depth > options.depthLimit\n ) {\n setReplace(LIMIT_REPLACE_NODE, val, k, parent);\n return;\n }\n\n if (\n typeof options.edgesLimit !== \"undefined\" &&\n edgeIndex + 1 > options.edgesLimit\n ) {\n setReplace(LIMIT_REPLACE_NODE, val, k, parent);\n return;\n }\n\n stack.push(val);\n // Optimize for Arrays. Big arrays could kill the performance otherwise!\n if (Array.isArray(val)) {\n for (i = 0; i < val.length; i++) {\n decirc(val[i], i, i, stack, val, depth, options);\n }\n } else {\n var keys = Object.keys(val);\n for (i = 0; i < keys.length; i++) {\n var key = keys[i];\n decirc(val[key], key, i, stack, val, depth, options);\n }\n }\n stack.pop();\n }\n}\n\n// Stable-stringify\nfunction compareFunction(a, b) {\n if (a < b) {\n return -1;\n }\n if (a > b) {\n return 1;\n }\n return 0;\n}\n\nfunction deterministicStringify(obj, replacer, spacer, options) {\n if (typeof options === \"undefined\") {\n options = defaultOptions();\n }\n\n var tmp = deterministicDecirc(obj, \"\", 0, [], undefined, 0, options) || obj;\n var res;\n try {\n if (replacerStack.length === 0) {\n res = JSON.stringify(tmp, replacer, spacer);\n } else {\n res = JSON.stringify(tmp, replaceGetterValues(replacer), spacer);\n }\n } catch (_) {\n return JSON.stringify(\n \"[unable to serialize, circular reference is too complex to analyze]\"\n );\n } finally {\n // Ensure that we restore the object as it was.\n while (arr.length !== 0) {\n var part = arr.pop();\n if (part.length === 4) {\n Object.defineProperty(part[0], part[1], part[3]);\n } else {\n part[0][part[1]] = part[2];\n }\n }\n }\n return res;\n}\n\nfunction deterministicDecirc(val, k, edgeIndex, stack, parent, depth, options) {\n depth += 1;\n var i;\n if (typeof val === \"object\" && val !== null) {\n for (i = 0; i < stack.length; i++) {\n if (stack[i] === val) {\n setReplace(CIRCULAR_REPLACE_NODE, val, k, parent);\n return;\n }\n }\n try {\n if (typeof val.toJSON === \"function\") {\n return;\n }\n } catch (_) {\n return;\n }\n\n if (\n typeof options.depthLimit !== \"undefined\" &&\n depth > options.depthLimit\n ) {\n setReplace(LIMIT_REPLACE_NODE, val, k, parent);\n return;\n }\n\n if (\n typeof options.edgesLimit !== \"undefined\" &&\n edgeIndex + 1 > options.edgesLimit\n ) {\n setReplace(LIMIT_REPLACE_NODE, val, k, parent);\n return;\n }\n\n stack.push(val);\n // Optimize for Arrays. Big arrays could kill the performance otherwise!\n if (Array.isArray(val)) {\n for (i = 0; i < val.length; i++) {\n deterministicDecirc(val[i], i, i, stack, val, depth, options);\n }\n } else {\n // Create a temporary object in the required way\n var tmp = {};\n var keys = Object.keys(val).sort(compareFunction);\n for (i = 0; i < keys.length; i++) {\n var key = keys[i];\n deterministicDecirc(val[key], key, i, stack, val, depth, options);\n tmp[key] = val[key];\n }\n if (typeof parent !== \"undefined\") {\n arr.push([parent, k, val]);\n parent[k] = tmp;\n } else {\n return tmp;\n }\n }\n stack.pop();\n }\n}\n\n// wraps replacer function to handle values we couldn't replace\n// and mark them as replaced value\nfunction replaceGetterValues(replacer) {\n replacer =\n typeof replacer !== \"undefined\"\n ? replacer\n : function (k, v) {\n return v;\n };\n return function (key, val) {\n if (replacerStack.length > 0) {\n for (var i = 0; i < replacerStack.length; i++) {\n var part = replacerStack[i];\n if (part[1] === key && part[0] === val) {\n val = part[2];\n replacerStack.splice(i, 1);\n break;\n }\n }\n }\n return replacer.call(this, key, val);\n };\n}\n"],"mappings":";;AAOA,IAAI,qBAAqB;AACzB,IAAI,wBAAwB;AAE5B,IAAI,MAAM;AACV,IAAI,gBAAgB;AAEpB,SAAS,iBAAiB;AACxB,QAAO;EACL,YAAY,OAAO;EACnB,YAAY,OAAO;;;AAKvB,SAAgB,UAAU,KAAK,UAAW,QAAS,SAAU;AAC3D,KAAI,OAAO,YAAY,YACrB,WAAU;AAGZ,QAAO,KAAK,IAAI,GAAG,IAAI,QAAW,GAAG;CACrC,IAAI;AACJ,KAAI;AACF,MAAI,cAAc,WAAW,EAC3B,OAAM,KAAK,UAAU,KAAK,UAAU;MAEpC,OAAM,KAAK,UAAU,KAAK,oBAAoB,WAAW;UAEpD,GAAG;AACV,SAAO,KAAK,UACV;WAEM;AACR,SAAO,IAAI,WAAW,GAAG;GACvB,IAAI,OAAO,IAAI;AACf,OAAI,KAAK,WAAW,EAClB,QAAO,eAAe,KAAK,IAAI,KAAK,IAAI,KAAK;OAE7C,MAAK,GAAG,KAAK,MAAM,KAAK;;;AAI9B,QAAO;;AAGT,SAAS,WAAW,SAAS,KAAK,GAAG,QAAQ;CAC3C,IAAI,qBAAqB,OAAO,yBAAyB,QAAQ;AACjE,KAAI,mBAAmB,QAAQ,OAC7B,KAAI,mBAAmB,cAAc;AACnC,SAAO,eAAe,QAAQ,GAAG,EAAE,OAAO;AAC1C,MAAI,KAAK;GAAC;GAAQ;GAAG;GAAK;;OAE1B,eAAc,KAAK;EAAC;EAAK;EAAG;;MAEzB;AACL,SAAO,KAAK;AACZ,MAAI,KAAK;GAAC;GAAQ;GAAG;;;;AAIzB,SAAS,OAAO,KAAK,GAAG,WAAW,OAAO,QAAQ,OAAO,SAAS;AAChE,UAAS;CACT,IAAI;AACJ,KAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,OAAK,IAAI,GAAG,IAAI,MAAM,QAAQ,IAC5B,KAAI,MAAM,OAAO,KAAK;AACpB,cAAW,uBAAuB,KAAK,GAAG;AAC1C;;AAIJ,MACE,OAAO,QAAQ,eAAe,eAC9B,QAAQ,QAAQ,YAChB;AACA,cAAW,oBAAoB,KAAK,GAAG;AACvC;;AAGF,MACE,OAAO,QAAQ,eAAe,eAC9B,YAAY,IAAI,QAAQ,YACxB;AACA,cAAW,oBAAoB,KAAK,GAAG;AACvC;;AAGF,QAAM,KAAK;AAEX,MAAI,MAAM,QAAQ,KAChB,MAAK,IAAI,GAAG,IAAI,IAAI,QAAQ,IAC1B,QAAO,IAAI,IAAI,GAAG,GAAG,OAAO,KAAK,OAAO;OAErC;GACL,IAAI,OAAO,OAAO,KAAK;AACvB,QAAK,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;IAChC,IAAI,MAAM,KAAK;AACf,WAAO,IAAI,MAAM,KAAK,GAAG,OAAO,KAAK,OAAO;;;AAGhD,QAAM;;;AA4GV,SAAS,oBAAoB,UAAU;AACrC,YACE,OAAO,aAAa,cAChB,WACA,SAAU,GAAG,GAAG;AACd,SAAO;;AAEf,QAAO,SAAU,KAAK,KAAK;AACzB,MAAI,cAAc,SAAS,EACzB,MAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;GAC7C,IAAI,OAAO,cAAc;AACzB,OAAI,KAAK,OAAO,OAAO,KAAK,OAAO,KAAK;AACtC,UAAM,KAAK;AACX,kBAAc,OAAO,GAAG;AACxB;;;AAIN,SAAO,SAAS,KAAK,MAAM,KAAK"} |
| {"version":3,"file":"base.cjs","names":["current: any","results: string[]","matchConditions: MatchCondition[]"],"sources":["../../src/store/base.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Embeddings } from \"@langchain/core/embeddings\";\n\n/**\n * Error thrown when an invalid namespace is provided.\n */\nexport class InvalidNamespaceError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"InvalidNamespaceError\";\n }\n}\n\n/**\n * Validates the provided namespace.\n * @param namespace The namespace to validate.\n * @throws {InvalidNamespaceError} If the namespace is invalid.\n */\nfunction validateNamespace(namespace: string[]): void {\n if (namespace.length === 0) {\n throw new InvalidNamespaceError(\"Namespace cannot be empty.\");\n }\n for (const label of namespace) {\n if (typeof label !== \"string\") {\n throw new InvalidNamespaceError(\n `Invalid namespace label '${label}' found in ${namespace}. Namespace labels ` +\n `must be strings, but got ${typeof label}.`\n );\n }\n if (label.includes(\".\")) {\n throw new InvalidNamespaceError(\n `Invalid namespace label '${label}' found in ${namespace}. Namespace labels cannot contain periods ('.').`\n );\n }\n if (label === \"\") {\n throw new InvalidNamespaceError(\n `Namespace labels cannot be empty strings. Got ${label} in ${namespace}`\n );\n }\n }\n if (namespace[0] === \"langgraph\") {\n throw new InvalidNamespaceError(\n `Root label for namespace cannot be \"langgraph\". Got: ${namespace}`\n );\n }\n}\n\n/**\n * Represents a stored item with metadata.\n */\nexport interface Item {\n /**\n * The stored data as an object. Keys are filterable.\n */\n value: Record<string, any>;\n /**\n * Unique identifier within the namespace.\n */\n key: string;\n /**\n * Hierarchical path defining the collection in which this document resides.\n * Represented as an array of strings, allowing for nested categorization.\n * For example: [\"documents\", \"user123\"]\n */\n namespace: string[];\n /**\n * Timestamp of item creation.\n */\n createdAt: Date;\n /**\n * Timestamp of last update.\n */\n updatedAt: Date;\n}\n\n/**\n * Represents a search result item with relevance score.\n * Extends the base Item interface with an optional similarity score.\n */\nexport interface SearchItem extends Item {\n /**\n * Relevance/similarity score if from a ranked operation.\n * Higher scores indicate better matches.\n *\n * This is typically a cosine similarity score between -1 and 1,\n * where 1 indicates identical vectors and -1 indicates opposite vectors.\n */\n score?: number;\n}\n\n/**\n * Operation to retrieve an item by namespace and ID.\n */\nexport interface GetOperation {\n /**\n * Hierarchical path for the item.\n *\n * @example\n * // Get a user profile\n * namespace: [\"users\", \"profiles\"]\n */\n namespace: string[];\n\n /**\n * Unique identifier within the namespace.\n * Together with namespace forms the complete path to the item.\n *\n * @example\n * key: \"user123\" // For a user profile\n * key: \"doc456\" // For a document\n */\n key: string;\n}\n\n/**\n * Operation to search for items within a namespace prefix.\n */\nexport interface SearchOperation {\n /**\n * Hierarchical path prefix to search within.\n * Only items under this prefix will be searched.\n *\n * @example\n * // Search all user documents\n * namespacePrefix: [\"users\", \"documents\"]\n *\n * // Search everything\n * namespacePrefix: []\n */\n namespacePrefix: string[];\n\n /**\n * Key-value pairs to filter results based on exact matches or comparison operators.\n *\n * Supports both exact matches and operator-based comparisons:\n * - $eq: Equal to (same as direct value comparison)\n * - $ne: Not equal to\n * - $gt: Greater than\n * - $gte: Greater than or equal to\n * - $lt: Less than\n * - $lte: Less than or equal to\n *\n * @example\n * // Exact match\n * filter: { status: \"active\" }\n *\n * // With operators\n * filter: { score: { $gt: 4.99 } }\n *\n * // Multiple conditions\n * filter: {\n * score: { $gte: 3.0 },\n * color: \"red\"\n * }\n */\n filter?: Record<string, any>;\n\n /**\n * Maximum number of items to return.\n * @default 10\n */\n limit?: number;\n\n /**\n * Number of items to skip before returning results.\n * Useful for pagination.\n * @default 0\n */\n offset?: number;\n\n /**\n * Natural language search query for semantic search.\n * When provided, results will be ranked by relevance to this query\n * using vector similarity search.\n *\n * @example\n * // Find technical documentation about APIs\n * query: \"technical documentation about REST APIs\"\n *\n * // Find recent ML papers\n * query: \"machine learning papers from 2023\"\n */\n query?: string;\n}\n\n/**\n * Operation to store, update, or delete an item.\n */\nexport interface PutOperation {\n /**\n * Hierarchical path for the item.\n * Acts as a folder-like structure to organize items.\n * Each element represents one level in the hierarchy.\n *\n * @example\n * // Root level documents\n * namespace: [\"documents\"]\n *\n * // User-specific documents\n * namespace: [\"documents\", \"user123\"]\n *\n * // Nested cache structure\n * namespace: [\"cache\", \"docs\", \"v1\"]\n */\n namespace: string[];\n\n /**\n * Unique identifier for the document within its namespace.\n * Together with namespace forms the complete path to the item.\n *\n * Example: If namespace is [\"documents\", \"user123\"] and key is \"report1\",\n * the full path would effectively be \"documents/user123/report1\"\n */\n key: string;\n\n /**\n * Data to be stored, or null to delete the item.\n * Must be a JSON-serializable object with string keys.\n * Setting to null signals that the item should be deleted.\n *\n * @example\n * {\n * field1: \"string value\",\n * field2: 123,\n * nested: { can: \"contain\", any: \"serializable data\" }\n * }\n */\n value: Record<string, any> | null;\n\n /**\n * Controls how the item's fields are indexed for search operations.\n *\n * - undefined: Uses store's default indexing configuration\n * - false: Disables indexing for this item\n * - string[]: List of field paths to index\n *\n * Path syntax supports:\n * - Nested fields: \"metadata.title\"\n * - Array access: \"chapters[*].content\" (each indexed separately)\n * - Specific indices: \"authors[0].name\"\n *\n * @example\n * // Index specific fields\n * index: [\"metadata.title\", \"chapters[*].content\"]\n *\n * // Disable indexing\n * index: false\n */\n index?: false | string[];\n}\n\n/**\n * Operation to list and filter namespaces in the store.\n */\nexport interface ListNamespacesOperation {\n matchConditions?: MatchCondition[];\n maxDepth?: number;\n limit: number;\n offset: number;\n}\n\nexport type NameSpacePath = (string | \"*\")[];\n\nexport type NamespaceMatchType = \"prefix\" | \"suffix\";\n\nexport interface MatchCondition {\n matchType: NamespaceMatchType;\n path: NameSpacePath;\n}\n\nexport type Operation =\n | GetOperation\n | SearchOperation\n | PutOperation\n | ListNamespacesOperation;\n\nexport type OperationResults<Tuple extends readonly Operation[]> = {\n [K in keyof Tuple]: Tuple[K] extends PutOperation\n ? void\n : Tuple[K] extends SearchOperation\n ? SearchItem[]\n : Tuple[K] extends GetOperation\n ? Item | null\n : Tuple[K] extends ListNamespacesOperation\n ? string[][]\n : never;\n};\n\n/**\n * Configuration for indexing documents for semantic search in the store.\n *\n * This configures how documents are embedded and indexed for vector similarity search.\n */\nexport interface IndexConfig {\n /**\n * Number of dimensions in the embedding vectors.\n *\n * Common embedding model dimensions:\n * - OpenAI text-embedding-3-large: 256, 1024, or 3072\n * - OpenAI text-embedding-3-small: 512 or 1536\n * - OpenAI text-embedding-ada-002: 1536\n * - Cohere embed-english-v3.0: 1024\n * - Cohere embed-english-light-v3.0: 384\n * - Cohere embed-multilingual-v3.0: 1024\n * - Cohere embed-multilingual-light-v3.0: 384\n */\n dims: number;\n\n /**\n * The embeddings model to use for generating vectors.\n * This should be a LangChain Embeddings implementation.\n */\n embeddings: Embeddings;\n\n /**\n * Fields to extract text from for embedding generation.\n *\n * Path syntax supports:\n * - Simple field access: \"field\"\n * - Nested fields: \"metadata.title\"\n * - Array indexing:\n * - All elements: \"chapters[*].content\"\n * - Specific index: \"authors[0].name\"\n * - Last element: \"array[-1]\"\n *\n * @default [\"$\"] Embeds the entire document as one vector\n */\n fields?: string[];\n}\n\n/**\n * Utility function to get text at a specific JSON path\n */\nexport function getTextAtPath(obj: any, path: string): string[] {\n const parts = path.split(\".\");\n let current: any = obj;\n\n for (const part of parts) {\n if (part.includes(\"[\")) {\n const [arrayName, indexStr] = part.split(\"[\");\n const index = indexStr.replace(\"]\", \"\");\n\n if (!current[arrayName]) return [];\n\n if (index === \"*\") {\n const results: string[] = [];\n for (const item of current[arrayName]) {\n if (typeof item === \"string\") results.push(item);\n }\n return results;\n }\n\n const idx = parseInt(index, 10);\n if (Number.isNaN(idx)) return [];\n current = current[arrayName][idx];\n } else {\n current = current[part];\n }\n\n if (current === undefined) return [];\n }\n\n return typeof current === \"string\" ? [current] : [];\n}\n\n/**\n * Tokenizes a JSON path into parts\n */\nexport function tokenizePath(path: string): string[] {\n return path.split(\".\");\n}\n\n/**\n * Abstract base class for persistent key-value stores.\n *\n * Stores enable persistence and memory that can be shared across threads,\n * scoped to user IDs, assistant IDs, or other arbitrary namespaces.\n *\n * Features:\n * - Hierarchical namespaces for organization\n * - Key-value storage with metadata\n * - Vector similarity search (if configured)\n * - Filtering and pagination\n */\nexport abstract class BaseStore {\n /**\n * Execute multiple operations in a single batch.\n * This is more efficient than executing operations individually.\n *\n * @param operations Array of operations to execute\n * @returns Promise resolving to results matching the operations\n */\n abstract batch<Op extends Operation[]>(\n operations: Op\n ): Promise<OperationResults<Op>>;\n\n /**\n * Retrieve a single item by its namespace and key.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n * @returns Promise resolving to the item or null if not found\n */\n async get(namespace: string[], key: string): Promise<Item | null> {\n return (await this.batch<[GetOperation]>([{ namespace, key }]))[0];\n }\n\n /**\n * Search for items within a namespace prefix.\n * Supports both metadata filtering and vector similarity search.\n *\n * @param namespacePrefix Hierarchical path prefix to search within\n * @param options Search options for filtering and pagination\n * @returns Promise resolving to list of matching items with relevance scores\n *\n * @example\n * // Search with filters\n * await store.search([\"documents\"], {\n * filter: { type: \"report\", status: \"active\" },\n * limit: 5,\n * offset: 10\n * });\n *\n * // Vector similarity search\n * await store.search([\"users\", \"content\"], {\n * query: \"technical documentation about APIs\",\n * limit: 20\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<SearchItem[]> {\n const { filter, limit = 10, offset = 0, query } = options;\n return (\n await this.batch<[SearchOperation]>([\n {\n namespacePrefix,\n filter,\n limit,\n offset,\n query,\n },\n ])\n )[0];\n }\n\n /**\n * Store or update an item.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n * @param value Object containing the item's data\n * @param index Optional indexing configuration\n *\n * @example\n * // Simple storage\n * await store.put([\"docs\"], \"report\", { title: \"Annual Report\" });\n *\n * // With specific field indexing\n * await store.put(\n * [\"docs\"],\n * \"report\",\n * {\n * title: \"Q4 Report\",\n * chapters: [{ content: \"...\" }, { content: \"...\" }]\n * },\n * [\"title\", \"chapters[*].content\"]\n * );\n */\n async put(\n namespace: string[],\n key: string,\n value: Record<string, any>,\n index?: false | string[]\n ): Promise<void> {\n validateNamespace(namespace);\n await this.batch<[PutOperation]>([{ namespace, key, value, index }]);\n }\n\n /**\n * Delete an item from the store.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n */\n async delete(namespace: string[], key: string): Promise<void> {\n await this.batch<[PutOperation]>([{ namespace, key, value: null }]);\n }\n\n /**\n * List and filter namespaces in the store.\n * Used to explore data organization and navigate the namespace hierarchy.\n *\n * @param options Options for listing namespaces\n * @returns Promise resolving to list of namespace paths\n *\n * @example\n * // List all namespaces under \"documents\"\n * await store.listNamespaces({\n * prefix: [\"documents\"],\n * maxDepth: 2\n * });\n *\n * // List namespaces ending with \"v1\"\n * await store.listNamespaces({\n * suffix: [\"v1\"],\n * limit: 50\n * });\n */\n async listNamespaces(\n options: {\n prefix?: string[];\n suffix?: string[];\n maxDepth?: number;\n limit?: number;\n offset?: number;\n } = {}\n ): Promise<string[][]> {\n const { prefix, suffix, maxDepth, limit = 100, offset = 0 } = options;\n\n const matchConditions: MatchCondition[] = [];\n if (prefix) {\n matchConditions.push({ matchType: \"prefix\", path: prefix });\n }\n if (suffix) {\n matchConditions.push({ matchType: \"suffix\", path: suffix });\n }\n\n return (\n await this.batch<[ListNamespacesOperation]>([\n {\n matchConditions: matchConditions.length ? matchConditions : undefined,\n maxDepth,\n limit,\n offset,\n },\n ])\n )[0];\n }\n\n /**\n * Start the store. Override if initialization is needed.\n */\n start(): void | Promise<void> {}\n\n /**\n * Stop the store. Override if cleanup is needed.\n */\n stop(): void | Promise<void> {}\n}\n"],"mappings":";;;;;AAMA,IAAa,wBAAb,cAA2C,MAAM;CAC/C,YAAY,SAAiB;AAC3B,QAAM;AACN,OAAK,OAAO;;;;;;;;AAShB,SAAS,kBAAkB,WAA2B;AACpD,KAAI,UAAU,WAAW,EACvB,OAAM,IAAI,sBAAsB;AAElC,MAAK,MAAM,SAAS,WAAW;AAC7B,MAAI,OAAO,UAAU,SACnB,OAAM,IAAI,sBACR,4BAA4B,MAAM,aAAa,UAAU,8CAC3B,OAAO,MAAM;AAG/C,MAAI,MAAM,SAAS,KACjB,OAAM,IAAI,sBACR,4BAA4B,MAAM,aAAa,UAAU;AAG7D,MAAI,UAAU,GACZ,OAAM,IAAI,sBACR,iDAAiD,MAAM,MAAM;;AAInE,KAAI,UAAU,OAAO,YACnB,OAAM,IAAI,sBACR,wDAAwD;;;;;AAmS9D,SAAgB,cAAc,KAAU,MAAwB;CAC9D,MAAM,QAAQ,KAAK,MAAM;CACzB,IAAIA,UAAe;AAEnB,MAAK,MAAM,QAAQ,OAAO;AACxB,MAAI,KAAK,SAAS,MAAM;GACtB,MAAM,CAAC,WAAW,YAAY,KAAK,MAAM;GACzC,MAAM,QAAQ,SAAS,QAAQ,KAAK;AAEpC,OAAI,CAAC,QAAQ,WAAY,QAAO;AAEhC,OAAI,UAAU,KAAK;IACjB,MAAMC,UAAoB;AAC1B,SAAK,MAAM,QAAQ,QAAQ,WACzB,KAAI,OAAO,SAAS,SAAU,SAAQ,KAAK;AAE7C,WAAO;;GAGT,MAAM,MAAM,SAAS,OAAO;AAC5B,OAAI,OAAO,MAAM,KAAM,QAAO;AAC9B,aAAU,QAAQ,WAAW;QAE7B,WAAU,QAAQ;AAGpB,MAAI,YAAY,OAAW,QAAO;;AAGpC,QAAO,OAAO,YAAY,WAAW,CAAC,WAAW;;;;;AAMnD,SAAgB,aAAa,MAAwB;AACnD,QAAO,KAAK,MAAM;;;;;;;;;;;;;;AAepB,IAAsB,YAAtB,MAAgC;;;;;;;;CAmB9B,MAAM,IAAI,WAAqB,KAAmC;AAChE,UAAQ,MAAM,KAAK,MAAsB,CAAC;GAAE;GAAW;OAAS;;;;;;;;;;;;;;;;;;;;;;;;CAyBlE,MAAM,OACJ,iBACA,UAKI,IACmB;EACvB,MAAM,EAAE,QAAQ,QAAQ,IAAI,SAAS,GAAG,UAAU;AAClD,UACE,MAAM,KAAK,MAAyB,CAClC;GACE;GACA;GACA;GACA;GACA;OAGJ;;;;;;;;;;;;;;;;;;;;;;;;;CA0BJ,MAAM,IACJ,WACA,KACA,OACA,OACe;AACf,oBAAkB;AAClB,QAAM,KAAK,MAAsB,CAAC;GAAE;GAAW;GAAK;GAAO;;;;;;;;;CAS7D,MAAM,OAAO,WAAqB,KAA4B;AAC5D,QAAM,KAAK,MAAsB,CAAC;GAAE;GAAW;GAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;CAuB7D,MAAM,eACJ,UAMI,IACiB;EACrB,MAAM,EAAE,QAAQ,QAAQ,UAAU,QAAQ,KAAK,SAAS,MAAM;EAE9D,MAAMC,kBAAoC;AAC1C,MAAI,OACF,iBAAgB,KAAK;GAAE,WAAW;GAAU,MAAM;;AAEpD,MAAI,OACF,iBAAgB,KAAK;GAAE,WAAW;GAAU,MAAM;;AAGpD,UACE,MAAM,KAAK,MAAiC,CAC1C;GACE,iBAAiB,gBAAgB,SAAS,kBAAkB;GAC5D;GACA;GACA;OAGJ;;;;;CAMJ,QAA8B;;;;CAK9B,OAA6B"} |
| import { Embeddings } from "@langchain/core/embeddings"; | ||
| //#region src/store/base.d.ts | ||
| /** | ||
| * Error thrown when an invalid namespace is provided. | ||
| */ | ||
| declare class InvalidNamespaceError extends Error { | ||
| constructor(message: string); | ||
| } | ||
| /** | ||
| * Represents a stored item with metadata. | ||
| */ | ||
| interface Item { | ||
| /** | ||
| * The stored data as an object. Keys are filterable. | ||
| */ | ||
| value: Record<string, any>; | ||
| /** | ||
| * Unique identifier within the namespace. | ||
| */ | ||
| key: string; | ||
| /** | ||
| * Hierarchical path defining the collection in which this document resides. | ||
| * Represented as an array of strings, allowing for nested categorization. | ||
| * For example: ["documents", "user123"] | ||
| */ | ||
| namespace: string[]; | ||
| /** | ||
| * Timestamp of item creation. | ||
| */ | ||
| createdAt: Date; | ||
| /** | ||
| * Timestamp of last update. | ||
| */ | ||
| updatedAt: Date; | ||
| } | ||
| /** | ||
| * Represents a search result item with relevance score. | ||
| * Extends the base Item interface with an optional similarity score. | ||
| */ | ||
| interface SearchItem extends Item { | ||
| /** | ||
| * Relevance/similarity score if from a ranked operation. | ||
| * Higher scores indicate better matches. | ||
| * | ||
| * This is typically a cosine similarity score between -1 and 1, | ||
| * where 1 indicates identical vectors and -1 indicates opposite vectors. | ||
| */ | ||
| score?: number; | ||
| } | ||
| /** | ||
| * Operation to retrieve an item by namespace and ID. | ||
| */ | ||
| interface GetOperation { | ||
| /** | ||
| * Hierarchical path for the item. | ||
| * | ||
| * @example | ||
| * // Get a user profile | ||
| * namespace: ["users", "profiles"] | ||
| */ | ||
| namespace: string[]; | ||
| /** | ||
| * Unique identifier within the namespace. | ||
| * Together with namespace forms the complete path to the item. | ||
| * | ||
| * @example | ||
| * key: "user123" // For a user profile | ||
| * key: "doc456" // For a document | ||
| */ | ||
| key: string; | ||
| } | ||
| /** | ||
| * Operation to search for items within a namespace prefix. | ||
| */ | ||
| interface SearchOperation { | ||
| /** | ||
| * Hierarchical path prefix to search within. | ||
| * Only items under this prefix will be searched. | ||
| * | ||
| * @example | ||
| * // Search all user documents | ||
| * namespacePrefix: ["users", "documents"] | ||
| * | ||
| * // Search everything | ||
| * namespacePrefix: [] | ||
| */ | ||
| namespacePrefix: string[]; | ||
| /** | ||
| * Key-value pairs to filter results based on exact matches or comparison operators. | ||
| * | ||
| * Supports both exact matches and operator-based comparisons: | ||
| * - $eq: Equal to (same as direct value comparison) | ||
| * - $ne: Not equal to | ||
| * - $gt: Greater than | ||
| * - $gte: Greater than or equal to | ||
| * - $lt: Less than | ||
| * - $lte: Less than or equal to | ||
| * | ||
| * @example | ||
| * // Exact match | ||
| * filter: { status: "active" } | ||
| * | ||
| * // With operators | ||
| * filter: { score: { $gt: 4.99 } } | ||
| * | ||
| * // Multiple conditions | ||
| * filter: { | ||
| * score: { $gte: 3.0 }, | ||
| * color: "red" | ||
| * } | ||
| */ | ||
| filter?: Record<string, any>; | ||
| /** | ||
| * Maximum number of items to return. | ||
| * @default 10 | ||
| */ | ||
| limit?: number; | ||
| /** | ||
| * Number of items to skip before returning results. | ||
| * Useful for pagination. | ||
| * @default 0 | ||
| */ | ||
| offset?: number; | ||
| /** | ||
| * Natural language search query for semantic search. | ||
| * When provided, results will be ranked by relevance to this query | ||
| * using vector similarity search. | ||
| * | ||
| * @example | ||
| * // Find technical documentation about APIs | ||
| * query: "technical documentation about REST APIs" | ||
| * | ||
| * // Find recent ML papers | ||
| * query: "machine learning papers from 2023" | ||
| */ | ||
| query?: string; | ||
| } | ||
| /** | ||
| * Operation to store, update, or delete an item. | ||
| */ | ||
| interface PutOperation { | ||
| /** | ||
| * Hierarchical path for the item. | ||
| * Acts as a folder-like structure to organize items. | ||
| * Each element represents one level in the hierarchy. | ||
| * | ||
| * @example | ||
| * // Root level documents | ||
| * namespace: ["documents"] | ||
| * | ||
| * // User-specific documents | ||
| * namespace: ["documents", "user123"] | ||
| * | ||
| * // Nested cache structure | ||
| * namespace: ["cache", "docs", "v1"] | ||
| */ | ||
| namespace: string[]; | ||
| /** | ||
| * Unique identifier for the document within its namespace. | ||
| * Together with namespace forms the complete path to the item. | ||
| * | ||
| * Example: If namespace is ["documents", "user123"] and key is "report1", | ||
| * the full path would effectively be "documents/user123/report1" | ||
| */ | ||
| key: string; | ||
| /** | ||
| * Data to be stored, or null to delete the item. | ||
| * Must be a JSON-serializable object with string keys. | ||
| * Setting to null signals that the item should be deleted. | ||
| * | ||
| * @example | ||
| * { | ||
| * field1: "string value", | ||
| * field2: 123, | ||
| * nested: { can: "contain", any: "serializable data" } | ||
| * } | ||
| */ | ||
| value: Record<string, any> | null; | ||
| /** | ||
| * Controls how the item's fields are indexed for search operations. | ||
| * | ||
| * - undefined: Uses store's default indexing configuration | ||
| * - false: Disables indexing for this item | ||
| * - string[]: List of field paths to index | ||
| * | ||
| * Path syntax supports: | ||
| * - Nested fields: "metadata.title" | ||
| * - Array access: "chapters[*].content" (each indexed separately) | ||
| * - Specific indices: "authors[0].name" | ||
| * | ||
| * @example | ||
| * // Index specific fields | ||
| * index: ["metadata.title", "chapters[*].content"] | ||
| * | ||
| * // Disable indexing | ||
| * index: false | ||
| */ | ||
| index?: false | string[]; | ||
| } | ||
| /** | ||
| * Operation to list and filter namespaces in the store. | ||
| */ | ||
| interface ListNamespacesOperation { | ||
| matchConditions?: MatchCondition[]; | ||
| maxDepth?: number; | ||
| limit: number; | ||
| offset: number; | ||
| } | ||
| type NameSpacePath = (string | "*")[]; | ||
| type NamespaceMatchType = "prefix" | "suffix"; | ||
| interface MatchCondition { | ||
| matchType: NamespaceMatchType; | ||
| path: NameSpacePath; | ||
| } | ||
| type Operation = GetOperation | SearchOperation | PutOperation | ListNamespacesOperation; | ||
| type OperationResults<Tuple extends readonly Operation[]> = { [K in keyof Tuple]: Tuple[K] extends PutOperation ? void : Tuple[K] extends SearchOperation ? SearchItem[] : Tuple[K] extends GetOperation ? Item | null : Tuple[K] extends ListNamespacesOperation ? string[][] : never }; | ||
| /** | ||
| * Configuration for indexing documents for semantic search in the store. | ||
| * | ||
| * This configures how documents are embedded and indexed for vector similarity search. | ||
| */ | ||
| interface IndexConfig { | ||
| /** | ||
| * Number of dimensions in the embedding vectors. | ||
| * | ||
| * Common embedding model dimensions: | ||
| * - OpenAI text-embedding-3-large: 256, 1024, or 3072 | ||
| * - OpenAI text-embedding-3-small: 512 or 1536 | ||
| * - OpenAI text-embedding-ada-002: 1536 | ||
| * - Cohere embed-english-v3.0: 1024 | ||
| * - Cohere embed-english-light-v3.0: 384 | ||
| * - Cohere embed-multilingual-v3.0: 1024 | ||
| * - Cohere embed-multilingual-light-v3.0: 384 | ||
| */ | ||
| dims: number; | ||
| /** | ||
| * The embeddings model to use for generating vectors. | ||
| * This should be a LangChain Embeddings implementation. | ||
| */ | ||
| embeddings: Embeddings; | ||
| /** | ||
| * Fields to extract text from for embedding generation. | ||
| * | ||
| * Path syntax supports: | ||
| * - Simple field access: "field" | ||
| * - Nested fields: "metadata.title" | ||
| * - Array indexing: | ||
| * - All elements: "chapters[*].content" | ||
| * - Specific index: "authors[0].name" | ||
| * - Last element: "array[-1]" | ||
| * | ||
| * @default ["$"] Embeds the entire document as one vector | ||
| */ | ||
| fields?: string[]; | ||
| } | ||
| /** | ||
| * Utility function to get text at a specific JSON path | ||
| */ | ||
| declare function getTextAtPath(obj: any, path: string): string[]; | ||
| /** | ||
| * Tokenizes a JSON path into parts | ||
| */ | ||
| declare function tokenizePath(path: string): string[]; | ||
| /** | ||
| * Abstract base class for persistent key-value stores. | ||
| * | ||
| * Stores enable persistence and memory that can be shared across threads, | ||
| * scoped to user IDs, assistant IDs, or other arbitrary namespaces. | ||
| * | ||
| * Features: | ||
| * - Hierarchical namespaces for organization | ||
| * - Key-value storage with metadata | ||
| * - Vector similarity search (if configured) | ||
| * - Filtering and pagination | ||
| */ | ||
| declare abstract class BaseStore { | ||
| /** | ||
| * Execute multiple operations in a single batch. | ||
| * This is more efficient than executing operations individually. | ||
| * | ||
| * @param operations Array of operations to execute | ||
| * @returns Promise resolving to results matching the operations | ||
| */ | ||
| abstract batch<Op extends Operation[]>(operations: Op): Promise<OperationResults<Op>>; | ||
| /** | ||
| * Retrieve a single item by its namespace and key. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @returns Promise resolving to the item or null if not found | ||
| */ | ||
| get(namespace: string[], key: string): Promise<Item | null>; | ||
| /** | ||
| * Search for items within a namespace prefix. | ||
| * Supports both metadata filtering and vector similarity search. | ||
| * | ||
| * @param namespacePrefix Hierarchical path prefix to search within | ||
| * @param options Search options for filtering and pagination | ||
| * @returns Promise resolving to list of matching items with relevance scores | ||
| * | ||
| * @example | ||
| * // Search with filters | ||
| * await store.search(["documents"], { | ||
| * filter: { type: "report", status: "active" }, | ||
| * limit: 5, | ||
| * offset: 10 | ||
| * }); | ||
| * | ||
| * // Vector similarity search | ||
| * await store.search(["users", "content"], { | ||
| * query: "technical documentation about APIs", | ||
| * limit: 20 | ||
| * }); | ||
| */ | ||
| search(namespacePrefix: string[], options?: { | ||
| filter?: Record<string, any>; | ||
| limit?: number; | ||
| offset?: number; | ||
| query?: string; | ||
| }): Promise<SearchItem[]>; | ||
| /** | ||
| * Store or update an item. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @param value Object containing the item's data | ||
| * @param index Optional indexing configuration | ||
| * | ||
| * @example | ||
| * // Simple storage | ||
| * await store.put(["docs"], "report", { title: "Annual Report" }); | ||
| * | ||
| * // With specific field indexing | ||
| * await store.put( | ||
| * ["docs"], | ||
| * "report", | ||
| * { | ||
| * title: "Q4 Report", | ||
| * chapters: [{ content: "..." }, { content: "..." }] | ||
| * }, | ||
| * ["title", "chapters[*].content"] | ||
| * ); | ||
| */ | ||
| put(namespace: string[], key: string, value: Record<string, any>, index?: false | string[]): Promise<void>; | ||
| /** | ||
| * Delete an item from the store. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| */ | ||
| delete(namespace: string[], key: string): Promise<void>; | ||
| /** | ||
| * List and filter namespaces in the store. | ||
| * Used to explore data organization and navigate the namespace hierarchy. | ||
| * | ||
| * @param options Options for listing namespaces | ||
| * @returns Promise resolving to list of namespace paths | ||
| * | ||
| * @example | ||
| * // List all namespaces under "documents" | ||
| * await store.listNamespaces({ | ||
| * prefix: ["documents"], | ||
| * maxDepth: 2 | ||
| * }); | ||
| * | ||
| * // List namespaces ending with "v1" | ||
| * await store.listNamespaces({ | ||
| * suffix: ["v1"], | ||
| * limit: 50 | ||
| * }); | ||
| */ | ||
| listNamespaces(options?: { | ||
| prefix?: string[]; | ||
| suffix?: string[]; | ||
| maxDepth?: number; | ||
| limit?: number; | ||
| offset?: number; | ||
| }): Promise<string[][]>; | ||
| /** | ||
| * Start the store. Override if initialization is needed. | ||
| */ | ||
| start(): void | Promise<void>; | ||
| /** | ||
| * Stop the store. Override if cleanup is needed. | ||
| */ | ||
| stop(): void | Promise<void>; | ||
| } | ||
| //#endregion | ||
| export { BaseStore, GetOperation, IndexConfig, InvalidNamespaceError, Item, ListNamespacesOperation, MatchCondition, NameSpacePath, NamespaceMatchType, Operation, OperationResults, PutOperation, SearchItem, SearchOperation, getTextAtPath, tokenizePath }; | ||
| //# sourceMappingURL=base.d.cts.map |
| {"version":3,"file":"base.d.cts","names":["Embeddings","InvalidNamespaceError","Error","Item","Record","Date","SearchItem","GetOperation","SearchOperation","PutOperation","ListNamespacesOperation","MatchCondition","NameSpacePath","NamespaceMatchType","Operation","OperationResults","Tuple","K","IndexConfig","getTextAtPath","tokenizePath","BaseStore","Op","Promise"],"sources":["../../src/store/base.d.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Embeddings } from \"@langchain/core/embeddings\";\n/**\n * Error thrown when an invalid namespace is provided.\n */\nexport declare class InvalidNamespaceError extends Error {\n constructor(message: string);\n}\n/**\n * Represents a stored item with metadata.\n */\nexport interface Item {\n /**\n * The stored data as an object. Keys are filterable.\n */\n value: Record<string, any>;\n /**\n * Unique identifier within the namespace.\n */\n key: string;\n /**\n * Hierarchical path defining the collection in which this document resides.\n * Represented as an array of strings, allowing for nested categorization.\n * For example: [\"documents\", \"user123\"]\n */\n namespace: string[];\n /**\n * Timestamp of item creation.\n */\n createdAt: Date;\n /**\n * Timestamp of last update.\n */\n updatedAt: Date;\n}\n/**\n * Represents a search result item with relevance score.\n * Extends the base Item interface with an optional similarity score.\n */\nexport interface SearchItem extends Item {\n /**\n * Relevance/similarity score if from a ranked operation.\n * Higher scores indicate better matches.\n *\n * This is typically a cosine similarity score between -1 and 1,\n * where 1 indicates identical vectors and -1 indicates opposite vectors.\n */\n score?: number;\n}\n/**\n * Operation to retrieve an item by namespace and ID.\n */\nexport interface GetOperation {\n /**\n * Hierarchical path for the item.\n *\n * @example\n * // Get a user profile\n * namespace: [\"users\", \"profiles\"]\n */\n namespace: string[];\n /**\n * Unique identifier within the namespace.\n * Together with namespace forms the complete path to the item.\n *\n * @example\n * key: \"user123\" // For a user profile\n * key: \"doc456\" // For a document\n */\n key: string;\n}\n/**\n * Operation to search for items within a namespace prefix.\n */\nexport interface SearchOperation {\n /**\n * Hierarchical path prefix to search within.\n * Only items under this prefix will be searched.\n *\n * @example\n * // Search all user documents\n * namespacePrefix: [\"users\", \"documents\"]\n *\n * // Search everything\n * namespacePrefix: []\n */\n namespacePrefix: string[];\n /**\n * Key-value pairs to filter results based on exact matches or comparison operators.\n *\n * Supports both exact matches and operator-based comparisons:\n * - $eq: Equal to (same as direct value comparison)\n * - $ne: Not equal to\n * - $gt: Greater than\n * - $gte: Greater than or equal to\n * - $lt: Less than\n * - $lte: Less than or equal to\n *\n * @example\n * // Exact match\n * filter: { status: \"active\" }\n *\n * // With operators\n * filter: { score: { $gt: 4.99 } }\n *\n * // Multiple conditions\n * filter: {\n * score: { $gte: 3.0 },\n * color: \"red\"\n * }\n */\n filter?: Record<string, any>;\n /**\n * Maximum number of items to return.\n * @default 10\n */\n limit?: number;\n /**\n * Number of items to skip before returning results.\n * Useful for pagination.\n * @default 0\n */\n offset?: number;\n /**\n * Natural language search query for semantic search.\n * When provided, results will be ranked by relevance to this query\n * using vector similarity search.\n *\n * @example\n * // Find technical documentation about APIs\n * query: \"technical documentation about REST APIs\"\n *\n * // Find recent ML papers\n * query: \"machine learning papers from 2023\"\n */\n query?: string;\n}\n/**\n * Operation to store, update, or delete an item.\n */\nexport interface PutOperation {\n /**\n * Hierarchical path for the item.\n * Acts as a folder-like structure to organize items.\n * Each element represents one level in the hierarchy.\n *\n * @example\n * // Root level documents\n * namespace: [\"documents\"]\n *\n * // User-specific documents\n * namespace: [\"documents\", \"user123\"]\n *\n * // Nested cache structure\n * namespace: [\"cache\", \"docs\", \"v1\"]\n */\n namespace: string[];\n /**\n * Unique identifier for the document within its namespace.\n * Together with namespace forms the complete path to the item.\n *\n * Example: If namespace is [\"documents\", \"user123\"] and key is \"report1\",\n * the full path would effectively be \"documents/user123/report1\"\n */\n key: string;\n /**\n * Data to be stored, or null to delete the item.\n * Must be a JSON-serializable object with string keys.\n * Setting to null signals that the item should be deleted.\n *\n * @example\n * {\n * field1: \"string value\",\n * field2: 123,\n * nested: { can: \"contain\", any: \"serializable data\" }\n * }\n */\n value: Record<string, any> | null;\n /**\n * Controls how the item's fields are indexed for search operations.\n *\n * - undefined: Uses store's default indexing configuration\n * - false: Disables indexing for this item\n * - string[]: List of field paths to index\n *\n * Path syntax supports:\n * - Nested fields: \"metadata.title\"\n * - Array access: \"chapters[*].content\" (each indexed separately)\n * - Specific indices: \"authors[0].name\"\n *\n * @example\n * // Index specific fields\n * index: [\"metadata.title\", \"chapters[*].content\"]\n *\n * // Disable indexing\n * index: false\n */\n index?: false | string[];\n}\n/**\n * Operation to list and filter namespaces in the store.\n */\nexport interface ListNamespacesOperation {\n matchConditions?: MatchCondition[];\n maxDepth?: number;\n limit: number;\n offset: number;\n}\nexport type NameSpacePath = (string | \"*\")[];\nexport type NamespaceMatchType = \"prefix\" | \"suffix\";\nexport interface MatchCondition {\n matchType: NamespaceMatchType;\n path: NameSpacePath;\n}\nexport type Operation = GetOperation | SearchOperation | PutOperation | ListNamespacesOperation;\nexport type OperationResults<Tuple extends readonly Operation[]> = {\n [K in keyof Tuple]: Tuple[K] extends PutOperation ? void : Tuple[K] extends SearchOperation ? SearchItem[] : Tuple[K] extends GetOperation ? Item | null : Tuple[K] extends ListNamespacesOperation ? string[][] : never;\n};\n/**\n * Configuration for indexing documents for semantic search in the store.\n *\n * This configures how documents are embedded and indexed for vector similarity search.\n */\nexport interface IndexConfig {\n /**\n * Number of dimensions in the embedding vectors.\n *\n * Common embedding model dimensions:\n * - OpenAI text-embedding-3-large: 256, 1024, or 3072\n * - OpenAI text-embedding-3-small: 512 or 1536\n * - OpenAI text-embedding-ada-002: 1536\n * - Cohere embed-english-v3.0: 1024\n * - Cohere embed-english-light-v3.0: 384\n * - Cohere embed-multilingual-v3.0: 1024\n * - Cohere embed-multilingual-light-v3.0: 384\n */\n dims: number;\n /**\n * The embeddings model to use for generating vectors.\n * This should be a LangChain Embeddings implementation.\n */\n embeddings: Embeddings;\n /**\n * Fields to extract text from for embedding generation.\n *\n * Path syntax supports:\n * - Simple field access: \"field\"\n * - Nested fields: \"metadata.title\"\n * - Array indexing:\n * - All elements: \"chapters[*].content\"\n * - Specific index: \"authors[0].name\"\n * - Last element: \"array[-1]\"\n *\n * @default [\"$\"] Embeds the entire document as one vector\n */\n fields?: string[];\n}\n/**\n * Utility function to get text at a specific JSON path\n */\nexport declare function getTextAtPath(obj: any, path: string): string[];\n/**\n * Tokenizes a JSON path into parts\n */\nexport declare function tokenizePath(path: string): string[];\n/**\n * Abstract base class for persistent key-value stores.\n *\n * Stores enable persistence and memory that can be shared across threads,\n * scoped to user IDs, assistant IDs, or other arbitrary namespaces.\n *\n * Features:\n * - Hierarchical namespaces for organization\n * - Key-value storage with metadata\n * - Vector similarity search (if configured)\n * - Filtering and pagination\n */\nexport declare abstract class BaseStore {\n /**\n * Execute multiple operations in a single batch.\n * This is more efficient than executing operations individually.\n *\n * @param operations Array of operations to execute\n * @returns Promise resolving to results matching the operations\n */\n abstract batch<Op extends Operation[]>(operations: Op): Promise<OperationResults<Op>>;\n /**\n * Retrieve a single item by its namespace and key.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n * @returns Promise resolving to the item or null if not found\n */\n get(namespace: string[], key: string): Promise<Item | null>;\n /**\n * Search for items within a namespace prefix.\n * Supports both metadata filtering and vector similarity search.\n *\n * @param namespacePrefix Hierarchical path prefix to search within\n * @param options Search options for filtering and pagination\n * @returns Promise resolving to list of matching items with relevance scores\n *\n * @example\n * // Search with filters\n * await store.search([\"documents\"], {\n * filter: { type: \"report\", status: \"active\" },\n * limit: 5,\n * offset: 10\n * });\n *\n * // Vector similarity search\n * await store.search([\"users\", \"content\"], {\n * query: \"technical documentation about APIs\",\n * limit: 20\n * });\n */\n search(namespacePrefix: string[], options?: {\n filter?: Record<string, any>;\n limit?: number;\n offset?: number;\n query?: string;\n }): Promise<SearchItem[]>;\n /**\n * Store or update an item.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n * @param value Object containing the item's data\n * @param index Optional indexing configuration\n *\n * @example\n * // Simple storage\n * await store.put([\"docs\"], \"report\", { title: \"Annual Report\" });\n *\n * // With specific field indexing\n * await store.put(\n * [\"docs\"],\n * \"report\",\n * {\n * title: \"Q4 Report\",\n * chapters: [{ content: \"...\" }, { content: \"...\" }]\n * },\n * [\"title\", \"chapters[*].content\"]\n * );\n */\n put(namespace: string[], key: string, value: Record<string, any>, index?: false | string[]): Promise<void>;\n /**\n * Delete an item from the store.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n */\n delete(namespace: string[], key: string): Promise<void>;\n /**\n * List and filter namespaces in the store.\n * Used to explore data organization and navigate the namespace hierarchy.\n *\n * @param options Options for listing namespaces\n * @returns Promise resolving to list of namespace paths\n *\n * @example\n * // List all namespaces under \"documents\"\n * await store.listNamespaces({\n * prefix: [\"documents\"],\n * maxDepth: 2\n * });\n *\n * // List namespaces ending with \"v1\"\n * await store.listNamespaces({\n * suffix: [\"v1\"],\n * limit: 50\n * });\n */\n listNamespaces(options?: {\n prefix?: string[];\n suffix?: string[];\n maxDepth?: number;\n limit?: number;\n offset?: number;\n }): Promise<string[][]>;\n /**\n * Start the store. Override if initialization is needed.\n */\n start(): void | Promise<void>;\n /**\n * Stop the store. Override if cleanup is needed.\n */\n stop(): void | Promise<void>;\n}\n"],"mappings":";;;;;AAKA;AAMA;AAAqB,cANAC,qBAAAA,SAA8BC,KAAAA,CAM9B;aAIVE,CAAAA,OAAAA,EAAAA,MAAAA;;;;AAwBX;AAaiBG,UAzCAJ,IAAAA,CAyCY;EAsBZK;AAkEjB;AA8DA;EAMYI,KAAAA,EAjMDR,MAiMCQ,CAAAA,MAAa,EAAA,GAAA,CAAA;EACbC;AACZ;;KACeA,EAAAA,MAAAA;;;AAGf;;;WAAuCL,EAAAA,MAAAA,EAAAA;;;;EAC3BO,SAAAA,EA1LGV,IA0LHU;EAAgB;;;WACJC,EAvLTX,IAuLSW;;;;;;AAA0EV,UAjLjFA,UAAAA,SAAmBH,IAiL8DG,CAAAA;;;;;;;;;AAOlG;AAqCA;AAIA;AAaA;AAAuC,UAjOtBC,YAAAA,CAiOsB;;;;;;;;WAwCtBH,EAAAA,MAAAA,EAAAA;;;;;;;;;;;;;;UAnPAI,eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAqCJJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA6BIK,YAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAqCNL;;;;;;;;;;;;;;;;;;;;;;;;;UAyBMM,uBAAAA;oBACKC;;;;;KAKVC,aAAAA;KACAC,kBAAAA;UACKF,cAAAA;aACFE;QACLD;;KAEEE,SAAAA,GAAYP,eAAeC,kBAAkBC,eAAeC;KAC5DK,wCAAwCD,6BACpCE,QAAQA,MAAMC,WAAWR,sBAAsBO,MAAMC,WAAWT,kBAAkBF,eAAeU,MAAMC,WAAWV,eAAeJ,cAAca,MAAMC,WAAWP;;;;;;UAO/JQ,WAAAA;;;;;;;;;;;;;;;;;;cAkBDlB;;;;;;;;;;;;;;;;;;;iBAmBQmB,aAAAA;;;;iBAIAC,YAAAA;;;;;;;;;;;;;uBAaMC,SAAAA;;;;;;;;4BAQAP,yBAAyBQ,KAAKC,QAAQR,iBAAiBO;;;;;;;;yCAQ1CC,QAAQpB;;;;;;;;;;;;;;;;;;;;;;;;aAwBlCC;;;;MAITmB,QAAQjB;;;;;;;;;;;;;;;;;;;;;;;;+CAwBiCF,gDAAgDmB;;;;;;;4CAOnDA;;;;;;;;;;;;;;;;;;;;;;;;;;;MA2BtCA;;;;kBAIYA;;;;iBAIDA"} |
| {"version":3,"file":"base.d.ts","names":["Embeddings","InvalidNamespaceError","Error","Item","Record","Date","SearchItem","GetOperation","SearchOperation","PutOperation","ListNamespacesOperation","MatchCondition","NameSpacePath","NamespaceMatchType","Operation","OperationResults","Tuple","K","IndexConfig","getTextAtPath","tokenizePath","BaseStore","Op","Promise"],"sources":["../../src/store/base.d.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Embeddings } from \"@langchain/core/embeddings\";\n/**\n * Error thrown when an invalid namespace is provided.\n */\nexport declare class InvalidNamespaceError extends Error {\n constructor(message: string);\n}\n/**\n * Represents a stored item with metadata.\n */\nexport interface Item {\n /**\n * The stored data as an object. Keys are filterable.\n */\n value: Record<string, any>;\n /**\n * Unique identifier within the namespace.\n */\n key: string;\n /**\n * Hierarchical path defining the collection in which this document resides.\n * Represented as an array of strings, allowing for nested categorization.\n * For example: [\"documents\", \"user123\"]\n */\n namespace: string[];\n /**\n * Timestamp of item creation.\n */\n createdAt: Date;\n /**\n * Timestamp of last update.\n */\n updatedAt: Date;\n}\n/**\n * Represents a search result item with relevance score.\n * Extends the base Item interface with an optional similarity score.\n */\nexport interface SearchItem extends Item {\n /**\n * Relevance/similarity score if from a ranked operation.\n * Higher scores indicate better matches.\n *\n * This is typically a cosine similarity score between -1 and 1,\n * where 1 indicates identical vectors and -1 indicates opposite vectors.\n */\n score?: number;\n}\n/**\n * Operation to retrieve an item by namespace and ID.\n */\nexport interface GetOperation {\n /**\n * Hierarchical path for the item.\n *\n * @example\n * // Get a user profile\n * namespace: [\"users\", \"profiles\"]\n */\n namespace: string[];\n /**\n * Unique identifier within the namespace.\n * Together with namespace forms the complete path to the item.\n *\n * @example\n * key: \"user123\" // For a user profile\n * key: \"doc456\" // For a document\n */\n key: string;\n}\n/**\n * Operation to search for items within a namespace prefix.\n */\nexport interface SearchOperation {\n /**\n * Hierarchical path prefix to search within.\n * Only items under this prefix will be searched.\n *\n * @example\n * // Search all user documents\n * namespacePrefix: [\"users\", \"documents\"]\n *\n * // Search everything\n * namespacePrefix: []\n */\n namespacePrefix: string[];\n /**\n * Key-value pairs to filter results based on exact matches or comparison operators.\n *\n * Supports both exact matches and operator-based comparisons:\n * - $eq: Equal to (same as direct value comparison)\n * - $ne: Not equal to\n * - $gt: Greater than\n * - $gte: Greater than or equal to\n * - $lt: Less than\n * - $lte: Less than or equal to\n *\n * @example\n * // Exact match\n * filter: { status: \"active\" }\n *\n * // With operators\n * filter: { score: { $gt: 4.99 } }\n *\n * // Multiple conditions\n * filter: {\n * score: { $gte: 3.0 },\n * color: \"red\"\n * }\n */\n filter?: Record<string, any>;\n /**\n * Maximum number of items to return.\n * @default 10\n */\n limit?: number;\n /**\n * Number of items to skip before returning results.\n * Useful for pagination.\n * @default 0\n */\n offset?: number;\n /**\n * Natural language search query for semantic search.\n * When provided, results will be ranked by relevance to this query\n * using vector similarity search.\n *\n * @example\n * // Find technical documentation about APIs\n * query: \"technical documentation about REST APIs\"\n *\n * // Find recent ML papers\n * query: \"machine learning papers from 2023\"\n */\n query?: string;\n}\n/**\n * Operation to store, update, or delete an item.\n */\nexport interface PutOperation {\n /**\n * Hierarchical path for the item.\n * Acts as a folder-like structure to organize items.\n * Each element represents one level in the hierarchy.\n *\n * @example\n * // Root level documents\n * namespace: [\"documents\"]\n *\n * // User-specific documents\n * namespace: [\"documents\", \"user123\"]\n *\n * // Nested cache structure\n * namespace: [\"cache\", \"docs\", \"v1\"]\n */\n namespace: string[];\n /**\n * Unique identifier for the document within its namespace.\n * Together with namespace forms the complete path to the item.\n *\n * Example: If namespace is [\"documents\", \"user123\"] and key is \"report1\",\n * the full path would effectively be \"documents/user123/report1\"\n */\n key: string;\n /**\n * Data to be stored, or null to delete the item.\n * Must be a JSON-serializable object with string keys.\n * Setting to null signals that the item should be deleted.\n *\n * @example\n * {\n * field1: \"string value\",\n * field2: 123,\n * nested: { can: \"contain\", any: \"serializable data\" }\n * }\n */\n value: Record<string, any> | null;\n /**\n * Controls how the item's fields are indexed for search operations.\n *\n * - undefined: Uses store's default indexing configuration\n * - false: Disables indexing for this item\n * - string[]: List of field paths to index\n *\n * Path syntax supports:\n * - Nested fields: \"metadata.title\"\n * - Array access: \"chapters[*].content\" (each indexed separately)\n * - Specific indices: \"authors[0].name\"\n *\n * @example\n * // Index specific fields\n * index: [\"metadata.title\", \"chapters[*].content\"]\n *\n * // Disable indexing\n * index: false\n */\n index?: false | string[];\n}\n/**\n * Operation to list and filter namespaces in the store.\n */\nexport interface ListNamespacesOperation {\n matchConditions?: MatchCondition[];\n maxDepth?: number;\n limit: number;\n offset: number;\n}\nexport type NameSpacePath = (string | \"*\")[];\nexport type NamespaceMatchType = \"prefix\" | \"suffix\";\nexport interface MatchCondition {\n matchType: NamespaceMatchType;\n path: NameSpacePath;\n}\nexport type Operation = GetOperation | SearchOperation | PutOperation | ListNamespacesOperation;\nexport type OperationResults<Tuple extends readonly Operation[]> = {\n [K in keyof Tuple]: Tuple[K] extends PutOperation ? void : Tuple[K] extends SearchOperation ? SearchItem[] : Tuple[K] extends GetOperation ? Item | null : Tuple[K] extends ListNamespacesOperation ? string[][] : never;\n};\n/**\n * Configuration for indexing documents for semantic search in the store.\n *\n * This configures how documents are embedded and indexed for vector similarity search.\n */\nexport interface IndexConfig {\n /**\n * Number of dimensions in the embedding vectors.\n *\n * Common embedding model dimensions:\n * - OpenAI text-embedding-3-large: 256, 1024, or 3072\n * - OpenAI text-embedding-3-small: 512 or 1536\n * - OpenAI text-embedding-ada-002: 1536\n * - Cohere embed-english-v3.0: 1024\n * - Cohere embed-english-light-v3.0: 384\n * - Cohere embed-multilingual-v3.0: 1024\n * - Cohere embed-multilingual-light-v3.0: 384\n */\n dims: number;\n /**\n * The embeddings model to use for generating vectors.\n * This should be a LangChain Embeddings implementation.\n */\n embeddings: Embeddings;\n /**\n * Fields to extract text from for embedding generation.\n *\n * Path syntax supports:\n * - Simple field access: \"field\"\n * - Nested fields: \"metadata.title\"\n * - Array indexing:\n * - All elements: \"chapters[*].content\"\n * - Specific index: \"authors[0].name\"\n * - Last element: \"array[-1]\"\n *\n * @default [\"$\"] Embeds the entire document as one vector\n */\n fields?: string[];\n}\n/**\n * Utility function to get text at a specific JSON path\n */\nexport declare function getTextAtPath(obj: any, path: string): string[];\n/**\n * Tokenizes a JSON path into parts\n */\nexport declare function tokenizePath(path: string): string[];\n/**\n * Abstract base class for persistent key-value stores.\n *\n * Stores enable persistence and memory that can be shared across threads,\n * scoped to user IDs, assistant IDs, or other arbitrary namespaces.\n *\n * Features:\n * - Hierarchical namespaces for organization\n * - Key-value storage with metadata\n * - Vector similarity search (if configured)\n * - Filtering and pagination\n */\nexport declare abstract class BaseStore {\n /**\n * Execute multiple operations in a single batch.\n * This is more efficient than executing operations individually.\n *\n * @param operations Array of operations to execute\n * @returns Promise resolving to results matching the operations\n */\n abstract batch<Op extends Operation[]>(operations: Op): Promise<OperationResults<Op>>;\n /**\n * Retrieve a single item by its namespace and key.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n * @returns Promise resolving to the item or null if not found\n */\n get(namespace: string[], key: string): Promise<Item | null>;\n /**\n * Search for items within a namespace prefix.\n * Supports both metadata filtering and vector similarity search.\n *\n * @param namespacePrefix Hierarchical path prefix to search within\n * @param options Search options for filtering and pagination\n * @returns Promise resolving to list of matching items with relevance scores\n *\n * @example\n * // Search with filters\n * await store.search([\"documents\"], {\n * filter: { type: \"report\", status: \"active\" },\n * limit: 5,\n * offset: 10\n * });\n *\n * // Vector similarity search\n * await store.search([\"users\", \"content\"], {\n * query: \"technical documentation about APIs\",\n * limit: 20\n * });\n */\n search(namespacePrefix: string[], options?: {\n filter?: Record<string, any>;\n limit?: number;\n offset?: number;\n query?: string;\n }): Promise<SearchItem[]>;\n /**\n * Store or update an item.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n * @param value Object containing the item's data\n * @param index Optional indexing configuration\n *\n * @example\n * // Simple storage\n * await store.put([\"docs\"], \"report\", { title: \"Annual Report\" });\n *\n * // With specific field indexing\n * await store.put(\n * [\"docs\"],\n * \"report\",\n * {\n * title: \"Q4 Report\",\n * chapters: [{ content: \"...\" }, { content: \"...\" }]\n * },\n * [\"title\", \"chapters[*].content\"]\n * );\n */\n put(namespace: string[], key: string, value: Record<string, any>, index?: false | string[]): Promise<void>;\n /**\n * Delete an item from the store.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n */\n delete(namespace: string[], key: string): Promise<void>;\n /**\n * List and filter namespaces in the store.\n * Used to explore data organization and navigate the namespace hierarchy.\n *\n * @param options Options for listing namespaces\n * @returns Promise resolving to list of namespace paths\n *\n * @example\n * // List all namespaces under \"documents\"\n * await store.listNamespaces({\n * prefix: [\"documents\"],\n * maxDepth: 2\n * });\n *\n * // List namespaces ending with \"v1\"\n * await store.listNamespaces({\n * suffix: [\"v1\"],\n * limit: 50\n * });\n */\n listNamespaces(options?: {\n prefix?: string[];\n suffix?: string[];\n maxDepth?: number;\n limit?: number;\n offset?: number;\n }): Promise<string[][]>;\n /**\n * Start the store. Override if initialization is needed.\n */\n start(): void | Promise<void>;\n /**\n * Stop the store. Override if cleanup is needed.\n */\n stop(): void | Promise<void>;\n}\n"],"mappings":";;;;;AAKA;AAMA;AAAqB,cANAC,qBAAAA,SAA8BC,KAAAA,CAM9B;aAIVE,CAAAA,OAAAA,EAAAA,MAAAA;;;;AAwBX;AAaiBG,UAzCAJ,IAAAA,CAyCY;EAsBZK;AAkEjB;AA8DA;EAMYI,KAAAA,EAjMDR,MAiMCQ,CAAAA,MAAa,EAAA,GAAA,CAAA;EACbC;AACZ;;KACeA,EAAAA,MAAAA;;;AAGf;;;WAAuCL,EAAAA,MAAAA,EAAAA;;;;EAC3BO,SAAAA,EA1LGV,IA0LHU;EAAgB;;;WACJC,EAvLTX,IAuLSW;;;;;;AAA0EV,UAjLjFA,UAAAA,SAAmBH,IAiL8DG,CAAAA;;;;;;;;;AAOlG;AAqCA;AAIA;AAaA;AAAuC,UAjOtBC,YAAAA,CAiOsB;;;;;;;;WAwCtBH,EAAAA,MAAAA,EAAAA;;;;;;;;;;;;;;UAnPAI,eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAqCJJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA6BIK,YAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAqCNL;;;;;;;;;;;;;;;;;;;;;;;;;UAyBMM,uBAAAA;oBACKC;;;;;KAKVC,aAAAA;KACAC,kBAAAA;UACKF,cAAAA;aACFE;QACLD;;KAEEE,SAAAA,GAAYP,eAAeC,kBAAkBC,eAAeC;KAC5DK,wCAAwCD,6BACpCE,QAAQA,MAAMC,WAAWR,sBAAsBO,MAAMC,WAAWT,kBAAkBF,eAAeU,MAAMC,WAAWV,eAAeJ,cAAca,MAAMC,WAAWP;;;;;;UAO/JQ,WAAAA;;;;;;;;;;;;;;;;;;cAkBDlB;;;;;;;;;;;;;;;;;;;iBAmBQmB,aAAAA;;;;iBAIAC,YAAAA;;;;;;;;;;;;;uBAaMC,SAAAA;;;;;;;;4BAQAP,yBAAyBQ,KAAKC,QAAQR,iBAAiBO;;;;;;;;yCAQ1CC,QAAQpB;;;;;;;;;;;;;;;;;;;;;;;;aAwBlCC;;;;MAITmB,QAAQjB;;;;;;;;;;;;;;;;;;;;;;;;+CAwBiCF,gDAAgDmB;;;;;;;4CAOnDA;;;;;;;;;;;;;;;;;;;;;;;;;;;MA2BtCA;;;;kBAIYA;;;;iBAIDA"} |
| {"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,uBAAU;CAC/C,UAAU;CAEV,AAAU;CAEV,AAAQ,wBAOJ,IAAI;CAER,AAAQ,UAAkB;CAE1B,AAAQ,UAAU;CAElB,AAAQ,iBAAuC;CAE/C,YAAY,OAAkB;AAC5B;AACA,OAAK,QAAQ,aAAa;;CAG5B,IAAI,YAAqB;AACvB,SAAO,KAAK;;;;;;;;CASd,MAAM,MACJ,aAC+B;AAC/B,QAAM,IAAI,MACR;;CAMJ,MAAM,IAAI,WAAqB,KAAmC;AAChE,SAAO,KAAK,iBAAiB;GAAE;GAAW;;;CAG5C,MAAM,OACJ,iBACA,SAMiB;EACjB,MAAM,EAAE,QAAQ,QAAQ,IAAI,SAAS,GAAG,UAAU,WAAW;AAC7D,SAAO,KAAK,iBAAiB;GAC3B;GACA;GACA;GACA;GACA;;;CAIJ,MAAM,IACJ,WACA,KACA,OACe;AACf,SAAO,KAAK,iBAAiB;GAAE;GAAW;GAAK;;;CAGjD,MAAM,OAAO,WAAqB,KAA4B;AAC5D,SAAO,KAAK,iBAAiB;GAC3B;GACA;GACA,OAAO;;;CAIX,QAAc;AACZ,MAAI,CAAC,KAAK,SAAS;AACjB,QAAK,UAAU;AACf,QAAK,iBAAiB,KAAK;;;CAI/B,MAAM,OAAsB;AAC1B,OAAK,UAAU;AACf,MAAI,KAAK,eACP,OAAM,KAAK;;CAIf,AAAQ,iBAAoB,WAAkC;AAC5D,SAAO,IAAI,SAAY,SAAS,WAAW;GACzC,MAAM,MAAM,KAAK;AACjB,QAAK,WAAW;AAChB,QAAK,MAAM,IAAI,KAAK;IAAE;IAAW;IAAS;;;;CAI9C,MAAc,oBAAmC;AAC/C,SAAO,KAAK,SAAS;AACnB,SAAM,IAAI,SAAS,YAAY;AAC7B,eAAW,SAAS;;AAEtB,OAAI,KAAK,MAAM,SAAS,EAAG;GAE3B,MAAM,QAAQ,IAAI,IAAI,KAAK;AAC3B,QAAK,MAAM;AAEX,OAAI;IACF,MAAM,aAAa,MAAM,KAAK,MAAM,UAAU,KAC3C,EAAE,gBAAgB;IAErB,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM;AAEvC,UAAM,SAAS,EAAE,WAAW,QAAQ;KAClC,MAAM,QAAQ,MAAM,KAAK,MAAM,QAAQ,QAAQ;AAC/C,aAAQ,QAAQ;;YAEX,GAAG;AACV,UAAM,SAAS,EAAE,aAAa;AAC5B,YAAO;;;;;CASf,SAAS;AACP,SAAO;GACL,OAAO,KAAK;GACZ,SAAS,KAAK;GACd,SAAS,KAAK;GACd,OAAO"} |
| import { BaseStore, Item, Operation, OperationResults } from "./base.cjs"; | ||
| //#region src/store/batch.d.ts | ||
| declare class AsyncBatchedStore extends BaseStore { | ||
| lg_name: string; | ||
| protected store: BaseStore; | ||
| private queue; | ||
| private nextKey; | ||
| private running; | ||
| private processingTask; | ||
| constructor(store: BaseStore); | ||
| get isRunning(): boolean; | ||
| /** | ||
| * @ignore | ||
| * Batch is not implemented here as we're only extending `BaseStore` | ||
| * to allow it to be passed where `BaseStore` is expected, and implement | ||
| * the convenience methods (get, search, put, delete). | ||
| */ | ||
| batch<Op extends Operation[]>(_operations: Op): Promise<OperationResults<Op>>; | ||
| get(namespace: string[], key: string): Promise<Item | null>; | ||
| search(namespacePrefix: string[], options?: { | ||
| filter?: Record<string, any>; | ||
| limit?: number; | ||
| offset?: number; | ||
| query?: string; | ||
| }): Promise<Item[]>; | ||
| put(namespace: string[], key: string, value: Record<string, any>): Promise<void>; | ||
| delete(namespace: string[], key: string): Promise<void>; | ||
| start(): void; | ||
| stop(): Promise<void>; | ||
| private enqueueOperation; | ||
| private processBatchQueue; | ||
| // AsyncBatchedStore is internal and gets passed as args into traced tasks | ||
| // some BaseStores contain circular references so just serialize without it | ||
| // as this causes warnings when tracing with LangSmith. | ||
| toJSON(): { | ||
| queue: Map<number, { | ||
| operation: Operation; | ||
| resolve: (value: any) => void; | ||
| reject: (reason?: any) => void; | ||
| }>; | ||
| nextKey: number; | ||
| running: boolean; | ||
| store: string; | ||
| }; | ||
| } | ||
| //#endregion | ||
| export { AsyncBatchedStore }; | ||
| //# sourceMappingURL=batch.d.cts.map |
| {"version":3,"file":"batch.d.cts","names":["BaseStore","Item","Operation","OperationResults","AsyncBatchedStore","Op","Promise","Record","Map"],"sources":["../../src/store/batch.d.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { BaseStore, type Item, type Operation, OperationResults } from \"./base.js\";\nexport declare class AsyncBatchedStore extends BaseStore {\n lg_name: string;\n protected store: BaseStore;\n private queue;\n private nextKey;\n private running;\n private processingTask;\n constructor(store: BaseStore);\n get isRunning(): boolean;\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 batch<Op extends Operation[]>(_operations: Op): Promise<OperationResults<Op>>;\n get(namespace: string[], key: string): Promise<Item | null>;\n search(namespacePrefix: string[], options?: {\n filter?: Record<string, any>;\n limit?: number;\n offset?: number;\n query?: string;\n }): Promise<Item[]>;\n put(namespace: string[], key: string, value: Record<string, any>): Promise<void>;\n delete(namespace: string[], key: string): Promise<void>;\n start(): void;\n stop(): Promise<void>;\n private enqueueOperation;\n private processBatchQueue;\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 queue: Map<number, {\n operation: Operation;\n resolve: (value: any) => void;\n reject: (reason?: any) => void;\n }>;\n nextKey: number;\n running: boolean;\n store: string;\n };\n}\n"],"mappings":";;;cAEqBI,iBAAAA,SAA0BJ,SAAAA;EAA1BI,OAAAA,EAAAA,MAAAA;EAAiB,UAAA,KAAA,EAEjBJ,SAFiB;UAEjBA,KAAAA;UAKEA,OAAAA;UAQFE,OAAAA;UAA0BG,cAAAA;aAA8BA,CAAAA,KAAAA,EARtDL,SAQsDK;MAAjBF,SAAAA,CAAAA,CAAAA,EAAAA,OAAAA;;;;;;;OAQXI,CAAAA,WAR5BL,SAQ4BK,EAAAA,CAAAA,CAAAA,WAAAA,EARFF,EAQEE,CAAAA,EARGD,OAQHC,CARWJ,gBAQXI,CAR4BF,EAQ5BE,CAAAA,CAAAA;KAAsBD,CAAAA,SAAAA,EAAAA,MAAAA,EAAAA,EAAAA,GAAAA,EAAAA,MAAAA,CAAAA,EAP5BA,OAO4BA,CAPpBL,IAOoBK,GAAAA,IAAAA,CAAAA;QACzBA,CAAAA,eAAAA,EAAAA,MAAAA,EAAAA,EAAAA,QAAAA,EAAAA;IAElCA,MAAAA,CAAAA,EARKC,MAQLD,CAAAA,MAAAA,EAAAA,GAAAA,CAAAA;IAQWJ,KAAAA,CAAAA,EAAAA,MAAAA;IADRM,MAAAA,CAAAA,EAAAA,MAAAA;IAjCgCR,KAAAA,CAAAA,EAAAA,MAAAA;MAsBvCM,QAAQL;+CACiCM,sBAAsBD;4CACzBA;;UAElCA;;;;;;;WAOGE;iBACQN"} |
| {"version":3,"file":"batch.d.ts","names":["BaseStore","Item","Operation","OperationResults","AsyncBatchedStore","Op","Promise","Record","Map"],"sources":["../../src/store/batch.d.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { BaseStore, type Item, type Operation, OperationResults } from \"./base.js\";\nexport declare class AsyncBatchedStore extends BaseStore {\n lg_name: string;\n protected store: BaseStore;\n private queue;\n private nextKey;\n private running;\n private processingTask;\n constructor(store: BaseStore);\n get isRunning(): boolean;\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 batch<Op extends Operation[]>(_operations: Op): Promise<OperationResults<Op>>;\n get(namespace: string[], key: string): Promise<Item | null>;\n search(namespacePrefix: string[], options?: {\n filter?: Record<string, any>;\n limit?: number;\n offset?: number;\n query?: string;\n }): Promise<Item[]>;\n put(namespace: string[], key: string, value: Record<string, any>): Promise<void>;\n delete(namespace: string[], key: string): Promise<void>;\n start(): void;\n stop(): Promise<void>;\n private enqueueOperation;\n private processBatchQueue;\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 queue: Map<number, {\n operation: Operation;\n resolve: (value: any) => void;\n reject: (reason?: any) => void;\n }>;\n nextKey: number;\n running: boolean;\n store: string;\n };\n}\n"],"mappings":";;;cAEqBI,iBAAAA,SAA0BJ,SAAAA;EAA1BI,OAAAA,EAAAA,MAAAA;EAAiB,UAAA,KAAA,EAEjBJ,SAFiB;UAEjBA,KAAAA;UAKEA,OAAAA;UAQFE,OAAAA;UAA0BG,cAAAA;aAA8BA,CAAAA,KAAAA,EARtDL,SAQsDK;MAAjBF,SAAAA,CAAAA,CAAAA,EAAAA,OAAAA;;;;;;;OAQXI,CAAAA,WAR5BL,SAQ4BK,EAAAA,CAAAA,CAAAA,WAAAA,EARFF,EAQEE,CAAAA,EARGD,OAQHC,CARWJ,gBAQXI,CAR4BF,EAQ5BE,CAAAA,CAAAA;KAAsBD,CAAAA,SAAAA,EAAAA,MAAAA,EAAAA,EAAAA,GAAAA,EAAAA,MAAAA,CAAAA,EAP5BA,OAO4BA,CAPpBL,IAOoBK,GAAAA,IAAAA,CAAAA;QACzBA,CAAAA,eAAAA,EAAAA,MAAAA,EAAAA,EAAAA,QAAAA,EAAAA;IAElCA,MAAAA,CAAAA,EARKC,MAQLD,CAAAA,MAAAA,EAAAA,GAAAA,CAAAA;IAQWJ,KAAAA,CAAAA,EAAAA,MAAAA;IADRM,MAAAA,CAAAA,EAAAA,MAAAA;IAjCgCR,KAAAA,CAAAA,EAAAA,MAAAA;MAsBvCM,QAAQL;+CACiCM,sBAAsBD;4CACzBA;;UAElCA;;;;;;;WAOGE;iBACQN"} |
| {"version":3,"file":"memory.cjs","names":["BaseStore","tokenizePath","candidates: Item[]","compareValues","flatItems: Item[]","flatVectors: number[][]","scoreless: Item[]","kept: Array<[number | undefined, Item]>","toEmbed: { [text: string]: [string[], string, string][] }","getTextAtPath"],"sources":["../../src/store/memory.ts"],"sourcesContent":["import {\n BaseStore,\n type OperationResults,\n type Item,\n type Operation,\n MatchCondition,\n ListNamespacesOperation,\n PutOperation,\n SearchOperation,\n GetOperation,\n type IndexConfig,\n type SearchItem,\n} from \"./base.js\";\nimport { tokenizePath, compareValues, getTextAtPath } from \"./utils.js\";\n\n/**\n * In-memory key-value store with optional vector search.\n *\n * A lightweight store implementation using JavaScript Maps. Supports basic\n * key-value operations and vector search when configured with embeddings.\n *\n * @example\n * ```typescript\n * // Basic key-value storage\n * const store = new InMemoryStore();\n * await store.put([\"users\", \"123\"], \"prefs\", { theme: \"dark\" });\n * const item = await store.get([\"users\", \"123\"], \"prefs\");\n *\n * // Vector search with embeddings\n * import { OpenAIEmbeddings } from \"@langchain/openai\";\n * const store = new InMemoryStore({\n * index: {\n * dims: 1536,\n * embeddings: new OpenAIEmbeddings({ modelName: \"text-embedding-3-small\" }),\n * }\n * });\n *\n * // Store documents\n * await store.put([\"docs\"], \"doc1\", { text: \"Python tutorial\" });\n * await store.put([\"docs\"], \"doc2\", { text: \"TypeScript guide\" });\n *\n * // Search by similarity\n * const results = await store.search([\"docs\"], { query: \"python programming\" });\n * ```\n *\n * **Warning**: This store keeps all data in memory. Data is lost when the process exits.\n * For persistence, use a database-backed store.\n */\nexport class InMemoryStore extends BaseStore {\n private data: Map<string, Map<string, Item>> = new Map();\n\n // Namespace -> Key -> Path/field -> Vector\n private vectors: Map<string, Map<string, Map<string, number[]>>> = new Map();\n\n private _indexConfig?: IndexConfig & {\n __tokenizedFields: Array<[string, string[]]>;\n };\n\n constructor(options?: { index?: IndexConfig }) {\n super();\n if (options?.index) {\n this._indexConfig = {\n ...options.index,\n __tokenizedFields: (options.index.fields ?? [\"$\"]).map((p) => [\n p,\n p === \"$\" ? [p] : tokenizePath(p),\n ]),\n };\n }\n }\n\n async batch<Op extends readonly Operation[]>(\n operations: Op\n ): Promise<OperationResults<Op>> {\n const results = [];\n const putOps = new Map<string, PutOperation>();\n const searchOps = new Map<number, [SearchOperation, Item[]]>();\n\n // First pass - handle gets and prepare search/put operations\n for (let i = 0; i < operations.length; i += 1) {\n const op = operations[i];\n if (\"key\" in op && \"namespace\" in op && !(\"value\" in op)) {\n // GetOperation\n results.push(this.getOperation(op));\n } else if (\"namespacePrefix\" in op) {\n // SearchOperation\n const candidates = this.filterItems(op);\n searchOps.set(i, [op, candidates]);\n results.push(null);\n } else if (\"value\" in op) {\n // PutOperation\n const key = `${op.namespace.join(\":\")}:${op.key}`;\n putOps.set(key, op);\n results.push(null);\n } else if (\"matchConditions\" in op) {\n // ListNamespacesOperation\n results.push(this.listNamespacesOperation(op));\n }\n }\n\n // Handle search operations with embeddings\n if (searchOps.size > 0) {\n if (this._indexConfig?.embeddings) {\n const queries = new Set<string>();\n for (const [op] of searchOps.values()) {\n if (op.query) queries.add(op.query);\n }\n\n // Get embeddings for all queries\n const queryEmbeddings =\n queries.size > 0\n ? await Promise.all(\n Array.from(queries).map((q) =>\n this._indexConfig!.embeddings.embedQuery(q)\n )\n )\n : [];\n const queryVectors = Object.fromEntries(\n Array.from(queries).map((q, i) => [q, queryEmbeddings[i]])\n );\n\n // Process each search operation\n for (const [i, [op, candidates]] of searchOps.entries()) {\n if (op.query && queryVectors[op.query]) {\n const queryVector = queryVectors[op.query];\n const scoredResults = this.scoreResults(\n candidates,\n queryVector,\n op.offset ?? 0,\n op.limit ?? 10\n );\n results[i] = scoredResults;\n } else {\n results[i] = this.paginateResults(\n candidates.map((item) => ({ ...item, score: undefined })),\n op.offset ?? 0,\n op.limit ?? 10\n );\n }\n }\n } else {\n // No embeddings - just paginate the filtered results\n for (const [i, [op, candidates]] of searchOps.entries()) {\n results[i] = this.paginateResults(\n candidates.map((item) => ({ ...item, score: undefined })),\n op.offset ?? 0,\n op.limit ?? 10\n );\n }\n }\n }\n\n // Handle put operations with embeddings\n if (putOps.size > 0 && this._indexConfig?.embeddings) {\n const toEmbed = this.extractTexts(Array.from(putOps.values()));\n if (Object.keys(toEmbed).length > 0) {\n const embeddings = await this._indexConfig.embeddings.embedDocuments(\n Object.keys(toEmbed)\n );\n this.insertVectors(toEmbed, embeddings);\n }\n }\n\n // Apply all put operations\n for (const op of putOps.values()) {\n this.putOperation(op);\n }\n\n return results as OperationResults<Op>;\n }\n\n private getOperation(op: GetOperation): Item | null {\n const namespaceKey = op.namespace.join(\":\");\n const item = this.data.get(namespaceKey)?.get(op.key);\n return item ?? null;\n }\n\n private putOperation(op: PutOperation): void {\n const namespaceKey = op.namespace.join(\":\");\n if (!this.data.has(namespaceKey)) {\n this.data.set(namespaceKey, new Map());\n }\n const namespaceMap = this.data.get(namespaceKey)!;\n\n if (op.value === null) {\n namespaceMap.delete(op.key);\n } else {\n const now = new Date();\n if (namespaceMap.has(op.key)) {\n const item = namespaceMap.get(op.key)!;\n item.value = op.value;\n item.updatedAt = now;\n } else {\n namespaceMap.set(op.key, {\n value: op.value,\n key: op.key,\n namespace: op.namespace,\n createdAt: now,\n updatedAt: now,\n });\n }\n }\n }\n\n private listNamespacesOperation(op: ListNamespacesOperation): string[][] {\n const allNamespaces = Array.from(this.data.keys()).map((ns) =>\n ns.split(\":\")\n );\n let namespaces = allNamespaces;\n\n if (op.matchConditions && op.matchConditions.length > 0) {\n namespaces = namespaces.filter((ns) =>\n op.matchConditions!.every((condition) => this.doesMatch(condition, ns))\n );\n }\n\n if (op.maxDepth !== undefined) {\n namespaces = Array.from(\n new Set(namespaces.map((ns) => ns.slice(0, op.maxDepth).join(\":\")))\n ).map((ns) => ns.split(\":\"));\n }\n\n namespaces.sort((a, b) => a.join(\":\").localeCompare(b.join(\":\")));\n\n return namespaces.slice(\n op.offset ?? 0,\n (op.offset ?? 0) + (op.limit ?? namespaces.length)\n );\n }\n\n private doesMatch(matchCondition: MatchCondition, key: string[]): boolean {\n const { matchType, path } = matchCondition;\n\n if (matchType === \"prefix\") {\n if (path.length > key.length) return false;\n return path.every((pElem, index) => {\n const kElem = key[index];\n return pElem === \"*\" || kElem === pElem;\n });\n } else if (matchType === \"suffix\") {\n if (path.length > key.length) return false;\n return path.every((pElem, index) => {\n const kElem = key[key.length - path.length + index];\n return pElem === \"*\" || kElem === pElem;\n });\n }\n\n throw new Error(`Unsupported match type: ${matchType}`);\n }\n\n private filterItems(op: SearchOperation): Item[] {\n const candidates: Item[] = [];\n for (const [namespace, items] of this.data.entries()) {\n if (namespace.startsWith(op.namespacePrefix.join(\":\"))) {\n candidates.push(...items.values());\n }\n }\n\n let filteredCandidates = candidates;\n if (op.filter) {\n filteredCandidates = candidates.filter((item) =>\n Object.entries(op.filter!).every(([key, value]) =>\n compareValues(item.value[key], value)\n )\n );\n }\n return filteredCandidates;\n }\n\n private scoreResults(\n candidates: Item[],\n queryVector: number[],\n offset: number = 0,\n limit: number = 10\n ): SearchItem[] {\n const flatItems: Item[] = [];\n const flatVectors: number[][] = [];\n const scoreless: Item[] = [];\n\n for (const item of candidates) {\n const vectors = this.getVectors(item);\n if (vectors.length) {\n for (const vector of vectors) {\n flatItems.push(item);\n flatVectors.push(vector);\n }\n } else {\n scoreless.push(item);\n }\n }\n\n const scores = this.cosineSimilarity(queryVector, flatVectors);\n\n const sortedResults = scores\n .map((score, i) => [score, flatItems[i]] as [number, Item])\n .sort((a, b) => b[0] - a[0]);\n\n const seen = new Set<string>();\n const kept: Array<[number | undefined, Item]> = [];\n\n for (const [score, item] of sortedResults) {\n const key = `${item.namespace.join(\":\")}:${item.key}`;\n if (seen.has(key)) continue;\n\n const ix = seen.size;\n if (ix >= offset + limit) break;\n if (ix < offset) {\n seen.add(key);\n continue;\n }\n\n seen.add(key);\n kept.push([score, item]);\n }\n\n if (scoreless.length && kept.length < limit) {\n for (const item of scoreless.slice(0, limit - kept.length)) {\n const key = `${item.namespace.join(\":\")}:${item.key}`;\n if (!seen.has(key)) {\n seen.add(key);\n kept.push([undefined, item]);\n }\n }\n }\n return kept.map(([score, item]) => ({\n ...item,\n score,\n }));\n }\n\n private paginateResults(\n results: SearchItem[],\n offset: number,\n limit: number\n ): SearchItem[] {\n return results.slice(offset, offset + limit);\n }\n\n private extractTexts(ops: PutOperation[]): {\n [text: string]: [string[], string, string][];\n } {\n if (!ops.length || !this._indexConfig) {\n return {};\n }\n\n const toEmbed: { [text: string]: [string[], string, string][] } = {};\n\n for (const op of ops) {\n if (op.value !== null && op.index !== false) {\n const paths =\n op.index === null || op.index === undefined\n ? this._indexConfig.__tokenizedFields ?? []\n : op.index.map(\n (ix) => [ix, tokenizePath(ix)] as [string, string[]]\n );\n for (const [path, field] of paths) {\n const texts = getTextAtPath(op.value, field);\n if (texts.length) {\n if (texts.length > 1) {\n texts.forEach((text, i) => {\n if (!toEmbed[text]) toEmbed[text] = [];\n toEmbed[text].push([op.namespace, op.key, `${path}.${i}`]);\n });\n } else {\n if (!toEmbed[texts[0]]) toEmbed[texts[0]] = [];\n toEmbed[texts[0]].push([op.namespace, op.key, path]);\n }\n }\n }\n }\n }\n\n return toEmbed;\n }\n\n private insertVectors(\n texts: { [text: string]: [string[], string, string][] },\n embeddings: number[][]\n ): void {\n for (const [text, metadata] of Object.entries(texts)) {\n const embedding = embeddings.shift();\n if (!embedding) {\n throw new Error(`No embedding found for text: ${text}`);\n }\n\n for (const [namespace, key, field] of metadata) {\n const namespaceKey = namespace.join(\":\");\n if (!this.vectors.has(namespaceKey)) {\n this.vectors.set(namespaceKey, new Map());\n }\n const namespaceMap = this.vectors.get(namespaceKey)!;\n if (!namespaceMap.has(key)) {\n namespaceMap.set(key, new Map());\n }\n const itemMap = namespaceMap.get(key)!;\n itemMap.set(field, embedding);\n }\n }\n }\n\n private getVectors(item: Item): number[][] {\n const namespaceKey = item.namespace.join(\":\");\n const itemKey = item.key;\n if (!this.vectors.has(namespaceKey)) {\n return [];\n }\n const namespaceMap = this.vectors.get(namespaceKey)!;\n if (!namespaceMap.has(itemKey)) {\n return [];\n }\n const itemMap = namespaceMap.get(itemKey)!;\n const vectors = Array.from(itemMap.values());\n if (!vectors.length) {\n return [];\n }\n return vectors;\n }\n\n private cosineSimilarity(X: number[], Y: number[][]): number[] {\n if (!Y.length) return [];\n\n // Calculate dot products for all vectors at once\n const dotProducts = Y.map((vector) =>\n vector.reduce((acc, val, i) => acc + val * X[i], 0)\n );\n\n // Calculate magnitudes\n const magnitude1 = Math.sqrt(X.reduce((acc, val) => acc + val * val, 0));\n const magnitudes2 = Y.map((vector) =>\n Math.sqrt(vector.reduce((acc, val) => acc + val * val, 0))\n );\n\n // Calculate similarities\n return dotProducts.map((dot, i) => {\n const magnitude2 = magnitudes2[i];\n return magnitude1 && magnitude2 ? dot / (magnitude1 * magnitude2) : 0;\n });\n }\n\n public get indexConfig(): IndexConfig | undefined {\n return this._indexConfig;\n }\n}\n\n/** @deprecated Alias for InMemoryStore */\nexport class MemoryStore extends InMemoryStore {}\n"],"mappings":"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"} |
| import { BaseStore, IndexConfig, Operation, OperationResults } from "./base.cjs"; | ||
| //#region src/store/memory.d.ts | ||
| /** | ||
| * In-memory key-value store with optional vector search. | ||
| * | ||
| * A lightweight store implementation using JavaScript Maps. Supports basic | ||
| * key-value operations and vector search when configured with embeddings. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Basic key-value storage | ||
| * const store = new InMemoryStore(); | ||
| * await store.put(["users", "123"], "prefs", { theme: "dark" }); | ||
| * const item = await store.get(["users", "123"], "prefs"); | ||
| * | ||
| * // Vector search with embeddings | ||
| * import { OpenAIEmbeddings } from "@langchain/openai"; | ||
| * const store = new InMemoryStore({ | ||
| * index: { | ||
| * dims: 1536, | ||
| * embeddings: new OpenAIEmbeddings({ modelName: "text-embedding-3-small" }), | ||
| * } | ||
| * }); | ||
| * | ||
| * // Store documents | ||
| * await store.put(["docs"], "doc1", { text: "Python tutorial" }); | ||
| * await store.put(["docs"], "doc2", { text: "TypeScript guide" }); | ||
| * | ||
| * // Search by similarity | ||
| * const results = await store.search(["docs"], { query: "python programming" }); | ||
| * ``` | ||
| * | ||
| * **Warning**: This store keeps all data in memory. Data is lost when the process exits. | ||
| * For persistence, use a database-backed store. | ||
| */ | ||
| declare class InMemoryStore extends BaseStore { | ||
| private data; | ||
| // Namespace -> Key -> Path/field -> Vector | ||
| private vectors; | ||
| private _indexConfig?; | ||
| constructor(options?: { | ||
| index?: IndexConfig; | ||
| }); | ||
| batch<Op extends readonly Operation[]>(operations: Op): Promise<OperationResults<Op>>; | ||
| private getOperation; | ||
| private putOperation; | ||
| private listNamespacesOperation; | ||
| private doesMatch; | ||
| private filterItems; | ||
| private scoreResults; | ||
| private paginateResults; | ||
| private extractTexts; | ||
| private insertVectors; | ||
| private getVectors; | ||
| private cosineSimilarity; | ||
| get indexConfig(): IndexConfig | undefined; | ||
| } | ||
| /** @deprecated Alias for InMemoryStore */ | ||
| declare class MemoryStore extends InMemoryStore {} | ||
| //#endregion | ||
| export { InMemoryStore, MemoryStore }; | ||
| //# sourceMappingURL=memory.d.cts.map |
| {"version":3,"file":"memory.d.cts","names":["BaseStore","OperationResults","Operation","IndexConfig","InMemoryStore","Op","Promise","MemoryStore"],"sources":["../../src/store/memory.d.ts"],"sourcesContent":["import { BaseStore, type OperationResults, type Operation, type IndexConfig } from \"./base.js\";\n/**\n * In-memory key-value store with optional vector search.\n *\n * A lightweight store implementation using JavaScript Maps. Supports basic\n * key-value operations and vector search when configured with embeddings.\n *\n * @example\n * ```typescript\n * // Basic key-value storage\n * const store = new InMemoryStore();\n * await store.put([\"users\", \"123\"], \"prefs\", { theme: \"dark\" });\n * const item = await store.get([\"users\", \"123\"], \"prefs\");\n *\n * // Vector search with embeddings\n * import { OpenAIEmbeddings } from \"@langchain/openai\";\n * const store = new InMemoryStore({\n * index: {\n * dims: 1536,\n * embeddings: new OpenAIEmbeddings({ modelName: \"text-embedding-3-small\" }),\n * }\n * });\n *\n * // Store documents\n * await store.put([\"docs\"], \"doc1\", { text: \"Python tutorial\" });\n * await store.put([\"docs\"], \"doc2\", { text: \"TypeScript guide\" });\n *\n * // Search by similarity\n * const results = await store.search([\"docs\"], { query: \"python programming\" });\n * ```\n *\n * **Warning**: This store keeps all data in memory. Data is lost when the process exits.\n * For persistence, use a database-backed store.\n */\nexport declare class InMemoryStore extends BaseStore {\n private data;\n // Namespace -> Key -> Path/field -> Vector\n private vectors;\n private _indexConfig?;\n constructor(options?: {\n index?: IndexConfig;\n });\n batch<Op extends readonly Operation[]>(operations: Op): Promise<OperationResults<Op>>;\n private getOperation;\n private putOperation;\n private listNamespacesOperation;\n private doesMatch;\n private filterItems;\n private scoreResults;\n private paginateResults;\n private extractTexts;\n private insertVectors;\n private getVectors;\n private cosineSimilarity;\n get indexConfig(): IndexConfig | undefined;\n}\n/** @deprecated Alias for InMemoryStore */\nexport declare class MemoryStore extends InMemoryStore {\n}\n"],"mappings":";;;;;;AAkCA;;;;;;;;;;;AAuBA;;;;;;;;;;;;;;;;;;;;cAvBqBI,aAAAA,SAAsBJ,SAAAA;;;;;;YAM3BG;;4BAEcD,yBAAyBG,KAAKC,QAAQL,iBAAiBI;;;;;;;;;;;;qBAY9DF;;;cAGFI,WAAAA,SAAoBH,aAAAA"} |
| {"version":3,"file":"memory.d.ts","names":["BaseStore","OperationResults","Operation","IndexConfig","InMemoryStore","Op","Promise","MemoryStore"],"sources":["../../src/store/memory.d.ts"],"sourcesContent":["import { BaseStore, type OperationResults, type Operation, type IndexConfig } from \"./base.js\";\n/**\n * In-memory key-value store with optional vector search.\n *\n * A lightweight store implementation using JavaScript Maps. Supports basic\n * key-value operations and vector search when configured with embeddings.\n *\n * @example\n * ```typescript\n * // Basic key-value storage\n * const store = new InMemoryStore();\n * await store.put([\"users\", \"123\"], \"prefs\", { theme: \"dark\" });\n * const item = await store.get([\"users\", \"123\"], \"prefs\");\n *\n * // Vector search with embeddings\n * import { OpenAIEmbeddings } from \"@langchain/openai\";\n * const store = new InMemoryStore({\n * index: {\n * dims: 1536,\n * embeddings: new OpenAIEmbeddings({ modelName: \"text-embedding-3-small\" }),\n * }\n * });\n *\n * // Store documents\n * await store.put([\"docs\"], \"doc1\", { text: \"Python tutorial\" });\n * await store.put([\"docs\"], \"doc2\", { text: \"TypeScript guide\" });\n *\n * // Search by similarity\n * const results = await store.search([\"docs\"], { query: \"python programming\" });\n * ```\n *\n * **Warning**: This store keeps all data in memory. Data is lost when the process exits.\n * For persistence, use a database-backed store.\n */\nexport declare class InMemoryStore extends BaseStore {\n private data;\n // Namespace -> Key -> Path/field -> Vector\n private vectors;\n private _indexConfig?;\n constructor(options?: {\n index?: IndexConfig;\n });\n batch<Op extends readonly Operation[]>(operations: Op): Promise<OperationResults<Op>>;\n private getOperation;\n private putOperation;\n private listNamespacesOperation;\n private doesMatch;\n private filterItems;\n private scoreResults;\n private paginateResults;\n private extractTexts;\n private insertVectors;\n private getVectors;\n private cosineSimilarity;\n get indexConfig(): IndexConfig | undefined;\n}\n/** @deprecated Alias for InMemoryStore */\nexport declare class MemoryStore extends InMemoryStore {\n}\n"],"mappings":";;;;;;AAkCA;;;;;;;;;;;AAuBA;;;;;;;;;;;;;;;;;;;;cAvBqBI,aAAAA,SAAsBJ,SAAAA;;;;;;YAM3BG;;4BAEcD,yBAAyBG,KAAKC,QAAQL,iBAAiBI;;;;;;;;;;;;qBAY9DF;;;cAGFI,WAAAA,SAAoBH,aAAAA"} |
| {"version":3,"file":"utils.cjs","names":["tokens: string[]","current: string[]","tokens","obj","results: string[]"],"sources":["../../src/store/utils.ts"],"sourcesContent":["/**\n * Tokenize a JSON path into parts.\n * @example\n * tokenizePath(\"metadata.title\") // -> [\"metadata\", \"title\"]\n * tokenizePath(\"chapters[*].content\") // -> [\"chapters[*]\", \"content\"]\n */\nexport function tokenizePath(path: string): string[] {\n if (!path) {\n return [];\n }\n\n const tokens: string[] = [];\n let current: string[] = [];\n let i = 0;\n\n while (i < path.length) {\n const char = path[i];\n\n if (char === \"[\") {\n // Handle array index\n if (current.length) {\n tokens.push(current.join(\"\"));\n current = [];\n }\n let bracketCount = 1;\n const indexChars = [\"[\"];\n i += 1;\n while (i < path.length && bracketCount > 0) {\n if (path[i] === \"[\") {\n bracketCount += 1;\n } else if (path[i] === \"]\") {\n bracketCount -= 1;\n }\n indexChars.push(path[i]);\n i += 1;\n }\n tokens.push(indexChars.join(\"\"));\n continue;\n } else if (char === \"{\") {\n // Handle multi-field selection\n if (current.length) {\n tokens.push(current.join(\"\"));\n current = [];\n }\n let braceCount = 1;\n const fieldChars = [\"{\"];\n i += 1;\n while (i < path.length && braceCount > 0) {\n if (path[i] === \"{\") {\n braceCount += 1;\n } else if (path[i] === \"}\") {\n braceCount -= 1;\n }\n fieldChars.push(path[i]);\n i += 1;\n }\n tokens.push(fieldChars.join(\"\"));\n continue;\n } else if (char === \".\") {\n // Handle regular field\n if (current.length) {\n tokens.push(current.join(\"\"));\n current = [];\n }\n } else {\n current.push(char);\n }\n i += 1;\n }\n\n if (current.length) {\n tokens.push(current.join(\"\"));\n }\n\n return tokens;\n}\n\n/**\n * Represents the supported filter operators\n */\ntype FilterOperators = {\n $eq?: unknown;\n $ne?: unknown;\n $gt?: unknown;\n $gte?: unknown;\n $lt?: unknown;\n $lte?: unknown;\n $in?: unknown[];\n $nin?: unknown[];\n};\n\n/**\n * Type guard to check if an object is a FilterOperators\n */\nfunction isFilterOperators(obj: unknown): obj is FilterOperators {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n Object.keys(obj).every(\n (key) =>\n key === \"$eq\" ||\n key === \"$ne\" ||\n key === \"$gt\" ||\n key === \"$gte\" ||\n key === \"$lt\" ||\n key === \"$lte\" ||\n key === \"$in\" ||\n key === \"$nin\"\n )\n );\n}\n\n/**\n * Compare values for filtering, supporting operator-based comparisons.\n */\nexport function compareValues(\n itemValue: unknown,\n filterValue: unknown\n): boolean {\n if (isFilterOperators(filterValue)) {\n const operators = Object.keys(filterValue).filter((k) => k.startsWith(\"$\"));\n return operators.every((op) => {\n const value = filterValue[op as keyof FilterOperators];\n switch (op) {\n case \"$eq\":\n return itemValue === value;\n case \"$ne\":\n return itemValue !== value;\n case \"$gt\":\n return Number(itemValue) > Number(value);\n case \"$gte\":\n return Number(itemValue) >= Number(value);\n case \"$lt\":\n return Number(itemValue) < Number(value);\n case \"$lte\":\n return Number(itemValue) <= Number(value);\n case \"$in\":\n return Array.isArray(value) ? value.includes(itemValue) : false;\n case \"$nin\":\n return Array.isArray(value) ? !value.includes(itemValue) : true;\n default:\n return false;\n }\n });\n }\n\n // If no operators, do a direct comparison\n return itemValue === filterValue;\n}\n\n/**\n * Extract text from a value at a specific JSON path.\n *\n * Supports:\n * - Simple paths: \"field1.field2\"\n * - Array indexing: \"[0]\", \"[*]\", \"[-1]\"\n * - Wildcards: \"*\"\n * - Multi-field selection: \"{field1,field2}\"\n * - Nested paths in multi-field: \"{field1,nested.field2}\"\n */\nexport function getTextAtPath(obj: unknown, path: string[] | string): string[] {\n if (!path || path === \"$\") {\n return [JSON.stringify(obj, null, 2)];\n }\n const tokens = Array.isArray(path) ? path : tokenizePath(path);\n\n function extractFromObj(\n obj: unknown,\n tokens: string[],\n pos: number\n ): string[] {\n if (pos >= tokens.length) {\n if (\n typeof obj === \"string\" ||\n typeof obj === \"number\" ||\n typeof obj === \"boolean\"\n ) {\n return [String(obj)];\n }\n if (obj === null || obj === undefined) {\n return [];\n }\n if (Array.isArray(obj) || typeof obj === \"object\") {\n return [JSON.stringify(obj, null, 2)];\n }\n return [];\n }\n\n const token = tokens[pos];\n const results: string[] = [];\n if (pos === 0 && token === \"$\") {\n results.push(JSON.stringify(obj, null, 2));\n }\n\n if (token.startsWith(\"[\") && token.endsWith(\"]\")) {\n if (!Array.isArray(obj)) return [];\n\n const index = token.slice(1, -1);\n if (index === \"*\") {\n for (const item of obj) {\n results.push(...extractFromObj(item, tokens, pos + 1));\n }\n } else {\n try {\n let idx = parseInt(index, 10);\n if (idx < 0) {\n idx = obj.length + idx;\n }\n if (idx >= 0 && idx < obj.length) {\n results.push(...extractFromObj(obj[idx], tokens, pos + 1));\n }\n } catch {\n return [];\n }\n }\n } else if (token.startsWith(\"{\") && token.endsWith(\"}\")) {\n if (typeof obj !== \"object\" || obj === null) return [];\n\n const fields = token\n .slice(1, -1)\n .split(\",\")\n .map((f) => f.trim());\n for (const field of fields) {\n const nestedTokens = tokenizePath(field);\n if (nestedTokens.length) {\n let currentObj = obj as Record<string, unknown> | undefined;\n for (const nestedToken of nestedTokens) {\n if (\n currentObj &&\n typeof currentObj === \"object\" &&\n nestedToken in currentObj\n ) {\n currentObj = currentObj[nestedToken] as Record<string, unknown>;\n } else {\n currentObj = undefined;\n break;\n }\n }\n if (currentObj !== undefined) {\n if (\n typeof currentObj === \"string\" ||\n typeof currentObj === \"number\" ||\n typeof currentObj === \"boolean\"\n ) {\n results.push(String(currentObj));\n } else if (\n Array.isArray(currentObj) ||\n typeof currentObj === \"object\"\n ) {\n results.push(JSON.stringify(currentObj, null, 2));\n }\n }\n }\n }\n } else if (token === \"*\") {\n if (Array.isArray(obj)) {\n for (const item of obj) {\n results.push(...extractFromObj(item, tokens, pos + 1));\n }\n } else if (typeof obj === \"object\" && obj !== null) {\n for (const value of Object.values(obj)) {\n results.push(...extractFromObj(value, tokens, pos + 1));\n }\n }\n } else {\n if (typeof obj === \"object\" && obj !== null && token in obj) {\n results.push(\n ...extractFromObj(\n (obj as Record<string, unknown>)[token],\n tokens,\n pos + 1\n )\n );\n }\n }\n\n return results;\n }\n\n return extractFromObj(obj, tokens, 0);\n}\n\n/**\n * Calculate cosine similarity between two vectors.\n */\nexport function cosineSimilarity(vector1: number[], vector2: number[]): number {\n if (vector1.length !== vector2.length) {\n throw new Error(\"Vectors must have the same length\");\n }\n\n const dotProduct = vector1.reduce((acc, val, i) => acc + val * vector2[i], 0);\n const magnitude1 = Math.sqrt(\n vector1.reduce((acc, val) => acc + val * val, 0)\n );\n const magnitude2 = Math.sqrt(\n vector2.reduce((acc, val) => acc + val * val, 0)\n );\n\n if (magnitude1 === 0 || magnitude2 === 0) return 0;\n return dotProduct / (magnitude1 * magnitude2);\n}\n"],"mappings":"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"} |
| //#region src/types.d.ts | ||
| type All = "*"; | ||
| type PendingWriteValue = unknown; | ||
| type PendingWrite<Channel = string> = [Channel, PendingWriteValue]; | ||
| type CheckpointPendingWrite<TaskId = string> = [TaskId, ...PendingWrite<string>]; | ||
| /** | ||
| * Additional details about the checkpoint, including the source, step, writes, and parents. | ||
| * | ||
| * @typeParam ExtraProperties - Optional additional properties to include in the metadata. | ||
| */ | ||
| type CheckpointMetadata<ExtraProperties extends object = object> = { | ||
| /** | ||
| * The source of the checkpoint. | ||
| * - "input": The checkpoint was created from an input to invoke/stream/batch. | ||
| * - "loop": The checkpoint was created from inside the pregel loop. | ||
| * - "update": The checkpoint was created from a manual state update. | ||
| * - "fork": The checkpoint was created as a copy of another checkpoint. | ||
| */ | ||
| source: "input" | "loop" | "update" | "fork"; | ||
| /** | ||
| * The step number of the checkpoint. | ||
| * -1 for the first "input" checkpoint. | ||
| * 0 for the first "loop" checkpoint. | ||
| * ... for the nth checkpoint afterwards. | ||
| */ | ||
| step: number; | ||
| /** | ||
| * The IDs of the parent checkpoints. | ||
| * Mapping from checkpoint namespace to checkpoint ID. | ||
| */ | ||
| parents: Record<string, string>; | ||
| } & ExtraProperties; | ||
| //#endregion | ||
| export { All, CheckpointMetadata, CheckpointPendingWrite, PendingWrite, PendingWriteValue }; | ||
| //# sourceMappingURL=types.d.cts.map |
| {"version":3,"file":"types.d.cts","names":["All","PendingWriteValue","PendingWrite","Channel","CheckpointPendingWrite","TaskId","CheckpointMetadata","Record","ExtraProperties"],"sources":["../src/types.d.ts"],"sourcesContent":["export type All = \"*\";\nexport type PendingWriteValue = unknown;\nexport type PendingWrite<Channel = string> = [Channel, PendingWriteValue];\nexport type CheckpointPendingWrite<TaskId = string> = [\n TaskId,\n ...PendingWrite<string>\n];\n/**\n * Additional details about the checkpoint, including the source, step, writes, and parents.\n *\n * @typeParam ExtraProperties - Optional additional properties to include in the metadata.\n */\nexport type CheckpointMetadata<ExtraProperties extends object = object> = {\n /**\n * The source of the checkpoint.\n * - \"input\": The checkpoint was created from an input to invoke/stream/batch.\n * - \"loop\": The checkpoint was created from inside the pregel loop.\n * - \"update\": The checkpoint was created from a manual state update.\n * - \"fork\": The checkpoint was created as a copy of another checkpoint.\n */\n source: \"input\" | \"loop\" | \"update\" | \"fork\";\n /**\n * The step number of the checkpoint.\n * -1 for the first \"input\" checkpoint.\n * 0 for the first \"loop\" checkpoint.\n * ... for the nth checkpoint afterwards.\n */\n step: number;\n /**\n * The IDs of the parent checkpoints.\n * Mapping from checkpoint namespace to checkpoint ID.\n */\n parents: Record<string, string>;\n} & ExtraProperties;\n"],"mappings":";KAAYA,GAAAA;AAAAA,KACAC,iBAAAA,GADG,OAAA;AACHA,KACAC,YADiB,CAAA,UAAA,MAAA,CAAA,GAAA,CACiBC,OADjB,EAC0BF,iBAD1B,CAAA;AACjBC,KACAE,sBADY,CAAA,SAAA,MAAA,CAAA,GAAA,CAEpBC,MAFoB,KAGjBH,YAHuCC,CAAAA,MAAAA,CAAAA;;AAC9C;;;;KASYG;EAAAA;;;;;;;;;;;;;;;;;;;WAoBCC;IACTC"} |
| {"version":3,"file":"types.d.ts","names":["All","PendingWriteValue","PendingWrite","Channel","CheckpointPendingWrite","TaskId","CheckpointMetadata","Record","ExtraProperties"],"sources":["../src/types.d.ts"],"sourcesContent":["export type All = \"*\";\nexport type PendingWriteValue = unknown;\nexport type PendingWrite<Channel = string> = [Channel, PendingWriteValue];\nexport type CheckpointPendingWrite<TaskId = string> = [\n TaskId,\n ...PendingWrite<string>\n];\n/**\n * Additional details about the checkpoint, including the source, step, writes, and parents.\n *\n * @typeParam ExtraProperties - Optional additional properties to include in the metadata.\n */\nexport type CheckpointMetadata<ExtraProperties extends object = object> = {\n /**\n * The source of the checkpoint.\n * - \"input\": The checkpoint was created from an input to invoke/stream/batch.\n * - \"loop\": The checkpoint was created from inside the pregel loop.\n * - \"update\": The checkpoint was created from a manual state update.\n * - \"fork\": The checkpoint was created as a copy of another checkpoint.\n */\n source: \"input\" | \"loop\" | \"update\" | \"fork\";\n /**\n * The step number of the checkpoint.\n * -1 for the first \"input\" checkpoint.\n * 0 for the first \"loop\" checkpoint.\n * ... for the nth checkpoint afterwards.\n */\n step: number;\n /**\n * The IDs of the parent checkpoints.\n * Mapping from checkpoint namespace to checkpoint ID.\n */\n parents: Record<string, string>;\n} & ExtraProperties;\n"],"mappings":";KAAYA,GAAAA;AAAAA,KACAC,iBAAAA,GADG,OAAA;AACHA,KACAC,YADiB,CAAA,UAAA,MAAA,CAAA,GAAA,CACiBC,OADjB,EAC0BF,iBAD1B,CAAA;AACjBC,KACAE,sBADY,CAAA,SAAA,MAAA,CAAA,GAAA,CAEpBC,MAFoB,KAGjBH,YAHuCC,CAAAA,MAAAA,CAAAA;;AAC9C;;;;KASYG;EAAAA;;;;;;;;;;;;;;;;;;;WAoBCC;IACTC"} |
+6
-0
| # @langchain/langgraph-checkpoint | ||
| ## 1.0.0 | ||
| ### Major Changes | ||
| - 1e1ecbb: This release updates the package for compatibility with LangGraph v1.0. See the [v1.0 release notes](https://docs.langchain.com/oss/javascript/releases/langgraph-v1) for details on what's new. | ||
| ## 0.1.1 | ||
@@ -4,0 +10,0 @@ |
+74
-88
@@ -1,104 +0,90 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.WRITES_IDX_MAP = exports.BaseCheckpointSaver = void 0; | ||
| exports.deepCopy = deepCopy; | ||
| exports.emptyCheckpoint = emptyCheckpoint; | ||
| exports.copyCheckpoint = copyCheckpoint; | ||
| exports.compareChannelVersions = compareChannelVersions; | ||
| exports.maxChannelVersion = maxChannelVersion; | ||
| exports.getCheckpointId = getCheckpointId; | ||
| const id_js_1 = require("./id.cjs"); | ||
| const types_js_1 = require("./serde/types.cjs"); | ||
| const jsonplus_js_1 = require("./serde/jsonplus.cjs"); | ||
| const require_id = require('./id.cjs'); | ||
| const require_types = require('./serde/types.cjs'); | ||
| const require_jsonplus = require('./serde/jsonplus.cjs'); | ||
| //#region src/base.ts | ||
| function deepCopy(obj) { | ||
| if (typeof obj !== "object" || obj === null) { | ||
| return obj; | ||
| } | ||
| const newObj = Array.isArray(obj) ? [] : {}; | ||
| for (const key in obj) { | ||
| if (Object.prototype.hasOwnProperty.call(obj, key)) { | ||
| newObj[key] = deepCopy(obj[key]); | ||
| } | ||
| } | ||
| return newObj; | ||
| if (typeof obj !== "object" || obj === null) return obj; | ||
| const newObj = Array.isArray(obj) ? [] : {}; | ||
| for (const key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = deepCopy(obj[key]); | ||
| return newObj; | ||
| } | ||
| /** @hidden */ | ||
| function emptyCheckpoint() { | ||
| return { | ||
| v: 4, | ||
| id: (0, id_js_1.uuid6)(-2), | ||
| ts: new Date().toISOString(), | ||
| channel_values: {}, | ||
| channel_versions: {}, | ||
| versions_seen: {}, | ||
| }; | ||
| return { | ||
| v: 4, | ||
| id: require_id.uuid6(-2), | ||
| ts: (/* @__PURE__ */ new Date()).toISOString(), | ||
| channel_values: {}, | ||
| channel_versions: {}, | ||
| versions_seen: {} | ||
| }; | ||
| } | ||
| /** @hidden */ | ||
| function copyCheckpoint(checkpoint) { | ||
| return { | ||
| v: checkpoint.v, | ||
| id: checkpoint.id, | ||
| ts: checkpoint.ts, | ||
| channel_values: { ...checkpoint.channel_values }, | ||
| channel_versions: { ...checkpoint.channel_versions }, | ||
| versions_seen: deepCopy(checkpoint.versions_seen), | ||
| }; | ||
| return { | ||
| v: checkpoint.v, | ||
| id: checkpoint.id, | ||
| ts: checkpoint.ts, | ||
| channel_values: { ...checkpoint.channel_values }, | ||
| channel_versions: { ...checkpoint.channel_versions }, | ||
| versions_seen: deepCopy(checkpoint.versions_seen) | ||
| }; | ||
| } | ||
| class BaseCheckpointSaver { | ||
| constructor(serde) { | ||
| Object.defineProperty(this, "serde", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: new jsonplus_js_1.JsonPlusSerializer() | ||
| }); | ||
| this.serde = serde || this.serde; | ||
| } | ||
| async get(config) { | ||
| const value = await this.getTuple(config); | ||
| return value ? value.checkpoint : undefined; | ||
| } | ||
| /** | ||
| * Generate the next version ID for a channel. | ||
| * | ||
| * Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions, | ||
| * as long as they are monotonically increasing. | ||
| */ | ||
| getNextVersion(current) { | ||
| if (typeof current === "string") { | ||
| throw new Error("Please override this method to use string versions."); | ||
| } | ||
| return (current !== undefined && typeof current === "number" ? current + 1 : 1); | ||
| } | ||
| } | ||
| exports.BaseCheckpointSaver = BaseCheckpointSaver; | ||
| var BaseCheckpointSaver = class { | ||
| serde = new require_jsonplus.JsonPlusSerializer(); | ||
| constructor(serde) { | ||
| this.serde = serde || this.serde; | ||
| } | ||
| async get(config) { | ||
| const value = await this.getTuple(config); | ||
| return value ? value.checkpoint : void 0; | ||
| } | ||
| /** | ||
| * Generate the next version ID for a channel. | ||
| * | ||
| * Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions, | ||
| * as long as they are monotonically increasing. | ||
| */ | ||
| getNextVersion(current) { | ||
| if (typeof current === "string") throw new Error("Please override this method to use string versions."); | ||
| return current !== void 0 && typeof current === "number" ? current + 1 : 1; | ||
| } | ||
| }; | ||
| function compareChannelVersions(a, b) { | ||
| if (typeof a === "number" && typeof b === "number") { | ||
| return Math.sign(a - b); | ||
| } | ||
| return String(a).localeCompare(String(b)); | ||
| if (typeof a === "number" && typeof b === "number") return Math.sign(a - b); | ||
| return String(a).localeCompare(String(b)); | ||
| } | ||
| function maxChannelVersion(...versions) { | ||
| return versions.reduce((max, version, idx) => { | ||
| if (idx === 0) | ||
| return version; | ||
| return compareChannelVersions(max, version) >= 0 ? max : version; | ||
| }); | ||
| return versions.reduce((max, version, idx) => { | ||
| if (idx === 0) return version; | ||
| return compareChannelVersions(max, version) >= 0 ? max : version; | ||
| }); | ||
| } | ||
| /** | ||
| * Mapping from error type to error index. | ||
| * Regular writes just map to their index in the list of writes being saved. | ||
| * Special writes (e.g. errors) map to negative indices, to avoid those writes from | ||
| * conflicting with regular writes. | ||
| * Each Checkpointer implementation should use this mapping in put_writes. | ||
| */ | ||
| exports.WRITES_IDX_MAP = { | ||
| [types_js_1.ERROR]: -1, | ||
| [types_js_1.SCHEDULED]: -2, | ||
| [types_js_1.INTERRUPT]: -3, | ||
| [types_js_1.RESUME]: -4, | ||
| * Mapping from error type to error index. | ||
| * Regular writes just map to their index in the list of writes being saved. | ||
| * Special writes (e.g. errors) map to negative indices, to avoid those writes from | ||
| * conflicting with regular writes. | ||
| * Each Checkpointer implementation should use this mapping in put_writes. | ||
| */ | ||
| const WRITES_IDX_MAP = { | ||
| [require_types.ERROR]: -1, | ||
| [require_types.SCHEDULED]: -2, | ||
| [require_types.INTERRUPT]: -3, | ||
| [require_types.RESUME]: -4 | ||
| }; | ||
| function getCheckpointId(config) { | ||
| return (config.configurable?.checkpoint_id || config.configurable?.thread_ts || ""); | ||
| return config.configurable?.checkpoint_id || config.configurable?.thread_ts || ""; | ||
| } | ||
| //# sourceMappingURL=base.js.map | ||
| //#endregion | ||
| exports.BaseCheckpointSaver = BaseCheckpointSaver; | ||
| exports.WRITES_IDX_MAP = WRITES_IDX_MAP; | ||
| exports.compareChannelVersions = compareChannelVersions; | ||
| exports.copyCheckpoint = copyCheckpoint; | ||
| exports.deepCopy = deepCopy; | ||
| exports.emptyCheckpoint = emptyCheckpoint; | ||
| exports.getCheckpointId = getCheckpointId; | ||
| exports.maxChannelVersion = maxChannelVersion; | ||
| //# sourceMappingURL=base.cjs.map |
+79
-73
@@ -1,80 +0,84 @@ | ||
| import type { RunnableConfig } from "@langchain/core/runnables"; | ||
| import { SerializerProtocol } from "./serde/base.js"; | ||
| import type { PendingWrite, CheckpointPendingWrite, CheckpointMetadata } from "./types.js"; | ||
| import { CheckpointMetadata, CheckpointPendingWrite, PendingWrite } from "./types.js"; | ||
| import { RunnableConfig } from "@langchain/core/runnables"; | ||
| //#region src/base.d.ts | ||
| /** @inline */ | ||
| type ChannelVersion = number | string; | ||
| export type ChannelVersions = Record<string, ChannelVersion>; | ||
| export interface Checkpoint<N extends string = string, C extends string = string> { | ||
| /** | ||
| * The version of the checkpoint format. Currently 4 | ||
| */ | ||
| v: number; | ||
| /** | ||
| * Checkpoint ID {uuid6} | ||
| */ | ||
| id: string; | ||
| /** | ||
| * Timestamp {new Date().toISOString()} | ||
| */ | ||
| ts: string; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| channel_values: Record<C, unknown>; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| channel_versions: Record<C, ChannelVersion>; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| versions_seen: Record<N, Record<C, ChannelVersion>>; | ||
| type ChannelVersions = Record<string, ChannelVersion>; | ||
| interface Checkpoint<N extends string = string, C extends string = string> { | ||
| /** | ||
| * The version of the checkpoint format. Currently 4 | ||
| */ | ||
| v: number; | ||
| /** | ||
| * Checkpoint ID {uuid6} | ||
| */ | ||
| id: string; | ||
| /** | ||
| * Timestamp {new Date().toISOString()} | ||
| */ | ||
| ts: string; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| channel_values: Record<C, unknown>; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| channel_versions: Record<C, ChannelVersion>; | ||
| /** | ||
| * @default {} | ||
| */ | ||
| versions_seen: Record<N, Record<C, ChannelVersion>>; | ||
| } | ||
| export interface ReadonlyCheckpoint extends Readonly<Checkpoint> { | ||
| readonly channel_values: Readonly<Record<string, unknown>>; | ||
| readonly channel_versions: Readonly<Record<string, ChannelVersion>>; | ||
| readonly versions_seen: Readonly<Record<string, Readonly<Record<string, ChannelVersion>>>>; | ||
| interface ReadonlyCheckpoint extends Readonly<Checkpoint> { | ||
| readonly channel_values: Readonly<Record<string, unknown>>; | ||
| readonly channel_versions: Readonly<Record<string, ChannelVersion>>; | ||
| readonly versions_seen: Readonly<Record<string, Readonly<Record<string, ChannelVersion>>>>; | ||
| } | ||
| export declare function deepCopy<T>(obj: T): T; | ||
| declare function deepCopy<T>(obj: T): T; | ||
| /** @hidden */ | ||
| export declare function emptyCheckpoint(): Checkpoint; | ||
| declare function emptyCheckpoint(): Checkpoint; | ||
| /** @hidden */ | ||
| export declare function copyCheckpoint(checkpoint: ReadonlyCheckpoint): Checkpoint; | ||
| export interface CheckpointTuple { | ||
| config: RunnableConfig; | ||
| checkpoint: Checkpoint; | ||
| metadata?: CheckpointMetadata; | ||
| parentConfig?: RunnableConfig; | ||
| pendingWrites?: CheckpointPendingWrite[]; | ||
| declare function copyCheckpoint(checkpoint: ReadonlyCheckpoint): Checkpoint; | ||
| interface CheckpointTuple { | ||
| config: RunnableConfig; | ||
| checkpoint: Checkpoint; | ||
| metadata?: CheckpointMetadata; | ||
| parentConfig?: RunnableConfig; | ||
| pendingWrites?: CheckpointPendingWrite[]; | ||
| } | ||
| export type CheckpointListOptions = { | ||
| limit?: number; | ||
| before?: RunnableConfig; | ||
| filter?: Record<string, any>; | ||
| type CheckpointListOptions = { | ||
| limit?: number; | ||
| before?: RunnableConfig; | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| filter?: Record<string, any>; | ||
| }; | ||
| export declare abstract class BaseCheckpointSaver<V extends string | number = number> { | ||
| serde: SerializerProtocol; | ||
| constructor(serde?: SerializerProtocol); | ||
| get(config: RunnableConfig): Promise<Checkpoint | undefined>; | ||
| abstract getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>; | ||
| abstract list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>; | ||
| abstract put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, newVersions: ChannelVersions): Promise<RunnableConfig>; | ||
| /** | ||
| * Store intermediate writes linked to a checkpoint. | ||
| */ | ||
| abstract putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>; | ||
| /** | ||
| * Delete all checkpoints and writes associated with a specific thread ID. | ||
| * @param threadId The thread ID whose checkpoints should be deleted. | ||
| */ | ||
| abstract deleteThread(threadId: string): Promise<void>; | ||
| /** | ||
| * Generate the next version ID for a channel. | ||
| * | ||
| * Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions, | ||
| * as long as they are monotonically increasing. | ||
| */ | ||
| getNextVersion(current: V | undefined): V; | ||
| declare abstract class BaseCheckpointSaver<V extends string | number = number> { | ||
| serde: SerializerProtocol; | ||
| constructor(serde?: SerializerProtocol); | ||
| get(config: RunnableConfig): Promise<Checkpoint | undefined>; | ||
| abstract getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>; | ||
| abstract list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>; | ||
| abstract put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, newVersions: ChannelVersions): Promise<RunnableConfig>; | ||
| /** | ||
| * Store intermediate writes linked to a checkpoint. | ||
| */ | ||
| abstract putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>; | ||
| /** | ||
| * Delete all checkpoints and writes associated with a specific thread ID. | ||
| * @param threadId The thread ID whose checkpoints should be deleted. | ||
| */ | ||
| abstract deleteThread(threadId: string): Promise<void>; | ||
| /** | ||
| * Generate the next version ID for a channel. | ||
| * | ||
| * Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions, | ||
| * as long as they are monotonically increasing. | ||
| */ | ||
| getNextVersion(current: V | undefined): V; | ||
| } | ||
| export declare function compareChannelVersions(a: ChannelVersion, b: ChannelVersion): number; | ||
| export declare function maxChannelVersion(...versions: ChannelVersion[]): ChannelVersion; | ||
| declare function compareChannelVersions(a: ChannelVersion, b: ChannelVersion): number; | ||
| declare function maxChannelVersion(...versions: ChannelVersion[]): ChannelVersion; | ||
| /** | ||
@@ -87,4 +91,6 @@ * Mapping from error type to error index. | ||
| */ | ||
| export declare const WRITES_IDX_MAP: Record<string, number>; | ||
| export declare function getCheckpointId(config: RunnableConfig): string; | ||
| export {}; | ||
| declare const WRITES_IDX_MAP: Record<string, number>; | ||
| declare function getCheckpointId(config: RunnableConfig): string; | ||
| //#endregion | ||
| export { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointTuple, ReadonlyCheckpoint, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion }; | ||
| //# sourceMappingURL=base.d.ts.map |
+69
-80
| import { uuid6 } from "./id.js"; | ||
| import { ERROR, INTERRUPT, RESUME, SCHEDULED } from "./serde/types.js"; | ||
| import { JsonPlusSerializer } from "./serde/jsonplus.js"; | ||
| export function deepCopy(obj) { | ||
| if (typeof obj !== "object" || obj === null) { | ||
| return obj; | ||
| } | ||
| const newObj = Array.isArray(obj) ? [] : {}; | ||
| for (const key in obj) { | ||
| if (Object.prototype.hasOwnProperty.call(obj, key)) { | ||
| newObj[key] = deepCopy(obj[key]); | ||
| } | ||
| } | ||
| return newObj; | ||
| //#region src/base.ts | ||
| function deepCopy(obj) { | ||
| if (typeof obj !== "object" || obj === null) return obj; | ||
| const newObj = Array.isArray(obj) ? [] : {}; | ||
| for (const key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = deepCopy(obj[key]); | ||
| return newObj; | ||
| } | ||
| /** @hidden */ | ||
| export function emptyCheckpoint() { | ||
| return { | ||
| v: 4, | ||
| id: uuid6(-2), | ||
| ts: new Date().toISOString(), | ||
| channel_values: {}, | ||
| channel_versions: {}, | ||
| versions_seen: {}, | ||
| }; | ||
| function emptyCheckpoint() { | ||
| return { | ||
| v: 4, | ||
| id: uuid6(-2), | ||
| ts: (/* @__PURE__ */ new Date()).toISOString(), | ||
| channel_values: {}, | ||
| channel_versions: {}, | ||
| versions_seen: {} | ||
| }; | ||
| } | ||
| /** @hidden */ | ||
| export function copyCheckpoint(checkpoint) { | ||
| return { | ||
| v: checkpoint.v, | ||
| id: checkpoint.id, | ||
| ts: checkpoint.ts, | ||
| channel_values: { ...checkpoint.channel_values }, | ||
| channel_versions: { ...checkpoint.channel_versions }, | ||
| versions_seen: deepCopy(checkpoint.versions_seen), | ||
| }; | ||
| function copyCheckpoint(checkpoint) { | ||
| return { | ||
| v: checkpoint.v, | ||
| id: checkpoint.id, | ||
| ts: checkpoint.ts, | ||
| channel_values: { ...checkpoint.channel_values }, | ||
| channel_versions: { ...checkpoint.channel_versions }, | ||
| versions_seen: deepCopy(checkpoint.versions_seen) | ||
| }; | ||
| } | ||
| export class BaseCheckpointSaver { | ||
| constructor(serde) { | ||
| Object.defineProperty(this, "serde", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: new JsonPlusSerializer() | ||
| }); | ||
| this.serde = serde || this.serde; | ||
| } | ||
| async get(config) { | ||
| const value = await this.getTuple(config); | ||
| return value ? value.checkpoint : undefined; | ||
| } | ||
| /** | ||
| * Generate the next version ID for a channel. | ||
| * | ||
| * Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions, | ||
| * as long as they are monotonically increasing. | ||
| */ | ||
| getNextVersion(current) { | ||
| if (typeof current === "string") { | ||
| throw new Error("Please override this method to use string versions."); | ||
| } | ||
| return (current !== undefined && typeof current === "number" ? current + 1 : 1); | ||
| } | ||
| var BaseCheckpointSaver = class { | ||
| serde = new JsonPlusSerializer(); | ||
| constructor(serde) { | ||
| this.serde = serde || this.serde; | ||
| } | ||
| async get(config) { | ||
| const value = await this.getTuple(config); | ||
| return value ? value.checkpoint : void 0; | ||
| } | ||
| /** | ||
| * Generate the next version ID for a channel. | ||
| * | ||
| * Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions, | ||
| * as long as they are monotonically increasing. | ||
| */ | ||
| getNextVersion(current) { | ||
| if (typeof current === "string") throw new Error("Please override this method to use string versions."); | ||
| return current !== void 0 && typeof current === "number" ? current + 1 : 1; | ||
| } | ||
| }; | ||
| function compareChannelVersions(a, b) { | ||
| if (typeof a === "number" && typeof b === "number") return Math.sign(a - b); | ||
| return String(a).localeCompare(String(b)); | ||
| } | ||
| export function compareChannelVersions(a, b) { | ||
| if (typeof a === "number" && typeof b === "number") { | ||
| return Math.sign(a - b); | ||
| } | ||
| return String(a).localeCompare(String(b)); | ||
| function maxChannelVersion(...versions) { | ||
| return versions.reduce((max, version, idx) => { | ||
| if (idx === 0) return version; | ||
| return compareChannelVersions(max, version) >= 0 ? max : version; | ||
| }); | ||
| } | ||
| export function maxChannelVersion(...versions) { | ||
| return versions.reduce((max, version, idx) => { | ||
| if (idx === 0) | ||
| return version; | ||
| return compareChannelVersions(max, version) >= 0 ? max : version; | ||
| }); | ||
| } | ||
| /** | ||
| * Mapping from error type to error index. | ||
| * Regular writes just map to their index in the list of writes being saved. | ||
| * Special writes (e.g. errors) map to negative indices, to avoid those writes from | ||
| * conflicting with regular writes. | ||
| * Each Checkpointer implementation should use this mapping in put_writes. | ||
| */ | ||
| export const WRITES_IDX_MAP = { | ||
| [ERROR]: -1, | ||
| [SCHEDULED]: -2, | ||
| [INTERRUPT]: -3, | ||
| [RESUME]: -4, | ||
| * Mapping from error type to error index. | ||
| * Regular writes just map to their index in the list of writes being saved. | ||
| * Special writes (e.g. errors) map to negative indices, to avoid those writes from | ||
| * conflicting with regular writes. | ||
| * Each Checkpointer implementation should use this mapping in put_writes. | ||
| */ | ||
| const WRITES_IDX_MAP = { | ||
| [ERROR]: -1, | ||
| [SCHEDULED]: -2, | ||
| [INTERRUPT]: -3, | ||
| [RESUME]: -4 | ||
| }; | ||
| export function getCheckpointId(config) { | ||
| return (config.configurable?.checkpoint_id || config.configurable?.thread_ts || ""); | ||
| function getCheckpointId(config) { | ||
| return config.configurable?.checkpoint_id || config.configurable?.thread_ts || ""; | ||
| } | ||
| //#endregion | ||
| export { BaseCheckpointSaver, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion }; | ||
| //# sourceMappingURL=base.js.map |
+1
-1
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAMhC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AA4CzD,MAAM,UAAU,QAAQ,CAAI,GAAM;IAChC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5C,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QACtB,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YAClD,MAAuC,CAAC,GAAG,CAAC,GAAG,QAAQ,CACrD,GAA+B,CAAC,GAAG,CAAC,CACtC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,MAAW,CAAC;AACrB,CAAC;AAED,cAAc;AACd,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,CAAC,EAAE,CAAC;QACJ,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QACb,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,cAAc,EAAE,EAAE;QAClB,gBAAgB,EAAE,EAAE;QACpB,aAAa,EAAE,EAAE;KAClB,CAAC;AACJ,CAAC;AAED,cAAc;AACd,MAAM,UAAU,cAAc,CAAC,UAA8B;IAC3D,OAAO;QACL,CAAC,EAAE,UAAU,CAAC,CAAC;QACf,EAAE,EAAE,UAAU,CAAC,EAAE;QACjB,EAAE,EAAE,UAAU,CAAC,EAAE;QACjB,cAAc,EAAE,EAAE,GAAG,UAAU,CAAC,cAAc,EAAE;QAChD,gBAAgB,EAAE,EAAE,GAAG,UAAU,CAAC,gBAAgB,EAAE;QACpD,aAAa,EAAE,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC;KAClD,CAAC;AACJ,CAAC;AAiBD,MAAM,OAAgB,mBAAmB;IAGvC,YAAY,KAA0B;QAFtC;;;;mBAA4B,IAAI,kBAAkB,EAAE;WAAC;QAGnD,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,MAAsB;QAC9B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9C,CAAC;IAiCD;;;;;OAKG;IACH,cAAc,CAAC,OAAsB;QACnC,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,CACL,OAAO,KAAK,SAAS,IAAI,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAClE,CAAC;IACT,CAAC;CACF;AAED,MAAM,UAAU,sBAAsB,CACpC,CAAiB,EACjB,CAAiB;IAEjB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QACnD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,GAAG,QAA0B;IAE7B,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;QAC3C,IAAI,GAAG,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC;QAC9B,OAAO,sBAAsB,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAA2B;IACpD,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACX,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACf,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACf,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;CACb,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,MAAsB;IACpD,OAAO,CACL,MAAM,CAAC,YAAY,EAAE,aAAa,IAAI,MAAM,CAAC,YAAY,EAAE,SAAS,IAAI,EAAE,CAC3E,CAAC;AACJ,CAAC"} | ||
| {"version":3,"file":"base.js","names":["WRITES_IDX_MAP: Record<string, number>"],"sources":["../src/base.ts"],"sourcesContent":["import type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { SerializerProtocol } from \"./serde/base.js\";\nimport { uuid6 } from \"./id.js\";\nimport type {\n PendingWrite,\n CheckpointPendingWrite,\n CheckpointMetadata,\n} from \"./types.js\";\nimport { ERROR, INTERRUPT, RESUME, SCHEDULED } from \"./serde/types.js\";\nimport { JsonPlusSerializer } from \"./serde/jsonplus.js\";\n\n/** @inline */\ntype ChannelVersion = number | string;\n\nexport type ChannelVersions = Record<string, ChannelVersion>;\n\nexport interface Checkpoint<\n N extends string = string,\n C extends string = string\n> {\n /**\n * The version of the checkpoint format. Currently 4\n */\n v: number;\n /**\n * Checkpoint ID {uuid6}\n */\n id: string;\n /**\n * Timestamp {new Date().toISOString()}\n */\n ts: string;\n /**\n * @default {}\n */\n channel_values: Record<C, unknown>;\n /**\n * @default {}\n */\n channel_versions: Record<C, ChannelVersion>;\n /**\n * @default {}\n */\n versions_seen: Record<N, Record<C, ChannelVersion>>;\n}\n\nexport interface ReadonlyCheckpoint extends Readonly<Checkpoint> {\n readonly channel_values: Readonly<Record<string, unknown>>;\n readonly channel_versions: Readonly<Record<string, ChannelVersion>>;\n readonly versions_seen: Readonly<\n Record<string, Readonly<Record<string, ChannelVersion>>>\n >;\n}\n\nexport function deepCopy<T>(obj: T): T {\n if (typeof obj !== \"object\" || obj === null) {\n return obj;\n }\n\n const newObj = Array.isArray(obj) ? [] : {};\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n (newObj as Record<PropertyKey, unknown>)[key] = deepCopy(\n (obj as Record<string, unknown>)[key]\n );\n }\n }\n\n return newObj as T;\n}\n\n/** @hidden */\nexport function emptyCheckpoint(): Checkpoint {\n return {\n v: 4,\n id: uuid6(-2),\n ts: new Date().toISOString(),\n channel_values: {},\n channel_versions: {},\n versions_seen: {},\n };\n}\n\n/** @hidden */\nexport function copyCheckpoint(checkpoint: ReadonlyCheckpoint): Checkpoint {\n return {\n v: checkpoint.v,\n id: checkpoint.id,\n ts: checkpoint.ts,\n channel_values: { ...checkpoint.channel_values },\n channel_versions: { ...checkpoint.channel_versions },\n versions_seen: deepCopy(checkpoint.versions_seen),\n };\n}\n\nexport interface CheckpointTuple {\n config: RunnableConfig;\n checkpoint: Checkpoint;\n metadata?: CheckpointMetadata;\n parentConfig?: RunnableConfig;\n pendingWrites?: CheckpointPendingWrite[];\n}\n\nexport type CheckpointListOptions = {\n limit?: number;\n before?: RunnableConfig;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n filter?: Record<string, any>;\n};\n\nexport abstract class BaseCheckpointSaver<V extends string | number = number> {\n serde: SerializerProtocol = new JsonPlusSerializer();\n\n constructor(serde?: SerializerProtocol) {\n this.serde = serde || this.serde;\n }\n\n async get(config: RunnableConfig): Promise<Checkpoint | undefined> {\n const value = await this.getTuple(config);\n return value ? value.checkpoint : undefined;\n }\n\n abstract getTuple(\n config: RunnableConfig\n ): Promise<CheckpointTuple | undefined>;\n\n abstract list(\n config: RunnableConfig,\n options?: CheckpointListOptions\n ): AsyncGenerator<CheckpointTuple>;\n\n abstract put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata,\n newVersions: ChannelVersions\n ): Promise<RunnableConfig>;\n\n /**\n * Store intermediate writes linked to a checkpoint.\n */\n abstract putWrites(\n config: RunnableConfig,\n writes: PendingWrite[],\n taskId: string\n ): Promise<void>;\n\n /**\n * Delete all checkpoints and writes associated with a specific thread ID.\n * @param threadId The thread ID whose checkpoints should be deleted.\n */\n abstract deleteThread(threadId: string): Promise<void>;\n\n /**\n * Generate the next version ID for a channel.\n *\n * Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions,\n * as long as they are monotonically increasing.\n */\n getNextVersion(current: V | undefined): V {\n if (typeof current === \"string\") {\n throw new Error(\"Please override this method to use string versions.\");\n }\n return (\n current !== undefined && typeof current === \"number\" ? current + 1 : 1\n ) as V;\n }\n}\n\nexport function compareChannelVersions(\n a: ChannelVersion,\n b: ChannelVersion\n): number {\n if (typeof a === \"number\" && typeof b === \"number\") {\n return Math.sign(a - b);\n }\n\n return String(a).localeCompare(String(b));\n}\n\nexport function maxChannelVersion(\n ...versions: ChannelVersion[]\n): ChannelVersion {\n return versions.reduce((max, version, idx) => {\n if (idx === 0) return version;\n return compareChannelVersions(max, version) >= 0 ? max : version;\n });\n}\n\n/**\n * Mapping from error type to error index.\n * Regular writes just map to their index in the list of writes being saved.\n * Special writes (e.g. errors) map to negative indices, to avoid those writes from\n * conflicting with regular writes.\n * Each Checkpointer implementation should use this mapping in put_writes.\n */\nexport const WRITES_IDX_MAP: Record<string, number> = {\n [ERROR]: -1,\n [SCHEDULED]: -2,\n [INTERRUPT]: -3,\n [RESUME]: -4,\n};\n\nexport function getCheckpointId(config: RunnableConfig): string {\n return (\n config.configurable?.checkpoint_id || config.configurable?.thread_ts || \"\"\n );\n}\n"],"mappings":";;;;;AAsDA,SAAgB,SAAY,KAAW;AACrC,KAAI,OAAO,QAAQ,YAAY,QAAQ,KACrC,QAAO;CAGT,MAAM,SAAS,MAAM,QAAQ,OAAO,KAAK;AAEzC,MAAK,MAAM,OAAO,IAChB,KAAI,OAAO,UAAU,eAAe,KAAK,KAAK,KAC5C,CAAC,OAAwC,OAAO,SAC7C,IAAgC;AAKvC,QAAO;;;AAIT,SAAgB,kBAA8B;AAC5C,QAAO;EACL,GAAG;EACH,IAAI,MAAM;EACV,qBAAI,IAAI,QAAO;EACf,gBAAgB;EAChB,kBAAkB;EAClB,eAAe;;;;AAKnB,SAAgB,eAAe,YAA4C;AACzE,QAAO;EACL,GAAG,WAAW;EACd,IAAI,WAAW;EACf,IAAI,WAAW;EACf,gBAAgB,EAAE,GAAG,WAAW;EAChC,kBAAkB,EAAE,GAAG,WAAW;EAClC,eAAe,SAAS,WAAW;;;AAmBvC,IAAsB,sBAAtB,MAA8E;CAC5E,QAA4B,IAAI;CAEhC,YAAY,OAA4B;AACtC,OAAK,QAAQ,SAAS,KAAK;;CAG7B,MAAM,IAAI,QAAyD;EACjE,MAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,SAAO,QAAQ,MAAM,aAAa;;;;;;;;CAwCpC,eAAe,SAA2B;AACxC,MAAI,OAAO,YAAY,SACrB,OAAM,IAAI,MAAM;AAElB,SACE,YAAY,UAAa,OAAO,YAAY,WAAW,UAAU,IAAI;;;AAK3E,SAAgB,uBACd,GACA,GACQ;AACR,KAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SACxC,QAAO,KAAK,KAAK,IAAI;AAGvB,QAAO,OAAO,GAAG,cAAc,OAAO;;AAGxC,SAAgB,kBACd,GAAG,UACa;AAChB,QAAO,SAAS,QAAQ,KAAK,SAAS,QAAQ;AAC5C,MAAI,QAAQ,EAAG,QAAO;AACtB,SAAO,uBAAuB,KAAK,YAAY,IAAI,MAAM;;;;;;;;;;AAW7D,MAAaA,iBAAyC;EACnD,QAAQ;EACR,YAAY;EACZ,YAAY;EACZ,SAAS;;AAGZ,SAAgB,gBAAgB,QAAgC;AAC9D,QACE,OAAO,cAAc,iBAAiB,OAAO,cAAc,aAAa"} |
+17
-21
@@ -1,22 +0,18 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.BaseCache = void 0; | ||
| const jsonplus_js_1 = require("../serde/jsonplus.cjs"); | ||
| class BaseCache { | ||
| /** | ||
| * Initialize the cache with a serializer. | ||
| * | ||
| * @param serde - The serializer to use. | ||
| */ | ||
| constructor(serde) { | ||
| Object.defineProperty(this, "serde", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: new jsonplus_js_1.JsonPlusSerializer() | ||
| }); | ||
| this.serde = serde || this.serde; | ||
| } | ||
| } | ||
| const require_jsonplus = require('../serde/jsonplus.cjs'); | ||
| //#region src/cache/base.ts | ||
| var BaseCache = class { | ||
| serde = new require_jsonplus.JsonPlusSerializer(); | ||
| /** | ||
| * Initialize the cache with a serializer. | ||
| * | ||
| * @param serde - The serializer to use. | ||
| */ | ||
| constructor(serde) { | ||
| this.serde = serde || this.serde; | ||
| } | ||
| }; | ||
| //#endregion | ||
| exports.BaseCache = BaseCache; | ||
| //# sourceMappingURL=base.js.map | ||
| //# sourceMappingURL=base.cjs.map |
+41
-36
| import { SerializerProtocol } from "../serde/base.js"; | ||
| export type CacheNamespace = string[]; | ||
| export type CacheFullKey = [namespace: CacheNamespace, key: string]; | ||
| export declare abstract class BaseCache<V = unknown> { | ||
| serde: SerializerProtocol; | ||
| /** | ||
| * Initialize the cache with a serializer. | ||
| * | ||
| * @param serde - The serializer to use. | ||
| */ | ||
| constructor(serde?: SerializerProtocol); | ||
| /** | ||
| * Get the cached values for the given keys. | ||
| * | ||
| * @param keys - The keys to get. | ||
| */ | ||
| abstract get(keys: CacheFullKey[]): Promise<{ | ||
| key: CacheFullKey; | ||
| value: V; | ||
| }[]>; | ||
| /** | ||
| * Set the cached values for the given keys and TTLs. | ||
| * | ||
| * @param pairs - The pairs to set. | ||
| */ | ||
| abstract set(pairs: { | ||
| key: CacheFullKey; | ||
| value: V; | ||
| ttl?: number; | ||
| }[]): Promise<void>; | ||
| /** | ||
| * Delete the cached values for the given namespaces. | ||
| * If no namespaces are provided, clear all cached values. | ||
| * | ||
| * @param namespaces - The namespaces to clear. | ||
| */ | ||
| abstract clear(namespaces: CacheNamespace[]): Promise<void>; | ||
| //#region src/cache/base.d.ts | ||
| type CacheNamespace = string[]; | ||
| type CacheFullKey = [namespace: CacheNamespace, key: string]; | ||
| declare abstract class BaseCache<V = unknown> { | ||
| serde: SerializerProtocol; | ||
| /** | ||
| * Initialize the cache with a serializer. | ||
| * | ||
| * @param serde - The serializer to use. | ||
| */ | ||
| constructor(serde?: SerializerProtocol); | ||
| /** | ||
| * Get the cached values for the given keys. | ||
| * | ||
| * @param keys - The keys to get. | ||
| */ | ||
| abstract get(keys: CacheFullKey[]): Promise<{ | ||
| key: CacheFullKey; | ||
| value: V; | ||
| }[]>; | ||
| /** | ||
| * Set the cached values for the given keys and TTLs. | ||
| * | ||
| * @param pairs - The pairs to set. | ||
| */ | ||
| abstract set(pairs: { | ||
| key: CacheFullKey; | ||
| value: V; | ||
| ttl?: number; | ||
| }[]): Promise<void>; | ||
| /** | ||
| * Delete the cached values for the given namespaces. | ||
| * If no namespaces are provided, clear all cached values. | ||
| * | ||
| * @param namespaces - The namespaces to clear. | ||
| */ | ||
| abstract clear(namespaces: CacheNamespace[]): Promise<void>; | ||
| } | ||
| //#endregion | ||
| export { BaseCache, CacheFullKey, CacheNamespace }; | ||
| //# sourceMappingURL=base.d.ts.map |
+16
-16
| import { JsonPlusSerializer } from "../serde/jsonplus.js"; | ||
| export class BaseCache { | ||
| /** | ||
| * Initialize the cache with a serializer. | ||
| * | ||
| * @param serde - The serializer to use. | ||
| */ | ||
| constructor(serde) { | ||
| Object.defineProperty(this, "serde", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: new JsonPlusSerializer() | ||
| }); | ||
| this.serde = serde || this.serde; | ||
| } | ||
| } | ||
| //#region src/cache/base.ts | ||
| var BaseCache = class { | ||
| serde = new JsonPlusSerializer(); | ||
| /** | ||
| * Initialize the cache with a serializer. | ||
| * | ||
| * @param serde - The serializer to use. | ||
| */ | ||
| constructor(serde) { | ||
| this.serde = serde || this.serde; | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { BaseCache }; | ||
| //# sourceMappingURL=base.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/cache/base.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAK1D,MAAM,OAAgB,SAAS;IAG7B;;;;OAIG;IACH,YAAY,KAA0B;QAPtC;;;;mBAA4B,IAAI,kBAAkB,EAAE;WAAC;QAQnD,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC;IACnC,CAAC;CA2BF"} | ||
| {"version":3,"file":"base.js","names":[],"sources":["../../src/cache/base.ts"],"sourcesContent":["import { SerializerProtocol } from \"../serde/base.js\";\nimport { JsonPlusSerializer } from \"../serde/jsonplus.js\";\n\nexport type CacheNamespace = string[];\nexport type CacheFullKey = [namespace: CacheNamespace, key: string];\n\nexport abstract class BaseCache<V = unknown> {\n serde: SerializerProtocol = new JsonPlusSerializer();\n\n /**\n * Initialize the cache with a serializer.\n *\n * @param serde - The serializer to use.\n */\n constructor(serde?: SerializerProtocol) {\n this.serde = serde || this.serde;\n }\n\n /**\n * Get the cached values for the given keys.\n *\n * @param keys - The keys to get.\n */\n abstract get(\n keys: CacheFullKey[]\n ): Promise<{ key: CacheFullKey; value: V }[]>;\n\n /**\n * Set the cached values for the given keys and TTLs.\n *\n * @param pairs - The pairs to set.\n */\n abstract set(\n pairs: { key: CacheFullKey; value: V; ttl?: number }[]\n ): Promise<void>;\n\n /**\n * Delete the cached values for the given namespaces.\n * If no namespaces are provided, clear all cached values.\n *\n * @param namespaces - The namespaces to clear.\n */\n abstract clear(namespaces: CacheNamespace[]): Promise<void>;\n}\n"],"mappings":";;;AAMA,IAAsB,YAAtB,MAA6C;CAC3C,QAA4B,IAAI;;;;;;CAOhC,YAAY,OAA4B;AACtC,OAAK,QAAQ,SAAS,KAAK"} |
+2
-19
@@ -1,19 +0,2 @@ | ||
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
| for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| __exportStar(require("./base.cjs"), exports); | ||
| __exportStar(require("./memory.cjs"), exports); | ||
| //# sourceMappingURL=index.js.map | ||
| const require_base = require('./base.cjs'); | ||
| const require_memory = require('./memory.cjs'); |
@@ -1,3 +0,4 @@ | ||
| export * from "./base.js"; | ||
| export * from "./memory.js"; | ||
| //# sourceMappingURL=index.js.map | ||
| import { BaseCache } from "./base.js"; | ||
| import { InMemoryCache } from "./memory.js"; | ||
| export { }; |
+53
-58
@@ -1,59 +0,54 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.InMemoryCache = void 0; | ||
| const base_js_1 = require("./base.cjs"); | ||
| class InMemoryCache extends base_js_1.BaseCache { | ||
| constructor() { | ||
| super(...arguments); | ||
| Object.defineProperty(this, "cache", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: {} | ||
| }); | ||
| } | ||
| async get(keys) { | ||
| if (!keys.length) | ||
| return []; | ||
| const now = Date.now(); | ||
| return (await Promise.all(keys.map(async (fullKey) => { | ||
| const [namespace, key] = fullKey; | ||
| const strNamespace = namespace.join(","); | ||
| if (strNamespace in this.cache && key in this.cache[strNamespace]) { | ||
| const cached = this.cache[strNamespace][key]; | ||
| if (cached.exp == null || now < cached.exp) { | ||
| const value = await this.serde.loadsTyped(cached.enc, cached.val); | ||
| return [{ key: fullKey, value }]; | ||
| } | ||
| else { | ||
| delete this.cache[strNamespace][key]; | ||
| } | ||
| } | ||
| return []; | ||
| }))).flat(); | ||
| } | ||
| async set(pairs) { | ||
| const now = Date.now(); | ||
| for (const { key: fullKey, value, ttl } of pairs) { | ||
| const [namespace, key] = fullKey; | ||
| const strNamespace = namespace.join(","); | ||
| const [enc, val] = await this.serde.dumpsTyped(value); | ||
| const exp = ttl != null ? ttl * 1000 + now : null; | ||
| this.cache[strNamespace] ??= {}; | ||
| this.cache[strNamespace][key] = { enc, val, exp }; | ||
| } | ||
| } | ||
| async clear(namespaces) { | ||
| if (!namespaces.length) { | ||
| this.cache = {}; | ||
| return; | ||
| } | ||
| for (const namespace of namespaces) { | ||
| const strNamespace = namespace.join(","); | ||
| if (strNamespace in this.cache) | ||
| delete this.cache[strNamespace]; | ||
| } | ||
| } | ||
| } | ||
| const require_base = require('./base.cjs'); | ||
| //#region src/cache/memory.ts | ||
| var InMemoryCache = class extends require_base.BaseCache { | ||
| cache = {}; | ||
| async get(keys) { | ||
| if (!keys.length) return []; | ||
| const now = Date.now(); | ||
| return (await Promise.all(keys.map(async (fullKey) => { | ||
| const [namespace, key] = fullKey; | ||
| const strNamespace = namespace.join(","); | ||
| if (strNamespace in this.cache && key in this.cache[strNamespace]) { | ||
| const cached = this.cache[strNamespace][key]; | ||
| if (cached.exp == null || now < cached.exp) { | ||
| const value = await this.serde.loadsTyped(cached.enc, cached.val); | ||
| return [{ | ||
| key: fullKey, | ||
| value | ||
| }]; | ||
| } else delete this.cache[strNamespace][key]; | ||
| } | ||
| return []; | ||
| }))).flat(); | ||
| } | ||
| async set(pairs) { | ||
| const now = Date.now(); | ||
| for (const { key: fullKey, value, ttl } of pairs) { | ||
| const [namespace, key] = fullKey; | ||
| const strNamespace = namespace.join(","); | ||
| const [enc, val] = await this.serde.dumpsTyped(value); | ||
| const exp = ttl != null ? ttl * 1e3 + now : null; | ||
| this.cache[strNamespace] ??= {}; | ||
| this.cache[strNamespace][key] = { | ||
| enc, | ||
| val, | ||
| exp | ||
| }; | ||
| } | ||
| } | ||
| async clear(namespaces) { | ||
| if (!namespaces.length) { | ||
| this.cache = {}; | ||
| return; | ||
| } | ||
| for (const namespace of namespaces) { | ||
| const strNamespace = namespace.join(","); | ||
| if (strNamespace in this.cache) delete this.cache[strNamespace]; | ||
| } | ||
| } | ||
| }; | ||
| //#endregion | ||
| exports.InMemoryCache = InMemoryCache; | ||
| //# sourceMappingURL=memory.js.map | ||
| //# sourceMappingURL=memory.cjs.map |
+18
-13
@@ -1,14 +0,19 @@ | ||
| import { BaseCache, type CacheFullKey, type CacheNamespace } from "./base.js"; | ||
| export declare class InMemoryCache<V = unknown> extends BaseCache<V> { | ||
| private cache; | ||
| get(keys: CacheFullKey[]): Promise<{ | ||
| key: CacheFullKey; | ||
| value: V; | ||
| }[]>; | ||
| set(pairs: { | ||
| key: CacheFullKey; | ||
| value: V; | ||
| ttl?: number; | ||
| }[]): Promise<void>; | ||
| clear(namespaces: CacheNamespace[]): Promise<void>; | ||
| import { BaseCache, CacheFullKey, CacheNamespace } from "./base.js"; | ||
| //#region src/cache/memory.d.ts | ||
| declare class InMemoryCache<V = unknown> extends BaseCache<V> { | ||
| private cache; | ||
| get(keys: CacheFullKey[]): Promise<{ | ||
| key: CacheFullKey; | ||
| value: V; | ||
| }[]>; | ||
| set(pairs: { | ||
| key: CacheFullKey; | ||
| value: V; | ||
| ttl?: number; | ||
| }[]): Promise<void>; | ||
| clear(namespaces: CacheNamespace[]): Promise<void>; | ||
| } | ||
| //#endregion | ||
| export { InMemoryCache }; | ||
| //# sourceMappingURL=memory.d.ts.map |
+52
-53
| import { BaseCache } from "./base.js"; | ||
| export class InMemoryCache extends BaseCache { | ||
| constructor() { | ||
| super(...arguments); | ||
| Object.defineProperty(this, "cache", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: {} | ||
| }); | ||
| } | ||
| async get(keys) { | ||
| if (!keys.length) | ||
| return []; | ||
| const now = Date.now(); | ||
| return (await Promise.all(keys.map(async (fullKey) => { | ||
| const [namespace, key] = fullKey; | ||
| const strNamespace = namespace.join(","); | ||
| if (strNamespace in this.cache && key in this.cache[strNamespace]) { | ||
| const cached = this.cache[strNamespace][key]; | ||
| if (cached.exp == null || now < cached.exp) { | ||
| const value = await this.serde.loadsTyped(cached.enc, cached.val); | ||
| return [{ key: fullKey, value }]; | ||
| } | ||
| else { | ||
| delete this.cache[strNamespace][key]; | ||
| } | ||
| } | ||
| return []; | ||
| }))).flat(); | ||
| } | ||
| async set(pairs) { | ||
| const now = Date.now(); | ||
| for (const { key: fullKey, value, ttl } of pairs) { | ||
| const [namespace, key] = fullKey; | ||
| const strNamespace = namespace.join(","); | ||
| const [enc, val] = await this.serde.dumpsTyped(value); | ||
| const exp = ttl != null ? ttl * 1000 + now : null; | ||
| this.cache[strNamespace] ??= {}; | ||
| this.cache[strNamespace][key] = { enc, val, exp }; | ||
| } | ||
| } | ||
| async clear(namespaces) { | ||
| if (!namespaces.length) { | ||
| this.cache = {}; | ||
| return; | ||
| } | ||
| for (const namespace of namespaces) { | ||
| const strNamespace = namespace.join(","); | ||
| if (strNamespace in this.cache) | ||
| delete this.cache[strNamespace]; | ||
| } | ||
| } | ||
| } | ||
| //#region src/cache/memory.ts | ||
| var InMemoryCache = class extends BaseCache { | ||
| cache = {}; | ||
| async get(keys) { | ||
| if (!keys.length) return []; | ||
| const now = Date.now(); | ||
| return (await Promise.all(keys.map(async (fullKey) => { | ||
| const [namespace, key] = fullKey; | ||
| const strNamespace = namespace.join(","); | ||
| if (strNamespace in this.cache && key in this.cache[strNamespace]) { | ||
| const cached = this.cache[strNamespace][key]; | ||
| if (cached.exp == null || now < cached.exp) { | ||
| const value = await this.serde.loadsTyped(cached.enc, cached.val); | ||
| return [{ | ||
| key: fullKey, | ||
| value | ||
| }]; | ||
| } else delete this.cache[strNamespace][key]; | ||
| } | ||
| return []; | ||
| }))).flat(); | ||
| } | ||
| async set(pairs) { | ||
| const now = Date.now(); | ||
| for (const { key: fullKey, value, ttl } of pairs) { | ||
| const [namespace, key] = fullKey; | ||
| const strNamespace = namespace.join(","); | ||
| const [enc, val] = await this.serde.dumpsTyped(value); | ||
| const exp = ttl != null ? ttl * 1e3 + now : null; | ||
| this.cache[strNamespace] ??= {}; | ||
| this.cache[strNamespace][key] = { | ||
| enc, | ||
| val, | ||
| exp | ||
| }; | ||
| } | ||
| } | ||
| async clear(namespaces) { | ||
| if (!namespaces.length) { | ||
| this.cache = {}; | ||
| return; | ||
| } | ||
| for (const namespace of namespaces) { | ||
| const strNamespace = namespace.join(","); | ||
| if (strNamespace in this.cache) delete this.cache[strNamespace]; | ||
| } | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { InMemoryCache }; | ||
| //# sourceMappingURL=memory.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/cache/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA0C,MAAM,WAAW,CAAC;AAE9E,MAAM,OAAO,aAA2B,SAAQ,SAAY;IAA5D;;QACU;;;;mBAQJ,EAAE;WAAC;IA0DT,CAAC;IAxDC,KAAK,CAAC,GAAG,CAAC,IAAoB;QAC5B,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,OAAO,CACL,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,GAAG,CACN,KAAK,EAAE,OAAO,EAA8C,EAAE;YAC5D,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;YACjC,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEzC,IAAI,YAAY,IAAI,IAAI,CAAC,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;gBAClE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC7C,IAAI,MAAM,CAAC,GAAG,IAAI,IAAI,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;oBAC3C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CACvC,MAAM,CAAC,GAAG,EACV,MAAM,CAAC,GAAG,CACX,CAAC;oBACF,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;gBACnC,CAAC;qBAAM,CAAC;oBACN,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC;gBACvC,CAAC;YACH,CAAC;YAED,OAAO,EAAE,CAAC;QACZ,CAAC,CACF,CACF,CACF,CAAC,IAAI,EAAE,CAAC;IACX,CAAC;IAED,KAAK,CAAC,GAAG,CACP,KAAsD;QAEtD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,KAAK,EAAE,CAAC;YACjD,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;YACjC,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACtD,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAElD,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;QACpD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAA4B;QACtC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YACvB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzC,IAAI,YAAY,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;CACF"} | ||
| {"version":3,"file":"memory.js","names":[],"sources":["../../src/cache/memory.ts"],"sourcesContent":["import { BaseCache, type CacheFullKey, type CacheNamespace } from \"./base.js\";\n\nexport class InMemoryCache<V = unknown> extends BaseCache<V> {\n private cache: {\n [namespace: string]: {\n [key: string]: {\n enc: string;\n val: Uint8Array | string;\n exp: number | null;\n };\n };\n } = {};\n\n async get(keys: CacheFullKey[]): Promise<{ key: CacheFullKey; value: V }[]> {\n if (!keys.length) return [];\n const now = Date.now();\n return (\n await Promise.all(\n keys.map(\n async (fullKey): Promise<{ key: CacheFullKey; value: V }[]> => {\n const [namespace, key] = fullKey;\n const strNamespace = namespace.join(\",\");\n\n if (strNamespace in this.cache && key in this.cache[strNamespace]) {\n const cached = this.cache[strNamespace][key];\n if (cached.exp == null || now < cached.exp) {\n const value = await this.serde.loadsTyped(\n cached.enc,\n cached.val\n );\n return [{ key: fullKey, value }];\n } else {\n delete this.cache[strNamespace][key];\n }\n }\n\n return [];\n }\n )\n )\n ).flat();\n }\n\n async set(\n pairs: { key: CacheFullKey; value: V; ttl?: number }[]\n ): Promise<void> {\n const now = Date.now();\n for (const { key: fullKey, value, ttl } of pairs) {\n const [namespace, key] = fullKey;\n const strNamespace = namespace.join(\",\");\n const [enc, val] = await this.serde.dumpsTyped(value);\n const exp = ttl != null ? ttl * 1000 + now : null;\n\n this.cache[strNamespace] ??= {};\n this.cache[strNamespace][key] = { enc, val, exp };\n }\n }\n\n async clear(namespaces: CacheNamespace[]): Promise<void> {\n if (!namespaces.length) {\n this.cache = {};\n return;\n }\n\n for (const namespace of namespaces) {\n const strNamespace = namespace.join(\",\");\n if (strNamespace in this.cache) delete this.cache[strNamespace];\n }\n }\n}\n"],"mappings":";;;AAEA,IAAa,gBAAb,cAAgD,UAAa;CAC3D,AAAQ,QAQJ;CAEJ,MAAM,IAAI,MAAkE;AAC1E,MAAI,CAAC,KAAK,OAAQ,QAAO;EACzB,MAAM,MAAM,KAAK;AACjB,UACE,MAAM,QAAQ,IACZ,KAAK,IACH,OAAO,YAAwD;GAC7D,MAAM,CAAC,WAAW,OAAO;GACzB,MAAM,eAAe,UAAU,KAAK;AAEpC,OAAI,gBAAgB,KAAK,SAAS,OAAO,KAAK,MAAM,eAAe;IACjE,MAAM,SAAS,KAAK,MAAM,cAAc;AACxC,QAAI,OAAO,OAAO,QAAQ,MAAM,OAAO,KAAK;KAC1C,MAAM,QAAQ,MAAM,KAAK,MAAM,WAC7B,OAAO,KACP,OAAO;AAET,YAAO,CAAC;MAAE,KAAK;MAAS;;UAExB,QAAO,KAAK,MAAM,cAAc;;AAIpC,UAAO;OAIb;;CAGJ,MAAM,IACJ,OACe;EACf,MAAM,MAAM,KAAK;AACjB,OAAK,MAAM,EAAE,KAAK,SAAS,OAAO,SAAS,OAAO;GAChD,MAAM,CAAC,WAAW,OAAO;GACzB,MAAM,eAAe,UAAU,KAAK;GACpC,MAAM,CAAC,KAAK,OAAO,MAAM,KAAK,MAAM,WAAW;GAC/C,MAAM,MAAM,OAAO,OAAO,MAAM,MAAO,MAAM;AAE7C,QAAK,MAAM,kBAAkB;AAC7B,QAAK,MAAM,cAAc,OAAO;IAAE;IAAK;IAAK;;;;CAIhD,MAAM,MAAM,YAA6C;AACvD,MAAI,CAAC,WAAW,QAAQ;AACtB,QAAK,QAAQ;AACb;;AAGF,OAAK,MAAM,aAAa,YAAY;GAClC,MAAM,eAAe,UAAU,KAAK;AACpC,OAAI,gBAAgB,KAAK,MAAO,QAAO,KAAK,MAAM"} |
+12
-16
@@ -1,20 +0,16 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.uuid6 = uuid6; | ||
| exports.uuid5 = uuid5; | ||
| const uuid_1 = require("uuid"); | ||
| const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs'); | ||
| const uuid = require_rolldown_runtime.__toESM(require("uuid")); | ||
| //#region src/id.ts | ||
| function uuid6(clockseq) { | ||
| return (0, uuid_1.v6)({ clockseq }); | ||
| return (0, uuid.v6)({ clockseq }); | ||
| } | ||
| // Skip UUID validation check, since UUID6s | ||
| // generated with negative clockseq are not | ||
| // technically compliant, but still work. | ||
| // See: https://github.com/uuidjs/uuid/issues/511 | ||
| function uuid5(name, namespace) { | ||
| const namespaceBytes = namespace | ||
| .replace(/-/g, "") | ||
| .match(/.{2}/g) | ||
| .map((byte) => parseInt(byte, 16)); | ||
| return (0, uuid_1.v5)(name, new Uint8Array(namespaceBytes)); | ||
| const namespaceBytes = namespace.replace(/-/g, "").match(/.{2}/g).map((byte) => parseInt(byte, 16)); | ||
| return (0, uuid.v5)(name, new Uint8Array(namespaceBytes)); | ||
| } | ||
| //# sourceMappingURL=id.js.map | ||
| //#endregion | ||
| exports.uuid5 = uuid5; | ||
| exports.uuid6 = uuid6; | ||
| //# sourceMappingURL=id.cjs.map |
+10
-2
@@ -1,2 +0,10 @@ | ||
| export declare function uuid6(clockseq: number): string; | ||
| export declare function uuid5(name: string, namespace: string): string; | ||
| //#region src/id.d.ts | ||
| declare function uuid6(clockseq: number): string; | ||
| // Skip UUID validation check, since UUID6s | ||
| // generated with negative clockseq are not | ||
| // technically compliant, but still work. | ||
| // See: https://github.com/uuidjs/uuid/issues/511 | ||
| declare function uuid5(name: string, namespace: string): string; | ||
| //#endregion | ||
| export { uuid5, uuid6 }; | ||
| //# sourceMappingURL=id.d.ts.map |
+10
-12
| import { v5, v6 } from "uuid"; | ||
| export function uuid6(clockseq) { | ||
| return v6({ clockseq }); | ||
| //#region src/id.ts | ||
| function uuid6(clockseq) { | ||
| return v6({ clockseq }); | ||
| } | ||
| // Skip UUID validation check, since UUID6s | ||
| // generated with negative clockseq are not | ||
| // technically compliant, but still work. | ||
| // See: https://github.com/uuidjs/uuid/issues/511 | ||
| export function uuid5(name, namespace) { | ||
| const namespaceBytes = namespace | ||
| .replace(/-/g, "") | ||
| .match(/.{2}/g) | ||
| .map((byte) => parseInt(byte, 16)); | ||
| return v5(name, new Uint8Array(namespaceBytes)); | ||
| function uuid5(name, namespace) { | ||
| const namespaceBytes = namespace.replace(/-/g, "").match(/.{2}/g).map((byte) => parseInt(byte, 16)); | ||
| return v5(name, new Uint8Array(namespaceBytes)); | ||
| } | ||
| //#endregion | ||
| export { uuid5, uuid6 }; | ||
| //# sourceMappingURL=id.js.map |
+1
-1
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"id.js","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAE9B,MAAM,UAAU,KAAK,CAAC,QAAgB;IACpC,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC1B,CAAC;AAED,2CAA2C;AAC3C,2CAA2C;AAC3C,yCAAyC;AACzC,iDAAiD;AACjD,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,SAAiB;IACnD,MAAM,cAAc,GAAG,SAAS;SAC7B,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;SACjB,KAAK,CAAC,OAAO,CAAE;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IACrC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;AAClD,CAAC"} | ||
| {"version":3,"file":"id.js","names":[],"sources":["../src/id.ts"],"sourcesContent":["import { v5, v6 } from \"uuid\";\n\nexport function uuid6(clockseq: number): string {\n return v6({ clockseq });\n}\n\n// Skip UUID validation check, since UUID6s\n// generated with negative clockseq are not\n// technically compliant, but still work.\n// See: https://github.com/uuidjs/uuid/issues/511\nexport function uuid5(name: string, namespace: string): string {\n const namespaceBytes = namespace\n .replace(/-/g, \"\")\n .match(/.{2}/g)!\n .map((byte) => parseInt(byte, 16));\n return v5(name, new Uint8Array(namespaceBytes));\n}\n"],"mappings":";;;AAEA,SAAgB,MAAM,UAA0B;AAC9C,QAAO,GAAG,EAAE;;AAOd,SAAgB,MAAM,MAAc,WAA2B;CAC7D,MAAM,iBAAiB,UACpB,QAAQ,MAAM,IACd,MAAM,SACN,KAAK,SAAS,SAAS,MAAM;AAChC,QAAO,GAAG,MAAM,IAAI,WAAW"} |
+36
-27
@@ -1,27 +0,36 @@ | ||
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
| for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.MemorySaver = void 0; | ||
| var memory_js_1 = require("./memory.cjs"); | ||
| Object.defineProperty(exports, "MemorySaver", { enumerable: true, get: function () { return memory_js_1.MemorySaver; } }); | ||
| __exportStar(require("./base.cjs"), exports); | ||
| __exportStar(require("./id.cjs"), exports); | ||
| __exportStar(require("./types.cjs"), exports); | ||
| __exportStar(require("./serde/base.cjs"), exports); | ||
| __exportStar(require("./serde/types.cjs"), exports); | ||
| __exportStar(require("./store/index.cjs"), exports); | ||
| __exportStar(require("./cache/index.cjs"), exports); | ||
| //# sourceMappingURL=index.js.map | ||
| const require_id = require('./id.cjs'); | ||
| const require_types = require('./serde/types.cjs'); | ||
| const require_base = require('./base.cjs'); | ||
| const require_memory = require('./memory.cjs'); | ||
| const require_base$1 = require('./store/base.cjs'); | ||
| const require_batch = require('./store/batch.cjs'); | ||
| const require_memory$1 = require('./store/memory.cjs'); | ||
| const require_base$2 = require('./cache/base.cjs'); | ||
| const require_memory$2 = require('./cache/memory.cjs'); | ||
| require('./cache/index.cjs'); | ||
| exports.AsyncBatchedStore = require_batch.AsyncBatchedStore; | ||
| exports.BaseCache = require_base$2.BaseCache; | ||
| exports.BaseCheckpointSaver = require_base.BaseCheckpointSaver; | ||
| exports.BaseStore = require_base$1.BaseStore; | ||
| exports.ERROR = require_types.ERROR; | ||
| exports.INTERRUPT = require_types.INTERRUPT; | ||
| exports.InMemoryCache = require_memory$2.InMemoryCache; | ||
| exports.InMemoryStore = require_memory$1.InMemoryStore; | ||
| exports.InvalidNamespaceError = require_base$1.InvalidNamespaceError; | ||
| exports.MemorySaver = require_memory.MemorySaver; | ||
| exports.MemoryStore = require_memory$1.MemoryStore; | ||
| exports.RESUME = require_types.RESUME; | ||
| exports.SCHEDULED = require_types.SCHEDULED; | ||
| exports.TASKS = require_types.TASKS; | ||
| exports.WRITES_IDX_MAP = require_base.WRITES_IDX_MAP; | ||
| exports.compareChannelVersions = require_base.compareChannelVersions; | ||
| exports.copyCheckpoint = require_base.copyCheckpoint; | ||
| exports.deepCopy = require_base.deepCopy; | ||
| exports.emptyCheckpoint = require_base.emptyCheckpoint; | ||
| exports.getCheckpointId = require_base.getCheckpointId; | ||
| exports.getTextAtPath = require_base$1.getTextAtPath; | ||
| exports.maxChannelVersion = require_base.maxChannelVersion; | ||
| exports.tokenizePath = require_base$1.tokenizePath; | ||
| exports.uuid5 = require_id.uuid5; | ||
| exports.uuid6 = require_id.uuid6; |
+12
-8
@@ -1,8 +0,12 @@ | ||
| export { MemorySaver } from "./memory.js"; | ||
| export * from "./base.js"; | ||
| export * from "./id.js"; | ||
| export * from "./types.js"; | ||
| export * from "./serde/base.js"; | ||
| export * from "./serde/types.js"; | ||
| export * from "./store/index.js"; | ||
| export * from "./cache/index.js"; | ||
| import { SerializerProtocol } from "./serde/base.js"; | ||
| import { All, CheckpointMetadata, CheckpointPendingWrite, PendingWrite, PendingWriteValue } from "./types.js"; | ||
| import { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointTuple, ReadonlyCheckpoint, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion } from "./base.js"; | ||
| import { MemorySaver } from "./memory.js"; | ||
| import { uuid5, uuid6 } from "./id.js"; | ||
| import { ChannelProtocol, ERROR, INTERRUPT, RESUME, SCHEDULED, SendProtocol, TASKS } from "./serde/types.js"; | ||
| import { BaseStore, GetOperation, IndexConfig, InvalidNamespaceError, Item, ListNamespacesOperation, MatchCondition, NameSpacePath, NamespaceMatchType, Operation, OperationResults, PutOperation, SearchItem, SearchOperation, getTextAtPath, tokenizePath } from "./store/base.js"; | ||
| import { AsyncBatchedStore } from "./store/batch.js"; | ||
| import { InMemoryStore, MemoryStore } from "./store/memory.js"; | ||
| import { BaseCache, CacheFullKey, CacheNamespace } from "./cache/base.js"; | ||
| import { InMemoryCache } from "./cache/memory.js"; | ||
| export { All, AsyncBatchedStore, BaseCache, BaseCheckpointSaver, BaseStore, CacheFullKey, CacheNamespace, ChannelProtocol, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointMetadata, CheckpointPendingWrite, CheckpointTuple, ERROR, GetOperation, INTERRUPT, InMemoryCache, InMemoryStore, IndexConfig, InvalidNamespaceError, Item, ListNamespacesOperation, MatchCondition, MemorySaver, MemoryStore, NameSpacePath, NamespaceMatchType, Operation, OperationResults, PendingWrite, PendingWriteValue, PutOperation, RESUME, ReadonlyCheckpoint, SCHEDULED, SearchItem, SearchOperation, SendProtocol, SerializerProtocol, TASKS, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, getTextAtPath, maxChannelVersion, tokenizePath, uuid5, uuid6 }; |
+12
-9
@@ -1,9 +0,12 @@ | ||
| export { MemorySaver } from "./memory.js"; | ||
| export * from "./base.js"; | ||
| export * from "./id.js"; | ||
| export * from "./types.js"; | ||
| export * from "./serde/base.js"; | ||
| export * from "./serde/types.js"; | ||
| export * from "./store/index.js"; | ||
| export * from "./cache/index.js"; | ||
| //# sourceMappingURL=index.js.map | ||
| import { uuid5, uuid6 } from "./id.js"; | ||
| import { ERROR, INTERRUPT, RESUME, SCHEDULED, TASKS } from "./serde/types.js"; | ||
| import { BaseCheckpointSaver, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion } from "./base.js"; | ||
| import { MemorySaver } from "./memory.js"; | ||
| import { BaseStore, InvalidNamespaceError, getTextAtPath, tokenizePath } from "./store/base.js"; | ||
| import { AsyncBatchedStore } from "./store/batch.js"; | ||
| import { InMemoryStore, MemoryStore } from "./store/memory.js"; | ||
| import { BaseCache } from "./cache/base.js"; | ||
| import { InMemoryCache } from "./cache/memory.js"; | ||
| import "./cache/index.js"; | ||
| export { AsyncBatchedStore, BaseCache, BaseCheckpointSaver, BaseStore, ERROR, INTERRUPT, InMemoryCache, InMemoryStore, InvalidNamespaceError, MemorySaver, MemoryStore, RESUME, SCHEDULED, TASKS, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, getTextAtPath, maxChannelVersion, tokenizePath, uuid5, uuid6 }; |
+194
-268
@@ -1,273 +0,199 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.MemorySaver = void 0; | ||
| const base_js_1 = require("./base.cjs"); | ||
| const types_js_1 = require("./serde/types.cjs"); | ||
| const require_types = require('./serde/types.cjs'); | ||
| const require_base = require('./base.cjs'); | ||
| //#region src/memory.ts | ||
| function _generateKey(threadId, checkpointNamespace, checkpointId) { | ||
| return JSON.stringify([threadId, checkpointNamespace, checkpointId]); | ||
| return JSON.stringify([ | ||
| threadId, | ||
| checkpointNamespace, | ||
| checkpointId | ||
| ]); | ||
| } | ||
| function _parseKey(key) { | ||
| const [threadId, checkpointNamespace, checkpointId] = JSON.parse(key); | ||
| return { threadId, checkpointNamespace, checkpointId }; | ||
| const [threadId, checkpointNamespace, checkpointId] = JSON.parse(key); | ||
| return { | ||
| threadId, | ||
| checkpointNamespace, | ||
| checkpointId | ||
| }; | ||
| } | ||
| class MemorySaver extends base_js_1.BaseCheckpointSaver { | ||
| constructor(serde) { | ||
| super(serde); | ||
| // thread ID -> checkpoint namespace -> checkpoint ID -> checkpoint mapping | ||
| Object.defineProperty(this, "storage", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: {} | ||
| }); | ||
| Object.defineProperty(this, "writes", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: {} | ||
| }); | ||
| } | ||
| async _migratePendingSends(mutableCheckpoint, threadId, checkpointNs, parentCheckpointId) { | ||
| const deseriablizableCheckpoint = mutableCheckpoint; | ||
| const parentKey = _generateKey(threadId, checkpointNs, parentCheckpointId); | ||
| const pendingSends = await Promise.all(Object.values(this.writes[parentKey] ?? {}) | ||
| .filter(([_taskId, channel]) => channel === types_js_1.TASKS) | ||
| .map(async ([_taskId, _channel, writes]) => await this.serde.loadsTyped("json", writes))); | ||
| deseriablizableCheckpoint.channel_values ??= {}; | ||
| deseriablizableCheckpoint.channel_values[types_js_1.TASKS] = pendingSends; | ||
| deseriablizableCheckpoint.channel_versions ??= {}; | ||
| deseriablizableCheckpoint.channel_versions[types_js_1.TASKS] = | ||
| Object.keys(deseriablizableCheckpoint.channel_versions).length > 0 | ||
| ? (0, base_js_1.maxChannelVersion)(...Object.values(deseriablizableCheckpoint.channel_versions)) | ||
| : this.getNextVersion(undefined); | ||
| } | ||
| async getTuple(config) { | ||
| const thread_id = config.configurable?.thread_id; | ||
| const checkpoint_ns = config.configurable?.checkpoint_ns ?? ""; | ||
| let checkpoint_id = (0, base_js_1.getCheckpointId)(config); | ||
| if (checkpoint_id) { | ||
| const saved = this.storage[thread_id]?.[checkpoint_ns]?.[checkpoint_id]; | ||
| if (saved !== undefined) { | ||
| const [checkpoint, metadata, parentCheckpointId] = saved; | ||
| const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id); | ||
| const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint); | ||
| if (deserializedCheckpoint.v < 4 && parentCheckpointId !== undefined) { | ||
| await this._migratePendingSends(deserializedCheckpoint, thread_id, checkpoint_ns, parentCheckpointId); | ||
| } | ||
| const pendingWrites = await Promise.all(Object.values(this.writes[key] || {}).map(async ([taskId, channel, value]) => { | ||
| return [ | ||
| taskId, | ||
| channel, | ||
| await this.serde.loadsTyped("json", value), | ||
| ]; | ||
| })); | ||
| const checkpointTuple = { | ||
| config, | ||
| checkpoint: deserializedCheckpoint, | ||
| metadata: (await this.serde.loadsTyped("json", metadata)), | ||
| pendingWrites, | ||
| }; | ||
| if (parentCheckpointId !== undefined) { | ||
| checkpointTuple.parentConfig = { | ||
| configurable: { | ||
| thread_id, | ||
| checkpoint_ns, | ||
| checkpoint_id: parentCheckpointId, | ||
| }, | ||
| }; | ||
| } | ||
| return checkpointTuple; | ||
| } | ||
| } | ||
| else { | ||
| const checkpoints = this.storage[thread_id]?.[checkpoint_ns]; | ||
| if (checkpoints !== undefined) { | ||
| // eslint-disable-next-line prefer-destructuring | ||
| checkpoint_id = Object.keys(checkpoints).sort((a, b) => b.localeCompare(a))[0]; | ||
| const saved = checkpoints[checkpoint_id]; | ||
| const [checkpoint, metadata, parentCheckpointId] = saved; | ||
| const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id); | ||
| const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint); | ||
| if (deserializedCheckpoint.v < 4 && parentCheckpointId !== undefined) { | ||
| await this._migratePendingSends(deserializedCheckpoint, thread_id, checkpoint_ns, parentCheckpointId); | ||
| } | ||
| const pendingWrites = await Promise.all(Object.values(this.writes[key] || {}).map(async ([taskId, channel, value]) => { | ||
| return [ | ||
| taskId, | ||
| channel, | ||
| await this.serde.loadsTyped("json", value), | ||
| ]; | ||
| })); | ||
| const checkpointTuple = { | ||
| config: { | ||
| configurable: { | ||
| thread_id, | ||
| checkpoint_id, | ||
| checkpoint_ns, | ||
| }, | ||
| }, | ||
| checkpoint: deserializedCheckpoint, | ||
| metadata: (await this.serde.loadsTyped("json", metadata)), | ||
| pendingWrites, | ||
| }; | ||
| if (parentCheckpointId !== undefined) { | ||
| checkpointTuple.parentConfig = { | ||
| configurable: { | ||
| thread_id, | ||
| checkpoint_ns, | ||
| checkpoint_id: parentCheckpointId, | ||
| }, | ||
| }; | ||
| } | ||
| return checkpointTuple; | ||
| } | ||
| } | ||
| return undefined; | ||
| } | ||
| async *list(config, options) { | ||
| // eslint-disable-next-line prefer-const | ||
| let { before, limit, filter } = options ?? {}; | ||
| const threadIds = config.configurable?.thread_id | ||
| ? [config.configurable?.thread_id] | ||
| : Object.keys(this.storage); | ||
| const configCheckpointNamespace = config.configurable?.checkpoint_ns; | ||
| const configCheckpointId = config.configurable?.checkpoint_id; | ||
| for (const threadId of threadIds) { | ||
| for (const checkpointNamespace of Object.keys(this.storage[threadId] ?? {})) { | ||
| if (configCheckpointNamespace !== undefined && | ||
| checkpointNamespace !== configCheckpointNamespace) { | ||
| continue; | ||
| } | ||
| const checkpoints = this.storage[threadId]?.[checkpointNamespace] ?? {}; | ||
| const sortedCheckpoints = Object.entries(checkpoints).sort((a, b) => b[0].localeCompare(a[0])); | ||
| for (const [checkpointId, [checkpoint, metadataStr, parentCheckpointId],] of sortedCheckpoints) { | ||
| // Filter by checkpoint ID from config | ||
| if (configCheckpointId && checkpointId !== configCheckpointId) { | ||
| continue; | ||
| } | ||
| // Filter by checkpoint ID from before config | ||
| if (before && | ||
| before.configurable?.checkpoint_id && | ||
| checkpointId >= before.configurable.checkpoint_id) { | ||
| continue; | ||
| } | ||
| // Parse metadata | ||
| const metadata = (await this.serde.loadsTyped("json", metadataStr)); | ||
| if (filter && | ||
| !Object.entries(filter).every(([key, value]) => metadata[key] === value)) { | ||
| continue; | ||
| } | ||
| // Limit search results | ||
| if (limit !== undefined) { | ||
| if (limit <= 0) | ||
| break; | ||
| limit -= 1; | ||
| } | ||
| const key = _generateKey(threadId, checkpointNamespace, checkpointId); | ||
| const writes = Object.values(this.writes[key] || {}); | ||
| const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => { | ||
| return [ | ||
| taskId, | ||
| channel, | ||
| await this.serde.loadsTyped("json", value), | ||
| ]; | ||
| })); | ||
| const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint); | ||
| if (deserializedCheckpoint.v < 4 && | ||
| parentCheckpointId !== undefined) { | ||
| await this._migratePendingSends(deserializedCheckpoint, threadId, checkpointNamespace, parentCheckpointId); | ||
| } | ||
| const checkpointTuple = { | ||
| config: { | ||
| configurable: { | ||
| thread_id: threadId, | ||
| checkpoint_ns: checkpointNamespace, | ||
| checkpoint_id: checkpointId, | ||
| }, | ||
| }, | ||
| checkpoint: deserializedCheckpoint, | ||
| metadata, | ||
| pendingWrites, | ||
| }; | ||
| if (parentCheckpointId !== undefined) { | ||
| checkpointTuple.parentConfig = { | ||
| configurable: { | ||
| thread_id: threadId, | ||
| checkpoint_ns: checkpointNamespace, | ||
| checkpoint_id: parentCheckpointId, | ||
| }, | ||
| }; | ||
| } | ||
| yield checkpointTuple; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| async put(config, checkpoint, metadata) { | ||
| const preparedCheckpoint = (0, base_js_1.copyCheckpoint)(checkpoint); | ||
| const threadId = config.configurable?.thread_id; | ||
| const checkpointNamespace = config.configurable?.checkpoint_ns ?? ""; | ||
| if (threadId === undefined) { | ||
| throw new Error(`Failed to put checkpoint. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property.`); | ||
| } | ||
| if (!this.storage[threadId]) { | ||
| this.storage[threadId] = {}; | ||
| } | ||
| if (!this.storage[threadId][checkpointNamespace]) { | ||
| this.storage[threadId][checkpointNamespace] = {}; | ||
| } | ||
| const [[, serializedCheckpoint], [, serializedMetadata]] = await Promise.all([ | ||
| this.serde.dumpsTyped(preparedCheckpoint), | ||
| this.serde.dumpsTyped(metadata), | ||
| ]); | ||
| this.storage[threadId][checkpointNamespace][checkpoint.id] = [ | ||
| serializedCheckpoint, | ||
| serializedMetadata, | ||
| config.configurable?.checkpoint_id, // parent | ||
| ]; | ||
| return { | ||
| configurable: { | ||
| thread_id: threadId, | ||
| checkpoint_ns: checkpointNamespace, | ||
| checkpoint_id: checkpoint.id, | ||
| }, | ||
| }; | ||
| } | ||
| async putWrites(config, writes, taskId) { | ||
| const threadId = config.configurable?.thread_id; | ||
| const checkpointNamespace = config.configurable?.checkpoint_ns; | ||
| const checkpointId = config.configurable?.checkpoint_id; | ||
| if (threadId === undefined) { | ||
| throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property`); | ||
| } | ||
| if (checkpointId === undefined) { | ||
| throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "checkpoint_id" field in its "configurable" property.`); | ||
| } | ||
| const outerKey = _generateKey(threadId, checkpointNamespace, checkpointId); | ||
| const outerWrites_ = this.writes[outerKey]; | ||
| if (this.writes[outerKey] === undefined) { | ||
| this.writes[outerKey] = {}; | ||
| } | ||
| await Promise.all(writes.map(async ([channel, value], idx) => { | ||
| const [, serializedValue] = await this.serde.dumpsTyped(value); | ||
| const innerKey = [ | ||
| taskId, | ||
| base_js_1.WRITES_IDX_MAP[channel] || idx, | ||
| ]; | ||
| const innerKeyStr = `${innerKey[0]},${innerKey[1]}`; | ||
| if (innerKey[1] >= 0 && outerWrites_ && innerKeyStr in outerWrites_) { | ||
| return; | ||
| } | ||
| this.writes[outerKey][innerKeyStr] = [taskId, channel, serializedValue]; | ||
| })); | ||
| } | ||
| async deleteThread(threadId) { | ||
| delete this.storage[threadId]; | ||
| for (const key of Object.keys(this.writes)) { | ||
| if (_parseKey(key).threadId === threadId) | ||
| delete this.writes[key]; | ||
| } | ||
| } | ||
| } | ||
| var MemorySaver = class extends require_base.BaseCheckpointSaver { | ||
| storage = {}; | ||
| writes = {}; | ||
| constructor(serde) { | ||
| super(serde); | ||
| } | ||
| /** @internal */ | ||
| async _migratePendingSends(mutableCheckpoint, threadId, checkpointNs, parentCheckpointId) { | ||
| const deseriablizableCheckpoint = mutableCheckpoint; | ||
| const parentKey = _generateKey(threadId, checkpointNs, parentCheckpointId); | ||
| const pendingSends = await Promise.all(Object.values(this.writes[parentKey] ?? {}).filter(([_taskId, channel]) => channel === require_types.TASKS).map(async ([_taskId, _channel, writes]) => await this.serde.loadsTyped("json", writes))); | ||
| deseriablizableCheckpoint.channel_values ??= {}; | ||
| deseriablizableCheckpoint.channel_values[require_types.TASKS] = pendingSends; | ||
| deseriablizableCheckpoint.channel_versions ??= {}; | ||
| deseriablizableCheckpoint.channel_versions[require_types.TASKS] = Object.keys(deseriablizableCheckpoint.channel_versions).length > 0 ? require_base.maxChannelVersion(...Object.values(deseriablizableCheckpoint.channel_versions)) : this.getNextVersion(void 0); | ||
| } | ||
| async getTuple(config) { | ||
| const thread_id = config.configurable?.thread_id; | ||
| const checkpoint_ns = config.configurable?.checkpoint_ns ?? ""; | ||
| let checkpoint_id = require_base.getCheckpointId(config); | ||
| if (checkpoint_id) { | ||
| const saved = this.storage[thread_id]?.[checkpoint_ns]?.[checkpoint_id]; | ||
| if (saved !== void 0) { | ||
| const [checkpoint, metadata, parentCheckpointId] = saved; | ||
| const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id); | ||
| const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint); | ||
| if (deserializedCheckpoint.v < 4 && parentCheckpointId !== void 0) await this._migratePendingSends(deserializedCheckpoint, thread_id, checkpoint_ns, parentCheckpointId); | ||
| const pendingWrites = await Promise.all(Object.values(this.writes[key] || {}).map(async ([taskId, channel, value]) => { | ||
| return [ | ||
| taskId, | ||
| channel, | ||
| await this.serde.loadsTyped("json", value) | ||
| ]; | ||
| })); | ||
| const checkpointTuple = { | ||
| config, | ||
| checkpoint: deserializedCheckpoint, | ||
| metadata: await this.serde.loadsTyped("json", metadata), | ||
| pendingWrites | ||
| }; | ||
| if (parentCheckpointId !== void 0) checkpointTuple.parentConfig = { configurable: { | ||
| thread_id, | ||
| checkpoint_ns, | ||
| checkpoint_id: parentCheckpointId | ||
| } }; | ||
| return checkpointTuple; | ||
| } | ||
| } else { | ||
| const checkpoints = this.storage[thread_id]?.[checkpoint_ns]; | ||
| if (checkpoints !== void 0) { | ||
| checkpoint_id = Object.keys(checkpoints).sort((a, b) => b.localeCompare(a))[0]; | ||
| const saved = checkpoints[checkpoint_id]; | ||
| const [checkpoint, metadata, parentCheckpointId] = saved; | ||
| const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id); | ||
| const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint); | ||
| if (deserializedCheckpoint.v < 4 && parentCheckpointId !== void 0) await this._migratePendingSends(deserializedCheckpoint, thread_id, checkpoint_ns, parentCheckpointId); | ||
| const pendingWrites = await Promise.all(Object.values(this.writes[key] || {}).map(async ([taskId, channel, value]) => { | ||
| return [ | ||
| taskId, | ||
| channel, | ||
| await this.serde.loadsTyped("json", value) | ||
| ]; | ||
| })); | ||
| const checkpointTuple = { | ||
| config: { configurable: { | ||
| thread_id, | ||
| checkpoint_id, | ||
| checkpoint_ns | ||
| } }, | ||
| checkpoint: deserializedCheckpoint, | ||
| metadata: await this.serde.loadsTyped("json", metadata), | ||
| pendingWrites | ||
| }; | ||
| if (parentCheckpointId !== void 0) checkpointTuple.parentConfig = { configurable: { | ||
| thread_id, | ||
| checkpoint_ns, | ||
| checkpoint_id: parentCheckpointId | ||
| } }; | ||
| return checkpointTuple; | ||
| } | ||
| } | ||
| return void 0; | ||
| } | ||
| async *list(config, options) { | ||
| let { before, limit, filter } = options ?? {}; | ||
| const threadIds = config.configurable?.thread_id ? [config.configurable?.thread_id] : Object.keys(this.storage); | ||
| const configCheckpointNamespace = config.configurable?.checkpoint_ns; | ||
| const configCheckpointId = config.configurable?.checkpoint_id; | ||
| for (const threadId of threadIds) for (const checkpointNamespace of Object.keys(this.storage[threadId] ?? {})) { | ||
| if (configCheckpointNamespace !== void 0 && checkpointNamespace !== configCheckpointNamespace) continue; | ||
| const checkpoints = this.storage[threadId]?.[checkpointNamespace] ?? {}; | ||
| const sortedCheckpoints = Object.entries(checkpoints).sort((a, b) => b[0].localeCompare(a[0])); | ||
| for (const [checkpointId, [checkpoint, metadataStr, parentCheckpointId]] of sortedCheckpoints) { | ||
| if (configCheckpointId && checkpointId !== configCheckpointId) continue; | ||
| if (before && before.configurable?.checkpoint_id && checkpointId >= before.configurable.checkpoint_id) continue; | ||
| const metadata = await this.serde.loadsTyped("json", metadataStr); | ||
| if (filter && !Object.entries(filter).every(([key$1, value]) => metadata[key$1] === value)) continue; | ||
| if (limit !== void 0) { | ||
| if (limit <= 0) break; | ||
| limit -= 1; | ||
| } | ||
| const key = _generateKey(threadId, checkpointNamespace, checkpointId); | ||
| const writes = Object.values(this.writes[key] || {}); | ||
| const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => { | ||
| return [ | ||
| taskId, | ||
| channel, | ||
| await this.serde.loadsTyped("json", value) | ||
| ]; | ||
| })); | ||
| const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint); | ||
| if (deserializedCheckpoint.v < 4 && parentCheckpointId !== void 0) await this._migratePendingSends(deserializedCheckpoint, threadId, checkpointNamespace, parentCheckpointId); | ||
| const checkpointTuple = { | ||
| config: { configurable: { | ||
| thread_id: threadId, | ||
| checkpoint_ns: checkpointNamespace, | ||
| checkpoint_id: checkpointId | ||
| } }, | ||
| checkpoint: deserializedCheckpoint, | ||
| metadata, | ||
| pendingWrites | ||
| }; | ||
| if (parentCheckpointId !== void 0) checkpointTuple.parentConfig = { configurable: { | ||
| thread_id: threadId, | ||
| checkpoint_ns: checkpointNamespace, | ||
| checkpoint_id: parentCheckpointId | ||
| } }; | ||
| yield checkpointTuple; | ||
| } | ||
| } | ||
| } | ||
| async put(config, checkpoint, metadata) { | ||
| const preparedCheckpoint = require_base.copyCheckpoint(checkpoint); | ||
| const threadId = config.configurable?.thread_id; | ||
| const checkpointNamespace = config.configurable?.checkpoint_ns ?? ""; | ||
| if (threadId === void 0) throw new Error(`Failed to put checkpoint. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property.`); | ||
| if (!this.storage[threadId]) this.storage[threadId] = {}; | ||
| if (!this.storage[threadId][checkpointNamespace]) this.storage[threadId][checkpointNamespace] = {}; | ||
| const [[, serializedCheckpoint], [, serializedMetadata]] = await Promise.all([this.serde.dumpsTyped(preparedCheckpoint), this.serde.dumpsTyped(metadata)]); | ||
| this.storage[threadId][checkpointNamespace][checkpoint.id] = [ | ||
| serializedCheckpoint, | ||
| serializedMetadata, | ||
| config.configurable?.checkpoint_id | ||
| ]; | ||
| return { configurable: { | ||
| thread_id: threadId, | ||
| checkpoint_ns: checkpointNamespace, | ||
| checkpoint_id: checkpoint.id | ||
| } }; | ||
| } | ||
| async putWrites(config, writes, taskId) { | ||
| const threadId = config.configurable?.thread_id; | ||
| const checkpointNamespace = config.configurable?.checkpoint_ns; | ||
| const checkpointId = config.configurable?.checkpoint_id; | ||
| if (threadId === void 0) throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property`); | ||
| if (checkpointId === void 0) throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "checkpoint_id" field in its "configurable" property.`); | ||
| const outerKey = _generateKey(threadId, checkpointNamespace, checkpointId); | ||
| const outerWrites_ = this.writes[outerKey]; | ||
| if (this.writes[outerKey] === void 0) this.writes[outerKey] = {}; | ||
| await Promise.all(writes.map(async ([channel, value], idx) => { | ||
| const [, serializedValue] = await this.serde.dumpsTyped(value); | ||
| const innerKey = [taskId, require_base.WRITES_IDX_MAP[channel] || idx]; | ||
| const innerKeyStr = `${innerKey[0]},${innerKey[1]}`; | ||
| if (innerKey[1] >= 0 && outerWrites_ && innerKeyStr in outerWrites_) return; | ||
| this.writes[outerKey][innerKeyStr] = [ | ||
| taskId, | ||
| channel, | ||
| serializedValue | ||
| ]; | ||
| })); | ||
| } | ||
| async deleteThread(threadId) { | ||
| delete this.storage[threadId]; | ||
| for (const key of Object.keys(this.writes)) if (_parseKey(key).threadId === threadId) delete this.writes[key]; | ||
| } | ||
| }; | ||
| //#endregion | ||
| exports.MemorySaver = MemorySaver; | ||
| //# sourceMappingURL=memory.js.map | ||
| //# sourceMappingURL=memory.cjs.map |
+19
-12
@@ -1,15 +0,22 @@ | ||
| import type { RunnableConfig } from "@langchain/core/runnables"; | ||
| import { BaseCheckpointSaver, Checkpoint, CheckpointListOptions, CheckpointTuple } from "./base.js"; | ||
| import { SerializerProtocol } from "./serde/base.js"; | ||
| import { CheckpointMetadata, PendingWrite } from "./types.js"; | ||
| export declare class MemorySaver extends BaseCheckpointSaver { | ||
| storage: Record<string, Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>>; | ||
| writes: Record<string, Record<string, [string, string, Uint8Array]>>; | ||
| constructor(serde?: SerializerProtocol); | ||
| _migratePendingSends(mutableCheckpoint: Checkpoint, threadId: string, checkpointNs: string, parentCheckpointId: string): Promise<void>; | ||
| getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>; | ||
| list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>; | ||
| put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig>; | ||
| putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>; | ||
| deleteThread(threadId: string): Promise<void>; | ||
| import { BaseCheckpointSaver, Checkpoint, CheckpointListOptions, CheckpointTuple } from "./base.js"; | ||
| import { RunnableConfig } from "@langchain/core/runnables"; | ||
| //#region src/memory.d.ts | ||
| declare class MemorySaver extends BaseCheckpointSaver { | ||
| // thread ID -> checkpoint namespace -> checkpoint ID -> checkpoint mapping | ||
| storage: Record<string, Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>>; | ||
| writes: Record<string, Record<string, [string, string, Uint8Array]>>; | ||
| constructor(serde?: SerializerProtocol); | ||
| /** @internal */ | ||
| _migratePendingSends(mutableCheckpoint: Checkpoint, threadId: string, checkpointNs: string, parentCheckpointId: string): Promise<void>; | ||
| getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>; | ||
| list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>; | ||
| put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig>; | ||
| putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>; | ||
| deleteThread(threadId: string): Promise<void>; | ||
| } | ||
| //#endregion | ||
| export { MemorySaver }; | ||
| //# sourceMappingURL=memory.d.ts.map |
+193
-263
@@ -1,269 +0,199 @@ | ||
| import { BaseCheckpointSaver, copyCheckpoint, getCheckpointId, maxChannelVersion, WRITES_IDX_MAP, } from "./base.js"; | ||
| import { TASKS } from "./serde/types.js"; | ||
| import { BaseCheckpointSaver, WRITES_IDX_MAP, copyCheckpoint, getCheckpointId, maxChannelVersion } from "./base.js"; | ||
| //#region src/memory.ts | ||
| function _generateKey(threadId, checkpointNamespace, checkpointId) { | ||
| return JSON.stringify([threadId, checkpointNamespace, checkpointId]); | ||
| return JSON.stringify([ | ||
| threadId, | ||
| checkpointNamespace, | ||
| checkpointId | ||
| ]); | ||
| } | ||
| function _parseKey(key) { | ||
| const [threadId, checkpointNamespace, checkpointId] = JSON.parse(key); | ||
| return { threadId, checkpointNamespace, checkpointId }; | ||
| const [threadId, checkpointNamespace, checkpointId] = JSON.parse(key); | ||
| return { | ||
| threadId, | ||
| checkpointNamespace, | ||
| checkpointId | ||
| }; | ||
| } | ||
| export class MemorySaver extends BaseCheckpointSaver { | ||
| constructor(serde) { | ||
| super(serde); | ||
| // thread ID -> checkpoint namespace -> checkpoint ID -> checkpoint mapping | ||
| Object.defineProperty(this, "storage", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: {} | ||
| }); | ||
| Object.defineProperty(this, "writes", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: {} | ||
| }); | ||
| } | ||
| async _migratePendingSends(mutableCheckpoint, threadId, checkpointNs, parentCheckpointId) { | ||
| const deseriablizableCheckpoint = mutableCheckpoint; | ||
| const parentKey = _generateKey(threadId, checkpointNs, parentCheckpointId); | ||
| const pendingSends = await Promise.all(Object.values(this.writes[parentKey] ?? {}) | ||
| .filter(([_taskId, channel]) => channel === TASKS) | ||
| .map(async ([_taskId, _channel, writes]) => await this.serde.loadsTyped("json", writes))); | ||
| deseriablizableCheckpoint.channel_values ??= {}; | ||
| deseriablizableCheckpoint.channel_values[TASKS] = pendingSends; | ||
| deseriablizableCheckpoint.channel_versions ??= {}; | ||
| deseriablizableCheckpoint.channel_versions[TASKS] = | ||
| Object.keys(deseriablizableCheckpoint.channel_versions).length > 0 | ||
| ? maxChannelVersion(...Object.values(deseriablizableCheckpoint.channel_versions)) | ||
| : this.getNextVersion(undefined); | ||
| } | ||
| async getTuple(config) { | ||
| const thread_id = config.configurable?.thread_id; | ||
| const checkpoint_ns = config.configurable?.checkpoint_ns ?? ""; | ||
| let checkpoint_id = getCheckpointId(config); | ||
| if (checkpoint_id) { | ||
| const saved = this.storage[thread_id]?.[checkpoint_ns]?.[checkpoint_id]; | ||
| if (saved !== undefined) { | ||
| const [checkpoint, metadata, parentCheckpointId] = saved; | ||
| const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id); | ||
| const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint); | ||
| if (deserializedCheckpoint.v < 4 && parentCheckpointId !== undefined) { | ||
| await this._migratePendingSends(deserializedCheckpoint, thread_id, checkpoint_ns, parentCheckpointId); | ||
| } | ||
| const pendingWrites = await Promise.all(Object.values(this.writes[key] || {}).map(async ([taskId, channel, value]) => { | ||
| return [ | ||
| taskId, | ||
| channel, | ||
| await this.serde.loadsTyped("json", value), | ||
| ]; | ||
| })); | ||
| const checkpointTuple = { | ||
| config, | ||
| checkpoint: deserializedCheckpoint, | ||
| metadata: (await this.serde.loadsTyped("json", metadata)), | ||
| pendingWrites, | ||
| }; | ||
| if (parentCheckpointId !== undefined) { | ||
| checkpointTuple.parentConfig = { | ||
| configurable: { | ||
| thread_id, | ||
| checkpoint_ns, | ||
| checkpoint_id: parentCheckpointId, | ||
| }, | ||
| }; | ||
| } | ||
| return checkpointTuple; | ||
| } | ||
| } | ||
| else { | ||
| const checkpoints = this.storage[thread_id]?.[checkpoint_ns]; | ||
| if (checkpoints !== undefined) { | ||
| // eslint-disable-next-line prefer-destructuring | ||
| checkpoint_id = Object.keys(checkpoints).sort((a, b) => b.localeCompare(a))[0]; | ||
| const saved = checkpoints[checkpoint_id]; | ||
| const [checkpoint, metadata, parentCheckpointId] = saved; | ||
| const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id); | ||
| const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint); | ||
| if (deserializedCheckpoint.v < 4 && parentCheckpointId !== undefined) { | ||
| await this._migratePendingSends(deserializedCheckpoint, thread_id, checkpoint_ns, parentCheckpointId); | ||
| } | ||
| const pendingWrites = await Promise.all(Object.values(this.writes[key] || {}).map(async ([taskId, channel, value]) => { | ||
| return [ | ||
| taskId, | ||
| channel, | ||
| await this.serde.loadsTyped("json", value), | ||
| ]; | ||
| })); | ||
| const checkpointTuple = { | ||
| config: { | ||
| configurable: { | ||
| thread_id, | ||
| checkpoint_id, | ||
| checkpoint_ns, | ||
| }, | ||
| }, | ||
| checkpoint: deserializedCheckpoint, | ||
| metadata: (await this.serde.loadsTyped("json", metadata)), | ||
| pendingWrites, | ||
| }; | ||
| if (parentCheckpointId !== undefined) { | ||
| checkpointTuple.parentConfig = { | ||
| configurable: { | ||
| thread_id, | ||
| checkpoint_ns, | ||
| checkpoint_id: parentCheckpointId, | ||
| }, | ||
| }; | ||
| } | ||
| return checkpointTuple; | ||
| } | ||
| } | ||
| return undefined; | ||
| } | ||
| async *list(config, options) { | ||
| // eslint-disable-next-line prefer-const | ||
| let { before, limit, filter } = options ?? {}; | ||
| const threadIds = config.configurable?.thread_id | ||
| ? [config.configurable?.thread_id] | ||
| : Object.keys(this.storage); | ||
| const configCheckpointNamespace = config.configurable?.checkpoint_ns; | ||
| const configCheckpointId = config.configurable?.checkpoint_id; | ||
| for (const threadId of threadIds) { | ||
| for (const checkpointNamespace of Object.keys(this.storage[threadId] ?? {})) { | ||
| if (configCheckpointNamespace !== undefined && | ||
| checkpointNamespace !== configCheckpointNamespace) { | ||
| continue; | ||
| } | ||
| const checkpoints = this.storage[threadId]?.[checkpointNamespace] ?? {}; | ||
| const sortedCheckpoints = Object.entries(checkpoints).sort((a, b) => b[0].localeCompare(a[0])); | ||
| for (const [checkpointId, [checkpoint, metadataStr, parentCheckpointId],] of sortedCheckpoints) { | ||
| // Filter by checkpoint ID from config | ||
| if (configCheckpointId && checkpointId !== configCheckpointId) { | ||
| continue; | ||
| } | ||
| // Filter by checkpoint ID from before config | ||
| if (before && | ||
| before.configurable?.checkpoint_id && | ||
| checkpointId >= before.configurable.checkpoint_id) { | ||
| continue; | ||
| } | ||
| // Parse metadata | ||
| const metadata = (await this.serde.loadsTyped("json", metadataStr)); | ||
| if (filter && | ||
| !Object.entries(filter).every(([key, value]) => metadata[key] === value)) { | ||
| continue; | ||
| } | ||
| // Limit search results | ||
| if (limit !== undefined) { | ||
| if (limit <= 0) | ||
| break; | ||
| limit -= 1; | ||
| } | ||
| const key = _generateKey(threadId, checkpointNamespace, checkpointId); | ||
| const writes = Object.values(this.writes[key] || {}); | ||
| const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => { | ||
| return [ | ||
| taskId, | ||
| channel, | ||
| await this.serde.loadsTyped("json", value), | ||
| ]; | ||
| })); | ||
| const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint); | ||
| if (deserializedCheckpoint.v < 4 && | ||
| parentCheckpointId !== undefined) { | ||
| await this._migratePendingSends(deserializedCheckpoint, threadId, checkpointNamespace, parentCheckpointId); | ||
| } | ||
| const checkpointTuple = { | ||
| config: { | ||
| configurable: { | ||
| thread_id: threadId, | ||
| checkpoint_ns: checkpointNamespace, | ||
| checkpoint_id: checkpointId, | ||
| }, | ||
| }, | ||
| checkpoint: deserializedCheckpoint, | ||
| metadata, | ||
| pendingWrites, | ||
| }; | ||
| if (parentCheckpointId !== undefined) { | ||
| checkpointTuple.parentConfig = { | ||
| configurable: { | ||
| thread_id: threadId, | ||
| checkpoint_ns: checkpointNamespace, | ||
| checkpoint_id: parentCheckpointId, | ||
| }, | ||
| }; | ||
| } | ||
| yield checkpointTuple; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| async put(config, checkpoint, metadata) { | ||
| const preparedCheckpoint = copyCheckpoint(checkpoint); | ||
| const threadId = config.configurable?.thread_id; | ||
| const checkpointNamespace = config.configurable?.checkpoint_ns ?? ""; | ||
| if (threadId === undefined) { | ||
| throw new Error(`Failed to put checkpoint. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property.`); | ||
| } | ||
| if (!this.storage[threadId]) { | ||
| this.storage[threadId] = {}; | ||
| } | ||
| if (!this.storage[threadId][checkpointNamespace]) { | ||
| this.storage[threadId][checkpointNamespace] = {}; | ||
| } | ||
| const [[, serializedCheckpoint], [, serializedMetadata]] = await Promise.all([ | ||
| this.serde.dumpsTyped(preparedCheckpoint), | ||
| this.serde.dumpsTyped(metadata), | ||
| ]); | ||
| this.storage[threadId][checkpointNamespace][checkpoint.id] = [ | ||
| serializedCheckpoint, | ||
| serializedMetadata, | ||
| config.configurable?.checkpoint_id, // parent | ||
| ]; | ||
| return { | ||
| configurable: { | ||
| thread_id: threadId, | ||
| checkpoint_ns: checkpointNamespace, | ||
| checkpoint_id: checkpoint.id, | ||
| }, | ||
| }; | ||
| } | ||
| async putWrites(config, writes, taskId) { | ||
| const threadId = config.configurable?.thread_id; | ||
| const checkpointNamespace = config.configurable?.checkpoint_ns; | ||
| const checkpointId = config.configurable?.checkpoint_id; | ||
| if (threadId === undefined) { | ||
| throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property`); | ||
| } | ||
| if (checkpointId === undefined) { | ||
| throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "checkpoint_id" field in its "configurable" property.`); | ||
| } | ||
| const outerKey = _generateKey(threadId, checkpointNamespace, checkpointId); | ||
| const outerWrites_ = this.writes[outerKey]; | ||
| if (this.writes[outerKey] === undefined) { | ||
| this.writes[outerKey] = {}; | ||
| } | ||
| await Promise.all(writes.map(async ([channel, value], idx) => { | ||
| const [, serializedValue] = await this.serde.dumpsTyped(value); | ||
| const innerKey = [ | ||
| taskId, | ||
| WRITES_IDX_MAP[channel] || idx, | ||
| ]; | ||
| const innerKeyStr = `${innerKey[0]},${innerKey[1]}`; | ||
| if (innerKey[1] >= 0 && outerWrites_ && innerKeyStr in outerWrites_) { | ||
| return; | ||
| } | ||
| this.writes[outerKey][innerKeyStr] = [taskId, channel, serializedValue]; | ||
| })); | ||
| } | ||
| async deleteThread(threadId) { | ||
| delete this.storage[threadId]; | ||
| for (const key of Object.keys(this.writes)) { | ||
| if (_parseKey(key).threadId === threadId) | ||
| delete this.writes[key]; | ||
| } | ||
| } | ||
| } | ||
| var MemorySaver = class extends BaseCheckpointSaver { | ||
| storage = {}; | ||
| writes = {}; | ||
| constructor(serde) { | ||
| super(serde); | ||
| } | ||
| /** @internal */ | ||
| async _migratePendingSends(mutableCheckpoint, threadId, checkpointNs, parentCheckpointId) { | ||
| const deseriablizableCheckpoint = mutableCheckpoint; | ||
| const parentKey = _generateKey(threadId, checkpointNs, parentCheckpointId); | ||
| const pendingSends = await Promise.all(Object.values(this.writes[parentKey] ?? {}).filter(([_taskId, channel]) => channel === TASKS).map(async ([_taskId, _channel, writes]) => await this.serde.loadsTyped("json", writes))); | ||
| deseriablizableCheckpoint.channel_values ??= {}; | ||
| deseriablizableCheckpoint.channel_values[TASKS] = pendingSends; | ||
| deseriablizableCheckpoint.channel_versions ??= {}; | ||
| deseriablizableCheckpoint.channel_versions[TASKS] = Object.keys(deseriablizableCheckpoint.channel_versions).length > 0 ? maxChannelVersion(...Object.values(deseriablizableCheckpoint.channel_versions)) : this.getNextVersion(void 0); | ||
| } | ||
| async getTuple(config) { | ||
| const thread_id = config.configurable?.thread_id; | ||
| const checkpoint_ns = config.configurable?.checkpoint_ns ?? ""; | ||
| let checkpoint_id = getCheckpointId(config); | ||
| if (checkpoint_id) { | ||
| const saved = this.storage[thread_id]?.[checkpoint_ns]?.[checkpoint_id]; | ||
| if (saved !== void 0) { | ||
| const [checkpoint, metadata, parentCheckpointId] = saved; | ||
| const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id); | ||
| const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint); | ||
| if (deserializedCheckpoint.v < 4 && parentCheckpointId !== void 0) await this._migratePendingSends(deserializedCheckpoint, thread_id, checkpoint_ns, parentCheckpointId); | ||
| const pendingWrites = await Promise.all(Object.values(this.writes[key] || {}).map(async ([taskId, channel, value]) => { | ||
| return [ | ||
| taskId, | ||
| channel, | ||
| await this.serde.loadsTyped("json", value) | ||
| ]; | ||
| })); | ||
| const checkpointTuple = { | ||
| config, | ||
| checkpoint: deserializedCheckpoint, | ||
| metadata: await this.serde.loadsTyped("json", metadata), | ||
| pendingWrites | ||
| }; | ||
| if (parentCheckpointId !== void 0) checkpointTuple.parentConfig = { configurable: { | ||
| thread_id, | ||
| checkpoint_ns, | ||
| checkpoint_id: parentCheckpointId | ||
| } }; | ||
| return checkpointTuple; | ||
| } | ||
| } else { | ||
| const checkpoints = this.storage[thread_id]?.[checkpoint_ns]; | ||
| if (checkpoints !== void 0) { | ||
| checkpoint_id = Object.keys(checkpoints).sort((a, b) => b.localeCompare(a))[0]; | ||
| const saved = checkpoints[checkpoint_id]; | ||
| const [checkpoint, metadata, parentCheckpointId] = saved; | ||
| const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id); | ||
| const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint); | ||
| if (deserializedCheckpoint.v < 4 && parentCheckpointId !== void 0) await this._migratePendingSends(deserializedCheckpoint, thread_id, checkpoint_ns, parentCheckpointId); | ||
| const pendingWrites = await Promise.all(Object.values(this.writes[key] || {}).map(async ([taskId, channel, value]) => { | ||
| return [ | ||
| taskId, | ||
| channel, | ||
| await this.serde.loadsTyped("json", value) | ||
| ]; | ||
| })); | ||
| const checkpointTuple = { | ||
| config: { configurable: { | ||
| thread_id, | ||
| checkpoint_id, | ||
| checkpoint_ns | ||
| } }, | ||
| checkpoint: deserializedCheckpoint, | ||
| metadata: await this.serde.loadsTyped("json", metadata), | ||
| pendingWrites | ||
| }; | ||
| if (parentCheckpointId !== void 0) checkpointTuple.parentConfig = { configurable: { | ||
| thread_id, | ||
| checkpoint_ns, | ||
| checkpoint_id: parentCheckpointId | ||
| } }; | ||
| return checkpointTuple; | ||
| } | ||
| } | ||
| return void 0; | ||
| } | ||
| async *list(config, options) { | ||
| let { before, limit, filter } = options ?? {}; | ||
| const threadIds = config.configurable?.thread_id ? [config.configurable?.thread_id] : Object.keys(this.storage); | ||
| const configCheckpointNamespace = config.configurable?.checkpoint_ns; | ||
| const configCheckpointId = config.configurable?.checkpoint_id; | ||
| for (const threadId of threadIds) for (const checkpointNamespace of Object.keys(this.storage[threadId] ?? {})) { | ||
| if (configCheckpointNamespace !== void 0 && checkpointNamespace !== configCheckpointNamespace) continue; | ||
| const checkpoints = this.storage[threadId]?.[checkpointNamespace] ?? {}; | ||
| const sortedCheckpoints = Object.entries(checkpoints).sort((a, b) => b[0].localeCompare(a[0])); | ||
| for (const [checkpointId, [checkpoint, metadataStr, parentCheckpointId]] of sortedCheckpoints) { | ||
| if (configCheckpointId && checkpointId !== configCheckpointId) continue; | ||
| if (before && before.configurable?.checkpoint_id && checkpointId >= before.configurable.checkpoint_id) continue; | ||
| const metadata = await this.serde.loadsTyped("json", metadataStr); | ||
| if (filter && !Object.entries(filter).every(([key$1, value]) => metadata[key$1] === value)) continue; | ||
| if (limit !== void 0) { | ||
| if (limit <= 0) break; | ||
| limit -= 1; | ||
| } | ||
| const key = _generateKey(threadId, checkpointNamespace, checkpointId); | ||
| const writes = Object.values(this.writes[key] || {}); | ||
| const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => { | ||
| return [ | ||
| taskId, | ||
| channel, | ||
| await this.serde.loadsTyped("json", value) | ||
| ]; | ||
| })); | ||
| const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint); | ||
| if (deserializedCheckpoint.v < 4 && parentCheckpointId !== void 0) await this._migratePendingSends(deserializedCheckpoint, threadId, checkpointNamespace, parentCheckpointId); | ||
| const checkpointTuple = { | ||
| config: { configurable: { | ||
| thread_id: threadId, | ||
| checkpoint_ns: checkpointNamespace, | ||
| checkpoint_id: checkpointId | ||
| } }, | ||
| checkpoint: deserializedCheckpoint, | ||
| metadata, | ||
| pendingWrites | ||
| }; | ||
| if (parentCheckpointId !== void 0) checkpointTuple.parentConfig = { configurable: { | ||
| thread_id: threadId, | ||
| checkpoint_ns: checkpointNamespace, | ||
| checkpoint_id: parentCheckpointId | ||
| } }; | ||
| yield checkpointTuple; | ||
| } | ||
| } | ||
| } | ||
| async put(config, checkpoint, metadata) { | ||
| const preparedCheckpoint = copyCheckpoint(checkpoint); | ||
| const threadId = config.configurable?.thread_id; | ||
| const checkpointNamespace = config.configurable?.checkpoint_ns ?? ""; | ||
| if (threadId === void 0) throw new Error(`Failed to put checkpoint. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property.`); | ||
| if (!this.storage[threadId]) this.storage[threadId] = {}; | ||
| if (!this.storage[threadId][checkpointNamespace]) this.storage[threadId][checkpointNamespace] = {}; | ||
| const [[, serializedCheckpoint], [, serializedMetadata]] = await Promise.all([this.serde.dumpsTyped(preparedCheckpoint), this.serde.dumpsTyped(metadata)]); | ||
| this.storage[threadId][checkpointNamespace][checkpoint.id] = [ | ||
| serializedCheckpoint, | ||
| serializedMetadata, | ||
| config.configurable?.checkpoint_id | ||
| ]; | ||
| return { configurable: { | ||
| thread_id: threadId, | ||
| checkpoint_ns: checkpointNamespace, | ||
| checkpoint_id: checkpoint.id | ||
| } }; | ||
| } | ||
| async putWrites(config, writes, taskId) { | ||
| const threadId = config.configurable?.thread_id; | ||
| const checkpointNamespace = config.configurable?.checkpoint_ns; | ||
| const checkpointId = config.configurable?.checkpoint_id; | ||
| if (threadId === void 0) throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "thread_id" field in its "configurable" property`); | ||
| if (checkpointId === void 0) throw new Error(`Failed to put writes. The passed RunnableConfig is missing a required "checkpoint_id" field in its "configurable" property.`); | ||
| const outerKey = _generateKey(threadId, checkpointNamespace, checkpointId); | ||
| const outerWrites_ = this.writes[outerKey]; | ||
| if (this.writes[outerKey] === void 0) this.writes[outerKey] = {}; | ||
| await Promise.all(writes.map(async ([channel, value], idx) => { | ||
| const [, serializedValue] = await this.serde.dumpsTyped(value); | ||
| const innerKey = [taskId, WRITES_IDX_MAP[channel] || idx]; | ||
| const innerKeyStr = `${innerKey[0]},${innerKey[1]}`; | ||
| if (innerKey[1] >= 0 && outerWrites_ && innerKeyStr in outerWrites_) return; | ||
| this.writes[outerKey][innerKeyStr] = [ | ||
| taskId, | ||
| channel, | ||
| serializedValue | ||
| ]; | ||
| })); | ||
| } | ||
| async deleteThread(threadId) { | ||
| delete this.storage[threadId]; | ||
| for (const key of Object.keys(this.writes)) if (_parseKey(key).threadId === threadId) delete this.writes[key]; | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { MemorySaver }; | ||
| //# sourceMappingURL=memory.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"memory.js","names":["deserializedCheckpoint: Checkpoint","pendingWrites: CheckpointPendingWrite[]","checkpointTuple: CheckpointTuple","key","preparedCheckpoint: Partial<Checkpoint>","innerKey: [string, number]"],"sources":["../src/memory.ts"],"sourcesContent":["import type { RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n BaseCheckpointSaver,\n Checkpoint,\n CheckpointListOptions,\n CheckpointTuple,\n copyCheckpoint,\n getCheckpointId,\n maxChannelVersion,\n WRITES_IDX_MAP,\n} from \"./base.js\";\nimport { SerializerProtocol } from \"./serde/base.js\";\nimport {\n CheckpointMetadata,\n CheckpointPendingWrite,\n PendingWrite,\n} from \"./types.js\";\nimport { TASKS } from \"./serde/types.js\";\n\nfunction _generateKey(\n threadId: string,\n checkpointNamespace: string,\n checkpointId: string\n) {\n return JSON.stringify([threadId, checkpointNamespace, checkpointId]);\n}\n\nfunction _parseKey(key: string) {\n const [threadId, checkpointNamespace, checkpointId] = JSON.parse(key);\n return { threadId, checkpointNamespace, checkpointId };\n}\n\nexport class MemorySaver extends BaseCheckpointSaver {\n // thread ID -> checkpoint namespace -> checkpoint ID -> checkpoint mapping\n storage: Record<\n string,\n Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>\n > = {};\n\n writes: Record<string, Record<string, [string, string, Uint8Array]>> = {};\n\n constructor(serde?: SerializerProtocol) {\n super(serde);\n }\n\n /** @internal */\n async _migratePendingSends(\n mutableCheckpoint: Checkpoint,\n threadId: string,\n checkpointNs: string,\n parentCheckpointId: string\n ) {\n const deseriablizableCheckpoint = mutableCheckpoint;\n const parentKey = _generateKey(threadId, checkpointNs, parentCheckpointId);\n\n const pendingSends = await Promise.all(\n Object.values(this.writes[parentKey] ?? {})\n .filter(([_taskId, channel]) => channel === TASKS)\n .map(\n async ([_taskId, _channel, writes]) =>\n await this.serde.loadsTyped(\"json\", writes)\n )\n );\n\n deseriablizableCheckpoint.channel_values ??= {};\n deseriablizableCheckpoint.channel_values[TASKS] = pendingSends;\n\n deseriablizableCheckpoint.channel_versions ??= {};\n deseriablizableCheckpoint.channel_versions[TASKS] =\n Object.keys(deseriablizableCheckpoint.channel_versions).length > 0\n ? maxChannelVersion(\n ...Object.values(deseriablizableCheckpoint.channel_versions)\n )\n : this.getNextVersion(undefined);\n }\n\n async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {\n const thread_id = config.configurable?.thread_id;\n const checkpoint_ns = config.configurable?.checkpoint_ns ?? \"\";\n let checkpoint_id = getCheckpointId(config);\n\n if (checkpoint_id) {\n const saved = this.storage[thread_id]?.[checkpoint_ns]?.[checkpoint_id];\n if (saved !== undefined) {\n const [checkpoint, metadata, parentCheckpointId] = saved;\n const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id);\n const deserializedCheckpoint: Checkpoint = await this.serde.loadsTyped(\n \"json\",\n checkpoint\n );\n\n if (deserializedCheckpoint.v < 4 && parentCheckpointId !== undefined) {\n await this._migratePendingSends(\n deserializedCheckpoint,\n thread_id,\n checkpoint_ns,\n parentCheckpointId\n );\n }\n\n const pendingWrites: CheckpointPendingWrite[] = await Promise.all(\n Object.values(this.writes[key] || {}).map(\n async ([taskId, channel, value]) => {\n return [\n taskId,\n channel,\n await this.serde.loadsTyped(\"json\", value),\n ];\n }\n )\n );\n const checkpointTuple: CheckpointTuple = {\n config,\n checkpoint: deserializedCheckpoint,\n metadata: (await this.serde.loadsTyped(\n \"json\",\n metadata\n )) as CheckpointMetadata,\n pendingWrites,\n };\n if (parentCheckpointId !== undefined) {\n checkpointTuple.parentConfig = {\n configurable: {\n thread_id,\n checkpoint_ns,\n checkpoint_id: parentCheckpointId,\n },\n };\n }\n return checkpointTuple;\n }\n } else {\n const checkpoints = this.storage[thread_id]?.[checkpoint_ns];\n if (checkpoints !== undefined) {\n // eslint-disable-next-line prefer-destructuring\n checkpoint_id = Object.keys(checkpoints).sort((a, b) =>\n b.localeCompare(a)\n )[0];\n const saved = checkpoints[checkpoint_id];\n const [checkpoint, metadata, parentCheckpointId] = saved;\n const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id);\n const deserializedCheckpoint: Checkpoint = await this.serde.loadsTyped(\n \"json\",\n checkpoint\n );\n\n if (deserializedCheckpoint.v < 4 && parentCheckpointId !== undefined) {\n await this._migratePendingSends(\n deserializedCheckpoint,\n thread_id,\n checkpoint_ns,\n parentCheckpointId\n );\n }\n\n const pendingWrites: CheckpointPendingWrite[] = await Promise.all(\n Object.values(this.writes[key] || {}).map(\n async ([taskId, channel, value]) => {\n return [\n taskId,\n channel,\n await this.serde.loadsTyped(\"json\", value),\n ];\n }\n )\n );\n const checkpointTuple: CheckpointTuple = {\n config: {\n configurable: {\n thread_id,\n checkpoint_id,\n checkpoint_ns,\n },\n },\n checkpoint: deserializedCheckpoint,\n metadata: (await this.serde.loadsTyped(\n \"json\",\n metadata\n )) as CheckpointMetadata,\n pendingWrites,\n };\n if (parentCheckpointId !== undefined) {\n checkpointTuple.parentConfig = {\n configurable: {\n thread_id,\n checkpoint_ns,\n checkpoint_id: parentCheckpointId,\n },\n };\n }\n return checkpointTuple;\n }\n }\n\n return undefined;\n }\n\n async *list(\n config: RunnableConfig,\n options?: CheckpointListOptions\n ): AsyncGenerator<CheckpointTuple> {\n // eslint-disable-next-line prefer-const\n let { before, limit, filter } = options ?? {};\n const threadIds = config.configurable?.thread_id\n ? [config.configurable?.thread_id]\n : Object.keys(this.storage);\n const configCheckpointNamespace = config.configurable?.checkpoint_ns;\n const configCheckpointId = config.configurable?.checkpoint_id;\n\n for (const threadId of threadIds) {\n for (const checkpointNamespace of Object.keys(\n this.storage[threadId] ?? {}\n )) {\n if (\n configCheckpointNamespace !== undefined &&\n checkpointNamespace !== configCheckpointNamespace\n ) {\n continue;\n }\n const checkpoints = this.storage[threadId]?.[checkpointNamespace] ?? {};\n const sortedCheckpoints = Object.entries(checkpoints).sort((a, b) =>\n b[0].localeCompare(a[0])\n );\n\n for (const [\n checkpointId,\n [checkpoint, metadataStr, parentCheckpointId],\n ] of sortedCheckpoints) {\n // Filter by checkpoint ID from config\n if (configCheckpointId && checkpointId !== configCheckpointId) {\n continue;\n }\n\n // Filter by checkpoint ID from before config\n if (\n before &&\n before.configurable?.checkpoint_id &&\n checkpointId >= before.configurable.checkpoint_id\n ) {\n continue;\n }\n\n // Parse metadata\n const metadata = (await this.serde.loadsTyped(\n \"json\",\n metadataStr\n )) as CheckpointMetadata;\n\n if (\n filter &&\n !Object.entries(filter).every(\n ([key, value]) =>\n (metadata as unknown as Record<string, unknown>)[key] === value\n )\n ) {\n continue;\n }\n\n // Limit search results\n if (limit !== undefined) {\n if (limit <= 0) break;\n limit -= 1;\n }\n\n const key = _generateKey(threadId, checkpointNamespace, checkpointId);\n const writes = Object.values(this.writes[key] || {});\n\n const pendingWrites: CheckpointPendingWrite[] = await Promise.all(\n writes.map(async ([taskId, channel, value]) => {\n return [\n taskId,\n channel,\n await this.serde.loadsTyped(\"json\", value),\n ];\n })\n );\n\n const deserializedCheckpoint = await this.serde.loadsTyped(\n \"json\",\n checkpoint\n );\n\n if (\n deserializedCheckpoint.v < 4 &&\n parentCheckpointId !== undefined\n ) {\n await this._migratePendingSends(\n deserializedCheckpoint,\n threadId,\n checkpointNamespace,\n parentCheckpointId\n );\n }\n\n const checkpointTuple: CheckpointTuple = {\n config: {\n configurable: {\n thread_id: threadId,\n checkpoint_ns: checkpointNamespace,\n checkpoint_id: checkpointId,\n },\n },\n checkpoint: deserializedCheckpoint,\n metadata,\n pendingWrites,\n };\n if (parentCheckpointId !== undefined) {\n checkpointTuple.parentConfig = {\n configurable: {\n thread_id: threadId,\n checkpoint_ns: checkpointNamespace,\n checkpoint_id: parentCheckpointId,\n },\n };\n }\n yield checkpointTuple;\n }\n }\n }\n }\n\n async put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata\n ): Promise<RunnableConfig> {\n const preparedCheckpoint: Partial<Checkpoint> = copyCheckpoint(checkpoint);\n const threadId = config.configurable?.thread_id;\n const checkpointNamespace = config.configurable?.checkpoint_ns ?? \"\";\n if (threadId === undefined) {\n throw new Error(\n `Failed to put checkpoint. The passed RunnableConfig is missing a required \"thread_id\" field in its \"configurable\" property.`\n );\n }\n\n if (!this.storage[threadId]) {\n this.storage[threadId] = {};\n }\n if (!this.storage[threadId][checkpointNamespace]) {\n this.storage[threadId][checkpointNamespace] = {};\n }\n\n const [[, serializedCheckpoint], [, serializedMetadata]] =\n await Promise.all([\n this.serde.dumpsTyped(preparedCheckpoint),\n this.serde.dumpsTyped(metadata),\n ]);\n\n this.storage[threadId][checkpointNamespace][checkpoint.id] = [\n serializedCheckpoint,\n serializedMetadata,\n config.configurable?.checkpoint_id, // parent\n ];\n\n return {\n configurable: {\n thread_id: threadId,\n checkpoint_ns: checkpointNamespace,\n checkpoint_id: checkpoint.id,\n },\n };\n }\n\n async putWrites(\n config: RunnableConfig,\n writes: PendingWrite[],\n taskId: string\n ): Promise<void> {\n const threadId = config.configurable?.thread_id;\n const checkpointNamespace = config.configurable?.checkpoint_ns;\n const checkpointId = config.configurable?.checkpoint_id;\n if (threadId === undefined) {\n throw new Error(\n `Failed to put writes. The passed RunnableConfig is missing a required \"thread_id\" field in its \"configurable\" property`\n );\n }\n if (checkpointId === undefined) {\n throw new Error(\n `Failed to put writes. The passed RunnableConfig is missing a required \"checkpoint_id\" field in its \"configurable\" property.`\n );\n }\n const outerKey = _generateKey(threadId, checkpointNamespace, checkpointId);\n const outerWrites_ = this.writes[outerKey];\n if (this.writes[outerKey] === undefined) {\n this.writes[outerKey] = {};\n }\n\n await Promise.all(\n writes.map(async ([channel, value], idx) => {\n const [, serializedValue] = await this.serde.dumpsTyped(value);\n const innerKey: [string, number] = [\n taskId,\n WRITES_IDX_MAP[channel] || idx,\n ];\n const innerKeyStr = `${innerKey[0]},${innerKey[1]}`;\n if (innerKey[1] >= 0 && outerWrites_ && innerKeyStr in outerWrites_) {\n return;\n }\n this.writes[outerKey][innerKeyStr] = [taskId, channel, serializedValue];\n })\n );\n }\n\n async deleteThread(threadId: string): Promise<void> {\n delete this.storage[threadId];\n for (const key of Object.keys(this.writes)) {\n if (_parseKey(key).threadId === threadId) delete this.writes[key];\n }\n }\n}\n"],"mappings":"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"} |
@@ -1,4 +0,10 @@ | ||
| export interface SerializerProtocol { | ||
| dumpsTyped(data: any): Promise<[string, Uint8Array]>; | ||
| loadsTyped(type: string, data: Uint8Array | string): Promise<any>; | ||
| //#region src/serde/base.d.ts | ||
| interface SerializerProtocol { | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| dumpsTyped(data: any): Promise<[string, Uint8Array]>; | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| loadsTyped(type: string, data: Uint8Array | string): Promise<any>; | ||
| } | ||
| //#endregion | ||
| export { SerializerProtocol }; | ||
| //# sourceMappingURL=base.d.ts.map |
+92
-141
@@ -1,150 +0,101 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.JsonPlusSerializer = void 0; | ||
| /* eslint-disable @typescript-eslint/no-explicit-any */ | ||
| /* eslint-disable no-instanceof/no-instanceof */ | ||
| const load_1 = require("@langchain/core/load"); | ||
| const index_js_1 = require("./utils/fast-safe-stringify/index.cjs"); | ||
| const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs'); | ||
| const require_index = require('./utils/fast-safe-stringify/index.cjs'); | ||
| const __langchain_core_load = require_rolldown_runtime.__toESM(require("@langchain/core/load")); | ||
| //#region src/serde/jsonplus.ts | ||
| function isLangChainSerializedObject(value) { | ||
| return (value !== null && | ||
| value.lc === 1 && | ||
| value.type === "constructor" && | ||
| Array.isArray(value.id)); | ||
| return value !== null && value.lc === 1 && value.type === "constructor" && Array.isArray(value.id); | ||
| } | ||
| /** | ||
| * The replacer in stringify does not allow delegation to built-in LangChain | ||
| * serialization methods, and instead immediately calls `.toJSON()` and | ||
| * continues to stringify subfields. | ||
| * | ||
| * We therefore must start from the most nested elements in the input and | ||
| * deserialize upwards rather than top-down. | ||
| */ | ||
| * The replacer in stringify does not allow delegation to built-in LangChain | ||
| * serialization methods, and instead immediately calls `.toJSON()` and | ||
| * continues to stringify subfields. | ||
| * | ||
| * We therefore must start from the most nested elements in the input and | ||
| * deserialize upwards rather than top-down. | ||
| */ | ||
| async function _reviver(value) { | ||
| if (value && typeof value === "object") { | ||
| if (Array.isArray(value)) { | ||
| const revivedArray = await Promise.all(value.map((item) => _reviver(item))); | ||
| return revivedArray; | ||
| } | ||
| else { | ||
| const revivedObj = {}; | ||
| for (const [k, v] of Object.entries(value)) { | ||
| revivedObj[k] = await _reviver(v); | ||
| } | ||
| if (revivedObj.lc === 2 && revivedObj.type === "undefined") { | ||
| return undefined; | ||
| } | ||
| else if (revivedObj.lc === 2 && | ||
| revivedObj.type === "constructor" && | ||
| Array.isArray(revivedObj.id)) { | ||
| try { | ||
| const constructorName = revivedObj.id[revivedObj.id.length - 1]; | ||
| let constructor; | ||
| switch (constructorName) { | ||
| case "Set": | ||
| constructor = Set; | ||
| break; | ||
| case "Map": | ||
| constructor = Map; | ||
| break; | ||
| case "RegExp": | ||
| constructor = RegExp; | ||
| break; | ||
| case "Error": | ||
| constructor = Error; | ||
| break; | ||
| default: | ||
| return revivedObj; | ||
| } | ||
| if (revivedObj.method) { | ||
| return constructor[revivedObj.method](...(revivedObj.args || [])); | ||
| } | ||
| else { | ||
| return new constructor(...(revivedObj.args || [])); | ||
| } | ||
| } | ||
| catch (error) { | ||
| return revivedObj; | ||
| } | ||
| } | ||
| else if (isLangChainSerializedObject(revivedObj)) { | ||
| return (0, load_1.load)(JSON.stringify(revivedObj)); | ||
| } | ||
| return revivedObj; | ||
| } | ||
| } | ||
| return value; | ||
| if (value && typeof value === "object") if (Array.isArray(value)) { | ||
| const revivedArray = await Promise.all(value.map((item) => _reviver(item))); | ||
| return revivedArray; | ||
| } else { | ||
| const revivedObj = {}; | ||
| for (const [k, v] of Object.entries(value)) revivedObj[k] = await _reviver(v); | ||
| if (revivedObj.lc === 2 && revivedObj.type === "undefined") return void 0; | ||
| else if (revivedObj.lc === 2 && revivedObj.type === "constructor" && Array.isArray(revivedObj.id)) try { | ||
| const constructorName = revivedObj.id[revivedObj.id.length - 1]; | ||
| let constructor; | ||
| switch (constructorName) { | ||
| case "Set": | ||
| constructor = Set; | ||
| break; | ||
| case "Map": | ||
| constructor = Map; | ||
| break; | ||
| case "RegExp": | ||
| constructor = RegExp; | ||
| break; | ||
| case "Error": | ||
| constructor = Error; | ||
| break; | ||
| default: return revivedObj; | ||
| } | ||
| if (revivedObj.method) return constructor[revivedObj.method](...revivedObj.args || []); | ||
| else return new constructor(...revivedObj.args || []); | ||
| } catch (error) { | ||
| return revivedObj; | ||
| } | ||
| else if (isLangChainSerializedObject(revivedObj)) return (0, __langchain_core_load.load)(JSON.stringify(revivedObj)); | ||
| return revivedObj; | ||
| } | ||
| return value; | ||
| } | ||
| function _encodeConstructorArgs( | ||
| // eslint-disable-next-line @typescript-eslint/ban-types | ||
| constructor, method, args, kwargs) { | ||
| return { | ||
| lc: 2, | ||
| type: "constructor", | ||
| id: [constructor.name], | ||
| method: method ?? null, | ||
| args: args ?? [], | ||
| kwargs: kwargs ?? {}, | ||
| }; | ||
| function _encodeConstructorArgs(constructor, method, args, kwargs) { | ||
| return { | ||
| lc: 2, | ||
| type: "constructor", | ||
| id: [constructor.name], | ||
| method: method ?? null, | ||
| args: args ?? [], | ||
| kwargs: kwargs ?? {} | ||
| }; | ||
| } | ||
| function _default(obj) { | ||
| if (obj === undefined) { | ||
| return { | ||
| lc: 2, | ||
| type: "undefined", | ||
| }; | ||
| } | ||
| else if (obj instanceof Set || obj instanceof Map) { | ||
| return _encodeConstructorArgs(obj.constructor, undefined, [ | ||
| Array.from(obj), | ||
| ]); | ||
| } | ||
| else if (obj instanceof RegExp) { | ||
| return _encodeConstructorArgs(RegExp, undefined, [obj.source, obj.flags]); | ||
| } | ||
| else if (obj instanceof Error) { | ||
| return _encodeConstructorArgs(obj.constructor, undefined, [obj.message]); | ||
| // TODO: Remove special case | ||
| } | ||
| else if (obj?.lg_name === "Send") { | ||
| return { | ||
| node: obj.node, | ||
| args: obj.args, | ||
| }; | ||
| } | ||
| else { | ||
| return obj; | ||
| } | ||
| if (obj === void 0) return { | ||
| lc: 2, | ||
| type: "undefined" | ||
| }; | ||
| else if (obj instanceof Set || obj instanceof Map) return _encodeConstructorArgs(obj.constructor, void 0, [Array.from(obj)]); | ||
| else if (obj instanceof RegExp) return _encodeConstructorArgs(RegExp, void 0, [obj.source, obj.flags]); | ||
| else if (obj instanceof Error) return _encodeConstructorArgs(obj.constructor, void 0, [obj.message]); | ||
| else if (obj?.lg_name === "Send") return { | ||
| node: obj.node, | ||
| args: obj.args | ||
| }; | ||
| else return obj; | ||
| } | ||
| class JsonPlusSerializer { | ||
| _dumps(obj) { | ||
| const encoder = new TextEncoder(); | ||
| return encoder.encode((0, index_js_1.stringify)(obj, (_, value) => { | ||
| return _default(value); | ||
| })); | ||
| } | ||
| async dumpsTyped(obj) { | ||
| if (obj instanceof Uint8Array) { | ||
| return ["bytes", obj]; | ||
| } | ||
| else { | ||
| return ["json", this._dumps(obj)]; | ||
| } | ||
| } | ||
| async _loads(data) { | ||
| const parsed = JSON.parse(data); | ||
| return _reviver(parsed); | ||
| } | ||
| async loadsTyped(type, data) { | ||
| if (type === "bytes") { | ||
| return typeof data === "string" ? new TextEncoder().encode(data) : data; | ||
| } | ||
| else if (type === "json") { | ||
| return this._loads(typeof data === "string" ? data : new TextDecoder().decode(data)); | ||
| } | ||
| else { | ||
| throw new Error(`Unknown serialization type: ${type}`); | ||
| } | ||
| } | ||
| } | ||
| var JsonPlusSerializer = class { | ||
| _dumps(obj) { | ||
| const encoder = new TextEncoder(); | ||
| return encoder.encode(require_index.stringify(obj, (_, value) => { | ||
| return _default(value); | ||
| })); | ||
| } | ||
| async dumpsTyped(obj) { | ||
| if (obj instanceof Uint8Array) return ["bytes", obj]; | ||
| else return ["json", this._dumps(obj)]; | ||
| } | ||
| async _loads(data) { | ||
| const parsed = JSON.parse(data); | ||
| return _reviver(parsed); | ||
| } | ||
| async loadsTyped(type, data) { | ||
| if (type === "bytes") return typeof data === "string" ? new TextEncoder().encode(data) : data; | ||
| else if (type === "json") return this._loads(typeof data === "string" ? data : new TextDecoder().decode(data)); | ||
| else throw new Error(`Unknown serialization type: ${type}`); | ||
| } | ||
| }; | ||
| //#endregion | ||
| exports.JsonPlusSerializer = JsonPlusSerializer; | ||
| //# sourceMappingURL=jsonplus.js.map | ||
| //# sourceMappingURL=jsonplus.cjs.map |
+90
-136
@@ -1,146 +0,100 @@ | ||
| /* eslint-disable @typescript-eslint/no-explicit-any */ | ||
| /* eslint-disable no-instanceof/no-instanceof */ | ||
| import { stringify } from "./utils/fast-safe-stringify/index.js"; | ||
| import { load } from "@langchain/core/load"; | ||
| import { stringify } from "./utils/fast-safe-stringify/index.js"; | ||
| //#region src/serde/jsonplus.ts | ||
| function isLangChainSerializedObject(value) { | ||
| return (value !== null && | ||
| value.lc === 1 && | ||
| value.type === "constructor" && | ||
| Array.isArray(value.id)); | ||
| return value !== null && value.lc === 1 && value.type === "constructor" && Array.isArray(value.id); | ||
| } | ||
| /** | ||
| * The replacer in stringify does not allow delegation to built-in LangChain | ||
| * serialization methods, and instead immediately calls `.toJSON()` and | ||
| * continues to stringify subfields. | ||
| * | ||
| * We therefore must start from the most nested elements in the input and | ||
| * deserialize upwards rather than top-down. | ||
| */ | ||
| * The replacer in stringify does not allow delegation to built-in LangChain | ||
| * serialization methods, and instead immediately calls `.toJSON()` and | ||
| * continues to stringify subfields. | ||
| * | ||
| * We therefore must start from the most nested elements in the input and | ||
| * deserialize upwards rather than top-down. | ||
| */ | ||
| async function _reviver(value) { | ||
| if (value && typeof value === "object") { | ||
| if (Array.isArray(value)) { | ||
| const revivedArray = await Promise.all(value.map((item) => _reviver(item))); | ||
| return revivedArray; | ||
| } | ||
| else { | ||
| const revivedObj = {}; | ||
| for (const [k, v] of Object.entries(value)) { | ||
| revivedObj[k] = await _reviver(v); | ||
| } | ||
| if (revivedObj.lc === 2 && revivedObj.type === "undefined") { | ||
| return undefined; | ||
| } | ||
| else if (revivedObj.lc === 2 && | ||
| revivedObj.type === "constructor" && | ||
| Array.isArray(revivedObj.id)) { | ||
| try { | ||
| const constructorName = revivedObj.id[revivedObj.id.length - 1]; | ||
| let constructor; | ||
| switch (constructorName) { | ||
| case "Set": | ||
| constructor = Set; | ||
| break; | ||
| case "Map": | ||
| constructor = Map; | ||
| break; | ||
| case "RegExp": | ||
| constructor = RegExp; | ||
| break; | ||
| case "Error": | ||
| constructor = Error; | ||
| break; | ||
| default: | ||
| return revivedObj; | ||
| } | ||
| if (revivedObj.method) { | ||
| return constructor[revivedObj.method](...(revivedObj.args || [])); | ||
| } | ||
| else { | ||
| return new constructor(...(revivedObj.args || [])); | ||
| } | ||
| } | ||
| catch (error) { | ||
| return revivedObj; | ||
| } | ||
| } | ||
| else if (isLangChainSerializedObject(revivedObj)) { | ||
| return load(JSON.stringify(revivedObj)); | ||
| } | ||
| return revivedObj; | ||
| } | ||
| } | ||
| return value; | ||
| if (value && typeof value === "object") if (Array.isArray(value)) { | ||
| const revivedArray = await Promise.all(value.map((item) => _reviver(item))); | ||
| return revivedArray; | ||
| } else { | ||
| const revivedObj = {}; | ||
| for (const [k, v] of Object.entries(value)) revivedObj[k] = await _reviver(v); | ||
| if (revivedObj.lc === 2 && revivedObj.type === "undefined") return void 0; | ||
| else if (revivedObj.lc === 2 && revivedObj.type === "constructor" && Array.isArray(revivedObj.id)) try { | ||
| const constructorName = revivedObj.id[revivedObj.id.length - 1]; | ||
| let constructor; | ||
| switch (constructorName) { | ||
| case "Set": | ||
| constructor = Set; | ||
| break; | ||
| case "Map": | ||
| constructor = Map; | ||
| break; | ||
| case "RegExp": | ||
| constructor = RegExp; | ||
| break; | ||
| case "Error": | ||
| constructor = Error; | ||
| break; | ||
| default: return revivedObj; | ||
| } | ||
| if (revivedObj.method) return constructor[revivedObj.method](...revivedObj.args || []); | ||
| else return new constructor(...revivedObj.args || []); | ||
| } catch (error) { | ||
| return revivedObj; | ||
| } | ||
| else if (isLangChainSerializedObject(revivedObj)) return load(JSON.stringify(revivedObj)); | ||
| return revivedObj; | ||
| } | ||
| return value; | ||
| } | ||
| function _encodeConstructorArgs( | ||
| // eslint-disable-next-line @typescript-eslint/ban-types | ||
| constructor, method, args, kwargs) { | ||
| return { | ||
| lc: 2, | ||
| type: "constructor", | ||
| id: [constructor.name], | ||
| method: method ?? null, | ||
| args: args ?? [], | ||
| kwargs: kwargs ?? {}, | ||
| }; | ||
| function _encodeConstructorArgs(constructor, method, args, kwargs) { | ||
| return { | ||
| lc: 2, | ||
| type: "constructor", | ||
| id: [constructor.name], | ||
| method: method ?? null, | ||
| args: args ?? [], | ||
| kwargs: kwargs ?? {} | ||
| }; | ||
| } | ||
| function _default(obj) { | ||
| if (obj === undefined) { | ||
| return { | ||
| lc: 2, | ||
| type: "undefined", | ||
| }; | ||
| } | ||
| else if (obj instanceof Set || obj instanceof Map) { | ||
| return _encodeConstructorArgs(obj.constructor, undefined, [ | ||
| Array.from(obj), | ||
| ]); | ||
| } | ||
| else if (obj instanceof RegExp) { | ||
| return _encodeConstructorArgs(RegExp, undefined, [obj.source, obj.flags]); | ||
| } | ||
| else if (obj instanceof Error) { | ||
| return _encodeConstructorArgs(obj.constructor, undefined, [obj.message]); | ||
| // TODO: Remove special case | ||
| } | ||
| else if (obj?.lg_name === "Send") { | ||
| return { | ||
| node: obj.node, | ||
| args: obj.args, | ||
| }; | ||
| } | ||
| else { | ||
| return obj; | ||
| } | ||
| if (obj === void 0) return { | ||
| lc: 2, | ||
| type: "undefined" | ||
| }; | ||
| else if (obj instanceof Set || obj instanceof Map) return _encodeConstructorArgs(obj.constructor, void 0, [Array.from(obj)]); | ||
| else if (obj instanceof RegExp) return _encodeConstructorArgs(RegExp, void 0, [obj.source, obj.flags]); | ||
| else if (obj instanceof Error) return _encodeConstructorArgs(obj.constructor, void 0, [obj.message]); | ||
| else if (obj?.lg_name === "Send") return { | ||
| node: obj.node, | ||
| args: obj.args | ||
| }; | ||
| else return obj; | ||
| } | ||
| export class JsonPlusSerializer { | ||
| _dumps(obj) { | ||
| const encoder = new TextEncoder(); | ||
| return encoder.encode(stringify(obj, (_, value) => { | ||
| return _default(value); | ||
| })); | ||
| } | ||
| async dumpsTyped(obj) { | ||
| if (obj instanceof Uint8Array) { | ||
| return ["bytes", obj]; | ||
| } | ||
| else { | ||
| return ["json", this._dumps(obj)]; | ||
| } | ||
| } | ||
| async _loads(data) { | ||
| const parsed = JSON.parse(data); | ||
| return _reviver(parsed); | ||
| } | ||
| async loadsTyped(type, data) { | ||
| if (type === "bytes") { | ||
| return typeof data === "string" ? new TextEncoder().encode(data) : data; | ||
| } | ||
| else if (type === "json") { | ||
| return this._loads(typeof data === "string" ? data : new TextDecoder().decode(data)); | ||
| } | ||
| else { | ||
| throw new Error(`Unknown serialization type: ${type}`); | ||
| } | ||
| } | ||
| } | ||
| var JsonPlusSerializer = class { | ||
| _dumps(obj) { | ||
| const encoder = new TextEncoder(); | ||
| return encoder.encode(stringify(obj, (_, value) => { | ||
| return _default(value); | ||
| })); | ||
| } | ||
| async dumpsTyped(obj) { | ||
| if (obj instanceof Uint8Array) return ["bytes", obj]; | ||
| else return ["json", this._dumps(obj)]; | ||
| } | ||
| async _loads(data) { | ||
| const parsed = JSON.parse(data); | ||
| return _reviver(parsed); | ||
| } | ||
| async loadsTyped(type, data) { | ||
| if (type === "bytes") return typeof data === "string" ? new TextEncoder().encode(data) : data; | ||
| else if (type === "json") return this._loads(typeof data === "string" ? data : new TextDecoder().decode(data)); | ||
| else throw new Error(`Unknown serialization type: ${type}`); | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { JsonPlusSerializer }; | ||
| //# sourceMappingURL=jsonplus.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"jsonplus.js","sourceRoot":"","sources":["../../src/serde/jsonplus.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"jsonplus.js","names":["revivedObj: any","constructor: any"],"sources":["../../src/serde/jsonplus.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable no-instanceof/no-instanceof */\nimport { load } from \"@langchain/core/load\";\nimport { SerializerProtocol } from \"./base.js\";\nimport { stringify } from \"./utils/fast-safe-stringify/index.js\";\n\nfunction isLangChainSerializedObject(value: Record<string, unknown>) {\n return (\n value !== null &&\n value.lc === 1 &&\n value.type === \"constructor\" &&\n Array.isArray(value.id)\n );\n}\n\n/**\n * The replacer in stringify does not allow delegation to built-in LangChain\n * serialization methods, and instead immediately calls `.toJSON()` and\n * continues to stringify subfields.\n *\n * We therefore must start from the most nested elements in the input and\n * deserialize upwards rather than top-down.\n */\nasync function _reviver(value: any): Promise<any> {\n if (value && typeof value === \"object\") {\n if (Array.isArray(value)) {\n const revivedArray = await Promise.all(\n value.map((item) => _reviver(item))\n );\n return revivedArray;\n } else {\n const revivedObj: any = {};\n for (const [k, v] of Object.entries(value)) {\n revivedObj[k] = await _reviver(v);\n }\n\n if (revivedObj.lc === 2 && revivedObj.type === \"undefined\") {\n return undefined;\n } else if (\n revivedObj.lc === 2 &&\n revivedObj.type === \"constructor\" &&\n Array.isArray(revivedObj.id)\n ) {\n try {\n const constructorName = revivedObj.id[revivedObj.id.length - 1];\n let constructor: any;\n\n switch (constructorName) {\n case \"Set\":\n constructor = Set;\n break;\n case \"Map\":\n constructor = Map;\n break;\n case \"RegExp\":\n constructor = RegExp;\n break;\n case \"Error\":\n constructor = Error;\n break;\n default:\n return revivedObj;\n }\n if (revivedObj.method) {\n return (constructor as any)[revivedObj.method](\n ...(revivedObj.args || [])\n );\n } else {\n return new (constructor as any)(...(revivedObj.args || []));\n }\n } catch (error) {\n return revivedObj;\n }\n } else if (isLangChainSerializedObject(revivedObj)) {\n return load(JSON.stringify(revivedObj));\n }\n\n return revivedObj;\n }\n }\n return value;\n}\n\nfunction _encodeConstructorArgs(\n // eslint-disable-next-line @typescript-eslint/ban-types\n constructor: Function,\n method?: string,\n args?: any[],\n kwargs?: Record<string, any>\n): object {\n return {\n lc: 2,\n type: \"constructor\",\n id: [constructor.name],\n method: method ?? null,\n args: args ?? [],\n kwargs: kwargs ?? {},\n };\n}\n\nfunction _default(obj: any): any {\n if (obj === undefined) {\n return {\n lc: 2,\n type: \"undefined\",\n };\n } else if (obj instanceof Set || obj instanceof Map) {\n return _encodeConstructorArgs(obj.constructor, undefined, [\n Array.from(obj),\n ]);\n } else if (obj instanceof RegExp) {\n return _encodeConstructorArgs(RegExp, undefined, [obj.source, obj.flags]);\n } else if (obj instanceof Error) {\n return _encodeConstructorArgs(obj.constructor, undefined, [obj.message]);\n // TODO: Remove special case\n } else if (obj?.lg_name === \"Send\") {\n return {\n node: obj.node,\n args: obj.args,\n };\n } else {\n return obj;\n }\n}\n\nexport class JsonPlusSerializer implements SerializerProtocol {\n protected _dumps(obj: any): Uint8Array {\n const encoder = new TextEncoder();\n return encoder.encode(\n stringify(obj, (_: string, value: any) => {\n return _default(value);\n })\n );\n }\n\n async dumpsTyped(obj: any): Promise<[string, Uint8Array]> {\n if (obj instanceof Uint8Array) {\n return [\"bytes\", obj];\n } else {\n return [\"json\", this._dumps(obj)];\n }\n }\n\n protected async _loads(data: string): Promise<any> {\n const parsed = JSON.parse(data);\n return _reviver(parsed);\n }\n\n async loadsTyped(type: string, data: Uint8Array | string): Promise<any> {\n if (type === \"bytes\") {\n return typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n } else if (type === \"json\") {\n return this._loads(\n typeof data === \"string\" ? data : new TextDecoder().decode(data)\n );\n } else {\n throw new Error(`Unknown serialization type: ${type}`);\n }\n }\n}\n"],"mappings":";;;;AAMA,SAAS,4BAA4B,OAAgC;AACnE,QACE,UAAU,QACV,MAAM,OAAO,KACb,MAAM,SAAS,iBACf,MAAM,QAAQ,MAAM;;;;;;;;;;AAYxB,eAAe,SAAS,OAA0B;AAChD,KAAI,SAAS,OAAO,UAAU,SAC5B,KAAI,MAAM,QAAQ,QAAQ;EACxB,MAAM,eAAe,MAAM,QAAQ,IACjC,MAAM,KAAK,SAAS,SAAS;AAE/B,SAAO;QACF;EACL,MAAMA,aAAkB;AACxB,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,OAClC,YAAW,KAAK,MAAM,SAAS;AAGjC,MAAI,WAAW,OAAO,KAAK,WAAW,SAAS,YAC7C,QAAO;WAEP,WAAW,OAAO,KAClB,WAAW,SAAS,iBACpB,MAAM,QAAQ,WAAW,IAEzB,KAAI;GACF,MAAM,kBAAkB,WAAW,GAAG,WAAW,GAAG,SAAS;GAC7D,IAAIC;AAEJ,WAAQ,iBAAR;IACE,KAAK;AACH,mBAAc;AACd;IACF,KAAK;AACH,mBAAc;AACd;IACF,KAAK;AACH,mBAAc;AACd;IACF,KAAK;AACH,mBAAc;AACd;IACF,QACE,QAAO;;AAEX,OAAI,WAAW,OACb,QAAQ,YAAoB,WAAW,QACrC,GAAI,WAAW,QAAQ;OAGzB,QAAO,IAAK,YAAoB,GAAI,WAAW,QAAQ;WAElD,OAAO;AACd,UAAO;;WAEA,4BAA4B,YACrC,QAAO,KAAK,KAAK,UAAU;AAG7B,SAAO;;AAGX,QAAO;;AAGT,SAAS,uBAEP,aACA,QACA,MACA,QACQ;AACR,QAAO;EACL,IAAI;EACJ,MAAM;EACN,IAAI,CAAC,YAAY;EACjB,QAAQ,UAAU;EAClB,MAAM,QAAQ;EACd,QAAQ,UAAU;;;AAItB,SAAS,SAAS,KAAe;AAC/B,KAAI,QAAQ,OACV,QAAO;EACL,IAAI;EACJ,MAAM;;UAEC,eAAe,OAAO,eAAe,IAC9C,QAAO,uBAAuB,IAAI,aAAa,QAAW,CACxD,MAAM,KAAK;UAEJ,eAAe,OACxB,QAAO,uBAAuB,QAAQ,QAAW,CAAC,IAAI,QAAQ,IAAI;UACzD,eAAe,MACxB,QAAO,uBAAuB,IAAI,aAAa,QAAW,CAAC,IAAI;UAEtD,KAAK,YAAY,OAC1B,QAAO;EACL,MAAM,IAAI;EACV,MAAM,IAAI;;KAGZ,QAAO;;AAIX,IAAa,qBAAb,MAA8D;CAC5D,AAAU,OAAO,KAAsB;EACrC,MAAM,UAAU,IAAI;AACpB,SAAO,QAAQ,OACb,UAAU,MAAM,GAAW,UAAe;AACxC,UAAO,SAAS;;;CAKtB,MAAM,WAAW,KAAyC;AACxD,MAAI,eAAe,WACjB,QAAO,CAAC,SAAS;MAEjB,QAAO,CAAC,QAAQ,KAAK,OAAO;;CAIhC,MAAgB,OAAO,MAA4B;EACjD,MAAM,SAAS,KAAK,MAAM;AAC1B,SAAO,SAAS;;CAGlB,MAAM,WAAW,MAAc,MAAyC;AACtE,MAAI,SAAS,QACX,QAAO,OAAO,SAAS,WAAW,IAAI,cAAc,OAAO,QAAQ;WAC1D,SAAS,OAClB,QAAO,KAAK,OACV,OAAO,SAAS,WAAW,OAAO,IAAI,cAAc,OAAO;MAG7D,OAAM,IAAI,MAAM,+BAA+B"} |
+15
-9
@@ -1,9 +0,15 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.RESUME = exports.INTERRUPT = exports.SCHEDULED = exports.ERROR = exports.TASKS = void 0; | ||
| exports.TASKS = "__pregel_tasks"; | ||
| exports.ERROR = "__error__"; | ||
| exports.SCHEDULED = "__scheduled__"; | ||
| exports.INTERRUPT = "__interrupt__"; | ||
| exports.RESUME = "__resume__"; | ||
| //# sourceMappingURL=types.js.map | ||
| //#region src/serde/types.ts | ||
| const TASKS = "__pregel_tasks"; | ||
| const ERROR = "__error__"; | ||
| const SCHEDULED = "__scheduled__"; | ||
| const INTERRUPT = "__interrupt__"; | ||
| const RESUME = "__resume__"; | ||
| //#endregion | ||
| exports.ERROR = ERROR; | ||
| exports.INTERRUPT = INTERRUPT; | ||
| exports.RESUME = RESUME; | ||
| exports.SCHEDULED = SCHEDULED; | ||
| exports.TASKS = TASKS; | ||
| //# sourceMappingURL=types.cjs.map |
+53
-47
@@ -1,49 +0,55 @@ | ||
| export declare const TASKS = "__pregel_tasks"; | ||
| export declare const ERROR = "__error__"; | ||
| export declare const SCHEDULED = "__scheduled__"; | ||
| export declare const INTERRUPT = "__interrupt__"; | ||
| export declare const RESUME = "__resume__"; | ||
| export interface ChannelProtocol<ValueType = unknown, UpdateType = unknown, CheckpointType = unknown> { | ||
| ValueType: ValueType; | ||
| UpdateType: UpdateType; | ||
| /** | ||
| * The name of the channel. | ||
| */ | ||
| lc_graph_name: string; | ||
| /** | ||
| * Return a new identical channel, optionally initialized from a checkpoint. | ||
| * Can be thought of as a "restoration" from a checkpoint which is a "snapshot" of the channel's state. | ||
| * | ||
| * @param {CheckpointType | undefined} checkpoint | ||
| * @param {CheckpointType | undefined} initialValue | ||
| * @returns {this} | ||
| */ | ||
| fromCheckpoint(checkpoint?: CheckpointType): this; | ||
| /** | ||
| * Update the channel's value with the given sequence of updates. | ||
| * The order of the updates in the sequence is arbitrary. | ||
| * | ||
| * @throws {InvalidUpdateError} if the sequence of updates is invalid. | ||
| * @param {Array<UpdateType>} values | ||
| * @returns {void} | ||
| */ | ||
| update(values: UpdateType[]): void; | ||
| /** | ||
| * Return the current value of the channel. | ||
| * | ||
| * @throws {EmptyChannelError} if the channel is empty (never updated yet). | ||
| * @returns {ValueType} | ||
| */ | ||
| get(): ValueType; | ||
| /** | ||
| * Return a string representation of the channel's current state. | ||
| * | ||
| * @throws {EmptyChannelError} if the channel is empty (never updated yet), or doesn't support checkpoints. | ||
| * @returns {CheckpointType | undefined} | ||
| */ | ||
| checkpoint(): CheckpointType | undefined; | ||
| //#region src/serde/types.d.ts | ||
| declare const TASKS = "__pregel_tasks"; | ||
| declare const ERROR = "__error__"; | ||
| declare const SCHEDULED = "__scheduled__"; | ||
| declare const INTERRUPT = "__interrupt__"; | ||
| declare const RESUME = "__resume__"; | ||
| // Mirrors BaseChannel in "@langchain/langgraph" | ||
| interface ChannelProtocol<ValueType = unknown, UpdateType = unknown, CheckpointType = unknown> { | ||
| ValueType: ValueType; | ||
| UpdateType: UpdateType; | ||
| /** | ||
| * The name of the channel. | ||
| */ | ||
| lc_graph_name: string; | ||
| /** | ||
| * Return a new identical channel, optionally initialized from a checkpoint. | ||
| * Can be thought of as a "restoration" from a checkpoint which is a "snapshot" of the channel's state. | ||
| * | ||
| * @param {CheckpointType | undefined} checkpoint | ||
| * @returns {this} | ||
| */ | ||
| fromCheckpoint(checkpoint?: CheckpointType): this; | ||
| /** | ||
| * Update the channel's value with the given sequence of updates. | ||
| * The order of the updates in the sequence is arbitrary. | ||
| * | ||
| * @throws {InvalidUpdateError} if the sequence of updates is invalid. | ||
| * @param {Array<UpdateType>} values | ||
| * @returns {void} | ||
| */ | ||
| update(values: UpdateType[]): void; | ||
| /** | ||
| * Return the current value of the channel. | ||
| * | ||
| * @throws {EmptyChannelError} if the channel is empty (never updated yet). | ||
| * @returns {ValueType} | ||
| */ | ||
| get(): ValueType; | ||
| /** | ||
| * Return a string representation of the channel's current state. | ||
| * | ||
| * @throws {EmptyChannelError} if the channel is empty (never updated yet), or doesn't support checkpoints. | ||
| * @returns {CheckpointType | undefined} | ||
| */ | ||
| checkpoint(): CheckpointType | undefined; | ||
| } | ||
| export interface SendProtocol { | ||
| node: string; | ||
| args: any; | ||
| // Mirrors SendInterface in "@langchain/langgraph" | ||
| interface SendProtocol { | ||
| node: string; | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| args: any; | ||
| } | ||
| //#endregion | ||
| export { ChannelProtocol, ERROR, INTERRUPT, RESUME, SCHEDULED, SendProtocol, TASKS }; | ||
| //# sourceMappingURL=types.d.ts.map |
@@ -1,6 +0,10 @@ | ||
| export const TASKS = "__pregel_tasks"; | ||
| export const ERROR = "__error__"; | ||
| export const SCHEDULED = "__scheduled__"; | ||
| export const INTERRUPT = "__interrupt__"; | ||
| export const RESUME = "__resume__"; | ||
| //#region src/serde/types.ts | ||
| const TASKS = "__pregel_tasks"; | ||
| const ERROR = "__error__"; | ||
| const SCHEDULED = "__scheduled__"; | ||
| const INTERRUPT = "__interrupt__"; | ||
| const RESUME = "__resume__"; | ||
| //#endregion | ||
| export { ERROR, INTERRUPT, RESUME, SCHEDULED, TASKS }; | ||
| //# sourceMappingURL=types.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/serde/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,KAAK,GAAG,gBAAgB,CAAC;AACtC,MAAM,CAAC,MAAM,KAAK,GAAG,WAAW,CAAC;AACjC,MAAM,CAAC,MAAM,SAAS,GAAG,eAAe,CAAC;AACzC,MAAM,CAAC,MAAM,SAAS,GAAG,eAAe,CAAC;AACzC,MAAM,CAAC,MAAM,MAAM,GAAG,YAAY,CAAC"} | ||
| {"version":3,"file":"types.js","names":[],"sources":["../../src/serde/types.ts"],"sourcesContent":["export const TASKS = \"__pregel_tasks\";\nexport const ERROR = \"__error__\";\nexport const SCHEDULED = \"__scheduled__\";\nexport const INTERRUPT = \"__interrupt__\";\nexport const RESUME = \"__resume__\";\n\n// Mirrors BaseChannel in \"@langchain/langgraph\"\nexport interface ChannelProtocol<\n ValueType = unknown,\n UpdateType = unknown,\n CheckpointType = unknown\n> {\n ValueType: ValueType;\n\n UpdateType: UpdateType;\n\n /**\n * The name of the channel.\n */\n lc_graph_name: string;\n\n /**\n * Return a new identical channel, optionally initialized from a checkpoint.\n * Can be thought of as a \"restoration\" from a checkpoint which is a \"snapshot\" of the channel's state.\n *\n * @param {CheckpointType | undefined} checkpoint\n * @returns {this}\n */\n fromCheckpoint(checkpoint?: CheckpointType): this;\n\n /**\n * Update the channel's value with the given sequence of updates.\n * The order of the updates in the sequence is arbitrary.\n *\n * @throws {InvalidUpdateError} if the sequence of updates is invalid.\n * @param {Array<UpdateType>} values\n * @returns {void}\n */\n update(values: UpdateType[]): void;\n\n /**\n * Return the current value of the channel.\n *\n * @throws {EmptyChannelError} if the channel is empty (never updated yet).\n * @returns {ValueType}\n */\n get(): ValueType;\n\n /**\n * Return a string representation of the channel's current state.\n *\n * @throws {EmptyChannelError} if the channel is empty (never updated yet), or doesn't support checkpoints.\n * @returns {CheckpointType | undefined}\n */\n checkpoint(): CheckpointType | undefined;\n}\n\n// Mirrors SendInterface in \"@langchain/langgraph\"\nexport interface SendProtocol {\n node: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args: any;\n}\n"],"mappings":";AAAA,MAAa,QAAQ;AACrB,MAAa,QAAQ;AACrB,MAAa,YAAY;AACzB,MAAa,YAAY;AACzB,MAAa,SAAS"} |
@@ -1,9 +0,3 @@ | ||
| "use strict"; | ||
| /* eslint-disable */ | ||
| // @ts-nocheck | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.stringify = stringify; | ||
| // Stringify that can handle circular references. | ||
| // Inlined due to ESM import issues | ||
| // Source: https://www.npmjs.com/package/fast-safe-stringify | ||
| //#region src/serde/utils/fast-safe-stringify/index.ts | ||
| var LIMIT_REPLACE_NODE = "[...]"; | ||
@@ -14,210 +8,96 @@ var CIRCULAR_REPLACE_NODE = "[Circular]"; | ||
| function defaultOptions() { | ||
| return { | ||
| depthLimit: Number.MAX_SAFE_INTEGER, | ||
| edgesLimit: Number.MAX_SAFE_INTEGER, | ||
| }; | ||
| return { | ||
| depthLimit: Number.MAX_SAFE_INTEGER, | ||
| edgesLimit: Number.MAX_SAFE_INTEGER | ||
| }; | ||
| } | ||
| // Regular stringify | ||
| function stringify(obj, replacer, spacer, options) { | ||
| if (typeof options === "undefined") { | ||
| options = defaultOptions(); | ||
| } | ||
| decirc(obj, "", 0, [], undefined, 0, options); | ||
| var res; | ||
| try { | ||
| if (replacerStack.length === 0) { | ||
| res = JSON.stringify(obj, replacer, spacer); | ||
| } | ||
| else { | ||
| res = JSON.stringify(obj, replaceGetterValues(replacer), spacer); | ||
| } | ||
| } | ||
| catch (_) { | ||
| return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]"); | ||
| } | ||
| finally { | ||
| while (arr.length !== 0) { | ||
| var part = arr.pop(); | ||
| if (part.length === 4) { | ||
| Object.defineProperty(part[0], part[1], part[3]); | ||
| } | ||
| else { | ||
| part[0][part[1]] = part[2]; | ||
| } | ||
| } | ||
| } | ||
| return res; | ||
| if (typeof options === "undefined") options = defaultOptions(); | ||
| decirc(obj, "", 0, [], void 0, 0, options); | ||
| var res; | ||
| try { | ||
| if (replacerStack.length === 0) res = JSON.stringify(obj, replacer, spacer); | ||
| else res = JSON.stringify(obj, replaceGetterValues(replacer), spacer); | ||
| } catch (_) { | ||
| return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]"); | ||
| } finally { | ||
| while (arr.length !== 0) { | ||
| var part = arr.pop(); | ||
| if (part.length === 4) Object.defineProperty(part[0], part[1], part[3]); | ||
| else part[0][part[1]] = part[2]; | ||
| } | ||
| } | ||
| return res; | ||
| } | ||
| function setReplace(replace, val, k, parent) { | ||
| var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k); | ||
| if (propertyDescriptor.get !== undefined) { | ||
| if (propertyDescriptor.configurable) { | ||
| Object.defineProperty(parent, k, { value: replace }); | ||
| arr.push([parent, k, val, propertyDescriptor]); | ||
| } | ||
| else { | ||
| replacerStack.push([val, k, replace]); | ||
| } | ||
| } | ||
| else { | ||
| parent[k] = replace; | ||
| arr.push([parent, k, val]); | ||
| } | ||
| var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k); | ||
| if (propertyDescriptor.get !== void 0) if (propertyDescriptor.configurable) { | ||
| Object.defineProperty(parent, k, { value: replace }); | ||
| arr.push([ | ||
| parent, | ||
| k, | ||
| val, | ||
| propertyDescriptor | ||
| ]); | ||
| } else replacerStack.push([ | ||
| val, | ||
| k, | ||
| replace | ||
| ]); | ||
| else { | ||
| parent[k] = replace; | ||
| arr.push([ | ||
| parent, | ||
| k, | ||
| val | ||
| ]); | ||
| } | ||
| } | ||
| function decirc(val, k, edgeIndex, stack, parent, depth, options) { | ||
| depth += 1; | ||
| var i; | ||
| if (typeof val === "object" && val !== null) { | ||
| for (i = 0; i < stack.length; i++) { | ||
| if (stack[i] === val) { | ||
| setReplace(CIRCULAR_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| } | ||
| if (typeof options.depthLimit !== "undefined" && | ||
| depth > options.depthLimit) { | ||
| setReplace(LIMIT_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| if (typeof options.edgesLimit !== "undefined" && | ||
| edgeIndex + 1 > options.edgesLimit) { | ||
| setReplace(LIMIT_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| stack.push(val); | ||
| // Optimize for Arrays. Big arrays could kill the performance otherwise! | ||
| if (Array.isArray(val)) { | ||
| for (i = 0; i < val.length; i++) { | ||
| decirc(val[i], i, i, stack, val, depth, options); | ||
| } | ||
| } | ||
| else { | ||
| var keys = Object.keys(val); | ||
| for (i = 0; i < keys.length; i++) { | ||
| var key = keys[i]; | ||
| decirc(val[key], key, i, stack, val, depth, options); | ||
| } | ||
| } | ||
| stack.pop(); | ||
| } | ||
| depth += 1; | ||
| var i; | ||
| if (typeof val === "object" && val !== null) { | ||
| for (i = 0; i < stack.length; i++) if (stack[i] === val) { | ||
| setReplace(CIRCULAR_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| if (typeof options.depthLimit !== "undefined" && depth > options.depthLimit) { | ||
| setReplace(LIMIT_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| if (typeof options.edgesLimit !== "undefined" && edgeIndex + 1 > options.edgesLimit) { | ||
| setReplace(LIMIT_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| stack.push(val); | ||
| if (Array.isArray(val)) for (i = 0; i < val.length; i++) decirc(val[i], i, i, stack, val, depth, options); | ||
| else { | ||
| var keys = Object.keys(val); | ||
| for (i = 0; i < keys.length; i++) { | ||
| var key = keys[i]; | ||
| decirc(val[key], key, i, stack, val, depth, options); | ||
| } | ||
| } | ||
| stack.pop(); | ||
| } | ||
| } | ||
| // Stable-stringify | ||
| function compareFunction(a, b) { | ||
| if (a < b) { | ||
| return -1; | ||
| } | ||
| if (a > b) { | ||
| return 1; | ||
| } | ||
| return 0; | ||
| } | ||
| function deterministicStringify(obj, replacer, spacer, options) { | ||
| if (typeof options === "undefined") { | ||
| options = defaultOptions(); | ||
| } | ||
| var tmp = deterministicDecirc(obj, "", 0, [], undefined, 0, options) || obj; | ||
| var res; | ||
| try { | ||
| if (replacerStack.length === 0) { | ||
| res = JSON.stringify(tmp, replacer, spacer); | ||
| } | ||
| else { | ||
| res = JSON.stringify(tmp, replaceGetterValues(replacer), spacer); | ||
| } | ||
| } | ||
| catch (_) { | ||
| return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]"); | ||
| } | ||
| finally { | ||
| // Ensure that we restore the object as it was. | ||
| while (arr.length !== 0) { | ||
| var part = arr.pop(); | ||
| if (part.length === 4) { | ||
| Object.defineProperty(part[0], part[1], part[3]); | ||
| } | ||
| else { | ||
| part[0][part[1]] = part[2]; | ||
| } | ||
| } | ||
| } | ||
| return res; | ||
| } | ||
| function deterministicDecirc(val, k, edgeIndex, stack, parent, depth, options) { | ||
| depth += 1; | ||
| var i; | ||
| if (typeof val === "object" && val !== null) { | ||
| for (i = 0; i < stack.length; i++) { | ||
| if (stack[i] === val) { | ||
| setReplace(CIRCULAR_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| } | ||
| try { | ||
| if (typeof val.toJSON === "function") { | ||
| return; | ||
| } | ||
| } | ||
| catch (_) { | ||
| return; | ||
| } | ||
| if (typeof options.depthLimit !== "undefined" && | ||
| depth > options.depthLimit) { | ||
| setReplace(LIMIT_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| if (typeof options.edgesLimit !== "undefined" && | ||
| edgeIndex + 1 > options.edgesLimit) { | ||
| setReplace(LIMIT_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| stack.push(val); | ||
| // Optimize for Arrays. Big arrays could kill the performance otherwise! | ||
| if (Array.isArray(val)) { | ||
| for (i = 0; i < val.length; i++) { | ||
| deterministicDecirc(val[i], i, i, stack, val, depth, options); | ||
| } | ||
| } | ||
| else { | ||
| // Create a temporary object in the required way | ||
| var tmp = {}; | ||
| var keys = Object.keys(val).sort(compareFunction); | ||
| for (i = 0; i < keys.length; i++) { | ||
| var key = keys[i]; | ||
| deterministicDecirc(val[key], key, i, stack, val, depth, options); | ||
| tmp[key] = val[key]; | ||
| } | ||
| if (typeof parent !== "undefined") { | ||
| arr.push([parent, k, val]); | ||
| parent[k] = tmp; | ||
| } | ||
| else { | ||
| return tmp; | ||
| } | ||
| } | ||
| stack.pop(); | ||
| } | ||
| } | ||
| // wraps replacer function to handle values we couldn't replace | ||
| // and mark them as replaced value | ||
| function replaceGetterValues(replacer) { | ||
| replacer = | ||
| typeof replacer !== "undefined" | ||
| ? replacer | ||
| : function (k, v) { | ||
| return v; | ||
| }; | ||
| return function (key, val) { | ||
| if (replacerStack.length > 0) { | ||
| for (var i = 0; i < replacerStack.length; i++) { | ||
| var part = replacerStack[i]; | ||
| if (part[1] === key && part[0] === val) { | ||
| val = part[2]; | ||
| replacerStack.splice(i, 1); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| return replacer.call(this, key, val); | ||
| }; | ||
| replacer = typeof replacer !== "undefined" ? replacer : function(k, v) { | ||
| return v; | ||
| }; | ||
| return function(key, val) { | ||
| if (replacerStack.length > 0) for (var i = 0; i < replacerStack.length; i++) { | ||
| var part = replacerStack[i]; | ||
| if (part[1] === key && part[0] === val) { | ||
| val = part[2]; | ||
| replacerStack.splice(i, 1); | ||
| break; | ||
| } | ||
| } | ||
| return replacer.call(this, key, val); | ||
| }; | ||
| } | ||
| //# sourceMappingURL=index.js.map | ||
| //#endregion | ||
| exports.stringify = stringify; | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,6 +0,2 @@ | ||
| /* eslint-disable */ | ||
| // @ts-nocheck | ||
| // Stringify that can handle circular references. | ||
| // Inlined due to ESM import issues | ||
| // Source: https://www.npmjs.com/package/fast-safe-stringify | ||
| //#region src/serde/utils/fast-safe-stringify/index.ts | ||
| var LIMIT_REPLACE_NODE = "[...]"; | ||
@@ -11,210 +7,96 @@ var CIRCULAR_REPLACE_NODE = "[Circular]"; | ||
| function defaultOptions() { | ||
| return { | ||
| depthLimit: Number.MAX_SAFE_INTEGER, | ||
| edgesLimit: Number.MAX_SAFE_INTEGER, | ||
| }; | ||
| return { | ||
| depthLimit: Number.MAX_SAFE_INTEGER, | ||
| edgesLimit: Number.MAX_SAFE_INTEGER | ||
| }; | ||
| } | ||
| // Regular stringify | ||
| export function stringify(obj, replacer, spacer, options) { | ||
| if (typeof options === "undefined") { | ||
| options = defaultOptions(); | ||
| } | ||
| decirc(obj, "", 0, [], undefined, 0, options); | ||
| var res; | ||
| try { | ||
| if (replacerStack.length === 0) { | ||
| res = JSON.stringify(obj, replacer, spacer); | ||
| } | ||
| else { | ||
| res = JSON.stringify(obj, replaceGetterValues(replacer), spacer); | ||
| } | ||
| } | ||
| catch (_) { | ||
| return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]"); | ||
| } | ||
| finally { | ||
| while (arr.length !== 0) { | ||
| var part = arr.pop(); | ||
| if (part.length === 4) { | ||
| Object.defineProperty(part[0], part[1], part[3]); | ||
| } | ||
| else { | ||
| part[0][part[1]] = part[2]; | ||
| } | ||
| } | ||
| } | ||
| return res; | ||
| function stringify(obj, replacer, spacer, options) { | ||
| if (typeof options === "undefined") options = defaultOptions(); | ||
| decirc(obj, "", 0, [], void 0, 0, options); | ||
| var res; | ||
| try { | ||
| if (replacerStack.length === 0) res = JSON.stringify(obj, replacer, spacer); | ||
| else res = JSON.stringify(obj, replaceGetterValues(replacer), spacer); | ||
| } catch (_) { | ||
| return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]"); | ||
| } finally { | ||
| while (arr.length !== 0) { | ||
| var part = arr.pop(); | ||
| if (part.length === 4) Object.defineProperty(part[0], part[1], part[3]); | ||
| else part[0][part[1]] = part[2]; | ||
| } | ||
| } | ||
| return res; | ||
| } | ||
| function setReplace(replace, val, k, parent) { | ||
| var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k); | ||
| if (propertyDescriptor.get !== undefined) { | ||
| if (propertyDescriptor.configurable) { | ||
| Object.defineProperty(parent, k, { value: replace }); | ||
| arr.push([parent, k, val, propertyDescriptor]); | ||
| } | ||
| else { | ||
| replacerStack.push([val, k, replace]); | ||
| } | ||
| } | ||
| else { | ||
| parent[k] = replace; | ||
| arr.push([parent, k, val]); | ||
| } | ||
| var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k); | ||
| if (propertyDescriptor.get !== void 0) if (propertyDescriptor.configurable) { | ||
| Object.defineProperty(parent, k, { value: replace }); | ||
| arr.push([ | ||
| parent, | ||
| k, | ||
| val, | ||
| propertyDescriptor | ||
| ]); | ||
| } else replacerStack.push([ | ||
| val, | ||
| k, | ||
| replace | ||
| ]); | ||
| else { | ||
| parent[k] = replace; | ||
| arr.push([ | ||
| parent, | ||
| k, | ||
| val | ||
| ]); | ||
| } | ||
| } | ||
| function decirc(val, k, edgeIndex, stack, parent, depth, options) { | ||
| depth += 1; | ||
| var i; | ||
| if (typeof val === "object" && val !== null) { | ||
| for (i = 0; i < stack.length; i++) { | ||
| if (stack[i] === val) { | ||
| setReplace(CIRCULAR_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| } | ||
| if (typeof options.depthLimit !== "undefined" && | ||
| depth > options.depthLimit) { | ||
| setReplace(LIMIT_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| if (typeof options.edgesLimit !== "undefined" && | ||
| edgeIndex + 1 > options.edgesLimit) { | ||
| setReplace(LIMIT_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| stack.push(val); | ||
| // Optimize for Arrays. Big arrays could kill the performance otherwise! | ||
| if (Array.isArray(val)) { | ||
| for (i = 0; i < val.length; i++) { | ||
| decirc(val[i], i, i, stack, val, depth, options); | ||
| } | ||
| } | ||
| else { | ||
| var keys = Object.keys(val); | ||
| for (i = 0; i < keys.length; i++) { | ||
| var key = keys[i]; | ||
| decirc(val[key], key, i, stack, val, depth, options); | ||
| } | ||
| } | ||
| stack.pop(); | ||
| } | ||
| depth += 1; | ||
| var i; | ||
| if (typeof val === "object" && val !== null) { | ||
| for (i = 0; i < stack.length; i++) if (stack[i] === val) { | ||
| setReplace(CIRCULAR_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| if (typeof options.depthLimit !== "undefined" && depth > options.depthLimit) { | ||
| setReplace(LIMIT_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| if (typeof options.edgesLimit !== "undefined" && edgeIndex + 1 > options.edgesLimit) { | ||
| setReplace(LIMIT_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| stack.push(val); | ||
| if (Array.isArray(val)) for (i = 0; i < val.length; i++) decirc(val[i], i, i, stack, val, depth, options); | ||
| else { | ||
| var keys = Object.keys(val); | ||
| for (i = 0; i < keys.length; i++) { | ||
| var key = keys[i]; | ||
| decirc(val[key], key, i, stack, val, depth, options); | ||
| } | ||
| } | ||
| stack.pop(); | ||
| } | ||
| } | ||
| // Stable-stringify | ||
| function compareFunction(a, b) { | ||
| if (a < b) { | ||
| return -1; | ||
| } | ||
| if (a > b) { | ||
| return 1; | ||
| } | ||
| return 0; | ||
| } | ||
| function deterministicStringify(obj, replacer, spacer, options) { | ||
| if (typeof options === "undefined") { | ||
| options = defaultOptions(); | ||
| } | ||
| var tmp = deterministicDecirc(obj, "", 0, [], undefined, 0, options) || obj; | ||
| var res; | ||
| try { | ||
| if (replacerStack.length === 0) { | ||
| res = JSON.stringify(tmp, replacer, spacer); | ||
| } | ||
| else { | ||
| res = JSON.stringify(tmp, replaceGetterValues(replacer), spacer); | ||
| } | ||
| } | ||
| catch (_) { | ||
| return JSON.stringify("[unable to serialize, circular reference is too complex to analyze]"); | ||
| } | ||
| finally { | ||
| // Ensure that we restore the object as it was. | ||
| while (arr.length !== 0) { | ||
| var part = arr.pop(); | ||
| if (part.length === 4) { | ||
| Object.defineProperty(part[0], part[1], part[3]); | ||
| } | ||
| else { | ||
| part[0][part[1]] = part[2]; | ||
| } | ||
| } | ||
| } | ||
| return res; | ||
| } | ||
| function deterministicDecirc(val, k, edgeIndex, stack, parent, depth, options) { | ||
| depth += 1; | ||
| var i; | ||
| if (typeof val === "object" && val !== null) { | ||
| for (i = 0; i < stack.length; i++) { | ||
| if (stack[i] === val) { | ||
| setReplace(CIRCULAR_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| } | ||
| try { | ||
| if (typeof val.toJSON === "function") { | ||
| return; | ||
| } | ||
| } | ||
| catch (_) { | ||
| return; | ||
| } | ||
| if (typeof options.depthLimit !== "undefined" && | ||
| depth > options.depthLimit) { | ||
| setReplace(LIMIT_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| if (typeof options.edgesLimit !== "undefined" && | ||
| edgeIndex + 1 > options.edgesLimit) { | ||
| setReplace(LIMIT_REPLACE_NODE, val, k, parent); | ||
| return; | ||
| } | ||
| stack.push(val); | ||
| // Optimize for Arrays. Big arrays could kill the performance otherwise! | ||
| if (Array.isArray(val)) { | ||
| for (i = 0; i < val.length; i++) { | ||
| deterministicDecirc(val[i], i, i, stack, val, depth, options); | ||
| } | ||
| } | ||
| else { | ||
| // Create a temporary object in the required way | ||
| var tmp = {}; | ||
| var keys = Object.keys(val).sort(compareFunction); | ||
| for (i = 0; i < keys.length; i++) { | ||
| var key = keys[i]; | ||
| deterministicDecirc(val[key], key, i, stack, val, depth, options); | ||
| tmp[key] = val[key]; | ||
| } | ||
| if (typeof parent !== "undefined") { | ||
| arr.push([parent, k, val]); | ||
| parent[k] = tmp; | ||
| } | ||
| else { | ||
| return tmp; | ||
| } | ||
| } | ||
| stack.pop(); | ||
| } | ||
| } | ||
| // wraps replacer function to handle values we couldn't replace | ||
| // and mark them as replaced value | ||
| function replaceGetterValues(replacer) { | ||
| replacer = | ||
| typeof replacer !== "undefined" | ||
| ? replacer | ||
| : function (k, v) { | ||
| return v; | ||
| }; | ||
| return function (key, val) { | ||
| if (replacerStack.length > 0) { | ||
| for (var i = 0; i < replacerStack.length; i++) { | ||
| var part = replacerStack[i]; | ||
| if (part[1] === key && part[0] === val) { | ||
| val = part[2]; | ||
| replacerStack.splice(i, 1); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| return replacer.call(this, key, val); | ||
| }; | ||
| replacer = typeof replacer !== "undefined" ? replacer : function(k, v) { | ||
| return v; | ||
| }; | ||
| return function(key, val) { | ||
| if (replacerStack.length > 0) for (var i = 0; i < replacerStack.length; i++) { | ||
| var part = replacerStack[i]; | ||
| if (part[1] === key && part[0] === val) { | ||
| val = part[2]; | ||
| replacerStack.splice(i, 1); | ||
| break; | ||
| } | ||
| } | ||
| return replacer.call(this, key, val); | ||
| }; | ||
| } | ||
| //#endregion | ||
| export { stringify }; | ||
| //# sourceMappingURL=index.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/serde/utils/fast-safe-stringify/index.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"index.js","names":[],"sources":["../../../../src/serde/utils/fast-safe-stringify/index.ts"],"sourcesContent":["/* eslint-disable */\n// @ts-nocheck\n\n// Stringify that can handle circular references.\n// Inlined due to ESM import issues\n// Source: https://www.npmjs.com/package/fast-safe-stringify\n\nvar LIMIT_REPLACE_NODE = \"[...]\";\nvar CIRCULAR_REPLACE_NODE = \"[Circular]\";\n\nvar arr = [];\nvar replacerStack = [];\n\nfunction defaultOptions() {\n return {\n depthLimit: Number.MAX_SAFE_INTEGER,\n edgesLimit: Number.MAX_SAFE_INTEGER,\n };\n}\n\n// Regular stringify\nexport function stringify(obj, replacer?, spacer?, options?) {\n if (typeof options === \"undefined\") {\n options = defaultOptions();\n }\n\n decirc(obj, \"\", 0, [], undefined, 0, options);\n var res;\n try {\n if (replacerStack.length === 0) {\n res = JSON.stringify(obj, replacer, spacer);\n } else {\n res = JSON.stringify(obj, replaceGetterValues(replacer), spacer);\n }\n } catch (_) {\n return JSON.stringify(\n \"[unable to serialize, circular reference is too complex to analyze]\"\n );\n } finally {\n while (arr.length !== 0) {\n var part = arr.pop();\n if (part.length === 4) {\n Object.defineProperty(part[0], part[1], part[3]);\n } else {\n part[0][part[1]] = part[2];\n }\n }\n }\n return res;\n}\n\nfunction setReplace(replace, val, k, parent) {\n var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k);\n if (propertyDescriptor.get !== undefined) {\n if (propertyDescriptor.configurable) {\n Object.defineProperty(parent, k, { value: replace });\n arr.push([parent, k, val, propertyDescriptor]);\n } else {\n replacerStack.push([val, k, replace]);\n }\n } else {\n parent[k] = replace;\n arr.push([parent, k, val]);\n }\n}\n\nfunction decirc(val, k, edgeIndex, stack, parent, depth, options) {\n depth += 1;\n var i;\n if (typeof val === \"object\" && val !== null) {\n for (i = 0; i < stack.length; i++) {\n if (stack[i] === val) {\n setReplace(CIRCULAR_REPLACE_NODE, val, k, parent);\n return;\n }\n }\n\n if (\n typeof options.depthLimit !== \"undefined\" &&\n depth > options.depthLimit\n ) {\n setReplace(LIMIT_REPLACE_NODE, val, k, parent);\n return;\n }\n\n if (\n typeof options.edgesLimit !== \"undefined\" &&\n edgeIndex + 1 > options.edgesLimit\n ) {\n setReplace(LIMIT_REPLACE_NODE, val, k, parent);\n return;\n }\n\n stack.push(val);\n // Optimize for Arrays. Big arrays could kill the performance otherwise!\n if (Array.isArray(val)) {\n for (i = 0; i < val.length; i++) {\n decirc(val[i], i, i, stack, val, depth, options);\n }\n } else {\n var keys = Object.keys(val);\n for (i = 0; i < keys.length; i++) {\n var key = keys[i];\n decirc(val[key], key, i, stack, val, depth, options);\n }\n }\n stack.pop();\n }\n}\n\n// Stable-stringify\nfunction compareFunction(a, b) {\n if (a < b) {\n return -1;\n }\n if (a > b) {\n return 1;\n }\n return 0;\n}\n\nfunction deterministicStringify(obj, replacer, spacer, options) {\n if (typeof options === \"undefined\") {\n options = defaultOptions();\n }\n\n var tmp = deterministicDecirc(obj, \"\", 0, [], undefined, 0, options) || obj;\n var res;\n try {\n if (replacerStack.length === 0) {\n res = JSON.stringify(tmp, replacer, spacer);\n } else {\n res = JSON.stringify(tmp, replaceGetterValues(replacer), spacer);\n }\n } catch (_) {\n return JSON.stringify(\n \"[unable to serialize, circular reference is too complex to analyze]\"\n );\n } finally {\n // Ensure that we restore the object as it was.\n while (arr.length !== 0) {\n var part = arr.pop();\n if (part.length === 4) {\n Object.defineProperty(part[0], part[1], part[3]);\n } else {\n part[0][part[1]] = part[2];\n }\n }\n }\n return res;\n}\n\nfunction deterministicDecirc(val, k, edgeIndex, stack, parent, depth, options) {\n depth += 1;\n var i;\n if (typeof val === \"object\" && val !== null) {\n for (i = 0; i < stack.length; i++) {\n if (stack[i] === val) {\n setReplace(CIRCULAR_REPLACE_NODE, val, k, parent);\n return;\n }\n }\n try {\n if (typeof val.toJSON === \"function\") {\n return;\n }\n } catch (_) {\n return;\n }\n\n if (\n typeof options.depthLimit !== \"undefined\" &&\n depth > options.depthLimit\n ) {\n setReplace(LIMIT_REPLACE_NODE, val, k, parent);\n return;\n }\n\n if (\n typeof options.edgesLimit !== \"undefined\" &&\n edgeIndex + 1 > options.edgesLimit\n ) {\n setReplace(LIMIT_REPLACE_NODE, val, k, parent);\n return;\n }\n\n stack.push(val);\n // Optimize for Arrays. Big arrays could kill the performance otherwise!\n if (Array.isArray(val)) {\n for (i = 0; i < val.length; i++) {\n deterministicDecirc(val[i], i, i, stack, val, depth, options);\n }\n } else {\n // Create a temporary object in the required way\n var tmp = {};\n var keys = Object.keys(val).sort(compareFunction);\n for (i = 0; i < keys.length; i++) {\n var key = keys[i];\n deterministicDecirc(val[key], key, i, stack, val, depth, options);\n tmp[key] = val[key];\n }\n if (typeof parent !== \"undefined\") {\n arr.push([parent, k, val]);\n parent[k] = tmp;\n } else {\n return tmp;\n }\n }\n stack.pop();\n }\n}\n\n// wraps replacer function to handle values we couldn't replace\n// and mark them as replaced value\nfunction replaceGetterValues(replacer) {\n replacer =\n typeof replacer !== \"undefined\"\n ? replacer\n : function (k, v) {\n return v;\n };\n return function (key, val) {\n if (replacerStack.length > 0) {\n for (var i = 0; i < replacerStack.length; i++) {\n var part = replacerStack[i];\n if (part[1] === key && part[0] === val) {\n val = part[2];\n replacerStack.splice(i, 1);\n break;\n }\n }\n }\n return replacer.call(this, key, val);\n };\n}\n"],"mappings":";AAOA,IAAI,qBAAqB;AACzB,IAAI,wBAAwB;AAE5B,IAAI,MAAM;AACV,IAAI,gBAAgB;AAEpB,SAAS,iBAAiB;AACxB,QAAO;EACL,YAAY,OAAO;EACnB,YAAY,OAAO;;;AAKvB,SAAgB,UAAU,KAAK,UAAW,QAAS,SAAU;AAC3D,KAAI,OAAO,YAAY,YACrB,WAAU;AAGZ,QAAO,KAAK,IAAI,GAAG,IAAI,QAAW,GAAG;CACrC,IAAI;AACJ,KAAI;AACF,MAAI,cAAc,WAAW,EAC3B,OAAM,KAAK,UAAU,KAAK,UAAU;MAEpC,OAAM,KAAK,UAAU,KAAK,oBAAoB,WAAW;UAEpD,GAAG;AACV,SAAO,KAAK,UACV;WAEM;AACR,SAAO,IAAI,WAAW,GAAG;GACvB,IAAI,OAAO,IAAI;AACf,OAAI,KAAK,WAAW,EAClB,QAAO,eAAe,KAAK,IAAI,KAAK,IAAI,KAAK;OAE7C,MAAK,GAAG,KAAK,MAAM,KAAK;;;AAI9B,QAAO;;AAGT,SAAS,WAAW,SAAS,KAAK,GAAG,QAAQ;CAC3C,IAAI,qBAAqB,OAAO,yBAAyB,QAAQ;AACjE,KAAI,mBAAmB,QAAQ,OAC7B,KAAI,mBAAmB,cAAc;AACnC,SAAO,eAAe,QAAQ,GAAG,EAAE,OAAO;AAC1C,MAAI,KAAK;GAAC;GAAQ;GAAG;GAAK;;OAE1B,eAAc,KAAK;EAAC;EAAK;EAAG;;MAEzB;AACL,SAAO,KAAK;AACZ,MAAI,KAAK;GAAC;GAAQ;GAAG;;;;AAIzB,SAAS,OAAO,KAAK,GAAG,WAAW,OAAO,QAAQ,OAAO,SAAS;AAChE,UAAS;CACT,IAAI;AACJ,KAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,OAAK,IAAI,GAAG,IAAI,MAAM,QAAQ,IAC5B,KAAI,MAAM,OAAO,KAAK;AACpB,cAAW,uBAAuB,KAAK,GAAG;AAC1C;;AAIJ,MACE,OAAO,QAAQ,eAAe,eAC9B,QAAQ,QAAQ,YAChB;AACA,cAAW,oBAAoB,KAAK,GAAG;AACvC;;AAGF,MACE,OAAO,QAAQ,eAAe,eAC9B,YAAY,IAAI,QAAQ,YACxB;AACA,cAAW,oBAAoB,KAAK,GAAG;AACvC;;AAGF,QAAM,KAAK;AAEX,MAAI,MAAM,QAAQ,KAChB,MAAK,IAAI,GAAG,IAAI,IAAI,QAAQ,IAC1B,QAAO,IAAI,IAAI,GAAG,GAAG,OAAO,KAAK,OAAO;OAErC;GACL,IAAI,OAAO,OAAO,KAAK;AACvB,QAAK,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;IAChC,IAAI,MAAM,KAAK;AACf,WAAO,IAAI,MAAM,KAAK,GAAG,OAAO,KAAK,OAAO;;;AAGhD,QAAM;;;AA4GV,SAAS,oBAAoB,UAAU;AACrC,YACE,OAAO,aAAa,cAChB,WACA,SAAU,GAAG,GAAG;AACd,SAAO;;AAEf,QAAO,SAAU,KAAK,KAAK;AACzB,MAAI,cAAc,SAAS,EACzB,MAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;GAC7C,IAAI,OAAO,cAAc;AACzB,OAAI,KAAK,OAAO,OAAO,KAAK,OAAO,KAAK;AACtC,UAAM,KAAK;AACX,kBAAc,OAAO,GAAG;AACxB;;;AAIN,SAAO,SAAS,KAAK,MAAM,KAAK"} |
+200
-209
@@ -1,221 +0,212 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.BaseStore = exports.InvalidNamespaceError = void 0; | ||
| exports.getTextAtPath = getTextAtPath; | ||
| exports.tokenizePath = tokenizePath; | ||
| //#region src/store/base.ts | ||
| /** | ||
| * Error thrown when an invalid namespace is provided. | ||
| */ | ||
| class InvalidNamespaceError extends Error { | ||
| constructor(message) { | ||
| super(message); | ||
| this.name = "InvalidNamespaceError"; | ||
| } | ||
| } | ||
| exports.InvalidNamespaceError = InvalidNamespaceError; | ||
| * Error thrown when an invalid namespace is provided. | ||
| */ | ||
| var InvalidNamespaceError = class extends Error { | ||
| constructor(message) { | ||
| super(message); | ||
| this.name = "InvalidNamespaceError"; | ||
| } | ||
| }; | ||
| /** | ||
| * Validates the provided namespace. | ||
| * @param namespace The namespace to validate. | ||
| * @throws {InvalidNamespaceError} If the namespace is invalid. | ||
| */ | ||
| * Validates the provided namespace. | ||
| * @param namespace The namespace to validate. | ||
| * @throws {InvalidNamespaceError} If the namespace is invalid. | ||
| */ | ||
| function validateNamespace(namespace) { | ||
| if (namespace.length === 0) { | ||
| throw new InvalidNamespaceError("Namespace cannot be empty."); | ||
| } | ||
| for (const label of namespace) { | ||
| if (typeof label !== "string") { | ||
| throw new InvalidNamespaceError(`Invalid namespace label '${label}' found in ${namespace}. Namespace labels ` + | ||
| `must be strings, but got ${typeof label}.`); | ||
| } | ||
| if (label.includes(".")) { | ||
| throw new InvalidNamespaceError(`Invalid namespace label '${label}' found in ${namespace}. Namespace labels cannot contain periods ('.').`); | ||
| } | ||
| if (label === "") { | ||
| throw new InvalidNamespaceError(`Namespace labels cannot be empty strings. Got ${label} in ${namespace}`); | ||
| } | ||
| } | ||
| if (namespace[0] === "langgraph") { | ||
| throw new InvalidNamespaceError(`Root label for namespace cannot be "langgraph". Got: ${namespace}`); | ||
| } | ||
| if (namespace.length === 0) throw new InvalidNamespaceError("Namespace cannot be empty."); | ||
| for (const label of namespace) { | ||
| if (typeof label !== "string") throw new InvalidNamespaceError(`Invalid namespace label '${label}' found in ${namespace}. Namespace labels must be strings, but got ${typeof label}.`); | ||
| if (label.includes(".")) throw new InvalidNamespaceError(`Invalid namespace label '${label}' found in ${namespace}. Namespace labels cannot contain periods ('.').`); | ||
| if (label === "") throw new InvalidNamespaceError(`Namespace labels cannot be empty strings. Got ${label} in ${namespace}`); | ||
| } | ||
| if (namespace[0] === "langgraph") throw new InvalidNamespaceError(`Root label for namespace cannot be "langgraph". Got: ${namespace}`); | ||
| } | ||
| /** | ||
| * Utility function to get text at a specific JSON path | ||
| */ | ||
| * Utility function to get text at a specific JSON path | ||
| */ | ||
| function getTextAtPath(obj, path) { | ||
| const parts = path.split("."); | ||
| let current = obj; | ||
| for (const part of parts) { | ||
| if (part.includes("[")) { | ||
| const [arrayName, indexStr] = part.split("["); | ||
| const index = indexStr.replace("]", ""); | ||
| if (!current[arrayName]) | ||
| return []; | ||
| if (index === "*") { | ||
| const results = []; | ||
| for (const item of current[arrayName]) { | ||
| if (typeof item === "string") | ||
| results.push(item); | ||
| } | ||
| return results; | ||
| } | ||
| const idx = parseInt(index, 10); | ||
| if (Number.isNaN(idx)) | ||
| return []; | ||
| current = current[arrayName][idx]; | ||
| } | ||
| else { | ||
| current = current[part]; | ||
| } | ||
| if (current === undefined) | ||
| return []; | ||
| } | ||
| return typeof current === "string" ? [current] : []; | ||
| const parts = path.split("."); | ||
| let current = obj; | ||
| for (const part of parts) { | ||
| if (part.includes("[")) { | ||
| const [arrayName, indexStr] = part.split("["); | ||
| const index = indexStr.replace("]", ""); | ||
| if (!current[arrayName]) return []; | ||
| if (index === "*") { | ||
| const results = []; | ||
| for (const item of current[arrayName]) if (typeof item === "string") results.push(item); | ||
| return results; | ||
| } | ||
| const idx = parseInt(index, 10); | ||
| if (Number.isNaN(idx)) return []; | ||
| current = current[arrayName][idx]; | ||
| } else current = current[part]; | ||
| if (current === void 0) return []; | ||
| } | ||
| return typeof current === "string" ? [current] : []; | ||
| } | ||
| /** | ||
| * Tokenizes a JSON path into parts | ||
| */ | ||
| * Tokenizes a JSON path into parts | ||
| */ | ||
| function tokenizePath(path) { | ||
| return path.split("."); | ||
| return path.split("."); | ||
| } | ||
| /** | ||
| * Abstract base class for persistent key-value stores. | ||
| * | ||
| * Stores enable persistence and memory that can be shared across threads, | ||
| * scoped to user IDs, assistant IDs, or other arbitrary namespaces. | ||
| * | ||
| * Features: | ||
| * - Hierarchical namespaces for organization | ||
| * - Key-value storage with metadata | ||
| * - Vector similarity search (if configured) | ||
| * - Filtering and pagination | ||
| */ | ||
| class BaseStore { | ||
| /** | ||
| * Retrieve a single item by its namespace and key. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @returns Promise resolving to the item or null if not found | ||
| */ | ||
| async get(namespace, key) { | ||
| return (await this.batch([{ namespace, key }]))[0]; | ||
| } | ||
| /** | ||
| * Search for items within a namespace prefix. | ||
| * Supports both metadata filtering and vector similarity search. | ||
| * | ||
| * @param namespacePrefix Hierarchical path prefix to search within | ||
| * @param options Search options for filtering and pagination | ||
| * @returns Promise resolving to list of matching items with relevance scores | ||
| * | ||
| * @example | ||
| * // Search with filters | ||
| * await store.search(["documents"], { | ||
| * filter: { type: "report", status: "active" }, | ||
| * limit: 5, | ||
| * offset: 10 | ||
| * }); | ||
| * | ||
| * // Vector similarity search | ||
| * await store.search(["users", "content"], { | ||
| * query: "technical documentation about APIs", | ||
| * limit: 20 | ||
| * }); | ||
| */ | ||
| async search(namespacePrefix, options = {}) { | ||
| const { filter, limit = 10, offset = 0, query } = options; | ||
| return (await this.batch([ | ||
| { | ||
| namespacePrefix, | ||
| filter, | ||
| limit, | ||
| offset, | ||
| query, | ||
| }, | ||
| ]))[0]; | ||
| } | ||
| /** | ||
| * Store or update an item. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @param value Object containing the item's data | ||
| * @param index Optional indexing configuration | ||
| * | ||
| * @example | ||
| * // Simple storage | ||
| * await store.put(["docs"], "report", { title: "Annual Report" }); | ||
| * | ||
| * // With specific field indexing | ||
| * await store.put( | ||
| * ["docs"], | ||
| * "report", | ||
| * { | ||
| * title: "Q4 Report", | ||
| * chapters: [{ content: "..." }, { content: "..." }] | ||
| * }, | ||
| * ["title", "chapters[*].content"] | ||
| * ); | ||
| */ | ||
| async put(namespace, key, value, index) { | ||
| validateNamespace(namespace); | ||
| await this.batch([{ namespace, key, value, index }]); | ||
| } | ||
| /** | ||
| * Delete an item from the store. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| */ | ||
| async delete(namespace, key) { | ||
| await this.batch([{ namespace, key, value: null }]); | ||
| } | ||
| /** | ||
| * List and filter namespaces in the store. | ||
| * Used to explore data organization and navigate the namespace hierarchy. | ||
| * | ||
| * @param options Options for listing namespaces | ||
| * @returns Promise resolving to list of namespace paths | ||
| * | ||
| * @example | ||
| * // List all namespaces under "documents" | ||
| * await store.listNamespaces({ | ||
| * prefix: ["documents"], | ||
| * maxDepth: 2 | ||
| * }); | ||
| * | ||
| * // List namespaces ending with "v1" | ||
| * await store.listNamespaces({ | ||
| * suffix: ["v1"], | ||
| * limit: 50 | ||
| * }); | ||
| */ | ||
| async listNamespaces(options = {}) { | ||
| const { prefix, suffix, maxDepth, limit = 100, offset = 0 } = options; | ||
| const matchConditions = []; | ||
| if (prefix) { | ||
| matchConditions.push({ matchType: "prefix", path: prefix }); | ||
| } | ||
| if (suffix) { | ||
| matchConditions.push({ matchType: "suffix", path: suffix }); | ||
| } | ||
| return (await this.batch([ | ||
| { | ||
| matchConditions: matchConditions.length ? matchConditions : undefined, | ||
| maxDepth, | ||
| limit, | ||
| offset, | ||
| }, | ||
| ]))[0]; | ||
| } | ||
| /** | ||
| * Start the store. Override if initialization is needed. | ||
| */ | ||
| start() { } | ||
| /** | ||
| * Stop the store. Override if cleanup is needed. | ||
| */ | ||
| stop() { } | ||
| } | ||
| * Abstract base class for persistent key-value stores. | ||
| * | ||
| * Stores enable persistence and memory that can be shared across threads, | ||
| * scoped to user IDs, assistant IDs, or other arbitrary namespaces. | ||
| * | ||
| * Features: | ||
| * - Hierarchical namespaces for organization | ||
| * - Key-value storage with metadata | ||
| * - Vector similarity search (if configured) | ||
| * - Filtering and pagination | ||
| */ | ||
| var BaseStore = class { | ||
| /** | ||
| * Retrieve a single item by its namespace and key. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @returns Promise resolving to the item or null if not found | ||
| */ | ||
| async get(namespace, key) { | ||
| return (await this.batch([{ | ||
| namespace, | ||
| key | ||
| }]))[0]; | ||
| } | ||
| /** | ||
| * Search for items within a namespace prefix. | ||
| * Supports both metadata filtering and vector similarity search. | ||
| * | ||
| * @param namespacePrefix Hierarchical path prefix to search within | ||
| * @param options Search options for filtering and pagination | ||
| * @returns Promise resolving to list of matching items with relevance scores | ||
| * | ||
| * @example | ||
| * // Search with filters | ||
| * await store.search(["documents"], { | ||
| * filter: { type: "report", status: "active" }, | ||
| * limit: 5, | ||
| * offset: 10 | ||
| * }); | ||
| * | ||
| * // Vector similarity search | ||
| * await store.search(["users", "content"], { | ||
| * query: "technical documentation about APIs", | ||
| * limit: 20 | ||
| * }); | ||
| */ | ||
| async search(namespacePrefix, options = {}) { | ||
| const { filter, limit = 10, offset = 0, query } = options; | ||
| return (await this.batch([{ | ||
| namespacePrefix, | ||
| filter, | ||
| limit, | ||
| offset, | ||
| query | ||
| }]))[0]; | ||
| } | ||
| /** | ||
| * Store or update an item. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @param value Object containing the item's data | ||
| * @param index Optional indexing configuration | ||
| * | ||
| * @example | ||
| * // Simple storage | ||
| * await store.put(["docs"], "report", { title: "Annual Report" }); | ||
| * | ||
| * // With specific field indexing | ||
| * await store.put( | ||
| * ["docs"], | ||
| * "report", | ||
| * { | ||
| * title: "Q4 Report", | ||
| * chapters: [{ content: "..." }, { content: "..." }] | ||
| * }, | ||
| * ["title", "chapters[*].content"] | ||
| * ); | ||
| */ | ||
| async put(namespace, key, value, index) { | ||
| validateNamespace(namespace); | ||
| await this.batch([{ | ||
| namespace, | ||
| key, | ||
| value, | ||
| index | ||
| }]); | ||
| } | ||
| /** | ||
| * Delete an item from the store. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| */ | ||
| async delete(namespace, key) { | ||
| await this.batch([{ | ||
| namespace, | ||
| key, | ||
| value: null | ||
| }]); | ||
| } | ||
| /** | ||
| * List and filter namespaces in the store. | ||
| * Used to explore data organization and navigate the namespace hierarchy. | ||
| * | ||
| * @param options Options for listing namespaces | ||
| * @returns Promise resolving to list of namespace paths | ||
| * | ||
| * @example | ||
| * // List all namespaces under "documents" | ||
| * await store.listNamespaces({ | ||
| * prefix: ["documents"], | ||
| * maxDepth: 2 | ||
| * }); | ||
| * | ||
| * // List namespaces ending with "v1" | ||
| * await store.listNamespaces({ | ||
| * suffix: ["v1"], | ||
| * limit: 50 | ||
| * }); | ||
| */ | ||
| async listNamespaces(options = {}) { | ||
| const { prefix, suffix, maxDepth, limit = 100, offset = 0 } = options; | ||
| const matchConditions = []; | ||
| if (prefix) matchConditions.push({ | ||
| matchType: "prefix", | ||
| path: prefix | ||
| }); | ||
| if (suffix) matchConditions.push({ | ||
| matchType: "suffix", | ||
| path: suffix | ||
| }); | ||
| return (await this.batch([{ | ||
| matchConditions: matchConditions.length ? matchConditions : void 0, | ||
| maxDepth, | ||
| limit, | ||
| offset | ||
| }]))[0]; | ||
| } | ||
| /** | ||
| * Start the store. Override if initialization is needed. | ||
| */ | ||
| start() {} | ||
| /** | ||
| * Stop the store. Override if cleanup is needed. | ||
| */ | ||
| stop() {} | ||
| }; | ||
| //#endregion | ||
| exports.BaseStore = BaseStore; | ||
| //# sourceMappingURL=base.js.map | ||
| exports.InvalidNamespaceError = InvalidNamespaceError; | ||
| exports.getTextAtPath = getTextAtPath; | ||
| exports.tokenizePath = tokenizePath; | ||
| //# sourceMappingURL=base.cjs.map |
+336
-332
| import { Embeddings } from "@langchain/core/embeddings"; | ||
| //#region src/store/base.d.ts | ||
| /** | ||
| * Error thrown when an invalid namespace is provided. | ||
| */ | ||
| export declare class InvalidNamespaceError extends Error { | ||
| constructor(message: string); | ||
| declare class InvalidNamespaceError extends Error { | ||
| constructor(message: string); | ||
| } | ||
@@ -11,25 +14,25 @@ /** | ||
| */ | ||
| export interface Item { | ||
| /** | ||
| * The stored data as an object. Keys are filterable. | ||
| */ | ||
| value: Record<string, any>; | ||
| /** | ||
| * Unique identifier within the namespace. | ||
| */ | ||
| key: string; | ||
| /** | ||
| * Hierarchical path defining the collection in which this document resides. | ||
| * Represented as an array of strings, allowing for nested categorization. | ||
| * For example: ["documents", "user123"] | ||
| */ | ||
| namespace: string[]; | ||
| /** | ||
| * Timestamp of item creation. | ||
| */ | ||
| createdAt: Date; | ||
| /** | ||
| * Timestamp of last update. | ||
| */ | ||
| updatedAt: Date; | ||
| interface Item { | ||
| /** | ||
| * The stored data as an object. Keys are filterable. | ||
| */ | ||
| value: Record<string, any>; | ||
| /** | ||
| * Unique identifier within the namespace. | ||
| */ | ||
| key: string; | ||
| /** | ||
| * Hierarchical path defining the collection in which this document resides. | ||
| * Represented as an array of strings, allowing for nested categorization. | ||
| * For example: ["documents", "user123"] | ||
| */ | ||
| namespace: string[]; | ||
| /** | ||
| * Timestamp of item creation. | ||
| */ | ||
| createdAt: Date; | ||
| /** | ||
| * Timestamp of last update. | ||
| */ | ||
| updatedAt: Date; | ||
| } | ||
@@ -40,11 +43,11 @@ /** | ||
| */ | ||
| export interface SearchItem extends Item { | ||
| /** | ||
| * Relevance/similarity score if from a ranked operation. | ||
| * Higher scores indicate better matches. | ||
| * | ||
| * This is typically a cosine similarity score between -1 and 1, | ||
| * where 1 indicates identical vectors and -1 indicates opposite vectors. | ||
| */ | ||
| score?: number; | ||
| interface SearchItem extends Item { | ||
| /** | ||
| * Relevance/similarity score if from a ranked operation. | ||
| * Higher scores indicate better matches. | ||
| * | ||
| * This is typically a cosine similarity score between -1 and 1, | ||
| * where 1 indicates identical vectors and -1 indicates opposite vectors. | ||
| */ | ||
| score?: number; | ||
| } | ||
@@ -54,20 +57,20 @@ /** | ||
| */ | ||
| export interface GetOperation { | ||
| /** | ||
| * Hierarchical path for the item. | ||
| * | ||
| * @example | ||
| * // Get a user profile | ||
| * namespace: ["users", "profiles"] | ||
| */ | ||
| namespace: string[]; | ||
| /** | ||
| * Unique identifier within the namespace. | ||
| * Together with namespace forms the complete path to the item. | ||
| * | ||
| * @example | ||
| * key: "user123" // For a user profile | ||
| * key: "doc456" // For a document | ||
| */ | ||
| key: string; | ||
| interface GetOperation { | ||
| /** | ||
| * Hierarchical path for the item. | ||
| * | ||
| * @example | ||
| * // Get a user profile | ||
| * namespace: ["users", "profiles"] | ||
| */ | ||
| namespace: string[]; | ||
| /** | ||
| * Unique identifier within the namespace. | ||
| * Together with namespace forms the complete path to the item. | ||
| * | ||
| * @example | ||
| * key: "user123" // For a user profile | ||
| * key: "doc456" // For a document | ||
| */ | ||
| key: string; | ||
| } | ||
@@ -77,64 +80,64 @@ /** | ||
| */ | ||
| export interface SearchOperation { | ||
| /** | ||
| * Hierarchical path prefix to search within. | ||
| * Only items under this prefix will be searched. | ||
| * | ||
| * @example | ||
| * // Search all user documents | ||
| * namespacePrefix: ["users", "documents"] | ||
| * | ||
| * // Search everything | ||
| * namespacePrefix: [] | ||
| */ | ||
| namespacePrefix: string[]; | ||
| /** | ||
| * Key-value pairs to filter results based on exact matches or comparison operators. | ||
| * | ||
| * Supports both exact matches and operator-based comparisons: | ||
| * - $eq: Equal to (same as direct value comparison) | ||
| * - $ne: Not equal to | ||
| * - $gt: Greater than | ||
| * - $gte: Greater than or equal to | ||
| * - $lt: Less than | ||
| * - $lte: Less than or equal to | ||
| * | ||
| * @example | ||
| * // Exact match | ||
| * filter: { status: "active" } | ||
| * | ||
| * // With operators | ||
| * filter: { score: { $gt: 4.99 } } | ||
| * | ||
| * // Multiple conditions | ||
| * filter: { | ||
| * score: { $gte: 3.0 }, | ||
| * color: "red" | ||
| * } | ||
| */ | ||
| filter?: Record<string, any>; | ||
| /** | ||
| * Maximum number of items to return. | ||
| * @default 10 | ||
| */ | ||
| limit?: number; | ||
| /** | ||
| * Number of items to skip before returning results. | ||
| * Useful for pagination. | ||
| * @default 0 | ||
| */ | ||
| offset?: number; | ||
| /** | ||
| * Natural language search query for semantic search. | ||
| * When provided, results will be ranked by relevance to this query | ||
| * using vector similarity search. | ||
| * | ||
| * @example | ||
| * // Find technical documentation about APIs | ||
| * query: "technical documentation about REST APIs" | ||
| * | ||
| * // Find recent ML papers | ||
| * query: "machine learning papers from 2023" | ||
| */ | ||
| query?: string; | ||
| interface SearchOperation { | ||
| /** | ||
| * Hierarchical path prefix to search within. | ||
| * Only items under this prefix will be searched. | ||
| * | ||
| * @example | ||
| * // Search all user documents | ||
| * namespacePrefix: ["users", "documents"] | ||
| * | ||
| * // Search everything | ||
| * namespacePrefix: [] | ||
| */ | ||
| namespacePrefix: string[]; | ||
| /** | ||
| * Key-value pairs to filter results based on exact matches or comparison operators. | ||
| * | ||
| * Supports both exact matches and operator-based comparisons: | ||
| * - $eq: Equal to (same as direct value comparison) | ||
| * - $ne: Not equal to | ||
| * - $gt: Greater than | ||
| * - $gte: Greater than or equal to | ||
| * - $lt: Less than | ||
| * - $lte: Less than or equal to | ||
| * | ||
| * @example | ||
| * // Exact match | ||
| * filter: { status: "active" } | ||
| * | ||
| * // With operators | ||
| * filter: { score: { $gt: 4.99 } } | ||
| * | ||
| * // Multiple conditions | ||
| * filter: { | ||
| * score: { $gte: 3.0 }, | ||
| * color: "red" | ||
| * } | ||
| */ | ||
| filter?: Record<string, any>; | ||
| /** | ||
| * Maximum number of items to return. | ||
| * @default 10 | ||
| */ | ||
| limit?: number; | ||
| /** | ||
| * Number of items to skip before returning results. | ||
| * Useful for pagination. | ||
| * @default 0 | ||
| */ | ||
| offset?: number; | ||
| /** | ||
| * Natural language search query for semantic search. | ||
| * When provided, results will be ranked by relevance to this query | ||
| * using vector similarity search. | ||
| * | ||
| * @example | ||
| * // Find technical documentation about APIs | ||
| * query: "technical documentation about REST APIs" | ||
| * | ||
| * // Find recent ML papers | ||
| * query: "machine learning papers from 2023" | ||
| */ | ||
| query?: string; | ||
| } | ||
@@ -144,60 +147,60 @@ /** | ||
| */ | ||
| export interface PutOperation { | ||
| /** | ||
| * Hierarchical path for the item. | ||
| * Acts as a folder-like structure to organize items. | ||
| * Each element represents one level in the hierarchy. | ||
| * | ||
| * @example | ||
| * // Root level documents | ||
| * namespace: ["documents"] | ||
| * | ||
| * // User-specific documents | ||
| * namespace: ["documents", "user123"] | ||
| * | ||
| * // Nested cache structure | ||
| * namespace: ["cache", "docs", "v1"] | ||
| */ | ||
| namespace: string[]; | ||
| /** | ||
| * Unique identifier for the document within its namespace. | ||
| * Together with namespace forms the complete path to the item. | ||
| * | ||
| * Example: If namespace is ["documents", "user123"] and key is "report1", | ||
| * the full path would effectively be "documents/user123/report1" | ||
| */ | ||
| key: string; | ||
| /** | ||
| * Data to be stored, or null to delete the item. | ||
| * Must be a JSON-serializable object with string keys. | ||
| * Setting to null signals that the item should be deleted. | ||
| * | ||
| * @example | ||
| * { | ||
| * field1: "string value", | ||
| * field2: 123, | ||
| * nested: { can: "contain", any: "serializable data" } | ||
| * } | ||
| */ | ||
| value: Record<string, any> | null; | ||
| /** | ||
| * Controls how the item's fields are indexed for search operations. | ||
| * | ||
| * - undefined: Uses store's default indexing configuration | ||
| * - false: Disables indexing for this item | ||
| * - string[]: List of field paths to index | ||
| * | ||
| * Path syntax supports: | ||
| * - Nested fields: "metadata.title" | ||
| * - Array access: "chapters[*].content" (each indexed separately) | ||
| * - Specific indices: "authors[0].name" | ||
| * | ||
| * @example | ||
| * // Index specific fields | ||
| * index: ["metadata.title", "chapters[*].content"] | ||
| * | ||
| * // Disable indexing | ||
| * index: false | ||
| */ | ||
| index?: false | string[]; | ||
| interface PutOperation { | ||
| /** | ||
| * Hierarchical path for the item. | ||
| * Acts as a folder-like structure to organize items. | ||
| * Each element represents one level in the hierarchy. | ||
| * | ||
| * @example | ||
| * // Root level documents | ||
| * namespace: ["documents"] | ||
| * | ||
| * // User-specific documents | ||
| * namespace: ["documents", "user123"] | ||
| * | ||
| * // Nested cache structure | ||
| * namespace: ["cache", "docs", "v1"] | ||
| */ | ||
| namespace: string[]; | ||
| /** | ||
| * Unique identifier for the document within its namespace. | ||
| * Together with namespace forms the complete path to the item. | ||
| * | ||
| * Example: If namespace is ["documents", "user123"] and key is "report1", | ||
| * the full path would effectively be "documents/user123/report1" | ||
| */ | ||
| key: string; | ||
| /** | ||
| * Data to be stored, or null to delete the item. | ||
| * Must be a JSON-serializable object with string keys. | ||
| * Setting to null signals that the item should be deleted. | ||
| * | ||
| * @example | ||
| * { | ||
| * field1: "string value", | ||
| * field2: 123, | ||
| * nested: { can: "contain", any: "serializable data" } | ||
| * } | ||
| */ | ||
| value: Record<string, any> | null; | ||
| /** | ||
| * Controls how the item's fields are indexed for search operations. | ||
| * | ||
| * - undefined: Uses store's default indexing configuration | ||
| * - false: Disables indexing for this item | ||
| * - string[]: List of field paths to index | ||
| * | ||
| * Path syntax supports: | ||
| * - Nested fields: "metadata.title" | ||
| * - Array access: "chapters[*].content" (each indexed separately) | ||
| * - Specific indices: "authors[0].name" | ||
| * | ||
| * @example | ||
| * // Index specific fields | ||
| * index: ["metadata.title", "chapters[*].content"] | ||
| * | ||
| * // Disable indexing | ||
| * index: false | ||
| */ | ||
| index?: false | string[]; | ||
| } | ||
@@ -207,18 +210,16 @@ /** | ||
| */ | ||
| export interface ListNamespacesOperation { | ||
| matchConditions?: MatchCondition[]; | ||
| maxDepth?: number; | ||
| limit: number; | ||
| offset: number; | ||
| interface ListNamespacesOperation { | ||
| matchConditions?: MatchCondition[]; | ||
| maxDepth?: number; | ||
| limit: number; | ||
| offset: number; | ||
| } | ||
| export type NameSpacePath = (string | "*")[]; | ||
| export type NamespaceMatchType = "prefix" | "suffix"; | ||
| export interface MatchCondition { | ||
| matchType: NamespaceMatchType; | ||
| path: NameSpacePath; | ||
| type NameSpacePath = (string | "*")[]; | ||
| type NamespaceMatchType = "prefix" | "suffix"; | ||
| interface MatchCondition { | ||
| matchType: NamespaceMatchType; | ||
| path: NameSpacePath; | ||
| } | ||
| export type Operation = GetOperation | SearchOperation | PutOperation | ListNamespacesOperation; | ||
| export type OperationResults<Tuple extends readonly Operation[]> = { | ||
| [K in keyof Tuple]: Tuple[K] extends PutOperation ? void : Tuple[K] extends SearchOperation ? SearchItem[] : Tuple[K] extends GetOperation ? Item | null : Tuple[K] extends ListNamespacesOperation ? string[][] : never; | ||
| }; | ||
| type Operation = GetOperation | SearchOperation | PutOperation | ListNamespacesOperation; | ||
| type OperationResults<Tuple extends readonly Operation[]> = { [K in keyof Tuple]: Tuple[K] extends PutOperation ? void : Tuple[K] extends SearchOperation ? SearchItem[] : Tuple[K] extends GetOperation ? Item | null : Tuple[K] extends ListNamespacesOperation ? string[][] : never }; | ||
| /** | ||
@@ -229,35 +230,35 @@ * Configuration for indexing documents for semantic search in the store. | ||
| */ | ||
| export interface IndexConfig { | ||
| /** | ||
| * Number of dimensions in the embedding vectors. | ||
| * | ||
| * Common embedding model dimensions: | ||
| * - OpenAI text-embedding-3-large: 256, 1024, or 3072 | ||
| * - OpenAI text-embedding-3-small: 512 or 1536 | ||
| * - OpenAI text-embedding-ada-002: 1536 | ||
| * - Cohere embed-english-v3.0: 1024 | ||
| * - Cohere embed-english-light-v3.0: 384 | ||
| * - Cohere embed-multilingual-v3.0: 1024 | ||
| * - Cohere embed-multilingual-light-v3.0: 384 | ||
| */ | ||
| dims: number; | ||
| /** | ||
| * The embeddings model to use for generating vectors. | ||
| * This should be a LangChain Embeddings implementation. | ||
| */ | ||
| embeddings: Embeddings; | ||
| /** | ||
| * Fields to extract text from for embedding generation. | ||
| * | ||
| * Path syntax supports: | ||
| * - Simple field access: "field" | ||
| * - Nested fields: "metadata.title" | ||
| * - Array indexing: | ||
| * - All elements: "chapters[*].content" | ||
| * - Specific index: "authors[0].name" | ||
| * - Last element: "array[-1]" | ||
| * | ||
| * @default ["$"] Embeds the entire document as one vector | ||
| */ | ||
| fields?: string[]; | ||
| interface IndexConfig { | ||
| /** | ||
| * Number of dimensions in the embedding vectors. | ||
| * | ||
| * Common embedding model dimensions: | ||
| * - OpenAI text-embedding-3-large: 256, 1024, or 3072 | ||
| * - OpenAI text-embedding-3-small: 512 or 1536 | ||
| * - OpenAI text-embedding-ada-002: 1536 | ||
| * - Cohere embed-english-v3.0: 1024 | ||
| * - Cohere embed-english-light-v3.0: 384 | ||
| * - Cohere embed-multilingual-v3.0: 1024 | ||
| * - Cohere embed-multilingual-light-v3.0: 384 | ||
| */ | ||
| dims: number; | ||
| /** | ||
| * The embeddings model to use for generating vectors. | ||
| * This should be a LangChain Embeddings implementation. | ||
| */ | ||
| embeddings: Embeddings; | ||
| /** | ||
| * Fields to extract text from for embedding generation. | ||
| * | ||
| * Path syntax supports: | ||
| * - Simple field access: "field" | ||
| * - Nested fields: "metadata.title" | ||
| * - Array indexing: | ||
| * - All elements: "chapters[*].content" | ||
| * - Specific index: "authors[0].name" | ||
| * - Last element: "array[-1]" | ||
| * | ||
| * @default ["$"] Embeds the entire document as one vector | ||
| */ | ||
| fields?: string[]; | ||
| } | ||
@@ -267,7 +268,7 @@ /** | ||
| */ | ||
| export declare function getTextAtPath(obj: any, path: string): string[]; | ||
| declare function getTextAtPath(obj: any, path: string): string[]; | ||
| /** | ||
| * Tokenizes a JSON path into parts | ||
| */ | ||
| export declare function tokenizePath(path: string): string[]; | ||
| declare function tokenizePath(path: string): string[]; | ||
| /** | ||
@@ -285,113 +286,116 @@ * Abstract base class for persistent key-value stores. | ||
| */ | ||
| export declare abstract class BaseStore { | ||
| /** | ||
| * Execute multiple operations in a single batch. | ||
| * This is more efficient than executing operations individually. | ||
| * | ||
| * @param operations Array of operations to execute | ||
| * @returns Promise resolving to results matching the operations | ||
| */ | ||
| abstract batch<Op extends Operation[]>(operations: Op): Promise<OperationResults<Op>>; | ||
| /** | ||
| * Retrieve a single item by its namespace and key. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @returns Promise resolving to the item or null if not found | ||
| */ | ||
| get(namespace: string[], key: string): Promise<Item | null>; | ||
| /** | ||
| * Search for items within a namespace prefix. | ||
| * Supports both metadata filtering and vector similarity search. | ||
| * | ||
| * @param namespacePrefix Hierarchical path prefix to search within | ||
| * @param options Search options for filtering and pagination | ||
| * @returns Promise resolving to list of matching items with relevance scores | ||
| * | ||
| * @example | ||
| * // Search with filters | ||
| * await store.search(["documents"], { | ||
| * filter: { type: "report", status: "active" }, | ||
| * limit: 5, | ||
| * offset: 10 | ||
| * }); | ||
| * | ||
| * // Vector similarity search | ||
| * await store.search(["users", "content"], { | ||
| * query: "technical documentation about APIs", | ||
| * limit: 20 | ||
| * }); | ||
| */ | ||
| search(namespacePrefix: string[], options?: { | ||
| filter?: Record<string, any>; | ||
| limit?: number; | ||
| offset?: number; | ||
| query?: string; | ||
| }): Promise<SearchItem[]>; | ||
| /** | ||
| * Store or update an item. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @param value Object containing the item's data | ||
| * @param index Optional indexing configuration | ||
| * | ||
| * @example | ||
| * // Simple storage | ||
| * await store.put(["docs"], "report", { title: "Annual Report" }); | ||
| * | ||
| * // With specific field indexing | ||
| * await store.put( | ||
| * ["docs"], | ||
| * "report", | ||
| * { | ||
| * title: "Q4 Report", | ||
| * chapters: [{ content: "..." }, { content: "..." }] | ||
| * }, | ||
| * ["title", "chapters[*].content"] | ||
| * ); | ||
| */ | ||
| put(namespace: string[], key: string, value: Record<string, any>, index?: false | string[]): Promise<void>; | ||
| /** | ||
| * Delete an item from the store. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| */ | ||
| delete(namespace: string[], key: string): Promise<void>; | ||
| /** | ||
| * List and filter namespaces in the store. | ||
| * Used to explore data organization and navigate the namespace hierarchy. | ||
| * | ||
| * @param options Options for listing namespaces | ||
| * @returns Promise resolving to list of namespace paths | ||
| * | ||
| * @example | ||
| * // List all namespaces under "documents" | ||
| * await store.listNamespaces({ | ||
| * prefix: ["documents"], | ||
| * maxDepth: 2 | ||
| * }); | ||
| * | ||
| * // List namespaces ending with "v1" | ||
| * await store.listNamespaces({ | ||
| * suffix: ["v1"], | ||
| * limit: 50 | ||
| * }); | ||
| */ | ||
| listNamespaces(options?: { | ||
| prefix?: string[]; | ||
| suffix?: string[]; | ||
| maxDepth?: number; | ||
| limit?: number; | ||
| offset?: number; | ||
| }): Promise<string[][]>; | ||
| /** | ||
| * Start the store. Override if initialization is needed. | ||
| */ | ||
| start(): void | Promise<void>; | ||
| /** | ||
| * Stop the store. Override if cleanup is needed. | ||
| */ | ||
| stop(): void | Promise<void>; | ||
| declare abstract class BaseStore { | ||
| /** | ||
| * Execute multiple operations in a single batch. | ||
| * This is more efficient than executing operations individually. | ||
| * | ||
| * @param operations Array of operations to execute | ||
| * @returns Promise resolving to results matching the operations | ||
| */ | ||
| abstract batch<Op extends Operation[]>(operations: Op): Promise<OperationResults<Op>>; | ||
| /** | ||
| * Retrieve a single item by its namespace and key. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @returns Promise resolving to the item or null if not found | ||
| */ | ||
| get(namespace: string[], key: string): Promise<Item | null>; | ||
| /** | ||
| * Search for items within a namespace prefix. | ||
| * Supports both metadata filtering and vector similarity search. | ||
| * | ||
| * @param namespacePrefix Hierarchical path prefix to search within | ||
| * @param options Search options for filtering and pagination | ||
| * @returns Promise resolving to list of matching items with relevance scores | ||
| * | ||
| * @example | ||
| * // Search with filters | ||
| * await store.search(["documents"], { | ||
| * filter: { type: "report", status: "active" }, | ||
| * limit: 5, | ||
| * offset: 10 | ||
| * }); | ||
| * | ||
| * // Vector similarity search | ||
| * await store.search(["users", "content"], { | ||
| * query: "technical documentation about APIs", | ||
| * limit: 20 | ||
| * }); | ||
| */ | ||
| search(namespacePrefix: string[], options?: { | ||
| filter?: Record<string, any>; | ||
| limit?: number; | ||
| offset?: number; | ||
| query?: string; | ||
| }): Promise<SearchItem[]>; | ||
| /** | ||
| * Store or update an item. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @param value Object containing the item's data | ||
| * @param index Optional indexing configuration | ||
| * | ||
| * @example | ||
| * // Simple storage | ||
| * await store.put(["docs"], "report", { title: "Annual Report" }); | ||
| * | ||
| * // With specific field indexing | ||
| * await store.put( | ||
| * ["docs"], | ||
| * "report", | ||
| * { | ||
| * title: "Q4 Report", | ||
| * chapters: [{ content: "..." }, { content: "..." }] | ||
| * }, | ||
| * ["title", "chapters[*].content"] | ||
| * ); | ||
| */ | ||
| put(namespace: string[], key: string, value: Record<string, any>, index?: false | string[]): Promise<void>; | ||
| /** | ||
| * Delete an item from the store. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| */ | ||
| delete(namespace: string[], key: string): Promise<void>; | ||
| /** | ||
| * List and filter namespaces in the store. | ||
| * Used to explore data organization and navigate the namespace hierarchy. | ||
| * | ||
| * @param options Options for listing namespaces | ||
| * @returns Promise resolving to list of namespace paths | ||
| * | ||
| * @example | ||
| * // List all namespaces under "documents" | ||
| * await store.listNamespaces({ | ||
| * prefix: ["documents"], | ||
| * maxDepth: 2 | ||
| * }); | ||
| * | ||
| * // List namespaces ending with "v1" | ||
| * await store.listNamespaces({ | ||
| * suffix: ["v1"], | ||
| * limit: 50 | ||
| * }); | ||
| */ | ||
| listNamespaces(options?: { | ||
| prefix?: string[]; | ||
| suffix?: string[]; | ||
| maxDepth?: number; | ||
| limit?: number; | ||
| offset?: number; | ||
| }): Promise<string[][]>; | ||
| /** | ||
| * Start the store. Override if initialization is needed. | ||
| */ | ||
| start(): void | Promise<void>; | ||
| /** | ||
| * Stop the store. Override if cleanup is needed. | ||
| */ | ||
| stop(): void | Promise<void>; | ||
| } | ||
| //#endregion | ||
| export { BaseStore, GetOperation, IndexConfig, InvalidNamespaceError, Item, ListNamespacesOperation, MatchCondition, NameSpacePath, NamespaceMatchType, Operation, OperationResults, PutOperation, SearchItem, SearchOperation, getTextAtPath, tokenizePath }; | ||
| //# sourceMappingURL=base.d.ts.map |
+198
-204
@@ -0,214 +1,208 @@ | ||
| //#region src/store/base.ts | ||
| /** | ||
| * Error thrown when an invalid namespace is provided. | ||
| */ | ||
| export class InvalidNamespaceError extends Error { | ||
| constructor(message) { | ||
| super(message); | ||
| this.name = "InvalidNamespaceError"; | ||
| } | ||
| } | ||
| * Error thrown when an invalid namespace is provided. | ||
| */ | ||
| var InvalidNamespaceError = class extends Error { | ||
| constructor(message) { | ||
| super(message); | ||
| this.name = "InvalidNamespaceError"; | ||
| } | ||
| }; | ||
| /** | ||
| * Validates the provided namespace. | ||
| * @param namespace The namespace to validate. | ||
| * @throws {InvalidNamespaceError} If the namespace is invalid. | ||
| */ | ||
| * Validates the provided namespace. | ||
| * @param namespace The namespace to validate. | ||
| * @throws {InvalidNamespaceError} If the namespace is invalid. | ||
| */ | ||
| function validateNamespace(namespace) { | ||
| if (namespace.length === 0) { | ||
| throw new InvalidNamespaceError("Namespace cannot be empty."); | ||
| } | ||
| for (const label of namespace) { | ||
| if (typeof label !== "string") { | ||
| throw new InvalidNamespaceError(`Invalid namespace label '${label}' found in ${namespace}. Namespace labels ` + | ||
| `must be strings, but got ${typeof label}.`); | ||
| } | ||
| if (label.includes(".")) { | ||
| throw new InvalidNamespaceError(`Invalid namespace label '${label}' found in ${namespace}. Namespace labels cannot contain periods ('.').`); | ||
| } | ||
| if (label === "") { | ||
| throw new InvalidNamespaceError(`Namespace labels cannot be empty strings. Got ${label} in ${namespace}`); | ||
| } | ||
| } | ||
| if (namespace[0] === "langgraph") { | ||
| throw new InvalidNamespaceError(`Root label for namespace cannot be "langgraph". Got: ${namespace}`); | ||
| } | ||
| if (namespace.length === 0) throw new InvalidNamespaceError("Namespace cannot be empty."); | ||
| for (const label of namespace) { | ||
| if (typeof label !== "string") throw new InvalidNamespaceError(`Invalid namespace label '${label}' found in ${namespace}. Namespace labels must be strings, but got ${typeof label}.`); | ||
| if (label.includes(".")) throw new InvalidNamespaceError(`Invalid namespace label '${label}' found in ${namespace}. Namespace labels cannot contain periods ('.').`); | ||
| if (label === "") throw new InvalidNamespaceError(`Namespace labels cannot be empty strings. Got ${label} in ${namespace}`); | ||
| } | ||
| if (namespace[0] === "langgraph") throw new InvalidNamespaceError(`Root label for namespace cannot be "langgraph". Got: ${namespace}`); | ||
| } | ||
| /** | ||
| * Utility function to get text at a specific JSON path | ||
| */ | ||
| export function getTextAtPath(obj, path) { | ||
| const parts = path.split("."); | ||
| let current = obj; | ||
| for (const part of parts) { | ||
| if (part.includes("[")) { | ||
| const [arrayName, indexStr] = part.split("["); | ||
| const index = indexStr.replace("]", ""); | ||
| if (!current[arrayName]) | ||
| return []; | ||
| if (index === "*") { | ||
| const results = []; | ||
| for (const item of current[arrayName]) { | ||
| if (typeof item === "string") | ||
| results.push(item); | ||
| } | ||
| return results; | ||
| } | ||
| const idx = parseInt(index, 10); | ||
| if (Number.isNaN(idx)) | ||
| return []; | ||
| current = current[arrayName][idx]; | ||
| } | ||
| else { | ||
| current = current[part]; | ||
| } | ||
| if (current === undefined) | ||
| return []; | ||
| } | ||
| return typeof current === "string" ? [current] : []; | ||
| * Utility function to get text at a specific JSON path | ||
| */ | ||
| function getTextAtPath(obj, path) { | ||
| const parts = path.split("."); | ||
| let current = obj; | ||
| for (const part of parts) { | ||
| if (part.includes("[")) { | ||
| const [arrayName, indexStr] = part.split("["); | ||
| const index = indexStr.replace("]", ""); | ||
| if (!current[arrayName]) return []; | ||
| if (index === "*") { | ||
| const results = []; | ||
| for (const item of current[arrayName]) if (typeof item === "string") results.push(item); | ||
| return results; | ||
| } | ||
| const idx = parseInt(index, 10); | ||
| if (Number.isNaN(idx)) return []; | ||
| current = current[arrayName][idx]; | ||
| } else current = current[part]; | ||
| if (current === void 0) return []; | ||
| } | ||
| return typeof current === "string" ? [current] : []; | ||
| } | ||
| /** | ||
| * Tokenizes a JSON path into parts | ||
| */ | ||
| export function tokenizePath(path) { | ||
| return path.split("."); | ||
| * Tokenizes a JSON path into parts | ||
| */ | ||
| function tokenizePath(path) { | ||
| return path.split("."); | ||
| } | ||
| /** | ||
| * Abstract base class for persistent key-value stores. | ||
| * | ||
| * Stores enable persistence and memory that can be shared across threads, | ||
| * scoped to user IDs, assistant IDs, or other arbitrary namespaces. | ||
| * | ||
| * Features: | ||
| * - Hierarchical namespaces for organization | ||
| * - Key-value storage with metadata | ||
| * - Vector similarity search (if configured) | ||
| * - Filtering and pagination | ||
| */ | ||
| export class BaseStore { | ||
| /** | ||
| * Retrieve a single item by its namespace and key. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @returns Promise resolving to the item or null if not found | ||
| */ | ||
| async get(namespace, key) { | ||
| return (await this.batch([{ namespace, key }]))[0]; | ||
| } | ||
| /** | ||
| * Search for items within a namespace prefix. | ||
| * Supports both metadata filtering and vector similarity search. | ||
| * | ||
| * @param namespacePrefix Hierarchical path prefix to search within | ||
| * @param options Search options for filtering and pagination | ||
| * @returns Promise resolving to list of matching items with relevance scores | ||
| * | ||
| * @example | ||
| * // Search with filters | ||
| * await store.search(["documents"], { | ||
| * filter: { type: "report", status: "active" }, | ||
| * limit: 5, | ||
| * offset: 10 | ||
| * }); | ||
| * | ||
| * // Vector similarity search | ||
| * await store.search(["users", "content"], { | ||
| * query: "technical documentation about APIs", | ||
| * limit: 20 | ||
| * }); | ||
| */ | ||
| async search(namespacePrefix, options = {}) { | ||
| const { filter, limit = 10, offset = 0, query } = options; | ||
| return (await this.batch([ | ||
| { | ||
| namespacePrefix, | ||
| filter, | ||
| limit, | ||
| offset, | ||
| query, | ||
| }, | ||
| ]))[0]; | ||
| } | ||
| /** | ||
| * Store or update an item. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @param value Object containing the item's data | ||
| * @param index Optional indexing configuration | ||
| * | ||
| * @example | ||
| * // Simple storage | ||
| * await store.put(["docs"], "report", { title: "Annual Report" }); | ||
| * | ||
| * // With specific field indexing | ||
| * await store.put( | ||
| * ["docs"], | ||
| * "report", | ||
| * { | ||
| * title: "Q4 Report", | ||
| * chapters: [{ content: "..." }, { content: "..." }] | ||
| * }, | ||
| * ["title", "chapters[*].content"] | ||
| * ); | ||
| */ | ||
| async put(namespace, key, value, index) { | ||
| validateNamespace(namespace); | ||
| await this.batch([{ namespace, key, value, index }]); | ||
| } | ||
| /** | ||
| * Delete an item from the store. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| */ | ||
| async delete(namespace, key) { | ||
| await this.batch([{ namespace, key, value: null }]); | ||
| } | ||
| /** | ||
| * List and filter namespaces in the store. | ||
| * Used to explore data organization and navigate the namespace hierarchy. | ||
| * | ||
| * @param options Options for listing namespaces | ||
| * @returns Promise resolving to list of namespace paths | ||
| * | ||
| * @example | ||
| * // List all namespaces under "documents" | ||
| * await store.listNamespaces({ | ||
| * prefix: ["documents"], | ||
| * maxDepth: 2 | ||
| * }); | ||
| * | ||
| * // List namespaces ending with "v1" | ||
| * await store.listNamespaces({ | ||
| * suffix: ["v1"], | ||
| * limit: 50 | ||
| * }); | ||
| */ | ||
| async listNamespaces(options = {}) { | ||
| const { prefix, suffix, maxDepth, limit = 100, offset = 0 } = options; | ||
| const matchConditions = []; | ||
| if (prefix) { | ||
| matchConditions.push({ matchType: "prefix", path: prefix }); | ||
| } | ||
| if (suffix) { | ||
| matchConditions.push({ matchType: "suffix", path: suffix }); | ||
| } | ||
| return (await this.batch([ | ||
| { | ||
| matchConditions: matchConditions.length ? matchConditions : undefined, | ||
| maxDepth, | ||
| limit, | ||
| offset, | ||
| }, | ||
| ]))[0]; | ||
| } | ||
| /** | ||
| * Start the store. Override if initialization is needed. | ||
| */ | ||
| start() { } | ||
| /** | ||
| * Stop the store. Override if cleanup is needed. | ||
| */ | ||
| stop() { } | ||
| } | ||
| * Abstract base class for persistent key-value stores. | ||
| * | ||
| * Stores enable persistence and memory that can be shared across threads, | ||
| * scoped to user IDs, assistant IDs, or other arbitrary namespaces. | ||
| * | ||
| * Features: | ||
| * - Hierarchical namespaces for organization | ||
| * - Key-value storage with metadata | ||
| * - Vector similarity search (if configured) | ||
| * - Filtering and pagination | ||
| */ | ||
| var BaseStore = class { | ||
| /** | ||
| * Retrieve a single item by its namespace and key. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @returns Promise resolving to the item or null if not found | ||
| */ | ||
| async get(namespace, key) { | ||
| return (await this.batch([{ | ||
| namespace, | ||
| key | ||
| }]))[0]; | ||
| } | ||
| /** | ||
| * Search for items within a namespace prefix. | ||
| * Supports both metadata filtering and vector similarity search. | ||
| * | ||
| * @param namespacePrefix Hierarchical path prefix to search within | ||
| * @param options Search options for filtering and pagination | ||
| * @returns Promise resolving to list of matching items with relevance scores | ||
| * | ||
| * @example | ||
| * // Search with filters | ||
| * await store.search(["documents"], { | ||
| * filter: { type: "report", status: "active" }, | ||
| * limit: 5, | ||
| * offset: 10 | ||
| * }); | ||
| * | ||
| * // Vector similarity search | ||
| * await store.search(["users", "content"], { | ||
| * query: "technical documentation about APIs", | ||
| * limit: 20 | ||
| * }); | ||
| */ | ||
| async search(namespacePrefix, options = {}) { | ||
| const { filter, limit = 10, offset = 0, query } = options; | ||
| return (await this.batch([{ | ||
| namespacePrefix, | ||
| filter, | ||
| limit, | ||
| offset, | ||
| query | ||
| }]))[0]; | ||
| } | ||
| /** | ||
| * Store or update an item. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| * @param value Object containing the item's data | ||
| * @param index Optional indexing configuration | ||
| * | ||
| * @example | ||
| * // Simple storage | ||
| * await store.put(["docs"], "report", { title: "Annual Report" }); | ||
| * | ||
| * // With specific field indexing | ||
| * await store.put( | ||
| * ["docs"], | ||
| * "report", | ||
| * { | ||
| * title: "Q4 Report", | ||
| * chapters: [{ content: "..." }, { content: "..." }] | ||
| * }, | ||
| * ["title", "chapters[*].content"] | ||
| * ); | ||
| */ | ||
| async put(namespace, key, value, index) { | ||
| validateNamespace(namespace); | ||
| await this.batch([{ | ||
| namespace, | ||
| key, | ||
| value, | ||
| index | ||
| }]); | ||
| } | ||
| /** | ||
| * Delete an item from the store. | ||
| * | ||
| * @param namespace Hierarchical path for the item | ||
| * @param key Unique identifier within the namespace | ||
| */ | ||
| async delete(namespace, key) { | ||
| await this.batch([{ | ||
| namespace, | ||
| key, | ||
| value: null | ||
| }]); | ||
| } | ||
| /** | ||
| * List and filter namespaces in the store. | ||
| * Used to explore data organization and navigate the namespace hierarchy. | ||
| * | ||
| * @param options Options for listing namespaces | ||
| * @returns Promise resolving to list of namespace paths | ||
| * | ||
| * @example | ||
| * // List all namespaces under "documents" | ||
| * await store.listNamespaces({ | ||
| * prefix: ["documents"], | ||
| * maxDepth: 2 | ||
| * }); | ||
| * | ||
| * // List namespaces ending with "v1" | ||
| * await store.listNamespaces({ | ||
| * suffix: ["v1"], | ||
| * limit: 50 | ||
| * }); | ||
| */ | ||
| async listNamespaces(options = {}) { | ||
| const { prefix, suffix, maxDepth, limit = 100, offset = 0 } = options; | ||
| const matchConditions = []; | ||
| if (prefix) matchConditions.push({ | ||
| matchType: "prefix", | ||
| path: prefix | ||
| }); | ||
| if (suffix) matchConditions.push({ | ||
| matchType: "suffix", | ||
| path: suffix | ||
| }); | ||
| return (await this.batch([{ | ||
| matchConditions: matchConditions.length ? matchConditions : void 0, | ||
| maxDepth, | ||
| limit, | ||
| offset | ||
| }]))[0]; | ||
| } | ||
| /** | ||
| * Start the store. Override if initialization is needed. | ||
| */ | ||
| start() {} | ||
| /** | ||
| * Stop the store. Override if cleanup is needed. | ||
| */ | ||
| stop() {} | ||
| }; | ||
| //#endregion | ||
| export { BaseStore, InvalidNamespaceError, getTextAtPath, tokenizePath }; | ||
| //# sourceMappingURL=base.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/store/base.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"base.js","names":["current: any","results: string[]","matchConditions: MatchCondition[]"],"sources":["../../src/store/base.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Embeddings } from \"@langchain/core/embeddings\";\n\n/**\n * Error thrown when an invalid namespace is provided.\n */\nexport class InvalidNamespaceError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"InvalidNamespaceError\";\n }\n}\n\n/**\n * Validates the provided namespace.\n * @param namespace The namespace to validate.\n * @throws {InvalidNamespaceError} If the namespace is invalid.\n */\nfunction validateNamespace(namespace: string[]): void {\n if (namespace.length === 0) {\n throw new InvalidNamespaceError(\"Namespace cannot be empty.\");\n }\n for (const label of namespace) {\n if (typeof label !== \"string\") {\n throw new InvalidNamespaceError(\n `Invalid namespace label '${label}' found in ${namespace}. Namespace labels ` +\n `must be strings, but got ${typeof label}.`\n );\n }\n if (label.includes(\".\")) {\n throw new InvalidNamespaceError(\n `Invalid namespace label '${label}' found in ${namespace}. Namespace labels cannot contain periods ('.').`\n );\n }\n if (label === \"\") {\n throw new InvalidNamespaceError(\n `Namespace labels cannot be empty strings. Got ${label} in ${namespace}`\n );\n }\n }\n if (namespace[0] === \"langgraph\") {\n throw new InvalidNamespaceError(\n `Root label for namespace cannot be \"langgraph\". Got: ${namespace}`\n );\n }\n}\n\n/**\n * Represents a stored item with metadata.\n */\nexport interface Item {\n /**\n * The stored data as an object. Keys are filterable.\n */\n value: Record<string, any>;\n /**\n * Unique identifier within the namespace.\n */\n key: string;\n /**\n * Hierarchical path defining the collection in which this document resides.\n * Represented as an array of strings, allowing for nested categorization.\n * For example: [\"documents\", \"user123\"]\n */\n namespace: string[];\n /**\n * Timestamp of item creation.\n */\n createdAt: Date;\n /**\n * Timestamp of last update.\n */\n updatedAt: Date;\n}\n\n/**\n * Represents a search result item with relevance score.\n * Extends the base Item interface with an optional similarity score.\n */\nexport interface SearchItem extends Item {\n /**\n * Relevance/similarity score if from a ranked operation.\n * Higher scores indicate better matches.\n *\n * This is typically a cosine similarity score between -1 and 1,\n * where 1 indicates identical vectors and -1 indicates opposite vectors.\n */\n score?: number;\n}\n\n/**\n * Operation to retrieve an item by namespace and ID.\n */\nexport interface GetOperation {\n /**\n * Hierarchical path for the item.\n *\n * @example\n * // Get a user profile\n * namespace: [\"users\", \"profiles\"]\n */\n namespace: string[];\n\n /**\n * Unique identifier within the namespace.\n * Together with namespace forms the complete path to the item.\n *\n * @example\n * key: \"user123\" // For a user profile\n * key: \"doc456\" // For a document\n */\n key: string;\n}\n\n/**\n * Operation to search for items within a namespace prefix.\n */\nexport interface SearchOperation {\n /**\n * Hierarchical path prefix to search within.\n * Only items under this prefix will be searched.\n *\n * @example\n * // Search all user documents\n * namespacePrefix: [\"users\", \"documents\"]\n *\n * // Search everything\n * namespacePrefix: []\n */\n namespacePrefix: string[];\n\n /**\n * Key-value pairs to filter results based on exact matches or comparison operators.\n *\n * Supports both exact matches and operator-based comparisons:\n * - $eq: Equal to (same as direct value comparison)\n * - $ne: Not equal to\n * - $gt: Greater than\n * - $gte: Greater than or equal to\n * - $lt: Less than\n * - $lte: Less than or equal to\n *\n * @example\n * // Exact match\n * filter: { status: \"active\" }\n *\n * // With operators\n * filter: { score: { $gt: 4.99 } }\n *\n * // Multiple conditions\n * filter: {\n * score: { $gte: 3.0 },\n * color: \"red\"\n * }\n */\n filter?: Record<string, any>;\n\n /**\n * Maximum number of items to return.\n * @default 10\n */\n limit?: number;\n\n /**\n * Number of items to skip before returning results.\n * Useful for pagination.\n * @default 0\n */\n offset?: number;\n\n /**\n * Natural language search query for semantic search.\n * When provided, results will be ranked by relevance to this query\n * using vector similarity search.\n *\n * @example\n * // Find technical documentation about APIs\n * query: \"technical documentation about REST APIs\"\n *\n * // Find recent ML papers\n * query: \"machine learning papers from 2023\"\n */\n query?: string;\n}\n\n/**\n * Operation to store, update, or delete an item.\n */\nexport interface PutOperation {\n /**\n * Hierarchical path for the item.\n * Acts as a folder-like structure to organize items.\n * Each element represents one level in the hierarchy.\n *\n * @example\n * // Root level documents\n * namespace: [\"documents\"]\n *\n * // User-specific documents\n * namespace: [\"documents\", \"user123\"]\n *\n * // Nested cache structure\n * namespace: [\"cache\", \"docs\", \"v1\"]\n */\n namespace: string[];\n\n /**\n * Unique identifier for the document within its namespace.\n * Together with namespace forms the complete path to the item.\n *\n * Example: If namespace is [\"documents\", \"user123\"] and key is \"report1\",\n * the full path would effectively be \"documents/user123/report1\"\n */\n key: string;\n\n /**\n * Data to be stored, or null to delete the item.\n * Must be a JSON-serializable object with string keys.\n * Setting to null signals that the item should be deleted.\n *\n * @example\n * {\n * field1: \"string value\",\n * field2: 123,\n * nested: { can: \"contain\", any: \"serializable data\" }\n * }\n */\n value: Record<string, any> | null;\n\n /**\n * Controls how the item's fields are indexed for search operations.\n *\n * - undefined: Uses store's default indexing configuration\n * - false: Disables indexing for this item\n * - string[]: List of field paths to index\n *\n * Path syntax supports:\n * - Nested fields: \"metadata.title\"\n * - Array access: \"chapters[*].content\" (each indexed separately)\n * - Specific indices: \"authors[0].name\"\n *\n * @example\n * // Index specific fields\n * index: [\"metadata.title\", \"chapters[*].content\"]\n *\n * // Disable indexing\n * index: false\n */\n index?: false | string[];\n}\n\n/**\n * Operation to list and filter namespaces in the store.\n */\nexport interface ListNamespacesOperation {\n matchConditions?: MatchCondition[];\n maxDepth?: number;\n limit: number;\n offset: number;\n}\n\nexport type NameSpacePath = (string | \"*\")[];\n\nexport type NamespaceMatchType = \"prefix\" | \"suffix\";\n\nexport interface MatchCondition {\n matchType: NamespaceMatchType;\n path: NameSpacePath;\n}\n\nexport type Operation =\n | GetOperation\n | SearchOperation\n | PutOperation\n | ListNamespacesOperation;\n\nexport type OperationResults<Tuple extends readonly Operation[]> = {\n [K in keyof Tuple]: Tuple[K] extends PutOperation\n ? void\n : Tuple[K] extends SearchOperation\n ? SearchItem[]\n : Tuple[K] extends GetOperation\n ? Item | null\n : Tuple[K] extends ListNamespacesOperation\n ? string[][]\n : never;\n};\n\n/**\n * Configuration for indexing documents for semantic search in the store.\n *\n * This configures how documents are embedded and indexed for vector similarity search.\n */\nexport interface IndexConfig {\n /**\n * Number of dimensions in the embedding vectors.\n *\n * Common embedding model dimensions:\n * - OpenAI text-embedding-3-large: 256, 1024, or 3072\n * - OpenAI text-embedding-3-small: 512 or 1536\n * - OpenAI text-embedding-ada-002: 1536\n * - Cohere embed-english-v3.0: 1024\n * - Cohere embed-english-light-v3.0: 384\n * - Cohere embed-multilingual-v3.0: 1024\n * - Cohere embed-multilingual-light-v3.0: 384\n */\n dims: number;\n\n /**\n * The embeddings model to use for generating vectors.\n * This should be a LangChain Embeddings implementation.\n */\n embeddings: Embeddings;\n\n /**\n * Fields to extract text from for embedding generation.\n *\n * Path syntax supports:\n * - Simple field access: \"field\"\n * - Nested fields: \"metadata.title\"\n * - Array indexing:\n * - All elements: \"chapters[*].content\"\n * - Specific index: \"authors[0].name\"\n * - Last element: \"array[-1]\"\n *\n * @default [\"$\"] Embeds the entire document as one vector\n */\n fields?: string[];\n}\n\n/**\n * Utility function to get text at a specific JSON path\n */\nexport function getTextAtPath(obj: any, path: string): string[] {\n const parts = path.split(\".\");\n let current: any = obj;\n\n for (const part of parts) {\n if (part.includes(\"[\")) {\n const [arrayName, indexStr] = part.split(\"[\");\n const index = indexStr.replace(\"]\", \"\");\n\n if (!current[arrayName]) return [];\n\n if (index === \"*\") {\n const results: string[] = [];\n for (const item of current[arrayName]) {\n if (typeof item === \"string\") results.push(item);\n }\n return results;\n }\n\n const idx = parseInt(index, 10);\n if (Number.isNaN(idx)) return [];\n current = current[arrayName][idx];\n } else {\n current = current[part];\n }\n\n if (current === undefined) return [];\n }\n\n return typeof current === \"string\" ? [current] : [];\n}\n\n/**\n * Tokenizes a JSON path into parts\n */\nexport function tokenizePath(path: string): string[] {\n return path.split(\".\");\n}\n\n/**\n * Abstract base class for persistent key-value stores.\n *\n * Stores enable persistence and memory that can be shared across threads,\n * scoped to user IDs, assistant IDs, or other arbitrary namespaces.\n *\n * Features:\n * - Hierarchical namespaces for organization\n * - Key-value storage with metadata\n * - Vector similarity search (if configured)\n * - Filtering and pagination\n */\nexport abstract class BaseStore {\n /**\n * Execute multiple operations in a single batch.\n * This is more efficient than executing operations individually.\n *\n * @param operations Array of operations to execute\n * @returns Promise resolving to results matching the operations\n */\n abstract batch<Op extends Operation[]>(\n operations: Op\n ): Promise<OperationResults<Op>>;\n\n /**\n * Retrieve a single item by its namespace and key.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n * @returns Promise resolving to the item or null if not found\n */\n async get(namespace: string[], key: string): Promise<Item | null> {\n return (await this.batch<[GetOperation]>([{ namespace, key }]))[0];\n }\n\n /**\n * Search for items within a namespace prefix.\n * Supports both metadata filtering and vector similarity search.\n *\n * @param namespacePrefix Hierarchical path prefix to search within\n * @param options Search options for filtering and pagination\n * @returns Promise resolving to list of matching items with relevance scores\n *\n * @example\n * // Search with filters\n * await store.search([\"documents\"], {\n * filter: { type: \"report\", status: \"active\" },\n * limit: 5,\n * offset: 10\n * });\n *\n * // Vector similarity search\n * await store.search([\"users\", \"content\"], {\n * query: \"technical documentation about APIs\",\n * limit: 20\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<SearchItem[]> {\n const { filter, limit = 10, offset = 0, query } = options;\n return (\n await this.batch<[SearchOperation]>([\n {\n namespacePrefix,\n filter,\n limit,\n offset,\n query,\n },\n ])\n )[0];\n }\n\n /**\n * Store or update an item.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n * @param value Object containing the item's data\n * @param index Optional indexing configuration\n *\n * @example\n * // Simple storage\n * await store.put([\"docs\"], \"report\", { title: \"Annual Report\" });\n *\n * // With specific field indexing\n * await store.put(\n * [\"docs\"],\n * \"report\",\n * {\n * title: \"Q4 Report\",\n * chapters: [{ content: \"...\" }, { content: \"...\" }]\n * },\n * [\"title\", \"chapters[*].content\"]\n * );\n */\n async put(\n namespace: string[],\n key: string,\n value: Record<string, any>,\n index?: false | string[]\n ): Promise<void> {\n validateNamespace(namespace);\n await this.batch<[PutOperation]>([{ namespace, key, value, index }]);\n }\n\n /**\n * Delete an item from the store.\n *\n * @param namespace Hierarchical path for the item\n * @param key Unique identifier within the namespace\n */\n async delete(namespace: string[], key: string): Promise<void> {\n await this.batch<[PutOperation]>([{ namespace, key, value: null }]);\n }\n\n /**\n * List and filter namespaces in the store.\n * Used to explore data organization and navigate the namespace hierarchy.\n *\n * @param options Options for listing namespaces\n * @returns Promise resolving to list of namespace paths\n *\n * @example\n * // List all namespaces under \"documents\"\n * await store.listNamespaces({\n * prefix: [\"documents\"],\n * maxDepth: 2\n * });\n *\n * // List namespaces ending with \"v1\"\n * await store.listNamespaces({\n * suffix: [\"v1\"],\n * limit: 50\n * });\n */\n async listNamespaces(\n options: {\n prefix?: string[];\n suffix?: string[];\n maxDepth?: number;\n limit?: number;\n offset?: number;\n } = {}\n ): Promise<string[][]> {\n const { prefix, suffix, maxDepth, limit = 100, offset = 0 } = options;\n\n const matchConditions: MatchCondition[] = [];\n if (prefix) {\n matchConditions.push({ matchType: \"prefix\", path: prefix });\n }\n if (suffix) {\n matchConditions.push({ matchType: \"suffix\", path: suffix });\n }\n\n return (\n await this.batch<[ListNamespacesOperation]>([\n {\n matchConditions: matchConditions.length ? matchConditions : undefined,\n maxDepth,\n limit,\n offset,\n },\n ])\n )[0];\n }\n\n /**\n * Start the store. Override if initialization is needed.\n */\n start(): void | Promise<void> {}\n\n /**\n * Stop the store. Override if cleanup is needed.\n */\n stop(): void | Promise<void> {}\n}\n"],"mappings":";;;;AAMA,IAAa,wBAAb,cAA2C,MAAM;CAC/C,YAAY,SAAiB;AAC3B,QAAM;AACN,OAAK,OAAO;;;;;;;;AAShB,SAAS,kBAAkB,WAA2B;AACpD,KAAI,UAAU,WAAW,EACvB,OAAM,IAAI,sBAAsB;AAElC,MAAK,MAAM,SAAS,WAAW;AAC7B,MAAI,OAAO,UAAU,SACnB,OAAM,IAAI,sBACR,4BAA4B,MAAM,aAAa,UAAU,8CAC3B,OAAO,MAAM;AAG/C,MAAI,MAAM,SAAS,KACjB,OAAM,IAAI,sBACR,4BAA4B,MAAM,aAAa,UAAU;AAG7D,MAAI,UAAU,GACZ,OAAM,IAAI,sBACR,iDAAiD,MAAM,MAAM;;AAInE,KAAI,UAAU,OAAO,YACnB,OAAM,IAAI,sBACR,wDAAwD;;;;;AAmS9D,SAAgB,cAAc,KAAU,MAAwB;CAC9D,MAAM,QAAQ,KAAK,MAAM;CACzB,IAAIA,UAAe;AAEnB,MAAK,MAAM,QAAQ,OAAO;AACxB,MAAI,KAAK,SAAS,MAAM;GACtB,MAAM,CAAC,WAAW,YAAY,KAAK,MAAM;GACzC,MAAM,QAAQ,SAAS,QAAQ,KAAK;AAEpC,OAAI,CAAC,QAAQ,WAAY,QAAO;AAEhC,OAAI,UAAU,KAAK;IACjB,MAAMC,UAAoB;AAC1B,SAAK,MAAM,QAAQ,QAAQ,WACzB,KAAI,OAAO,SAAS,SAAU,SAAQ,KAAK;AAE7C,WAAO;;GAGT,MAAM,MAAM,SAAS,OAAO;AAC5B,OAAI,OAAO,MAAM,KAAM,QAAO;AAC9B,aAAU,QAAQ,WAAW;QAE7B,WAAU,QAAQ;AAGpB,MAAI,YAAY,OAAW,QAAO;;AAGpC,QAAO,OAAO,YAAY,WAAW,CAAC,WAAW;;;;;AAMnD,SAAgB,aAAa,MAAwB;AACnD,QAAO,KAAK,MAAM;;;;;;;;;;;;;;AAepB,IAAsB,YAAtB,MAAgC;;;;;;;;CAmB9B,MAAM,IAAI,WAAqB,KAAmC;AAChE,UAAQ,MAAM,KAAK,MAAsB,CAAC;GAAE;GAAW;OAAS;;;;;;;;;;;;;;;;;;;;;;;;CAyBlE,MAAM,OACJ,iBACA,UAKI,IACmB;EACvB,MAAM,EAAE,QAAQ,QAAQ,IAAI,SAAS,GAAG,UAAU;AAClD,UACE,MAAM,KAAK,MAAyB,CAClC;GACE;GACA;GACA;GACA;GACA;OAGJ;;;;;;;;;;;;;;;;;;;;;;;;;CA0BJ,MAAM,IACJ,WACA,KACA,OACA,OACe;AACf,oBAAkB;AAClB,QAAM,KAAK,MAAsB,CAAC;GAAE;GAAW;GAAK;GAAO;;;;;;;;;CAS7D,MAAM,OAAO,WAAqB,KAA4B;AAC5D,QAAM,KAAK,MAAsB,CAAC;GAAE;GAAW;GAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;CAuB7D,MAAM,eACJ,UAMI,IACiB;EACrB,MAAM,EAAE,QAAQ,QAAQ,UAAU,QAAQ,KAAK,SAAS,MAAM;EAE9D,MAAMC,kBAAoC;AAC1C,MAAI,OACF,iBAAgB,KAAK;GAAE,WAAW;GAAU,MAAM;;AAEpD,MAAI,OACF,iBAAgB,KAAK;GAAE,WAAW;GAAU,MAAM;;AAGpD,UACE,MAAM,KAAK,MAAiC,CAC1C;GACE,iBAAiB,gBAAgB,SAAS,kBAAkB;GAC5D;GACA;GACA;OAGJ;;;;;CAMJ,QAA8B;;;;CAK9B,OAA6B"} |
+116
-147
@@ -1,151 +0,120 @@ | ||
| "use strict"; | ||
| /* eslint-disable @typescript-eslint/no-explicit-any */ | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.AsyncBatchedStore = void 0; | ||
| const base_js_1 = require("./base.cjs"); | ||
| const require_base = require('./base.cjs'); | ||
| //#region src/store/batch.ts | ||
| /** | ||
| * Extracts and returns the underlying store from an `AsyncBatchedStore`, | ||
| * or returns the input if it is not an `AsyncBatchedStore`. | ||
| */ | ||
| * Extracts and returns the underlying store from an `AsyncBatchedStore`, | ||
| * or returns the input if it is not an `AsyncBatchedStore`. | ||
| */ | ||
| const extractStore = (input) => { | ||
| if ("lg_name" in input && input.lg_name === "AsyncBatchedStore") { | ||
| // @ts-expect-error is a protected property | ||
| return input.store; | ||
| } | ||
| return input; | ||
| if ("lg_name" in input && input.lg_name === "AsyncBatchedStore") return input.store; | ||
| return input; | ||
| }; | ||
| class AsyncBatchedStore extends base_js_1.BaseStore { | ||
| constructor(store) { | ||
| super(); | ||
| Object.defineProperty(this, "lg_name", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: "AsyncBatchedStore" | ||
| }); | ||
| Object.defineProperty(this, "store", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: void 0 | ||
| }); | ||
| Object.defineProperty(this, "queue", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: new Map() | ||
| }); | ||
| Object.defineProperty(this, "nextKey", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: 0 | ||
| }); | ||
| Object.defineProperty(this, "running", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: false | ||
| }); | ||
| Object.defineProperty(this, "processingTask", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: null | ||
| }); | ||
| this.store = extractStore(store); | ||
| } | ||
| get isRunning() { | ||
| return this.running; | ||
| } | ||
| /** | ||
| * @ignore | ||
| * Batch is not implemented here as we're only extending `BaseStore` | ||
| * to allow it to be passed where `BaseStore` is expected, and implement | ||
| * the convenience methods (get, search, put, delete). | ||
| */ | ||
| async batch(_operations) { | ||
| throw new Error("The `batch` method is not implemented on `AsyncBatchedStore`." + | ||
| "\n Instead, it calls the `batch` method on the wrapped store." + | ||
| "\n If you are seeing this error, something is wrong."); | ||
| } | ||
| async get(namespace, key) { | ||
| return this.enqueueOperation({ namespace, key }); | ||
| } | ||
| async search(namespacePrefix, options) { | ||
| const { filter, limit = 10, offset = 0, query } = options || {}; | ||
| return this.enqueueOperation({ | ||
| namespacePrefix, | ||
| filter, | ||
| limit, | ||
| offset, | ||
| query, | ||
| }); | ||
| } | ||
| async put(namespace, key, value) { | ||
| return this.enqueueOperation({ namespace, key, value }); | ||
| } | ||
| async delete(namespace, key) { | ||
| return this.enqueueOperation({ | ||
| namespace, | ||
| key, | ||
| value: null, | ||
| }); | ||
| } | ||
| start() { | ||
| if (!this.running) { | ||
| this.running = true; | ||
| this.processingTask = this.processBatchQueue(); | ||
| } | ||
| } | ||
| async stop() { | ||
| this.running = false; | ||
| if (this.processingTask) { | ||
| await this.processingTask; | ||
| } | ||
| } | ||
| enqueueOperation(operation) { | ||
| return new Promise((resolve, reject) => { | ||
| const key = this.nextKey; | ||
| this.nextKey += 1; | ||
| this.queue.set(key, { operation, resolve, reject }); | ||
| }); | ||
| } | ||
| async processBatchQueue() { | ||
| while (this.running) { | ||
| await new Promise((resolve) => { | ||
| setTimeout(resolve, 0); | ||
| }); | ||
| if (this.queue.size === 0) | ||
| continue; | ||
| const batch = new Map(this.queue); | ||
| this.queue.clear(); | ||
| try { | ||
| const operations = Array.from(batch.values()).map(({ operation }) => operation); | ||
| const results = await this.store.batch(operations); | ||
| batch.forEach(({ resolve }, key) => { | ||
| const index = Array.from(batch.keys()).indexOf(key); | ||
| resolve(results[index]); | ||
| }); | ||
| } | ||
| catch (e) { | ||
| batch.forEach(({ reject }) => { | ||
| reject(e); | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| // AsyncBatchedStore is internal and gets passed as args into traced tasks | ||
| // some BaseStores contain circular references so just serialize without it | ||
| // as this causes warnings when tracing with LangSmith. | ||
| toJSON() { | ||
| return { | ||
| queue: this.queue, | ||
| nextKey: this.nextKey, | ||
| running: this.running, | ||
| store: "[LangGraphStore]", | ||
| }; | ||
| } | ||
| } | ||
| var AsyncBatchedStore = class extends require_base.BaseStore { | ||
| lg_name = "AsyncBatchedStore"; | ||
| store; | ||
| queue = /* @__PURE__ */ new Map(); | ||
| nextKey = 0; | ||
| running = false; | ||
| processingTask = null; | ||
| constructor(store) { | ||
| super(); | ||
| this.store = extractStore(store); | ||
| } | ||
| get isRunning() { | ||
| return this.running; | ||
| } | ||
| /** | ||
| * @ignore | ||
| * Batch is not implemented here as we're only extending `BaseStore` | ||
| * to allow it to be passed where `BaseStore` is expected, and implement | ||
| * the convenience methods (get, search, put, delete). | ||
| */ | ||
| async batch(_operations) { | ||
| throw new Error("The `batch` method is not implemented on `AsyncBatchedStore`.\n Instead, it calls the `batch` method on the wrapped store.\n If you are seeing this error, something is wrong."); | ||
| } | ||
| async get(namespace, key) { | ||
| return this.enqueueOperation({ | ||
| namespace, | ||
| key | ||
| }); | ||
| } | ||
| async search(namespacePrefix, options) { | ||
| const { filter, limit = 10, offset = 0, query } = options || {}; | ||
| return this.enqueueOperation({ | ||
| namespacePrefix, | ||
| filter, | ||
| limit, | ||
| offset, | ||
| query | ||
| }); | ||
| } | ||
| async put(namespace, key, value) { | ||
| return this.enqueueOperation({ | ||
| namespace, | ||
| key, | ||
| value | ||
| }); | ||
| } | ||
| async delete(namespace, key) { | ||
| return this.enqueueOperation({ | ||
| namespace, | ||
| key, | ||
| value: null | ||
| }); | ||
| } | ||
| start() { | ||
| if (!this.running) { | ||
| this.running = true; | ||
| this.processingTask = this.processBatchQueue(); | ||
| } | ||
| } | ||
| async stop() { | ||
| this.running = false; | ||
| if (this.processingTask) await this.processingTask; | ||
| } | ||
| enqueueOperation(operation) { | ||
| return new Promise((resolve, reject) => { | ||
| const key = this.nextKey; | ||
| this.nextKey += 1; | ||
| this.queue.set(key, { | ||
| operation, | ||
| resolve, | ||
| reject | ||
| }); | ||
| }); | ||
| } | ||
| async processBatchQueue() { | ||
| while (this.running) { | ||
| await new Promise((resolve) => { | ||
| setTimeout(resolve, 0); | ||
| }); | ||
| if (this.queue.size === 0) continue; | ||
| const batch = new Map(this.queue); | ||
| this.queue.clear(); | ||
| try { | ||
| const operations = Array.from(batch.values()).map(({ operation }) => operation); | ||
| const results = await this.store.batch(operations); | ||
| batch.forEach(({ resolve }, key) => { | ||
| const index = Array.from(batch.keys()).indexOf(key); | ||
| resolve(results[index]); | ||
| }); | ||
| } catch (e) { | ||
| batch.forEach(({ reject }) => { | ||
| reject(e); | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| toJSON() { | ||
| return { | ||
| queue: this.queue, | ||
| nextKey: this.nextKey, | ||
| running: this.running, | ||
| store: "[LangGraphStore]" | ||
| }; | ||
| } | ||
| }; | ||
| //#endregion | ||
| exports.AsyncBatchedStore = AsyncBatchedStore; | ||
| //# sourceMappingURL=batch.js.map | ||
| //# sourceMappingURL=batch.cjs.map |
+48
-40
@@ -1,41 +0,49 @@ | ||
| import { BaseStore, type Item, type Operation, OperationResults } from "./base.js"; | ||
| export declare class AsyncBatchedStore extends BaseStore { | ||
| lg_name: string; | ||
| protected store: BaseStore; | ||
| private queue; | ||
| private nextKey; | ||
| private running; | ||
| private processingTask; | ||
| constructor(store: BaseStore); | ||
| get isRunning(): boolean; | ||
| /** | ||
| * @ignore | ||
| * Batch is not implemented here as we're only extending `BaseStore` | ||
| * to allow it to be passed where `BaseStore` is expected, and implement | ||
| * the convenience methods (get, search, put, delete). | ||
| */ | ||
| batch<Op extends Operation[]>(_operations: Op): Promise<OperationResults<Op>>; | ||
| get(namespace: string[], key: string): Promise<Item | null>; | ||
| search(namespacePrefix: string[], options?: { | ||
| filter?: Record<string, any>; | ||
| limit?: number; | ||
| offset?: number; | ||
| query?: string; | ||
| }): Promise<Item[]>; | ||
| put(namespace: string[], key: string, value: Record<string, any>): Promise<void>; | ||
| delete(namespace: string[], key: string): Promise<void>; | ||
| start(): void; | ||
| stop(): Promise<void>; | ||
| private enqueueOperation; | ||
| private processBatchQueue; | ||
| toJSON(): { | ||
| queue: Map<number, { | ||
| operation: Operation; | ||
| resolve: (value: any) => void; | ||
| reject: (reason?: any) => void; | ||
| }>; | ||
| nextKey: number; | ||
| running: boolean; | ||
| store: string; | ||
| }; | ||
| import { BaseStore, Item, Operation, OperationResults } from "./base.js"; | ||
| //#region src/store/batch.d.ts | ||
| declare class AsyncBatchedStore extends BaseStore { | ||
| lg_name: string; | ||
| protected store: BaseStore; | ||
| private queue; | ||
| private nextKey; | ||
| private running; | ||
| private processingTask; | ||
| constructor(store: BaseStore); | ||
| get isRunning(): boolean; | ||
| /** | ||
| * @ignore | ||
| * Batch is not implemented here as we're only extending `BaseStore` | ||
| * to allow it to be passed where `BaseStore` is expected, and implement | ||
| * the convenience methods (get, search, put, delete). | ||
| */ | ||
| batch<Op extends Operation[]>(_operations: Op): Promise<OperationResults<Op>>; | ||
| get(namespace: string[], key: string): Promise<Item | null>; | ||
| search(namespacePrefix: string[], options?: { | ||
| filter?: Record<string, any>; | ||
| limit?: number; | ||
| offset?: number; | ||
| query?: string; | ||
| }): Promise<Item[]>; | ||
| put(namespace: string[], key: string, value: Record<string, any>): Promise<void>; | ||
| delete(namespace: string[], key: string): Promise<void>; | ||
| start(): void; | ||
| stop(): Promise<void>; | ||
| private enqueueOperation; | ||
| private processBatchQueue; | ||
| // AsyncBatchedStore is internal and gets passed as args into traced tasks | ||
| // some BaseStores contain circular references so just serialize without it | ||
| // as this causes warnings when tracing with LangSmith. | ||
| toJSON(): { | ||
| queue: Map<number, { | ||
| operation: Operation; | ||
| resolve: (value: any) => void; | ||
| reject: (reason?: any) => void; | ||
| }>; | ||
| nextKey: number; | ||
| running: boolean; | ||
| store: string; | ||
| }; | ||
| } | ||
| //#endregion | ||
| export { AsyncBatchedStore }; | ||
| //# sourceMappingURL=batch.d.ts.map |
+116
-143
@@ -1,147 +0,120 @@ | ||
| /* eslint-disable @typescript-eslint/no-explicit-any */ | ||
| import { BaseStore, } from "./base.js"; | ||
| import { BaseStore } from "./base.js"; | ||
| //#region src/store/batch.ts | ||
| /** | ||
| * Extracts and returns the underlying store from an `AsyncBatchedStore`, | ||
| * or returns the input if it is not an `AsyncBatchedStore`. | ||
| */ | ||
| * Extracts and returns the underlying store from an `AsyncBatchedStore`, | ||
| * or returns the input if it is not an `AsyncBatchedStore`. | ||
| */ | ||
| const extractStore = (input) => { | ||
| if ("lg_name" in input && input.lg_name === "AsyncBatchedStore") { | ||
| // @ts-expect-error is a protected property | ||
| return input.store; | ||
| } | ||
| return input; | ||
| if ("lg_name" in input && input.lg_name === "AsyncBatchedStore") return input.store; | ||
| return input; | ||
| }; | ||
| export class AsyncBatchedStore extends BaseStore { | ||
| constructor(store) { | ||
| super(); | ||
| Object.defineProperty(this, "lg_name", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: "AsyncBatchedStore" | ||
| }); | ||
| Object.defineProperty(this, "store", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: void 0 | ||
| }); | ||
| Object.defineProperty(this, "queue", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: new Map() | ||
| }); | ||
| Object.defineProperty(this, "nextKey", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: 0 | ||
| }); | ||
| Object.defineProperty(this, "running", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: false | ||
| }); | ||
| Object.defineProperty(this, "processingTask", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: null | ||
| }); | ||
| this.store = extractStore(store); | ||
| } | ||
| get isRunning() { | ||
| return this.running; | ||
| } | ||
| /** | ||
| * @ignore | ||
| * Batch is not implemented here as we're only extending `BaseStore` | ||
| * to allow it to be passed where `BaseStore` is expected, and implement | ||
| * the convenience methods (get, search, put, delete). | ||
| */ | ||
| async batch(_operations) { | ||
| throw new Error("The `batch` method is not implemented on `AsyncBatchedStore`." + | ||
| "\n Instead, it calls the `batch` method on the wrapped store." + | ||
| "\n If you are seeing this error, something is wrong."); | ||
| } | ||
| async get(namespace, key) { | ||
| return this.enqueueOperation({ namespace, key }); | ||
| } | ||
| async search(namespacePrefix, options) { | ||
| const { filter, limit = 10, offset = 0, query } = options || {}; | ||
| return this.enqueueOperation({ | ||
| namespacePrefix, | ||
| filter, | ||
| limit, | ||
| offset, | ||
| query, | ||
| }); | ||
| } | ||
| async put(namespace, key, value) { | ||
| return this.enqueueOperation({ namespace, key, value }); | ||
| } | ||
| async delete(namespace, key) { | ||
| return this.enqueueOperation({ | ||
| namespace, | ||
| key, | ||
| value: null, | ||
| }); | ||
| } | ||
| start() { | ||
| if (!this.running) { | ||
| this.running = true; | ||
| this.processingTask = this.processBatchQueue(); | ||
| } | ||
| } | ||
| async stop() { | ||
| this.running = false; | ||
| if (this.processingTask) { | ||
| await this.processingTask; | ||
| } | ||
| } | ||
| enqueueOperation(operation) { | ||
| return new Promise((resolve, reject) => { | ||
| const key = this.nextKey; | ||
| this.nextKey += 1; | ||
| this.queue.set(key, { operation, resolve, reject }); | ||
| }); | ||
| } | ||
| async processBatchQueue() { | ||
| while (this.running) { | ||
| await new Promise((resolve) => { | ||
| setTimeout(resolve, 0); | ||
| }); | ||
| if (this.queue.size === 0) | ||
| continue; | ||
| const batch = new Map(this.queue); | ||
| this.queue.clear(); | ||
| try { | ||
| const operations = Array.from(batch.values()).map(({ operation }) => operation); | ||
| const results = await this.store.batch(operations); | ||
| batch.forEach(({ resolve }, key) => { | ||
| const index = Array.from(batch.keys()).indexOf(key); | ||
| resolve(results[index]); | ||
| }); | ||
| } | ||
| catch (e) { | ||
| batch.forEach(({ reject }) => { | ||
| reject(e); | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| // AsyncBatchedStore is internal and gets passed as args into traced tasks | ||
| // some BaseStores contain circular references so just serialize without it | ||
| // as this causes warnings when tracing with LangSmith. | ||
| toJSON() { | ||
| return { | ||
| queue: this.queue, | ||
| nextKey: this.nextKey, | ||
| running: this.running, | ||
| store: "[LangGraphStore]", | ||
| }; | ||
| } | ||
| } | ||
| var AsyncBatchedStore = class extends BaseStore { | ||
| lg_name = "AsyncBatchedStore"; | ||
| store; | ||
| queue = /* @__PURE__ */ new Map(); | ||
| nextKey = 0; | ||
| running = false; | ||
| processingTask = null; | ||
| constructor(store) { | ||
| super(); | ||
| this.store = extractStore(store); | ||
| } | ||
| get isRunning() { | ||
| return this.running; | ||
| } | ||
| /** | ||
| * @ignore | ||
| * Batch is not implemented here as we're only extending `BaseStore` | ||
| * to allow it to be passed where `BaseStore` is expected, and implement | ||
| * the convenience methods (get, search, put, delete). | ||
| */ | ||
| async batch(_operations) { | ||
| throw new Error("The `batch` method is not implemented on `AsyncBatchedStore`.\n Instead, it calls the `batch` method on the wrapped store.\n If you are seeing this error, something is wrong."); | ||
| } | ||
| async get(namespace, key) { | ||
| return this.enqueueOperation({ | ||
| namespace, | ||
| key | ||
| }); | ||
| } | ||
| async search(namespacePrefix, options) { | ||
| const { filter, limit = 10, offset = 0, query } = options || {}; | ||
| return this.enqueueOperation({ | ||
| namespacePrefix, | ||
| filter, | ||
| limit, | ||
| offset, | ||
| query | ||
| }); | ||
| } | ||
| async put(namespace, key, value) { | ||
| return this.enqueueOperation({ | ||
| namespace, | ||
| key, | ||
| value | ||
| }); | ||
| } | ||
| async delete(namespace, key) { | ||
| return this.enqueueOperation({ | ||
| namespace, | ||
| key, | ||
| value: null | ||
| }); | ||
| } | ||
| start() { | ||
| if (!this.running) { | ||
| this.running = true; | ||
| this.processingTask = this.processBatchQueue(); | ||
| } | ||
| } | ||
| async stop() { | ||
| this.running = false; | ||
| if (this.processingTask) await this.processingTask; | ||
| } | ||
| enqueueOperation(operation) { | ||
| return new Promise((resolve, reject) => { | ||
| const key = this.nextKey; | ||
| this.nextKey += 1; | ||
| this.queue.set(key, { | ||
| operation, | ||
| resolve, | ||
| reject | ||
| }); | ||
| }); | ||
| } | ||
| async processBatchQueue() { | ||
| while (this.running) { | ||
| await new Promise((resolve) => { | ||
| setTimeout(resolve, 0); | ||
| }); | ||
| if (this.queue.size === 0) continue; | ||
| const batch = new Map(this.queue); | ||
| this.queue.clear(); | ||
| try { | ||
| const operations = Array.from(batch.values()).map(({ operation }) => operation); | ||
| const results = await this.store.batch(operations); | ||
| batch.forEach(({ resolve }, key) => { | ||
| const index = Array.from(batch.keys()).indexOf(key); | ||
| resolve(results[index]); | ||
| }); | ||
| } catch (e) { | ||
| batch.forEach(({ reject }) => { | ||
| reject(e); | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| toJSON() { | ||
| return { | ||
| queue: this.queue, | ||
| nextKey: this.nextKey, | ||
| running: this.running, | ||
| store: "[LangGraphStore]" | ||
| }; | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { AsyncBatchedStore }; | ||
| //# sourceMappingURL=batch.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"batch.js","sourceRoot":"","sources":["../../src/store/batch.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"batch.js","names":[],"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,cAAuC,UAAU;CAC/C,UAAU;CAEV,AAAU;CAEV,AAAQ,wBAOJ,IAAI;CAER,AAAQ,UAAkB;CAE1B,AAAQ,UAAU;CAElB,AAAQ,iBAAuC;CAE/C,YAAY,OAAkB;AAC5B;AACA,OAAK,QAAQ,aAAa;;CAG5B,IAAI,YAAqB;AACvB,SAAO,KAAK;;;;;;;;CASd,MAAM,MACJ,aAC+B;AAC/B,QAAM,IAAI,MACR;;CAMJ,MAAM,IAAI,WAAqB,KAAmC;AAChE,SAAO,KAAK,iBAAiB;GAAE;GAAW;;;CAG5C,MAAM,OACJ,iBACA,SAMiB;EACjB,MAAM,EAAE,QAAQ,QAAQ,IAAI,SAAS,GAAG,UAAU,WAAW;AAC7D,SAAO,KAAK,iBAAiB;GAC3B;GACA;GACA;GACA;GACA;;;CAIJ,MAAM,IACJ,WACA,KACA,OACe;AACf,SAAO,KAAK,iBAAiB;GAAE;GAAW;GAAK;;;CAGjD,MAAM,OAAO,WAAqB,KAA4B;AAC5D,SAAO,KAAK,iBAAiB;GAC3B;GACA;GACA,OAAO;;;CAIX,QAAc;AACZ,MAAI,CAAC,KAAK,SAAS;AACjB,QAAK,UAAU;AACf,QAAK,iBAAiB,KAAK;;;CAI/B,MAAM,OAAsB;AAC1B,OAAK,UAAU;AACf,MAAI,KAAK,eACP,OAAM,KAAK;;CAIf,AAAQ,iBAAoB,WAAkC;AAC5D,SAAO,IAAI,SAAY,SAAS,WAAW;GACzC,MAAM,MAAM,KAAK;AACjB,QAAK,WAAW;AAChB,QAAK,MAAM,IAAI,KAAK;IAAE;IAAW;IAAS;;;;CAI9C,MAAc,oBAAmC;AAC/C,SAAO,KAAK,SAAS;AACnB,SAAM,IAAI,SAAS,YAAY;AAC7B,eAAW,SAAS;;AAEtB,OAAI,KAAK,MAAM,SAAS,EAAG;GAE3B,MAAM,QAAQ,IAAI,IAAI,KAAK;AAC3B,QAAK,MAAM;AAEX,OAAI;IACF,MAAM,aAAa,MAAM,KAAK,MAAM,UAAU,KAC3C,EAAE,gBAAgB;IAErB,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM;AAEvC,UAAM,SAAS,EAAE,WAAW,QAAQ;KAClC,MAAM,QAAQ,MAAM,KAAK,MAAM,QAAQ,QAAQ;AAC/C,aAAQ,QAAQ;;YAEX,GAAG;AACV,UAAM,SAAS,EAAE,aAAa;AAC5B,YAAO;;;;;CASf,SAAS;AACP,SAAO;GACL,OAAO,KAAK;GACZ,SAAS,KAAK;GACd,SAAS,KAAK;GACd,OAAO"} |
+262
-363
@@ -1,366 +0,265 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.MemoryStore = exports.InMemoryStore = void 0; | ||
| const base_js_1 = require("./base.cjs"); | ||
| const utils_js_1 = require("./utils.cjs"); | ||
| const require_base = require('./base.cjs'); | ||
| const require_utils = require('./utils.cjs'); | ||
| //#region src/store/memory.ts | ||
| /** | ||
| * In-memory key-value store with optional vector search. | ||
| * | ||
| * A lightweight store implementation using JavaScript Maps. Supports basic | ||
| * key-value operations and vector search when configured with embeddings. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Basic key-value storage | ||
| * const store = new InMemoryStore(); | ||
| * await store.put(["users", "123"], "prefs", { theme: "dark" }); | ||
| * const item = await store.get(["users", "123"], "prefs"); | ||
| * | ||
| * // Vector search with embeddings | ||
| * import { OpenAIEmbeddings } from "@langchain/openai"; | ||
| * const store = new InMemoryStore({ | ||
| * index: { | ||
| * dims: 1536, | ||
| * embeddings: new OpenAIEmbeddings({ modelName: "text-embedding-3-small" }), | ||
| * } | ||
| * }); | ||
| * | ||
| * // Store documents | ||
| * await store.put(["docs"], "doc1", { text: "Python tutorial" }); | ||
| * await store.put(["docs"], "doc2", { text: "TypeScript guide" }); | ||
| * | ||
| * // Search by similarity | ||
| * const results = await store.search(["docs"], { query: "python programming" }); | ||
| * ``` | ||
| * | ||
| * @warning This store keeps all data in memory. Data is lost when the process exits. | ||
| * For persistence, use a database-backed store. | ||
| */ | ||
| class InMemoryStore extends base_js_1.BaseStore { | ||
| constructor(options) { | ||
| super(); | ||
| Object.defineProperty(this, "data", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: new Map() | ||
| }); | ||
| // Namespace -> Key -> Path/field -> Vector | ||
| Object.defineProperty(this, "vectors", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: new Map() | ||
| }); | ||
| Object.defineProperty(this, "_indexConfig", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: void 0 | ||
| }); | ||
| if (options?.index) { | ||
| this._indexConfig = { | ||
| ...options.index, | ||
| __tokenizedFields: (options.index.fields ?? ["$"]).map((p) => [ | ||
| p, | ||
| p === "$" ? [p] : (0, utils_js_1.tokenizePath)(p), | ||
| ]), | ||
| }; | ||
| } | ||
| } | ||
| async batch(operations) { | ||
| const results = []; | ||
| const putOps = new Map(); | ||
| const searchOps = new Map(); | ||
| // First pass - handle gets and prepare search/put operations | ||
| for (let i = 0; i < operations.length; i += 1) { | ||
| const op = operations[i]; | ||
| if ("key" in op && "namespace" in op && !("value" in op)) { | ||
| // GetOperation | ||
| results.push(this.getOperation(op)); | ||
| } | ||
| else if ("namespacePrefix" in op) { | ||
| // SearchOperation | ||
| const candidates = this.filterItems(op); | ||
| searchOps.set(i, [op, candidates]); | ||
| results.push(null); | ||
| } | ||
| else if ("value" in op) { | ||
| // PutOperation | ||
| const key = `${op.namespace.join(":")}:${op.key}`; | ||
| putOps.set(key, op); | ||
| results.push(null); | ||
| } | ||
| else if ("matchConditions" in op) { | ||
| // ListNamespacesOperation | ||
| results.push(this.listNamespacesOperation(op)); | ||
| } | ||
| } | ||
| // Handle search operations with embeddings | ||
| if (searchOps.size > 0) { | ||
| if (this._indexConfig?.embeddings) { | ||
| const queries = new Set(); | ||
| for (const [op] of searchOps.values()) { | ||
| if (op.query) | ||
| queries.add(op.query); | ||
| } | ||
| // Get embeddings for all queries | ||
| const queryEmbeddings = queries.size > 0 | ||
| ? await Promise.all(Array.from(queries).map((q) => this._indexConfig.embeddings.embedQuery(q))) | ||
| : []; | ||
| const queryVectors = Object.fromEntries(Array.from(queries).map((q, i) => [q, queryEmbeddings[i]])); | ||
| // Process each search operation | ||
| for (const [i, [op, candidates]] of searchOps.entries()) { | ||
| if (op.query && queryVectors[op.query]) { | ||
| const queryVector = queryVectors[op.query]; | ||
| const scoredResults = this.scoreResults(candidates, queryVector, op.offset ?? 0, op.limit ?? 10); | ||
| results[i] = scoredResults; | ||
| } | ||
| else { | ||
| results[i] = this.paginateResults(candidates.map((item) => ({ ...item, score: undefined })), op.offset ?? 0, op.limit ?? 10); | ||
| } | ||
| } | ||
| } | ||
| else { | ||
| // No embeddings - just paginate the filtered results | ||
| for (const [i, [op, candidates]] of searchOps.entries()) { | ||
| results[i] = this.paginateResults(candidates.map((item) => ({ ...item, score: undefined })), op.offset ?? 0, op.limit ?? 10); | ||
| } | ||
| } | ||
| } | ||
| // Handle put operations with embeddings | ||
| if (putOps.size > 0 && this._indexConfig?.embeddings) { | ||
| const toEmbed = this.extractTexts(Array.from(putOps.values())); | ||
| if (Object.keys(toEmbed).length > 0) { | ||
| const embeddings = await this._indexConfig.embeddings.embedDocuments(Object.keys(toEmbed)); | ||
| this.insertVectors(toEmbed, embeddings); | ||
| } | ||
| } | ||
| // Apply all put operations | ||
| for (const op of putOps.values()) { | ||
| this.putOperation(op); | ||
| } | ||
| return results; | ||
| } | ||
| getOperation(op) { | ||
| const namespaceKey = op.namespace.join(":"); | ||
| const item = this.data.get(namespaceKey)?.get(op.key); | ||
| return item ?? null; | ||
| } | ||
| putOperation(op) { | ||
| const namespaceKey = op.namespace.join(":"); | ||
| if (!this.data.has(namespaceKey)) { | ||
| this.data.set(namespaceKey, new Map()); | ||
| } | ||
| const namespaceMap = this.data.get(namespaceKey); | ||
| if (op.value === null) { | ||
| namespaceMap.delete(op.key); | ||
| } | ||
| else { | ||
| const now = new Date(); | ||
| if (namespaceMap.has(op.key)) { | ||
| const item = namespaceMap.get(op.key); | ||
| item.value = op.value; | ||
| item.updatedAt = now; | ||
| } | ||
| else { | ||
| namespaceMap.set(op.key, { | ||
| value: op.value, | ||
| key: op.key, | ||
| namespace: op.namespace, | ||
| createdAt: now, | ||
| updatedAt: now, | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| listNamespacesOperation(op) { | ||
| const allNamespaces = Array.from(this.data.keys()).map((ns) => ns.split(":")); | ||
| let namespaces = allNamespaces; | ||
| if (op.matchConditions && op.matchConditions.length > 0) { | ||
| namespaces = namespaces.filter((ns) => op.matchConditions.every((condition) => this.doesMatch(condition, ns))); | ||
| } | ||
| if (op.maxDepth !== undefined) { | ||
| namespaces = Array.from(new Set(namespaces.map((ns) => ns.slice(0, op.maxDepth).join(":")))).map((ns) => ns.split(":")); | ||
| } | ||
| namespaces.sort((a, b) => a.join(":").localeCompare(b.join(":"))); | ||
| return namespaces.slice(op.offset ?? 0, (op.offset ?? 0) + (op.limit ?? namespaces.length)); | ||
| } | ||
| doesMatch(matchCondition, key) { | ||
| const { matchType, path } = matchCondition; | ||
| if (matchType === "prefix") { | ||
| if (path.length > key.length) | ||
| return false; | ||
| return path.every((pElem, index) => { | ||
| const kElem = key[index]; | ||
| return pElem === "*" || kElem === pElem; | ||
| }); | ||
| } | ||
| else if (matchType === "suffix") { | ||
| if (path.length > key.length) | ||
| return false; | ||
| return path.every((pElem, index) => { | ||
| const kElem = key[key.length - path.length + index]; | ||
| return pElem === "*" || kElem === pElem; | ||
| }); | ||
| } | ||
| throw new Error(`Unsupported match type: ${matchType}`); | ||
| } | ||
| filterItems(op) { | ||
| const candidates = []; | ||
| for (const [namespace, items] of this.data.entries()) { | ||
| if (namespace.startsWith(op.namespacePrefix.join(":"))) { | ||
| candidates.push(...items.values()); | ||
| } | ||
| } | ||
| let filteredCandidates = candidates; | ||
| if (op.filter) { | ||
| filteredCandidates = candidates.filter((item) => Object.entries(op.filter).every(([key, value]) => (0, utils_js_1.compareValues)(item.value[key], value))); | ||
| } | ||
| return filteredCandidates; | ||
| } | ||
| scoreResults(candidates, queryVector, offset = 0, limit = 10) { | ||
| const flatItems = []; | ||
| const flatVectors = []; | ||
| const scoreless = []; | ||
| for (const item of candidates) { | ||
| const vectors = this.getVectors(item); | ||
| if (vectors.length) { | ||
| for (const vector of vectors) { | ||
| flatItems.push(item); | ||
| flatVectors.push(vector); | ||
| } | ||
| } | ||
| else { | ||
| scoreless.push(item); | ||
| } | ||
| } | ||
| const scores = this.cosineSimilarity(queryVector, flatVectors); | ||
| const sortedResults = scores | ||
| .map((score, i) => [score, flatItems[i]]) | ||
| .sort((a, b) => b[0] - a[0]); | ||
| const seen = new Set(); | ||
| const kept = []; | ||
| for (const [score, item] of sortedResults) { | ||
| const key = `${item.namespace.join(":")}:${item.key}`; | ||
| if (seen.has(key)) | ||
| continue; | ||
| const ix = seen.size; | ||
| if (ix >= offset + limit) | ||
| break; | ||
| if (ix < offset) { | ||
| seen.add(key); | ||
| continue; | ||
| } | ||
| seen.add(key); | ||
| kept.push([score, item]); | ||
| } | ||
| if (scoreless.length && kept.length < limit) { | ||
| for (const item of scoreless.slice(0, limit - kept.length)) { | ||
| const key = `${item.namespace.join(":")}:${item.key}`; | ||
| if (!seen.has(key)) { | ||
| seen.add(key); | ||
| kept.push([undefined, item]); | ||
| } | ||
| } | ||
| } | ||
| return kept.map(([score, item]) => ({ | ||
| ...item, | ||
| score, | ||
| })); | ||
| } | ||
| paginateResults(results, offset, limit) { | ||
| return results.slice(offset, offset + limit); | ||
| } | ||
| extractTexts(ops) { | ||
| if (!ops.length || !this._indexConfig) { | ||
| return {}; | ||
| } | ||
| const toEmbed = {}; | ||
| for (const op of ops) { | ||
| if (op.value !== null && op.index !== false) { | ||
| const paths = op.index === null || op.index === undefined | ||
| ? this._indexConfig.__tokenizedFields ?? [] | ||
| : op.index.map((ix) => [ix, (0, utils_js_1.tokenizePath)(ix)]); | ||
| for (const [path, field] of paths) { | ||
| const texts = (0, utils_js_1.getTextAtPath)(op.value, field); | ||
| if (texts.length) { | ||
| if (texts.length > 1) { | ||
| texts.forEach((text, i) => { | ||
| if (!toEmbed[text]) | ||
| toEmbed[text] = []; | ||
| toEmbed[text].push([op.namespace, op.key, `${path}.${i}`]); | ||
| }); | ||
| } | ||
| else { | ||
| if (!toEmbed[texts[0]]) | ||
| toEmbed[texts[0]] = []; | ||
| toEmbed[texts[0]].push([op.namespace, op.key, path]); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return toEmbed; | ||
| } | ||
| insertVectors(texts, embeddings) { | ||
| for (const [text, metadata] of Object.entries(texts)) { | ||
| const embedding = embeddings.shift(); | ||
| if (!embedding) { | ||
| throw new Error(`No embedding found for text: ${text}`); | ||
| } | ||
| for (const [namespace, key, field] of metadata) { | ||
| const namespaceKey = namespace.join(":"); | ||
| if (!this.vectors.has(namespaceKey)) { | ||
| this.vectors.set(namespaceKey, new Map()); | ||
| } | ||
| const namespaceMap = this.vectors.get(namespaceKey); | ||
| if (!namespaceMap.has(key)) { | ||
| namespaceMap.set(key, new Map()); | ||
| } | ||
| const itemMap = namespaceMap.get(key); | ||
| itemMap.set(field, embedding); | ||
| } | ||
| } | ||
| } | ||
| getVectors(item) { | ||
| const namespaceKey = item.namespace.join(":"); | ||
| const itemKey = item.key; | ||
| if (!this.vectors.has(namespaceKey)) { | ||
| return []; | ||
| } | ||
| const namespaceMap = this.vectors.get(namespaceKey); | ||
| if (!namespaceMap.has(itemKey)) { | ||
| return []; | ||
| } | ||
| const itemMap = namespaceMap.get(itemKey); | ||
| const vectors = Array.from(itemMap.values()); | ||
| if (!vectors.length) { | ||
| return []; | ||
| } | ||
| return vectors; | ||
| } | ||
| cosineSimilarity(X, Y) { | ||
| if (!Y.length) | ||
| return []; | ||
| // Calculate dot products for all vectors at once | ||
| const dotProducts = Y.map((vector) => vector.reduce((acc, val, i) => acc + val * X[i], 0)); | ||
| // Calculate magnitudes | ||
| const magnitude1 = Math.sqrt(X.reduce((acc, val) => acc + val * val, 0)); | ||
| const magnitudes2 = Y.map((vector) => Math.sqrt(vector.reduce((acc, val) => acc + val * val, 0))); | ||
| // Calculate similarities | ||
| return dotProducts.map((dot, i) => { | ||
| const magnitude2 = magnitudes2[i]; | ||
| return magnitude1 && magnitude2 ? dot / (magnitude1 * magnitude2) : 0; | ||
| }); | ||
| } | ||
| get indexConfig() { | ||
| return this._indexConfig; | ||
| } | ||
| } | ||
| * In-memory key-value store with optional vector search. | ||
| * | ||
| * A lightweight store implementation using JavaScript Maps. Supports basic | ||
| * key-value operations and vector search when configured with embeddings. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Basic key-value storage | ||
| * const store = new InMemoryStore(); | ||
| * await store.put(["users", "123"], "prefs", { theme: "dark" }); | ||
| * const item = await store.get(["users", "123"], "prefs"); | ||
| * | ||
| * // Vector search with embeddings | ||
| * import { OpenAIEmbeddings } from "@langchain/openai"; | ||
| * const store = new InMemoryStore({ | ||
| * index: { | ||
| * dims: 1536, | ||
| * embeddings: new OpenAIEmbeddings({ modelName: "text-embedding-3-small" }), | ||
| * } | ||
| * }); | ||
| * | ||
| * // Store documents | ||
| * await store.put(["docs"], "doc1", { text: "Python tutorial" }); | ||
| * await store.put(["docs"], "doc2", { text: "TypeScript guide" }); | ||
| * | ||
| * // Search by similarity | ||
| * const results = await store.search(["docs"], { query: "python programming" }); | ||
| * ``` | ||
| * | ||
| * **Warning**: This store keeps all data in memory. Data is lost when the process exits. | ||
| * For persistence, use a database-backed store. | ||
| */ | ||
| var InMemoryStore = class extends require_base.BaseStore { | ||
| data = /* @__PURE__ */ new Map(); | ||
| vectors = /* @__PURE__ */ new Map(); | ||
| _indexConfig; | ||
| constructor(options) { | ||
| super(); | ||
| if (options?.index) this._indexConfig = { | ||
| ...options.index, | ||
| __tokenizedFields: (options.index.fields ?? ["$"]).map((p) => [p, p === "$" ? [p] : require_utils.tokenizePath(p)]) | ||
| }; | ||
| } | ||
| async batch(operations) { | ||
| const results = []; | ||
| const putOps = /* @__PURE__ */ new Map(); | ||
| const searchOps = /* @__PURE__ */ new Map(); | ||
| for (let i = 0; i < operations.length; i += 1) { | ||
| const op = operations[i]; | ||
| if ("key" in op && "namespace" in op && !("value" in op)) results.push(this.getOperation(op)); | ||
| else if ("namespacePrefix" in op) { | ||
| const candidates = this.filterItems(op); | ||
| searchOps.set(i, [op, candidates]); | ||
| results.push(null); | ||
| } else if ("value" in op) { | ||
| const key = `${op.namespace.join(":")}:${op.key}`; | ||
| putOps.set(key, op); | ||
| results.push(null); | ||
| } else if ("matchConditions" in op) results.push(this.listNamespacesOperation(op)); | ||
| } | ||
| if (searchOps.size > 0) if (this._indexConfig?.embeddings) { | ||
| const queries = /* @__PURE__ */ new Set(); | ||
| for (const [op] of searchOps.values()) if (op.query) queries.add(op.query); | ||
| const queryEmbeddings = queries.size > 0 ? await Promise.all(Array.from(queries).map((q) => this._indexConfig.embeddings.embedQuery(q))) : []; | ||
| const queryVectors = Object.fromEntries(Array.from(queries).map((q, i) => [q, queryEmbeddings[i]])); | ||
| for (const [i, [op, candidates]] of searchOps.entries()) if (op.query && queryVectors[op.query]) { | ||
| const queryVector = queryVectors[op.query]; | ||
| const scoredResults = this.scoreResults(candidates, queryVector, op.offset ?? 0, op.limit ?? 10); | ||
| results[i] = scoredResults; | ||
| } else results[i] = this.paginateResults(candidates.map((item) => ({ | ||
| ...item, | ||
| score: void 0 | ||
| })), op.offset ?? 0, op.limit ?? 10); | ||
| } else for (const [i, [op, candidates]] of searchOps.entries()) results[i] = this.paginateResults(candidates.map((item) => ({ | ||
| ...item, | ||
| score: void 0 | ||
| })), op.offset ?? 0, op.limit ?? 10); | ||
| if (putOps.size > 0 && this._indexConfig?.embeddings) { | ||
| const toEmbed = this.extractTexts(Array.from(putOps.values())); | ||
| if (Object.keys(toEmbed).length > 0) { | ||
| const embeddings = await this._indexConfig.embeddings.embedDocuments(Object.keys(toEmbed)); | ||
| this.insertVectors(toEmbed, embeddings); | ||
| } | ||
| } | ||
| for (const op of putOps.values()) this.putOperation(op); | ||
| return results; | ||
| } | ||
| getOperation(op) { | ||
| const namespaceKey = op.namespace.join(":"); | ||
| const item = this.data.get(namespaceKey)?.get(op.key); | ||
| return item ?? null; | ||
| } | ||
| putOperation(op) { | ||
| const namespaceKey = op.namespace.join(":"); | ||
| if (!this.data.has(namespaceKey)) this.data.set(namespaceKey, /* @__PURE__ */ new Map()); | ||
| const namespaceMap = this.data.get(namespaceKey); | ||
| if (op.value === null) namespaceMap.delete(op.key); | ||
| else { | ||
| const now = /* @__PURE__ */ new Date(); | ||
| if (namespaceMap.has(op.key)) { | ||
| const item = namespaceMap.get(op.key); | ||
| item.value = op.value; | ||
| item.updatedAt = now; | ||
| } else namespaceMap.set(op.key, { | ||
| value: op.value, | ||
| key: op.key, | ||
| namespace: op.namespace, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }); | ||
| } | ||
| } | ||
| listNamespacesOperation(op) { | ||
| const allNamespaces = Array.from(this.data.keys()).map((ns) => ns.split(":")); | ||
| let namespaces = allNamespaces; | ||
| if (op.matchConditions && op.matchConditions.length > 0) namespaces = namespaces.filter((ns) => op.matchConditions.every((condition) => this.doesMatch(condition, ns))); | ||
| if (op.maxDepth !== void 0) namespaces = Array.from(new Set(namespaces.map((ns) => ns.slice(0, op.maxDepth).join(":")))).map((ns) => ns.split(":")); | ||
| namespaces.sort((a, b) => a.join(":").localeCompare(b.join(":"))); | ||
| return namespaces.slice(op.offset ?? 0, (op.offset ?? 0) + (op.limit ?? namespaces.length)); | ||
| } | ||
| doesMatch(matchCondition, key) { | ||
| const { matchType, path } = matchCondition; | ||
| if (matchType === "prefix") { | ||
| if (path.length > key.length) return false; | ||
| return path.every((pElem, index) => { | ||
| const kElem = key[index]; | ||
| return pElem === "*" || kElem === pElem; | ||
| }); | ||
| } else if (matchType === "suffix") { | ||
| if (path.length > key.length) return false; | ||
| return path.every((pElem, index) => { | ||
| const kElem = key[key.length - path.length + index]; | ||
| return pElem === "*" || kElem === pElem; | ||
| }); | ||
| } | ||
| throw new Error(`Unsupported match type: ${matchType}`); | ||
| } | ||
| filterItems(op) { | ||
| const candidates = []; | ||
| for (const [namespace, items] of this.data.entries()) if (namespace.startsWith(op.namespacePrefix.join(":"))) candidates.push(...items.values()); | ||
| let filteredCandidates = candidates; | ||
| if (op.filter) filteredCandidates = candidates.filter((item) => Object.entries(op.filter).every(([key, value]) => require_utils.compareValues(item.value[key], value))); | ||
| return filteredCandidates; | ||
| } | ||
| scoreResults(candidates, queryVector, offset = 0, limit = 10) { | ||
| const flatItems = []; | ||
| const flatVectors = []; | ||
| const scoreless = []; | ||
| for (const item of candidates) { | ||
| const vectors = this.getVectors(item); | ||
| if (vectors.length) for (const vector of vectors) { | ||
| flatItems.push(item); | ||
| flatVectors.push(vector); | ||
| } | ||
| else scoreless.push(item); | ||
| } | ||
| const scores = this.cosineSimilarity(queryVector, flatVectors); | ||
| const sortedResults = scores.map((score, i) => [score, flatItems[i]]).sort((a, b) => b[0] - a[0]); | ||
| const seen = /* @__PURE__ */ new Set(); | ||
| const kept = []; | ||
| for (const [score, item] of sortedResults) { | ||
| const key = `${item.namespace.join(":")}:${item.key}`; | ||
| if (seen.has(key)) continue; | ||
| const ix = seen.size; | ||
| if (ix >= offset + limit) break; | ||
| if (ix < offset) { | ||
| seen.add(key); | ||
| continue; | ||
| } | ||
| seen.add(key); | ||
| kept.push([score, item]); | ||
| } | ||
| if (scoreless.length && kept.length < limit) for (const item of scoreless.slice(0, limit - kept.length)) { | ||
| const key = `${item.namespace.join(":")}:${item.key}`; | ||
| if (!seen.has(key)) { | ||
| seen.add(key); | ||
| kept.push([void 0, item]); | ||
| } | ||
| } | ||
| return kept.map(([score, item]) => ({ | ||
| ...item, | ||
| score | ||
| })); | ||
| } | ||
| paginateResults(results, offset, limit) { | ||
| return results.slice(offset, offset + limit); | ||
| } | ||
| extractTexts(ops) { | ||
| if (!ops.length || !this._indexConfig) return {}; | ||
| const toEmbed = {}; | ||
| for (const op of ops) if (op.value !== null && op.index !== false) { | ||
| const paths = op.index === null || op.index === void 0 ? this._indexConfig.__tokenizedFields ?? [] : op.index.map((ix) => [ix, require_utils.tokenizePath(ix)]); | ||
| for (const [path, field] of paths) { | ||
| const texts = require_utils.getTextAtPath(op.value, field); | ||
| if (texts.length) if (texts.length > 1) texts.forEach((text, i) => { | ||
| if (!toEmbed[text]) toEmbed[text] = []; | ||
| toEmbed[text].push([ | ||
| op.namespace, | ||
| op.key, | ||
| `${path}.${i}` | ||
| ]); | ||
| }); | ||
| else { | ||
| if (!toEmbed[texts[0]]) toEmbed[texts[0]] = []; | ||
| toEmbed[texts[0]].push([ | ||
| op.namespace, | ||
| op.key, | ||
| path | ||
| ]); | ||
| } | ||
| } | ||
| } | ||
| return toEmbed; | ||
| } | ||
| insertVectors(texts, embeddings) { | ||
| for (const [text, metadata] of Object.entries(texts)) { | ||
| const embedding = embeddings.shift(); | ||
| if (!embedding) throw new Error(`No embedding found for text: ${text}`); | ||
| for (const [namespace, key, field] of metadata) { | ||
| const namespaceKey = namespace.join(":"); | ||
| if (!this.vectors.has(namespaceKey)) this.vectors.set(namespaceKey, /* @__PURE__ */ new Map()); | ||
| const namespaceMap = this.vectors.get(namespaceKey); | ||
| if (!namespaceMap.has(key)) namespaceMap.set(key, /* @__PURE__ */ new Map()); | ||
| const itemMap = namespaceMap.get(key); | ||
| itemMap.set(field, embedding); | ||
| } | ||
| } | ||
| } | ||
| getVectors(item) { | ||
| const namespaceKey = item.namespace.join(":"); | ||
| const itemKey = item.key; | ||
| if (!this.vectors.has(namespaceKey)) return []; | ||
| const namespaceMap = this.vectors.get(namespaceKey); | ||
| if (!namespaceMap.has(itemKey)) return []; | ||
| const itemMap = namespaceMap.get(itemKey); | ||
| const vectors = Array.from(itemMap.values()); | ||
| if (!vectors.length) return []; | ||
| return vectors; | ||
| } | ||
| cosineSimilarity(X, Y) { | ||
| if (!Y.length) return []; | ||
| const dotProducts = Y.map((vector) => vector.reduce((acc, val, i) => acc + val * X[i], 0)); | ||
| const magnitude1 = Math.sqrt(X.reduce((acc, val) => acc + val * val, 0)); | ||
| const magnitudes2 = Y.map((vector) => Math.sqrt(vector.reduce((acc, val) => acc + val * val, 0))); | ||
| return dotProducts.map((dot, i) => { | ||
| const magnitude2 = magnitudes2[i]; | ||
| return magnitude1 && magnitude2 ? dot / (magnitude1 * magnitude2) : 0; | ||
| }); | ||
| } | ||
| get indexConfig() { | ||
| return this._indexConfig; | ||
| } | ||
| }; | ||
| /** @deprecated Alias for InMemoryStore */ | ||
| var MemoryStore = class extends InMemoryStore {}; | ||
| //#endregion | ||
| exports.InMemoryStore = InMemoryStore; | ||
| /** @deprecated Alias for InMemoryStore */ | ||
| class MemoryStore extends InMemoryStore { | ||
| } | ||
| exports.MemoryStore = MemoryStore; | ||
| //# sourceMappingURL=memory.js.map | ||
| //# sourceMappingURL=memory.cjs.map |
+30
-24
@@ -1,2 +0,5 @@ | ||
| import { BaseStore, type OperationResults, type Operation, type IndexConfig } from "./base.js"; | ||
| import { BaseStore, IndexConfig, Operation, OperationResults } from "./base.js"; | ||
| //#region src/store/memory.d.ts | ||
| /** | ||
@@ -32,28 +35,31 @@ * In-memory key-value store with optional vector search. | ||
| * | ||
| * @warning This store keeps all data in memory. Data is lost when the process exits. | ||
| * **Warning**: This store keeps all data in memory. Data is lost when the process exits. | ||
| * For persistence, use a database-backed store. | ||
| */ | ||
| export declare class InMemoryStore extends BaseStore { | ||
| private data; | ||
| private vectors; | ||
| private _indexConfig?; | ||
| constructor(options?: { | ||
| index?: IndexConfig; | ||
| }); | ||
| batch<Op extends readonly Operation[]>(operations: Op): Promise<OperationResults<Op>>; | ||
| private getOperation; | ||
| private putOperation; | ||
| private listNamespacesOperation; | ||
| private doesMatch; | ||
| private filterItems; | ||
| private scoreResults; | ||
| private paginateResults; | ||
| private extractTexts; | ||
| private insertVectors; | ||
| private getVectors; | ||
| private cosineSimilarity; | ||
| get indexConfig(): IndexConfig | undefined; | ||
| declare class InMemoryStore extends BaseStore { | ||
| private data; | ||
| // Namespace -> Key -> Path/field -> Vector | ||
| private vectors; | ||
| private _indexConfig?; | ||
| constructor(options?: { | ||
| index?: IndexConfig; | ||
| }); | ||
| batch<Op extends readonly Operation[]>(operations: Op): Promise<OperationResults<Op>>; | ||
| private getOperation; | ||
| private putOperation; | ||
| private listNamespacesOperation; | ||
| private doesMatch; | ||
| private filterItems; | ||
| private scoreResults; | ||
| private paginateResults; | ||
| private extractTexts; | ||
| private insertVectors; | ||
| private getVectors; | ||
| private cosineSimilarity; | ||
| get indexConfig(): IndexConfig | undefined; | ||
| } | ||
| /** @deprecated Alias for InMemoryStore */ | ||
| export declare class MemoryStore extends InMemoryStore { | ||
| } | ||
| declare class MemoryStore extends InMemoryStore {} | ||
| //#endregion | ||
| export { InMemoryStore, MemoryStore }; | ||
| //# sourceMappingURL=memory.d.ts.map |
+261
-358
@@ -1,361 +0,264 @@ | ||
| import { BaseStore, } from "./base.js"; | ||
| import { tokenizePath, compareValues, getTextAtPath } from "./utils.js"; | ||
| import { BaseStore } from "./base.js"; | ||
| import { compareValues, getTextAtPath, tokenizePath } from "./utils.js"; | ||
| //#region src/store/memory.ts | ||
| /** | ||
| * In-memory key-value store with optional vector search. | ||
| * | ||
| * A lightweight store implementation using JavaScript Maps. Supports basic | ||
| * key-value operations and vector search when configured with embeddings. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Basic key-value storage | ||
| * const store = new InMemoryStore(); | ||
| * await store.put(["users", "123"], "prefs", { theme: "dark" }); | ||
| * const item = await store.get(["users", "123"], "prefs"); | ||
| * | ||
| * // Vector search with embeddings | ||
| * import { OpenAIEmbeddings } from "@langchain/openai"; | ||
| * const store = new InMemoryStore({ | ||
| * index: { | ||
| * dims: 1536, | ||
| * embeddings: new OpenAIEmbeddings({ modelName: "text-embedding-3-small" }), | ||
| * } | ||
| * }); | ||
| * | ||
| * // Store documents | ||
| * await store.put(["docs"], "doc1", { text: "Python tutorial" }); | ||
| * await store.put(["docs"], "doc2", { text: "TypeScript guide" }); | ||
| * | ||
| * // Search by similarity | ||
| * const results = await store.search(["docs"], { query: "python programming" }); | ||
| * ``` | ||
| * | ||
| * @warning This store keeps all data in memory. Data is lost when the process exits. | ||
| * For persistence, use a database-backed store. | ||
| */ | ||
| export class InMemoryStore extends BaseStore { | ||
| constructor(options) { | ||
| super(); | ||
| Object.defineProperty(this, "data", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: new Map() | ||
| }); | ||
| // Namespace -> Key -> Path/field -> Vector | ||
| Object.defineProperty(this, "vectors", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: new Map() | ||
| }); | ||
| Object.defineProperty(this, "_indexConfig", { | ||
| enumerable: true, | ||
| configurable: true, | ||
| writable: true, | ||
| value: void 0 | ||
| }); | ||
| if (options?.index) { | ||
| this._indexConfig = { | ||
| ...options.index, | ||
| __tokenizedFields: (options.index.fields ?? ["$"]).map((p) => [ | ||
| p, | ||
| p === "$" ? [p] : tokenizePath(p), | ||
| ]), | ||
| }; | ||
| } | ||
| } | ||
| async batch(operations) { | ||
| const results = []; | ||
| const putOps = new Map(); | ||
| const searchOps = new Map(); | ||
| // First pass - handle gets and prepare search/put operations | ||
| for (let i = 0; i < operations.length; i += 1) { | ||
| const op = operations[i]; | ||
| if ("key" in op && "namespace" in op && !("value" in op)) { | ||
| // GetOperation | ||
| results.push(this.getOperation(op)); | ||
| } | ||
| else if ("namespacePrefix" in op) { | ||
| // SearchOperation | ||
| const candidates = this.filterItems(op); | ||
| searchOps.set(i, [op, candidates]); | ||
| results.push(null); | ||
| } | ||
| else if ("value" in op) { | ||
| // PutOperation | ||
| const key = `${op.namespace.join(":")}:${op.key}`; | ||
| putOps.set(key, op); | ||
| results.push(null); | ||
| } | ||
| else if ("matchConditions" in op) { | ||
| // ListNamespacesOperation | ||
| results.push(this.listNamespacesOperation(op)); | ||
| } | ||
| } | ||
| // Handle search operations with embeddings | ||
| if (searchOps.size > 0) { | ||
| if (this._indexConfig?.embeddings) { | ||
| const queries = new Set(); | ||
| for (const [op] of searchOps.values()) { | ||
| if (op.query) | ||
| queries.add(op.query); | ||
| } | ||
| // Get embeddings for all queries | ||
| const queryEmbeddings = queries.size > 0 | ||
| ? await Promise.all(Array.from(queries).map((q) => this._indexConfig.embeddings.embedQuery(q))) | ||
| : []; | ||
| const queryVectors = Object.fromEntries(Array.from(queries).map((q, i) => [q, queryEmbeddings[i]])); | ||
| // Process each search operation | ||
| for (const [i, [op, candidates]] of searchOps.entries()) { | ||
| if (op.query && queryVectors[op.query]) { | ||
| const queryVector = queryVectors[op.query]; | ||
| const scoredResults = this.scoreResults(candidates, queryVector, op.offset ?? 0, op.limit ?? 10); | ||
| results[i] = scoredResults; | ||
| } | ||
| else { | ||
| results[i] = this.paginateResults(candidates.map((item) => ({ ...item, score: undefined })), op.offset ?? 0, op.limit ?? 10); | ||
| } | ||
| } | ||
| } | ||
| else { | ||
| // No embeddings - just paginate the filtered results | ||
| for (const [i, [op, candidates]] of searchOps.entries()) { | ||
| results[i] = this.paginateResults(candidates.map((item) => ({ ...item, score: undefined })), op.offset ?? 0, op.limit ?? 10); | ||
| } | ||
| } | ||
| } | ||
| // Handle put operations with embeddings | ||
| if (putOps.size > 0 && this._indexConfig?.embeddings) { | ||
| const toEmbed = this.extractTexts(Array.from(putOps.values())); | ||
| if (Object.keys(toEmbed).length > 0) { | ||
| const embeddings = await this._indexConfig.embeddings.embedDocuments(Object.keys(toEmbed)); | ||
| this.insertVectors(toEmbed, embeddings); | ||
| } | ||
| } | ||
| // Apply all put operations | ||
| for (const op of putOps.values()) { | ||
| this.putOperation(op); | ||
| } | ||
| return results; | ||
| } | ||
| getOperation(op) { | ||
| const namespaceKey = op.namespace.join(":"); | ||
| const item = this.data.get(namespaceKey)?.get(op.key); | ||
| return item ?? null; | ||
| } | ||
| putOperation(op) { | ||
| const namespaceKey = op.namespace.join(":"); | ||
| if (!this.data.has(namespaceKey)) { | ||
| this.data.set(namespaceKey, new Map()); | ||
| } | ||
| const namespaceMap = this.data.get(namespaceKey); | ||
| if (op.value === null) { | ||
| namespaceMap.delete(op.key); | ||
| } | ||
| else { | ||
| const now = new Date(); | ||
| if (namespaceMap.has(op.key)) { | ||
| const item = namespaceMap.get(op.key); | ||
| item.value = op.value; | ||
| item.updatedAt = now; | ||
| } | ||
| else { | ||
| namespaceMap.set(op.key, { | ||
| value: op.value, | ||
| key: op.key, | ||
| namespace: op.namespace, | ||
| createdAt: now, | ||
| updatedAt: now, | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| listNamespacesOperation(op) { | ||
| const allNamespaces = Array.from(this.data.keys()).map((ns) => ns.split(":")); | ||
| let namespaces = allNamespaces; | ||
| if (op.matchConditions && op.matchConditions.length > 0) { | ||
| namespaces = namespaces.filter((ns) => op.matchConditions.every((condition) => this.doesMatch(condition, ns))); | ||
| } | ||
| if (op.maxDepth !== undefined) { | ||
| namespaces = Array.from(new Set(namespaces.map((ns) => ns.slice(0, op.maxDepth).join(":")))).map((ns) => ns.split(":")); | ||
| } | ||
| namespaces.sort((a, b) => a.join(":").localeCompare(b.join(":"))); | ||
| return namespaces.slice(op.offset ?? 0, (op.offset ?? 0) + (op.limit ?? namespaces.length)); | ||
| } | ||
| doesMatch(matchCondition, key) { | ||
| const { matchType, path } = matchCondition; | ||
| if (matchType === "prefix") { | ||
| if (path.length > key.length) | ||
| return false; | ||
| return path.every((pElem, index) => { | ||
| const kElem = key[index]; | ||
| return pElem === "*" || kElem === pElem; | ||
| }); | ||
| } | ||
| else if (matchType === "suffix") { | ||
| if (path.length > key.length) | ||
| return false; | ||
| return path.every((pElem, index) => { | ||
| const kElem = key[key.length - path.length + index]; | ||
| return pElem === "*" || kElem === pElem; | ||
| }); | ||
| } | ||
| throw new Error(`Unsupported match type: ${matchType}`); | ||
| } | ||
| filterItems(op) { | ||
| const candidates = []; | ||
| for (const [namespace, items] of this.data.entries()) { | ||
| if (namespace.startsWith(op.namespacePrefix.join(":"))) { | ||
| candidates.push(...items.values()); | ||
| } | ||
| } | ||
| let filteredCandidates = candidates; | ||
| if (op.filter) { | ||
| filteredCandidates = candidates.filter((item) => Object.entries(op.filter).every(([key, value]) => compareValues(item.value[key], value))); | ||
| } | ||
| return filteredCandidates; | ||
| } | ||
| scoreResults(candidates, queryVector, offset = 0, limit = 10) { | ||
| const flatItems = []; | ||
| const flatVectors = []; | ||
| const scoreless = []; | ||
| for (const item of candidates) { | ||
| const vectors = this.getVectors(item); | ||
| if (vectors.length) { | ||
| for (const vector of vectors) { | ||
| flatItems.push(item); | ||
| flatVectors.push(vector); | ||
| } | ||
| } | ||
| else { | ||
| scoreless.push(item); | ||
| } | ||
| } | ||
| const scores = this.cosineSimilarity(queryVector, flatVectors); | ||
| const sortedResults = scores | ||
| .map((score, i) => [score, flatItems[i]]) | ||
| .sort((a, b) => b[0] - a[0]); | ||
| const seen = new Set(); | ||
| const kept = []; | ||
| for (const [score, item] of sortedResults) { | ||
| const key = `${item.namespace.join(":")}:${item.key}`; | ||
| if (seen.has(key)) | ||
| continue; | ||
| const ix = seen.size; | ||
| if (ix >= offset + limit) | ||
| break; | ||
| if (ix < offset) { | ||
| seen.add(key); | ||
| continue; | ||
| } | ||
| seen.add(key); | ||
| kept.push([score, item]); | ||
| } | ||
| if (scoreless.length && kept.length < limit) { | ||
| for (const item of scoreless.slice(0, limit - kept.length)) { | ||
| const key = `${item.namespace.join(":")}:${item.key}`; | ||
| if (!seen.has(key)) { | ||
| seen.add(key); | ||
| kept.push([undefined, item]); | ||
| } | ||
| } | ||
| } | ||
| return kept.map(([score, item]) => ({ | ||
| ...item, | ||
| score, | ||
| })); | ||
| } | ||
| paginateResults(results, offset, limit) { | ||
| return results.slice(offset, offset + limit); | ||
| } | ||
| extractTexts(ops) { | ||
| if (!ops.length || !this._indexConfig) { | ||
| return {}; | ||
| } | ||
| const toEmbed = {}; | ||
| for (const op of ops) { | ||
| if (op.value !== null && op.index !== false) { | ||
| const paths = op.index === null || op.index === undefined | ||
| ? this._indexConfig.__tokenizedFields ?? [] | ||
| : op.index.map((ix) => [ix, tokenizePath(ix)]); | ||
| for (const [path, field] of paths) { | ||
| const texts = getTextAtPath(op.value, field); | ||
| if (texts.length) { | ||
| if (texts.length > 1) { | ||
| texts.forEach((text, i) => { | ||
| if (!toEmbed[text]) | ||
| toEmbed[text] = []; | ||
| toEmbed[text].push([op.namespace, op.key, `${path}.${i}`]); | ||
| }); | ||
| } | ||
| else { | ||
| if (!toEmbed[texts[0]]) | ||
| toEmbed[texts[0]] = []; | ||
| toEmbed[texts[0]].push([op.namespace, op.key, path]); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return toEmbed; | ||
| } | ||
| insertVectors(texts, embeddings) { | ||
| for (const [text, metadata] of Object.entries(texts)) { | ||
| const embedding = embeddings.shift(); | ||
| if (!embedding) { | ||
| throw new Error(`No embedding found for text: ${text}`); | ||
| } | ||
| for (const [namespace, key, field] of metadata) { | ||
| const namespaceKey = namespace.join(":"); | ||
| if (!this.vectors.has(namespaceKey)) { | ||
| this.vectors.set(namespaceKey, new Map()); | ||
| } | ||
| const namespaceMap = this.vectors.get(namespaceKey); | ||
| if (!namespaceMap.has(key)) { | ||
| namespaceMap.set(key, new Map()); | ||
| } | ||
| const itemMap = namespaceMap.get(key); | ||
| itemMap.set(field, embedding); | ||
| } | ||
| } | ||
| } | ||
| getVectors(item) { | ||
| const namespaceKey = item.namespace.join(":"); | ||
| const itemKey = item.key; | ||
| if (!this.vectors.has(namespaceKey)) { | ||
| return []; | ||
| } | ||
| const namespaceMap = this.vectors.get(namespaceKey); | ||
| if (!namespaceMap.has(itemKey)) { | ||
| return []; | ||
| } | ||
| const itemMap = namespaceMap.get(itemKey); | ||
| const vectors = Array.from(itemMap.values()); | ||
| if (!vectors.length) { | ||
| return []; | ||
| } | ||
| return vectors; | ||
| } | ||
| cosineSimilarity(X, Y) { | ||
| if (!Y.length) | ||
| return []; | ||
| // Calculate dot products for all vectors at once | ||
| const dotProducts = Y.map((vector) => vector.reduce((acc, val, i) => acc + val * X[i], 0)); | ||
| // Calculate magnitudes | ||
| const magnitude1 = Math.sqrt(X.reduce((acc, val) => acc + val * val, 0)); | ||
| const magnitudes2 = Y.map((vector) => Math.sqrt(vector.reduce((acc, val) => acc + val * val, 0))); | ||
| // Calculate similarities | ||
| return dotProducts.map((dot, i) => { | ||
| const magnitude2 = magnitudes2[i]; | ||
| return magnitude1 && magnitude2 ? dot / (magnitude1 * magnitude2) : 0; | ||
| }); | ||
| } | ||
| get indexConfig() { | ||
| return this._indexConfig; | ||
| } | ||
| } | ||
| * In-memory key-value store with optional vector search. | ||
| * | ||
| * A lightweight store implementation using JavaScript Maps. Supports basic | ||
| * key-value operations and vector search when configured with embeddings. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Basic key-value storage | ||
| * const store = new InMemoryStore(); | ||
| * await store.put(["users", "123"], "prefs", { theme: "dark" }); | ||
| * const item = await store.get(["users", "123"], "prefs"); | ||
| * | ||
| * // Vector search with embeddings | ||
| * import { OpenAIEmbeddings } from "@langchain/openai"; | ||
| * const store = new InMemoryStore({ | ||
| * index: { | ||
| * dims: 1536, | ||
| * embeddings: new OpenAIEmbeddings({ modelName: "text-embedding-3-small" }), | ||
| * } | ||
| * }); | ||
| * | ||
| * // Store documents | ||
| * await store.put(["docs"], "doc1", { text: "Python tutorial" }); | ||
| * await store.put(["docs"], "doc2", { text: "TypeScript guide" }); | ||
| * | ||
| * // Search by similarity | ||
| * const results = await store.search(["docs"], { query: "python programming" }); | ||
| * ``` | ||
| * | ||
| * **Warning**: This store keeps all data in memory. Data is lost when the process exits. | ||
| * For persistence, use a database-backed store. | ||
| */ | ||
| var InMemoryStore = class extends BaseStore { | ||
| data = /* @__PURE__ */ new Map(); | ||
| vectors = /* @__PURE__ */ new Map(); | ||
| _indexConfig; | ||
| constructor(options) { | ||
| super(); | ||
| if (options?.index) this._indexConfig = { | ||
| ...options.index, | ||
| __tokenizedFields: (options.index.fields ?? ["$"]).map((p) => [p, p === "$" ? [p] : tokenizePath(p)]) | ||
| }; | ||
| } | ||
| async batch(operations) { | ||
| const results = []; | ||
| const putOps = /* @__PURE__ */ new Map(); | ||
| const searchOps = /* @__PURE__ */ new Map(); | ||
| for (let i = 0; i < operations.length; i += 1) { | ||
| const op = operations[i]; | ||
| if ("key" in op && "namespace" in op && !("value" in op)) results.push(this.getOperation(op)); | ||
| else if ("namespacePrefix" in op) { | ||
| const candidates = this.filterItems(op); | ||
| searchOps.set(i, [op, candidates]); | ||
| results.push(null); | ||
| } else if ("value" in op) { | ||
| const key = `${op.namespace.join(":")}:${op.key}`; | ||
| putOps.set(key, op); | ||
| results.push(null); | ||
| } else if ("matchConditions" in op) results.push(this.listNamespacesOperation(op)); | ||
| } | ||
| if (searchOps.size > 0) if (this._indexConfig?.embeddings) { | ||
| const queries = /* @__PURE__ */ new Set(); | ||
| for (const [op] of searchOps.values()) if (op.query) queries.add(op.query); | ||
| const queryEmbeddings = queries.size > 0 ? await Promise.all(Array.from(queries).map((q) => this._indexConfig.embeddings.embedQuery(q))) : []; | ||
| const queryVectors = Object.fromEntries(Array.from(queries).map((q, i) => [q, queryEmbeddings[i]])); | ||
| for (const [i, [op, candidates]] of searchOps.entries()) if (op.query && queryVectors[op.query]) { | ||
| const queryVector = queryVectors[op.query]; | ||
| const scoredResults = this.scoreResults(candidates, queryVector, op.offset ?? 0, op.limit ?? 10); | ||
| results[i] = scoredResults; | ||
| } else results[i] = this.paginateResults(candidates.map((item) => ({ | ||
| ...item, | ||
| score: void 0 | ||
| })), op.offset ?? 0, op.limit ?? 10); | ||
| } else for (const [i, [op, candidates]] of searchOps.entries()) results[i] = this.paginateResults(candidates.map((item) => ({ | ||
| ...item, | ||
| score: void 0 | ||
| })), op.offset ?? 0, op.limit ?? 10); | ||
| if (putOps.size > 0 && this._indexConfig?.embeddings) { | ||
| const toEmbed = this.extractTexts(Array.from(putOps.values())); | ||
| if (Object.keys(toEmbed).length > 0) { | ||
| const embeddings = await this._indexConfig.embeddings.embedDocuments(Object.keys(toEmbed)); | ||
| this.insertVectors(toEmbed, embeddings); | ||
| } | ||
| } | ||
| for (const op of putOps.values()) this.putOperation(op); | ||
| return results; | ||
| } | ||
| getOperation(op) { | ||
| const namespaceKey = op.namespace.join(":"); | ||
| const item = this.data.get(namespaceKey)?.get(op.key); | ||
| return item ?? null; | ||
| } | ||
| putOperation(op) { | ||
| const namespaceKey = op.namespace.join(":"); | ||
| if (!this.data.has(namespaceKey)) this.data.set(namespaceKey, /* @__PURE__ */ new Map()); | ||
| const namespaceMap = this.data.get(namespaceKey); | ||
| if (op.value === null) namespaceMap.delete(op.key); | ||
| else { | ||
| const now = /* @__PURE__ */ new Date(); | ||
| if (namespaceMap.has(op.key)) { | ||
| const item = namespaceMap.get(op.key); | ||
| item.value = op.value; | ||
| item.updatedAt = now; | ||
| } else namespaceMap.set(op.key, { | ||
| value: op.value, | ||
| key: op.key, | ||
| namespace: op.namespace, | ||
| createdAt: now, | ||
| updatedAt: now | ||
| }); | ||
| } | ||
| } | ||
| listNamespacesOperation(op) { | ||
| const allNamespaces = Array.from(this.data.keys()).map((ns) => ns.split(":")); | ||
| let namespaces = allNamespaces; | ||
| if (op.matchConditions && op.matchConditions.length > 0) namespaces = namespaces.filter((ns) => op.matchConditions.every((condition) => this.doesMatch(condition, ns))); | ||
| if (op.maxDepth !== void 0) namespaces = Array.from(new Set(namespaces.map((ns) => ns.slice(0, op.maxDepth).join(":")))).map((ns) => ns.split(":")); | ||
| namespaces.sort((a, b) => a.join(":").localeCompare(b.join(":"))); | ||
| return namespaces.slice(op.offset ?? 0, (op.offset ?? 0) + (op.limit ?? namespaces.length)); | ||
| } | ||
| doesMatch(matchCondition, key) { | ||
| const { matchType, path } = matchCondition; | ||
| if (matchType === "prefix") { | ||
| if (path.length > key.length) return false; | ||
| return path.every((pElem, index) => { | ||
| const kElem = key[index]; | ||
| return pElem === "*" || kElem === pElem; | ||
| }); | ||
| } else if (matchType === "suffix") { | ||
| if (path.length > key.length) return false; | ||
| return path.every((pElem, index) => { | ||
| const kElem = key[key.length - path.length + index]; | ||
| return pElem === "*" || kElem === pElem; | ||
| }); | ||
| } | ||
| throw new Error(`Unsupported match type: ${matchType}`); | ||
| } | ||
| filterItems(op) { | ||
| const candidates = []; | ||
| for (const [namespace, items] of this.data.entries()) if (namespace.startsWith(op.namespacePrefix.join(":"))) candidates.push(...items.values()); | ||
| let filteredCandidates = candidates; | ||
| if (op.filter) filteredCandidates = candidates.filter((item) => Object.entries(op.filter).every(([key, value]) => compareValues(item.value[key], value))); | ||
| return filteredCandidates; | ||
| } | ||
| scoreResults(candidates, queryVector, offset = 0, limit = 10) { | ||
| const flatItems = []; | ||
| const flatVectors = []; | ||
| const scoreless = []; | ||
| for (const item of candidates) { | ||
| const vectors = this.getVectors(item); | ||
| if (vectors.length) for (const vector of vectors) { | ||
| flatItems.push(item); | ||
| flatVectors.push(vector); | ||
| } | ||
| else scoreless.push(item); | ||
| } | ||
| const scores = this.cosineSimilarity(queryVector, flatVectors); | ||
| const sortedResults = scores.map((score, i) => [score, flatItems[i]]).sort((a, b) => b[0] - a[0]); | ||
| const seen = /* @__PURE__ */ new Set(); | ||
| const kept = []; | ||
| for (const [score, item] of sortedResults) { | ||
| const key = `${item.namespace.join(":")}:${item.key}`; | ||
| if (seen.has(key)) continue; | ||
| const ix = seen.size; | ||
| if (ix >= offset + limit) break; | ||
| if (ix < offset) { | ||
| seen.add(key); | ||
| continue; | ||
| } | ||
| seen.add(key); | ||
| kept.push([score, item]); | ||
| } | ||
| if (scoreless.length && kept.length < limit) for (const item of scoreless.slice(0, limit - kept.length)) { | ||
| const key = `${item.namespace.join(":")}:${item.key}`; | ||
| if (!seen.has(key)) { | ||
| seen.add(key); | ||
| kept.push([void 0, item]); | ||
| } | ||
| } | ||
| return kept.map(([score, item]) => ({ | ||
| ...item, | ||
| score | ||
| })); | ||
| } | ||
| paginateResults(results, offset, limit) { | ||
| return results.slice(offset, offset + limit); | ||
| } | ||
| extractTexts(ops) { | ||
| if (!ops.length || !this._indexConfig) return {}; | ||
| const toEmbed = {}; | ||
| for (const op of ops) if (op.value !== null && op.index !== false) { | ||
| const paths = op.index === null || op.index === void 0 ? this._indexConfig.__tokenizedFields ?? [] : op.index.map((ix) => [ix, tokenizePath(ix)]); | ||
| for (const [path, field] of paths) { | ||
| const texts = getTextAtPath(op.value, field); | ||
| if (texts.length) if (texts.length > 1) texts.forEach((text, i) => { | ||
| if (!toEmbed[text]) toEmbed[text] = []; | ||
| toEmbed[text].push([ | ||
| op.namespace, | ||
| op.key, | ||
| `${path}.${i}` | ||
| ]); | ||
| }); | ||
| else { | ||
| if (!toEmbed[texts[0]]) toEmbed[texts[0]] = []; | ||
| toEmbed[texts[0]].push([ | ||
| op.namespace, | ||
| op.key, | ||
| path | ||
| ]); | ||
| } | ||
| } | ||
| } | ||
| return toEmbed; | ||
| } | ||
| insertVectors(texts, embeddings) { | ||
| for (const [text, metadata] of Object.entries(texts)) { | ||
| const embedding = embeddings.shift(); | ||
| if (!embedding) throw new Error(`No embedding found for text: ${text}`); | ||
| for (const [namespace, key, field] of metadata) { | ||
| const namespaceKey = namespace.join(":"); | ||
| if (!this.vectors.has(namespaceKey)) this.vectors.set(namespaceKey, /* @__PURE__ */ new Map()); | ||
| const namespaceMap = this.vectors.get(namespaceKey); | ||
| if (!namespaceMap.has(key)) namespaceMap.set(key, /* @__PURE__ */ new Map()); | ||
| const itemMap = namespaceMap.get(key); | ||
| itemMap.set(field, embedding); | ||
| } | ||
| } | ||
| } | ||
| getVectors(item) { | ||
| const namespaceKey = item.namespace.join(":"); | ||
| const itemKey = item.key; | ||
| if (!this.vectors.has(namespaceKey)) return []; | ||
| const namespaceMap = this.vectors.get(namespaceKey); | ||
| if (!namespaceMap.has(itemKey)) return []; | ||
| const itemMap = namespaceMap.get(itemKey); | ||
| const vectors = Array.from(itemMap.values()); | ||
| if (!vectors.length) return []; | ||
| return vectors; | ||
| } | ||
| cosineSimilarity(X, Y) { | ||
| if (!Y.length) return []; | ||
| const dotProducts = Y.map((vector) => vector.reduce((acc, val, i) => acc + val * X[i], 0)); | ||
| const magnitude1 = Math.sqrt(X.reduce((acc, val) => acc + val * val, 0)); | ||
| const magnitudes2 = Y.map((vector) => Math.sqrt(vector.reduce((acc, val) => acc + val * val, 0))); | ||
| return dotProducts.map((dot, i) => { | ||
| const magnitude2 = magnitudes2[i]; | ||
| return magnitude1 && magnitude2 ? dot / (magnitude1 * magnitude2) : 0; | ||
| }); | ||
| } | ||
| get indexConfig() { | ||
| return this._indexConfig; | ||
| } | ||
| }; | ||
| /** @deprecated Alias for InMemoryStore */ | ||
| export class MemoryStore extends InMemoryStore { | ||
| } | ||
| var MemoryStore = class extends InMemoryStore {}; | ||
| //#endregion | ||
| export { InMemoryStore, MemoryStore }; | ||
| //# sourceMappingURL=memory.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/store/memory.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"memory.js","names":["candidates: Item[]","flatItems: Item[]","flatVectors: number[][]","scoreless: Item[]","kept: Array<[number | undefined, Item]>","toEmbed: { [text: string]: [string[], string, string][] }"],"sources":["../../src/store/memory.ts"],"sourcesContent":["import {\n BaseStore,\n type OperationResults,\n type Item,\n type Operation,\n MatchCondition,\n ListNamespacesOperation,\n PutOperation,\n SearchOperation,\n GetOperation,\n type IndexConfig,\n type SearchItem,\n} from \"./base.js\";\nimport { tokenizePath, compareValues, getTextAtPath } from \"./utils.js\";\n\n/**\n * In-memory key-value store with optional vector search.\n *\n * A lightweight store implementation using JavaScript Maps. Supports basic\n * key-value operations and vector search when configured with embeddings.\n *\n * @example\n * ```typescript\n * // Basic key-value storage\n * const store = new InMemoryStore();\n * await store.put([\"users\", \"123\"], \"prefs\", { theme: \"dark\" });\n * const item = await store.get([\"users\", \"123\"], \"prefs\");\n *\n * // Vector search with embeddings\n * import { OpenAIEmbeddings } from \"@langchain/openai\";\n * const store = new InMemoryStore({\n * index: {\n * dims: 1536,\n * embeddings: new OpenAIEmbeddings({ modelName: \"text-embedding-3-small\" }),\n * }\n * });\n *\n * // Store documents\n * await store.put([\"docs\"], \"doc1\", { text: \"Python tutorial\" });\n * await store.put([\"docs\"], \"doc2\", { text: \"TypeScript guide\" });\n *\n * // Search by similarity\n * const results = await store.search([\"docs\"], { query: \"python programming\" });\n * ```\n *\n * **Warning**: This store keeps all data in memory. Data is lost when the process exits.\n * For persistence, use a database-backed store.\n */\nexport class InMemoryStore extends BaseStore {\n private data: Map<string, Map<string, Item>> = new Map();\n\n // Namespace -> Key -> Path/field -> Vector\n private vectors: Map<string, Map<string, Map<string, number[]>>> = new Map();\n\n private _indexConfig?: IndexConfig & {\n __tokenizedFields: Array<[string, string[]]>;\n };\n\n constructor(options?: { index?: IndexConfig }) {\n super();\n if (options?.index) {\n this._indexConfig = {\n ...options.index,\n __tokenizedFields: (options.index.fields ?? [\"$\"]).map((p) => [\n p,\n p === \"$\" ? [p] : tokenizePath(p),\n ]),\n };\n }\n }\n\n async batch<Op extends readonly Operation[]>(\n operations: Op\n ): Promise<OperationResults<Op>> {\n const results = [];\n const putOps = new Map<string, PutOperation>();\n const searchOps = new Map<number, [SearchOperation, Item[]]>();\n\n // First pass - handle gets and prepare search/put operations\n for (let i = 0; i < operations.length; i += 1) {\n const op = operations[i];\n if (\"key\" in op && \"namespace\" in op && !(\"value\" in op)) {\n // GetOperation\n results.push(this.getOperation(op));\n } else if (\"namespacePrefix\" in op) {\n // SearchOperation\n const candidates = this.filterItems(op);\n searchOps.set(i, [op, candidates]);\n results.push(null);\n } else if (\"value\" in op) {\n // PutOperation\n const key = `${op.namespace.join(\":\")}:${op.key}`;\n putOps.set(key, op);\n results.push(null);\n } else if (\"matchConditions\" in op) {\n // ListNamespacesOperation\n results.push(this.listNamespacesOperation(op));\n }\n }\n\n // Handle search operations with embeddings\n if (searchOps.size > 0) {\n if (this._indexConfig?.embeddings) {\n const queries = new Set<string>();\n for (const [op] of searchOps.values()) {\n if (op.query) queries.add(op.query);\n }\n\n // Get embeddings for all queries\n const queryEmbeddings =\n queries.size > 0\n ? await Promise.all(\n Array.from(queries).map((q) =>\n this._indexConfig!.embeddings.embedQuery(q)\n )\n )\n : [];\n const queryVectors = Object.fromEntries(\n Array.from(queries).map((q, i) => [q, queryEmbeddings[i]])\n );\n\n // Process each search operation\n for (const [i, [op, candidates]] of searchOps.entries()) {\n if (op.query && queryVectors[op.query]) {\n const queryVector = queryVectors[op.query];\n const scoredResults = this.scoreResults(\n candidates,\n queryVector,\n op.offset ?? 0,\n op.limit ?? 10\n );\n results[i] = scoredResults;\n } else {\n results[i] = this.paginateResults(\n candidates.map((item) => ({ ...item, score: undefined })),\n op.offset ?? 0,\n op.limit ?? 10\n );\n }\n }\n } else {\n // No embeddings - just paginate the filtered results\n for (const [i, [op, candidates]] of searchOps.entries()) {\n results[i] = this.paginateResults(\n candidates.map((item) => ({ ...item, score: undefined })),\n op.offset ?? 0,\n op.limit ?? 10\n );\n }\n }\n }\n\n // Handle put operations with embeddings\n if (putOps.size > 0 && this._indexConfig?.embeddings) {\n const toEmbed = this.extractTexts(Array.from(putOps.values()));\n if (Object.keys(toEmbed).length > 0) {\n const embeddings = await this._indexConfig.embeddings.embedDocuments(\n Object.keys(toEmbed)\n );\n this.insertVectors(toEmbed, embeddings);\n }\n }\n\n // Apply all put operations\n for (const op of putOps.values()) {\n this.putOperation(op);\n }\n\n return results as OperationResults<Op>;\n }\n\n private getOperation(op: GetOperation): Item | null {\n const namespaceKey = op.namespace.join(\":\");\n const item = this.data.get(namespaceKey)?.get(op.key);\n return item ?? null;\n }\n\n private putOperation(op: PutOperation): void {\n const namespaceKey = op.namespace.join(\":\");\n if (!this.data.has(namespaceKey)) {\n this.data.set(namespaceKey, new Map());\n }\n const namespaceMap = this.data.get(namespaceKey)!;\n\n if (op.value === null) {\n namespaceMap.delete(op.key);\n } else {\n const now = new Date();\n if (namespaceMap.has(op.key)) {\n const item = namespaceMap.get(op.key)!;\n item.value = op.value;\n item.updatedAt = now;\n } else {\n namespaceMap.set(op.key, {\n value: op.value,\n key: op.key,\n namespace: op.namespace,\n createdAt: now,\n updatedAt: now,\n });\n }\n }\n }\n\n private listNamespacesOperation(op: ListNamespacesOperation): string[][] {\n const allNamespaces = Array.from(this.data.keys()).map((ns) =>\n ns.split(\":\")\n );\n let namespaces = allNamespaces;\n\n if (op.matchConditions && op.matchConditions.length > 0) {\n namespaces = namespaces.filter((ns) =>\n op.matchConditions!.every((condition) => this.doesMatch(condition, ns))\n );\n }\n\n if (op.maxDepth !== undefined) {\n namespaces = Array.from(\n new Set(namespaces.map((ns) => ns.slice(0, op.maxDepth).join(\":\")))\n ).map((ns) => ns.split(\":\"));\n }\n\n namespaces.sort((a, b) => a.join(\":\").localeCompare(b.join(\":\")));\n\n return namespaces.slice(\n op.offset ?? 0,\n (op.offset ?? 0) + (op.limit ?? namespaces.length)\n );\n }\n\n private doesMatch(matchCondition: MatchCondition, key: string[]): boolean {\n const { matchType, path } = matchCondition;\n\n if (matchType === \"prefix\") {\n if (path.length > key.length) return false;\n return path.every((pElem, index) => {\n const kElem = key[index];\n return pElem === \"*\" || kElem === pElem;\n });\n } else if (matchType === \"suffix\") {\n if (path.length > key.length) return false;\n return path.every((pElem, index) => {\n const kElem = key[key.length - path.length + index];\n return pElem === \"*\" || kElem === pElem;\n });\n }\n\n throw new Error(`Unsupported match type: ${matchType}`);\n }\n\n private filterItems(op: SearchOperation): Item[] {\n const candidates: Item[] = [];\n for (const [namespace, items] of this.data.entries()) {\n if (namespace.startsWith(op.namespacePrefix.join(\":\"))) {\n candidates.push(...items.values());\n }\n }\n\n let filteredCandidates = candidates;\n if (op.filter) {\n filteredCandidates = candidates.filter((item) =>\n Object.entries(op.filter!).every(([key, value]) =>\n compareValues(item.value[key], value)\n )\n );\n }\n return filteredCandidates;\n }\n\n private scoreResults(\n candidates: Item[],\n queryVector: number[],\n offset: number = 0,\n limit: number = 10\n ): SearchItem[] {\n const flatItems: Item[] = [];\n const flatVectors: number[][] = [];\n const scoreless: Item[] = [];\n\n for (const item of candidates) {\n const vectors = this.getVectors(item);\n if (vectors.length) {\n for (const vector of vectors) {\n flatItems.push(item);\n flatVectors.push(vector);\n }\n } else {\n scoreless.push(item);\n }\n }\n\n const scores = this.cosineSimilarity(queryVector, flatVectors);\n\n const sortedResults = scores\n .map((score, i) => [score, flatItems[i]] as [number, Item])\n .sort((a, b) => b[0] - a[0]);\n\n const seen = new Set<string>();\n const kept: Array<[number | undefined, Item]> = [];\n\n for (const [score, item] of sortedResults) {\n const key = `${item.namespace.join(\":\")}:${item.key}`;\n if (seen.has(key)) continue;\n\n const ix = seen.size;\n if (ix >= offset + limit) break;\n if (ix < offset) {\n seen.add(key);\n continue;\n }\n\n seen.add(key);\n kept.push([score, item]);\n }\n\n if (scoreless.length && kept.length < limit) {\n for (const item of scoreless.slice(0, limit - kept.length)) {\n const key = `${item.namespace.join(\":\")}:${item.key}`;\n if (!seen.has(key)) {\n seen.add(key);\n kept.push([undefined, item]);\n }\n }\n }\n return kept.map(([score, item]) => ({\n ...item,\n score,\n }));\n }\n\n private paginateResults(\n results: SearchItem[],\n offset: number,\n limit: number\n ): SearchItem[] {\n return results.slice(offset, offset + limit);\n }\n\n private extractTexts(ops: PutOperation[]): {\n [text: string]: [string[], string, string][];\n } {\n if (!ops.length || !this._indexConfig) {\n return {};\n }\n\n const toEmbed: { [text: string]: [string[], string, string][] } = {};\n\n for (const op of ops) {\n if (op.value !== null && op.index !== false) {\n const paths =\n op.index === null || op.index === undefined\n ? this._indexConfig.__tokenizedFields ?? []\n : op.index.map(\n (ix) => [ix, tokenizePath(ix)] as [string, string[]]\n );\n for (const [path, field] of paths) {\n const texts = getTextAtPath(op.value, field);\n if (texts.length) {\n if (texts.length > 1) {\n texts.forEach((text, i) => {\n if (!toEmbed[text]) toEmbed[text] = [];\n toEmbed[text].push([op.namespace, op.key, `${path}.${i}`]);\n });\n } else {\n if (!toEmbed[texts[0]]) toEmbed[texts[0]] = [];\n toEmbed[texts[0]].push([op.namespace, op.key, path]);\n }\n }\n }\n }\n }\n\n return toEmbed;\n }\n\n private insertVectors(\n texts: { [text: string]: [string[], string, string][] },\n embeddings: number[][]\n ): void {\n for (const [text, metadata] of Object.entries(texts)) {\n const embedding = embeddings.shift();\n if (!embedding) {\n throw new Error(`No embedding found for text: ${text}`);\n }\n\n for (const [namespace, key, field] of metadata) {\n const namespaceKey = namespace.join(\":\");\n if (!this.vectors.has(namespaceKey)) {\n this.vectors.set(namespaceKey, new Map());\n }\n const namespaceMap = this.vectors.get(namespaceKey)!;\n if (!namespaceMap.has(key)) {\n namespaceMap.set(key, new Map());\n }\n const itemMap = namespaceMap.get(key)!;\n itemMap.set(field, embedding);\n }\n }\n }\n\n private getVectors(item: Item): number[][] {\n const namespaceKey = item.namespace.join(\":\");\n const itemKey = item.key;\n if (!this.vectors.has(namespaceKey)) {\n return [];\n }\n const namespaceMap = this.vectors.get(namespaceKey)!;\n if (!namespaceMap.has(itemKey)) {\n return [];\n }\n const itemMap = namespaceMap.get(itemKey)!;\n const vectors = Array.from(itemMap.values());\n if (!vectors.length) {\n return [];\n }\n return vectors;\n }\n\n private cosineSimilarity(X: number[], Y: number[][]): number[] {\n if (!Y.length) return [];\n\n // Calculate dot products for all vectors at once\n const dotProducts = Y.map((vector) =>\n vector.reduce((acc, val, i) => acc + val * X[i], 0)\n );\n\n // Calculate magnitudes\n const magnitude1 = Math.sqrt(X.reduce((acc, val) => acc + val * val, 0));\n const magnitudes2 = Y.map((vector) =>\n Math.sqrt(vector.reduce((acc, val) => acc + val * val, 0))\n );\n\n // Calculate similarities\n return dotProducts.map((dot, i) => {\n const magnitude2 = magnitudes2[i];\n return magnitude1 && magnitude2 ? dot / (magnitude1 * magnitude2) : 0;\n });\n }\n\n public get indexConfig(): IndexConfig | undefined {\n return this._indexConfig;\n }\n}\n\n/** @deprecated Alias for InMemoryStore */\nexport class MemoryStore extends InMemoryStore {}\n"],"mappings":"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"} |
+141
-249
@@ -1,261 +0,153 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.tokenizePath = tokenizePath; | ||
| exports.compareValues = compareValues; | ||
| exports.getTextAtPath = getTextAtPath; | ||
| exports.cosineSimilarity = cosineSimilarity; | ||
| //#region src/store/utils.ts | ||
| /** | ||
| * Tokenize a JSON path into parts. | ||
| * @example | ||
| * tokenizePath("metadata.title") // -> ["metadata", "title"] | ||
| * tokenizePath("chapters[*].content") // -> ["chapters[*]", "content"] | ||
| */ | ||
| * Tokenize a JSON path into parts. | ||
| * @example | ||
| * tokenizePath("metadata.title") // -> ["metadata", "title"] | ||
| * tokenizePath("chapters[*].content") // -> ["chapters[*]", "content"] | ||
| */ | ||
| function tokenizePath(path) { | ||
| if (!path) { | ||
| return []; | ||
| } | ||
| const tokens = []; | ||
| let current = []; | ||
| let i = 0; | ||
| while (i < path.length) { | ||
| const char = path[i]; | ||
| if (char === "[") { | ||
| // Handle array index | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| current = []; | ||
| } | ||
| let bracketCount = 1; | ||
| const indexChars = ["["]; | ||
| i += 1; | ||
| while (i < path.length && bracketCount > 0) { | ||
| if (path[i] === "[") { | ||
| bracketCount += 1; | ||
| } | ||
| else if (path[i] === "]") { | ||
| bracketCount -= 1; | ||
| } | ||
| indexChars.push(path[i]); | ||
| i += 1; | ||
| } | ||
| tokens.push(indexChars.join("")); | ||
| continue; | ||
| } | ||
| else if (char === "{") { | ||
| // Handle multi-field selection | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| current = []; | ||
| } | ||
| let braceCount = 1; | ||
| const fieldChars = ["{"]; | ||
| i += 1; | ||
| while (i < path.length && braceCount > 0) { | ||
| if (path[i] === "{") { | ||
| braceCount += 1; | ||
| } | ||
| else if (path[i] === "}") { | ||
| braceCount -= 1; | ||
| } | ||
| fieldChars.push(path[i]); | ||
| i += 1; | ||
| } | ||
| tokens.push(fieldChars.join("")); | ||
| continue; | ||
| } | ||
| else if (char === ".") { | ||
| // Handle regular field | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| current = []; | ||
| } | ||
| } | ||
| else { | ||
| current.push(char); | ||
| } | ||
| i += 1; | ||
| } | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| } | ||
| return tokens; | ||
| if (!path) return []; | ||
| const tokens = []; | ||
| let current = []; | ||
| let i = 0; | ||
| while (i < path.length) { | ||
| const char = path[i]; | ||
| if (char === "[") { | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| current = []; | ||
| } | ||
| let bracketCount = 1; | ||
| const indexChars = ["["]; | ||
| i += 1; | ||
| while (i < path.length && bracketCount > 0) { | ||
| if (path[i] === "[") bracketCount += 1; | ||
| else if (path[i] === "]") bracketCount -= 1; | ||
| indexChars.push(path[i]); | ||
| i += 1; | ||
| } | ||
| tokens.push(indexChars.join("")); | ||
| continue; | ||
| } else if (char === "{") { | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| current = []; | ||
| } | ||
| let braceCount = 1; | ||
| const fieldChars = ["{"]; | ||
| i += 1; | ||
| while (i < path.length && braceCount > 0) { | ||
| if (path[i] === "{") braceCount += 1; | ||
| else if (path[i] === "}") braceCount -= 1; | ||
| fieldChars.push(path[i]); | ||
| i += 1; | ||
| } | ||
| tokens.push(fieldChars.join("")); | ||
| continue; | ||
| } else if (char === ".") { | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| current = []; | ||
| } | ||
| } else current.push(char); | ||
| i += 1; | ||
| } | ||
| if (current.length) tokens.push(current.join("")); | ||
| return tokens; | ||
| } | ||
| /** | ||
| * Type guard to check if an object is a FilterOperators | ||
| */ | ||
| * Type guard to check if an object is a FilterOperators | ||
| */ | ||
| function isFilterOperators(obj) { | ||
| return (typeof obj === "object" && | ||
| obj !== null && | ||
| Object.keys(obj).every((key) => key === "$eq" || | ||
| key === "$ne" || | ||
| key === "$gt" || | ||
| key === "$gte" || | ||
| key === "$lt" || | ||
| key === "$lte" || | ||
| key === "$in" || | ||
| key === "$nin")); | ||
| return typeof obj === "object" && obj !== null && Object.keys(obj).every((key) => key === "$eq" || key === "$ne" || key === "$gt" || key === "$gte" || key === "$lt" || key === "$lte" || key === "$in" || key === "$nin"); | ||
| } | ||
| /** | ||
| * Compare values for filtering, supporting operator-based comparisons. | ||
| */ | ||
| * Compare values for filtering, supporting operator-based comparisons. | ||
| */ | ||
| function compareValues(itemValue, filterValue) { | ||
| if (isFilterOperators(filterValue)) { | ||
| const operators = Object.keys(filterValue).filter((k) => k.startsWith("$")); | ||
| return operators.every((op) => { | ||
| const value = filterValue[op]; | ||
| switch (op) { | ||
| case "$eq": | ||
| return itemValue === value; | ||
| case "$ne": | ||
| return itemValue !== value; | ||
| case "$gt": | ||
| return Number(itemValue) > Number(value); | ||
| case "$gte": | ||
| return Number(itemValue) >= Number(value); | ||
| case "$lt": | ||
| return Number(itemValue) < Number(value); | ||
| case "$lte": | ||
| return Number(itemValue) <= Number(value); | ||
| case "$in": | ||
| return Array.isArray(value) ? value.includes(itemValue) : false; | ||
| case "$nin": | ||
| return Array.isArray(value) ? !value.includes(itemValue) : true; | ||
| default: | ||
| return false; | ||
| } | ||
| }); | ||
| } | ||
| // If no operators, do a direct comparison | ||
| return itemValue === filterValue; | ||
| if (isFilterOperators(filterValue)) { | ||
| const operators = Object.keys(filterValue).filter((k) => k.startsWith("$")); | ||
| return operators.every((op) => { | ||
| const value = filterValue[op]; | ||
| switch (op) { | ||
| case "$eq": return itemValue === value; | ||
| case "$ne": return itemValue !== value; | ||
| case "$gt": return Number(itemValue) > Number(value); | ||
| case "$gte": return Number(itemValue) >= Number(value); | ||
| case "$lt": return Number(itemValue) < Number(value); | ||
| case "$lte": return Number(itemValue) <= Number(value); | ||
| case "$in": return Array.isArray(value) ? value.includes(itemValue) : false; | ||
| case "$nin": return Array.isArray(value) ? !value.includes(itemValue) : true; | ||
| default: return false; | ||
| } | ||
| }); | ||
| } | ||
| return itemValue === filterValue; | ||
| } | ||
| /** | ||
| * Extract text from a value at a specific JSON path. | ||
| * | ||
| * Supports: | ||
| * - Simple paths: "field1.field2" | ||
| * - Array indexing: "[0]", "[*]", "[-1]" | ||
| * - Wildcards: "*" | ||
| * - Multi-field selection: "{field1,field2}" | ||
| * - Nested paths in multi-field: "{field1,nested.field2}" | ||
| */ | ||
| * Extract text from a value at a specific JSON path. | ||
| * | ||
| * Supports: | ||
| * - Simple paths: "field1.field2" | ||
| * - Array indexing: "[0]", "[*]", "[-1]" | ||
| * - Wildcards: "*" | ||
| * - Multi-field selection: "{field1,field2}" | ||
| * - Nested paths in multi-field: "{field1,nested.field2}" | ||
| */ | ||
| function getTextAtPath(obj, path) { | ||
| if (!path || path === "$") { | ||
| return [JSON.stringify(obj, null, 2)]; | ||
| } | ||
| const tokens = Array.isArray(path) ? path : tokenizePath(path); | ||
| function extractFromObj(obj, tokens, pos) { | ||
| if (pos >= tokens.length) { | ||
| if (typeof obj === "string" || | ||
| typeof obj === "number" || | ||
| typeof obj === "boolean") { | ||
| return [String(obj)]; | ||
| } | ||
| if (obj === null || obj === undefined) { | ||
| return []; | ||
| } | ||
| if (Array.isArray(obj) || typeof obj === "object") { | ||
| return [JSON.stringify(obj, null, 2)]; | ||
| } | ||
| return []; | ||
| } | ||
| const token = tokens[pos]; | ||
| const results = []; | ||
| if (pos === 0 && token === "$") { | ||
| results.push(JSON.stringify(obj, null, 2)); | ||
| } | ||
| if (token.startsWith("[") && token.endsWith("]")) { | ||
| if (!Array.isArray(obj)) | ||
| return []; | ||
| const index = token.slice(1, -1); | ||
| if (index === "*") { | ||
| for (const item of obj) { | ||
| results.push(...extractFromObj(item, tokens, pos + 1)); | ||
| } | ||
| } | ||
| else { | ||
| try { | ||
| let idx = parseInt(index, 10); | ||
| if (idx < 0) { | ||
| idx = obj.length + idx; | ||
| } | ||
| if (idx >= 0 && idx < obj.length) { | ||
| results.push(...extractFromObj(obj[idx], tokens, pos + 1)); | ||
| } | ||
| } | ||
| catch { | ||
| return []; | ||
| } | ||
| } | ||
| } | ||
| else if (token.startsWith("{") && token.endsWith("}")) { | ||
| if (typeof obj !== "object" || obj === null) | ||
| return []; | ||
| const fields = token | ||
| .slice(1, -1) | ||
| .split(",") | ||
| .map((f) => f.trim()); | ||
| for (const field of fields) { | ||
| const nestedTokens = tokenizePath(field); | ||
| if (nestedTokens.length) { | ||
| let currentObj = obj; | ||
| for (const nestedToken of nestedTokens) { | ||
| if (currentObj && | ||
| typeof currentObj === "object" && | ||
| nestedToken in currentObj) { | ||
| currentObj = currentObj[nestedToken]; | ||
| } | ||
| else { | ||
| currentObj = undefined; | ||
| break; | ||
| } | ||
| } | ||
| if (currentObj !== undefined) { | ||
| if (typeof currentObj === "string" || | ||
| typeof currentObj === "number" || | ||
| typeof currentObj === "boolean") { | ||
| results.push(String(currentObj)); | ||
| } | ||
| else if (Array.isArray(currentObj) || | ||
| typeof currentObj === "object") { | ||
| results.push(JSON.stringify(currentObj, null, 2)); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| else if (token === "*") { | ||
| if (Array.isArray(obj)) { | ||
| for (const item of obj) { | ||
| results.push(...extractFromObj(item, tokens, pos + 1)); | ||
| } | ||
| } | ||
| else if (typeof obj === "object" && obj !== null) { | ||
| for (const value of Object.values(obj)) { | ||
| results.push(...extractFromObj(value, tokens, pos + 1)); | ||
| } | ||
| } | ||
| } | ||
| else { | ||
| if (typeof obj === "object" && obj !== null && token in obj) { | ||
| results.push(...extractFromObj(obj[token], tokens, pos + 1)); | ||
| } | ||
| } | ||
| return results; | ||
| } | ||
| return extractFromObj(obj, tokens, 0); | ||
| if (!path || path === "$") return [JSON.stringify(obj, null, 2)]; | ||
| const tokens = Array.isArray(path) ? path : tokenizePath(path); | ||
| function extractFromObj(obj$1, tokens$1, pos) { | ||
| if (pos >= tokens$1.length) { | ||
| if (typeof obj$1 === "string" || typeof obj$1 === "number" || typeof obj$1 === "boolean") return [String(obj$1)]; | ||
| if (obj$1 === null || obj$1 === void 0) return []; | ||
| if (Array.isArray(obj$1) || typeof obj$1 === "object") return [JSON.stringify(obj$1, null, 2)]; | ||
| return []; | ||
| } | ||
| const token = tokens$1[pos]; | ||
| const results = []; | ||
| if (pos === 0 && token === "$") results.push(JSON.stringify(obj$1, null, 2)); | ||
| if (token.startsWith("[") && token.endsWith("]")) { | ||
| if (!Array.isArray(obj$1)) return []; | ||
| const index = token.slice(1, -1); | ||
| if (index === "*") for (const item of obj$1) results.push(...extractFromObj(item, tokens$1, pos + 1)); | ||
| else try { | ||
| let idx = parseInt(index, 10); | ||
| if (idx < 0) idx = obj$1.length + idx; | ||
| if (idx >= 0 && idx < obj$1.length) results.push(...extractFromObj(obj$1[idx], tokens$1, pos + 1)); | ||
| } catch { | ||
| return []; | ||
| } | ||
| } else if (token.startsWith("{") && token.endsWith("}")) { | ||
| if (typeof obj$1 !== "object" || obj$1 === null) return []; | ||
| const fields = token.slice(1, -1).split(",").map((f) => f.trim()); | ||
| for (const field of fields) { | ||
| const nestedTokens = tokenizePath(field); | ||
| if (nestedTokens.length) { | ||
| let currentObj = obj$1; | ||
| for (const nestedToken of nestedTokens) if (currentObj && typeof currentObj === "object" && nestedToken in currentObj) currentObj = currentObj[nestedToken]; | ||
| else { | ||
| currentObj = void 0; | ||
| break; | ||
| } | ||
| if (currentObj !== void 0) { | ||
| if (typeof currentObj === "string" || typeof currentObj === "number" || typeof currentObj === "boolean") results.push(String(currentObj)); | ||
| else if (Array.isArray(currentObj) || typeof currentObj === "object") results.push(JSON.stringify(currentObj, null, 2)); | ||
| } | ||
| } | ||
| } | ||
| } else if (token === "*") { | ||
| if (Array.isArray(obj$1)) for (const item of obj$1) results.push(...extractFromObj(item, tokens$1, pos + 1)); | ||
| else if (typeof obj$1 === "object" && obj$1 !== null) for (const value of Object.values(obj$1)) results.push(...extractFromObj(value, tokens$1, pos + 1)); | ||
| } else if (typeof obj$1 === "object" && obj$1 !== null && token in obj$1) results.push(...extractFromObj(obj$1[token], tokens$1, pos + 1)); | ||
| return results; | ||
| } | ||
| return extractFromObj(obj, tokens, 0); | ||
| } | ||
| /** | ||
| * Calculate cosine similarity between two vectors. | ||
| */ | ||
| function cosineSimilarity(vector1, vector2) { | ||
| if (vector1.length !== vector2.length) { | ||
| throw new Error("Vectors must have the same length"); | ||
| } | ||
| const dotProduct = vector1.reduce((acc, val, i) => acc + val * vector2[i], 0); | ||
| const magnitude1 = Math.sqrt(vector1.reduce((acc, val) => acc + val * val, 0)); | ||
| const magnitude2 = Math.sqrt(vector2.reduce((acc, val) => acc + val * val, 0)); | ||
| if (magnitude1 === 0 || magnitude2 === 0) | ||
| return 0; | ||
| return dotProduct / (magnitude1 * magnitude2); | ||
| } | ||
| //# sourceMappingURL=utils.js.map | ||
| //#endregion | ||
| exports.compareValues = compareValues; | ||
| exports.getTextAtPath = getTextAtPath; | ||
| exports.tokenizePath = tokenizePath; | ||
| //# sourceMappingURL=utils.cjs.map |
+140
-245
@@ -0,255 +1,150 @@ | ||
| //#region src/store/utils.ts | ||
| /** | ||
| * Tokenize a JSON path into parts. | ||
| * @example | ||
| * tokenizePath("metadata.title") // -> ["metadata", "title"] | ||
| * tokenizePath("chapters[*].content") // -> ["chapters[*]", "content"] | ||
| */ | ||
| export function tokenizePath(path) { | ||
| if (!path) { | ||
| return []; | ||
| } | ||
| const tokens = []; | ||
| let current = []; | ||
| let i = 0; | ||
| while (i < path.length) { | ||
| const char = path[i]; | ||
| if (char === "[") { | ||
| // Handle array index | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| current = []; | ||
| } | ||
| let bracketCount = 1; | ||
| const indexChars = ["["]; | ||
| i += 1; | ||
| while (i < path.length && bracketCount > 0) { | ||
| if (path[i] === "[") { | ||
| bracketCount += 1; | ||
| } | ||
| else if (path[i] === "]") { | ||
| bracketCount -= 1; | ||
| } | ||
| indexChars.push(path[i]); | ||
| i += 1; | ||
| } | ||
| tokens.push(indexChars.join("")); | ||
| continue; | ||
| } | ||
| else if (char === "{") { | ||
| // Handle multi-field selection | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| current = []; | ||
| } | ||
| let braceCount = 1; | ||
| const fieldChars = ["{"]; | ||
| i += 1; | ||
| while (i < path.length && braceCount > 0) { | ||
| if (path[i] === "{") { | ||
| braceCount += 1; | ||
| } | ||
| else if (path[i] === "}") { | ||
| braceCount -= 1; | ||
| } | ||
| fieldChars.push(path[i]); | ||
| i += 1; | ||
| } | ||
| tokens.push(fieldChars.join("")); | ||
| continue; | ||
| } | ||
| else if (char === ".") { | ||
| // Handle regular field | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| current = []; | ||
| } | ||
| } | ||
| else { | ||
| current.push(char); | ||
| } | ||
| i += 1; | ||
| } | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| } | ||
| return tokens; | ||
| * Tokenize a JSON path into parts. | ||
| * @example | ||
| * tokenizePath("metadata.title") // -> ["metadata", "title"] | ||
| * tokenizePath("chapters[*].content") // -> ["chapters[*]", "content"] | ||
| */ | ||
| function tokenizePath(path) { | ||
| if (!path) return []; | ||
| const tokens = []; | ||
| let current = []; | ||
| let i = 0; | ||
| while (i < path.length) { | ||
| const char = path[i]; | ||
| if (char === "[") { | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| current = []; | ||
| } | ||
| let bracketCount = 1; | ||
| const indexChars = ["["]; | ||
| i += 1; | ||
| while (i < path.length && bracketCount > 0) { | ||
| if (path[i] === "[") bracketCount += 1; | ||
| else if (path[i] === "]") bracketCount -= 1; | ||
| indexChars.push(path[i]); | ||
| i += 1; | ||
| } | ||
| tokens.push(indexChars.join("")); | ||
| continue; | ||
| } else if (char === "{") { | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| current = []; | ||
| } | ||
| let braceCount = 1; | ||
| const fieldChars = ["{"]; | ||
| i += 1; | ||
| while (i < path.length && braceCount > 0) { | ||
| if (path[i] === "{") braceCount += 1; | ||
| else if (path[i] === "}") braceCount -= 1; | ||
| fieldChars.push(path[i]); | ||
| i += 1; | ||
| } | ||
| tokens.push(fieldChars.join("")); | ||
| continue; | ||
| } else if (char === ".") { | ||
| if (current.length) { | ||
| tokens.push(current.join("")); | ||
| current = []; | ||
| } | ||
| } else current.push(char); | ||
| i += 1; | ||
| } | ||
| if (current.length) tokens.push(current.join("")); | ||
| return tokens; | ||
| } | ||
| /** | ||
| * Type guard to check if an object is a FilterOperators | ||
| */ | ||
| * Type guard to check if an object is a FilterOperators | ||
| */ | ||
| function isFilterOperators(obj) { | ||
| return (typeof obj === "object" && | ||
| obj !== null && | ||
| Object.keys(obj).every((key) => key === "$eq" || | ||
| key === "$ne" || | ||
| key === "$gt" || | ||
| key === "$gte" || | ||
| key === "$lt" || | ||
| key === "$lte" || | ||
| key === "$in" || | ||
| key === "$nin")); | ||
| return typeof obj === "object" && obj !== null && Object.keys(obj).every((key) => key === "$eq" || key === "$ne" || key === "$gt" || key === "$gte" || key === "$lt" || key === "$lte" || key === "$in" || key === "$nin"); | ||
| } | ||
| /** | ||
| * Compare values for filtering, supporting operator-based comparisons. | ||
| */ | ||
| export function compareValues(itemValue, filterValue) { | ||
| if (isFilterOperators(filterValue)) { | ||
| const operators = Object.keys(filterValue).filter((k) => k.startsWith("$")); | ||
| return operators.every((op) => { | ||
| const value = filterValue[op]; | ||
| switch (op) { | ||
| case "$eq": | ||
| return itemValue === value; | ||
| case "$ne": | ||
| return itemValue !== value; | ||
| case "$gt": | ||
| return Number(itemValue) > Number(value); | ||
| case "$gte": | ||
| return Number(itemValue) >= Number(value); | ||
| case "$lt": | ||
| return Number(itemValue) < Number(value); | ||
| case "$lte": | ||
| return Number(itemValue) <= Number(value); | ||
| case "$in": | ||
| return Array.isArray(value) ? value.includes(itemValue) : false; | ||
| case "$nin": | ||
| return Array.isArray(value) ? !value.includes(itemValue) : true; | ||
| default: | ||
| return false; | ||
| } | ||
| }); | ||
| } | ||
| // If no operators, do a direct comparison | ||
| return itemValue === filterValue; | ||
| * Compare values for filtering, supporting operator-based comparisons. | ||
| */ | ||
| function compareValues(itemValue, filterValue) { | ||
| if (isFilterOperators(filterValue)) { | ||
| const operators = Object.keys(filterValue).filter((k) => k.startsWith("$")); | ||
| return operators.every((op) => { | ||
| const value = filterValue[op]; | ||
| switch (op) { | ||
| case "$eq": return itemValue === value; | ||
| case "$ne": return itemValue !== value; | ||
| case "$gt": return Number(itemValue) > Number(value); | ||
| case "$gte": return Number(itemValue) >= Number(value); | ||
| case "$lt": return Number(itemValue) < Number(value); | ||
| case "$lte": return Number(itemValue) <= Number(value); | ||
| case "$in": return Array.isArray(value) ? value.includes(itemValue) : false; | ||
| case "$nin": return Array.isArray(value) ? !value.includes(itemValue) : true; | ||
| default: return false; | ||
| } | ||
| }); | ||
| } | ||
| return itemValue === filterValue; | ||
| } | ||
| /** | ||
| * Extract text from a value at a specific JSON path. | ||
| * | ||
| * Supports: | ||
| * - Simple paths: "field1.field2" | ||
| * - Array indexing: "[0]", "[*]", "[-1]" | ||
| * - Wildcards: "*" | ||
| * - Multi-field selection: "{field1,field2}" | ||
| * - Nested paths in multi-field: "{field1,nested.field2}" | ||
| */ | ||
| export function getTextAtPath(obj, path) { | ||
| if (!path || path === "$") { | ||
| return [JSON.stringify(obj, null, 2)]; | ||
| } | ||
| const tokens = Array.isArray(path) ? path : tokenizePath(path); | ||
| function extractFromObj(obj, tokens, pos) { | ||
| if (pos >= tokens.length) { | ||
| if (typeof obj === "string" || | ||
| typeof obj === "number" || | ||
| typeof obj === "boolean") { | ||
| return [String(obj)]; | ||
| } | ||
| if (obj === null || obj === undefined) { | ||
| return []; | ||
| } | ||
| if (Array.isArray(obj) || typeof obj === "object") { | ||
| return [JSON.stringify(obj, null, 2)]; | ||
| } | ||
| return []; | ||
| } | ||
| const token = tokens[pos]; | ||
| const results = []; | ||
| if (pos === 0 && token === "$") { | ||
| results.push(JSON.stringify(obj, null, 2)); | ||
| } | ||
| if (token.startsWith("[") && token.endsWith("]")) { | ||
| if (!Array.isArray(obj)) | ||
| return []; | ||
| const index = token.slice(1, -1); | ||
| if (index === "*") { | ||
| for (const item of obj) { | ||
| results.push(...extractFromObj(item, tokens, pos + 1)); | ||
| } | ||
| } | ||
| else { | ||
| try { | ||
| let idx = parseInt(index, 10); | ||
| if (idx < 0) { | ||
| idx = obj.length + idx; | ||
| } | ||
| if (idx >= 0 && idx < obj.length) { | ||
| results.push(...extractFromObj(obj[idx], tokens, pos + 1)); | ||
| } | ||
| } | ||
| catch { | ||
| return []; | ||
| } | ||
| } | ||
| } | ||
| else if (token.startsWith("{") && token.endsWith("}")) { | ||
| if (typeof obj !== "object" || obj === null) | ||
| return []; | ||
| const fields = token | ||
| .slice(1, -1) | ||
| .split(",") | ||
| .map((f) => f.trim()); | ||
| for (const field of fields) { | ||
| const nestedTokens = tokenizePath(field); | ||
| if (nestedTokens.length) { | ||
| let currentObj = obj; | ||
| for (const nestedToken of nestedTokens) { | ||
| if (currentObj && | ||
| typeof currentObj === "object" && | ||
| nestedToken in currentObj) { | ||
| currentObj = currentObj[nestedToken]; | ||
| } | ||
| else { | ||
| currentObj = undefined; | ||
| break; | ||
| } | ||
| } | ||
| if (currentObj !== undefined) { | ||
| if (typeof currentObj === "string" || | ||
| typeof currentObj === "number" || | ||
| typeof currentObj === "boolean") { | ||
| results.push(String(currentObj)); | ||
| } | ||
| else if (Array.isArray(currentObj) || | ||
| typeof currentObj === "object") { | ||
| results.push(JSON.stringify(currentObj, null, 2)); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| else if (token === "*") { | ||
| if (Array.isArray(obj)) { | ||
| for (const item of obj) { | ||
| results.push(...extractFromObj(item, tokens, pos + 1)); | ||
| } | ||
| } | ||
| else if (typeof obj === "object" && obj !== null) { | ||
| for (const value of Object.values(obj)) { | ||
| results.push(...extractFromObj(value, tokens, pos + 1)); | ||
| } | ||
| } | ||
| } | ||
| else { | ||
| if (typeof obj === "object" && obj !== null && token in obj) { | ||
| results.push(...extractFromObj(obj[token], tokens, pos + 1)); | ||
| } | ||
| } | ||
| return results; | ||
| } | ||
| return extractFromObj(obj, tokens, 0); | ||
| * Extract text from a value at a specific JSON path. | ||
| * | ||
| * Supports: | ||
| * - Simple paths: "field1.field2" | ||
| * - Array indexing: "[0]", "[*]", "[-1]" | ||
| * - Wildcards: "*" | ||
| * - Multi-field selection: "{field1,field2}" | ||
| * - Nested paths in multi-field: "{field1,nested.field2}" | ||
| */ | ||
| function getTextAtPath(obj, path) { | ||
| if (!path || path === "$") return [JSON.stringify(obj, null, 2)]; | ||
| const tokens = Array.isArray(path) ? path : tokenizePath(path); | ||
| function extractFromObj(obj$1, tokens$1, pos) { | ||
| if (pos >= tokens$1.length) { | ||
| if (typeof obj$1 === "string" || typeof obj$1 === "number" || typeof obj$1 === "boolean") return [String(obj$1)]; | ||
| if (obj$1 === null || obj$1 === void 0) return []; | ||
| if (Array.isArray(obj$1) || typeof obj$1 === "object") return [JSON.stringify(obj$1, null, 2)]; | ||
| return []; | ||
| } | ||
| const token = tokens$1[pos]; | ||
| const results = []; | ||
| if (pos === 0 && token === "$") results.push(JSON.stringify(obj$1, null, 2)); | ||
| if (token.startsWith("[") && token.endsWith("]")) { | ||
| if (!Array.isArray(obj$1)) return []; | ||
| const index = token.slice(1, -1); | ||
| if (index === "*") for (const item of obj$1) results.push(...extractFromObj(item, tokens$1, pos + 1)); | ||
| else try { | ||
| let idx = parseInt(index, 10); | ||
| if (idx < 0) idx = obj$1.length + idx; | ||
| if (idx >= 0 && idx < obj$1.length) results.push(...extractFromObj(obj$1[idx], tokens$1, pos + 1)); | ||
| } catch { | ||
| return []; | ||
| } | ||
| } else if (token.startsWith("{") && token.endsWith("}")) { | ||
| if (typeof obj$1 !== "object" || obj$1 === null) return []; | ||
| const fields = token.slice(1, -1).split(",").map((f) => f.trim()); | ||
| for (const field of fields) { | ||
| const nestedTokens = tokenizePath(field); | ||
| if (nestedTokens.length) { | ||
| let currentObj = obj$1; | ||
| for (const nestedToken of nestedTokens) if (currentObj && typeof currentObj === "object" && nestedToken in currentObj) currentObj = currentObj[nestedToken]; | ||
| else { | ||
| currentObj = void 0; | ||
| break; | ||
| } | ||
| if (currentObj !== void 0) { | ||
| if (typeof currentObj === "string" || typeof currentObj === "number" || typeof currentObj === "boolean") results.push(String(currentObj)); | ||
| else if (Array.isArray(currentObj) || typeof currentObj === "object") results.push(JSON.stringify(currentObj, null, 2)); | ||
| } | ||
| } | ||
| } | ||
| } else if (token === "*") { | ||
| if (Array.isArray(obj$1)) for (const item of obj$1) results.push(...extractFromObj(item, tokens$1, pos + 1)); | ||
| else if (typeof obj$1 === "object" && obj$1 !== null) for (const value of Object.values(obj$1)) results.push(...extractFromObj(value, tokens$1, pos + 1)); | ||
| } else if (typeof obj$1 === "object" && obj$1 !== null && token in obj$1) results.push(...extractFromObj(obj$1[token], tokens$1, pos + 1)); | ||
| return results; | ||
| } | ||
| return extractFromObj(obj, tokens, 0); | ||
| } | ||
| /** | ||
| * Calculate cosine similarity between two vectors. | ||
| */ | ||
| export function cosineSimilarity(vector1, vector2) { | ||
| if (vector1.length !== vector2.length) { | ||
| throw new Error("Vectors must have the same length"); | ||
| } | ||
| const dotProduct = vector1.reduce((acc, val, i) => acc + val * vector2[i], 0); | ||
| const magnitude1 = Math.sqrt(vector1.reduce((acc, val) => acc + val * val, 0)); | ||
| const magnitude2 = Math.sqrt(vector2.reduce((acc, val) => acc + val * val, 0)); | ||
| if (magnitude1 === 0 || magnitude2 === 0) | ||
| return 0; | ||
| return dotProduct / (magnitude1 * magnitude2); | ||
| } | ||
| //#endregion | ||
| export { compareValues, getTextAtPath, tokenizePath }; | ||
| //# sourceMappingURL=utils.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/store/utils.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"utils.js","names":["tokens: string[]","current: string[]","tokens","obj","results: string[]"],"sources":["../../src/store/utils.ts"],"sourcesContent":["/**\n * Tokenize a JSON path into parts.\n * @example\n * tokenizePath(\"metadata.title\") // -> [\"metadata\", \"title\"]\n * tokenizePath(\"chapters[*].content\") // -> [\"chapters[*]\", \"content\"]\n */\nexport function tokenizePath(path: string): string[] {\n if (!path) {\n return [];\n }\n\n const tokens: string[] = [];\n let current: string[] = [];\n let i = 0;\n\n while (i < path.length) {\n const char = path[i];\n\n if (char === \"[\") {\n // Handle array index\n if (current.length) {\n tokens.push(current.join(\"\"));\n current = [];\n }\n let bracketCount = 1;\n const indexChars = [\"[\"];\n i += 1;\n while (i < path.length && bracketCount > 0) {\n if (path[i] === \"[\") {\n bracketCount += 1;\n } else if (path[i] === \"]\") {\n bracketCount -= 1;\n }\n indexChars.push(path[i]);\n i += 1;\n }\n tokens.push(indexChars.join(\"\"));\n continue;\n } else if (char === \"{\") {\n // Handle multi-field selection\n if (current.length) {\n tokens.push(current.join(\"\"));\n current = [];\n }\n let braceCount = 1;\n const fieldChars = [\"{\"];\n i += 1;\n while (i < path.length && braceCount > 0) {\n if (path[i] === \"{\") {\n braceCount += 1;\n } else if (path[i] === \"}\") {\n braceCount -= 1;\n }\n fieldChars.push(path[i]);\n i += 1;\n }\n tokens.push(fieldChars.join(\"\"));\n continue;\n } else if (char === \".\") {\n // Handle regular field\n if (current.length) {\n tokens.push(current.join(\"\"));\n current = [];\n }\n } else {\n current.push(char);\n }\n i += 1;\n }\n\n if (current.length) {\n tokens.push(current.join(\"\"));\n }\n\n return tokens;\n}\n\n/**\n * Represents the supported filter operators\n */\ntype FilterOperators = {\n $eq?: unknown;\n $ne?: unknown;\n $gt?: unknown;\n $gte?: unknown;\n $lt?: unknown;\n $lte?: unknown;\n $in?: unknown[];\n $nin?: unknown[];\n};\n\n/**\n * Type guard to check if an object is a FilterOperators\n */\nfunction isFilterOperators(obj: unknown): obj is FilterOperators {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n Object.keys(obj).every(\n (key) =>\n key === \"$eq\" ||\n key === \"$ne\" ||\n key === \"$gt\" ||\n key === \"$gte\" ||\n key === \"$lt\" ||\n key === \"$lte\" ||\n key === \"$in\" ||\n key === \"$nin\"\n )\n );\n}\n\n/**\n * Compare values for filtering, supporting operator-based comparisons.\n */\nexport function compareValues(\n itemValue: unknown,\n filterValue: unknown\n): boolean {\n if (isFilterOperators(filterValue)) {\n const operators = Object.keys(filterValue).filter((k) => k.startsWith(\"$\"));\n return operators.every((op) => {\n const value = filterValue[op as keyof FilterOperators];\n switch (op) {\n case \"$eq\":\n return itemValue === value;\n case \"$ne\":\n return itemValue !== value;\n case \"$gt\":\n return Number(itemValue) > Number(value);\n case \"$gte\":\n return Number(itemValue) >= Number(value);\n case \"$lt\":\n return Number(itemValue) < Number(value);\n case \"$lte\":\n return Number(itemValue) <= Number(value);\n case \"$in\":\n return Array.isArray(value) ? value.includes(itemValue) : false;\n case \"$nin\":\n return Array.isArray(value) ? !value.includes(itemValue) : true;\n default:\n return false;\n }\n });\n }\n\n // If no operators, do a direct comparison\n return itemValue === filterValue;\n}\n\n/**\n * Extract text from a value at a specific JSON path.\n *\n * Supports:\n * - Simple paths: \"field1.field2\"\n * - Array indexing: \"[0]\", \"[*]\", \"[-1]\"\n * - Wildcards: \"*\"\n * - Multi-field selection: \"{field1,field2}\"\n * - Nested paths in multi-field: \"{field1,nested.field2}\"\n */\nexport function getTextAtPath(obj: unknown, path: string[] | string): string[] {\n if (!path || path === \"$\") {\n return [JSON.stringify(obj, null, 2)];\n }\n const tokens = Array.isArray(path) ? path : tokenizePath(path);\n\n function extractFromObj(\n obj: unknown,\n tokens: string[],\n pos: number\n ): string[] {\n if (pos >= tokens.length) {\n if (\n typeof obj === \"string\" ||\n typeof obj === \"number\" ||\n typeof obj === \"boolean\"\n ) {\n return [String(obj)];\n }\n if (obj === null || obj === undefined) {\n return [];\n }\n if (Array.isArray(obj) || typeof obj === \"object\") {\n return [JSON.stringify(obj, null, 2)];\n }\n return [];\n }\n\n const token = tokens[pos];\n const results: string[] = [];\n if (pos === 0 && token === \"$\") {\n results.push(JSON.stringify(obj, null, 2));\n }\n\n if (token.startsWith(\"[\") && token.endsWith(\"]\")) {\n if (!Array.isArray(obj)) return [];\n\n const index = token.slice(1, -1);\n if (index === \"*\") {\n for (const item of obj) {\n results.push(...extractFromObj(item, tokens, pos + 1));\n }\n } else {\n try {\n let idx = parseInt(index, 10);\n if (idx < 0) {\n idx = obj.length + idx;\n }\n if (idx >= 0 && idx < obj.length) {\n results.push(...extractFromObj(obj[idx], tokens, pos + 1));\n }\n } catch {\n return [];\n }\n }\n } else if (token.startsWith(\"{\") && token.endsWith(\"}\")) {\n if (typeof obj !== \"object\" || obj === null) return [];\n\n const fields = token\n .slice(1, -1)\n .split(\",\")\n .map((f) => f.trim());\n for (const field of fields) {\n const nestedTokens = tokenizePath(field);\n if (nestedTokens.length) {\n let currentObj = obj as Record<string, unknown> | undefined;\n for (const nestedToken of nestedTokens) {\n if (\n currentObj &&\n typeof currentObj === \"object\" &&\n nestedToken in currentObj\n ) {\n currentObj = currentObj[nestedToken] as Record<string, unknown>;\n } else {\n currentObj = undefined;\n break;\n }\n }\n if (currentObj !== undefined) {\n if (\n typeof currentObj === \"string\" ||\n typeof currentObj === \"number\" ||\n typeof currentObj === \"boolean\"\n ) {\n results.push(String(currentObj));\n } else if (\n Array.isArray(currentObj) ||\n typeof currentObj === \"object\"\n ) {\n results.push(JSON.stringify(currentObj, null, 2));\n }\n }\n }\n }\n } else if (token === \"*\") {\n if (Array.isArray(obj)) {\n for (const item of obj) {\n results.push(...extractFromObj(item, tokens, pos + 1));\n }\n } else if (typeof obj === \"object\" && obj !== null) {\n for (const value of Object.values(obj)) {\n results.push(...extractFromObj(value, tokens, pos + 1));\n }\n }\n } else {\n if (typeof obj === \"object\" && obj !== null && token in obj) {\n results.push(\n ...extractFromObj(\n (obj as Record<string, unknown>)[token],\n tokens,\n pos + 1\n )\n );\n }\n }\n\n return results;\n }\n\n return extractFromObj(obj, tokens, 0);\n}\n\n/**\n * Calculate cosine similarity between two vectors.\n */\nexport function cosineSimilarity(vector1: number[], vector2: number[]): number {\n if (vector1.length !== vector2.length) {\n throw new Error(\"Vectors must have the same length\");\n }\n\n const dotProduct = vector1.reduce((acc, val, i) => acc + val * vector2[i], 0);\n const magnitude1 = Math.sqrt(\n vector1.reduce((acc, val) => acc + val * val, 0)\n );\n const magnitude2 = Math.sqrt(\n vector2.reduce((acc, val) => acc + val * val, 0)\n );\n\n if (magnitude1 === 0 || magnitude2 === 0) return 0;\n return dotProduct / (magnitude1 * magnitude2);\n}\n"],"mappings":"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"} |
+29
-28
@@ -1,8 +0,6 @@ | ||
| export type All = "*"; | ||
| export type PendingWriteValue = unknown; | ||
| export type PendingWrite<Channel = string> = [Channel, PendingWriteValue]; | ||
| export type CheckpointPendingWrite<TaskId = string> = [ | ||
| TaskId, | ||
| ...PendingWrite<string> | ||
| ]; | ||
| //#region src/types.d.ts | ||
| type All = "*"; | ||
| type PendingWriteValue = unknown; | ||
| type PendingWrite<Channel = string> = [Channel, PendingWriteValue]; | ||
| type CheckpointPendingWrite<TaskId = string> = [TaskId, ...PendingWrite<string>]; | ||
| /** | ||
@@ -13,23 +11,26 @@ * Additional details about the checkpoint, including the source, step, writes, and parents. | ||
| */ | ||
| export type CheckpointMetadata<ExtraProperties extends object = object> = { | ||
| /** | ||
| * The source of the checkpoint. | ||
| * - "input": The checkpoint was created from an input to invoke/stream/batch. | ||
| * - "loop": The checkpoint was created from inside the pregel loop. | ||
| * - "update": The checkpoint was created from a manual state update. | ||
| * - "fork": The checkpoint was created as a copy of another checkpoint. | ||
| */ | ||
| source: "input" | "loop" | "update" | "fork"; | ||
| /** | ||
| * The step number of the checkpoint. | ||
| * -1 for the first "input" checkpoint. | ||
| * 0 for the first "loop" checkpoint. | ||
| * ... for the nth checkpoint afterwards. | ||
| */ | ||
| step: number; | ||
| /** | ||
| * The IDs of the parent checkpoints. | ||
| * Mapping from checkpoint namespace to checkpoint ID. | ||
| */ | ||
| parents: Record<string, string>; | ||
| type CheckpointMetadata<ExtraProperties extends object = object> = { | ||
| /** | ||
| * The source of the checkpoint. | ||
| * - "input": The checkpoint was created from an input to invoke/stream/batch. | ||
| * - "loop": The checkpoint was created from inside the pregel loop. | ||
| * - "update": The checkpoint was created from a manual state update. | ||
| * - "fork": The checkpoint was created as a copy of another checkpoint. | ||
| */ | ||
| source: "input" | "loop" | "update" | "fork"; | ||
| /** | ||
| * The step number of the checkpoint. | ||
| * -1 for the first "input" checkpoint. | ||
| * 0 for the first "loop" checkpoint. | ||
| * ... for the nth checkpoint afterwards. | ||
| */ | ||
| step: number; | ||
| /** | ||
| * The IDs of the parent checkpoints. | ||
| * Mapping from checkpoint namespace to checkpoint ID. | ||
| */ | ||
| parents: Record<string, string>; | ||
| } & ExtraProperties; | ||
| //#endregion | ||
| export { All, CheckpointMetadata, CheckpointPendingWrite, PendingWrite, PendingWriteValue }; | ||
| //# sourceMappingURL=types.d.ts.map |
+16
-18
| { | ||
| "name": "@langchain/langgraph-checkpoint", | ||
| "version": "0.1.1", | ||
| "version": "1.0.0", | ||
| "description": "Library with base interfaces for LangGraph checkpoint savers.", | ||
@@ -9,4 +9,4 @@ "type": "module", | ||
| }, | ||
| "main": "./index.js", | ||
| "types": "./index.d.ts", | ||
| "main": "./dist/index.js", | ||
| "types": "./dist/index.d.ts", | ||
| "repository": { | ||
@@ -18,3 +18,3 @@ "type": "git", | ||
| "build": "yarn turbo:command build:internal --filter=@langchain/langgraph-checkpoint", | ||
| "build:internal": "yarn clean && yarn lc_build --create-entrypoints --pre --tree-shaking", | ||
| "build:internal": "yarn workspace @langchain/build compile @langchain/langgraph-checkpoint", | ||
| "clean": "rm -rf dist/ dist-cjs/ .turbo/", | ||
@@ -25,3 +25,3 @@ "lint:eslint": "NODE_OPTIONS=--max-old-space-size=4096 eslint --cache --ext .ts,.js src/", | ||
| "lint:fix": "yarn lint:eslint --fix && yarn lint:dpdm", | ||
| "prepack": "yarn build", | ||
| "prepublish": "yarn build", | ||
| "test": "vitest run", | ||
@@ -39,3 +39,3 @@ "test:watch": "vitest watch", | ||
| "peerDependencies": { | ||
| "@langchain/core": ">=0.2.31 <0.4.0 || ^1.0.0-alpha" | ||
| "@langchain/core": "^1.0.1" | ||
| }, | ||
@@ -57,3 +57,2 @@ "devDependencies": { | ||
| "prettier": "^2.8.3", | ||
| "release-it": "^19.0.2", | ||
| "rollup": "^4.37.0", | ||
@@ -70,9 +69,12 @@ "tsx": "^4.19.3", | ||
| ".": { | ||
| "types": { | ||
| "import": "./index.d.ts", | ||
| "require": "./index.d.cts", | ||
| "default": "./index.d.ts" | ||
| "input": "./src/index.ts", | ||
| "typedoc": "./src/index.ts", | ||
| "import": { | ||
| "types": "./dist/index.d.ts", | ||
| "default": "./dist/index.js" | ||
| }, | ||
| "import": "./index.js", | ||
| "require": "./index.cjs" | ||
| "require": { | ||
| "types": "./dist/index.d.cts", | ||
| "default": "./dist/index.cjs" | ||
| } | ||
| }, | ||
@@ -82,8 +84,4 @@ "./package.json": "./package.json" | ||
| "files": [ | ||
| "dist/", | ||
| "index.cjs", | ||
| "index.js", | ||
| "index.d.ts", | ||
| "index.d.cts" | ||
| "dist/" | ||
| ] | ||
| } |
| export * from "./base.js"; | ||
| export * from "./memory.js"; |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC"} |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"} |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| //# sourceMappingURL=base.js.map |
| export {}; | ||
| //# sourceMappingURL=base.js.map |
| {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/serde/base.ts"],"names":[],"mappings":""} |
| import { SerializerProtocol } from "./base.js"; | ||
| export declare class JsonPlusSerializer implements SerializerProtocol { | ||
| protected _dumps(obj: any): Uint8Array; | ||
| dumpsTyped(obj: any): Promise<[string, Uint8Array]>; | ||
| protected _loads(data: string): Promise<any>; | ||
| loadsTyped(type: string, data: Uint8Array | string): Promise<any>; | ||
| } |
| export declare function stringify(obj: any, replacer?: any, spacer?: any, options?: any): string; |
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
| for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| __exportStar(require("./base.cjs"), exports); | ||
| __exportStar(require("./batch.cjs"), exports); | ||
| __exportStar(require("./memory.cjs"), exports); | ||
| //# sourceMappingURL=index.js.map |
| export * from "./base.js"; | ||
| export * from "./batch.js"; | ||
| export * from "./memory.js"; |
| export * from "./base.js"; | ||
| export * from "./batch.js"; | ||
| export * from "./memory.js"; | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"} |
| /** | ||
| * Tokenize a JSON path into parts. | ||
| * @example | ||
| * tokenizePath("metadata.title") // -> ["metadata", "title"] | ||
| * tokenizePath("chapters[*].content") // -> ["chapters[*]", "content"] | ||
| */ | ||
| export declare function tokenizePath(path: string): string[]; | ||
| /** | ||
| * Compare values for filtering, supporting operator-based comparisons. | ||
| */ | ||
| export declare function compareValues(itemValue: unknown, filterValue: unknown): boolean; | ||
| /** | ||
| * Extract text from a value at a specific JSON path. | ||
| * | ||
| * Supports: | ||
| * - Simple paths: "field1.field2" | ||
| * - Array indexing: "[0]", "[*]", "[-1]" | ||
| * - Wildcards: "*" | ||
| * - Multi-field selection: "{field1,field2}" | ||
| * - Nested paths in multi-field: "{field1,nested.field2}" | ||
| */ | ||
| export declare function getTextAtPath(obj: unknown, path: string[] | string): string[]; | ||
| /** | ||
| * Calculate cosine similarity between two vectors. | ||
| */ | ||
| export declare function cosineSimilarity(vector1: number[], vector2: number[]): number; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| //# sourceMappingURL=types.js.map |
| export {}; | ||
| //# sourceMappingURL=types.js.map |
| {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""} |
| module.exports = require('./dist/index.cjs'); |
| export * from './dist/index.js' |
| export * from './dist/index.js' |
-1
| export * from './dist/index.js' |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
436348
90.73%18
-5.26%103
35.53%1
-50%3454
-23.16%