@langchain/langgraph-checkpoint 1.1.6 → 1.2.0
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 +67 -1
- package/dist/base.cjs.map +1 -1
- package/dist/base.d.cts +47 -2
- package/dist/base.d.cts.map +1 -1
- package/dist/base.d.ts +47 -2
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +66 -2
- package/dist/base.js.map +1 -1
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/memory.cjs +47 -39
- package/dist/memory.cjs.map +1 -1
- package/dist/memory.d.cts +12 -2
- package/dist/memory.d.cts.map +1 -1
- package/dist/memory.d.ts +12 -2
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +48 -40
- package/dist/memory.js.map +1 -1
- package/dist/store/base.cjs +28 -8
- package/dist/store/base.cjs.map +1 -1
- package/dist/store/base.d.cts.map +1 -1
- package/dist/store/base.d.ts.map +1 -1
- package/dist/store/base.js +28 -8
- package/dist/store/base.js.map +1 -1
- package/dist/store/batch.cjs +13 -0
- package/dist/store/batch.cjs.map +1 -1
- package/dist/store/batch.d.cts.map +1 -1
- package/dist/store/batch.d.ts.map +1 -1
- package/dist/store/batch.js +14 -1
- package/dist/store/batch.js.map +1 -1
- package/package.json +1 -1
package/dist/base.cjs
CHANGED
|
@@ -30,6 +30,62 @@ function copyCheckpoint(checkpoint) {
|
|
|
30
30
|
versions_seen: deepCopy(checkpoint.versions_seen ?? {})
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Sort key for the writes of one superstep.
|
|
35
|
+
*
|
|
36
|
+
* Live execution applies a superstep's tasks in this order (see `_applyWrites`
|
|
37
|
+
* in `@langchain/langgraph-core`), so a saver that replays stored writes, as
|
|
38
|
+
* `getDeltaChannelHistory` does, must sort them by it too, or an
|
|
39
|
+
* order-sensitive (but batching-invariant) reducer rebuilds a different value
|
|
40
|
+
* than the run produced. `taskPath` is the string passed to `putWrites`.
|
|
41
|
+
*
|
|
42
|
+
* Writes stored without a task path (graph input, `Command` updates, rows
|
|
43
|
+
* predating the column) use `""`, which sorts
|
|
44
|
+
* first, before any real task path — which is also where live execution
|
|
45
|
+
* applies input.
|
|
46
|
+
*/
|
|
47
|
+
function writesSortKey(taskPath, taskId = "", idx = 0) {
|
|
48
|
+
return [
|
|
49
|
+
taskPath,
|
|
50
|
+
taskId,
|
|
51
|
+
idx
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Compare two {@link WritesSortKey}s: strings by code point (matching Python
|
|
56
|
+
* `str` order, which differs from UTF-16 code-unit order for astral
|
|
57
|
+
* characters), `idx` numerically.
|
|
58
|
+
*
|
|
59
|
+
* The one comparator for a superstep's writes — used by live execution and
|
|
60
|
+
* every saver, so they cannot drift apart. Do not sort write keys with `<`,
|
|
61
|
+
* `localeCompare`, or default `Array.prototype.sort` on the key tuple.
|
|
62
|
+
*/
|
|
63
|
+
function compareWritesSortKeys(a, b) {
|
|
64
|
+
if (a[0] !== b[0]) return compareStringsByCodePoint(a[0], b[0]);
|
|
65
|
+
if (a[1] !== b[1]) return compareStringsByCodePoint(a[1], b[1]);
|
|
66
|
+
return a[2] < b[2] ? -1 : a[2] > b[2] ? 1 : 0;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Compare strings by Unicode code point (Python `str` order).
|
|
70
|
+
*
|
|
71
|
+
* Iterates actual code points with independent offsets, so unpaired
|
|
72
|
+
* surrogates compare as their own values, exactly as Python's `str`
|
|
73
|
+
* ordering treats them: "\ud800" < "\ue000", and an astral character
|
|
74
|
+
* (any surrogate pair) sorts after every BMP code point.
|
|
75
|
+
*/
|
|
76
|
+
function compareStringsByCodePoint(a, b) {
|
|
77
|
+
let ai = 0;
|
|
78
|
+
let bi = 0;
|
|
79
|
+
while (ai < a.length && bi < b.length) {
|
|
80
|
+
const ac = a.codePointAt(ai);
|
|
81
|
+
const bc = b.codePointAt(bi);
|
|
82
|
+
if (ac !== bc) return ac < bc ? -1 : 1;
|
|
83
|
+
ai += ac > 65535 ? 2 : 1;
|
|
84
|
+
bi += bc > 65535 ? 2 : 1;
|
|
85
|
+
}
|
|
86
|
+
if (ai >= a.length && bi >= b.length) return 0;
|
|
87
|
+
return ai >= a.length ? -1 : 1;
|
|
88
|
+
}
|
|
33
89
|
var BaseCheckpointSaver = class {
|
|
34
90
|
serde = new require_jsonplus.JsonPlusSerializer();
|
|
35
91
|
constructor(serde) {
|
|
@@ -61,6 +117,15 @@ var BaseCheckpointSaver = class {
|
|
|
61
117
|
* Walks the parent chain (not `list({ before })`): for forked threads, only
|
|
62
118
|
* on-path ancestors contribute.
|
|
63
119
|
*
|
|
120
|
+
* Within a single checkpoint, writes are ordered by `writesSortKey` —
|
|
121
|
+
* `(task_path, task_id, idx)` — the order live execution applies a
|
|
122
|
+
* superstep's task writes in. This default walk cannot sort by path itself
|
|
123
|
+
* (`CheckpointPendingWrite` carries no path), so it relies on `getTuple`
|
|
124
|
+
* returning `pendingWrites` already in `writesSortKey` order, which the
|
|
125
|
+
* contract above requires of every saver. Writes stored without a
|
|
126
|
+
* `task_path` (graph input, `Command` updates, rows predating the
|
|
127
|
+
* column) sort first, by `task_id`.
|
|
128
|
+
*
|
|
64
129
|
* The default implementation walks `getTuple` + `parentConfig` once for all
|
|
65
130
|
* channels — each ancestor visited once, not once per channel. Savers with
|
|
66
131
|
* direct storage access (e.g. `MemorySaver`) override for performance; the
|
|
@@ -94,7 +159,6 @@ var BaseCheckpointSaver = class {
|
|
|
94
159
|
}
|
|
95
160
|
for (const ch of Object.keys(perChannel)) {
|
|
96
161
|
const block = perChannel[ch];
|
|
97
|
-
block.sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
|
|
98
162
|
for (let i = block.length - 1; i >= 0; i -= 1) collectedByCh[ch].push(block[i]);
|
|
99
163
|
}
|
|
100
164
|
}
|
|
@@ -174,10 +238,12 @@ exports.BaseCheckpointSaver = BaseCheckpointSaver;
|
|
|
174
238
|
exports.EXCLUDED_METADATA_KEYS = EXCLUDED_METADATA_KEYS;
|
|
175
239
|
exports.WRITES_IDX_MAP = WRITES_IDX_MAP;
|
|
176
240
|
exports.compareChannelVersions = compareChannelVersions;
|
|
241
|
+
exports.compareWritesSortKeys = compareWritesSortKeys;
|
|
177
242
|
exports.copyCheckpoint = copyCheckpoint;
|
|
178
243
|
exports.deepCopy = deepCopy;
|
|
179
244
|
exports.emptyCheckpoint = emptyCheckpoint;
|
|
180
245
|
exports.getCheckpointId = getCheckpointId;
|
|
181
246
|
exports.maxChannelVersion = maxChannelVersion;
|
|
247
|
+
exports.writesSortKey = writesSortKey;
|
|
182
248
|
|
|
183
249
|
//# sourceMappingURL=base.cjs.map
|
package/dist/base.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.cjs","names":["uuid6","JsonPlusSerializer","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 DeltaChannelHistory,\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(0),\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 /**\n * Prevent `JSON.stringify` from traversing backend clients (e.g. pg Pool\n * timers) when a checkpointer is present in runnable `configurable`.\n */\n toJSON(): string {\n return `[${this.constructor.name}]`;\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 * Walk the parent chain returning per-channel writes + seed, used to\n * reconstruct `DeltaChannel` state from `checkpoint_writes`.\n *\n * For each requested channel, walks ancestors of the checkpoint identified\n * by `config` (following `parentConfig`) and accumulates the pending writes\n * for that channel. The walk terminates per-channel at the nearest ancestor\n * whose `channel_values[ch]` is populated; that value is returned as `seed`.\n * If the walk reaches the root without finding a stored value, `seed` is\n * omitted from that channel's entry — the consumer treats the absence as\n * \"start empty\".\n *\n * Walks the parent chain (not `list({ before })`): for forked threads, only\n * on-path ancestors contribute.\n *\n * The default implementation walks `getTuple` + `parentConfig` once for all\n * channels — each ancestor visited once, not once per channel. Savers with\n * direct storage access (e.g. `MemorySaver`) override for performance; the\n * return contract is fixed here.\n *\n * @remarks Beta. The signature, return shape, and interaction with\n * `DeltaSnapshot` blobs may change. Override at your own risk; the default\n * implementation will continue to work against the public\n * `BaseCheckpointSaver` contract.\n *\n * @param options.config Configuration identifying the target checkpoint.\n * @param options.channels Channel names to walk for. Empty → empty mapping.\n * @returns Per-channel {@link DeltaChannelHistory} for every requested name.\n */\n async getDeltaChannelHistory(options: {\n config: RunnableConfig;\n channels: string[];\n }): Promise<Record<string, DeltaChannelHistory>> {\n const { config, channels } = options;\n if (channels.length === 0) return {};\n\n const collectedByCh: Record<string, CheckpointPendingWrite[]> = {};\n const seedByCh: Record<string, unknown> = {};\n const remaining = new Set(channels);\n for (const ch of channels) collectedByCh[ch] = [];\n\n const targetTuple = await this.getTuple(config);\n let cursorConfig: RunnableConfig | undefined = targetTuple?.parentConfig;\n\n while (cursorConfig != null && remaining.size > 0) {\n const tup: CheckpointTuple | undefined =\n await this.getTuple(cursorConfig);\n if (tup === undefined) break;\n if (tup.pendingWrites && tup.pendingWrites.length > 0) {\n // DeltaChannel reconstruction must replay concurrent same-superstep\n // writes in the canonical (task_id, idx) order that live execution uses\n // (see `_applyWrites`), or the reconstructed value can diverge from the\n // live one. Group per channel and stable-sort by task id: a stable sort\n // keeps each task's writes in their stored `idx` order, making the\n // result independent of how a saver returns `pendingWrites`.\n const perChannel: Record<string, CheckpointPendingWrite[]> = {};\n for (const write of tup.pendingWrites) {\n const ch = write[1];\n if (remaining.has(ch)) (perChannel[ch] ??= []).push(write);\n }\n for (const ch of Object.keys(perChannel)) {\n const block = perChannel[ch];\n block.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));\n // Pushed reversed so the final `.reverse()` below yields oldest→newest\n // checkpoints with each checkpoint's writes ascending by (task_id, idx).\n for (let i = block.length - 1; i >= 0; i -= 1) {\n collectedByCh[ch].push(block[i]);\n }\n }\n }\n for (const ch of Array.from(remaining)) {\n if (\n Object.prototype.hasOwnProperty.call(\n tup.checkpoint.channel_values,\n ch\n )\n ) {\n seedByCh[ch] = tup.checkpoint.channel_values[ch];\n remaining.delete(ch);\n }\n }\n cursorConfig = tup.parentConfig;\n }\n\n const result: Record<string, DeltaChannelHistory> = {};\n for (const ch of channels) {\n const entry: DeltaChannelHistory = {\n writes: collectedByCh[ch].slice().reverse(),\n };\n if (Object.prototype.hasOwnProperty.call(seedByCh, ch)) {\n entry.seed = seedByCh[ch];\n }\n result[ch] = entry;\n }\n return result;\n }\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\n/**\n * Metadata keys that are LangGraph's internal framework bookkeeping and\n * should not be surfaced as user-meaningful metadata.\n *\n * Consumed by stream handlers (e.g. the `tasks` debug stream) to drop\n * framework keys — which are redundant with a task's own fields and\n * namespace — while keeping keys like `lc_agent_name`, `ls_integration`,\n * and user-supplied metadata.\n */\nexport const EXCLUDED_METADATA_KEYS: ReadonlySet<string> = new Set([\n \"thread_id\",\n \"checkpoint_id\",\n \"checkpoint_ns\",\n \"checkpoint_map\",\n \"langgraph_step\",\n \"langgraph_node\",\n \"langgraph_triggers\",\n \"langgraph_path\",\n \"langgraph_checkpoint_ns\",\n]);\n\nexport function getCheckpointId(config: RunnableConfig): string {\n return (\n config.configurable?.checkpoint_id || config.configurable?.thread_ts || \"\"\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.cjs","names":["uuid6","JsonPlusSerializer","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 DeltaChannelHistory,\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(0),\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\n/** Sort key for the writes of one superstep: `(task_path, task_id, idx)`. */\nexport type WritesSortKey = readonly [string, string, number];\n\n/**\n * Sort key for the writes of one superstep.\n *\n * Live execution applies a superstep's tasks in this order (see `_applyWrites`\n * in `@langchain/langgraph-core`), so a saver that replays stored writes, as\n * `getDeltaChannelHistory` does, must sort them by it too, or an\n * order-sensitive (but batching-invariant) reducer rebuilds a different value\n * than the run produced. `taskPath` is the string passed to `putWrites`.\n *\n * Writes stored without a task path (graph input, `Command` updates, rows\n * predating the column) use `\"\"`, which sorts\n * first, before any real task path — which is also where live execution\n * applies input.\n */\nexport function writesSortKey(\n taskPath: string,\n taskId = \"\",\n idx = 0\n): WritesSortKey {\n return [taskPath, taskId, idx];\n}\n\n/**\n * Compare two {@link WritesSortKey}s: strings by code point (matching Python\n * `str` order, which differs from UTF-16 code-unit order for astral\n * characters), `idx` numerically.\n *\n * The one comparator for a superstep's writes — used by live execution and\n * every saver, so they cannot drift apart. Do not sort write keys with `<`,\n * `localeCompare`, or default `Array.prototype.sort` on the key tuple.\n */\nexport function compareWritesSortKeys(\n a: WritesSortKey,\n b: WritesSortKey\n): number {\n if (a[0] !== b[0]) return compareStringsByCodePoint(a[0], b[0]);\n if (a[1] !== b[1]) return compareStringsByCodePoint(a[1], b[1]);\n return a[2] < b[2] ? -1 : a[2] > b[2] ? 1 : 0;\n}\n\n/**\n * Compare strings by Unicode code point (Python `str` order).\n *\n * Iterates actual code points with independent offsets, so unpaired\n * surrogates compare as their own values, exactly as Python's `str`\n * ordering treats them: \"\\ud800\" < \"\\ue000\", and an astral character\n * (any surrogate pair) sorts after every BMP code point.\n */\nfunction compareStringsByCodePoint(a: string, b: string): number {\n let ai = 0;\n let bi = 0;\n while (ai < a.length && bi < b.length) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const ac = a.codePointAt(ai)!;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const bc = b.codePointAt(bi)!;\n if (ac !== bc) return ac < bc ? -1 : 1;\n ai += ac > 0xffff ? 2 : 1;\n bi += bc > 0xffff ? 2 : 1;\n }\n if (ai >= a.length && bi >= b.length) return 0;\n return ai >= a.length ? -1 : 1;\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 /**\n * Prevent `JSON.stringify` from traversing backend clients (e.g. pg Pool\n * timers) when a checkpointer is present in runnable `configurable`.\n */\n toJSON(): string {\n return `[${this.constructor.name}]`;\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 * `taskPath` is the serialized path of the task creating the writes (see\n * `writesSortKey`). Implementations should persist it when they can, and\n * must return `pendingWrites` from `getTuple`/`list` in `writesSortKey`\n * order — live execution applies a superstep's writes in that order, so\n * replaying in any other order can rebuild a different value for an\n * order-sensitive reducer. Writes stored without a path (rows predating it,\n * savers that don't persist one) sort first by `taskId`, which is also the\n * order live execution applies input in.\n */\n abstract putWrites(\n config: RunnableConfig,\n writes: PendingWrite[],\n taskId: string,\n taskPath?: 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 * Walk the parent chain returning per-channel writes + seed, used to\n * reconstruct `DeltaChannel` state from `checkpoint_writes`.\n *\n * For each requested channel, walks ancestors of the checkpoint identified\n * by `config` (following `parentConfig`) and accumulates the pending writes\n * for that channel. The walk terminates per-channel at the nearest ancestor\n * whose `channel_values[ch]` is populated; that value is returned as `seed`.\n * If the walk reaches the root without finding a stored value, `seed` is\n * omitted from that channel's entry — the consumer treats the absence as\n * \"start empty\".\n *\n * Walks the parent chain (not `list({ before })`): for forked threads, only\n * on-path ancestors contribute.\n *\n * Within a single checkpoint, writes are ordered by `writesSortKey` —\n * `(task_path, task_id, idx)` — the order live execution applies a\n * superstep's task writes in. This default walk cannot sort by path itself\n * (`CheckpointPendingWrite` carries no path), so it relies on `getTuple`\n * returning `pendingWrites` already in `writesSortKey` order, which the\n * contract above requires of every saver. Writes stored without a\n * `task_path` (graph input, `Command` updates, rows predating the\n * column) sort first, by `task_id`.\n *\n * The default implementation walks `getTuple` + `parentConfig` once for all\n * channels — each ancestor visited once, not once per channel. Savers with\n * direct storage access (e.g. `MemorySaver`) override for performance; the\n * return contract is fixed here.\n *\n * @remarks Beta. The signature, return shape, and interaction with\n * `DeltaSnapshot` blobs may change. Override at your own risk; the default\n * implementation will continue to work against the public\n * `BaseCheckpointSaver` contract.\n *\n * @param options.config Configuration identifying the target checkpoint.\n * @param options.channels Channel names to walk for. Empty → empty mapping.\n * @returns Per-channel {@link DeltaChannelHistory} for every requested name.\n */\n async getDeltaChannelHistory(options: {\n config: RunnableConfig;\n channels: string[];\n }): Promise<Record<string, DeltaChannelHistory>> {\n const { config, channels } = options;\n if (channels.length === 0) return {};\n\n const collectedByCh: Record<string, CheckpointPendingWrite[]> = {};\n const seedByCh: Record<string, unknown> = {};\n const remaining = new Set(channels);\n for (const ch of channels) collectedByCh[ch] = [];\n\n const targetTuple = await this.getTuple(config);\n let cursorConfig: RunnableConfig | undefined = targetTuple?.parentConfig;\n\n while (cursorConfig != null && remaining.size > 0) {\n const tup: CheckpointTuple | undefined =\n await this.getTuple(cursorConfig);\n if (tup === undefined) break;\n if (tup.pendingWrites && tup.pendingWrites.length > 0) {\n // `getTuple` returns `pendingWrites` in `writesSortKey` order (see its\n // contract), which is the order live execution applies a superstep's\n // writes in — so no re-sorting here; just group per channel. Each\n // block is pushed reversed so the final `.reverse()` below yields\n // oldest→newest checkpoints with each checkpoint's writes ascending.\n const perChannel: Record<string, CheckpointPendingWrite[]> = {};\n for (const write of tup.pendingWrites) {\n const ch = write[1];\n if (remaining.has(ch)) (perChannel[ch] ??= []).push(write);\n }\n for (const ch of Object.keys(perChannel)) {\n const block = perChannel[ch];\n for (let i = block.length - 1; i >= 0; i -= 1) {\n collectedByCh[ch].push(block[i]);\n }\n }\n }\n for (const ch of Array.from(remaining)) {\n if (\n Object.prototype.hasOwnProperty.call(\n tup.checkpoint.channel_values,\n ch\n )\n ) {\n seedByCh[ch] = tup.checkpoint.channel_values[ch];\n remaining.delete(ch);\n }\n }\n cursorConfig = tup.parentConfig;\n }\n\n const result: Record<string, DeltaChannelHistory> = {};\n for (const ch of channels) {\n const entry: DeltaChannelHistory = {\n writes: collectedByCh[ch].slice().reverse(),\n };\n if (Object.prototype.hasOwnProperty.call(seedByCh, ch)) {\n entry.seed = seedByCh[ch];\n }\n result[ch] = entry;\n }\n return result;\n }\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\n/**\n * Metadata keys that are LangGraph's internal framework bookkeeping and\n * should not be surfaced as user-meaningful metadata.\n *\n * Consumed by stream handlers (e.g. the `tasks` debug stream) to drop\n * framework keys — which are redundant with a task's own fields and\n * namespace — while keeping keys like `lc_agent_name`, `ls_integration`,\n * and user-supplied metadata.\n */\nexport const EXCLUDED_METADATA_KEYS: ReadonlySet<string> = new Set([\n \"thread_id\",\n \"checkpoint_id\",\n \"checkpoint_ns\",\n \"checkpoint_map\",\n \"langgraph_step\",\n \"langgraph_node\",\n \"langgraph_triggers\",\n \"langgraph_path\",\n \"langgraph_checkpoint_ns\",\n]);\n\nexport function getCheckpointId(config: RunnableConfig): string {\n return (\n config.configurable?.checkpoint_id || config.configurable?.thread_ts || \"\"\n );\n}\n"],"mappings":"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"}
|
package/dist/base.d.cts
CHANGED
|
@@ -54,6 +54,33 @@ type CheckpointListOptions = {
|
|
|
54
54
|
before?: RunnableConfig;
|
|
55
55
|
filter?: Record<string, any>;
|
|
56
56
|
};
|
|
57
|
+
/** Sort key for the writes of one superstep: `(task_path, task_id, idx)`. */
|
|
58
|
+
type WritesSortKey = readonly [string, string, number];
|
|
59
|
+
/**
|
|
60
|
+
* Sort key for the writes of one superstep.
|
|
61
|
+
*
|
|
62
|
+
* Live execution applies a superstep's tasks in this order (see `_applyWrites`
|
|
63
|
+
* in `@langchain/langgraph-core`), so a saver that replays stored writes, as
|
|
64
|
+
* `getDeltaChannelHistory` does, must sort them by it too, or an
|
|
65
|
+
* order-sensitive (but batching-invariant) reducer rebuilds a different value
|
|
66
|
+
* than the run produced. `taskPath` is the string passed to `putWrites`.
|
|
67
|
+
*
|
|
68
|
+
* Writes stored without a task path (graph input, `Command` updates, rows
|
|
69
|
+
* predating the column) use `""`, which sorts
|
|
70
|
+
* first, before any real task path — which is also where live execution
|
|
71
|
+
* applies input.
|
|
72
|
+
*/
|
|
73
|
+
declare function writesSortKey(taskPath: string, taskId?: string, idx?: number): WritesSortKey;
|
|
74
|
+
/**
|
|
75
|
+
* Compare two {@link WritesSortKey}s: strings by code point (matching Python
|
|
76
|
+
* `str` order, which differs from UTF-16 code-unit order for astral
|
|
77
|
+
* characters), `idx` numerically.
|
|
78
|
+
*
|
|
79
|
+
* The one comparator for a superstep's writes — used by live execution and
|
|
80
|
+
* every saver, so they cannot drift apart. Do not sort write keys with `<`,
|
|
81
|
+
* `localeCompare`, or default `Array.prototype.sort` on the key tuple.
|
|
82
|
+
*/
|
|
83
|
+
declare function compareWritesSortKeys(a: WritesSortKey, b: WritesSortKey): number;
|
|
57
84
|
declare abstract class BaseCheckpointSaver<V extends string | number = number> {
|
|
58
85
|
serde: SerializerProtocol;
|
|
59
86
|
constructor(serde?: SerializerProtocol);
|
|
@@ -68,8 +95,17 @@ declare abstract class BaseCheckpointSaver<V extends string | number = number> {
|
|
|
68
95
|
abstract put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, newVersions: ChannelVersions): Promise<RunnableConfig>;
|
|
69
96
|
/**
|
|
70
97
|
* Store intermediate writes linked to a checkpoint.
|
|
98
|
+
*
|
|
99
|
+
* `taskPath` is the serialized path of the task creating the writes (see
|
|
100
|
+
* `writesSortKey`). Implementations should persist it when they can, and
|
|
101
|
+
* must return `pendingWrites` from `getTuple`/`list` in `writesSortKey`
|
|
102
|
+
* order — live execution applies a superstep's writes in that order, so
|
|
103
|
+
* replaying in any other order can rebuild a different value for an
|
|
104
|
+
* order-sensitive reducer. Writes stored without a path (rows predating it,
|
|
105
|
+
* savers that don't persist one) sort first by `taskId`, which is also the
|
|
106
|
+
* order live execution applies input in.
|
|
71
107
|
*/
|
|
72
|
-
abstract putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;
|
|
108
|
+
abstract putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string, taskPath?: string): Promise<void>;
|
|
73
109
|
/**
|
|
74
110
|
* Delete all checkpoints and writes associated with a specific thread ID.
|
|
75
111
|
* @param threadId The thread ID whose checkpoints should be deleted.
|
|
@@ -90,6 +126,15 @@ declare abstract class BaseCheckpointSaver<V extends string | number = number> {
|
|
|
90
126
|
* Walks the parent chain (not `list({ before })`): for forked threads, only
|
|
91
127
|
* on-path ancestors contribute.
|
|
92
128
|
*
|
|
129
|
+
* Within a single checkpoint, writes are ordered by `writesSortKey` —
|
|
130
|
+
* `(task_path, task_id, idx)` — the order live execution applies a
|
|
131
|
+
* superstep's task writes in. This default walk cannot sort by path itself
|
|
132
|
+
* (`CheckpointPendingWrite` carries no path), so it relies on `getTuple`
|
|
133
|
+
* returning `pendingWrites` already in `writesSortKey` order, which the
|
|
134
|
+
* contract above requires of every saver. Writes stored without a
|
|
135
|
+
* `task_path` (graph input, `Command` updates, rows predating the
|
|
136
|
+
* column) sort first, by `task_id`.
|
|
137
|
+
*
|
|
93
138
|
* The default implementation walks `getTuple` + `parentConfig` once for all
|
|
94
139
|
* channels — each ancestor visited once, not once per channel. Savers with
|
|
95
140
|
* direct storage access (e.g. `MemorySaver`) override for performance; the
|
|
@@ -138,5 +183,5 @@ declare const WRITES_IDX_MAP: Record<string, number>;
|
|
|
138
183
|
declare const EXCLUDED_METADATA_KEYS: ReadonlySet<string>;
|
|
139
184
|
declare function getCheckpointId(config: RunnableConfig): string;
|
|
140
185
|
//#endregion
|
|
141
|
-
export { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointTuple, EXCLUDED_METADATA_KEYS, ReadonlyCheckpoint, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion };
|
|
186
|
+
export { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointTuple, EXCLUDED_METADATA_KEYS, ReadonlyCheckpoint, WRITES_IDX_MAP, WritesSortKey, compareChannelVersions, compareWritesSortKeys, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion, writesSortKey };
|
|
142
187
|
//# sourceMappingURL=base.d.cts.map
|
package/dist/base.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.cts","names":[],"sources":["../src/base.ts"],"mappings":";;;;;;KAaK,cAAA;AAAA,KAEO,eAAA,GAAkB,MAAA,SAAe,cAAA;AAAA,UAE5B,UAAA;;;;EAOf,CAAA;EATyB;;;EAazB,EAAA;EAXe;;;EAef,EAAA;EAIgB;;;EAAhB,cAAA,EAAgB,MAAA,CAAO,CAAA;EAQD;;;EAJtB,gBAAA,EAAkB,MAAA,CAAO,CAAA,EAAG,cAAA;EAIb;;;EAAf,aAAA,EAAe,MAAA,CAAO,CAAA,EAAG,MAAA,CAAO,CAAA,EAAG,cAAA;AAAA;AAAA,UAGpB,kBAAA,SAA2B,QAAA,CAAS,UAAA;EAAA,SAC1C,cAAA,EAAgB,QAAA,CAAS,MAAA;EAAA,SACzB,gBAAA,EAAkB,QAAA,CAAS,MAAA,SAAe,cAAA;EAAA,SAC1C,aAAA,EAAe,QAAA,CACtB,MAAA,SAAe,QAAA,CAAS,MAAA,SAAe,cAAA;AAAA;AAAA,iBAI3B,QAAA,GAAA,CAAY,GAAA,EAAK,CAAA,GAAI,CAAA;;iBAmBrB,eAAA,CAAA,GAAmB,UAAA;;iBAYnB,cAAA,CAAe,UAAA,EAAY,kBAAA,GAAqB,UAAA;AAAA,UAW/C,eAAA;EACf,MAAA,EAAQ,cAAA;EACR,UAAA,EAAY,UAAA;EACZ,QAAA,GAAW,kBAAA;EACX,YAAA,GAAe,cAAA;EACf,aAAA,GAAgB,sBAAA;AAAA;AAAA,KAGN,qBAAA;EACV,KAAA;EACA,MAAA,GAAS,cAAA;EAET,MAAA,GAAS,MAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"base.d.cts","names":[],"sources":["../src/base.ts"],"mappings":";;;;;;KAaK,cAAA;AAAA,KAEO,eAAA,GAAkB,MAAA,SAAe,cAAA;AAAA,UAE5B,UAAA;;;;EAOf,CAAA;EATyB;;;EAazB,EAAA;EAXe;;;EAef,EAAA;EAIgB;;;EAAhB,cAAA,EAAgB,MAAA,CAAO,CAAA;EAQD;;;EAJtB,gBAAA,EAAkB,MAAA,CAAO,CAAA,EAAG,cAAA;EAIb;;;EAAf,aAAA,EAAe,MAAA,CAAO,CAAA,EAAG,MAAA,CAAO,CAAA,EAAG,cAAA;AAAA;AAAA,UAGpB,kBAAA,SAA2B,QAAA,CAAS,UAAA;EAAA,SAC1C,cAAA,EAAgB,QAAA,CAAS,MAAA;EAAA,SACzB,gBAAA,EAAkB,QAAA,CAAS,MAAA,SAAe,cAAA;EAAA,SAC1C,aAAA,EAAe,QAAA,CACtB,MAAA,SAAe,QAAA,CAAS,MAAA,SAAe,cAAA;AAAA;AAAA,iBAI3B,QAAA,GAAA,CAAY,GAAA,EAAK,CAAA,GAAI,CAAA;;iBAmBrB,eAAA,CAAA,GAAmB,UAAA;;iBAYnB,cAAA,CAAe,UAAA,EAAY,kBAAA,GAAqB,UAAA;AAAA,UAW/C,eAAA;EACf,MAAA,EAAQ,cAAA;EACR,UAAA,EAAY,UAAA;EACZ,QAAA,GAAW,kBAAA;EACX,YAAA,GAAe,cAAA;EACf,aAAA,GAAgB,sBAAA;AAAA;AAAA,KAGN,qBAAA;EACV,KAAA;EACA,MAAA,GAAS,cAAA;EAET,MAAA,GAAS,MAAA;AAAA;;KAIC,aAAA;;;;;;;;;;;;;;;iBAgBI,aAAA,CACd,QAAA,UACA,MAAA,WACA,GAAA,YACC,aAAA;;;;;;;;;;iBAaa,qBAAA,CACd,CAAA,EAAG,aAAA,EACH,CAAA,EAAG,aAAA;AAAA,uBA+BiB,mBAAA;EACpB,KAAA,EAAO,kBAAA;EAEP,WAAA,CAAY,KAAA,GAAQ,kBAAA;EA/HN;;;;EAuId,MAAA,CAAA;EAIM,GAAA,CAAI,MAAA,EAAQ,cAAA,GAAiB,OAAA,CAAQ,UAAA;EAAA,SAKlC,QAAA,CACP,MAAA,EAAQ,cAAA,GACP,OAAA,CAAQ,eAAA;EAAA,SAEF,IAAA,CACP,MAAA,EAAQ,cAAA,EACR,OAAA,GAAU,qBAAA,GACT,cAAA,CAAe,eAAA;EAAA,SAET,GAAA,CACP,MAAA,EAAQ,cAAA,EACR,UAAA,EAAY,UAAA,EACZ,QAAA,EAAU,kBAAA,EACV,WAAA,EAAa,eAAA,GACZ,OAAA,CAAQ,cAAA;EA9JyB;AAmBtC;;;;;AAYA;;;;;;EA/BsC,SA4K3B,SAAA,CACP,MAAA,EAAQ,cAAA,EACR,MAAA,EAAQ,YAAA,IACR,MAAA,UACA,QAAA,YACC,OAAA;EAlJqE;;AAW1E;;EAX0E,SAwJ/D,YAAA,CAAa,QAAA,WAAmB,OAAA;EA5IjC;;;;;;;;;;;;;;;;;;;AAOV;;;;;;;;;;;AAQA;;;;;AAgBA;;;EAqJQ,sBAAA,CAAuB,OAAA;IAC3B,MAAA,EAAQ,cAAA;IACR,QAAA;EAAA,IACE,OAAA,CAAQ,MAAA,SAAe,mBAAA;EApJ1B;;;AAaH;;;EA0ME,cAAA,CAAe,OAAA,EAAS,CAAA,eAAgB,CAAA;AAAA;AAAA,iBAU1B,sBAAA,CACd,CAAA,EAAG,cAAA,EACH,CAAA,EAAG,cAAA;AAAA,iBASW,iBAAA,CAAA,GACX,QAAA,EAAU,cAAA,KACZ,cAAA;;;;AAhMH;;;;cA8Ma,cAAA,EAAgB,MAAA;;;;;;;;;;cAgBhB,sBAAA,EAAwB,WAAA;AAAA,iBAYrB,eAAA,CAAgB,MAAA,EAAQ,cAAA"}
|
package/dist/base.d.ts
CHANGED
|
@@ -54,6 +54,33 @@ type CheckpointListOptions = {
|
|
|
54
54
|
before?: RunnableConfig;
|
|
55
55
|
filter?: Record<string, any>;
|
|
56
56
|
};
|
|
57
|
+
/** Sort key for the writes of one superstep: `(task_path, task_id, idx)`. */
|
|
58
|
+
type WritesSortKey = readonly [string, string, number];
|
|
59
|
+
/**
|
|
60
|
+
* Sort key for the writes of one superstep.
|
|
61
|
+
*
|
|
62
|
+
* Live execution applies a superstep's tasks in this order (see `_applyWrites`
|
|
63
|
+
* in `@langchain/langgraph-core`), so a saver that replays stored writes, as
|
|
64
|
+
* `getDeltaChannelHistory` does, must sort them by it too, or an
|
|
65
|
+
* order-sensitive (but batching-invariant) reducer rebuilds a different value
|
|
66
|
+
* than the run produced. `taskPath` is the string passed to `putWrites`.
|
|
67
|
+
*
|
|
68
|
+
* Writes stored without a task path (graph input, `Command` updates, rows
|
|
69
|
+
* predating the column) use `""`, which sorts
|
|
70
|
+
* first, before any real task path — which is also where live execution
|
|
71
|
+
* applies input.
|
|
72
|
+
*/
|
|
73
|
+
declare function writesSortKey(taskPath: string, taskId?: string, idx?: number): WritesSortKey;
|
|
74
|
+
/**
|
|
75
|
+
* Compare two {@link WritesSortKey}s: strings by code point (matching Python
|
|
76
|
+
* `str` order, which differs from UTF-16 code-unit order for astral
|
|
77
|
+
* characters), `idx` numerically.
|
|
78
|
+
*
|
|
79
|
+
* The one comparator for a superstep's writes — used by live execution and
|
|
80
|
+
* every saver, so they cannot drift apart. Do not sort write keys with `<`,
|
|
81
|
+
* `localeCompare`, or default `Array.prototype.sort` on the key tuple.
|
|
82
|
+
*/
|
|
83
|
+
declare function compareWritesSortKeys(a: WritesSortKey, b: WritesSortKey): number;
|
|
57
84
|
declare abstract class BaseCheckpointSaver<V extends string | number = number> {
|
|
58
85
|
serde: SerializerProtocol;
|
|
59
86
|
constructor(serde?: SerializerProtocol);
|
|
@@ -68,8 +95,17 @@ declare abstract class BaseCheckpointSaver<V extends string | number = number> {
|
|
|
68
95
|
abstract put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, newVersions: ChannelVersions): Promise<RunnableConfig>;
|
|
69
96
|
/**
|
|
70
97
|
* Store intermediate writes linked to a checkpoint.
|
|
98
|
+
*
|
|
99
|
+
* `taskPath` is the serialized path of the task creating the writes (see
|
|
100
|
+
* `writesSortKey`). Implementations should persist it when they can, and
|
|
101
|
+
* must return `pendingWrites` from `getTuple`/`list` in `writesSortKey`
|
|
102
|
+
* order — live execution applies a superstep's writes in that order, so
|
|
103
|
+
* replaying in any other order can rebuild a different value for an
|
|
104
|
+
* order-sensitive reducer. Writes stored without a path (rows predating it,
|
|
105
|
+
* savers that don't persist one) sort first by `taskId`, which is also the
|
|
106
|
+
* order live execution applies input in.
|
|
71
107
|
*/
|
|
72
|
-
abstract putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;
|
|
108
|
+
abstract putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string, taskPath?: string): Promise<void>;
|
|
73
109
|
/**
|
|
74
110
|
* Delete all checkpoints and writes associated with a specific thread ID.
|
|
75
111
|
* @param threadId The thread ID whose checkpoints should be deleted.
|
|
@@ -90,6 +126,15 @@ declare abstract class BaseCheckpointSaver<V extends string | number = number> {
|
|
|
90
126
|
* Walks the parent chain (not `list({ before })`): for forked threads, only
|
|
91
127
|
* on-path ancestors contribute.
|
|
92
128
|
*
|
|
129
|
+
* Within a single checkpoint, writes are ordered by `writesSortKey` —
|
|
130
|
+
* `(task_path, task_id, idx)` — the order live execution applies a
|
|
131
|
+
* superstep's task writes in. This default walk cannot sort by path itself
|
|
132
|
+
* (`CheckpointPendingWrite` carries no path), so it relies on `getTuple`
|
|
133
|
+
* returning `pendingWrites` already in `writesSortKey` order, which the
|
|
134
|
+
* contract above requires of every saver. Writes stored without a
|
|
135
|
+
* `task_path` (graph input, `Command` updates, rows predating the
|
|
136
|
+
* column) sort first, by `task_id`.
|
|
137
|
+
*
|
|
93
138
|
* The default implementation walks `getTuple` + `parentConfig` once for all
|
|
94
139
|
* channels — each ancestor visited once, not once per channel. Savers with
|
|
95
140
|
* direct storage access (e.g. `MemorySaver`) override for performance; the
|
|
@@ -138,5 +183,5 @@ declare const WRITES_IDX_MAP: Record<string, number>;
|
|
|
138
183
|
declare const EXCLUDED_METADATA_KEYS: ReadonlySet<string>;
|
|
139
184
|
declare function getCheckpointId(config: RunnableConfig): string;
|
|
140
185
|
//#endregion
|
|
141
|
-
export { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointTuple, EXCLUDED_METADATA_KEYS, ReadonlyCheckpoint, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion };
|
|
186
|
+
export { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointTuple, EXCLUDED_METADATA_KEYS, ReadonlyCheckpoint, WRITES_IDX_MAP, WritesSortKey, compareChannelVersions, compareWritesSortKeys, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion, writesSortKey };
|
|
142
187
|
//# sourceMappingURL=base.d.ts.map
|
package/dist/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","names":[],"sources":["../src/base.ts"],"mappings":";;;;;;KAaK,cAAA;AAAA,KAEO,eAAA,GAAkB,MAAA,SAAe,cAAA;AAAA,UAE5B,UAAA;;;;EAOf,CAAA;EATyB;;;EAazB,EAAA;EAXe;;;EAef,EAAA;EAIgB;;;EAAhB,cAAA,EAAgB,MAAA,CAAO,CAAA;EAQD;;;EAJtB,gBAAA,EAAkB,MAAA,CAAO,CAAA,EAAG,cAAA;EAIb;;;EAAf,aAAA,EAAe,MAAA,CAAO,CAAA,EAAG,MAAA,CAAO,CAAA,EAAG,cAAA;AAAA;AAAA,UAGpB,kBAAA,SAA2B,QAAA,CAAS,UAAA;EAAA,SAC1C,cAAA,EAAgB,QAAA,CAAS,MAAA;EAAA,SACzB,gBAAA,EAAkB,QAAA,CAAS,MAAA,SAAe,cAAA;EAAA,SAC1C,aAAA,EAAe,QAAA,CACtB,MAAA,SAAe,QAAA,CAAS,MAAA,SAAe,cAAA;AAAA;AAAA,iBAI3B,QAAA,GAAA,CAAY,GAAA,EAAK,CAAA,GAAI,CAAA;;iBAmBrB,eAAA,CAAA,GAAmB,UAAA;;iBAYnB,cAAA,CAAe,UAAA,EAAY,kBAAA,GAAqB,UAAA;AAAA,UAW/C,eAAA;EACf,MAAA,EAAQ,cAAA;EACR,UAAA,EAAY,UAAA;EACZ,QAAA,GAAW,kBAAA;EACX,YAAA,GAAe,cAAA;EACf,aAAA,GAAgB,sBAAA;AAAA;AAAA,KAGN,qBAAA;EACV,KAAA;EACA,MAAA,GAAS,cAAA;EAET,MAAA,GAAS,MAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"base.d.ts","names":[],"sources":["../src/base.ts"],"mappings":";;;;;;KAaK,cAAA;AAAA,KAEO,eAAA,GAAkB,MAAA,SAAe,cAAA;AAAA,UAE5B,UAAA;;;;EAOf,CAAA;EATyB;;;EAazB,EAAA;EAXe;;;EAef,EAAA;EAIgB;;;EAAhB,cAAA,EAAgB,MAAA,CAAO,CAAA;EAQD;;;EAJtB,gBAAA,EAAkB,MAAA,CAAO,CAAA,EAAG,cAAA;EAIb;;;EAAf,aAAA,EAAe,MAAA,CAAO,CAAA,EAAG,MAAA,CAAO,CAAA,EAAG,cAAA;AAAA;AAAA,UAGpB,kBAAA,SAA2B,QAAA,CAAS,UAAA;EAAA,SAC1C,cAAA,EAAgB,QAAA,CAAS,MAAA;EAAA,SACzB,gBAAA,EAAkB,QAAA,CAAS,MAAA,SAAe,cAAA;EAAA,SAC1C,aAAA,EAAe,QAAA,CACtB,MAAA,SAAe,QAAA,CAAS,MAAA,SAAe,cAAA;AAAA;AAAA,iBAI3B,QAAA,GAAA,CAAY,GAAA,EAAK,CAAA,GAAI,CAAA;;iBAmBrB,eAAA,CAAA,GAAmB,UAAA;;iBAYnB,cAAA,CAAe,UAAA,EAAY,kBAAA,GAAqB,UAAA;AAAA,UAW/C,eAAA;EACf,MAAA,EAAQ,cAAA;EACR,UAAA,EAAY,UAAA;EACZ,QAAA,GAAW,kBAAA;EACX,YAAA,GAAe,cAAA;EACf,aAAA,GAAgB,sBAAA;AAAA;AAAA,KAGN,qBAAA;EACV,KAAA;EACA,MAAA,GAAS,cAAA;EAET,MAAA,GAAS,MAAA;AAAA;;KAIC,aAAA;;;;;;;;;;;;;;;iBAgBI,aAAA,CACd,QAAA,UACA,MAAA,WACA,GAAA,YACC,aAAA;;;;;;;;;;iBAaa,qBAAA,CACd,CAAA,EAAG,aAAA,EACH,CAAA,EAAG,aAAA;AAAA,uBA+BiB,mBAAA;EACpB,KAAA,EAAO,kBAAA;EAEP,WAAA,CAAY,KAAA,GAAQ,kBAAA;EA/HN;;;;EAuId,MAAA,CAAA;EAIM,GAAA,CAAI,MAAA,EAAQ,cAAA,GAAiB,OAAA,CAAQ,UAAA;EAAA,SAKlC,QAAA,CACP,MAAA,EAAQ,cAAA,GACP,OAAA,CAAQ,eAAA;EAAA,SAEF,IAAA,CACP,MAAA,EAAQ,cAAA,EACR,OAAA,GAAU,qBAAA,GACT,cAAA,CAAe,eAAA;EAAA,SAET,GAAA,CACP,MAAA,EAAQ,cAAA,EACR,UAAA,EAAY,UAAA,EACZ,QAAA,EAAU,kBAAA,EACV,WAAA,EAAa,eAAA,GACZ,OAAA,CAAQ,cAAA;EA9JyB;AAmBtC;;;;;AAYA;;;;;;EA/BsC,SA4K3B,SAAA,CACP,MAAA,EAAQ,cAAA,EACR,MAAA,EAAQ,YAAA,IACR,MAAA,UACA,QAAA,YACC,OAAA;EAlJqE;;AAW1E;;EAX0E,SAwJ/D,YAAA,CAAa,QAAA,WAAmB,OAAA;EA5IjC;;;;;;;;;;;;;;;;;;;AAOV;;;;;;;;;;;AAQA;;;;;AAgBA;;;EAqJQ,sBAAA,CAAuB,OAAA;IAC3B,MAAA,EAAQ,cAAA;IACR,QAAA;EAAA,IACE,OAAA,CAAQ,MAAA,SAAe,mBAAA;EApJ1B;;;AAaH;;;EA0ME,cAAA,CAAe,OAAA,EAAS,CAAA,eAAgB,CAAA;AAAA;AAAA,iBAU1B,sBAAA,CACd,CAAA,EAAG,cAAA,EACH,CAAA,EAAG,cAAA;AAAA,iBASW,iBAAA,CAAA,GACX,QAAA,EAAU,cAAA,KACZ,cAAA;;;;AAhMH;;;;cA8Ma,cAAA,EAAgB,MAAA;;;;;;;;;;cAgBhB,sBAAA,EAAwB,WAAA;AAAA,iBAYrB,eAAA,CAAgB,MAAA,EAAQ,cAAA"}
|
package/dist/base.js
CHANGED
|
@@ -30,6 +30,62 @@ function copyCheckpoint(checkpoint) {
|
|
|
30
30
|
versions_seen: deepCopy(checkpoint.versions_seen ?? {})
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Sort key for the writes of one superstep.
|
|
35
|
+
*
|
|
36
|
+
* Live execution applies a superstep's tasks in this order (see `_applyWrites`
|
|
37
|
+
* in `@langchain/langgraph-core`), so a saver that replays stored writes, as
|
|
38
|
+
* `getDeltaChannelHistory` does, must sort them by it too, or an
|
|
39
|
+
* order-sensitive (but batching-invariant) reducer rebuilds a different value
|
|
40
|
+
* than the run produced. `taskPath` is the string passed to `putWrites`.
|
|
41
|
+
*
|
|
42
|
+
* Writes stored without a task path (graph input, `Command` updates, rows
|
|
43
|
+
* predating the column) use `""`, which sorts
|
|
44
|
+
* first, before any real task path — which is also where live execution
|
|
45
|
+
* applies input.
|
|
46
|
+
*/
|
|
47
|
+
function writesSortKey(taskPath, taskId = "", idx = 0) {
|
|
48
|
+
return [
|
|
49
|
+
taskPath,
|
|
50
|
+
taskId,
|
|
51
|
+
idx
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Compare two {@link WritesSortKey}s: strings by code point (matching Python
|
|
56
|
+
* `str` order, which differs from UTF-16 code-unit order for astral
|
|
57
|
+
* characters), `idx` numerically.
|
|
58
|
+
*
|
|
59
|
+
* The one comparator for a superstep's writes — used by live execution and
|
|
60
|
+
* every saver, so they cannot drift apart. Do not sort write keys with `<`,
|
|
61
|
+
* `localeCompare`, or default `Array.prototype.sort` on the key tuple.
|
|
62
|
+
*/
|
|
63
|
+
function compareWritesSortKeys(a, b) {
|
|
64
|
+
if (a[0] !== b[0]) return compareStringsByCodePoint(a[0], b[0]);
|
|
65
|
+
if (a[1] !== b[1]) return compareStringsByCodePoint(a[1], b[1]);
|
|
66
|
+
return a[2] < b[2] ? -1 : a[2] > b[2] ? 1 : 0;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Compare strings by Unicode code point (Python `str` order).
|
|
70
|
+
*
|
|
71
|
+
* Iterates actual code points with independent offsets, so unpaired
|
|
72
|
+
* surrogates compare as their own values, exactly as Python's `str`
|
|
73
|
+
* ordering treats them: "\ud800" < "\ue000", and an astral character
|
|
74
|
+
* (any surrogate pair) sorts after every BMP code point.
|
|
75
|
+
*/
|
|
76
|
+
function compareStringsByCodePoint(a, b) {
|
|
77
|
+
let ai = 0;
|
|
78
|
+
let bi = 0;
|
|
79
|
+
while (ai < a.length && bi < b.length) {
|
|
80
|
+
const ac = a.codePointAt(ai);
|
|
81
|
+
const bc = b.codePointAt(bi);
|
|
82
|
+
if (ac !== bc) return ac < bc ? -1 : 1;
|
|
83
|
+
ai += ac > 65535 ? 2 : 1;
|
|
84
|
+
bi += bc > 65535 ? 2 : 1;
|
|
85
|
+
}
|
|
86
|
+
if (ai >= a.length && bi >= b.length) return 0;
|
|
87
|
+
return ai >= a.length ? -1 : 1;
|
|
88
|
+
}
|
|
33
89
|
var BaseCheckpointSaver = class {
|
|
34
90
|
serde = new JsonPlusSerializer();
|
|
35
91
|
constructor(serde) {
|
|
@@ -61,6 +117,15 @@ var BaseCheckpointSaver = class {
|
|
|
61
117
|
* Walks the parent chain (not `list({ before })`): for forked threads, only
|
|
62
118
|
* on-path ancestors contribute.
|
|
63
119
|
*
|
|
120
|
+
* Within a single checkpoint, writes are ordered by `writesSortKey` —
|
|
121
|
+
* `(task_path, task_id, idx)` — the order live execution applies a
|
|
122
|
+
* superstep's task writes in. This default walk cannot sort by path itself
|
|
123
|
+
* (`CheckpointPendingWrite` carries no path), so it relies on `getTuple`
|
|
124
|
+
* returning `pendingWrites` already in `writesSortKey` order, which the
|
|
125
|
+
* contract above requires of every saver. Writes stored without a
|
|
126
|
+
* `task_path` (graph input, `Command` updates, rows predating the
|
|
127
|
+
* column) sort first, by `task_id`.
|
|
128
|
+
*
|
|
64
129
|
* The default implementation walks `getTuple` + `parentConfig` once for all
|
|
65
130
|
* channels — each ancestor visited once, not once per channel. Savers with
|
|
66
131
|
* direct storage access (e.g. `MemorySaver`) override for performance; the
|
|
@@ -94,7 +159,6 @@ var BaseCheckpointSaver = class {
|
|
|
94
159
|
}
|
|
95
160
|
for (const ch of Object.keys(perChannel)) {
|
|
96
161
|
const block = perChannel[ch];
|
|
97
|
-
block.sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
|
|
98
162
|
for (let i = block.length - 1; i >= 0; i -= 1) collectedByCh[ch].push(block[i]);
|
|
99
163
|
}
|
|
100
164
|
}
|
|
@@ -170,6 +234,6 @@ function getCheckpointId(config) {
|
|
|
170
234
|
return config.configurable?.checkpoint_id || config.configurable?.thread_ts || "";
|
|
171
235
|
}
|
|
172
236
|
//#endregion
|
|
173
|
-
export { BaseCheckpointSaver, EXCLUDED_METADATA_KEYS, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion };
|
|
237
|
+
export { BaseCheckpointSaver, EXCLUDED_METADATA_KEYS, WRITES_IDX_MAP, compareChannelVersions, compareWritesSortKeys, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion, writesSortKey };
|
|
174
238
|
|
|
175
239
|
//# sourceMappingURL=base.js.map
|
package/dist/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","names":[],"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 DeltaChannelHistory,\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(0),\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 /**\n * Prevent `JSON.stringify` from traversing backend clients (e.g. pg Pool\n * timers) when a checkpointer is present in runnable `configurable`.\n */\n toJSON(): string {\n return `[${this.constructor.name}]`;\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 * Walk the parent chain returning per-channel writes + seed, used to\n * reconstruct `DeltaChannel` state from `checkpoint_writes`.\n *\n * For each requested channel, walks ancestors of the checkpoint identified\n * by `config` (following `parentConfig`) and accumulates the pending writes\n * for that channel. The walk terminates per-channel at the nearest ancestor\n * whose `channel_values[ch]` is populated; that value is returned as `seed`.\n * If the walk reaches the root without finding a stored value, `seed` is\n * omitted from that channel's entry — the consumer treats the absence as\n * \"start empty\".\n *\n * Walks the parent chain (not `list({ before })`): for forked threads, only\n * on-path ancestors contribute.\n *\n * The default implementation walks `getTuple` + `parentConfig` once for all\n * channels — each ancestor visited once, not once per channel. Savers with\n * direct storage access (e.g. `MemorySaver`) override for performance; the\n * return contract is fixed here.\n *\n * @remarks Beta. The signature, return shape, and interaction with\n * `DeltaSnapshot` blobs may change. Override at your own risk; the default\n * implementation will continue to work against the public\n * `BaseCheckpointSaver` contract.\n *\n * @param options.config Configuration identifying the target checkpoint.\n * @param options.channels Channel names to walk for. Empty → empty mapping.\n * @returns Per-channel {@link DeltaChannelHistory} for every requested name.\n */\n async getDeltaChannelHistory(options: {\n config: RunnableConfig;\n channels: string[];\n }): Promise<Record<string, DeltaChannelHistory>> {\n const { config, channels } = options;\n if (channels.length === 0) return {};\n\n const collectedByCh: Record<string, CheckpointPendingWrite[]> = {};\n const seedByCh: Record<string, unknown> = {};\n const remaining = new Set(channels);\n for (const ch of channels) collectedByCh[ch] = [];\n\n const targetTuple = await this.getTuple(config);\n let cursorConfig: RunnableConfig | undefined = targetTuple?.parentConfig;\n\n while (cursorConfig != null && remaining.size > 0) {\n const tup: CheckpointTuple | undefined =\n await this.getTuple(cursorConfig);\n if (tup === undefined) break;\n if (tup.pendingWrites && tup.pendingWrites.length > 0) {\n // DeltaChannel reconstruction must replay concurrent same-superstep\n // writes in the canonical (task_id, idx) order that live execution uses\n // (see `_applyWrites`), or the reconstructed value can diverge from the\n // live one. Group per channel and stable-sort by task id: a stable sort\n // keeps each task's writes in their stored `idx` order, making the\n // result independent of how a saver returns `pendingWrites`.\n const perChannel: Record<string, CheckpointPendingWrite[]> = {};\n for (const write of tup.pendingWrites) {\n const ch = write[1];\n if (remaining.has(ch)) (perChannel[ch] ??= []).push(write);\n }\n for (const ch of Object.keys(perChannel)) {\n const block = perChannel[ch];\n block.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));\n // Pushed reversed so the final `.reverse()` below yields oldest→newest\n // checkpoints with each checkpoint's writes ascending by (task_id, idx).\n for (let i = block.length - 1; i >= 0; i -= 1) {\n collectedByCh[ch].push(block[i]);\n }\n }\n }\n for (const ch of Array.from(remaining)) {\n if (\n Object.prototype.hasOwnProperty.call(\n tup.checkpoint.channel_values,\n ch\n )\n ) {\n seedByCh[ch] = tup.checkpoint.channel_values[ch];\n remaining.delete(ch);\n }\n }\n cursorConfig = tup.parentConfig;\n }\n\n const result: Record<string, DeltaChannelHistory> = {};\n for (const ch of channels) {\n const entry: DeltaChannelHistory = {\n writes: collectedByCh[ch].slice().reverse(),\n };\n if (Object.prototype.hasOwnProperty.call(seedByCh, ch)) {\n entry.seed = seedByCh[ch];\n }\n result[ch] = entry;\n }\n return result;\n }\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\n/**\n * Metadata keys that are LangGraph's internal framework bookkeeping and\n * should not be surfaced as user-meaningful metadata.\n *\n * Consumed by stream handlers (e.g. the `tasks` debug stream) to drop\n * framework keys — which are redundant with a task's own fields and\n * namespace — while keeping keys like `lc_agent_name`, `ls_integration`,\n * and user-supplied metadata.\n */\nexport const EXCLUDED_METADATA_KEYS: ReadonlySet<string> = new Set([\n \"thread_id\",\n \"checkpoint_id\",\n \"checkpoint_ns\",\n \"checkpoint_map\",\n \"langgraph_step\",\n \"langgraph_node\",\n \"langgraph_triggers\",\n \"langgraph_path\",\n \"langgraph_checkpoint_ns\",\n]);\n\nexport function getCheckpointId(config: RunnableConfig): string {\n return (\n config.configurable?.checkpoint_id || config.configurable?.thread_ts || \"\"\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.js","names":[],"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 DeltaChannelHistory,\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(0),\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\n/** Sort key for the writes of one superstep: `(task_path, task_id, idx)`. */\nexport type WritesSortKey = readonly [string, string, number];\n\n/**\n * Sort key for the writes of one superstep.\n *\n * Live execution applies a superstep's tasks in this order (see `_applyWrites`\n * in `@langchain/langgraph-core`), so a saver that replays stored writes, as\n * `getDeltaChannelHistory` does, must sort them by it too, or an\n * order-sensitive (but batching-invariant) reducer rebuilds a different value\n * than the run produced. `taskPath` is the string passed to `putWrites`.\n *\n * Writes stored without a task path (graph input, `Command` updates, rows\n * predating the column) use `\"\"`, which sorts\n * first, before any real task path — which is also where live execution\n * applies input.\n */\nexport function writesSortKey(\n taskPath: string,\n taskId = \"\",\n idx = 0\n): WritesSortKey {\n return [taskPath, taskId, idx];\n}\n\n/**\n * Compare two {@link WritesSortKey}s: strings by code point (matching Python\n * `str` order, which differs from UTF-16 code-unit order for astral\n * characters), `idx` numerically.\n *\n * The one comparator for a superstep's writes — used by live execution and\n * every saver, so they cannot drift apart. Do not sort write keys with `<`,\n * `localeCompare`, or default `Array.prototype.sort` on the key tuple.\n */\nexport function compareWritesSortKeys(\n a: WritesSortKey,\n b: WritesSortKey\n): number {\n if (a[0] !== b[0]) return compareStringsByCodePoint(a[0], b[0]);\n if (a[1] !== b[1]) return compareStringsByCodePoint(a[1], b[1]);\n return a[2] < b[2] ? -1 : a[2] > b[2] ? 1 : 0;\n}\n\n/**\n * Compare strings by Unicode code point (Python `str` order).\n *\n * Iterates actual code points with independent offsets, so unpaired\n * surrogates compare as their own values, exactly as Python's `str`\n * ordering treats them: \"\\ud800\" < \"\\ue000\", and an astral character\n * (any surrogate pair) sorts after every BMP code point.\n */\nfunction compareStringsByCodePoint(a: string, b: string): number {\n let ai = 0;\n let bi = 0;\n while (ai < a.length && bi < b.length) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const ac = a.codePointAt(ai)!;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const bc = b.codePointAt(bi)!;\n if (ac !== bc) return ac < bc ? -1 : 1;\n ai += ac > 0xffff ? 2 : 1;\n bi += bc > 0xffff ? 2 : 1;\n }\n if (ai >= a.length && bi >= b.length) return 0;\n return ai >= a.length ? -1 : 1;\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 /**\n * Prevent `JSON.stringify` from traversing backend clients (e.g. pg Pool\n * timers) when a checkpointer is present in runnable `configurable`.\n */\n toJSON(): string {\n return `[${this.constructor.name}]`;\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 * `taskPath` is the serialized path of the task creating the writes (see\n * `writesSortKey`). Implementations should persist it when they can, and\n * must return `pendingWrites` from `getTuple`/`list` in `writesSortKey`\n * order — live execution applies a superstep's writes in that order, so\n * replaying in any other order can rebuild a different value for an\n * order-sensitive reducer. Writes stored without a path (rows predating it,\n * savers that don't persist one) sort first by `taskId`, which is also the\n * order live execution applies input in.\n */\n abstract putWrites(\n config: RunnableConfig,\n writes: PendingWrite[],\n taskId: string,\n taskPath?: 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 * Walk the parent chain returning per-channel writes + seed, used to\n * reconstruct `DeltaChannel` state from `checkpoint_writes`.\n *\n * For each requested channel, walks ancestors of the checkpoint identified\n * by `config` (following `parentConfig`) and accumulates the pending writes\n * for that channel. The walk terminates per-channel at the nearest ancestor\n * whose `channel_values[ch]` is populated; that value is returned as `seed`.\n * If the walk reaches the root without finding a stored value, `seed` is\n * omitted from that channel's entry — the consumer treats the absence as\n * \"start empty\".\n *\n * Walks the parent chain (not `list({ before })`): for forked threads, only\n * on-path ancestors contribute.\n *\n * Within a single checkpoint, writes are ordered by `writesSortKey` —\n * `(task_path, task_id, idx)` — the order live execution applies a\n * superstep's task writes in. This default walk cannot sort by path itself\n * (`CheckpointPendingWrite` carries no path), so it relies on `getTuple`\n * returning `pendingWrites` already in `writesSortKey` order, which the\n * contract above requires of every saver. Writes stored without a\n * `task_path` (graph input, `Command` updates, rows predating the\n * column) sort first, by `task_id`.\n *\n * The default implementation walks `getTuple` + `parentConfig` once for all\n * channels — each ancestor visited once, not once per channel. Savers with\n * direct storage access (e.g. `MemorySaver`) override for performance; the\n * return contract is fixed here.\n *\n * @remarks Beta. The signature, return shape, and interaction with\n * `DeltaSnapshot` blobs may change. Override at your own risk; the default\n * implementation will continue to work against the public\n * `BaseCheckpointSaver` contract.\n *\n * @param options.config Configuration identifying the target checkpoint.\n * @param options.channels Channel names to walk for. Empty → empty mapping.\n * @returns Per-channel {@link DeltaChannelHistory} for every requested name.\n */\n async getDeltaChannelHistory(options: {\n config: RunnableConfig;\n channels: string[];\n }): Promise<Record<string, DeltaChannelHistory>> {\n const { config, channels } = options;\n if (channels.length === 0) return {};\n\n const collectedByCh: Record<string, CheckpointPendingWrite[]> = {};\n const seedByCh: Record<string, unknown> = {};\n const remaining = new Set(channels);\n for (const ch of channels) collectedByCh[ch] = [];\n\n const targetTuple = await this.getTuple(config);\n let cursorConfig: RunnableConfig | undefined = targetTuple?.parentConfig;\n\n while (cursorConfig != null && remaining.size > 0) {\n const tup: CheckpointTuple | undefined =\n await this.getTuple(cursorConfig);\n if (tup === undefined) break;\n if (tup.pendingWrites && tup.pendingWrites.length > 0) {\n // `getTuple` returns `pendingWrites` in `writesSortKey` order (see its\n // contract), which is the order live execution applies a superstep's\n // writes in — so no re-sorting here; just group per channel. Each\n // block is pushed reversed so the final `.reverse()` below yields\n // oldest→newest checkpoints with each checkpoint's writes ascending.\n const perChannel: Record<string, CheckpointPendingWrite[]> = {};\n for (const write of tup.pendingWrites) {\n const ch = write[1];\n if (remaining.has(ch)) (perChannel[ch] ??= []).push(write);\n }\n for (const ch of Object.keys(perChannel)) {\n const block = perChannel[ch];\n for (let i = block.length - 1; i >= 0; i -= 1) {\n collectedByCh[ch].push(block[i]);\n }\n }\n }\n for (const ch of Array.from(remaining)) {\n if (\n Object.prototype.hasOwnProperty.call(\n tup.checkpoint.channel_values,\n ch\n )\n ) {\n seedByCh[ch] = tup.checkpoint.channel_values[ch];\n remaining.delete(ch);\n }\n }\n cursorConfig = tup.parentConfig;\n }\n\n const result: Record<string, DeltaChannelHistory> = {};\n for (const ch of channels) {\n const entry: DeltaChannelHistory = {\n writes: collectedByCh[ch].slice().reverse(),\n };\n if (Object.prototype.hasOwnProperty.call(seedByCh, ch)) {\n entry.seed = seedByCh[ch];\n }\n result[ch] = entry;\n }\n return result;\n }\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\n/**\n * Metadata keys that are LangGraph's internal framework bookkeeping and\n * should not be surfaced as user-meaningful metadata.\n *\n * Consumed by stream handlers (e.g. the `tasks` debug stream) to drop\n * framework keys — which are redundant with a task's own fields and\n * namespace — while keeping keys like `lc_agent_name`, `ls_integration`,\n * and user-supplied metadata.\n */\nexport const EXCLUDED_METADATA_KEYS: ReadonlySet<string> = new Set([\n \"thread_id\",\n \"checkpoint_id\",\n \"checkpoint_ns\",\n \"checkpoint_map\",\n \"langgraph_step\",\n \"langgraph_node\",\n \"langgraph_triggers\",\n \"langgraph_path\",\n \"langgraph_checkpoint_ns\",\n]);\n\nexport function getCheckpointId(config: RunnableConfig): string {\n return (\n config.configurable?.checkpoint_id || config.configurable?.thread_ts || \"\"\n );\n}\n"],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -27,6 +27,7 @@ exports.SCHEDULED = require_types.SCHEDULED;
|
|
|
27
27
|
exports.TASKS = require_types.TASKS;
|
|
28
28
|
exports.WRITES_IDX_MAP = require_base.WRITES_IDX_MAP;
|
|
29
29
|
exports.compareChannelVersions = require_base.compareChannelVersions;
|
|
30
|
+
exports.compareWritesSortKeys = require_base.compareWritesSortKeys;
|
|
30
31
|
exports.copyCheckpoint = require_base.copyCheckpoint;
|
|
31
32
|
exports.deepCopy = require_base.deepCopy;
|
|
32
33
|
exports.emptyCheckpoint = require_base.emptyCheckpoint;
|
|
@@ -38,3 +39,4 @@ exports.tokenizePath = require_base$1.tokenizePath;
|
|
|
38
39
|
exports.uuid5 = require_id.uuid5;
|
|
39
40
|
exports.uuid6 = require_id.uuid6;
|
|
40
41
|
exports.validateNamespace = require_base$1.validateNamespace;
|
|
42
|
+
exports.writesSortKey = require_base.writesSortKey;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SerializerProtocol } from "./serde/base.cjs";
|
|
2
2
|
import { All, CheckpointMetadata, CheckpointPendingWrite, DeltaChannelHistory, PendingWrite, PendingWriteValue } from "./types.cjs";
|
|
3
|
-
import { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointTuple, EXCLUDED_METADATA_KEYS, ReadonlyCheckpoint, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion } from "./base.cjs";
|
|
3
|
+
import { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointTuple, EXCLUDED_METADATA_KEYS, ReadonlyCheckpoint, WRITES_IDX_MAP, WritesSortKey, compareChannelVersions, compareWritesSortKeys, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion, writesSortKey } from "./base.cjs";
|
|
4
4
|
import { MemorySaver } from "./memory.cjs";
|
|
5
5
|
import { uuid5, uuid6 } from "./id.cjs";
|
|
6
6
|
import { ChannelProtocol, ConstructorRecord, DeltaSnapshot, ERROR, INTERRUPT, RESUME, SCHEDULED, SendProtocol, TASKS, isDeltaSnapshot } from "./serde/types.cjs";
|
|
@@ -9,4 +9,4 @@ import { AsyncBatchedStore } from "./store/batch.cjs";
|
|
|
9
9
|
import { InMemoryStore, MemoryStore } from "./store/memory.cjs";
|
|
10
10
|
import { BaseCache, CacheFullKey, CacheNamespace } from "./cache/base.cjs";
|
|
11
11
|
import { InMemoryCache } from "./cache/memory.cjs";
|
|
12
|
-
export { All, AsyncBatchedStore, BaseCache, BaseCheckpointSaver, BaseStore, CacheFullKey, CacheNamespace, ChannelProtocol, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointMetadata, CheckpointPendingWrite, CheckpointTuple, ConstructorRecord, DeltaChannelHistory, DeltaSnapshot, ERROR, EXCLUDED_METADATA_KEYS, 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, isDeltaSnapshot, maxChannelVersion, tokenizePath, uuid5, uuid6, validateNamespace };
|
|
12
|
+
export { All, AsyncBatchedStore, BaseCache, BaseCheckpointSaver, BaseStore, CacheFullKey, CacheNamespace, ChannelProtocol, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointMetadata, CheckpointPendingWrite, CheckpointTuple, ConstructorRecord, DeltaChannelHistory, DeltaSnapshot, ERROR, EXCLUDED_METADATA_KEYS, 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, WritesSortKey, compareChannelVersions, compareWritesSortKeys, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, getTextAtPath, isDeltaSnapshot, maxChannelVersion, tokenizePath, uuid5, uuid6, validateNamespace, writesSortKey };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SerializerProtocol } from "./serde/base.js";
|
|
2
2
|
import { All, CheckpointMetadata, CheckpointPendingWrite, DeltaChannelHistory, PendingWrite, PendingWriteValue } from "./types.js";
|
|
3
|
-
import { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointTuple, EXCLUDED_METADATA_KEYS, ReadonlyCheckpoint, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion } from "./base.js";
|
|
3
|
+
import { BaseCheckpointSaver, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointTuple, EXCLUDED_METADATA_KEYS, ReadonlyCheckpoint, WRITES_IDX_MAP, WritesSortKey, compareChannelVersions, compareWritesSortKeys, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion, writesSortKey } from "./base.js";
|
|
4
4
|
import { MemorySaver } from "./memory.js";
|
|
5
5
|
import { uuid5, uuid6 } from "./id.js";
|
|
6
6
|
import { ChannelProtocol, ConstructorRecord, DeltaSnapshot, ERROR, INTERRUPT, RESUME, SCHEDULED, SendProtocol, TASKS, isDeltaSnapshot } from "./serde/types.js";
|
|
@@ -9,4 +9,4 @@ import { AsyncBatchedStore } from "./store/batch.js";
|
|
|
9
9
|
import { InMemoryStore, MemoryStore } from "./store/memory.js";
|
|
10
10
|
import { BaseCache, CacheFullKey, CacheNamespace } from "./cache/base.js";
|
|
11
11
|
import { InMemoryCache } from "./cache/memory.js";
|
|
12
|
-
export { All, AsyncBatchedStore, BaseCache, BaseCheckpointSaver, BaseStore, CacheFullKey, CacheNamespace, ChannelProtocol, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointMetadata, CheckpointPendingWrite, CheckpointTuple, ConstructorRecord, DeltaChannelHistory, DeltaSnapshot, ERROR, EXCLUDED_METADATA_KEYS, 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, isDeltaSnapshot, maxChannelVersion, tokenizePath, uuid5, uuid6, validateNamespace };
|
|
12
|
+
export { All, AsyncBatchedStore, BaseCache, BaseCheckpointSaver, BaseStore, CacheFullKey, CacheNamespace, ChannelProtocol, ChannelVersions, Checkpoint, CheckpointListOptions, CheckpointMetadata, CheckpointPendingWrite, CheckpointTuple, ConstructorRecord, DeltaChannelHistory, DeltaSnapshot, ERROR, EXCLUDED_METADATA_KEYS, 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, WritesSortKey, compareChannelVersions, compareWritesSortKeys, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, getTextAtPath, isDeltaSnapshot, maxChannelVersion, tokenizePath, uuid5, uuid6, validateNamespace, writesSortKey };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { uuid5, uuid6 } from "./id.js";
|
|
2
2
|
import { DeltaSnapshot, ERROR, INTERRUPT, RESUME, SCHEDULED, TASKS, isDeltaSnapshot } from "./serde/types.js";
|
|
3
|
-
import { BaseCheckpointSaver, EXCLUDED_METADATA_KEYS, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion } from "./base.js";
|
|
3
|
+
import { BaseCheckpointSaver, EXCLUDED_METADATA_KEYS, WRITES_IDX_MAP, compareChannelVersions, compareWritesSortKeys, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, maxChannelVersion, writesSortKey } from "./base.js";
|
|
4
4
|
import { MemorySaver } from "./memory.js";
|
|
5
5
|
import { BaseStore, InvalidNamespaceError, getTextAtPath, tokenizePath, validateNamespace } from "./store/base.js";
|
|
6
6
|
import { AsyncBatchedStore } from "./store/batch.js";
|
|
@@ -8,4 +8,4 @@ import { InMemoryStore, MemoryStore } from "./store/memory.js";
|
|
|
8
8
|
import { BaseCache } from "./cache/base.js";
|
|
9
9
|
import { InMemoryCache } from "./cache/memory.js";
|
|
10
10
|
import "./cache/index.js";
|
|
11
|
-
export { AsyncBatchedStore, BaseCache, BaseCheckpointSaver, BaseStore, DeltaSnapshot, ERROR, EXCLUDED_METADATA_KEYS, INTERRUPT, InMemoryCache, InMemoryStore, InvalidNamespaceError, MemorySaver, MemoryStore, RESUME, SCHEDULED, TASKS, WRITES_IDX_MAP, compareChannelVersions, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, getTextAtPath, isDeltaSnapshot, maxChannelVersion, tokenizePath, uuid5, uuid6, validateNamespace };
|
|
11
|
+
export { AsyncBatchedStore, BaseCache, BaseCheckpointSaver, BaseStore, DeltaSnapshot, ERROR, EXCLUDED_METADATA_KEYS, INTERRUPT, InMemoryCache, InMemoryStore, InvalidNamespaceError, MemorySaver, MemoryStore, RESUME, SCHEDULED, TASKS, WRITES_IDX_MAP, compareChannelVersions, compareWritesSortKeys, copyCheckpoint, deepCopy, emptyCheckpoint, getCheckpointId, getTextAtPath, isDeltaSnapshot, maxChannelVersion, tokenizePath, uuid5, uuid6, validateNamespace, writesSortKey };
|