@langchain/langgraph 0.2.3 → 0.2.5-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.
Files changed (55) hide show
  1. package/dist/channels/base.cjs +16 -4
  2. package/dist/channels/base.d.ts +3 -0
  3. package/dist/channels/base.js +14 -3
  4. package/dist/constants.cjs +4 -1
  5. package/dist/constants.d.ts +3 -0
  6. package/dist/constants.js +3 -0
  7. package/dist/graph/annotation.cjs +5 -1
  8. package/dist/graph/annotation.d.ts +5 -4
  9. package/dist/graph/annotation.js +5 -1
  10. package/dist/graph/state.cjs +19 -7
  11. package/dist/graph/state.d.ts +13 -8
  12. package/dist/graph/state.js +18 -6
  13. package/dist/managed/base.cjs +163 -0
  14. package/dist/managed/base.d.ts +30 -0
  15. package/dist/managed/base.js +155 -0
  16. package/dist/managed/index.cjs +19 -0
  17. package/dist/managed/index.d.ts +3 -0
  18. package/dist/managed/index.js +3 -0
  19. package/dist/managed/is_last_step.cjs +11 -0
  20. package/dist/managed/is_last_step.d.ts +4 -0
  21. package/dist/managed/is_last_step.js +7 -0
  22. package/dist/managed/shared_value.cjs +109 -0
  23. package/dist/managed/shared_value.d.ts +23 -0
  24. package/dist/managed/shared_value.js +105 -0
  25. package/dist/prebuilt/agent_executor.d.ts +1 -1
  26. package/dist/pregel/algo.cjs +111 -50
  27. package/dist/pregel/algo.d.ts +7 -6
  28. package/dist/pregel/algo.js +112 -51
  29. package/dist/pregel/index.cjs +78 -6
  30. package/dist/pregel/index.d.ts +10 -2
  31. package/dist/pregel/index.js +80 -8
  32. package/dist/pregel/loop.cjs +40 -3
  33. package/dist/pregel/loop.d.ts +10 -0
  34. package/dist/pregel/loop.js +40 -3
  35. package/dist/pregel/types.d.ts +9 -2
  36. package/dist/pregel/validate.d.ts +3 -2
  37. package/dist/store/base.cjs +12 -0
  38. package/dist/store/base.d.ts +7 -0
  39. package/dist/store/base.js +8 -0
  40. package/dist/store/batch.cjs +126 -0
  41. package/dist/store/batch.d.ts +55 -0
  42. package/dist/store/batch.js +122 -0
  43. package/dist/store/index.cjs +19 -0
  44. package/dist/store/index.d.ts +3 -0
  45. package/dist/store/index.js +3 -0
  46. package/dist/store/memory.cjs +43 -0
  47. package/dist/store/memory.d.ts +6 -0
  48. package/dist/store/memory.js +39 -0
  49. package/dist/utils.cjs +26 -1
  50. package/dist/utils.d.ts +1 -0
  51. package/dist/utils.js +24 -0
  52. package/dist/web.cjs +2 -0
  53. package/dist/web.d.ts +2 -0
  54. package/dist/web.js +2 -0
  55. package/package.json +1 -1
@@ -8,6 +8,7 @@ import { mapInput, mapOutputUpdates, mapOutputValues } from "./io.js";
8
8
  import { EmptyInputError, GraphInterrupt } from "../errors.js";
9
9
  import { getNewChannelVersions } from "./utils.js";
10
10
  import { mapDebugTasks, mapDebugCheckpoint, mapDebugTaskResults, } from "./debug.js";
11
+ import { AsyncBatchedStore } from "../store/batch.js";
11
12
  const INPUT_DONE = Symbol.for("INPUT_DONE");
12
13
  const INPUT_RESUMING = Symbol.for("INPUT_RESUMING");
13
14
  const DEFAULT_LOOP_LIMIT = 25;
@@ -44,6 +45,12 @@ export class PregelLoop {
44
45
  writable: true,
45
46
  value: void 0
46
47
  });
