@earendil-works/pi-agent-core 0.84.3 → 0.85.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/README.md +4 -0
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +32 -25
- package/dist/agent-loop.js.map +1 -1
- package/dist/harness/agent-harness.d.ts +639 -384
- package/dist/harness/agent-harness.d.ts.map +1 -1
- package/dist/harness/agent-harness.js +5 -251
- package/dist/harness/agent-harness.js.map +1 -1
- package/dist/harness/compaction/branch-summarization.d.ts +12 -6
- package/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/harness/compaction/branch-summarization.js +33 -26
- package/dist/harness/compaction/branch-summarization.js.map +1 -1
- package/dist/harness/compaction/compaction.d.ts +30 -8
- package/dist/harness/compaction/compaction.d.ts.map +1 -1
- package/dist/harness/compaction/compaction.js +53 -63
- package/dist/harness/compaction/compaction.js.map +1 -1
- package/dist/harness/config.d.ts +9 -0
- package/dist/harness/config.d.ts.map +1 -0
- package/dist/harness/config.js +27 -0
- package/dist/harness/config.js.map +1 -0
- package/dist/harness/context.d.ts +9 -0
- package/dist/harness/context.d.ts.map +1 -0
- package/dist/harness/context.js +13 -0
- package/dist/harness/context.js.map +1 -0
- package/dist/harness/env/nodejs.d.ts +24 -28
- package/dist/harness/env/nodejs.d.ts.map +1 -1
- package/dist/harness/env/nodejs.js +242 -87
- package/dist/harness/env/nodejs.js.map +1 -1
- package/dist/harness/events.d.ts +20 -38
- package/dist/harness/events.d.ts.map +1 -1
- package/dist/harness/events.js +240 -55
- package/dist/harness/events.js.map +1 -1
- package/dist/harness/execution/assistant.d.ts +42 -0
- package/dist/harness/execution/assistant.d.ts.map +1 -0
- package/dist/harness/execution/assistant.js +82 -0
- package/dist/harness/execution/assistant.js.map +1 -0
- package/dist/harness/execution/effect-gate.d.ts +22 -0
- package/dist/harness/execution/effect-gate.d.ts.map +1 -0
- package/dist/harness/execution/effect-gate.js +49 -0
- package/dist/harness/execution/effect-gate.js.map +1 -0
- package/dist/harness/execution/tools.d.ts +67 -0
- package/dist/harness/execution/tools.d.ts.map +1 -0
- package/dist/harness/execution/tools.js +121 -0
- package/dist/harness/execution/tools.js.map +1 -0
- package/dist/harness/hooks.d.ts +38 -0
- package/dist/harness/hooks.d.ts.map +1 -0
- package/dist/harness/hooks.js +406 -0
- package/dist/harness/hooks.js.map +1 -0
- package/dist/harness/messages.d.ts +2 -2
- package/dist/harness/messages.d.ts.map +1 -1
- package/dist/harness/messages.js.map +1 -1
- package/dist/harness/prompt-templates.d.ts +3 -2
- package/dist/harness/prompt-templates.d.ts.map +1 -1
- package/dist/harness/prompt-templates.js +17 -17
- package/dist/harness/prompt-templates.js.map +1 -1
- package/dist/harness/result.d.ts +93 -0
- package/dist/harness/result.d.ts.map +1 -1
- package/dist/harness/result.js +40 -0
- package/dist/harness/result.js.map +1 -1
- package/dist/harness/runtime/drive/boundary.d.ts +28 -0
- package/dist/harness/runtime/drive/boundary.d.ts.map +1 -0
- package/dist/harness/runtime/drive/boundary.js +170 -0
- package/dist/harness/runtime/drive/boundary.js.map +1 -0
- package/dist/harness/runtime/drive/checkpoint.d.ts +8 -0
- package/dist/harness/runtime/drive/checkpoint.d.ts.map +1 -0
- package/dist/harness/runtime/drive/checkpoint.js +133 -0
- package/dist/harness/runtime/drive/checkpoint.js.map +1 -0
- package/dist/harness/runtime/drive/deferred.d.ts +15 -0
- package/dist/harness/runtime/drive/deferred.d.ts.map +1 -0
- package/dist/harness/runtime/drive/deferred.js +179 -0
- package/dist/harness/runtime/drive/deferred.js.map +1 -0
- package/dist/harness/runtime/drive/generation.d.ts +8 -0
- package/dist/harness/runtime/drive/generation.d.ts.map +1 -0
- package/dist/harness/runtime/drive/generation.js +205 -0
- package/dist/harness/runtime/drive/generation.js.map +1 -0
- package/dist/harness/runtime/drive/reconcile.d.ts +5 -0
- package/dist/harness/runtime/drive/reconcile.d.ts.map +1 -0
- package/dist/harness/runtime/drive/reconcile.js +140 -0
- package/dist/harness/runtime/drive/reconcile.js.map +1 -0
- package/dist/harness/runtime/drive/recovery.d.ts +8 -0
- package/dist/harness/runtime/drive/recovery.d.ts.map +1 -0
- package/dist/harness/runtime/drive/recovery.js +85 -0
- package/dist/harness/runtime/drive/recovery.js.map +1 -0
- package/dist/harness/runtime/drive/response.d.ts +23 -0
- package/dist/harness/runtime/drive/response.d.ts.map +1 -0
- package/dist/harness/runtime/drive/response.js +394 -0
- package/dist/harness/runtime/drive/response.js.map +1 -0
- package/dist/harness/runtime/drive/retry.d.ts +4 -0
- package/dist/harness/runtime/drive/retry.d.ts.map +1 -0
- package/dist/harness/runtime/drive/retry.js +37 -0
- package/dist/harness/runtime/drive/retry.js.map +1 -0
- package/dist/harness/runtime/drive/structural.d.ts +32 -0
- package/dist/harness/runtime/drive/structural.d.ts.map +1 -0
- package/dist/harness/runtime/drive/structural.js +929 -0
- package/dist/harness/runtime/drive/structural.js.map +1 -0
- package/dist/harness/runtime/drive/terminal.d.ts +7 -0
- package/dist/harness/runtime/drive/terminal.d.ts.map +1 -0
- package/dist/harness/runtime/drive/terminal.js +49 -0
- package/dist/harness/runtime/drive/terminal.js.map +1 -0
- package/dist/harness/runtime/drive/tool-placement.d.ts +14 -0
- package/dist/harness/runtime/drive/tool-placement.d.ts.map +1 -0
- package/dist/harness/runtime/drive/tool-placement.js +244 -0
- package/dist/harness/runtime/drive/tool-placement.js.map +1 -0
- package/dist/harness/runtime/drive/tools.d.ts +6 -0
- package/dist/harness/runtime/drive/tools.d.ts.map +1 -0
- package/dist/harness/runtime/drive/tools.js +449 -0
- package/dist/harness/runtime/drive/tools.js.map +1 -0
- package/dist/harness/runtime/drive.d.ts +6 -0
- package/dist/harness/runtime/drive.d.ts.map +1 -0
- package/dist/harness/runtime/drive.js +93 -0
- package/dist/harness/runtime/drive.js.map +1 -0
- package/dist/harness/runtime/harness.d.ts +59 -0
- package/dist/harness/runtime/harness.d.ts.map +1 -0
- package/dist/harness/runtime/harness.js +311 -0
- package/dist/harness/runtime/harness.js.map +1 -0
- package/dist/harness/runtime/index.d.ts +2 -0
- package/dist/harness/runtime/index.d.ts.map +1 -0
- package/dist/harness/runtime/index.js +2 -0
- package/dist/harness/runtime/index.js.map +1 -0
- package/dist/harness/runtime/lane.d.ts +101 -0
- package/dist/harness/runtime/lane.d.ts.map +1 -0
- package/dist/harness/runtime/lane.js +1575 -0
- package/dist/harness/runtime/lane.js.map +1 -0
- package/dist/harness/runtime/progress.d.ts +15 -0
- package/dist/harness/runtime/progress.d.ts.map +1 -0
- package/dist/harness/runtime/progress.js +66 -0
- package/dist/harness/runtime/progress.js.map +1 -0
- package/dist/harness/runtime/reducer.d.ts +5 -0
- package/dist/harness/runtime/reducer.d.ts.map +1 -0
- package/dist/harness/runtime/reducer.js +240 -0
- package/dist/harness/runtime/reducer.js.map +1 -0
- package/dist/harness/runtime/restore.d.ts +24 -0
- package/dist/harness/runtime/restore.d.ts.map +1 -0
- package/dist/harness/runtime/restore.js +117 -0
- package/dist/harness/runtime/restore.js.map +1 -0
- package/dist/harness/runtime/transcript.d.ts +21 -0
- package/dist/harness/runtime/transcript.d.ts.map +1 -0
- package/dist/harness/runtime/transcript.js +72 -0
- package/dist/harness/runtime/transcript.js.map +1 -0
- package/dist/harness/runtime/types.d.ts +105 -0
- package/dist/harness/runtime/types.d.ts.map +1 -0
- package/dist/harness/runtime/types.js +61 -0
- package/dist/harness/runtime/types.js.map +1 -0
- package/dist/harness/session/commit.d.ts +53 -0
- package/dist/harness/session/commit.d.ts.map +1 -0
- package/dist/harness/session/commit.js +57 -0
- package/dist/harness/session/commit.js.map +1 -0
- package/dist/harness/session/context.d.ts +6 -18
- package/dist/harness/session/context.d.ts.map +1 -1
- package/dist/harness/session/context.js +31 -49
- package/dist/harness/session/context.js.map +1 -1
- package/dist/harness/session/fork-policy.d.ts +13 -0
- package/dist/harness/session/fork-policy.d.ts.map +1 -0
- package/dist/harness/session/fork-policy.js +22 -0
- package/dist/harness/session/fork-policy.js.map +1 -0
- package/dist/harness/session/fork.d.ts +18 -0
- package/dist/harness/session/fork.d.ts.map +1 -0
- package/dist/harness/session/fork.js +127 -0
- package/dist/harness/session/fork.js.map +1 -0
- package/dist/harness/session/in-memory-storage-state.d.ts +39 -0
- package/dist/harness/session/in-memory-storage-state.d.ts.map +1 -0
- package/dist/harness/session/in-memory-storage-state.js +216 -0
- package/dist/harness/session/in-memory-storage-state.js.map +1 -0
- package/dist/harness/session/index.d.ts +9 -5
- package/dist/harness/session/index.d.ts.map +1 -1
- package/dist/harness/session/index.js +7 -4
- package/dist/harness/session/index.js.map +1 -1
- package/dist/harness/session/jsonl/codec.d.ts +19 -8
- package/dist/harness/session/jsonl/codec.d.ts.map +1 -1
- package/dist/harness/session/jsonl/codec.js +34 -218
- package/dist/harness/session/jsonl/codec.js.map +1 -1
- package/dist/harness/session/jsonl/index.d.ts +4 -0
- package/dist/harness/session/jsonl/index.d.ts.map +1 -0
- package/dist/harness/session/jsonl/index.js +4 -0
- package/dist/harness/session/jsonl/index.js.map +1 -0
- package/dist/harness/session/jsonl/legacy-v3.d.ts +18 -0
- package/dist/harness/session/jsonl/legacy-v3.d.ts.map +1 -0
- package/dist/harness/session/jsonl/legacy-v3.js +383 -0
- package/dist/harness/session/jsonl/legacy-v3.js.map +1 -0
- package/dist/harness/session/jsonl/repo.d.ts +26 -19
- package/dist/harness/session/jsonl/repo.d.ts.map +1 -1
- package/dist/harness/session/jsonl/repo.js +266 -156
- package/dist/harness/session/jsonl/repo.js.map +1 -1
- package/dist/harness/session/jsonl/storage.d.ts +39 -41
- package/dist/harness/session/jsonl/storage.d.ts.map +1 -1
- package/dist/harness/session/jsonl/storage.js +238 -181
- package/dist/harness/session/jsonl/storage.js.map +1 -1
- package/dist/harness/session/jsonl/types.d.ts +23 -22
- package/dist/harness/session/jsonl/types.d.ts.map +1 -1
- package/dist/harness/session/jsonl/types.js +2 -1
- package/dist/harness/session/jsonl/types.js.map +1 -1
- package/dist/harness/session/memory.d.ts +46 -40
- package/dist/harness/session/memory.d.ts.map +1 -1
- package/dist/harness/session/memory.js +346 -113
- package/dist/harness/session/memory.js.map +1 -1
- package/dist/harness/session/mutation-line.d.ts +8 -0
- package/dist/harness/session/mutation-line.d.ts.map +1 -0
- package/dist/harness/session/mutation-line.js +21 -0
- package/dist/harness/session/mutation-line.js.map +1 -0
- package/dist/harness/session/session.d.ts +78 -46
- package/dist/harness/session/session.d.ts.map +1 -1
- package/dist/harness/session/session.js +343 -209
- package/dist/harness/session/session.js.map +1 -1
- package/dist/harness/session/testing/benchmark/datasets.d.ts +12 -0
- package/dist/harness/session/testing/benchmark/datasets.d.ts.map +1 -0
- package/dist/harness/session/testing/benchmark/datasets.js +24 -0
- package/dist/harness/session/testing/benchmark/datasets.js.map +1 -0
- package/dist/harness/session/testing/benchmark/session-repo.d.ts +42 -0
- package/dist/harness/session/testing/benchmark/session-repo.d.ts.map +1 -0
- package/dist/harness/session/testing/benchmark/session-repo.js +127 -0
- package/dist/harness/session/testing/benchmark/session-repo.js.map +1 -0
- package/dist/harness/session/testing/benchmark/storage.d.ts +25 -0
- package/dist/harness/session/testing/benchmark/storage.d.ts.map +1 -0
- package/dist/harness/session/testing/benchmark/storage.js +114 -0
- package/dist/harness/session/testing/benchmark/storage.js.map +1 -0
- package/dist/harness/session/testing/conformance/session-repo.d.ts +21 -0
- package/dist/harness/session/testing/conformance/session-repo.d.ts.map +1 -0
- package/dist/harness/session/testing/conformance/session-repo.js +590 -0
- package/dist/harness/session/testing/conformance/session-repo.js.map +1 -0
- package/dist/harness/session/testing/conformance/storage.d.ts +4 -0
- package/dist/harness/session/testing/conformance/storage.d.ts.map +1 -0
- package/dist/harness/session/testing/conformance/storage.js +600 -0
- package/dist/harness/session/testing/conformance/storage.js.map +1 -0
- package/dist/harness/session/testing/gating-storage.d.ts +26 -0
- package/dist/harness/session/testing/gating-storage.d.ts.map +1 -0
- package/dist/harness/session/testing/gating-storage.js +100 -0
- package/dist/harness/session/testing/gating-storage.js.map +1 -0
- package/dist/harness/session/testing/index.d.ts +9 -2
- package/dist/harness/session/testing/index.d.ts.map +1 -1
- package/dist/harness/session/testing/index.js +8 -1
- package/dist/harness/session/testing/index.js.map +1 -1
- package/dist/harness/session/testing/instrumented-storage.d.ts +11 -0
- package/dist/harness/session/testing/instrumented-storage.d.ts.map +1 -0
- package/dist/harness/session/testing/instrumented-storage.js +16 -0
- package/dist/harness/session/testing/instrumented-storage.js.map +1 -0
- package/dist/harness/session/testing/storage-decorator.d.ts +20 -0
- package/dist/harness/session/testing/storage-decorator.d.ts.map +1 -0
- package/dist/harness/session/testing/storage-decorator.js +41 -0
- package/dist/harness/session/testing/storage-decorator.js.map +1 -0
- package/dist/harness/session/testing/types.d.ts +5 -7
- package/dist/harness/session/testing/types.d.ts.map +1 -1
- package/dist/harness/session/testing/types.js.map +1 -1
- package/dist/harness/session/types.d.ts +424 -259
- package/dist/harness/session/types.d.ts.map +1 -1
- package/dist/harness/session/types.js +7 -8
- package/dist/harness/session/types.js.map +1 -1
- package/dist/harness/session/values.d.ts +95 -0
- package/dist/harness/session/values.d.ts.map +1 -0
- package/dist/harness/session/values.js +81 -0
- package/dist/harness/session/values.js.map +1 -0
- package/dist/harness/skills.d.ts +3 -2
- package/dist/harness/skills.d.ts.map +1 -1
- package/dist/harness/skills.js +29 -26
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/telemetry.d.ts +64 -43
- package/dist/harness/telemetry.d.ts.map +1 -1
- package/dist/harness/telemetry.js +45 -26
- package/dist/harness/telemetry.js.map +1 -1
- package/dist/harness/tools/bash.d.ts +4 -4
- package/dist/harness/tools/bash.d.ts.map +1 -1
- package/dist/harness/tools/bash.js +66 -93
- package/dist/harness/tools/bash.js.map +1 -1
- package/dist/harness/tools/edit.d.ts.map +1 -1
- package/dist/harness/tools/edit.js +10 -10
- package/dist/harness/tools/edit.js.map +1 -1
- package/dist/harness/tools/file-mutation-queue.d.ts +2 -1
- package/dist/harness/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/harness/tools/file-mutation-queue.js +5 -5
- package/dist/harness/tools/file-mutation-queue.js.map +1 -1
- package/dist/harness/tools/path-utils.d.ts +3 -2
- package/dist/harness/tools/path-utils.d.ts.map +1 -1
- package/dist/harness/tools/path-utils.js +5 -5
- package/dist/harness/tools/path-utils.js.map +1 -1
- package/dist/harness/tools/read.d.ts +2 -1
- package/dist/harness/tools/read.d.ts.map +1 -1
- package/dist/harness/tools/read.js +4 -6
- package/dist/harness/tools/read.js.map +1 -1
- package/dist/harness/tools/write.d.ts.map +1 -1
- package/dist/harness/tools/write.js +7 -7
- package/dist/harness/tools/write.js.map +1 -1
- package/dist/harness/types.d.ts +108 -45
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/utils/adaptive-publisher.d.ts +24 -0
- package/dist/harness/utils/adaptive-publisher.d.ts.map +1 -0
- package/dist/harness/utils/adaptive-publisher.js +79 -0
- package/dist/harness/utils/adaptive-publisher.js.map +1 -0
- package/dist/harness/utils/output-capture.d.ts +31 -0
- package/dist/harness/utils/output-capture.d.ts.map +1 -0
- package/dist/harness/utils/output-capture.js +217 -0
- package/dist/harness/utils/output-capture.js.map +1 -0
- package/dist/harness/utils/shell-output.d.ts +12 -5
- package/dist/harness/utils/shell-output.d.ts.map +1 -1
- package/dist/harness/utils/shell-output.js +64 -174
- package/dist/harness/utils/shell-output.js.map +1 -1
- package/dist/harness/utils/truncate.d.ts +1 -0
- package/dist/harness/utils/truncate.d.ts.map +1 -1
- package/dist/harness/utils/truncate.js +1 -1
- package/dist/harness/utils/truncate.js.map +1 -1
- package/dist/harness/utils/usage.d.ts +4 -0
- package/dist/harness/utils/usage.d.ts.map +1 -0
- package/dist/harness/utils/usage.js +33 -0
- package/dist/harness/utils/usage.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -6
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts +2 -0
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +40 -10
- package/dist/proxy.js.map +1 -1
- package/dist/search/index.d.ts +24 -16
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +1 -1
- package/dist/search/index.js.map +1 -1
- package/dist/types.d.ts +5 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +25 -4
- package/dist/harness/reducer.d.ts +0 -100
- package/dist/harness/reducer.d.ts.map +0 -1
- package/dist/harness/reducer.js +0 -415
- package/dist/harness/reducer.js.map +0 -1
- package/dist/harness/session/jsonl/errors.d.ts +0 -9
- package/dist/harness/session/jsonl/errors.d.ts.map +0 -1
- package/dist/harness/session/jsonl/errors.js +0 -19
- package/dist/harness/session/jsonl/errors.js.map +0 -1
- package/dist/harness/session/jsonl.d.ts +0 -3
- package/dist/harness/session/jsonl.d.ts.map +0 -1
- package/dist/harness/session/jsonl.js +0 -2
- package/dist/harness/session/jsonl.js.map +0 -1
- package/dist/harness/session/state.d.ts +0 -65
- package/dist/harness/session/state.d.ts.map +0 -1
- package/dist/harness/session/state.js +0 -319
- package/dist/harness/session/state.js.map +0 -1
- package/dist/harness/session/testing/conformance.d.ts +0 -4
- package/dist/harness/session/testing/conformance.d.ts.map +0 -1
- package/dist/harness/session/testing/conformance.js +0 -762
- package/dist/harness/session/testing/conformance.js.map +0 -1
- package/dist/search/scanning.d.ts +0 -29
- package/dist/search/scanning.d.ts.map +0 -1
- package/dist/search/scanning.js +0 -103
- package/dist/search/scanning.js.map +0 -1
|
@@ -1,141 +1,374 @@
|
|
|
1
|
-
import { uuidv7 } from "@earendil-works/pi-ai";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
export class
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import { uuidv7 } from "@earendil-works/pi-ai/utils/uuid";
|
|
2
|
+
import { createForkSnapshot, forkSnapshotWrites, } from "./fork.js";
|
|
3
|
+
import { InMemoryStorageState } from "./in-memory-storage-state.js";
|
|
4
|
+
import { StorageBackedSession } from "./session.js";
|
|
5
|
+
export class MemoryStorage {
|
|
6
|
+
now;
|
|
7
|
+
storageState = new InMemoryStorageState();
|
|
8
|
+
commitQueue = Promise.resolve();
|
|
9
|
+
state = "open";
|
|
10
|
+
closePromise;
|
|
11
|
+
constructor(options = {}) {
|
|
12
|
+
this.now = options.now ?? Date.now;
|
|
13
|
+
}
|
|
14
|
+
async commit(writes, _context) {
|
|
15
|
+
if (this.state !== "open")
|
|
16
|
+
throw new Error("MemoryStorage is closed");
|
|
17
|
+
const result = this.commitQueue.then(() => {
|
|
18
|
+
const prepared = this.storageState.prepareCommit(writes, this.now());
|
|
19
|
+
const stats = this.storageState.applyValidated(prepared.writes);
|
|
20
|
+
return { ...prepared.result, stats };
|
|
21
|
+
});
|
|
22
|
+
this.commitQueue = result.then(() => undefined, () => undefined);
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
getEntries(ids, _context) {
|
|
26
|
+
if (this.state !== "open")
|
|
27
|
+
return Promise.reject(new Error("MemoryStorage is closed"));
|
|
28
|
+
return Promise.resolve(this.storageState.getEntries(ids));
|
|
29
|
+
}
|
|
30
|
+
getValue(address, _context) {
|
|
31
|
+
if (this.state !== "open")
|
|
32
|
+
return Promise.reject(new Error("MemoryStorage is closed"));
|
|
33
|
+
return Promise.resolve(this.storageState.getValue(address));
|
|
34
|
+
}
|
|
35
|
+
scanValues(prefix, _context) {
|
|
36
|
+
if (this.state !== "open")
|
|
37
|
+
return Promise.reject(new Error("MemoryStorage is closed"));
|
|
38
|
+
return Promise.resolve(this.storageState.scanValues(prefix));
|
|
39
|
+
}
|
|
40
|
+
async readList(address, options, _context) {
|
|
41
|
+
if (this.state !== "open")
|
|
42
|
+
throw new Error("MemoryStorage is closed");
|
|
43
|
+
return this.storageState.readList(address, options);
|
|
44
|
+
}
|
|
45
|
+
async scanBranch(query, _context) {
|
|
46
|
+
if (this.state !== "open")
|
|
47
|
+
throw new Error("MemoryStorage is closed");
|
|
48
|
+
return this.storageState.scanBranch(query);
|
|
49
|
+
}
|
|
50
|
+
async scanBranchStructure(query, _context) {
|
|
51
|
+
if (this.state !== "open")
|
|
52
|
+
throw new Error("MemoryStorage is closed");
|
|
53
|
+
return this.storageState.scanBranchStructure(query);
|
|
54
|
+
}
|
|
55
|
+
scanEntries(query, _context) {
|
|
56
|
+
if (this.state !== "open")
|
|
57
|
+
return Promise.reject(new Error("MemoryStorage is closed"));
|
|
58
|
+
return Promise.resolve(this.storageState.scanEntries(query));
|
|
59
|
+
}
|
|
60
|
+
scanUsage(query, _context) {
|
|
61
|
+
if (this.state !== "open")
|
|
62
|
+
return Promise.reject(new Error("MemoryStorage is closed"));
|
|
63
|
+
return Promise.resolve(this.storageState.scanUsage(query));
|
|
64
|
+
}
|
|
65
|
+
getStats(_context) {
|
|
66
|
+
if (this.state !== "open")
|
|
67
|
+
return Promise.reject(new Error("MemoryStorage is closed"));
|
|
68
|
+
return Promise.resolve(this.storageState.getStats());
|
|
69
|
+
}
|
|
70
|
+
/** Capture the state needed to fork at one serialized boundary between commits. */
|
|
71
|
+
captureForkSource(_context) {
|
|
72
|
+
if (this.state !== "open")
|
|
73
|
+
return Promise.reject(new Error("MemoryStorage is closed"));
|
|
74
|
+
const result = this.commitQueue.then(() => this.storageState.snapshotEntriesAndValues());
|
|
75
|
+
this.commitQueue = result.then(() => undefined, () => undefined);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
close(_context) {
|
|
79
|
+
if (this.closePromise !== undefined)
|
|
80
|
+
return this.closePromise;
|
|
81
|
+
this.state = "closing";
|
|
82
|
+
this.closePromise = this.commitQueue.then(() => {
|
|
83
|
+
this.state = "closed";
|
|
84
|
+
});
|
|
85
|
+
return this.closePromise;
|
|
86
|
+
}
|
|
87
|
+
static fromSnapshot(options, snapshot) {
|
|
88
|
+
const storage = new MemoryStorage(options);
|
|
89
|
+
const writes = forkSnapshotWrites(snapshot);
|
|
90
|
+
storage.storageState.validateCommitted(writes);
|
|
91
|
+
storage.storageState.applyValidated(writes);
|
|
15
92
|
return storage;
|
|
16
93
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.
|
|
30
|
-
this.
|
|
31
|
-
this.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (
|
|
50
|
-
|
|
94
|
+
}
|
|
95
|
+
const MEMORY_STORAGE_VERSION = 1;
|
|
96
|
+
class MemorySessionFacade {
|
|
97
|
+
metadata;
|
|
98
|
+
idGenerator;
|
|
99
|
+
session;
|
|
100
|
+
onClose;
|
|
101
|
+
admitted = new Set();
|
|
102
|
+
closedError = new Error("Session is closed");
|
|
103
|
+
state = "open";
|
|
104
|
+
closePromise;
|
|
105
|
+
constructor(session, onClose) {
|
|
106
|
+
this.session = session;
|
|
107
|
+
this.metadata = session.metadata;
|
|
108
|
+
this.idGenerator = session.idGenerator;
|
|
109
|
+
this.onClose = onClose;
|
|
110
|
+
}
|
|
111
|
+
async beginMutation(context) {
|
|
112
|
+
let resolveFinished;
|
|
113
|
+
const finished = new Promise((resolve) => {
|
|
114
|
+
resolveFinished = resolve;
|
|
115
|
+
});
|
|
116
|
+
this.admitted.add(finished);
|
|
117
|
+
let source;
|
|
118
|
+
try {
|
|
119
|
+
source = await this.admit(() => this.session.beginMutation(context));
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
this.admitted.delete(finished);
|
|
123
|
+
resolveFinished();
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
if (this.state !== "open") {
|
|
127
|
+
await source.end(context);
|
|
128
|
+
this.admitted.delete(finished);
|
|
129
|
+
resolveFinished();
|
|
130
|
+
throw this.closedError;
|
|
51
131
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
132
|
+
let ended = false;
|
|
133
|
+
return {
|
|
134
|
+
commit: (writes, commitContext) => source.commit(writes, commitContext),
|
|
135
|
+
end: async (endContext) => {
|
|
136
|
+
try {
|
|
137
|
+
await source.end(endContext);
|
|
138
|
+
}
|
|
139
|
+
finally {
|
|
140
|
+
if (!ended) {
|
|
141
|
+
ended = true;
|
|
142
|
+
this.admitted.delete(finished);
|
|
143
|
+
resolveFinished();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
getEntries: (ids, readContext) => source.getEntries(ids, readContext),
|
|
148
|
+
getStats: (readContext) => source.getStats(readContext),
|
|
149
|
+
getValue: (address, readContext) => source.getValue(address, readContext),
|
|
150
|
+
scanValues: (prefix, readContext) => source.scanValues(prefix, readContext),
|
|
151
|
+
readList: (address, options, readContext) => source.readList(address, options, readContext),
|
|
152
|
+
scanBranch: (query, readContext) => source.scanBranch(query, readContext),
|
|
56
153
|
};
|
|
57
|
-
this.state.applyMutation({ kind: "record", record });
|
|
58
|
-
return structuredClone(record);
|
|
59
154
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
155
|
+
mutate(mutation, context) {
|
|
156
|
+
return this.admit(() => this.session.mutate((mutator, mutationContext) => {
|
|
157
|
+
if (this.state !== "open")
|
|
158
|
+
throw this.closedError;
|
|
159
|
+
return mutation(mutator, mutationContext);
|
|
160
|
+
}, context));
|
|
161
|
+
}
|
|
162
|
+
getEntries(ids, context) {
|
|
163
|
+
return this.admit(() => this.session.getEntries(ids, context));
|
|
164
|
+
}
|
|
165
|
+
getEntry(id, context) {
|
|
166
|
+
return this.admit(() => this.session.getEntry(id, context));
|
|
167
|
+
}
|
|
168
|
+
getValue(address, context) {
|
|
169
|
+
return this.admit(() => this.session.getValue(address, context));
|
|
63
170
|
}
|
|
64
|
-
|
|
65
|
-
return
|
|
171
|
+
scanValues(prefix, context) {
|
|
172
|
+
return this.admit(() => this.session.scanValues(prefix, context));
|
|
66
173
|
}
|
|
67
|
-
|
|
68
|
-
return
|
|
174
|
+
readList(address, options, context) {
|
|
175
|
+
return this.admit(() => this.session.readList(address, options, context));
|
|
69
176
|
}
|
|
70
|
-
|
|
71
|
-
return
|
|
177
|
+
scanBranch(query, context) {
|
|
178
|
+
return this.admit(() => this.session.scanBranch(query, context));
|
|
72
179
|
}
|
|
73
|
-
|
|
74
|
-
return
|
|
180
|
+
getStats(context) {
|
|
181
|
+
return this.admit(() => this.session.getStats(context));
|
|
75
182
|
}
|
|
76
|
-
|
|
77
|
-
return
|
|
183
|
+
getName(context) {
|
|
184
|
+
return this.admit(() => this.session.getName(context));
|
|
78
185
|
}
|
|
79
|
-
|
|
80
|
-
return this.
|
|
186
|
+
getLabel(targetId, context) {
|
|
187
|
+
return this.admit(() => this.session.getLabel(targetId, context));
|
|
81
188
|
}
|
|
82
|
-
|
|
83
|
-
this.
|
|
189
|
+
findEntries(query, context) {
|
|
190
|
+
return this.admit(() => this.session.findEntries(query, context));
|
|
84
191
|
}
|
|
85
|
-
|
|
86
|
-
return this.
|
|
192
|
+
findEntry(query, context) {
|
|
193
|
+
return this.admit(() => this.session.findEntry(query, context));
|
|
87
194
|
}
|
|
88
|
-
async
|
|
89
|
-
this.
|
|
90
|
-
this.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
195
|
+
async branch(name, context) {
|
|
196
|
+
const branch = await this.admit(() => this.session.branch(name, context));
|
|
197
|
+
return branch === undefined ? undefined : this.wrapBranch(branch);
|
|
198
|
+
}
|
|
199
|
+
async createBranch(name, at, context) {
|
|
200
|
+
return this.wrapBranch(await this.admit(() => this.session.createBranch(name, at, context)));
|
|
201
|
+
}
|
|
202
|
+
setValue(address, next, context) {
|
|
203
|
+
return this.admit(() => this.session.setValue(address, next, context));
|
|
204
|
+
}
|
|
205
|
+
deleteValue(address, context) {
|
|
206
|
+
return this.admit(() => this.session.deleteValue(address, context));
|
|
207
|
+
}
|
|
208
|
+
appendList(address, element, context) {
|
|
209
|
+
return this.admit(() => this.session.appendList(address, element, context));
|
|
210
|
+
}
|
|
211
|
+
deleteList(address, context) {
|
|
212
|
+
return this.admit(() => this.session.deleteList(address, context));
|
|
213
|
+
}
|
|
214
|
+
setName(name, context) {
|
|
215
|
+
return this.admit(() => this.session.setName(name, context));
|
|
216
|
+
}
|
|
217
|
+
setLabel(targetId, label, context) {
|
|
218
|
+
return this.admit(() => this.session.setLabel(targetId, label, context));
|
|
219
|
+
}
|
|
220
|
+
close(_context) {
|
|
221
|
+
if (this.closePromise !== undefined)
|
|
222
|
+
return this.closePromise;
|
|
223
|
+
this.state = "closing";
|
|
224
|
+
this.closePromise = Promise.allSettled([...this.admitted]).then(() => {
|
|
225
|
+
this.state = "closed";
|
|
226
|
+
this.onClose();
|
|
96
227
|
});
|
|
228
|
+
return this.closePromise;
|
|
229
|
+
}
|
|
230
|
+
wrapBranch(branch) {
|
|
231
|
+
return {
|
|
232
|
+
name: branch.name,
|
|
233
|
+
getTipId: (context) => this.admit(() => branch.getTipId(context)),
|
|
234
|
+
findEntries: (query, context) => this.admit(() => branch.findEntries(query, context)),
|
|
235
|
+
findEntry: (query, context) => this.admit(() => branch.findEntry(query, context)),
|
|
236
|
+
appendMessage: (message, context) => this.admit(() => branch.appendMessage(message, context)),
|
|
237
|
+
appendCustomEntry: (customType, data, context) => this.admit(() => branch.appendCustomEntry(customType, data, context)),
|
|
238
|
+
};
|
|
97
239
|
}
|
|
98
|
-
|
|
99
|
-
|
|
240
|
+
admit(operation) {
|
|
241
|
+
if (this.state !== "open")
|
|
242
|
+
return Promise.reject(this.closedError);
|
|
243
|
+
let result;
|
|
244
|
+
try {
|
|
245
|
+
result = operation();
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
result = Promise.reject(error);
|
|
249
|
+
}
|
|
250
|
+
this.admitted.add(result);
|
|
251
|
+
void result.then(() => this.admitted.delete(result), () => this.admitted.delete(result));
|
|
252
|
+
return result;
|
|
100
253
|
}
|
|
101
254
|
}
|
|
102
|
-
export class
|
|
255
|
+
export class MemorySessionRepo {
|
|
256
|
+
now;
|
|
103
257
|
sessions = new Map();
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
258
|
+
pendingIds = new Set();
|
|
259
|
+
closed = false;
|
|
260
|
+
closePromise;
|
|
261
|
+
constructor(options = {}) {
|
|
262
|
+
this.now = options.now ?? Date.now;
|
|
263
|
+
}
|
|
264
|
+
async create(options, context) {
|
|
265
|
+
this.assertOpen();
|
|
266
|
+
const createdAt = this.now();
|
|
267
|
+
const id = options.id ?? uuidv7(createdAt);
|
|
268
|
+
this.reserveId(id);
|
|
269
|
+
const metadata = {
|
|
109
270
|
id,
|
|
110
|
-
createdAt
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
271
|
+
createdAt,
|
|
272
|
+
storageVersion: MEMORY_STORAGE_VERSION,
|
|
273
|
+
...(options.parentSessionId === undefined ? {} : { parentSessionId: options.parentSessionId }),
|
|
274
|
+
};
|
|
275
|
+
const storage = new MemoryStorage({ now: this.now });
|
|
276
|
+
const session = new StorageBackedSession(metadata, storage);
|
|
277
|
+
try {
|
|
278
|
+
const record = {
|
|
279
|
+
metadata,
|
|
280
|
+
storage,
|
|
281
|
+
session,
|
|
282
|
+
open: true,
|
|
283
|
+
};
|
|
284
|
+
this.sessions.set(id, record);
|
|
285
|
+
return this.openRecord(record);
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
await session.close(context);
|
|
289
|
+
throw error;
|
|
290
|
+
}
|
|
291
|
+
finally {
|
|
292
|
+
this.pendingIds.delete(id);
|
|
293
|
+
}
|
|
115
294
|
}
|
|
116
|
-
|
|
117
|
-
|
|
295
|
+
open(metadata, _context) {
|
|
296
|
+
// Memory sessions are always created at the current storage version, so
|
|
297
|
+
// persistent-backend version gating does not apply here.
|
|
298
|
+
this.assertOpen();
|
|
299
|
+
const record = this.sessions.get(metadata.id);
|
|
300
|
+
if (record === undefined)
|
|
301
|
+
return Promise.reject(new Error(`Unknown session: ${metadata.id}`));
|
|
302
|
+
if (record.open)
|
|
303
|
+
return Promise.reject(new Error(`Session is already open: ${metadata.id}`));
|
|
304
|
+
record.open = true;
|
|
305
|
+
return Promise.resolve(this.openRecord(record));
|
|
118
306
|
}
|
|
119
|
-
|
|
120
|
-
|
|
307
|
+
list(_options, _context) {
|
|
308
|
+
this.assertOpen();
|
|
309
|
+
return Promise.resolve([...this.sessions.values()].map(({ metadata }) => metadata));
|
|
121
310
|
}
|
|
122
|
-
async delete(metadata) {
|
|
311
|
+
async delete(metadata, context) {
|
|
312
|
+
this.assertOpen();
|
|
313
|
+
const record = this.sessions.get(metadata.id);
|
|
314
|
+
if (record === undefined)
|
|
315
|
+
throw new Error(`Unknown session: ${metadata.id}`);
|
|
316
|
+
if (record.open)
|
|
317
|
+
throw new Error(`Session is open: ${metadata.id}`);
|
|
318
|
+
await record.session.close(context);
|
|
123
319
|
this.sessions.delete(metadata.id);
|
|
124
320
|
}
|
|
125
|
-
async fork(source, options
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
if (
|
|
129
|
-
throw new
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
321
|
+
async fork(source, options, context) {
|
|
322
|
+
this.assertOpen();
|
|
323
|
+
const sourceRecord = this.sessions.get(source.id);
|
|
324
|
+
if (sourceRecord === undefined)
|
|
325
|
+
throw new Error(`Unknown session: ${source.id}`);
|
|
326
|
+
const createdAt = this.now();
|
|
327
|
+
const id = options.id ?? uuidv7(createdAt);
|
|
328
|
+
this.reserveId(id);
|
|
329
|
+
try {
|
|
330
|
+
const snapshot = createForkSnapshot(await sourceRecord.storage.captureForkSource(context), options);
|
|
331
|
+
const storage = MemoryStorage.fromSnapshot({ now: this.now }, snapshot);
|
|
332
|
+
const metadata = {
|
|
333
|
+
id,
|
|
334
|
+
createdAt,
|
|
335
|
+
storageVersion: MEMORY_STORAGE_VERSION,
|
|
336
|
+
parentSessionId: sourceRecord.metadata.id,
|
|
337
|
+
};
|
|
338
|
+
const session = new StorageBackedSession(metadata, storage);
|
|
339
|
+
const record = {
|
|
340
|
+
metadata,
|
|
341
|
+
storage,
|
|
342
|
+
session,
|
|
343
|
+
open: true,
|
|
344
|
+
};
|
|
345
|
+
this.sessions.set(id, record);
|
|
346
|
+
return this.openRecord(record);
|
|
347
|
+
}
|
|
348
|
+
finally {
|
|
349
|
+
this.pendingIds.delete(id);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
close(context) {
|
|
353
|
+
if (this.closePromise !== undefined)
|
|
354
|
+
return this.closePromise;
|
|
355
|
+
this.closed = true;
|
|
356
|
+
this.closePromise = Promise.all([...this.sessions.values()].map(({ session }) => session.close(context))).then(() => undefined);
|
|
357
|
+
return this.closePromise;
|
|
358
|
+
}
|
|
359
|
+
openRecord(record) {
|
|
360
|
+
return new MemorySessionFacade(record.session, () => {
|
|
361
|
+
record.open = false;
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
reserveId(id) {
|
|
365
|
+
if (this.sessions.has(id) || this.pendingIds.has(id))
|
|
366
|
+
throw new Error(`Session already exists: ${id}`);
|
|
367
|
+
this.pendingIds.add(id);
|
|
368
|
+
}
|
|
369
|
+
assertOpen() {
|
|
370
|
+
if (this.closed)
|
|
371
|
+
throw new Error("MemorySessionRepo is closed");
|
|
139
372
|
}
|
|
140
373
|
}
|
|
141
374
|
//# sourceMappingURL=memory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/harness/session/memory.ts"],"names":[],"mappings":"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","sourcesContent":["import { uuidv7 } from \"@earendil-works/pi-ai\";\nimport { Session } from \"./session.ts\";\nimport { SessionState } from \"./state.ts\";\nimport {\n\ttype BranchBounds,\n\ttype Entry,\n\ttype EntryQuery,\n\ttype ForkOptions,\n\ttype LanePointer,\n\ttype LaneRecord,\n\ttype LogItem,\n\ttype LogOptions,\n\ttype NewRecord,\n\ttype OperationStartedRecord,\n\ttype ProvisionedEntry,\n\ttype RecordQuery,\n\ttype SessionCreateOptions,\n\tSessionError,\n\ttype SessionMetadata,\n\ttype SessionRepo,\n\ttype SessionStats,\n\ttype SessionStorage,\n} from \"./types.ts\";\n\nexport class InMemorySessionStorage implements SessionStorage {\n\tprivate readonly metadata: SessionMetadata;\n\tprivate readonly state = new SessionState();\n\n\tconstructor(metadata: SessionMetadata) {\n\t\tthis.metadata = structuredClone(metadata);\n\t}\n\n\tfork(metadata: SessionMetadata, options: ForkOptions & SessionCreateOptions): InMemorySessionStorage {\n\t\tconst storage = new InMemorySessionStorage(metadata);\n\t\tfor (const mutation of this.state.createForkMutations(options)) storage.state.applyMutation(mutation);\n\t\treturn storage;\n\t}\n\n\tasync getMetadata(): Promise<SessionMetadata> {\n\t\treturn structuredClone(this.metadata);\n\t}\n\n\tasync getLanes(): Promise<LanePointer[]> {\n\t\treturn this.state.getLanes();\n\t}\n\n\tasync createLane(lane: string, at: string | null): Promise<void> {\n\t\tthis.state.validateNewLane(lane);\n\t\tthis.state.validateTarget(at);\n\t\tthis.state.applyMutation({ kind: \"lane\", seq: this.state.nextSequence, lane, leafId: at });\n\t}\n\n\tasync moveLane(lane: string, to: string | null): Promise<void> {\n\t\tthis.state.requireLane(lane);\n\t\tthis.state.validateTarget(to);\n\t\tthis.state.applyMutation({ kind: \"lane\", seq: this.state.nextSequence, lane, leafId: to });\n\t}\n\n\tasync appendEntry<TEntry extends Entry>(newEntry: ProvisionedEntry<TEntry>, lane: string): Promise<TEntry> {\n\t\tconst parentId = this.state.requireLane(lane);\n\t\tthis.state.validateUnusedId(newEntry.id);\n\t\tconst entry = {\n\t\t\t...structuredClone(newEntry),\n\t\t\tparentId,\n\t\t\tseq: this.state.nextSequence,\n\t\t\ttimestamp: Date.now(),\n\t\t} as unknown as TEntry;\n\t\tthis.state.applyMutation({ kind: \"entry\", lane, entry });\n\t\treturn structuredClone(entry);\n\t}\n\n\tasync appendRecord<TRecord extends LaneRecord>(newRecord: NewRecord<TRecord>): Promise<TRecord> {\n\t\tthis.state.requireLane(newRecord.lane);\n\t\tthis.state.validateUnusedId(newRecord.id);\n\t\tconst currentOpenOperationId = this.state.findOpenOperations(newRecord.lane, { limit: 1 })[0]?.id;\n\t\tif (newRecord.type === \"operation_started\" && currentOpenOperationId !== undefined) {\n\t\t\tthrow new SessionError(\n\t\t\t\t\"storage\",\n\t\t\t\t`Lane ${newRecord.lane} already has an open operation ${currentOpenOperationId}`,\n\t\t\t);\n\t\t}\n\t\tconst record = {\n\t\t\t...structuredClone(newRecord),\n\t\t\tseq: this.state.nextSequence,\n\t\t\ttimestamp: Date.now(),\n\t\t} as unknown as TRecord;\n\t\tthis.state.applyMutation({ kind: \"record\", record });\n\t\treturn structuredClone(record);\n\t}\n\n\tasync getEntry(id: string): Promise<Entry | undefined> {\n\t\tconst entry = this.state.getEntry(id);\n\t\treturn entry === undefined ? undefined : structuredClone(entry);\n\t}\n\n\tasync findEntries(query: EntryQuery = {}): Promise<Entry[]> {\n\t\treturn structuredClone(this.state.findEntries(query));\n\t}\n\n\tasync findEntriesOnBranch(query: EntryQuery & BranchBounds & { start: string }): Promise<Entry[]> {\n\t\treturn structuredClone(this.state.findEntriesOnBranch(query));\n\t}\n\n\tasync findRecords<K extends LaneRecord[\"type\"]>(\n\t\tquery: RecordQuery & { type: K },\n\t): Promise<Extract<LaneRecord, { type: K }>[]>;\n\tasync findRecords(query?: RecordQuery): Promise<LaneRecord[]>;\n\tasync findRecords(query: RecordQuery = {}): Promise<LaneRecord[]> {\n\t\treturn structuredClone(this.state.findRecords(query));\n\t}\n\n\tasync findOpenOperations(lane: string, options?: { limit?: number }): Promise<OperationStartedRecord[]> {\n\t\treturn structuredClone(this.state.findOpenOperations(lane, options));\n\t}\n\n\tasync getLog(options: LogOptions = {}): Promise<LogItem[]> {\n\t\treturn structuredClone(this.state.getLog(options));\n\t}\n\n\tasync getName(): Promise<string | undefined> {\n\t\treturn this.state.getName();\n\t}\n\n\tasync setName(name: string | undefined): Promise<void> {\n\t\tthis.state.applyMutation({ kind: \"fact\", seq: this.state.nextSequence, fact: \"name\", name });\n\t}\n\n\tasync getLabel(id: string): Promise<string | undefined> {\n\t\treturn this.state.getLabel(id);\n\t}\n\n\tasync setLabel(id: string, label: string | undefined): Promise<void> {\n\t\tthis.state.validateTarget(id);\n\t\tthis.state.applyMutation({\n\t\t\tkind: \"fact\",\n\t\t\tseq: this.state.nextSequence,\n\t\t\tfact: \"label\",\n\t\t\ttargetId: id,\n\t\t\tlabel,\n\t\t});\n\t}\n\n\tasync getStats(): Promise<SessionStats> {\n\t\treturn structuredClone(this.state.getStats());\n\t}\n}\n\nexport class InMemorySessionRepo implements SessionRepo {\n\tprivate readonly sessions = new Map<string, InMemorySessionStorage>();\n\n\tasync create(options: SessionCreateOptions = {}): Promise<Session> {\n\t\tconst id = options.id ?? uuidv7();\n\t\tif (this.sessions.has(id)) throw new SessionError(\"already_exists\", `Session already exists: ${id}`);\n\t\tconst storage = new InMemorySessionStorage({\n\t\t\tid,\n\t\t\tcreatedAt: Date.now(),\n\t\t\tparentSessionId: options.parentSessionId,\n\t\t});\n\t\tthis.sessions.set(id, storage);\n\t\treturn new Session(storage);\n\t}\n\n\tasync open(metadata: SessionMetadata): Promise<Session> {\n\t\treturn new Session(this.requireStorage(metadata.id));\n\t}\n\n\tasync list(): Promise<SessionMetadata[]> {\n\t\treturn Promise.all([...this.sessions.values()].map((storage) => storage.getMetadata()));\n\t}\n\n\tasync delete(metadata: SessionMetadata): Promise<void> {\n\t\tthis.sessions.delete(metadata.id);\n\t}\n\n\tasync fork(source: SessionMetadata, options: ForkOptions & SessionCreateOptions = {}): Promise<Session> {\n\t\tconst sourceStorage = this.requireStorage(source.id);\n\t\tconst id = options.id ?? uuidv7();\n\t\tif (this.sessions.has(id)) throw new SessionError(\"already_exists\", `Session already exists: ${id}`);\n\t\tconst storage = sourceStorage.fork(\n\t\t\t{ id, createdAt: Date.now(), parentSessionId: options.parentSessionId ?? source.id },\n\t\t\toptions,\n\t\t);\n\t\tthis.sessions.set(id, storage);\n\t\treturn new Session(storage);\n\t}\n\n\tprivate requireStorage(id: string): InMemorySessionStorage {\n\t\tconst storage = this.sessions.get(id);\n\t\tif (!storage) throw new SessionError(\"not_found\", `Session not found: ${id}`);\n\t\treturn storage;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/harness/session/memory.ts"],"names":[],"mappings":"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","sourcesContent":["import { uuidv7 } from \"@earendil-works/pi-ai/utils/uuid\";\nimport type { Context } from \"../context.ts\";\nimport {\n\tcreateForkSnapshot,\n\ttype ForkDestinationSnapshot,\n\ttype ForkSourceSnapshot,\n\tforkSnapshotWrites,\n} from \"./fork.ts\";\nimport { InMemoryStorageState } from \"./in-memory-storage-state.ts\";\nimport { StorageBackedSession } from \"./session.ts\";\nimport type {\n\tBranch,\n\tCommitResult,\n\tEntry,\n\tEntryQuery,\n\tEntryScan,\n\tEntryStructure,\n\tForkOptions,\n\tIdGenerator,\n\tSession,\n\tSessionCreateOptions,\n\tSessionMetadata,\n\tSessionMutation,\n\tSessionMutationCallback,\n\tSessionRepo,\n\tSessionStats,\n\tStorage,\n\tStorageBranchScan,\n\tUsageRow,\n\tUsageScan,\n\tWrite,\n} from \"./types.ts\";\nimport type { ListElement, ListReadOptions, StoredValue, Value, ValueList } from \"./values.ts\";\n\nexport interface MemoryStorageOptions {\n\tnow?: () => number;\n}\n\nexport interface MemorySessionRepoOptions {\n\tnow?: () => number;\n}\n\nexport class MemoryStorage implements Storage {\n\tprivate readonly now: () => number;\n\tprivate storageState = new InMemoryStorageState();\n\tprivate commitQueue: Promise<void> = Promise.resolve();\n\tprivate state: \"open\" | \"closing\" | \"closed\" = \"open\";\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(options: MemoryStorageOptions = {}) {\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tasync commit(writes: Write[], _context: Context): Promise<CommitResult> {\n\t\tif (this.state !== \"open\") throw new Error(\"MemoryStorage is closed\");\n\t\tconst result = this.commitQueue.then(() => {\n\t\t\tconst prepared = this.storageState.prepareCommit(writes, this.now());\n\t\t\tconst stats = this.storageState.applyValidated(prepared.writes);\n\t\t\treturn { ...prepared.result, stats };\n\t\t});\n\t\tthis.commitQueue = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\tgetEntries(ids: string[], _context: Context): Promise<Map<string, Entry>> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.getEntries(ids));\n\t}\n\n\tgetValue<T>(address: Value<T>, _context: Context): Promise<StoredValue<T> | undefined> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.getValue(address));\n\t}\n\n\tscanValues<T>(prefix: Value<T>, _context: Context): Promise<StoredValue<T>[]> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.scanValues(prefix));\n\t}\n\n\tasync readList<T>(\n\t\taddress: ValueList<T>,\n\t\toptions: ListReadOptions | undefined,\n\t\t_context: Context,\n\t): Promise<ListElement<T>[]> {\n\t\tif (this.state !== \"open\") throw new Error(\"MemoryStorage is closed\");\n\t\treturn this.storageState.readList(address, options);\n\t}\n\n\tasync scanBranch(query: StorageBranchScan, _context: Context): Promise<Entry[]> {\n\t\tif (this.state !== \"open\") throw new Error(\"MemoryStorage is closed\");\n\t\treturn this.storageState.scanBranch(query);\n\t}\n\n\tasync scanBranchStructure(query: StorageBranchScan, _context: Context): Promise<EntryStructure[]> {\n\t\tif (this.state !== \"open\") throw new Error(\"MemoryStorage is closed\");\n\t\treturn this.storageState.scanBranchStructure(query);\n\t}\n\n\tscanEntries(query: EntryScan, _context: Context): Promise<Entry[]> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.scanEntries(query));\n\t}\n\n\tscanUsage(query: UsageScan, _context: Context): Promise<UsageRow[]> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.scanUsage(query));\n\t}\n\n\tgetStats(_context: Context): Promise<SessionStats> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.getStats());\n\t}\n\n\t/** Capture the state needed to fork at one serialized boundary between commits. */\n\tcaptureForkSource(_context: Context): Promise<ForkSourceSnapshot> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\tconst result = this.commitQueue.then(() => this.storageState.snapshotEntriesAndValues());\n\t\tthis.commitQueue = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.state = \"closing\";\n\t\tthis.closePromise = this.commitQueue.then(() => {\n\t\t\tthis.state = \"closed\";\n\t\t});\n\t\treturn this.closePromise;\n\t}\n\n\tstatic fromSnapshot(options: MemoryStorageOptions, snapshot: ForkDestinationSnapshot): MemoryStorage {\n\t\tconst storage = new MemoryStorage(options);\n\t\tconst writes = forkSnapshotWrites(snapshot);\n\t\tstorage.storageState.validateCommitted(writes);\n\t\tstorage.storageState.applyValidated(writes);\n\t\treturn storage;\n\t}\n}\n\nconst MEMORY_STORAGE_VERSION = 1;\n\ninterface MemorySessionRecord {\n\tmetadata: SessionMetadata;\n\tstorage: MemoryStorage;\n\tsession: StorageBackedSession;\n\topen: boolean;\n}\n\nclass MemorySessionFacade implements Session {\n\treadonly metadata: SessionMetadata;\n\treadonly idGenerator: IdGenerator;\n\tprivate readonly session: StorageBackedSession;\n\tprivate readonly onClose: () => void;\n\tprivate readonly admitted = new Set<Promise<unknown>>();\n\tprivate readonly closedError = new Error(\"Session is closed\");\n\tprivate state: \"open\" | \"closing\" | \"closed\" = \"open\";\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(session: StorageBackedSession, onClose: () => void) {\n\t\tthis.session = session;\n\t\tthis.metadata = session.metadata;\n\t\tthis.idGenerator = session.idGenerator;\n\t\tthis.onClose = onClose;\n\t}\n\n\tasync beginMutation(context: Context): Promise<SessionMutation> {\n\t\tlet resolveFinished!: () => void;\n\t\tconst finished = new Promise<void>((resolve) => {\n\t\t\tresolveFinished = resolve;\n\t\t});\n\t\tthis.admitted.add(finished);\n\t\tlet source: SessionMutation;\n\t\ttry {\n\t\t\tsource = await this.admit(() => this.session.beginMutation(context));\n\t\t} catch (error) {\n\t\t\tthis.admitted.delete(finished);\n\t\t\tresolveFinished();\n\t\t\tthrow error;\n\t\t}\n\t\tif (this.state !== \"open\") {\n\t\t\tawait source.end(context);\n\t\t\tthis.admitted.delete(finished);\n\t\t\tresolveFinished();\n\t\t\tthrow this.closedError;\n\t\t}\n\t\tlet ended = false;\n\t\treturn {\n\t\t\tcommit: (writes, commitContext) => source.commit(writes, commitContext),\n\t\t\tend: async (endContext) => {\n\t\t\t\ttry {\n\t\t\t\t\tawait source.end(endContext);\n\t\t\t\t} finally {\n\t\t\t\t\tif (!ended) {\n\t\t\t\t\t\tended = true;\n\t\t\t\t\t\tthis.admitted.delete(finished);\n\t\t\t\t\t\tresolveFinished();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tgetEntries: (ids, readContext) => source.getEntries(ids, readContext),\n\t\t\tgetStats: (readContext) => source.getStats(readContext),\n\t\t\tgetValue: (address, readContext) => source.getValue(address, readContext),\n\t\t\tscanValues: (prefix, readContext) => source.scanValues(prefix, readContext),\n\t\t\treadList: (address, options, readContext) => source.readList(address, options, readContext),\n\t\t\tscanBranch: (query, readContext) => source.scanBranch(query, readContext),\n\t\t};\n\t}\n\n\tmutate<T>(mutation: SessionMutationCallback<T>, context: Context): Promise<T> {\n\t\treturn this.admit(() =>\n\t\t\tthis.session.mutate((mutator, mutationContext) => {\n\t\t\t\tif (this.state !== \"open\") throw this.closedError;\n\t\t\t\treturn mutation(mutator, mutationContext);\n\t\t\t}, context),\n\t\t);\n\t}\n\n\tgetEntries(ids: string[], context: Context): Promise<Map<string, Entry>> {\n\t\treturn this.admit(() => this.session.getEntries(ids, context));\n\t}\n\n\tgetEntry(id: string, context: Context): Promise<Entry | undefined> {\n\t\treturn this.admit(() => this.session.getEntry(id, context));\n\t}\n\n\tgetValue<T>(address: Value<T>, context: Context): Promise<StoredValue<T> | undefined> {\n\t\treturn this.admit(() => this.session.getValue(address, context));\n\t}\n\n\tscanValues<T>(prefix: Value<T>, context: Context): Promise<StoredValue<T>[]> {\n\t\treturn this.admit(() => this.session.scanValues(prefix, context));\n\t}\n\n\treadList<T>(\n\t\taddress: ValueList<T>,\n\t\toptions: ListReadOptions | undefined,\n\t\tcontext: Context,\n\t): Promise<ListElement<T>[]> {\n\t\treturn this.admit(() => this.session.readList(address, options, context));\n\t}\n\n\tscanBranch(query: StorageBranchScan, context: Context): Promise<Entry[]> {\n\t\treturn this.admit(() => this.session.scanBranch(query, context));\n\t}\n\n\tgetStats(context: Context): Promise<SessionStats> {\n\t\treturn this.admit(() => this.session.getStats(context));\n\t}\n\n\tgetName(context: Context): Promise<string | undefined> {\n\t\treturn this.admit(() => this.session.getName(context));\n\t}\n\n\tgetLabel(targetId: string, context: Context): Promise<string | undefined> {\n\t\treturn this.admit(() => this.session.getLabel(targetId, context));\n\t}\n\n\tfindEntries(query: EntryQuery | undefined, context: Context): Promise<Entry[]> {\n\t\treturn this.admit(() => this.session.findEntries(query, context));\n\t}\n\n\tfindEntry(query: EntryQuery | undefined, context: Context): Promise<Entry | undefined> {\n\t\treturn this.admit(() => this.session.findEntry(query, context));\n\t}\n\n\tasync branch(name: string, context: Context): Promise<Branch | undefined> {\n\t\tconst branch = await this.admit(() => this.session.branch(name, context));\n\t\treturn branch === undefined ? undefined : this.wrapBranch(branch);\n\t}\n\n\tasync createBranch(name: string, at: string | null, context: Context): Promise<Branch> {\n\t\treturn this.wrapBranch(await this.admit(() => this.session.createBranch(name, at, context)));\n\t}\n\n\tsetValue<T>(address: Value<T>, next: NoInfer<T>, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.setValue(address, next, context));\n\t}\n\n\tdeleteValue<T>(address: Value<T>, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.deleteValue(address, context));\n\t}\n\n\tappendList<T>(address: ValueList<T>, element: NoInfer<T>, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.appendList(address, element, context));\n\t}\n\n\tdeleteList<T>(address: ValueList<T>, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.deleteList(address, context));\n\t}\n\n\tsetName(name: string | undefined, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.setName(name, context));\n\t}\n\n\tsetLabel(targetId: string, label: string | undefined, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.setLabel(targetId, label, context));\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.state = \"closing\";\n\t\tthis.closePromise = Promise.allSettled([...this.admitted]).then(() => {\n\t\t\tthis.state = \"closed\";\n\t\t\tthis.onClose();\n\t\t});\n\t\treturn this.closePromise;\n\t}\n\n\tprivate wrapBranch(branch: Branch): Branch {\n\t\treturn {\n\t\t\tname: branch.name,\n\t\t\tgetTipId: (context) => this.admit(() => branch.getTipId(context)),\n\t\t\tfindEntries: (query, context) => this.admit(() => branch.findEntries(query, context)),\n\t\t\tfindEntry: (query, context) => this.admit(() => branch.findEntry(query, context)),\n\t\t\tappendMessage: (message, context) => this.admit(() => branch.appendMessage(message, context)),\n\t\t\tappendCustomEntry: (customType, data, context) =>\n\t\t\t\tthis.admit(() => branch.appendCustomEntry(customType, data, context)),\n\t\t};\n\t}\n\n\tprivate admit<T>(operation: () => Promise<T>): Promise<T> {\n\t\tif (this.state !== \"open\") return Promise.reject(this.closedError);\n\t\tlet result: Promise<T>;\n\t\ttry {\n\t\t\tresult = operation();\n\t\t} catch (error) {\n\t\t\tresult = Promise.reject(error);\n\t\t}\n\t\tthis.admitted.add(result);\n\t\tvoid result.then(\n\t\t\t() => this.admitted.delete(result),\n\t\t\t() => this.admitted.delete(result),\n\t\t);\n\t\treturn result;\n\t}\n}\n\nexport class MemorySessionRepo implements SessionRepo {\n\tprivate readonly now: () => number;\n\tprivate readonly sessions = new Map<string, MemorySessionRecord>();\n\tprivate readonly pendingIds = new Set<string>();\n\tprivate closed = false;\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(options: MemorySessionRepoOptions = {}) {\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tasync create(options: SessionCreateOptions, context: Context): Promise<Session> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst id = options.id ?? uuidv7(createdAt);\n\t\tthis.reserveId(id);\n\t\tconst metadata: SessionMetadata = {\n\t\t\tid,\n\t\t\tcreatedAt,\n\t\t\tstorageVersion: MEMORY_STORAGE_VERSION,\n\t\t\t...(options.parentSessionId === undefined ? {} : { parentSessionId: options.parentSessionId }),\n\t\t};\n\t\tconst storage = new MemoryStorage({ now: this.now });\n\t\tconst session = new StorageBackedSession(metadata, storage);\n\t\ttry {\n\t\t\tconst record: MemorySessionRecord = {\n\t\t\t\tmetadata,\n\t\t\t\tstorage,\n\t\t\t\tsession,\n\t\t\t\topen: true,\n\t\t\t};\n\t\t\tthis.sessions.set(id, record);\n\t\t\treturn this.openRecord(record);\n\t\t} catch (error) {\n\t\t\tawait session.close(context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingIds.delete(id);\n\t\t}\n\t}\n\n\topen(metadata: SessionMetadata, _context: Context): Promise<Session> {\n\t\t// Memory sessions are always created at the current storage version, so\n\t\t// persistent-backend version gating does not apply here.\n\t\tthis.assertOpen();\n\t\tconst record = this.sessions.get(metadata.id);\n\t\tif (record === undefined) return Promise.reject(new Error(`Unknown session: ${metadata.id}`));\n\t\tif (record.open) return Promise.reject(new Error(`Session is already open: ${metadata.id}`));\n\t\trecord.open = true;\n\t\treturn Promise.resolve(this.openRecord(record));\n\t}\n\n\tlist(_options: undefined, _context: Context): Promise<SessionMetadata[]> {\n\t\tthis.assertOpen();\n\t\treturn Promise.resolve([...this.sessions.values()].map(({ metadata }) => metadata));\n\t}\n\n\tasync delete(metadata: SessionMetadata, context: Context): Promise<void> {\n\t\tthis.assertOpen();\n\t\tconst record = this.sessions.get(metadata.id);\n\t\tif (record === undefined) throw new Error(`Unknown session: ${metadata.id}`);\n\t\tif (record.open) throw new Error(`Session is open: ${metadata.id}`);\n\t\tawait record.session.close(context);\n\t\tthis.sessions.delete(metadata.id);\n\t}\n\n\tasync fork(source: SessionMetadata, options: ForkOptions, context: Context): Promise<Session> {\n\t\tthis.assertOpen();\n\t\tconst sourceRecord = this.sessions.get(source.id);\n\t\tif (sourceRecord === undefined) throw new Error(`Unknown session: ${source.id}`);\n\t\tconst createdAt = this.now();\n\t\tconst id = options.id ?? uuidv7(createdAt);\n\t\tthis.reserveId(id);\n\n\t\ttry {\n\t\t\tconst snapshot = createForkSnapshot(await sourceRecord.storage.captureForkSource(context), options);\n\t\t\tconst storage = MemoryStorage.fromSnapshot({ now: this.now }, snapshot);\n\t\t\tconst metadata: SessionMetadata = {\n\t\t\t\tid,\n\t\t\t\tcreatedAt,\n\t\t\t\tstorageVersion: MEMORY_STORAGE_VERSION,\n\t\t\t\tparentSessionId: sourceRecord.metadata.id,\n\t\t\t};\n\t\t\tconst session = new StorageBackedSession(metadata, storage);\n\t\t\tconst record: MemorySessionRecord = {\n\t\t\t\tmetadata,\n\t\t\t\tstorage,\n\t\t\t\tsession,\n\t\t\t\topen: true,\n\t\t\t};\n\t\t\tthis.sessions.set(id, record);\n\t\t\treturn this.openRecord(record);\n\t\t} finally {\n\t\t\tthis.pendingIds.delete(id);\n\t\t}\n\t}\n\n\tclose(context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.closed = true;\n\t\tthis.closePromise = Promise.all([...this.sessions.values()].map(({ session }) => session.close(context))).then(\n\t\t\t() => undefined,\n\t\t);\n\t\treturn this.closePromise;\n\t}\n\n\tprivate openRecord(record: MemorySessionRecord): Session {\n\t\treturn new MemorySessionFacade(record.session, () => {\n\t\t\trecord.open = false;\n\t\t});\n\t}\n\n\tprivate reserveId(id: string): void {\n\t\tif (this.sessions.has(id) || this.pendingIds.has(id)) throw new Error(`Session already exists: ${id}`);\n\t\tthis.pendingIds.add(id);\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"MemorySessionRepo is closed\");\n\t}\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Serializes complete read-modify-write jobs for one Session. */
|
|
2
|
+
export declare class MutationLine {
|
|
3
|
+
private tail;
|
|
4
|
+
private sealedError;
|
|
5
|
+
run<T>(operation: () => T | Promise<T>): Promise<T>;
|
|
6
|
+
seal(error: Error): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=mutation-line.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutation-line.d.ts","sourceRoot":"","sources":["../../../src/harness/session/mutation-line.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,qBAAa,YAAY;IACxB,OAAO,CAAC,IAAI,CAAoC;IAChD,OAAO,CAAC,WAAW,CAAoB;IAEvC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAWlD;IAED,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhC;CACD","sourcesContent":["/** Serializes complete read-modify-write jobs for one Session. */\nexport class MutationLine {\n\tprivate tail: Promise<void> = Promise.resolve();\n\tprivate sealedError: Error | undefined;\n\n\trun<T>(operation: () => T | Promise<T>): Promise<T> {\n\t\tif (this.sealedError !== undefined) return Promise.reject(this.sealedError);\n\t\tconst result = this.tail.then(() => {\n\t\t\tif (this.sealedError !== undefined) throw this.sealedError;\n\t\t\treturn operation();\n\t\t});\n\t\tthis.tail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\tseal(error: Error): Promise<void> {\n\t\tthis.sealedError ??= error;\n\t\treturn this.tail;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Serializes complete read-modify-write jobs for one Session. */
|
|
2
|
+
export class MutationLine {
|
|
3
|
+
tail = Promise.resolve();
|
|
4
|
+
sealedError;
|
|
5
|
+
run(operation) {
|
|
6
|
+
if (this.sealedError !== undefined)
|
|
7
|
+
return Promise.reject(this.sealedError);
|
|
8
|
+
const result = this.tail.then(() => {
|
|
9
|
+
if (this.sealedError !== undefined)
|
|
10
|
+
throw this.sealedError;
|
|
11
|
+
return operation();
|
|
12
|
+
});
|
|
13
|
+
this.tail = result.then(() => undefined, () => undefined);
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
seal(error) {
|
|
17
|
+
this.sealedError ??= error;
|
|
18
|
+
return this.tail;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=mutation-line.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutation-line.js","sourceRoot":"","sources":["../../../src/harness/session/mutation-line.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,OAAO,YAAY;IAChB,IAAI,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IACxC,WAAW,CAAoB;IAEvC,GAAG,CAAI,SAA+B,EAAc;QACnD,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;gBAAE,MAAM,IAAI,CAAC,WAAW,CAAC;YAC3D,OAAO,SAAS,EAAE,CAAC;QAAA,CACnB,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CACtB,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;QACF,OAAO,MAAM,CAAC;IAAA,CACd;IAED,IAAI,CAAC,KAAY,EAAiB;QACjC,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC;QAC3B,OAAO,IAAI,CAAC,IAAI,CAAC;IAAA,CACjB;CACD","sourcesContent":["/** Serializes complete read-modify-write jobs for one Session. */\nexport class MutationLine {\n\tprivate tail: Promise<void> = Promise.resolve();\n\tprivate sealedError: Error | undefined;\n\n\trun<T>(operation: () => T | Promise<T>): Promise<T> {\n\t\tif (this.sealedError !== undefined) return Promise.reject(this.sealedError);\n\t\tconst result = this.tail.then(() => {\n\t\t\tif (this.sealedError !== undefined) throw this.sealedError;\n\t\t\treturn operation();\n\t\t});\n\t\tthis.tail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\tseal(error: Error): Promise<void> {\n\t\tthis.sealedError ??= error;\n\t\treturn this.tail;\n\t}\n}\n"]}
|