@demlik/tea 0.1.0 → 0.1.2
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/LICENSE +21 -0
- package/dist/agent/index.d.ts +907 -0
- package/dist/agent/index.js +20 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/authed-call/index.d.ts +119 -0
- package/dist/authed-call/index.js +148 -0
- package/dist/authed-call/index.js.map +1 -0
- package/dist/await-terminal/index.d.ts +99 -0
- package/dist/await-terminal/index.js +75 -0
- package/dist/await-terminal/index.js.map +1 -0
- package/dist/batch-window/index.d.ts +259 -0
- package/dist/batch-window/index.js +43 -0
- package/dist/batch-window/index.js.map +1 -0
- package/dist/cache/index.d.ts +2 -2
- package/dist/cache/index.js +2 -50
- package/dist/cache/index.js.map +1 -1
- package/dist/chunk-27N2SPTN.js +222 -0
- package/dist/chunk-27N2SPTN.js.map +1 -0
- package/dist/chunk-2YOE5PIS.js +45 -0
- package/dist/chunk-2YOE5PIS.js.map +1 -0
- package/dist/chunk-3545BOYL.js +65 -0
- package/dist/chunk-3545BOYL.js.map +1 -0
- package/dist/chunk-3XJWC7VW.js +61 -0
- package/dist/chunk-3XJWC7VW.js.map +1 -0
- package/dist/chunk-5DEQ5I3U.js +132 -0
- package/dist/chunk-5DEQ5I3U.js.map +1 -0
- package/dist/chunk-5VNWZADP.js +49 -0
- package/dist/chunk-5VNWZADP.js.map +1 -0
- package/dist/chunk-6RGBKODV.js +268 -0
- package/dist/chunk-6RGBKODV.js.map +1 -0
- package/dist/{chunk-ZRUST6BK.js → chunk-7FYQGDMF.js} +2 -2
- package/dist/chunk-7FYQGDMF.js.map +1 -0
- package/dist/chunk-7W4LMPUW.js +186 -0
- package/dist/chunk-7W4LMPUW.js.map +1 -0
- package/dist/chunk-BYQUGDD3.js +16 -0
- package/dist/chunk-BYQUGDD3.js.map +1 -0
- package/dist/{chunk-PYBQREFU.js → chunk-DILMKOZ7.js} +22 -26
- package/dist/chunk-DILMKOZ7.js.map +1 -0
- package/dist/chunk-EHIX7NYZ.js +93 -0
- package/dist/chunk-EHIX7NYZ.js.map +1 -0
- package/dist/chunk-HCEVHFJ7.js +54 -0
- package/dist/chunk-HCEVHFJ7.js.map +1 -0
- package/dist/chunk-HJO6VNQI.js +15 -0
- package/dist/chunk-HJO6VNQI.js.map +1 -0
- package/dist/chunk-IN33Q4VJ.js +52 -0
- package/dist/chunk-IN33Q4VJ.js.map +1 -0
- package/dist/chunk-J6527VRQ.js +56 -0
- package/dist/chunk-J6527VRQ.js.map +1 -0
- package/dist/chunk-JELSZN25.js +47 -0
- package/dist/chunk-JELSZN25.js.map +1 -0
- package/dist/chunk-K575PT4S.js +58 -0
- package/dist/chunk-K575PT4S.js.map +1 -0
- package/dist/chunk-K7Q23EQ4.js +20 -0
- package/dist/chunk-K7Q23EQ4.js.map +1 -0
- package/dist/chunk-LEC4U6CX.js +91 -0
- package/dist/chunk-LEC4U6CX.js.map +1 -0
- package/dist/{chunk-PYOCUBQJ.js → chunk-LP7VQBRG.js} +22 -15
- package/dist/chunk-LP7VQBRG.js.map +1 -0
- package/dist/{chunk-CMG2KMWX.js → chunk-MMH7CW5K.js} +220 -189
- package/dist/chunk-MMH7CW5K.js.map +1 -0
- package/dist/{chunk-Y5JM3UUH.js → chunk-NSDFA6M6.js} +75 -3
- package/dist/chunk-NSDFA6M6.js.map +1 -0
- package/dist/chunk-ON24RKSE.js +60 -0
- package/dist/chunk-ON24RKSE.js.map +1 -0
- package/dist/chunk-PS23H6KQ.js +87 -0
- package/dist/chunk-PS23H6KQ.js.map +1 -0
- package/dist/chunk-QLA76GIT.js +162 -0
- package/dist/chunk-QLA76GIT.js.map +1 -0
- package/dist/chunk-S3FQN4SL.js +506 -0
- package/dist/chunk-S3FQN4SL.js.map +1 -0
- package/dist/chunk-SC3FAFZN.js +53 -0
- package/dist/chunk-SC3FAFZN.js.map +1 -0
- package/dist/chunk-SINXE47Y.js +55 -0
- package/dist/chunk-SINXE47Y.js.map +1 -0
- package/dist/chunk-SQTCS44W.js +33 -0
- package/dist/chunk-SQTCS44W.js.map +1 -0
- package/dist/chunk-TGG26XMK.js +52 -0
- package/dist/chunk-TGG26XMK.js.map +1 -0
- package/dist/chunk-UV6UWGEO.js +147 -0
- package/dist/chunk-UV6UWGEO.js.map +1 -0
- package/dist/chunk-UYWUVEP6.js +158 -0
- package/dist/chunk-UYWUVEP6.js.map +1 -0
- package/dist/chunk-VLGARN6H.js +202 -0
- package/dist/chunk-VLGARN6H.js.map +1 -0
- package/dist/circuit-breaker/index.js +1 -51
- package/dist/circuit-breaker/index.js.map +1 -1
- package/dist/core-BoB6t7dB.d.ts +188 -0
- package/dist/deadline/index.d.ts +24 -5
- package/dist/deadline/index.js +4 -18
- package/dist/deadline/index.js.map +1 -1
- package/dist/debounce/index.d.ts +6 -0
- package/dist/debounce/index.js +1 -54
- package/dist/debounce/index.js.map +1 -1
- package/dist/devtools/index.d.ts +1 -1
- package/dist/devtools/index.js +18 -6
- package/dist/devtools/index.js.map +1 -1
- package/dist/do/index.d.ts +1723 -92
- package/dist/do/index.js +673 -31
- package/dist/do/index.js.map +1 -1
- package/dist/durable-effects-CO9Uh971.d.ts +180 -0
- package/dist/extension/index.d.ts +31 -13
- package/dist/extension/index.js +5 -3
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/react.js +8 -3
- package/dist/extension/react.js.map +1 -1
- package/dist/extension/subs/index.d.ts +2 -2
- package/dist/extension/subs/index.js.map +1 -1
- package/dist/extension/test-utils.js +11 -3
- package/dist/extension/test-utils.js.map +1 -1
- package/dist/fan-out/index.d.ts +239 -0
- package/dist/fan-out/index.js +5 -0
- package/dist/fan-out/index.js.map +1 -0
- package/dist/idempotency/adapter.d.ts +62 -0
- package/dist/idempotency/adapter.js +4 -0
- package/dist/idempotency/adapter.js.map +1 -0
- package/dist/idempotency/index.js +1 -56
- package/dist/idempotency/index.js.map +1 -1
- package/dist/idempotent-intake/index.d.ts +186 -0
- package/dist/idempotent-intake/index.js +7 -0
- package/dist/idempotent-intake/index.js.map +1 -0
- package/dist/index.d.ts +341 -191
- package/dist/index.js +2 -1
- package/dist/llm-call/index.d.ts +309 -0
- package/dist/llm-call/index.js +14 -0
- package/dist/llm-call/index.js.map +1 -0
- package/dist/machine-viz/index.d.ts +4 -4
- package/dist/machine-viz/index.js +5 -9
- package/dist/machine-viz/index.js.map +1 -1
- package/dist/mem/index.d.ts +1 -0
- package/dist/monitored-run/index.d.ts +253 -0
- package/dist/monitored-run/index.js +10 -0
- package/dist/monitored-run/index.js.map +1 -0
- package/dist/node/index.d.ts +5 -5
- package/dist/node/index.js.map +1 -1
- package/dist/paginated-walk/index.d.ts +234 -0
- package/dist/paginated-walk/index.js +15 -0
- package/dist/paginated-walk/index.js.map +1 -0
- package/dist/paginator/index.d.ts +271 -0
- package/dist/paginator/index.js +3 -0
- package/dist/paginator/index.js.map +1 -0
- package/dist/parity/index.d.ts +92 -0
- package/dist/parity/index.js +78 -0
- package/dist/parity/index.js.map +1 -0
- package/dist/pbt/arbitraries/index.d.ts +1 -1
- package/dist/pbt/arbitraries/index.js +1 -1
- package/dist/pbt/index.d.ts +15 -8
- package/dist/pbt/index.js +6 -11
- package/dist/pbt/index.js.map +1 -1
- package/dist/pbt/runners/index.d.ts +1 -1
- package/dist/pbt/runners/index.js +3 -2
- package/dist/poller/index.d.ts +288 -0
- package/dist/poller/index.js +79 -0
- package/dist/poller/index.js.map +1 -0
- package/dist/prediction/index.d.ts +130 -0
- package/dist/prediction/index.js +4 -0
- package/dist/prediction/index.js.map +1 -0
- package/dist/protocol-B5YmJr0d.d.ts +45 -0
- package/dist/pure/index.d.ts +2 -0
- package/dist/pure/index.js +4 -0
- package/dist/pure/index.js.map +1 -0
- package/dist/raft/demo.d.ts +105 -0
- package/dist/raft/demo.js +172 -0
- package/dist/raft/demo.js.map +1 -0
- package/dist/raft/index.d.ts +548 -0
- package/dist/raft/index.js +7 -0
- package/dist/raft/index.js.map +1 -0
- package/dist/raft/sim.d.ts +222 -0
- package/dist/raft/sim.js +8 -0
- package/dist/raft/sim.js.map +1 -0
- package/dist/raft/timeline.d.ts +46 -0
- package/dist/raft/timeline.js +62 -0
- package/dist/raft/timeline.js.map +1 -0
- package/dist/rate-limit/index.js +1 -43
- package/dist/rate-limit/index.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +43 -20
- package/dist/react/index.js.map +1 -1
- package/dist/reconciler/index.d.ts +192 -0
- package/dist/reconciler/index.js +166 -0
- package/dist/reconciler/index.js.map +1 -0
- package/dist/recorder/index.d.ts +7 -3
- package/dist/recorder/index.js +1 -155
- package/dist/recorder/index.js.map +1 -1
- package/dist/resilient-call/index.d.ts +294 -0
- package/dist/resilient-call/index.js +13 -0
- package/dist/resilient-call/index.js.map +1 -0
- package/dist/retry-backoff/index.d.ts +42 -5
- package/dist/retry-backoff/index.js +1 -35
- package/dist/retry-backoff/index.js.map +1 -1
- package/dist/retry-to-success/index.d.ts +109 -0
- package/dist/retry-to-success/index.js +35 -0
- package/dist/retry-to-success/index.js.map +1 -0
- package/dist/saga/index.d.ts +238 -0
- package/dist/saga/index.js +150 -0
- package/dist/saga/index.js.map +1 -0
- package/dist/snapshot/index.d.ts +334 -0
- package/dist/snapshot/index.js +5 -0
- package/dist/snapshot/index.js.map +1 -0
- package/dist/subs/index.d.ts +48 -10
- package/dist/subs/index.js +1 -1
- package/dist/testing/index.d.ts +107 -2
- package/dist/testing/index.js +204 -6
- package/dist/testing/index.js.map +1 -1
- package/dist/throttle/index.d.ts +9 -0
- package/dist/throttle/index.js +1 -52
- package/dist/throttle/index.js.map +1 -1
- package/dist/throttled-input/index.d.ts +380 -0
- package/dist/throttled-input/index.js +88 -0
- package/dist/throttled-input/index.js.map +1 -0
- package/dist/token-refresh/index.d.ts +215 -0
- package/dist/token-refresh/index.js +6 -0
- package/dist/token-refresh/index.js.map +1 -0
- package/dist/trace-replay/index.d.ts +11 -2
- package/dist/trace-replay/index.js +3 -55
- package/dist/trace-replay/index.js.map +1 -1
- package/dist/{types-CwBC5wMn.d.ts → types-B-8bcAp8.d.ts} +1 -1
- package/dist/with-deadline/index.d.ts +196 -0
- package/dist/with-deadline/index.js +111 -0
- package/dist/with-deadline/index.js.map +1 -0
- package/dist/with-resilience/index.d.ts +205 -0
- package/dist/with-resilience/index.js +251 -0
- package/dist/with-resilience/index.js.map +1 -0
- package/dist/with-telemetry/index.d.ts +149 -0
- package/dist/with-telemetry/index.js +70 -0
- package/dist/with-telemetry/index.js.map +1 -0
- package/dist/work-queue/adapter.d.ts +82 -0
- package/dist/work-queue/adapter.js +4 -0
- package/dist/work-queue/adapter.js.map +1 -0
- package/dist/work-queue/index.d.ts +25 -11
- package/dist/work-queue/index.js +1 -46
- package/dist/work-queue/index.js.map +1 -1
- package/dist/work-queue/ops.d.ts +69 -0
- package/dist/work-queue/ops.js +3 -0
- package/dist/work-queue/ops.js.map +1 -0
- package/dist/workflow/index.d.ts +450 -0
- package/dist/workflow/index.js +225 -0
- package/dist/workflow/index.js.map +1 -0
- package/package.json +168 -25
- package/dist/chunk-CMG2KMWX.js.map +0 -1
- package/dist/chunk-PYBQREFU.js.map +0 -1
- package/dist/chunk-PYOCUBQJ.js.map +0 -1
- package/dist/chunk-Y5JM3UUH.js.map +0 -1
- package/dist/chunk-ZRUST6BK.js.map +0 -1
package/dist/do/index.js
CHANGED
|
@@ -1,54 +1,696 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { status, agentBootMsg, agentEvents } from '../chunk-S3FQN4SL.js';
|
|
2
|
+
import '../chunk-7W4LMPUW.js';
|
|
3
|
+
import '../chunk-PS23H6KQ.js';
|
|
4
|
+
export { applyEffectEvent, emptyLedger, foldLedger, isOwed, pendingEffectsLedger, survivingEffects } from '../chunk-3545BOYL.js';
|
|
5
|
+
import '../chunk-EHIX7NYZ.js';
|
|
6
|
+
import '../chunk-27N2SPTN.js';
|
|
7
|
+
import '../chunk-JELSZN25.js';
|
|
8
|
+
import '../chunk-UV6UWGEO.js';
|
|
9
|
+
import { createIntake } from '../chunk-LEC4U6CX.js';
|
|
10
|
+
import '../chunk-K7Q23EQ4.js';
|
|
11
|
+
import { defaultRetryPolicy, initRetry, recordFailure, shouldRetry, nextDelayMs } from '../chunk-5VNWZADP.js';
|
|
12
|
+
import '../chunk-2YOE5PIS.js';
|
|
13
|
+
import '../chunk-BYQUGDD3.js';
|
|
14
|
+
import '../chunk-K575PT4S.js';
|
|
15
|
+
import '../chunk-SC3FAFZN.js';
|
|
16
|
+
import '../chunk-IN33Q4VJ.js';
|
|
17
|
+
import '../chunk-HJO6VNQI.js';
|
|
18
|
+
import '../chunk-TGG26XMK.js';
|
|
19
|
+
import '../chunk-NSDFA6M6.js';
|
|
20
|
+
import '../chunk-2YFLOCWX.js';
|
|
21
|
+
import { run, replay } from '../chunk-MMH7CW5K.js';
|
|
22
|
+
import '../chunk-QLA76GIT.js';
|
|
23
|
+
|
|
24
|
+
// src/do/durable-timer.ts
|
|
25
|
+
function durableTimer(config) {
|
|
26
|
+
const { alarm, nextDeadline, onFire } = config;
|
|
27
|
+
const timer = {
|
|
28
|
+
async rearm() {
|
|
29
|
+
const at = await nextDeadline();
|
|
30
|
+
if (at !== null) await alarm.setAlarm(at);
|
|
31
|
+
},
|
|
32
|
+
async onAlarm() {
|
|
33
|
+
await onFire();
|
|
34
|
+
await timer.rearm();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
return timer;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/do/event-sourced-store.ts
|
|
41
|
+
var DEFAULT_SNAPSHOT_KEY = "@@es/snapshot";
|
|
42
|
+
var DEFAULT_META_KEY = "@@es/meta";
|
|
43
|
+
var DEFAULT_EVENT_PREFIX = "@@es/evt/";
|
|
44
|
+
var SEQ_WIDTH = 16;
|
|
45
|
+
function eventKey(prefix, seq) {
|
|
46
|
+
return prefix + String(seq).padStart(SEQ_WIDTH, "0");
|
|
47
|
+
}
|
|
48
|
+
var defaultParse = (raw) => raw !== null && typeof raw === "object" && !Array.isArray(raw) ? raw : null;
|
|
49
|
+
var defaultParseEvent = (raw) => raw !== null && typeof raw === "object" && !Array.isArray(raw) && typeof raw.type === "string" ? raw : null;
|
|
50
|
+
function doEventSourcedStore(storage, machine, ctx, opts = {}) {
|
|
51
|
+
const snapshotEvery = opts.snapshotEvery ?? 100;
|
|
52
|
+
if (snapshotEvery < 1 || !Number.isInteger(snapshotEvery)) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`@demlik/tea/do: snapshotEvery must be an integer >= 1, got ${snapshotEvery}`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
const parse = opts.parse ?? defaultParse;
|
|
58
|
+
const parseEvent = opts.parseEvent ?? defaultParseEvent;
|
|
59
|
+
const snapshotKey = opts.keys?.snapshot ?? DEFAULT_SNAPSHOT_KEY;
|
|
60
|
+
const metaKey = opts.keys?.meta ?? DEFAULT_META_KEY;
|
|
61
|
+
const eventPrefix = opts.keys?.eventPrefix ?? DEFAULT_EVENT_PREFIX;
|
|
62
|
+
let lastSeq = null;
|
|
63
|
+
let snapshotSeq = 0;
|
|
64
|
+
let latestState = null;
|
|
65
|
+
let readyFired = false;
|
|
66
|
+
async function readMeta() {
|
|
67
|
+
const raw = await storage.get(metaKey);
|
|
68
|
+
if (raw === void 0 || raw === null) return 0;
|
|
69
|
+
const meta = JSON.parse(raw);
|
|
70
|
+
return typeof meta.lastSeq === "number" ? meta.lastSeq : 0;
|
|
71
|
+
}
|
|
72
|
+
async function readSnapshot() {
|
|
73
|
+
const raw = await storage.get(snapshotKey);
|
|
74
|
+
if (raw === void 0 || raw === null) return { state: null, seq: 0 };
|
|
75
|
+
const cell = JSON.parse(raw);
|
|
76
|
+
const parsed = parse(cell.state);
|
|
77
|
+
if (parsed === null) return { state: null, seq: 0 };
|
|
78
|
+
const seq = typeof cell.seq === "number" ? cell.seq : 0;
|
|
79
|
+
return { state: parsed, seq };
|
|
80
|
+
}
|
|
81
|
+
async function* readEvents(range = {}) {
|
|
82
|
+
const fromSeq = range.fromSeq ?? Number.NEGATIVE_INFINITY;
|
|
83
|
+
const toSeq = range.toSeq ?? Number.POSITIVE_INFINITY;
|
|
84
|
+
const rows = await storage.list({ prefix: eventPrefix });
|
|
85
|
+
for (const [key, value] of rows) {
|
|
86
|
+
const seq = Number(key.slice(eventPrefix.length));
|
|
87
|
+
if (!Number.isFinite(seq) || seq < fromSeq || seq > toSeq) continue;
|
|
88
|
+
const decoded = parseEvent(JSON.parse(value));
|
|
89
|
+
if (decoded !== null) yield { seq, event: decoded };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function readLog(afterSeq) {
|
|
93
|
+
const events = [];
|
|
94
|
+
for await (const { event } of readEvents({ fromSeq: afterSeq + 1 })) {
|
|
95
|
+
events.push(event);
|
|
96
|
+
}
|
|
97
|
+
return events;
|
|
98
|
+
}
|
|
99
|
+
const store = {
|
|
5
100
|
async load() {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
101
|
+
const { state: snapshot, seq: snapSeq } = await readSnapshot();
|
|
102
|
+
snapshotSeq = snapSeq;
|
|
103
|
+
lastSeq = await readMeta();
|
|
104
|
+
const events = await readLog(snapSeq);
|
|
105
|
+
const { state } = replay(machine, {
|
|
106
|
+
msgs: events,
|
|
107
|
+
ctx,
|
|
108
|
+
loaded: snapshot
|
|
109
|
+
});
|
|
110
|
+
if (!readyFired) {
|
|
111
|
+
readyFired = true;
|
|
112
|
+
opts.onReady?.(state);
|
|
113
|
+
}
|
|
114
|
+
return state;
|
|
9
115
|
},
|
|
10
116
|
async save(state) {
|
|
11
|
-
|
|
117
|
+
latestState = state;
|
|
12
118
|
},
|
|
13
119
|
migrate(raw) {
|
|
14
120
|
return parse(raw);
|
|
15
121
|
}
|
|
16
122
|
};
|
|
123
|
+
async function writeSnapshot(seq, state) {
|
|
124
|
+
const cell = { seq, state };
|
|
125
|
+
await storage.put(snapshotKey, JSON.stringify(cell));
|
|
126
|
+
snapshotSeq = seq;
|
|
127
|
+
}
|
|
128
|
+
async function append(msg) {
|
|
129
|
+
if (lastSeq === null) lastSeq = await readMeta();
|
|
130
|
+
const seq = lastSeq + 1;
|
|
131
|
+
lastSeq = seq;
|
|
132
|
+
await storage.put(eventKey(eventPrefix, seq), JSON.stringify(msg));
|
|
133
|
+
await storage.put(
|
|
134
|
+
metaKey,
|
|
135
|
+
JSON.stringify({ lastSeq: seq })
|
|
136
|
+
);
|
|
137
|
+
if (seq - snapshotSeq >= snapshotEvery && latestState !== null) {
|
|
138
|
+
await writeSnapshot(seq, latestState);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async function snapshotNow() {
|
|
142
|
+
if (lastSeq === null) lastSeq = await readMeta();
|
|
143
|
+
if (latestState === null || lastSeq <= snapshotSeq) return false;
|
|
144
|
+
await writeSnapshot(lastSeq, latestState);
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
return { store, append, snapshotNow, readEvents };
|
|
17
148
|
}
|
|
18
|
-
|
|
149
|
+
|
|
150
|
+
// src/do/host.ts
|
|
151
|
+
function deferredGateway() {
|
|
152
|
+
const pending = /* @__PURE__ */ new Map();
|
|
19
153
|
return {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
154
|
+
await(callId, send, deadlineMs) {
|
|
155
|
+
const existing = pending.get(callId);
|
|
156
|
+
if (existing !== void 0) return existing.promise;
|
|
157
|
+
let resolve;
|
|
158
|
+
let reject;
|
|
159
|
+
const promise = new Promise((res, rej) => {
|
|
160
|
+
resolve = res;
|
|
161
|
+
reject = rej;
|
|
162
|
+
});
|
|
163
|
+
const timer = setTimeout(() => {
|
|
164
|
+
if (pending.delete(callId)) {
|
|
165
|
+
reject(new Error(`deadline_exceeded after ${deadlineMs}ms`));
|
|
166
|
+
}
|
|
167
|
+
}, deadlineMs);
|
|
168
|
+
pending.set(callId, {
|
|
169
|
+
resolve: (v) => {
|
|
170
|
+
clearTimeout(timer);
|
|
171
|
+
resolve(v);
|
|
172
|
+
},
|
|
173
|
+
reject: (e) => {
|
|
174
|
+
clearTimeout(timer);
|
|
175
|
+
reject(e);
|
|
176
|
+
},
|
|
177
|
+
promise
|
|
178
|
+
});
|
|
179
|
+
send();
|
|
180
|
+
return promise;
|
|
181
|
+
},
|
|
182
|
+
settle(callId, result) {
|
|
183
|
+
const entry = pending.get(callId);
|
|
184
|
+
if (entry === void 0) return;
|
|
185
|
+
pending.delete(callId);
|
|
186
|
+
entry.resolve(result);
|
|
187
|
+
},
|
|
188
|
+
fail(callId, reason) {
|
|
189
|
+
const entry = pending.get(callId);
|
|
190
|
+
if (entry === void 0) return;
|
|
191
|
+
pending.delete(callId);
|
|
192
|
+
entry.reject(new Error(reason));
|
|
193
|
+
},
|
|
194
|
+
inFlight() {
|
|
195
|
+
return [...pending.keys()];
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function durableDeferredGateway(inner, recorder, hooks) {
|
|
200
|
+
const idByCallId = /* @__PURE__ */ new Map();
|
|
201
|
+
return {
|
|
202
|
+
recorder,
|
|
203
|
+
await(callId, send, deadlineMs) {
|
|
204
|
+
if (!idByCallId.has(callId)) {
|
|
205
|
+
const { id, event } = recorder.owe({ callId });
|
|
206
|
+
idByCallId.set(callId, id);
|
|
207
|
+
hooks.recordOwed(callId, event);
|
|
25
208
|
}
|
|
26
|
-
return (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
209
|
+
return inner.await(callId, send, deadlineMs);
|
|
210
|
+
},
|
|
211
|
+
settle(callId, result) {
|
|
212
|
+
confirm(callId);
|
|
213
|
+
inner.settle(callId, result);
|
|
214
|
+
},
|
|
215
|
+
fail(callId, reason) {
|
|
216
|
+
confirm(callId);
|
|
217
|
+
inner.fail(callId, reason);
|
|
218
|
+
},
|
|
219
|
+
inFlight() {
|
|
220
|
+
return inner.inFlight();
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
function confirm(callId) {
|
|
224
|
+
const id = idByCallId.get(callId);
|
|
225
|
+
if (id === void 0) return;
|
|
226
|
+
idByCallId.delete(callId);
|
|
227
|
+
const { event } = recorder.confirm(id);
|
|
228
|
+
hooks.recordConfirmed(callId, event);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
async function bootResume(booting, port, now = Date.now) {
|
|
232
|
+
const runtime = await booting.ready;
|
|
233
|
+
if (port.isResumable(runtime.getState())) {
|
|
234
|
+
await runtime.dispatch(port.resumeMsg(now()));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function agentIsResumable(state) {
|
|
238
|
+
return status(state).kind === "suspended";
|
|
239
|
+
}
|
|
240
|
+
async function autoBoot(booting, now = Date.now) {
|
|
241
|
+
await bootResume(
|
|
242
|
+
booting,
|
|
243
|
+
{ isResumable: agentIsResumable, resumeMsg: agentBootMsg },
|
|
244
|
+
now
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
function acceptCommandSocket(clients, onFrame) {
|
|
248
|
+
const pair = new WebSocketPair();
|
|
249
|
+
const [client, server] = [pair[0], pair[1]];
|
|
250
|
+
server.accept();
|
|
251
|
+
clients.add(server);
|
|
252
|
+
server.addEventListener("message", (ev) => {
|
|
253
|
+
if (typeof ev.data === "string") onFrame(ev.data);
|
|
254
|
+
});
|
|
255
|
+
server.addEventListener("close", () => clients.delete(server));
|
|
256
|
+
return new Response(null, { status: 101, webSocket: client });
|
|
257
|
+
}
|
|
258
|
+
function broadcast(clients, frame) {
|
|
259
|
+
const json = JSON.stringify(frame);
|
|
260
|
+
for (const ws of clients) {
|
|
261
|
+
try {
|
|
262
|
+
ws.send(json);
|
|
263
|
+
} catch {
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function acceptDurableCommandSocket(ctx) {
|
|
268
|
+
const pair = new WebSocketPair();
|
|
269
|
+
const [client, server] = [pair[0], pair[1]];
|
|
270
|
+
ctx.acceptWebSocket(server);
|
|
271
|
+
return new Response(null, { status: 101, webSocket: client });
|
|
272
|
+
}
|
|
273
|
+
function broadcastHibernatable(ctx, frame) {
|
|
274
|
+
const json = JSON.stringify(frame);
|
|
275
|
+
for (const ws of ctx.getWebSockets()) {
|
|
276
|
+
try {
|
|
277
|
+
ws.send(json);
|
|
278
|
+
} catch {
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
function durableCommandCarrier(inner, recorder, hooks) {
|
|
283
|
+
return durableDeferredGateway(inner, recorder, hooks);
|
|
284
|
+
}
|
|
285
|
+
function reissueSurvivingEffects(carrier, reissue) {
|
|
286
|
+
const reemitted = [];
|
|
287
|
+
for (const { effect } of carrier.recorder.surviving()) {
|
|
288
|
+
reissue(effect.callId);
|
|
289
|
+
reemitted.push(effect.callId);
|
|
290
|
+
}
|
|
291
|
+
return reemitted;
|
|
292
|
+
}
|
|
293
|
+
function sseHub() {
|
|
294
|
+
const sinks = /* @__PURE__ */ new Set();
|
|
295
|
+
const encoder = new TextEncoder();
|
|
296
|
+
return {
|
|
297
|
+
emit(event) {
|
|
298
|
+
for (const sink of sinks) {
|
|
299
|
+
try {
|
|
300
|
+
sink(event);
|
|
301
|
+
} catch {
|
|
33
302
|
}
|
|
34
|
-
}
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
open() {
|
|
306
|
+
let sink;
|
|
307
|
+
const stream = new ReadableStream({
|
|
308
|
+
start: (controller) => {
|
|
309
|
+
sink = (event) => {
|
|
310
|
+
controller.enqueue(
|
|
311
|
+
encoder.encode(`data: ${JSON.stringify(event)}
|
|
312
|
+
|
|
313
|
+
`)
|
|
314
|
+
);
|
|
315
|
+
};
|
|
316
|
+
sinks.add(sink);
|
|
317
|
+
},
|
|
318
|
+
cancel: () => {
|
|
319
|
+
sinks.delete(sink);
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
return new Response(stream, {
|
|
323
|
+
headers: {
|
|
324
|
+
"content-type": "text/event-stream",
|
|
325
|
+
"cache-control": "no-cache",
|
|
326
|
+
connection: "keep-alive"
|
|
327
|
+
}
|
|
328
|
+
});
|
|
35
329
|
},
|
|
36
|
-
|
|
37
|
-
|
|
330
|
+
register(sink) {
|
|
331
|
+
sinks.add(sink);
|
|
38
332
|
return () => {
|
|
39
|
-
|
|
333
|
+
sinks.delete(sink);
|
|
40
334
|
};
|
|
41
335
|
}
|
|
42
336
|
};
|
|
43
337
|
}
|
|
44
|
-
function
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
338
|
+
function sseProjection(hub, toEvent, id = {}) {
|
|
339
|
+
return {
|
|
340
|
+
id: { name: id.name ?? "sse", key: id.key ?? "main" },
|
|
341
|
+
initial: null,
|
|
342
|
+
apply(_view, update) {
|
|
343
|
+
return toEvent(update.msg, update.model);
|
|
344
|
+
},
|
|
345
|
+
emit(view) {
|
|
346
|
+
if (view !== null) hub.emit(view);
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
function sseFromAgentEvents(runtime, hub, toFrame) {
|
|
351
|
+
const push = (event) => {
|
|
352
|
+
const frame = toFrame(event);
|
|
353
|
+
if (frame !== null) hub.emit(frame);
|
|
354
|
+
};
|
|
355
|
+
const offs = [
|
|
356
|
+
runtime.on("TurnSettled", push),
|
|
357
|
+
runtime.on("ToolSettled", push),
|
|
358
|
+
runtime.on("RunDone", push)
|
|
359
|
+
];
|
|
360
|
+
return () => {
|
|
361
|
+
for (const off of offs) off();
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
function createAgentHost(config) {
|
|
365
|
+
const sse = sseHub();
|
|
366
|
+
const now = config.now ?? Date.now;
|
|
367
|
+
const isTerminal = config.terminal ?? ((s) => s.run.phase === "done" || s.run.phase === "failed");
|
|
368
|
+
let cached = null;
|
|
369
|
+
async function runtime() {
|
|
370
|
+
if (cached !== null) return cached;
|
|
371
|
+
const booting = run(config.buildMachine(), {
|
|
372
|
+
ctx: config.ctx,
|
|
373
|
+
store: config.store,
|
|
374
|
+
events: agentEvents(),
|
|
375
|
+
terminal: isTerminal
|
|
376
|
+
});
|
|
377
|
+
sseFromAgentEvents(booting, sse, config.toSseFrame);
|
|
378
|
+
await autoBoot(booting, now);
|
|
379
|
+
cached = await booting.ready;
|
|
380
|
+
return cached;
|
|
381
|
+
}
|
|
382
|
+
return {
|
|
383
|
+
runtime,
|
|
384
|
+
async status() {
|
|
385
|
+
return status((await runtime()).getState());
|
|
386
|
+
},
|
|
387
|
+
async result() {
|
|
388
|
+
return (await runtime()).result();
|
|
389
|
+
},
|
|
390
|
+
sse,
|
|
391
|
+
async reset() {
|
|
392
|
+
if (cached === null) return;
|
|
393
|
+
await cached.stop();
|
|
394
|
+
cached = null;
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// src/do/idempotent-effect.ts
|
|
400
|
+
function emptyApplied() {
|
|
401
|
+
return /* @__PURE__ */ new Set();
|
|
402
|
+
}
|
|
403
|
+
function applyAppliedEvent(applied, event) {
|
|
404
|
+
switch (event.type) {
|
|
405
|
+
case "effect_applied": {
|
|
406
|
+
if (applied.has(event.key)) return applied;
|
|
407
|
+
const next = new Set(applied);
|
|
408
|
+
next.add(event.key);
|
|
409
|
+
return next;
|
|
410
|
+
}
|
|
411
|
+
case "effect_forgotten": {
|
|
412
|
+
if (!applied.has(event.key)) return applied;
|
|
413
|
+
const next = new Set(applied);
|
|
414
|
+
next.delete(event.key);
|
|
415
|
+
return next;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
function foldApplied(events) {
|
|
420
|
+
let applied = emptyApplied();
|
|
421
|
+
for (const event of events) applied = applyAppliedEvent(applied, event);
|
|
422
|
+
return applied;
|
|
423
|
+
}
|
|
424
|
+
function isApplied(applied, key) {
|
|
425
|
+
return applied.has(key);
|
|
426
|
+
}
|
|
427
|
+
function idempotentEffect(key, fn) {
|
|
428
|
+
return { key, fn };
|
|
429
|
+
}
|
|
430
|
+
function appliedEffects(restore) {
|
|
431
|
+
let mirror = restore?.events ? foldApplied(restore.events) : emptyApplied();
|
|
432
|
+
return {
|
|
433
|
+
async run(effect) {
|
|
434
|
+
if (mirror.has(effect.key)) {
|
|
435
|
+
return { ran: false, key: effect.key };
|
|
436
|
+
}
|
|
437
|
+
const result = await effect.fn();
|
|
438
|
+
const event = { type: "effect_applied", key: effect.key };
|
|
439
|
+
mirror = applyAppliedEvent(mirror, event);
|
|
440
|
+
return { ran: true, key: effect.key, result, event };
|
|
441
|
+
},
|
|
442
|
+
forget(key) {
|
|
443
|
+
const event = { type: "effect_forgotten", key };
|
|
444
|
+
mirror = applyAppliedEvent(mirror, event);
|
|
445
|
+
return { event };
|
|
446
|
+
},
|
|
447
|
+
applied() {
|
|
448
|
+
return mirror;
|
|
449
|
+
},
|
|
450
|
+
isApplied(key) {
|
|
451
|
+
return mirror.has(key);
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// src/do/presence.ts
|
|
457
|
+
var WS_READY_STATE_OPEN = 1;
|
|
458
|
+
function broadcastFrame(sockets, frame, options) {
|
|
459
|
+
const serialize = options?.serialize ?? JSON.stringify;
|
|
460
|
+
const except = options?.except;
|
|
461
|
+
const json = serialize(frame);
|
|
462
|
+
let sent = 0;
|
|
463
|
+
let skipped = 0;
|
|
464
|
+
for (const ws of sockets) {
|
|
465
|
+
if (except !== void 0 && ws === except) {
|
|
466
|
+
skipped++;
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
if (ws.readyState !== void 0 && ws.readyState !== WS_READY_STATE_OPEN) {
|
|
470
|
+
skipped++;
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
try {
|
|
474
|
+
ws.send(json);
|
|
475
|
+
sent++;
|
|
476
|
+
} catch {
|
|
477
|
+
skipped++;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return { sent, skipped };
|
|
481
|
+
}
|
|
482
|
+
function registerHibernatableSocket(ctx, server, options) {
|
|
483
|
+
ctx.acceptWebSocket(
|
|
484
|
+
server,
|
|
485
|
+
options?.tags === void 0 ? void 0 : [...options.tags]
|
|
486
|
+
);
|
|
487
|
+
if (options?.attachment !== void 0) {
|
|
488
|
+
server.serializeAttachment(options.attachment);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
function acceptPresenceSocket(ctx, options) {
|
|
492
|
+
const pair = new WebSocketPair();
|
|
493
|
+
const client = pair[0];
|
|
494
|
+
const server = pair[1];
|
|
495
|
+
registerHibernatableSocket(ctx, server, options);
|
|
496
|
+
return {
|
|
497
|
+
server,
|
|
498
|
+
response: new Response(null, { status: 101, webSocket: client })
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
function presenceCount(ctx, tag) {
|
|
502
|
+
return ctx.getWebSockets(tag).length;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// src/do/projection.ts
|
|
506
|
+
function projectionIdString(id) {
|
|
507
|
+
return `${id.name}-${id.key}`;
|
|
508
|
+
}
|
|
509
|
+
function runProjection(projection, startOffset = 0) {
|
|
510
|
+
let view = projection.initial;
|
|
511
|
+
let storedOffset = startOffset;
|
|
512
|
+
return {
|
|
513
|
+
id: projection.id,
|
|
514
|
+
view: () => view,
|
|
515
|
+
offset: () => storedOffset,
|
|
516
|
+
present(update) {
|
|
517
|
+
if (update.offset <= storedOffset) return false;
|
|
518
|
+
const next = projection.apply(view, update);
|
|
519
|
+
view = next;
|
|
520
|
+
storedOffset = update.offset;
|
|
521
|
+
projection.emit(next);
|
|
522
|
+
return true;
|
|
523
|
+
},
|
|
524
|
+
reset() {
|
|
525
|
+
view = projection.initial;
|
|
526
|
+
storedOffset = 0;
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
function projectionRegistry() {
|
|
531
|
+
const runners = /* @__PURE__ */ new Set();
|
|
532
|
+
let counter = -1;
|
|
533
|
+
return {
|
|
534
|
+
register(projection, startOffset) {
|
|
535
|
+
const runner = runProjection(projection, startOffset);
|
|
536
|
+
runners.add(runner);
|
|
537
|
+
return runner;
|
|
538
|
+
},
|
|
539
|
+
dispatch(msg, model) {
|
|
540
|
+
const offset = ++counter;
|
|
541
|
+
const update = { msg, model, offset };
|
|
542
|
+
for (const runner of runners) {
|
|
543
|
+
try {
|
|
544
|
+
runner.present(update);
|
|
545
|
+
} catch {
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
return offset;
|
|
549
|
+
},
|
|
550
|
+
offset: () => counter,
|
|
551
|
+
runners: () => [...runners]
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
function driveProjections(registry, runtime) {
|
|
555
|
+
const unboot = runtime.onBoot((model) => {
|
|
556
|
+
registry.dispatch(null, model);
|
|
557
|
+
});
|
|
558
|
+
const unobserve = runtime.observe((msg, model) => {
|
|
559
|
+
registry.dispatch(msg, model);
|
|
560
|
+
});
|
|
561
|
+
return () => {
|
|
562
|
+
unobserve();
|
|
563
|
+
unboot();
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
function rebuildProjection(projection, updates) {
|
|
567
|
+
const runner = runProjection(projection, 0);
|
|
568
|
+
updates.forEach((u, i) => {
|
|
569
|
+
runner.present({ msg: u.msg, model: u.model, offset: i + 1 });
|
|
570
|
+
});
|
|
571
|
+
return runner;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// src/do/step-host.ts
|
|
575
|
+
function mintRunToken(randomBytes = defaultRandomBytes) {
|
|
576
|
+
const bytes = randomBytes(32);
|
|
577
|
+
let hex = "";
|
|
578
|
+
for (const b of bytes) hex += b.toString(16).padStart(2, "0");
|
|
579
|
+
return hex;
|
|
580
|
+
}
|
|
581
|
+
function defaultRandomBytes(n) {
|
|
582
|
+
const out = new Uint8Array(n);
|
|
583
|
+
crypto.getRandomValues(out);
|
|
584
|
+
return out;
|
|
585
|
+
}
|
|
586
|
+
function constantTimeEqual(a, b) {
|
|
587
|
+
const lengthMatches = a.length === b.length;
|
|
588
|
+
const rhs = lengthMatches ? b : a;
|
|
589
|
+
let diff = 0;
|
|
590
|
+
for (let i = 0; i < a.length; i++) {
|
|
591
|
+
diff |= a.charCodeAt(i) ^ rhs.charCodeAt(i);
|
|
592
|
+
}
|
|
593
|
+
return diff === 0 && lengthMatches;
|
|
594
|
+
}
|
|
595
|
+
var DEFAULT_GIVE_UP_MS = 5 * 6e4;
|
|
596
|
+
function stepHost(ctx, engine, config = {}) {
|
|
597
|
+
const giveUpAfterMs = config.giveUpAfterMs ?? DEFAULT_GIVE_UP_MS;
|
|
598
|
+
const intake = createIntake({
|
|
599
|
+
keyOf: (posted) => posted.callId
|
|
600
|
+
});
|
|
601
|
+
let intakeState = intake.init();
|
|
602
|
+
async function handle(request, now) {
|
|
603
|
+
const stored = await engine.tokenFor(request.runId);
|
|
604
|
+
if (stored === null) {
|
|
605
|
+
return { status: 404, body: { error: "unknown run" } };
|
|
606
|
+
}
|
|
607
|
+
if (!constantTimeEqual(request.token, stored)) {
|
|
608
|
+
return { status: 401, body: { error: "invalid token" } };
|
|
609
|
+
}
|
|
610
|
+
await ctx.storage.setAlarm(now + giveUpAfterMs);
|
|
611
|
+
const posted = request.posted;
|
|
612
|
+
if (posted !== null) {
|
|
613
|
+
const [nextIntake, cmds] = intake.receive(
|
|
614
|
+
intakeState,
|
|
615
|
+
posted,
|
|
616
|
+
now,
|
|
617
|
+
posted.callId
|
|
618
|
+
);
|
|
619
|
+
intakeState = nextIntake;
|
|
620
|
+
for (const cmd of cmds) {
|
|
621
|
+
if (cmd.type === "intake:process") {
|
|
622
|
+
await engine.resume(request.runId, posted);
|
|
623
|
+
const [completed] = intake.complete(
|
|
624
|
+
intakeState,
|
|
625
|
+
cmd.key,
|
|
626
|
+
"settled",
|
|
627
|
+
now
|
|
628
|
+
);
|
|
629
|
+
intakeState = completed;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
const next = await engine.nextStep(request.runId);
|
|
634
|
+
if (next === null) {
|
|
635
|
+
const output = await engine.terminalOutput(request.runId);
|
|
636
|
+
return { status: 200, body: { done: true, output } };
|
|
637
|
+
}
|
|
638
|
+
return { status: 200, body: { done: false, step: next } };
|
|
48
639
|
}
|
|
49
|
-
return
|
|
640
|
+
return { handle };
|
|
641
|
+
}
|
|
642
|
+
async function runStepLoop(token, runId, transport, execute, config) {
|
|
643
|
+
const policy = config.retry ?? defaultRetryPolicy;
|
|
644
|
+
const now = config.now ?? Date.now;
|
|
645
|
+
const sleep = config.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
646
|
+
const rng = config.rng;
|
|
647
|
+
const executed = /* @__PURE__ */ new Map();
|
|
648
|
+
let posted = null;
|
|
649
|
+
for (; ; ) {
|
|
650
|
+
if (now() >= config.deadlineMs) return { kind: "deadline_exceeded" };
|
|
651
|
+
let response;
|
|
652
|
+
let retry = initRetry();
|
|
653
|
+
for (; ; ) {
|
|
654
|
+
try {
|
|
655
|
+
response = await transport({ token, runId, posted });
|
|
656
|
+
break;
|
|
657
|
+
} catch (error) {
|
|
658
|
+
retry = recordFailure(retry, error);
|
|
659
|
+
if (!shouldRetry(retry, policy)) return { kind: "gave_up", error };
|
|
660
|
+
if (now() >= config.deadlineMs) return { kind: "deadline_exceeded" };
|
|
661
|
+
await sleep(nextDelayMs(retry, policy, rng));
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
if (response.done) return { kind: "done", output: response.output };
|
|
665
|
+
const step = response.step;
|
|
666
|
+
const cached = executed.get(step.callId);
|
|
667
|
+
const result = cached !== void 0 ? cached : await execute(step);
|
|
668
|
+
if (cached === void 0) executed.set(step.callId, result);
|
|
669
|
+
posted = { callId: step.callId, result };
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// src/do/index.ts
|
|
674
|
+
var DEFAULT_STATE_KEY = "@@state";
|
|
675
|
+
function doStore(storage, parse, keyOrOptions = DEFAULT_STATE_KEY) {
|
|
676
|
+
const options = typeof keyOrOptions === "string" ? { key: keyOrOptions } : keyOrOptions;
|
|
677
|
+
const key = options.key ?? DEFAULT_STATE_KEY;
|
|
678
|
+
const serialize = options.serialize ?? ((state) => state);
|
|
679
|
+
return {
|
|
680
|
+
async load() {
|
|
681
|
+
const raw = await storage.get(key);
|
|
682
|
+
if (raw === void 0 || raw === null) return null;
|
|
683
|
+
return JSON.parse(raw);
|
|
684
|
+
},
|
|
685
|
+
async save(state) {
|
|
686
|
+
await storage.put(key, JSON.stringify(serialize(state)));
|
|
687
|
+
},
|
|
688
|
+
migrate(raw) {
|
|
689
|
+
return parse(raw);
|
|
690
|
+
}
|
|
691
|
+
};
|
|
50
692
|
}
|
|
51
693
|
|
|
52
|
-
export { doStore,
|
|
694
|
+
export { WS_READY_STATE_OPEN, acceptCommandSocket, acceptDurableCommandSocket, acceptPresenceSocket, agentIsResumable, appliedEffects, applyAppliedEvent, autoBoot, bootResume, broadcast, broadcastFrame, broadcastHibernatable, constantTimeEqual, createAgentHost, deferredGateway, doEventSourcedStore, doStore, driveProjections, durableCommandCarrier, durableDeferredGateway, durableTimer, emptyApplied, foldApplied, idempotentEffect, isApplied, mintRunToken, presenceCount, projectionIdString, projectionRegistry, rebuildProjection, registerHibernatableSocket, reissueSurvivingEffects, runProjection, runStepLoop, sseFromAgentEvents, sseHub, sseProjection, stepHost };
|
|
53
695
|
//# sourceMappingURL=index.js.map
|
|
54
696
|
//# sourceMappingURL=index.js.map
|