48
+ Object.defineProperty(this, "managed", {
49
+ enumerable: true,
50
+ configurable: true,
51
+ writable: true,
52
+ value: void 0
53
+ });
47
54
  Object.defineProperty(this, "checkpoint", {
48
55
  enumerable: true,
49
56
  configurable: true,
@@ -148,6 +155,12 @@ export class PregelLoop {
148
155
  writable: true,
149
156
  value: Promise.resolve()
150
157
  });
158
+ Object.defineProperty(this, "store", {
159
+ enumerable: true,
160
+ configurable: true,
161
+ writable: true,
162
+ value: void 0
163
+ });
151
164
  this.input = params.input;
152
165
  this.config = params.config;
153
166
  this.checkpointer = params.checkpointer;
@@ -164,6 +177,7 @@ export class PregelLoop {
164
177
  this.checkpointMetadata = params.checkpointMetadata;
165
178
  this.checkpointPreviousVersions = params.checkpointPreviousVersions;
166
179
  this.channels = params.channels;
180
+ this.managed = params.managed;
167
181
  this.checkpointPendingWrites = params.checkpointPendingWrites;
168
182
  this.step = params.step;
169
183
  this.stop = params.stop;
@@ -172,6 +186,7 @@ export class PregelLoop {
172
186
  this.streamKeys = params.streamKeys;
173
187
  this.nodes = params.nodes;
174
188
  this.skipDoneTasks = this.config.configurable?.checkpoint_id === undefined;
189
+ this.store = params.store;
175
190
  }
176
191
  static async initialize(params) {
177
192
  const saved = (await params.checkpointer?.getTuple(params.config)) ?? {
@@ -199,6 +214,13 @@ export class PregelLoop {
199
214
  const step = (checkpointMetadata.step ?? 0) + 1;
200
215
  const stop = step + (params.config.recursionLimit ?? DEFAULT_LOOP_LIMIT) + 1;
201
216
  const checkpointPreviousVersions = { ...checkpoint.channel_versions };
217
+ const store = params.store
218
+ ? new AsyncBatchedStore(params.store)
219
+ : undefined;
220
+ if (store) {
221
+ // Start the store. This is a batch store, so it will run continuously
222
+ store.start();
223
+ }
202
224
  return new PregelLoop({
203
225
  input: params.input,
204
226
  config: params.config,
@@ -207,6 +229,7 @@ export class PregelLoop {
207
229
  checkpointMetadata,
208
230
  checkpointConfig,
209
231
  channels,
232
+ managed: params.managed,
210
233
  step,
211
234
  stop,
212
235
  checkpointPreviousVersions,
@@ -214,6 +237,7 @@ export class PregelLoop {
214
237
  outputKeys: params.outputKeys ?? [],
215
238
  streamKeys: params.streamKeys ?? [],
216
239
  nodes: params.nodes,
240
+ store,
217
241
  });
218
242
  }
219
243
  _checkpointerPutAfterPrevious(input) {
@@ -222,6 +246,13 @@ export class PregelLoop {
222
246
  });
223
247
  this.checkpointerPromises.push(this._checkpointerChainedPromise);
224
248
  }
249
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
250
+ async updateManagedValues(key, values) {
251
+ const mv = this.managed.get(key);
252
+ if (mv && "update" in mv && typeof mv.update === "function") {
253
+ await mv.update(values);
254
+ }
255
+ }
225
256
  /**
226
257
  * Put writes for a task, to be read by the next tick.
227
258
  * @param taskId
@@ -255,6 +286,9 @@ export class PregelLoop {
255
286
  * @param params
256
287
  */
257
288
  async tick(params) {
289
+ if (this.store && !this.store.isRunning) {
290
+ this.store?.start();
291
+ }
258
292
  const { inputKeys = [], interruptAfter = [], interruptBefore = [], manager, } = params;
259
293
  if (this.status !== "pending") {
260
294
  throw new Error(`Cannot tick when status is no longer "pending". Current status: "${this.status}"`);
@@ -265,7 +299,10 @@ export class PregelLoop {
265
299
  else if (this.tasks.every((task) => task.writes.length > 0)) {
266
300
  const writes = this.tasks.flatMap((t) => t.writes);
267
301
  // All tasks have finished
268
- _applyWrites(this.checkpoint, this.channels, this.tasks, this.checkpointerGetNextVersion);
302
+ const myWrites = _applyWrites(this.checkpoint, this.channels, this.tasks, this.checkpointerGetNextVersion);
303
+ for (const [key, values] of Object.entries(myWrites)) {
304
+ await this.updateManagedValues(key, values);
305
+ }
269
306
  // produce values output
270
307
  const valuesOutput = await gatherIterator(prefixGenerator(mapOutputValues(this.outputKeys, writes, this.channels), "values"));
271
308
  this.stream.push(...valuesOutput);
@@ -293,7 +330,7 @@ export class PregelLoop {
293
330
  this.status = "out_of_steps";
294
331
  return false;
295
332
  }
296
- const nextTasks = _prepareNextTasks(this.checkpoint, this.nodes, this.channels, this.config, true, {
333
+ const nextTasks = _prepareNextTasks(this.checkpoint, this.nodes, this.channels, this.managed, this.config, true, {
297
334
  step: this.step,
298
335
  checkpointer: this.checkpointer,
299
336
  isResuming: this.input === INPUT_RESUMING,
@@ -371,7 +408,7 @@ export class PregelLoop {
371
408
  if (inputWrites.length === 0) {
372
409
  throw new EmptyInputError(`Received no input writes for ${JSON.stringify(inputKeys, null, 2)}`);
373
410
  }
374
- const discardTasks = _prepareNextTasks(this.checkpoint, this.nodes, this.channels, this.config, true, { step: this.step });
411
+ const discardTasks = _prepareNextTasks(this.checkpoint, this.nodes, this.channels, this.managed, this.config, true, { step: this.step });
375
412
  _applyWrites(this.checkpoint, this.channels, discardTasks.concat([
376
413
  {
377
414
  name: INPUT,
@@ -4,6 +4,8 @@ import type { BaseChannel } from "../channels/base.js";
4
4
  import type { PregelNode } from "./read.js";
5
5
  import { RetryPolicy } from "./utils.js";
6
6
  import { Interrupt } from "../constants.js";
7
+ import { BaseStore } from "../store/base.js";
8
+ import { type ManagedValueSpec } from "../managed/base.js";
7
9
  export type StreamMode = "values" | "updates" | "debug";
8
10
  /**
9
11
  * Construct a type with a set of properties K of type T
@@ -11,7 +13,7 @@ export type StreamMode = "values" | "updates" | "debug";
11
13
  type StrRecord<K extends string, T> = {
12
14
  [P in K]: T;
13
15
  };
14
- export interface PregelInterface<Nn extends StrRecord<string, PregelNode>, Cc extends StrRecord<string, BaseChannel>> {
16
+ export interface PregelInterface<Nn extends StrRecord<string, PregelNode>, Cc extends StrRecord<string, BaseChannel | ManagedValueSpec>> {
15
17
  nodes: Nn;
16
18
  channels: Cc;
17
19
  /**
@@ -24,6 +26,7 @@ export interface PregelInterface<Nn extends StrRecord<string, PregelNode>, Cc ex
24
26
  streamMode?: StreamMode | StreamMode[];
25
27
  inputChannels: keyof Cc | Array<keyof Cc>;
26
28
  outputChannels: keyof Cc | Array<keyof Cc>;
29
+ configKeys?: string[];
27
30
  /**
28
31
  * @default []
29
32
  */
@@ -44,8 +47,12 @@ export interface PregelInterface<Nn extends StrRecord<string, PregelNode>, Cc ex
44
47
  debug?: boolean;
45
48
  checkpointer?: BaseCheckpointSaver;
46
49
  retryPolicy?: RetryPolicy;
50
+ /**
51
+ * Memory store to use for SharedValues.
52
+ */
53
+ store?: BaseStore;
47
54
  }
48
- export type PregelParams<Nn extends StrRecord<string, PregelNode>, Cc extends StrRecord<string, BaseChannel>> = Omit<PregelInterface<Nn, Cc>, "streamChannelsAsIs">;
55
+ export type PregelParams<Nn extends StrRecord<string, PregelNode>, Cc extends StrRecord<string, BaseChannel | ManagedValueSpec>> = Omit<PregelInterface<Nn, Cc>, "streamChannelsAsIs">;
49
56
  export interface PregelTaskDescription {
50
57
  readonly id: string;
51
58
  readonly name: string;
@@ -1,10 +1,11 @@
1
1
  import { All } from "@langchain/langgraph-checkpoint";
2
2
  import { BaseChannel } from "../channels/index.js";
3
3
  import { PregelNode } from "./read.js";
4
+ import { type ManagedValueSpec } from "../managed/base.js";
4
5
  export declare class GraphValidationError extends Error {
5
6
  constructor(message?: string);
6
7
  }
7
- export declare function validateGraph<Nn extends Record<string, PregelNode>, Cc extends Record<string, BaseChannel>>({ nodes, channels, inputChannels, outputChannels, streamChannels, interruptAfterNodes, interruptBeforeNodes, }: {
8
+ export declare function validateGraph<Nn extends Record<string, PregelNode>, Cc extends Record<string, BaseChannel | ManagedValueSpec>>({ nodes, channels, inputChannels, outputChannels, streamChannels, interruptAfterNodes, interruptBeforeNodes, }: {
8
9
  nodes: Nn;
9
10
  channels: Cc;
10
11
  inputChannels: keyof Cc | Array<keyof Cc>;
@@ -13,4 +14,4 @@ export declare function validateGraph<Nn extends Record<string, PregelNode>, Cc
13
14
  interruptAfterNodes?: Array<keyof Nn> | All;
14
15
  interruptBeforeNodes?: Array<keyof Nn> | All;
15
16
  }): void;
16
- export declare function validateKeys<Cc extends Record<string, BaseChannel>>(keys: keyof Cc | Array<keyof Cc>, channels: Cc): void;
17
+ export declare function validateKeys<Cc extends Record<string, BaseChannel | ManagedValueSpec>>(keys: keyof Cc | Array<keyof Cc>, channels: Cc): void;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseStore = void 0;
4
+ class BaseStore {
5
+ stop() {
6
+ // no-op if not implemented.
7
+ }
8
+ start() {
9
+ // no-op if not implemented.
10
+ }
11
+ }
12
+ exports.BaseStore = BaseStore;
@@ -0,0 +1,7 @@
1
+ export type Values = Record<string, any>;
2
+ export declare abstract class BaseStore {
3
+ abstract list(prefixes: string[]): Promise<Record<string, Record<string, Values>>>;
4
+ abstract put(writes: Array<[string, string, Values | null]>): Promise<void>;
5
+ stop(): void;
6
+ start(): void;
7
+ }
@@ -0,0 +1,8 @@
1
+ export class BaseStore {
2
+ stop() {
3
+ // no-op if not implemented.
4
+ }
5
+ start() {
6
+ // no-op if not implemented.
7
+ }
8
+ }
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AsyncBatchedStore = void 0;
4
+ const base_js_1 = require("./base.cjs");
5
+ /**
6
+ * AsyncBatchedStore extends BaseStore to provide batched operations for list and put methods.
7
+ * It queues operations and processes them in batches for improved efficiency. This store is
8
+ * designed to run for the full duration of the process, or until `stop()` is called.
9
+ */
10
+ class AsyncBatchedStore extends base_js_1.BaseStore {
11
+ get isRunning() {
12
+ return this.running;
13
+ }
14
+ constructor(store) {
15
+ super();
16
+ /**
17
+ * The store to batch operations for.
18
+ * @type {BaseStore}
19
+ */
20
+ Object.defineProperty(this, "store", {
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true,
24
+ value: void 0
25
+ });
26
+ /**
27
+ * A queue of operations to be processed in batch.
28
+ * @type {QueueItem[]}
29
+ */
30
+ Object.defineProperty(this, "queue", {
31
+ enumerable: true,
32
+ configurable: true,
33
+ writable: true,
34
+ value: []
35
+ });
36
+ /**
37
+ * Whether or not the batched processing is currently running.
38
+ * @type {boolean}
39
+ * @default {false}
40
+ */
41
+ Object.defineProperty(this, "running", {
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true,
45
+ value: false
46
+ });
47
+ this.store = store;
48
+ }
49
+ /**
50
+ * Queues a list operation to be processed in batch.
51
+ * @param {string[]} prefixes An array of prefixes to list.
52
+ * @returns {Promise<Record<string, Record<string, Values>>>} A promise that resolves with the list results.
53
+ */
54
+ async list(prefixes) {
55
+ return new Promise((resolve, reject) => {
56
+ this.queue.push({ resolve, reject, op: { prefixes } });
57
+ });
58
+ }
59
+ /**
60
+ * Queues a put operation to be processed in batch.
61
+ * @param {Array<[string, string, Values | null]>} writes An array of write operations to be performed.
62
+ * @returns {Promise<void>} A promise that resolves when the put operation is complete.
63
+ */
64
+ async put(writes) {
65
+ return new Promise((resolve, reject) => {
66
+ this.queue.push({ resolve, reject, op: { writes } });
67
+ });
68
+ }
69
+ /**
70
+ * Start running the batched processing of operations.
71
+ * This process will run continuously until the store is stopped,
72
+ * which can be done by calling the `stop()` method.
73
+ */
74
+ start() {
75
+ this.running = true;
76
+ void this.processBatchQueue();
77
+ }
78
+ /**
79
+ * Stops the batched processing of operations.
80
+ */
81
+ stop() {
82
+ this.running = false;
83
+ }
84
+ /**
85
+ * Runs the task that processes queued operations in batches.
86
+ * This method runs continuously until the store is stopped,
87
+ * or the process is terminated.
88
+ * @returns {Promise<void>} A promise that resolves when the task is complete.
89
+ */
90
+ async processBatchQueue() {
91
+ while (this.running) {
92
+ await new Promise((resolve) => {
93
+ setTimeout(resolve, 0);
94
+ });
95
+ if (this.queue.length === 0)
96
+ continue;
97
+ const taken = this.queue.splice(0);
98
+ const lists = taken.filter((item) => "prefixes" in item.op);
99
+ if (lists.length > 0) {
100
+ try {
101
+ const allPrefixes = lists.flatMap((item) => item.op.prefixes);
102
+ const results = await this.store.list(allPrefixes);
103
+ lists.forEach((item) => {
104
+ const { prefixes } = item.op;
105
+ item.resolve(Object.fromEntries(prefixes.map((p) => [p, results[p] || {}])));
106
+ });
107
+ }
108
+ catch (e) {
109
+ lists.forEach((item) => item.reject(e));
110
+ }
111
+ }
112
+ const puts = taken.filter((item) => "writes" in item.op);
113
+ if (puts.length > 0) {
114
+ try {
115
+ const allWrites = puts.flatMap((item) => item.op.writes);
116
+ await this.store.put(allWrites);
117
+ puts.forEach((item) => item.resolve());
118
+ }
119
+ catch (e) {
120
+ puts.forEach((item) => item.reject(e));
121
+ }
122
+ }
123
+ }
124
+ }
125
+ }
126
+ exports.AsyncBatchedStore = AsyncBatchedStore;
@@ -0,0 +1,55 @@
1
+ import { BaseStore, type Values } from "./base.js";
2
+ /**
3
+ * AsyncBatchedStore extends BaseStore to provide batched operations for list and put methods.
4
+ * It queues operations and processes them in batches for improved efficiency. This store is
5
+ * designed to run for the full duration of the process, or until `stop()` is called.
6
+ */
7
+ export declare class AsyncBatchedStore extends BaseStore {
8
+ /**
9
+ * The store to batch operations for.
10
+ * @type {BaseStore}
11
+ */
12
+ private store;
13
+ /**
14
+ * A queue of operations to be processed in batch.
15
+ * @type {QueueItem[]}
16
+ */
17
+ private queue;
18
+ /**
19
+ * Whether or not the batched processing is currently running.
20
+ * @type {boolean}
21
+ * @default {false}
22
+ */
23
+ private running;
24
+ get isRunning(): boolean;
25
+ constructor(store: BaseStore);
26
+ /**
27
+ * Queues a list operation to be processed in batch.
28
+ * @param {string[]} prefixes An array of prefixes to list.
29
+ * @returns {Promise<Record<string, Record<string, Values>>>} A promise that resolves with the list results.
30
+ */
31
+ list(prefixes: string[]): Promise<Record<string, Record<string, Values>>>;
32
+ /**
33
+ * Queues a put operation to be processed in batch.
34
+ * @param {Array<[string, string, Values | null]>} writes An array of write operations to be performed.
35
+ * @returns {Promise<void>} A promise that resolves when the put operation is complete.
36
+ */
37
+ put(writes: Array<[string, string, Values | null]>): Promise<void>;
38
+ /**
39
+ * Start running the batched processing of operations.
40
+ * This process will run continuously until the store is stopped,
41
+ * which can be done by calling the `stop()` method.
42
+ */
43
+ start(): void;
44
+ /**
45
+ * Stops the batched processing of operations.
46
+ */
47
+ stop(): void;
48
+ /**
49
+ * Runs the task that processes queued operations in batches.
50
+ * This method runs continuously until the store is stopped,
51
+ * or the process is terminated.
52
+ * @returns {Promise<void>} A promise that resolves when the task is complete.
53
+ */
54
+ private processBatchQueue;
55
+ }
@@ -0,0 +1,122 @@
1
+ import { BaseStore } from "./base.js";
2
+ /**
3
+ * AsyncBatchedStore extends BaseStore to provide batched operations for list and put methods.
4
+ * It queues operations and processes them in batches for improved efficiency. This store is
5
+ * designed to run for the full duration of the process, or until `stop()` is called.
6
+ */
7
+ export class AsyncBatchedStore extends BaseStore {
8
+ get isRunning() {
9
+ return this.running;
10
+ }
11
+ constructor(store) {
12
+ super();
13
+ /**
14
+ * The store to batch operations for.
15
+ * @type {BaseStore}
16
+ */
17
+ Object.defineProperty(this, "store", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: void 0
22
+ });
23
+ /**
24
+ * A queue of operations to be processed in batch.
25
+ * @type {QueueItem[]}
26
+ */
27
+ Object.defineProperty(this, "queue", {
28
+ enumerable: true,
29
+ configurable: true,
30
+ writable: true,
31
+ value: []
32
+ });
33
+ /**
34
+ * Whether or not the batched processing is currently running.
35
+ * @type {boolean}
36
+ * @default {false}
37
+ */
38
+ Object.defineProperty(this, "running", {
39
+ enumerable: true,
40
+ configurable: true,
41
+ writable: true,
42
+ value: false
43
+ });
44
+ this.store = store;
45
+ }
46
+ /**
47
+ * Queues a list operation to be processed in batch.
48
+ * @param {string[]} prefixes An array of prefixes to list.
49
+ * @returns {Promise<Record<string, Record<string, Values>>>} A promise that resolves with the list results.
50
+ */
51
+ async list(prefixes) {
52
+ return new Promise((resolve, reject) => {
53
+ this.queue.push({ resolve, reject, op: { prefixes } });
54
+ });
55
+ }
56
+ /**
57
+ * Queues a put operation to be processed in batch.
58
+ * @param {Array<[string, string, Values | null]>} writes An array of write operations to be performed.
59
+ * @returns {Promise<void>} A promise that resolves when the put operation is complete.
60
+ */
61
+ async put(writes) {
62
+ return new Promise((resolve, reject) => {
63
+ this.queue.push({ resolve, reject, op: { writes } });
64
+ });
65
+ }
66
+ /**
67
+ * Start running the batched processing of operations.
68
+ * This process will run continuously until the store is stopped,
69
+ * which can be done by calling the `stop()` method.
70
+ */
71
+ start() {
72
+ this.running = true;
73
+ void this.processBatchQueue();
74
+ }
75
+ /**
76
+ * Stops the batched processing of operations.
77
+ */
78
+ stop() {
79
+ this.running = false;
80
+ }
81
+ /**
82
+ * Runs the task that processes queued operations in batches.
83
+ * This method runs continuously until the store is stopped,
84
+ * or the process is terminated.
85
+ * @returns {Promise<void>} A promise that resolves when the task is complete.
86
+ */
87
+ async processBatchQueue() {
88
+ while (this.running) {
89
+ await new Promise((resolve) => {
90
+ setTimeout(resolve, 0);
91
+ });
92
+ if (this.queue.length === 0)
93
+ continue;
94
+ const taken = this.queue.splice(0);
95
+ const lists = taken.filter((item) => "prefixes" in item.op);
96
+ if (lists.length > 0) {
97
+ try {
98
+ const allPrefixes = lists.flatMap((item) => item.op.prefixes);
99
+ const results = await this.store.list(allPrefixes);
100
+ lists.forEach((item) => {
101
+ const { prefixes } = item.op;
102
+ item.resolve(Object.fromEntries(prefixes.map((p) => [p, results[p] || {}])));
103
+ });
104
+ }
105
+ catch (e) {
106
+ lists.forEach((item) => item.reject(e));
107
+ }
108
+ }
109
+ const puts = taken.filter((item) => "writes" in item.op);
110
+ if (puts.length > 0) {
111
+ try {
112
+ const allWrites = puts.flatMap((item) => item.op.writes);
113
+ await this.store.put(allWrites);
114
+ puts.forEach((item) => item.resolve());
115
+ }
116
+ catch (e) {
117
+ puts.forEach((item) => item.reject(e));
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./base.cjs"), exports);
18
+ __exportStar(require("./batch.cjs"), exports);
19
+ __exportStar(require("./memory.cjs"), exports);
@@ -0,0 +1,3 @@
1
+ export * from "./base.js";
2
+ export * from "./batch.js";
3
+ export * from "./memory.js";
@@ -0,0 +1,3 @@
1
+ export * from "./base.js";
2
+ export * from "./batch.js";
3
+ export * from "./memory.js";
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MemoryStore = void 0;
4
+ const base_js_1 = require("./base.cjs");
5
+ class MemoryStore extends base_js_1.BaseStore {
6
+ constructor() {
7
+ super(...arguments);
8
+ Object.defineProperty(this, "data", {
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true,
12
+ value: new Map()
13
+ });
14
+ }
15
+ async list(prefixes) {
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ const result = {};
18
+ for (const prefix of prefixes) {
19
+ if (this.data.has(prefix)) {
20
+ result[prefix] = Object.fromEntries(this.data.get(prefix));
21
+ }
22
+ else {
23
+ result[prefix] = {};
24
+ }
25
+ }
26
+ return Promise.resolve(result);
27
+ }
28
+ async put(writes) {
29
+ for (const [namespace, key, value] of writes) {
30
+ if (!this.data.has(namespace)) {
31
+ this.data.set(namespace, new Map());
32
+ }
33
+ const namespaceMap = this.data.get(namespace);
34
+ if (value === null) {
35
+ namespaceMap.delete(key);
36
+ }
37
+ else {
38
+ namespaceMap.set(key, value);
39
+ }
40
+ }
41
+ }
42
+ }
43
+ exports.MemoryStore = MemoryStore;
@@ -0,0 +1,6 @@
1
+ import { BaseStore, type Values } from "./base.js";
2
+ export declare class MemoryStore extends BaseStore {
3
+ private data;
4
+ list(prefixes: string[]): Promise<Record<string, Record<string, Values>>>;
5
+ put(writes: Array<[string, string, Values | null]>): Promise<void>;
6
+ }
@@ -0,0 +1,39 @@
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 list(prefixes) {
13
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
+ const result = {};
15
+ for (const prefix of prefixes) {
16
+ if (this.data.has(prefix)) {
17
+ result[prefix] = Object.fromEntries(this.data.get(prefix));
18
+ }
19
+ else {
20
+ result[prefix] = {};
21
+ }
22
+ }
23
+ return Promise.resolve(result);
24
+ }
25
+ async put(writes) {
26
+ for (const [namespace, key, value] of writes) {
27
+ if (!this.data.has(namespace)) {
28
+ this.data.set(namespace, new Map());
29
+ }
30
+ const namespaceMap = this.data.get(namespace);
31
+ if (value === null) {
32
+ namespaceMap.delete(key);
33
+ }
34
+ else {
35
+ namespaceMap.set(key, value);
36
+ }
37
+ }
38
+ }
39
+ }