@langchain/langgraph-checkpoint 0.0.6 → 0.0.8-rc.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.
@@ -0,0 +1,112 @@
1
+ import { BaseStore, } from "./base.js";
2
+ export class MemoryStore extends BaseStore {
3
+ constructor() {
4
+ super(...arguments);
5
+ Object.defineProperty(this, "data", {
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true,
9
+ value: new Map()
10
+ });
11
+ }
12
+ async batch(operations) {
13
+ const results = [];
14
+ for (const op of operations) {
15
+ if ("id" in op && "namespace" in op && !("value" in op)) {
16
+ // GetOperation
17
+ results.push(this.getOperation(op));
18
+ }
19
+ else if ("namespacePrefix" in op) {
20
+ // SearchOperation
21
+ results.push(this.searchOperation(op));
22
+ }
23
+ else if ("value" in op) {
24
+ // PutOperation
25
+ results.push(this.putOperation(op));
26
+ }
27
+ else if ("matchConditions" in op) {
28
+ // ListNamespacesOperation
29
+ results.push(this.listNamespacesOperation(op));
30
+ }
31
+ }
32
+ return Promise.resolve(results);
33
+ }
34
+ getOperation(op) {
35
+ const namespaceKey = op.namespace.join(":");
36
+ const item = this.data.get(namespaceKey)?.get(op.id);
37
+ return item || null;
38
+ }
39
+ searchOperation(op) {
40
+ const candidates = [];
41
+ for (const [namespace, items] of this.data.entries()) {
42
+ if (namespace.startsWith(op.namespacePrefix.join(":"))) {
43
+ candidates.push(...items.values());
44
+ }
45
+ }
46
+ let filteredCandidates = candidates;
47
+ if (op.filter) {
48
+ filteredCandidates = candidates.filter((item) => Object.entries(op.filter).every(([key, value]) => item.value[key] === value));
49
+ }
50
+ const searchResults = filteredCandidates.slice(op.offset || 0, (op.offset || 0) + (op.limit || 10));
51
+ return searchResults;
52
+ }
53
+ putOperation(op) {
54
+ const namespaceKey = op.namespace.join(":");
55
+ if (!this.data.has(namespaceKey)) {
56
+ this.data.set(namespaceKey, new Map());
57
+ }
58
+ const namespaceMap = this.data.get(namespaceKey);
59
+ if (op.value === null) {
60
+ namespaceMap.delete(op.id);
61
+ }
62
+ else {
63
+ const now = new Date();
64
+ if (namespaceMap.has(op.id)) {
65
+ const item = namespaceMap.get(op.id);
66
+ item.value = op.value;
67
+ item.updatedAt = now;
68
+ }
69
+ else {
70
+ namespaceMap.set(op.id, {
71
+ value: op.value,
72
+ id: op.id,
73
+ namespace: op.namespace,
74
+ createdAt: now,
75
+ updatedAt: now,
76
+ });
77
+ }
78
+ }
79
+ }
80
+ listNamespacesOperation(op) {
81
+ const allNamespaces = Array.from(this.data.keys()).map((ns) => ns.split(":"));
82
+ let namespaces = allNamespaces;
83
+ if (op.matchConditions && op.matchConditions.length > 0) {
84
+ namespaces = namespaces.filter((ns) => op.matchConditions.every((condition) => this.doesMatch(condition, ns)));
85
+ }
86
+ if (op.maxDepth !== undefined) {
87
+ namespaces = Array.from(new Set(namespaces.map((ns) => ns.slice(0, op.maxDepth).join(":")))).map((ns) => ns.split(":"));
88
+ }
89
+ namespaces.sort((a, b) => a.join(":").localeCompare(b.join(":")));
90
+ const paginatedNamespaces = namespaces.slice(op.offset, op.offset + op.limit);
91
+ return paginatedNamespaces;
92
+ }
93
+ doesMatch(matchCondition, key) {
94
+ const { matchType, path } = matchCondition;
95
+ if (key.length < path.length) {
96
+ return false;
97
+ }
98
+ if (matchType === "prefix") {
99
+ return path.every((pElem, index) => {
100
+ const kElem = key[index];
101
+ return pElem === "*" || kElem === pElem;
102
+ });
103
+ }
104
+ else if (matchType === "suffix") {
105
+ return [...path].reverse().every((pElem, index) => {
106
+ const kElem = key[key.length - 1 - index];
107
+ return pElem === "*" || kElem === pElem;
108
+ });
109
+ }
110
+ throw new Error(`Unsupported match type: ${matchType}`);
111
+ }
112
+ }
package/dist/types.d.ts CHANGED
@@ -25,4 +25,9 @@ export interface CheckpointMetadata {
25
25
  * Mapping from node name to writes emitted by that node.
26
26
  */
27
27
  writes: Record<string, unknown> | null;
28
+ /**
29
+ * The IDs of the parent checkpoints.
30
+ * Mapping from checkpoint namespace to checkpoint ID.
31
+ */
32
+ parents: Record<string, string>;
28
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph-checkpoint",
3
- "version": "0.0.6",
3
+ "version": "0.0.8-rc.0",
4
4
  "description": "Library with base interfaces for LangGraph checkpoint savers.",
5
5
  "type": "module",
6
6
  "engines": {