@langchain/langgraph-checkpoint 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base.cjs +4 -5
- package/dist/base.cjs.map +1 -1
- package/dist/base.d.cts +0 -1
- package/dist/base.d.cts.map +1 -1
- package/dist/base.d.ts +0 -1
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +1 -2
- package/dist/base.js.map +1 -1
- package/dist/cache/base.cjs +2 -3
- package/dist/cache/base.cjs.map +1 -1
- package/dist/cache/base.d.cts.map +1 -1
- package/dist/cache/base.d.ts.map +1 -1
- package/dist/cache/base.js +1 -2
- package/dist/cache/base.js.map +1 -1
- package/dist/cache/index.cjs +2 -2
- package/dist/cache/index.js +3 -4
- package/dist/cache/memory.cjs +7 -10
- package/dist/cache/memory.cjs.map +1 -1
- package/dist/cache/memory.d.cts.map +1 -1
- package/dist/cache/memory.d.ts.map +1 -1
- package/dist/cache/memory.js +6 -9
- package/dist/cache/memory.js.map +1 -1
- package/dist/id.cjs +2 -4
- package/dist/id.cjs.map +1 -1
- package/dist/id.d.cts +0 -4
- package/dist/id.d.cts.map +1 -1
- package/dist/id.d.ts +0 -4
- package/dist/id.d.ts.map +1 -1
- package/dist/id.js +1 -2
- package/dist/id.js.map +1 -1
- package/dist/index.cjs +12 -12
- package/dist/index.js +1 -2
- package/dist/memory.cjs +7 -10
- package/dist/memory.cjs.map +1 -1
- package/dist/memory.d.cts +0 -1
- package/dist/memory.d.cts.map +1 -1
- package/dist/memory.d.ts +0 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +5 -8
- package/dist/memory.js.map +1 -1
- package/dist/serde/base.d.cts +0 -2
- package/dist/serde/base.d.cts.map +1 -1
- package/dist/serde/base.d.ts +0 -2
- package/dist/serde/base.d.ts.map +1 -1
- package/dist/serde/jsonplus.cjs +14 -16
- package/dist/serde/jsonplus.cjs.map +1 -1
- package/dist/serde/jsonplus.js +11 -12
- package/dist/serde/jsonplus.js.map +1 -1
- package/dist/serde/types.cjs +1 -2
- package/dist/serde/types.cjs.map +1 -1
- package/dist/serde/types.d.cts +0 -3
- package/dist/serde/types.d.cts.map +1 -1
- package/dist/serde/types.d.ts +0 -3
- package/dist/serde/types.d.ts.map +1 -1
- package/dist/serde/types.js +1 -1
- package/dist/serde/types.js.map +1 -1
- package/dist/serde/utils/fast-safe-stringify/index.cjs +1 -2
- package/dist/serde/utils/fast-safe-stringify/index.cjs.map +1 -1
- package/dist/serde/utils/fast-safe-stringify/index.js +1 -1
- package/dist/serde/utils/fast-safe-stringify/index.js.map +1 -1
- package/dist/store/base.cjs +1 -2
- package/dist/store/base.cjs.map +1 -1
- package/dist/store/base.d.cts +0 -1
- package/dist/store/base.d.cts.map +1 -1
- package/dist/store/base.d.ts +0 -1
- package/dist/store/base.d.ts.map +1 -1
- package/dist/store/base.js +1 -1
- package/dist/store/base.js.map +1 -1
- package/dist/store/batch.cjs +3 -5
- package/dist/store/batch.cjs.map +1 -1
- package/dist/store/batch.d.cts +0 -3
- package/dist/store/batch.d.cts.map +1 -1
- package/dist/store/batch.d.ts +0 -3
- package/dist/store/batch.d.ts.map +1 -1
- package/dist/store/batch.js +2 -4
- package/dist/store/batch.js.map +1 -1
- package/dist/store/memory.cjs +8 -14
- package/dist/store/memory.cjs.map +1 -1
- package/dist/store/memory.d.cts +0 -2
- package/dist/store/memory.d.cts.map +1 -1
- package/dist/store/memory.d.ts +0 -2
- package/dist/store/memory.d.ts.map +1 -1
- package/dist/store/memory.js +6 -12
- package/dist/store/memory.js.map +1 -1
- package/dist/store/utils.cjs +31 -35
- package/dist/store/utils.cjs.map +1 -1
- package/dist/store/utils.js +31 -34
- package/dist/store/utils.js.map +1 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +17 -29
- package/CHANGELOG.md +0 -25
- package/dist/_virtual/rolldown_runtime.cjs +0 -25
package/dist/memory.cjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
const require_types = require(
|
|
2
|
-
const require_base = require(
|
|
3
|
-
|
|
1
|
+
const require_types = require("./serde/types.cjs");
|
|
2
|
+
const require_base = require("./base.cjs");
|
|
4
3
|
//#region src/memory.ts
|
|
5
4
|
function _generateKey(threadId, checkpointNamespace, checkpointId) {
|
|
6
5
|
return JSON.stringify([
|
|
@@ -68,8 +67,7 @@ var MemorySaver = class extends require_base.BaseCheckpointSaver {
|
|
|
68
67
|
const checkpoints = this.storage[thread_id]?.[checkpoint_ns];
|
|
69
68
|
if (checkpoints !== void 0) {
|
|
70
69
|
checkpoint_id = Object.keys(checkpoints).sort((a, b) => b.localeCompare(a))[0];
|
|
71
|
-
const
|
|
72
|
-
const [checkpoint, metadata, parentCheckpointId] = saved;
|
|
70
|
+
const [checkpoint, metadata, parentCheckpointId] = checkpoints[checkpoint_id];
|
|
73
71
|
const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id);
|
|
74
72
|
const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint);
|
|
75
73
|
if (deserializedCheckpoint.v < 4 && parentCheckpointId !== void 0) await this._migratePendingSends(deserializedCheckpoint, thread_id, checkpoint_ns, parentCheckpointId);
|
|
@@ -98,7 +96,6 @@ var MemorySaver = class extends require_base.BaseCheckpointSaver {
|
|
|
98
96
|
return checkpointTuple;
|
|
99
97
|
}
|
|
100
98
|
}
|
|
101
|
-
return void 0;
|
|
102
99
|
}
|
|
103
100
|
async *list(config, options) {
|
|
104
101
|
let { before, limit, filter } = options ?? {};
|
|
@@ -113,7 +110,7 @@ var MemorySaver = class extends require_base.BaseCheckpointSaver {
|
|
|
113
110
|
if (configCheckpointId && checkpointId !== configCheckpointId) continue;
|
|
114
111
|
if (before && before.configurable?.checkpoint_id && checkpointId >= before.configurable.checkpoint_id) continue;
|
|
115
112
|
const metadata = await this.serde.loadsTyped("json", metadataStr);
|
|
116
|
-
if (filter && !Object.entries(filter).every(([key
|
|
113
|
+
if (filter && !Object.entries(filter).every(([key, value]) => metadata[key] === value)) continue;
|
|
117
114
|
if (limit !== void 0) {
|
|
118
115
|
if (limit <= 0) break;
|
|
119
116
|
limit -= 1;
|
|
@@ -152,7 +149,7 @@ var MemorySaver = class extends require_base.BaseCheckpointSaver {
|
|
|
152
149
|
const preparedCheckpoint = require_base.copyCheckpoint(checkpoint);
|
|
153
150
|
const threadId = config.configurable?.thread_id;
|
|
154
151
|
const checkpointNamespace = config.configurable?.checkpoint_ns ?? "";
|
|
155
|
-
if (threadId === void 0) throw new Error(
|
|
152
|
+
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. When using a checkpointer, you must pass a \"thread_id\" so the checkpointer knows which conversation thread to persist state for. Example: graph.stream(input, { configurable: { thread_id: \"my-thread-id\" } })");
|
|
156
153
|
if (!this.storage[threadId]) this.storage[threadId] = {};
|
|
157
154
|
if (!this.storage[threadId][checkpointNamespace]) this.storage[threadId][checkpointNamespace] = {};
|
|
158
155
|
const [[, serializedCheckpoint], [, serializedMetadata]] = await Promise.all([this.serde.dumpsTyped(preparedCheckpoint), this.serde.dumpsTyped(metadata)]);
|
|
@@ -171,7 +168,7 @@ var MemorySaver = class extends require_base.BaseCheckpointSaver {
|
|
|
171
168
|
const threadId = config.configurable?.thread_id;
|
|
172
169
|
const checkpointNamespace = config.configurable?.checkpoint_ns;
|
|
173
170
|
const checkpointId = config.configurable?.checkpoint_id;
|
|
174
|
-
if (threadId === void 0) throw new Error(
|
|
171
|
+
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. When using a checkpointer, you must pass a \"thread_id\" so the checkpointer knows which conversation thread to persist state for. Example: graph.stream(input, { configurable: { thread_id: \"my-thread-id\" } })");
|
|
175
172
|
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.`);
|
|
176
173
|
const outerKey = _generateKey(threadId, checkpointNamespace, checkpointId);
|
|
177
174
|
const outerWrites_ = this.writes[outerKey];
|
|
@@ -193,7 +190,7 @@ var MemorySaver = class extends require_base.BaseCheckpointSaver {
|
|
|
193
190
|
for (const key of Object.keys(this.writes)) if (_parseKey(key).threadId === threadId) delete this.writes[key];
|
|
194
191
|
}
|
|
195
192
|
};
|
|
196
|
-
|
|
197
193
|
//#endregion
|
|
198
194
|
exports.MemorySaver = MemorySaver;
|
|
195
|
+
|
|
199
196
|
//# sourceMappingURL=memory.cjs.map
|
package/dist/memory.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"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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"}
|
|
1
|
+
{"version":3,"file":"memory.cjs","names":["BaseCheckpointSaver","TASKS","maxChannelVersion","getCheckpointId","copyCheckpoint","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 `When using a checkpointer, you must pass a \"thread_id\" so the checkpointer knows which conversation thread to persist state for. ` +\n `Example: graph.stream(input, { configurable: { thread_id: \"my-thread-id\" } })`\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 `When using a checkpointer, you must pass a \"thread_id\" so the checkpointer knows which conversation thread to persist state for. ` +\n `Example: graph.stream(input, { configurable: { thread_id: \"my-thread-id\" } })`\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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"}
|
package/dist/memory.d.cts
CHANGED
|
@@ -5,7 +5,6 @@ import { RunnableConfig } from "@langchain/core/runnables";
|
|
|
5
5
|
|
|
6
6
|
//#region src/memory.d.ts
|
|
7
7
|
declare class MemorySaver extends BaseCheckpointSaver {
|
|
8
|
-
// thread ID -> checkpoint namespace -> checkpoint ID -> checkpoint mapping
|
|
9
8
|
storage: Record<string, Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>>;
|
|
10
9
|
writes: Record<string, Record<string, [string, string, Uint8Array]>>;
|
|
11
10
|
constructor(serde?: SerializerProtocol);
|
package/dist/memory.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.cts","names":[
|
|
1
|
+
{"version":3,"file":"memory.d.cts","names":[],"sources":["../src/memory.ts"],"mappings":";;;;;;cAgCa,WAAA,SAAoB,mBAAA;EAE/B,OAAA,EAAS,MAAA,SAEP,MAAA,SAAe,MAAA,UAAgB,UAAA,EAAY,UAAA;EAG7C,MAAA,EAAQ,MAAA,SAAe,MAAA,0BAAgC,UAAA;EAEvD,WAAA,CAAY,KAAA,GAAQ,kBAAA;;EAKd,oBAAA,CACJ,iBAAA,EAAmB,UAAA,EACnB,QAAA,UACA,YAAA,UACA,kBAAA,WAA0B,OAAA;EA0BtB,QAAA,CAAS,MAAA,EAAQ,cAAA,GAAiB,OAAA,CAAQ,eAAA;EAyHzC,IAAA,CACL,MAAA,EAAQ,cAAA,EACR,OAAA,GAAU,qBAAA,GACT,cAAA,CAAe,eAAA;EAyHZ,GAAA,CACJ,MAAA,EAAQ,cAAA,EACR,UAAA,EAAY,UAAA,EACZ,QAAA,EAAU,kBAAA,GACT,OAAA,CAAQ,cAAA;EAwCL,SAAA,CACJ,MAAA,EAAQ,cAAA,EACR,MAAA,EAAQ,YAAA,IACR,MAAA,WACC,OAAA;EAsCG,YAAA,CAAa,QAAA,WAAmB,OAAA;AAAA"}
|
package/dist/memory.d.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { RunnableConfig } from "@langchain/core/runnables";
|
|
|
5
5
|
|
|
6
6
|
//#region src/memory.d.ts
|
|
7
7
|
declare class MemorySaver extends BaseCheckpointSaver {
|
|
8
|
-
// thread ID -> checkpoint namespace -> checkpoint ID -> checkpoint mapping
|
|
9
8
|
storage: Record<string, Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>>;
|
|
10
9
|
writes: Record<string, Record<string, [string, string, Uint8Array]>>;
|
|
11
10
|
constructor(serde?: SerializerProtocol);
|
package/dist/memory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","names":[
|
|
1
|
+
{"version":3,"file":"memory.d.ts","names":[],"sources":["../src/memory.ts"],"mappings":";;;;;;cAgCa,WAAA,SAAoB,mBAAA;EAE/B,OAAA,EAAS,MAAA,SAEP,MAAA,SAAe,MAAA,UAAgB,UAAA,EAAY,UAAA;EAG7C,MAAA,EAAQ,MAAA,SAAe,MAAA,0BAAgC,UAAA;EAEvD,WAAA,CAAY,KAAA,GAAQ,kBAAA;;EAKd,oBAAA,CACJ,iBAAA,EAAmB,UAAA,EACnB,QAAA,UACA,YAAA,UACA,kBAAA,WAA0B,OAAA;EA0BtB,QAAA,CAAS,MAAA,EAAQ,cAAA,GAAiB,OAAA,CAAQ,eAAA;EAyHzC,IAAA,CACL,MAAA,EAAQ,cAAA,EACR,OAAA,GAAU,qBAAA,GACT,cAAA,CAAe,eAAA;EAyHZ,GAAA,CACJ,MAAA,EAAQ,cAAA,EACR,UAAA,EAAY,UAAA,EACZ,QAAA,EAAU,kBAAA,GACT,OAAA,CAAQ,cAAA;EAwCL,SAAA,CACJ,MAAA,EAAQ,cAAA,EACR,MAAA,EAAQ,YAAA,IACR,MAAA,WACC,OAAA;EAsCG,YAAA,CAAa,QAAA,WAAmB,OAAA;AAAA"}
|
package/dist/memory.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { TASKS } from "./serde/types.js";
|
|
2
2
|
import { BaseCheckpointSaver, WRITES_IDX_MAP, copyCheckpoint, getCheckpointId, maxChannelVersion } from "./base.js";
|
|
3
|
-
|
|
4
3
|
//#region src/memory.ts
|
|
5
4
|
function _generateKey(threadId, checkpointNamespace, checkpointId) {
|
|
6
5
|
return JSON.stringify([
|
|
@@ -68,8 +67,7 @@ var MemorySaver = class extends BaseCheckpointSaver {
|
|
|
68
67
|
const checkpoints = this.storage[thread_id]?.[checkpoint_ns];
|
|
69
68
|
if (checkpoints !== void 0) {
|
|
70
69
|
checkpoint_id = Object.keys(checkpoints).sort((a, b) => b.localeCompare(a))[0];
|
|
71
|
-
const
|
|
72
|
-
const [checkpoint, metadata, parentCheckpointId] = saved;
|
|
70
|
+
const [checkpoint, metadata, parentCheckpointId] = checkpoints[checkpoint_id];
|
|
73
71
|
const key = _generateKey(thread_id, checkpoint_ns, checkpoint_id);
|
|
74
72
|
const deserializedCheckpoint = await this.serde.loadsTyped("json", checkpoint);
|
|
75
73
|
if (deserializedCheckpoint.v < 4 && parentCheckpointId !== void 0) await this._migratePendingSends(deserializedCheckpoint, thread_id, checkpoint_ns, parentCheckpointId);
|
|
@@ -98,7 +96,6 @@ var MemorySaver = class extends BaseCheckpointSaver {
|
|
|
98
96
|
return checkpointTuple;
|
|
99
97
|
}
|
|
100
98
|
}
|
|
101
|
-
return void 0;
|
|
102
99
|
}
|
|
103
100
|
async *list(config, options) {
|
|
104
101
|
let { before, limit, filter } = options ?? {};
|
|
@@ -113,7 +110,7 @@ var MemorySaver = class extends BaseCheckpointSaver {
|
|
|
113
110
|
if (configCheckpointId && checkpointId !== configCheckpointId) continue;
|
|
114
111
|
if (before && before.configurable?.checkpoint_id && checkpointId >= before.configurable.checkpoint_id) continue;
|
|
115
112
|
const metadata = await this.serde.loadsTyped("json", metadataStr);
|
|
116
|
-
if (filter && !Object.entries(filter).every(([key
|
|
113
|
+
if (filter && !Object.entries(filter).every(([key, value]) => metadata[key] === value)) continue;
|
|
117
114
|
if (limit !== void 0) {
|
|
118
115
|
if (limit <= 0) break;
|
|
119
116
|
limit -= 1;
|
|
@@ -152,7 +149,7 @@ var MemorySaver = class extends BaseCheckpointSaver {
|
|
|
152
149
|
const preparedCheckpoint = copyCheckpoint(checkpoint);
|
|
153
150
|
const threadId = config.configurable?.thread_id;
|
|
154
151
|
const checkpointNamespace = config.configurable?.checkpoint_ns ?? "";
|
|
155
|
-
if (threadId === void 0) throw new Error(
|
|
152
|
+
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. When using a checkpointer, you must pass a \"thread_id\" so the checkpointer knows which conversation thread to persist state for. Example: graph.stream(input, { configurable: { thread_id: \"my-thread-id\" } })");
|
|
156
153
|
if (!this.storage[threadId]) this.storage[threadId] = {};
|
|
157
154
|
if (!this.storage[threadId][checkpointNamespace]) this.storage[threadId][checkpointNamespace] = {};
|
|
158
155
|
const [[, serializedCheckpoint], [, serializedMetadata]] = await Promise.all([this.serde.dumpsTyped(preparedCheckpoint), this.serde.dumpsTyped(metadata)]);
|
|
@@ -171,7 +168,7 @@ var MemorySaver = class extends BaseCheckpointSaver {
|
|
|
171
168
|
const threadId = config.configurable?.thread_id;
|
|
172
169
|
const checkpointNamespace = config.configurable?.checkpoint_ns;
|
|
173
170
|
const checkpointId = config.configurable?.checkpoint_id;
|
|
174
|
-
if (threadId === void 0) throw new Error(
|
|
171
|
+
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. When using a checkpointer, you must pass a \"thread_id\" so the checkpointer knows which conversation thread to persist state for. Example: graph.stream(input, { configurable: { thread_id: \"my-thread-id\" } })");
|
|
175
172
|
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.`);
|
|
176
173
|
const outerKey = _generateKey(threadId, checkpointNamespace, checkpointId);
|
|
177
174
|
const outerWrites_ = this.writes[outerKey];
|
|
@@ -193,7 +190,7 @@ var MemorySaver = class extends BaseCheckpointSaver {
|
|
|
193
190
|
for (const key of Object.keys(this.writes)) if (_parseKey(key).threadId === threadId) delete this.writes[key];
|
|
194
191
|
}
|
|
195
192
|
};
|
|
196
|
-
|
|
197
193
|
//#endregion
|
|
198
194
|
export { MemorySaver };
|
|
195
|
+
|
|
199
196
|
//# sourceMappingURL=memory.js.map
|
package/dist/memory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"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
|
+
{"version":3,"file":"memory.js","names":[],"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 `When using a checkpointer, you must pass a \"thread_id\" so the checkpointer knows which conversation thread to persist state for. ` +\n `Example: graph.stream(input, { configurable: { thread_id: \"my-thread-id\" } })`\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 `When using a checkpointer, you must pass a \"thread_id\" so the checkpointer knows which conversation thread to persist state for. ` +\n `Example: graph.stream(input, { configurable: { thread_id: \"my-thread-id\" } })`\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":";;;AAmBA,SAAS,aACP,UACA,qBACA,cACA;AACA,QAAO,KAAK,UAAU;EAAC;EAAU;EAAqB;EAAa,CAAC;;AAGtE,SAAS,UAAU,KAAa;CAC9B,MAAM,CAAC,UAAU,qBAAqB,gBAAgB,KAAK,MAAM,IAAI;AACrE,QAAO;EAAE;EAAU;EAAqB;EAAc;;AAGxD,IAAa,cAAb,cAAiC,oBAAoB;CAEnD,UAGI,EAAE;CAEN,SAAuE,EAAE;CAEzE,YAAY,OAA4B;AACtC,QAAM,MAAM;;;CAId,MAAM,qBACJ,mBACA,UACA,cACA,oBACA;EACA,MAAM,4BAA4B;EAClC,MAAM,YAAY,aAAa,UAAU,cAAc,mBAAmB;EAE1E,MAAM,eAAe,MAAM,QAAQ,IACjC,OAAO,OAAO,KAAK,OAAO,cAAc,EAAE,CAAC,CACxC,QAAQ,CAAC,SAAS,aAAa,YAAY,MAAM,CACjD,IACC,OAAO,CAAC,SAAS,UAAU,YACzB,MAAM,KAAK,MAAM,WAAW,QAAQ,OAAO,CAC9C,CACJ;AAED,4BAA0B,mBAAmB,EAAE;AAC/C,4BAA0B,eAAe,SAAS;AAElD,4BAA0B,qBAAqB,EAAE;AACjD,4BAA0B,iBAAiB,SACzC,OAAO,KAAK,0BAA0B,iBAAiB,CAAC,SAAS,IAC7D,kBACE,GAAG,OAAO,OAAO,0BAA0B,iBAAiB,CAC7D,GACD,KAAK,eAAe,KAAA,EAAU;;CAGtC,MAAM,SAAS,QAA8D;EAC3E,MAAM,YAAY,OAAO,cAAc;EACvC,MAAM,gBAAgB,OAAO,cAAc,iBAAiB;EAC5D,IAAI,gBAAgB,gBAAgB,OAAO;AAE3C,MAAI,eAAe;GACjB,MAAM,QAAQ,KAAK,QAAQ,aAAa,iBAAiB;AACzD,OAAI,UAAU,KAAA,GAAW;IACvB,MAAM,CAAC,YAAY,UAAU,sBAAsB;IACnD,MAAM,MAAM,aAAa,WAAW,eAAe,cAAc;IACjE,MAAM,yBAAqC,MAAM,KAAK,MAAM,WAC1D,QACA,WACD;AAED,QAAI,uBAAuB,IAAI,KAAK,uBAAuB,KAAA,EACzD,OAAM,KAAK,qBACT,wBACA,WACA,eACA,mBACD;IAGH,MAAM,gBAA0C,MAAM,QAAQ,IAC5D,OAAO,OAAO,KAAK,OAAO,QAAQ,EAAE,CAAC,CAAC,IACpC,OAAO,CAAC,QAAQ,SAAS,WAAW;AAClC,YAAO;MACL;MACA;MACA,MAAM,KAAK,MAAM,WAAW,QAAQ,MAAM;MAC3C;MAEJ,CACF;IACD,MAAM,kBAAmC;KACvC;KACA,YAAY;KACZ,UAAW,MAAM,KAAK,MAAM,WAC1B,QACA,SACD;KACD;KACD;AACD,QAAI,uBAAuB,KAAA,EACzB,iBAAgB,eAAe,EAC7B,cAAc;KACZ;KACA;KACA,eAAe;KAChB,EACF;AAEH,WAAO;;SAEJ;GACL,MAAM,cAAc,KAAK,QAAQ,aAAa;AAC9C,OAAI,gBAAgB,KAAA,GAAW;AAE7B,oBAAgB,OAAO,KAAK,YAAY,CAAC,MAAM,GAAG,MAChD,EAAE,cAAc,EAAE,CACnB,CAAC;IAEF,MAAM,CAAC,YAAY,UAAU,sBADf,YAAY;IAE1B,MAAM,MAAM,aAAa,WAAW,eAAe,cAAc;IACjE,MAAM,yBAAqC,MAAM,KAAK,MAAM,WAC1D,QACA,WACD;AAED,QAAI,uBAAuB,IAAI,KAAK,uBAAuB,KAAA,EACzD,OAAM,KAAK,qBACT,wBACA,WACA,eACA,mBACD;IAGH,MAAM,gBAA0C,MAAM,QAAQ,IAC5D,OAAO,OAAO,KAAK,OAAO,QAAQ,EAAE,CAAC,CAAC,IACpC,OAAO,CAAC,QAAQ,SAAS,WAAW;AAClC,YAAO;MACL;MACA;MACA,MAAM,KAAK,MAAM,WAAW,QAAQ,MAAM;MAC3C;MAEJ,CACF;IACD,MAAM,kBAAmC;KACvC,QAAQ,EACN,cAAc;MACZ;MACA;MACA;MACD,EACF;KACD,YAAY;KACZ,UAAW,MAAM,KAAK,MAAM,WAC1B,QACA,SACD;KACD;KACD;AACD,QAAI,uBAAuB,KAAA,EACzB,iBAAgB,eAAe,EAC7B,cAAc;KACZ;KACA;KACA,eAAe;KAChB,EACF;AAEH,WAAO;;;;CAOb,OAAO,KACL,QACA,SACiC;EAEjC,IAAI,EAAE,QAAQ,OAAO,WAAW,WAAW,EAAE;EAC7C,MAAM,YAAY,OAAO,cAAc,YACnC,CAAC,OAAO,cAAc,UAAU,GAChC,OAAO,KAAK,KAAK,QAAQ;EAC7B,MAAM,4BAA4B,OAAO,cAAc;EACvD,MAAM,qBAAqB,OAAO,cAAc;AAEhD,OAAK,MAAM,YAAY,UACrB,MAAK,MAAM,uBAAuB,OAAO,KACvC,KAAK,QAAQ,aAAa,EAAE,CAC7B,EAAE;AACD,OACE,8BAA8B,KAAA,KAC9B,wBAAwB,0BAExB;GAEF,MAAM,cAAc,KAAK,QAAQ,YAAY,wBAAwB,EAAE;GACvE,MAAM,oBAAoB,OAAO,QAAQ,YAAY,CAAC,MAAM,GAAG,MAC7D,EAAE,GAAG,cAAc,EAAE,GAAG,CACzB;AAED,QAAK,MAAM,CACT,cACA,CAAC,YAAY,aAAa,wBACvB,mBAAmB;AAEtB,QAAI,sBAAsB,iBAAiB,mBACzC;AAIF,QACE,UACA,OAAO,cAAc,iBACrB,gBAAgB,OAAO,aAAa,cAEpC;IAIF,MAAM,WAAY,MAAM,KAAK,MAAM,WACjC,QACA,YACD;AAED,QACE,UACA,CAAC,OAAO,QAAQ,OAAO,CAAC,OACrB,CAAC,KAAK,WACJ,SAAgD,SAAS,MAC7D,CAED;AAIF,QAAI,UAAU,KAAA,GAAW;AACvB,SAAI,SAAS,EAAG;AAChB,cAAS;;IAGX,MAAM,MAAM,aAAa,UAAU,qBAAqB,aAAa;IACrE,MAAM,SAAS,OAAO,OAAO,KAAK,OAAO,QAAQ,EAAE,CAAC;IAEpD,MAAM,gBAA0C,MAAM,QAAQ,IAC5D,OAAO,IAAI,OAAO,CAAC,QAAQ,SAAS,WAAW;AAC7C,YAAO;MACL;MACA;MACA,MAAM,KAAK,MAAM,WAAW,QAAQ,MAAM;MAC3C;MACD,CACH;IAED,MAAM,yBAAyB,MAAM,KAAK,MAAM,WAC9C,QACA,WACD;AAED,QACE,uBAAuB,IAAI,KAC3B,uBAAuB,KAAA,EAEvB,OAAM,KAAK,qBACT,wBACA,UACA,qBACA,mBACD;IAGH,MAAM,kBAAmC;KACvC,QAAQ,EACN,cAAc;MACZ,WAAW;MACX,eAAe;MACf,eAAe;MAChB,EACF;KACD,YAAY;KACZ;KACA;KACD;AACD,QAAI,uBAAuB,KAAA,EACzB,iBAAgB,eAAe,EAC7B,cAAc;KACZ,WAAW;KACX,eAAe;KACf,eAAe;KAChB,EACF;AAEH,UAAM;;;;CAMd,MAAM,IACJ,QACA,YACA,UACyB;EACzB,MAAM,qBAA0C,eAAe,WAAW;EAC1E,MAAM,WAAW,OAAO,cAAc;EACtC,MAAM,sBAAsB,OAAO,cAAc,iBAAiB;AAClE,MAAI,aAAa,KAAA,EACf,OAAM,IAAI,MACR,qVAGD;AAGH,MAAI,CAAC,KAAK,QAAQ,UAChB,MAAK,QAAQ,YAAY,EAAE;AAE7B,MAAI,CAAC,KAAK,QAAQ,UAAU,qBAC1B,MAAK,QAAQ,UAAU,uBAAuB,EAAE;EAGlD,MAAM,CAAC,GAAG,uBAAuB,GAAG,uBAClC,MAAM,QAAQ,IAAI,CAChB,KAAK,MAAM,WAAW,mBAAmB,EACzC,KAAK,MAAM,WAAW,SAAS,CAChC,CAAC;AAEJ,OAAK,QAAQ,UAAU,qBAAqB,WAAW,MAAM;GAC3D;GACA;GACA,OAAO,cAAc;GACtB;AAED,SAAO,EACL,cAAc;GACZ,WAAW;GACX,eAAe;GACf,eAAe,WAAW;GAC3B,EACF;;CAGH,MAAM,UACJ,QACA,QACA,QACe;EACf,MAAM,WAAW,OAAO,cAAc;EACtC,MAAM,sBAAsB,OAAO,cAAc;EACjD,MAAM,eAAe,OAAO,cAAc;AAC1C,MAAI,aAAa,KAAA,EACf,OAAM,IAAI,MACR,iVAGD;AAEH,MAAI,iBAAiB,KAAA,EACnB,OAAM,IAAI,MACR,8HACD;EAEH,MAAM,WAAW,aAAa,UAAU,qBAAqB,aAAa;EAC1E,MAAM,eAAe,KAAK,OAAO;AACjC,MAAI,KAAK,OAAO,cAAc,KAAA,EAC5B,MAAK,OAAO,YAAY,EAAE;AAG5B,QAAM,QAAQ,IACZ,OAAO,IAAI,OAAO,CAAC,SAAS,QAAQ,QAAQ;GAC1C,MAAM,GAAG,mBAAmB,MAAM,KAAK,MAAM,WAAW,MAAM;GAC9D,MAAM,WAA6B,CACjC,QACA,eAAe,YAAY,IAC5B;GACD,MAAM,cAAc,GAAG,SAAS,GAAG,GAAG,SAAS;AAC/C,OAAI,SAAS,MAAM,KAAK,gBAAgB,eAAe,aACrD;AAEF,QAAK,OAAO,UAAU,eAAe;IAAC;IAAQ;IAAS;IAAgB;IACvE,CACH;;CAGH,MAAM,aAAa,UAAiC;AAClD,SAAO,KAAK,QAAQ;AACpB,OAAK,MAAM,OAAO,OAAO,KAAK,KAAK,OAAO,CACxC,KAAI,UAAU,IAAI,CAAC,aAAa,SAAU,QAAO,KAAK,OAAO"}
|
package/dist/serde/base.d.cts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
//#region src/serde/base.d.ts
|
|
2
2
|
interface SerializerProtocol {
|
|
3
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
3
|
dumpsTyped(data: any): Promise<[string, Uint8Array]>;
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
4
|
loadsTyped(type: string, data: Uint8Array | string): Promise<any>;
|
|
7
5
|
}
|
|
8
6
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.cts","names":[
|
|
1
|
+
{"version":3,"file":"base.d.cts","names":[],"sources":["../../src/serde/base.ts"],"mappings":";UAAiB,kBAAA;EAEf,UAAA,CAAW,IAAA,QAAY,OAAA,UAAiB,UAAA;EAExC,UAAA,CAAW,IAAA,UAAc,IAAA,EAAM,UAAA,YAAsB,OAAA;AAAA"}
|
package/dist/serde/base.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
//#region src/serde/base.d.ts
|
|
2
2
|
interface SerializerProtocol {
|
|
3
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
3
|
dumpsTyped(data: any): Promise<[string, Uint8Array]>;
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
4
|
loadsTyped(type: string, data: Uint8Array | string): Promise<any>;
|
|
7
5
|
}
|
|
8
6
|
//#endregion
|
package/dist/serde/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","names":[
|
|
1
|
+
{"version":3,"file":"base.d.ts","names":[],"sources":["../../src/serde/base.ts"],"mappings":";UAAiB,kBAAA;EAEf,UAAA,CAAW,IAAA,QAAY,OAAA,UAAiB,UAAA;EAExC,UAAA,CAAW,IAAA,UAAc,IAAA,EAAM,UAAA,YAAsB,OAAA;AAAA"}
|
package/dist/serde/jsonplus.cjs
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
const __langchain_core_load = require_rolldown_runtime.__toESM(require("@langchain/core/load"));
|
|
4
|
-
|
|
1
|
+
const require_index = require("./utils/fast-safe-stringify/index.cjs");
|
|
2
|
+
let _langchain_core_load = require("@langchain/core/load");
|
|
5
3
|
//#region src/serde/jsonplus.ts
|
|
6
4
|
function isLangChainSerializedObject(value) {
|
|
7
5
|
return value !== null && value.lc === 1 && value.type === "constructor" && Array.isArray(value.id);
|
|
@@ -15,13 +13,11 @@ function isLangChainSerializedObject(value) {
|
|
|
15
13
|
* deserialize upwards rather than top-down.
|
|
16
14
|
*/
|
|
17
15
|
async function _reviver(value) {
|
|
18
|
-
if (value && typeof value === "object") if (Array.isArray(value))
|
|
19
|
-
|
|
20
|
-
return revivedArray;
|
|
21
|
-
} else {
|
|
16
|
+
if (value && typeof value === "object") if (Array.isArray(value)) return await Promise.all(value.map((item) => _reviver(item)));
|
|
17
|
+
else {
|
|
22
18
|
const revivedObj = {};
|
|
23
19
|
for (const [k, v] of Object.entries(value)) revivedObj[k] = await _reviver(v);
|
|
24
|
-
if (revivedObj.lc === 2 && revivedObj.type === "undefined") return
|
|
20
|
+
if (revivedObj.lc === 2 && revivedObj.type === "undefined") return;
|
|
25
21
|
else if (revivedObj.lc === 2 && revivedObj.type === "constructor" && Array.isArray(revivedObj.id)) try {
|
|
26
22
|
const constructorName = revivedObj.id[revivedObj.id.length - 1];
|
|
27
23
|
let constructor;
|
|
@@ -38,14 +34,17 @@ async function _reviver(value) {
|
|
|
38
34
|
case "Error":
|
|
39
35
|
constructor = Error;
|
|
40
36
|
break;
|
|
37
|
+
case "Uint8Array":
|
|
38
|
+
constructor = Uint8Array;
|
|
39
|
+
break;
|
|
41
40
|
default: return revivedObj;
|
|
42
41
|
}
|
|
43
42
|
if (revivedObj.method) return constructor[revivedObj.method](...revivedObj.args || []);
|
|
44
43
|
else return new constructor(...revivedObj.args || []);
|
|
45
|
-
} catch
|
|
44
|
+
} catch {
|
|
46
45
|
return revivedObj;
|
|
47
46
|
}
|
|
48
|
-
else if (isLangChainSerializedObject(revivedObj)) return (0,
|
|
47
|
+
else if (isLangChainSerializedObject(revivedObj)) return (0, _langchain_core_load.load)(JSON.stringify(revivedObj));
|
|
49
48
|
return revivedObj;
|
|
50
49
|
}
|
|
51
50
|
return value;
|
|
@@ -72,12 +71,12 @@ function _default(obj) {
|
|
|
72
71
|
node: obj.node,
|
|
73
72
|
args: obj.args
|
|
74
73
|
};
|
|
74
|
+
else if (obj instanceof Uint8Array) return _encodeConstructorArgs(Uint8Array, "from", [Array.from(obj)]);
|
|
75
75
|
else return obj;
|
|
76
76
|
}
|
|
77
77
|
var JsonPlusSerializer = class {
|
|
78
78
|
_dumps(obj) {
|
|
79
|
-
|
|
80
|
-
return encoder.encode(require_index.stringify(obj, (_, value) => {
|
|
79
|
+
return new TextEncoder().encode(require_index.stringify(obj, (_, value) => {
|
|
81
80
|
return _default(value);
|
|
82
81
|
}));
|
|
83
82
|
}
|
|
@@ -86,8 +85,7 @@ var JsonPlusSerializer = class {
|
|
|
86
85
|
else return ["json", this._dumps(obj)];
|
|
87
86
|
}
|
|
88
87
|
async _loads(data) {
|
|
89
|
-
|
|
90
|
-
return _reviver(parsed);
|
|
88
|
+
return _reviver(JSON.parse(data));
|
|
91
89
|
}
|
|
92
90
|
async loadsTyped(type, data) {
|
|
93
91
|
if (type === "bytes") return typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
@@ -95,7 +93,7 @@ var JsonPlusSerializer = class {
|
|
|
95
93
|
else throw new Error(`Unknown serialization type: ${type}`);
|
|
96
94
|
}
|
|
97
95
|
};
|
|
98
|
-
|
|
99
96
|
//#endregion
|
|
100
97
|
exports.JsonPlusSerializer = JsonPlusSerializer;
|
|
98
|
+
|
|
101
99
|
//# sourceMappingURL=jsonplus.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonplus.cjs","names":["
|
|
1
|
+
{"version":3,"file":"jsonplus.cjs","names":["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 case \"Uint8Array\":\n constructor = Uint8Array;\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 {\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 // oxlint-disable-next-line @typescript-eslint/no-unsafe-function-type\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 if (obj instanceof Uint8Array) {\n return _encodeConstructorArgs(Uint8Array, \"from\", [Array.from(obj)]);\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":"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"}
|
package/dist/serde/jsonplus.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { stringify } from "./utils/fast-safe-stringify/index.js";
|
|
2
2
|
import { load } from "@langchain/core/load";
|
|
3
|
-
|
|
4
3
|
//#region src/serde/jsonplus.ts
|
|
5
4
|
function isLangChainSerializedObject(value) {
|
|
6
5
|
return value !== null && value.lc === 1 && value.type === "constructor" && Array.isArray(value.id);
|
|
@@ -14,13 +13,11 @@ function isLangChainSerializedObject(value) {
|
|
|
14
13
|
* deserialize upwards rather than top-down.
|
|
15
14
|
*/
|
|
16
15
|
async function _reviver(value) {
|
|
17
|
-
if (value && typeof value === "object") if (Array.isArray(value))
|
|
18
|
-
|
|
19
|
-
return revivedArray;
|
|
20
|
-
} else {
|
|
16
|
+
if (value && typeof value === "object") if (Array.isArray(value)) return await Promise.all(value.map((item) => _reviver(item)));
|
|
17
|
+
else {
|
|
21
18
|
const revivedObj = {};
|
|
22
19
|
for (const [k, v] of Object.entries(value)) revivedObj[k] = await _reviver(v);
|
|
23
|
-
if (revivedObj.lc === 2 && revivedObj.type === "undefined") return
|
|
20
|
+
if (revivedObj.lc === 2 && revivedObj.type === "undefined") return;
|
|
24
21
|
else if (revivedObj.lc === 2 && revivedObj.type === "constructor" && Array.isArray(revivedObj.id)) try {
|
|
25
22
|
const constructorName = revivedObj.id[revivedObj.id.length - 1];
|
|
26
23
|
let constructor;
|
|
@@ -37,11 +34,14 @@ async function _reviver(value) {
|
|
|
37
34
|
case "Error":
|
|
38
35
|
constructor = Error;
|
|
39
36
|
break;
|
|
37
|
+
case "Uint8Array":
|
|
38
|
+
constructor = Uint8Array;
|
|
39
|
+
break;
|
|
40
40
|
default: return revivedObj;
|
|
41
41
|
}
|
|
42
42
|
if (revivedObj.method) return constructor[revivedObj.method](...revivedObj.args || []);
|
|
43
43
|
else return new constructor(...revivedObj.args || []);
|
|
44
|
-
} catch
|
|
44
|
+
} catch {
|
|
45
45
|
return revivedObj;
|
|
46
46
|
}
|
|
47
47
|
else if (isLangChainSerializedObject(revivedObj)) return load(JSON.stringify(revivedObj));
|
|
@@ -71,12 +71,12 @@ function _default(obj) {
|
|
|
71
71
|
node: obj.node,
|
|
72
72
|
args: obj.args
|
|
73
73
|
};
|
|
74
|
+
else if (obj instanceof Uint8Array) return _encodeConstructorArgs(Uint8Array, "from", [Array.from(obj)]);
|
|
74
75
|
else return obj;
|
|
75
76
|
}
|
|
76
77
|
var JsonPlusSerializer = class {
|
|
77
78
|
_dumps(obj) {
|
|
78
|
-
|
|
79
|
-
return encoder.encode(stringify(obj, (_, value) => {
|
|
79
|
+
return new TextEncoder().encode(stringify(obj, (_, value) => {
|
|
80
80
|
return _default(value);
|
|
81
81
|
}));
|
|
82
82
|
}
|
|
@@ -85,8 +85,7 @@ var JsonPlusSerializer = class {
|
|
|
85
85
|
else return ["json", this._dumps(obj)];
|
|
86
86
|
}
|
|
87
87
|
async _loads(data) {
|
|
88
|
-
|
|
89
|
-
return _reviver(parsed);
|
|
88
|
+
return _reviver(JSON.parse(data));
|
|
90
89
|
}
|
|
91
90
|
async loadsTyped(type, data) {
|
|
92
91
|
if (type === "bytes") return typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
@@ -94,7 +93,7 @@ var JsonPlusSerializer = class {
|
|
|
94
93
|
else throw new Error(`Unknown serialization type: ${type}`);
|
|
95
94
|
}
|
|
96
95
|
};
|
|
97
|
-
|
|
98
96
|
//#endregion
|
|
99
97
|
export { JsonPlusSerializer };
|
|
98
|
+
|
|
100
99
|
//# sourceMappingURL=jsonplus.js.map
|