@langchain/langgraph-checkpoint 0.0.0 → 0.0.1
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 +2 -2
- package/dist/base.d.ts +2 -2
- package/dist/base.js +2 -2
- package/dist/memory.cjs +27 -12
- package/dist/memory.d.ts +2 -2
- package/dist/memory.js +27 -12
- package/dist/serde/base.cjs +0 -6
- package/dist/serde/base.d.ts +3 -11
- package/dist/serde/base.js +1 -5
- package/dist/serde/jsonplus.cjs +131 -0
- package/dist/serde/jsonplus.d.ts +7 -0
- package/dist/serde/jsonplus.js +127 -0
- package/package.json +3 -3
package/dist/base.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BaseCheckpointSaver = exports.copyCheckpoint = exports.emptyCheckpoint = exports.deepCopy = void 0;
|
|
4
|
-
const base_js_1 = require("./serde/base.cjs");
|
|
5
4
|
const id_js_1 = require("./id.cjs");
|
|
5
|
+
const jsonplus_js_1 = require("./serde/jsonplus.cjs");
|
|
6
6
|
function deepCopy(obj) {
|
|
7
7
|
if (typeof obj !== "object" || obj === null) {
|
|
8
8
|
return obj;
|
|
@@ -46,7 +46,7 @@ class BaseCheckpointSaver {
|
|
|
46
46
|
enumerable: true,
|
|
47
47
|
configurable: true,
|
|
48
48
|
writable: true,
|
|
49
|
-
value:
|
|
49
|
+
value: new jsonplus_js_1.JsonPlusSerializer()
|
|
50
50
|
});
|
|
51
51
|
this.serde = serde || this.serde;
|
|
52
52
|
}
|
package/dist/base.d.ts
CHANGED
|
@@ -55,8 +55,8 @@ export type CheckpointListOptions = {
|
|
|
55
55
|
filter?: Record<string, any>;
|
|
56
56
|
};
|
|
57
57
|
export declare abstract class BaseCheckpointSaver<V = number> {
|
|
58
|
-
serde: SerializerProtocol
|
|
59
|
-
constructor(serde?: SerializerProtocol
|
|
58
|
+
serde: SerializerProtocol;
|
|
59
|
+
constructor(serde?: SerializerProtocol);
|
|
60
60
|
get(config: RunnableConfig): Promise<Checkpoint | undefined>;
|
|
61
61
|
abstract getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;
|
|
62
62
|
abstract list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>;
|
package/dist/base.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DefaultSerializer } from "./serde/base.js";
|
|
2
1
|
import { uuid6 } from "./id.js";
|
|
2
|
+
import { JsonPlusSerializer } from "./serde/jsonplus.js";
|
|
3
3
|
export function deepCopy(obj) {
|
|
4
4
|
if (typeof obj !== "object" || obj === null) {
|
|
5
5
|
return obj;
|
|
@@ -40,7 +40,7 @@ export class BaseCheckpointSaver {
|
|
|
40
40
|
enumerable: true,
|
|
41
41
|
configurable: true,
|
|
42
42
|
writable: true,
|
|
43
|
-
value:
|
|
43
|
+
value: new JsonPlusSerializer()
|
|
44
44
|
});
|
|
45
45
|
this.serde = serde || this.serde;
|
|
46
46
|
}
|
package/dist/memory.cjs
CHANGED
|
@@ -33,7 +33,11 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
|
|
|
33
33
|
const writes = this.writes[_generateKey(thread_id, checkpoint_ns, checkpoint_id)] ??
|
|
34
34
|
[];
|
|
35
35
|
const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
|
|
36
|
-
return [
|
|
36
|
+
return [
|
|
37
|
+
taskId,
|
|
38
|
+
channel,
|
|
39
|
+
await this.serde.loadsTyped("json", value),
|
|
40
|
+
];
|
|
37
41
|
}));
|
|
38
42
|
const parentConfig = parentCheckpointId !== undefined
|
|
39
43
|
? {
|
|
@@ -46,8 +50,8 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
|
|
|
46
50
|
: undefined;
|
|
47
51
|
return {
|
|
48
52
|
config,
|
|
49
|
-
checkpoint: (await this.serde.
|
|
50
|
-
metadata: (await this.serde.
|
|
53
|
+
checkpoint: (await this.serde.loadsTyped("json", checkpoint)),
|
|
54
|
+
metadata: (await this.serde.loadsTyped("json", metadata)),
|
|
51
55
|
pendingWrites,
|
|
52
56
|
parentConfig,
|
|
53
57
|
};
|
|
@@ -63,7 +67,11 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
|
|
|
63
67
|
const writes = this.writes[_generateKey(thread_id, checkpoint_ns, checkpoint_id)] ??
|
|
64
68
|
[];
|
|
65
69
|
const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
|
|
66
|
-
return [
|
|
70
|
+
return [
|
|
71
|
+
taskId,
|
|
72
|
+
channel,
|
|
73
|
+
await this.serde.loadsTyped("json", value),
|
|
74
|
+
];
|
|
67
75
|
}));
|
|
68
76
|
const parentConfig = parentCheckpointId !== undefined
|
|
69
77
|
? {
|
|
@@ -82,8 +90,8 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
|
|
|
82
90
|
checkpoint_ns,
|
|
83
91
|
},
|
|
84
92
|
},
|
|
85
|
-
checkpoint: (await this.serde.
|
|
86
|
-
metadata: (await this.serde.
|
|
93
|
+
checkpoint: (await this.serde.loadsTyped("json", checkpoint)),
|
|
94
|
+
metadata: (await this.serde.loadsTyped("json", metadata)),
|
|
87
95
|
pendingWrites,
|
|
88
96
|
parentConfig,
|
|
89
97
|
};
|
|
@@ -109,7 +117,7 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
|
|
|
109
117
|
continue;
|
|
110
118
|
}
|
|
111
119
|
// Parse metadata
|
|
112
|
-
const metadata = (await this.serde.
|
|
120
|
+
const metadata = (await this.serde.loadsTyped("json", metadataStr));
|
|
113
121
|
// Limit search results
|
|
114
122
|
if (limit !== undefined) {
|
|
115
123
|
if (limit <= 0)
|
|
@@ -119,7 +127,11 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
|
|
|
119
127
|
}
|
|
120
128
|
const writes = this.writes[_generateKey(threadId, checkpointNamespace, checkpointId)] ?? [];
|
|
121
129
|
const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
|
|
122
|
-
return [
|
|
130
|
+
return [
|
|
131
|
+
taskId,
|
|
132
|
+
channel,
|
|
133
|
+
await this.serde.loadsTyped("json", value),
|
|
134
|
+
];
|
|
123
135
|
}));
|
|
124
136
|
yield {
|
|
125
137
|
config: {
|
|
@@ -129,7 +141,7 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
|
|
|
129
141
|
checkpoint_id: checkpointId,
|
|
130
142
|
},
|
|
131
143
|
},
|
|
132
|
-
checkpoint: (await this.serde.
|
|
144
|
+
checkpoint: (await this.serde.loadsTyped("json", checkpoint)),
|
|
133
145
|
metadata,
|
|
134
146
|
pendingWrites,
|
|
135
147
|
parentConfig: parentCheckpointId
|
|
@@ -160,9 +172,11 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
|
|
|
160
172
|
if (!this.storage[threadId][checkpointNamespace]) {
|
|
161
173
|
this.storage[threadId][checkpointNamespace] = {};
|
|
162
174
|
}
|
|
175
|
+
const [, serializedCheckpoint] = this.serde.dumpsTyped(checkpoint);
|
|
176
|
+
const [, serializedMetadata] = this.serde.dumpsTyped(metadata);
|
|
163
177
|
this.storage[threadId][checkpointNamespace][checkpoint.id] = [
|
|
164
|
-
|
|
165
|
-
|
|
178
|
+
serializedCheckpoint,
|
|
179
|
+
serializedMetadata,
|
|
166
180
|
config.configurable?.checkpoint_id, // parent
|
|
167
181
|
];
|
|
168
182
|
return {
|
|
@@ -188,7 +202,8 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
|
|
|
188
202
|
this.writes[key] = [];
|
|
189
203
|
}
|
|
190
204
|
const pendingWrites = writes.map(([channel, value]) => {
|
|
191
|
-
|
|
205
|
+
const [, serializedValue] = this.serde.dumpsTyped(value);
|
|
206
|
+
return [taskId, channel, serializedValue];
|
|
192
207
|
});
|
|
193
208
|
this.writes[key].push(...pendingWrites);
|
|
194
209
|
}
|
package/dist/memory.d.ts
CHANGED
|
@@ -3,9 +3,9 @@ import { BaseCheckpointSaver, Checkpoint, CheckpointListOptions, CheckpointTuple
|
|
|
3
3
|
import { SerializerProtocol } from "./serde/base.js";
|
|
4
4
|
import { CheckpointMetadata, CheckpointPendingWrite, PendingWrite } from "./types.js";
|
|
5
5
|
export declare class MemorySaver extends BaseCheckpointSaver {
|
|
6
|
-
storage: Record<string, Record<string, Record<string, [
|
|
6
|
+
storage: Record<string, Record<string, Record<string, [Uint8Array, Uint8Array, string | undefined]>>>;
|
|
7
7
|
writes: Record<string, CheckpointPendingWrite[]>;
|
|
8
|
-
constructor(serde?: SerializerProtocol
|
|
8
|
+
constructor(serde?: SerializerProtocol);
|
|
9
9
|
getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;
|
|
10
10
|
list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>;
|
|
11
11
|
put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig>;
|
package/dist/memory.js
CHANGED
|
@@ -30,7 +30,11 @@ export class MemorySaver extends BaseCheckpointSaver {
|
|
|
30
30
|
const writes = this.writes[_generateKey(thread_id, checkpoint_ns, checkpoint_id)] ??
|
|
31
31
|
[];
|
|
32
32
|
const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
|
|
33
|
-
return [
|
|
33
|
+
return [
|
|
34
|
+
taskId,
|
|
35
|
+
channel,
|
|
36
|
+
await this.serde.loadsTyped("json", value),
|
|
37
|
+
];
|
|
34
38
|
}));
|
|
35
39
|
const parentConfig = parentCheckpointId !== undefined
|
|
36
40
|
? {
|
|
@@ -43,8 +47,8 @@ export class MemorySaver extends BaseCheckpointSaver {
|
|
|
43
47
|
: undefined;
|
|
44
48
|
return {
|
|
45
49
|
config,
|
|
46
|
-
checkpoint: (await this.serde.
|
|
47
|
-
metadata: (await this.serde.
|
|
50
|
+
checkpoint: (await this.serde.loadsTyped("json", checkpoint)),
|
|
51
|
+
metadata: (await this.serde.loadsTyped("json", metadata)),
|
|
48
52
|
pendingWrites,
|
|
49
53
|
parentConfig,
|
|
50
54
|
};
|
|
@@ -60,7 +64,11 @@ export class MemorySaver extends BaseCheckpointSaver {
|
|
|
60
64
|
const writes = this.writes[_generateKey(thread_id, checkpoint_ns, checkpoint_id)] ??
|
|
61
65
|
[];
|
|
62
66
|
const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
|
|
63
|
-
return [
|
|
67
|
+
return [
|
|
68
|
+
taskId,
|
|
69
|
+
channel,
|
|
70
|
+
await this.serde.loadsTyped("json", value),
|
|
71
|
+
];
|
|
64
72
|
}));
|
|
65
73
|
const parentConfig = parentCheckpointId !== undefined
|
|
66
74
|
? {
|
|
@@ -79,8 +87,8 @@ export class MemorySaver extends BaseCheckpointSaver {
|
|
|
79
87
|
checkpoint_ns,
|
|
80
88
|
},
|
|
81
89
|
},
|
|
82
|
-
checkpoint: (await this.serde.
|
|
83
|
-
metadata: (await this.serde.
|
|
90
|
+
checkpoint: (await this.serde.loadsTyped("json", checkpoint)),
|
|
91
|
+
metadata: (await this.serde.loadsTyped("json", metadata)),
|
|
84
92
|
pendingWrites,
|
|
85
93
|
parentConfig,
|
|
86
94
|
};
|
|
@@ -106,7 +114,7 @@ export class MemorySaver extends BaseCheckpointSaver {
|
|
|
106
114
|
continue;
|
|
107
115
|
}
|
|
108
116
|
// Parse metadata
|
|
109
|
-
const metadata = (await this.serde.
|
|
117
|
+
const metadata = (await this.serde.loadsTyped("json", metadataStr));
|
|
110
118
|
// Limit search results
|
|
111
119
|
if (limit !== undefined) {
|
|
112
120
|
if (limit <= 0)
|
|
@@ -116,7 +124,11 @@ export class MemorySaver extends BaseCheckpointSaver {
|
|
|
116
124
|
}
|
|
117
125
|
const writes = this.writes[_generateKey(threadId, checkpointNamespace, checkpointId)] ?? [];
|
|
118
126
|
const pendingWrites = await Promise.all(writes.map(async ([taskId, channel, value]) => {
|
|
119
|
-
return [
|
|
127
|
+
return [
|
|
128
|
+
taskId,
|
|
129
|
+
channel,
|
|
130
|
+
await this.serde.loadsTyped("json", value),
|
|
131
|
+
];
|
|
120
132
|
}));
|
|
121
133
|
yield {
|
|
122
134
|
config: {
|
|
@@ -126,7 +138,7 @@ export class MemorySaver extends BaseCheckpointSaver {
|
|
|
126
138
|
checkpoint_id: checkpointId,
|
|
127
139
|
},
|
|
128
140
|
},
|
|
129
|
-
checkpoint: (await this.serde.
|
|
141
|
+
checkpoint: (await this.serde.loadsTyped("json", checkpoint)),
|
|
130
142
|
metadata,
|
|
131
143
|
pendingWrites,
|
|
132
144
|
parentConfig: parentCheckpointId
|
|
@@ -157,9 +169,11 @@ export class MemorySaver extends BaseCheckpointSaver {
|
|
|
157
169
|
if (!this.storage[threadId][checkpointNamespace]) {
|
|
158
170
|
this.storage[threadId][checkpointNamespace] = {};
|
|
159
171
|
}
|
|
172
|
+
const [, serializedCheckpoint] = this.serde.dumpsTyped(checkpoint);
|
|
173
|
+
const [, serializedMetadata] = this.serde.dumpsTyped(metadata);
|
|
160
174
|
this.storage[threadId][checkpointNamespace][checkpoint.id] = [
|
|
161
|
-
|
|
162
|
-
|
|
175
|
+
serializedCheckpoint,
|
|
176
|
+
serializedMetadata,
|
|
163
177
|
config.configurable?.checkpoint_id, // parent
|
|
164
178
|
];
|
|
165
179
|
return {
|
|
@@ -185,7 +199,8 @@ export class MemorySaver extends BaseCheckpointSaver {
|
|
|
185
199
|
this.writes[key] = [];
|
|
186
200
|
}
|
|
187
201
|
const pendingWrites = writes.map(([channel, value]) => {
|
|
188
|
-
|
|
202
|
+
const [, serializedValue] = this.serde.dumpsTyped(value);
|
|
203
|
+
return [taskId, channel, serializedValue];
|
|
189
204
|
});
|
|
190
205
|
this.writes[key].push(...pendingWrites);
|
|
191
206
|
}
|
package/dist/serde/base.cjs
CHANGED
package/dist/serde/base.d.ts
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
parse(data: string): Promise<D>;
|
|
1
|
+
export interface SerializerProtocol {
|
|
2
|
+
dumpsTyped(data: any): [string, Uint8Array];
|
|
3
|
+
loadsTyped(type: string, data: Uint8Array | string): any;
|
|
5
4
|
}
|
|
6
|
-
export declare const DefaultSerializer: {
|
|
7
|
-
stringify: {
|
|
8
|
-
(value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string;
|
|
9
|
-
(value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string;
|
|
10
|
-
};
|
|
11
|
-
parse: typeof load;
|
|
12
|
-
};
|
package/dist/serde/base.js
CHANGED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JsonPlusSerializer = void 0;
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
|
+
/* eslint-disable no-instanceof/no-instanceof */
|
|
6
|
+
const load_1 = require("@langchain/core/load");
|
|
7
|
+
async function _reviver(value) {
|
|
8
|
+
if (value && typeof value === "object") {
|
|
9
|
+
if (value.lc === 2 &&
|
|
10
|
+
value.type === "constructor" &&
|
|
11
|
+
Array.isArray(value.id)) {
|
|
12
|
+
try {
|
|
13
|
+
const constructorName = value.id[value.id.length - 1];
|
|
14
|
+
let constructor;
|
|
15
|
+
switch (constructorName) {
|
|
16
|
+
case "Set":
|
|
17
|
+
constructor = Set;
|
|
18
|
+
break;
|
|
19
|
+
case "Map":
|
|
20
|
+
constructor = Map;
|
|
21
|
+
break;
|
|
22
|
+
case "RegExp":
|
|
23
|
+
constructor = RegExp;
|
|
24
|
+
break;
|
|
25
|
+
case "Error":
|
|
26
|
+
constructor = Error;
|
|
27
|
+
break;
|
|
28
|
+
default:
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
if (value.method) {
|
|
32
|
+
return constructor[value.method](...(value.args || []));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
return new constructor(...(value.args || []));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (value.lc === 1) {
|
|
43
|
+
return (0, load_1.load)(JSON.stringify(value));
|
|
44
|
+
}
|
|
45
|
+
else if (Array.isArray(value)) {
|
|
46
|
+
return Promise.all(value.map((item) => _reviver(item)));
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const revivedObj = {};
|
|
50
|
+
for (const [k, v] of Object.entries(value)) {
|
|
51
|
+
revivedObj[k] = await _reviver(v);
|
|
52
|
+
}
|
|
53
|
+
return revivedObj;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
function _encodeConstructorArgs(
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
60
|
+
constructor, method, args, kwargs) {
|
|
61
|
+
return {
|
|
62
|
+
lc: 2,
|
|
63
|
+
type: "constructor",
|
|
64
|
+
id: [constructor.name],
|
|
65
|
+
method,
|
|
66
|
+
args: args ?? [],
|
|
67
|
+
kwargs: kwargs ?? {},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function _default(_key, obj) {
|
|
71
|
+
if (obj instanceof Set || obj instanceof Map) {
|
|
72
|
+
return _encodeConstructorArgs(obj.constructor, undefined, [
|
|
73
|
+
Array.from(obj),
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
else if (obj instanceof RegExp) {
|
|
77
|
+
return _encodeConstructorArgs(RegExp, undefined, [obj.source, obj.flags]);
|
|
78
|
+
}
|
|
79
|
+
else if (obj instanceof Error) {
|
|
80
|
+
return _encodeConstructorArgs(obj.constructor, undefined, [obj.message]);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return obj;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
class JsonPlusSerializer {
|
|
87
|
+
_dumps(obj) {
|
|
88
|
+
const jsonString = JSON.stringify(obj, (key, value) => {
|
|
89
|
+
if (value && typeof value === "object") {
|
|
90
|
+
if (Array.isArray(value)) {
|
|
91
|
+
// Handle arrays
|
|
92
|
+
return value.map((item) => _default(key, item));
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// Handle objects
|
|
96
|
+
const serialized = {};
|
|
97
|
+
for (const [k, v] of Object.entries(value)) {
|
|
98
|
+
serialized[k] = _default(k, v);
|
|
99
|
+
}
|
|
100
|
+
return serialized;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return _default(key, value);
|
|
104
|
+
});
|
|
105
|
+
return new TextEncoder().encode(jsonString);
|
|
106
|
+
}
|
|
107
|
+
dumpsTyped(obj) {
|
|
108
|
+
if (obj instanceof Uint8Array) {
|
|
109
|
+
return ["bytes", obj];
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
return ["json", this._dumps(obj)];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async _loads(data) {
|
|
116
|
+
const parsed = JSON.parse(data);
|
|
117
|
+
return _reviver(parsed);
|
|
118
|
+
}
|
|
119
|
+
async loadsTyped(type, data) {
|
|
120
|
+
if (type === "bytes") {
|
|
121
|
+
return typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
122
|
+
}
|
|
123
|
+
else if (type === "json") {
|
|
124
|
+
return this._loads(typeof data === "string" ? data : new TextDecoder().decode(data));
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
throw new Error(`Unknown serialization type: ${type}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
exports.JsonPlusSerializer = JsonPlusSerializer;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SerializerProtocol } from "./base.js";
|
|
2
|
+
export declare class JsonPlusSerializer implements SerializerProtocol {
|
|
3
|
+
protected _dumps(obj: any): Uint8Array;
|
|
4
|
+
dumpsTyped(obj: any): [string, Uint8Array];
|
|
5
|
+
protected _loads(data: string): Promise<any>;
|
|
6
|
+
loadsTyped(type: string, data: Uint8Array | string): Promise<any>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/* eslint-disable no-instanceof/no-instanceof */
|
|
3
|
+
import { load } from "@langchain/core/load";
|
|
4
|
+
async function _reviver(value) {
|
|
5
|
+
if (value && typeof value === "object") {
|
|
6
|
+
if (value.lc === 2 &&
|
|
7
|
+
value.type === "constructor" &&
|
|
8
|
+
Array.isArray(value.id)) {
|
|
9
|
+
try {
|
|
10
|
+
const constructorName = value.id[value.id.length - 1];
|
|
11
|
+
let constructor;
|
|
12
|
+
switch (constructorName) {
|
|
13
|
+
case "Set":
|
|
14
|
+
constructor = Set;
|
|
15
|
+
break;
|
|
16
|
+
case "Map":
|
|
17
|
+
constructor = Map;
|
|
18
|
+
break;
|
|
19
|
+
case "RegExp":
|
|
20
|
+
constructor = RegExp;
|
|
21
|
+
break;
|
|
22
|
+
case "Error":
|
|
23
|
+
constructor = Error;
|
|
24
|
+
break;
|
|
25
|
+
default:
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
if (value.method) {
|
|
29
|
+
return constructor[value.method](...(value.args || []));
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return new constructor(...(value.args || []));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (value.lc === 1) {
|
|
40
|
+
return load(JSON.stringify(value));
|
|
41
|
+
}
|
|
42
|
+
else if (Array.isArray(value)) {
|
|
43
|
+
return Promise.all(value.map((item) => _reviver(item)));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const revivedObj = {};
|
|
47
|
+
for (const [k, v] of Object.entries(value)) {
|
|
48
|
+
revivedObj[k] = await _reviver(v);
|
|
49
|
+
}
|
|
50
|
+
return revivedObj;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
function _encodeConstructorArgs(
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
57
|
+
constructor, method, args, kwargs) {
|
|
58
|
+
return {
|
|
59
|
+
lc: 2,
|
|
60
|
+
type: "constructor",
|
|
61
|
+
id: [constructor.name],
|
|
62
|
+
method,
|
|
63
|
+
args: args ?? [],
|
|
64
|
+
kwargs: kwargs ?? {},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function _default(_key, obj) {
|
|
68
|
+
if (obj instanceof Set || obj instanceof Map) {
|
|
69
|
+
return _encodeConstructorArgs(obj.constructor, undefined, [
|
|
70
|
+
Array.from(obj),
|
|
71
|
+
]);
|
|
72
|
+
}
|
|
73
|
+
else if (obj instanceof RegExp) {
|
|
74
|
+
return _encodeConstructorArgs(RegExp, undefined, [obj.source, obj.flags]);
|
|
75
|
+
}
|
|
76
|
+
else if (obj instanceof Error) {
|
|
77
|
+
return _encodeConstructorArgs(obj.constructor, undefined, [obj.message]);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
return obj;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
export class JsonPlusSerializer {
|
|
84
|
+
_dumps(obj) {
|
|
85
|
+
const jsonString = JSON.stringify(obj, (key, value) => {
|
|
86
|
+
if (value && typeof value === "object") {
|
|
87
|
+
if (Array.isArray(value)) {
|
|
88
|
+
// Handle arrays
|
|
89
|
+
return value.map((item) => _default(key, item));
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// Handle objects
|
|
93
|
+
const serialized = {};
|
|
94
|
+
for (const [k, v] of Object.entries(value)) {
|
|
95
|
+
serialized[k] = _default(k, v);
|
|
96
|
+
}
|
|
97
|
+
return serialized;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return _default(key, value);
|
|
101
|
+
});
|
|
102
|
+
return new TextEncoder().encode(jsonString);
|
|
103
|
+
}
|
|
104
|
+
dumpsTyped(obj) {
|
|
105
|
+
if (obj instanceof Uint8Array) {
|
|
106
|
+
return ["bytes", obj];
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
return ["json", this._dumps(obj)];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async _loads(data) {
|
|
113
|
+
const parsed = JSON.parse(data);
|
|
114
|
+
return _reviver(parsed);
|
|
115
|
+
}
|
|
116
|
+
async loadsTyped(type, data) {
|
|
117
|
+
if (type === "bytes") {
|
|
118
|
+
return typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
119
|
+
}
|
|
120
|
+
else if (type === "json") {
|
|
121
|
+
return this._loads(typeof data === "string" ? data : new TextDecoder().decode(data));
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
throw new Error(`Unknown serialization type: ${type}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/langgraph-checkpoint",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.1",
|
|
4
4
|
"description": "Library with base interfaces for LangGraph checkpoint savers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
16
|
"build": "yarn turbo:command build:internal --filter=@langchain/langgraph-checkpoint",
|
|
17
|
-
"build:internal": "yarn
|
|
17
|
+
"build:internal": "yarn lc_build --create-entrypoints --pre --tree-shaking",
|
|
18
18
|
"lint:eslint": "NODE_OPTIONS=--max-old-space-size=4096 eslint --cache --ext .ts,.js src/",
|
|
19
19
|
"lint:dpdm": "dpdm --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts",
|
|
20
20
|
"lint": "yarn lint:eslint && yarn lint:dpdm",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@jest/globals": "^29.5.0",
|
|
40
|
-
"@langchain/scripts": "
|
|
40
|
+
"@langchain/scripts": ">=0.1.0 <0.2.0",
|
|
41
41
|
"@swc/core": "^1.3.90",
|
|
42
42
|
"@swc/jest": "^0.2.29",
|
|
43
43
|
"@tsconfig/recommended": "^1.0.3",
|