@demlik/tea 0.1.2 → 0.3.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 +49 -0
- package/dist/agent/index.d.ts +16 -770
- package/dist/agent/index.js +18 -16
- package/dist/authed-call/index.d.ts +3 -3
- package/dist/authed-call/index.js +22 -36
- package/dist/authed-call/index.js.map +1 -1
- package/dist/await-terminal/index.d.ts +2 -2
- package/dist/await-terminal/index.js +2 -2
- package/dist/batch-window/index.d.ts +3 -3
- package/dist/batch-window/index.js +3 -3
- package/dist/cache/index.d.ts +2 -2
- package/dist/cache/index.js +5 -2
- package/dist/{chunk-3545BOYL.js → chunk-25LBDCBC.js} +6 -5
- package/dist/chunk-25LBDCBC.js.map +1 -0
- package/dist/{chunk-IN33Q4VJ.js → chunk-2KNLKQVN.js} +3 -3
- package/dist/{chunk-IN33Q4VJ.js.map → chunk-2KNLKQVN.js.map} +1 -1
- package/dist/{chunk-MMH7CW5K.js → chunk-BP2R7TPP.js} +216 -157
- package/dist/chunk-BP2R7TPP.js.map +1 -0
- package/dist/chunk-C6QC273X.js +71 -0
- package/dist/chunk-C6QC273X.js.map +1 -0
- package/dist/{chunk-7W4LMPUW.js → chunk-CAXMQJJ3.js} +17 -24
- package/dist/chunk-CAXMQJJ3.js.map +1 -0
- package/dist/{chunk-UV6UWGEO.js → chunk-D736QUGF.js} +6 -5
- package/dist/chunk-D736QUGF.js.map +1 -0
- package/dist/chunk-EWJP3YYP.js +21 -0
- package/dist/chunk-EWJP3YYP.js.map +1 -0
- package/dist/{chunk-TGG26XMK.js → chunk-FV3Z5MBE.js} +10 -5
- package/dist/chunk-FV3Z5MBE.js.map +1 -0
- package/dist/chunk-G5E74IJB.js +8 -0
- package/dist/chunk-G5E74IJB.js.map +1 -0
- package/dist/{chunk-27N2SPTN.js → chunk-IXBKFQH5.js} +12 -11
- package/dist/chunk-IXBKFQH5.js.map +1 -0
- package/dist/{chunk-SQTCS44W.js → chunk-JFFVBEDI.js} +3 -3
- package/dist/{chunk-SQTCS44W.js.map → chunk-JFFVBEDI.js.map} +1 -1
- package/dist/chunk-LYLDCIPH.js +365 -0
- package/dist/chunk-LYLDCIPH.js.map +1 -0
- package/dist/{chunk-HJO6VNQI.js → chunk-MU6MCIAC.js} +3 -3
- package/dist/{chunk-HJO6VNQI.js.map → chunk-MU6MCIAC.js.map} +1 -1
- package/dist/{chunk-UYWUVEP6.js → chunk-MUUROGIH.js} +2 -2
- package/dist/chunk-MUUROGIH.js.map +1 -0
- package/dist/{chunk-EHIX7NYZ.js → chunk-MVY5DAMF.js} +4 -4
- package/dist/{chunk-EHIX7NYZ.js.map → chunk-MVY5DAMF.js.map} +1 -1
- package/dist/{chunk-LP7VQBRG.js → chunk-NPERUUUE.js} +76 -95
- package/dist/chunk-NPERUUUE.js.map +1 -0
- package/dist/{chunk-QLA76GIT.js → chunk-PBDYW2TU.js} +68 -9
- package/dist/chunk-PBDYW2TU.js.map +1 -0
- package/dist/{chunk-5VNWZADP.js → chunk-Q2UM7BXU.js} +18 -7
- package/dist/chunk-Q2UM7BXU.js.map +1 -0
- package/dist/chunk-RMX4EOQK.js +26 -0
- package/dist/chunk-RMX4EOQK.js.map +1 -0
- package/dist/{chunk-2YOE5PIS.js → chunk-S2EGRPCM.js} +8 -6
- package/dist/chunk-S2EGRPCM.js.map +1 -0
- package/dist/{chunk-ON24RKSE.js → chunk-S4O26D7B.js} +7 -14
- package/dist/chunk-S4O26D7B.js.map +1 -0
- package/dist/{chunk-3XJWC7VW.js → chunk-SK5JGUY7.js} +3 -3
- package/dist/{chunk-3XJWC7VW.js.map → chunk-SK5JGUY7.js.map} +1 -1
- package/dist/{chunk-5DEQ5I3U.js → chunk-TPGASTFF.js} +8 -10
- package/dist/chunk-TPGASTFF.js.map +1 -0
- package/dist/{chunk-SC3FAFZN.js → chunk-UF4MZSLT.js} +2 -2
- package/dist/chunk-UF4MZSLT.js.map +1 -0
- package/dist/{chunk-PS23H6KQ.js → chunk-VBUCHVCV.js} +6 -5
- package/dist/chunk-VBUCHVCV.js.map +1 -0
- package/dist/{chunk-S3FQN4SL.js → chunk-WGGAMW7Y.js} +191 -178
- package/dist/chunk-WGGAMW7Y.js.map +1 -0
- package/dist/chunk-ZJ5AOYBH.js +8 -0
- package/dist/chunk-ZJ5AOYBH.js.map +1 -0
- package/dist/{chunk-LEC4U6CX.js → chunk-ZVJZ72HY.js} +3 -3
- package/dist/{chunk-LEC4U6CX.js.map → chunk-ZVJZ72HY.js.map} +1 -1
- package/dist/circuit-breaker/index.d.ts +1 -0
- package/dist/circuit-breaker/index.js +1 -1
- package/dist/{core-BoB6t7dB.d.ts → core-42kapW0n.d.ts} +105 -6
- package/dist/deadline/index.d.ts +77 -11
- package/dist/deadline/index.js +3 -3
- package/dist/devtools/index.js +8 -28
- package/dist/devtools/index.js.map +1 -1
- package/dist/do/index.d.ts +483 -339
- package/dist/do/index.js +244 -214
- package/dist/do/index.js.map +1 -1
- package/dist/{durable-effects-CO9Uh971.d.ts → durable-effects-CFRngTNA.d.ts} +3 -3
- package/dist/extension/index.d.ts +25 -7
- package/dist/extension/index.js +4 -3
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/react.js +4 -3
- package/dist/extension/react.js.map +1 -1
- package/dist/extension/subs/index.d.ts +2 -2
- package/dist/extension/subs/index.js +7 -10
- package/dist/extension/subs/index.js.map +1 -1
- package/dist/fan-out/index.d.ts +10 -10
- package/dist/fan-out/index.js +3 -3
- package/dist/idempotent-intake/index.d.ts +2 -2
- package/dist/idempotent-intake/index.js +3 -3
- package/dist/index.d.ts +50 -472
- package/dist/index.js +2 -2
- package/dist/llm-call/index.d.ts +3 -2
- package/dist/llm-call/index.js +12 -10
- package/dist/machine-B_BF4jij.d.ts +804 -0
- package/dist/machine-viz/index.d.ts +1 -1
- package/dist/machine-viz/index.js +2 -2
- package/dist/mem/index.d.ts +3 -2
- package/dist/mem/index.js.map +1 -1
- package/dist/monitored-run/index.d.ts +54 -30
- package/dist/monitored-run/index.js +7 -7
- package/dist/node/index.d.ts +3 -2
- package/dist/node/index.js +2 -3
- package/dist/node/index.js.map +1 -1
- package/dist/paginated-walk/index.d.ts +2 -2
- package/dist/paginated-walk/index.js +11 -10
- package/dist/parity/index.d.ts +6 -5
- package/dist/parity/index.js +5 -4
- package/dist/parity/index.js.map +1 -1
- package/dist/pbt/arbitraries/index.d.ts +1 -1
- package/dist/pbt/index.d.ts +1 -1
- package/dist/pbt/index.js +3 -3
- package/dist/pbt/index.js.map +1 -1
- package/dist/pbt/runners/index.d.ts +1 -1
- package/dist/pbt/runners/index.js +3 -3
- package/dist/poller/index.d.ts +59 -17
- package/dist/poller/index.js +56 -20
- package/dist/poller/index.js.map +1 -1
- package/dist/prediction/index.d.ts +1 -1
- package/dist/prediction/index.js +2 -2
- package/dist/pure/index.d.ts +1 -1
- package/dist/pure/index.js +2 -2
- package/dist/rate-limit/index.d.ts +2 -2
- package/dist/rate-limit/index.js +1 -1
- package/dist/react/index.d.ts +3 -2
- package/dist/react/index.js +2 -2
- package/dist/react/index.js.map +1 -1
- package/dist/reconciler/index.d.ts +2 -2
- package/dist/reconciler/index.js +13 -15
- package/dist/reconciler/index.js.map +1 -1
- package/dist/recorder/index.d.ts +20 -20
- package/dist/recorder/index.js +1 -1
- package/dist/resilient-call/index.d.ts +31 -6
- package/dist/resilient-call/index.js +10 -9
- package/dist/retry-backoff/index.d.ts +191 -14
- package/dist/retry-backoff/index.js +1 -1
- package/dist/retry-to-success/index.js +1 -1
- package/dist/runtime-types-gsog27b6.d.ts +337 -0
- package/dist/saga/index.d.ts +3 -2
- package/dist/saga/index.js +2 -2
- package/dist/saga/index.js.map +1 -1
- package/dist/snapshot/index.d.ts +1 -1
- package/dist/snapshot/index.js +3 -3
- package/dist/subs/index.d.ts +372 -4
- package/dist/subs/index.js +4 -1
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js +2 -2
- package/dist/throttled-input/index.d.ts +2 -2
- package/dist/throttled-input/index.js +14 -13
- package/dist/throttled-input/index.js.map +1 -1
- package/dist/token-refresh/index.d.ts +1 -1
- package/dist/token-refresh/index.js +3 -3
- package/dist/trace-replay/index.d.ts +12 -7
- package/dist/trace-replay/index.js +4 -3
- package/dist/{types-B-8bcAp8.d.ts → types-KbL3W1mj.d.ts} +1 -1
- package/dist/with-deadline/index.d.ts +1 -1
- package/dist/with-deadline/index.js +2 -2
- package/dist/with-resilience/index.d.ts +21 -2
- package/dist/with-resilience/index.js +12 -23
- package/dist/with-resilience/index.js.map +1 -1
- package/dist/with-telemetry/index.d.ts +1 -1
- package/dist/with-telemetry/index.js +2 -2
- package/dist/work-queue/adapter.d.ts +2 -2
- package/dist/work-queue/adapter.js +2 -2
- package/dist/work-queue/index.d.ts +3 -2
- package/dist/work-queue/index.js +1 -1
- package/dist/work-queue/index.js.map +1 -1
- package/dist/work-queue/ops.d.ts +2 -2
- package/dist/work-queue/ops.js +1 -1
- package/dist/workflow/index.d.ts +51 -19
- package/dist/workflow/index.js +71 -52
- package/dist/workflow/index.js.map +1 -1
- package/package.json +4 -19
- package/dist/chunk-27N2SPTN.js.map +0 -1
- package/dist/chunk-2YOE5PIS.js.map +0 -1
- package/dist/chunk-3545BOYL.js.map +0 -1
- package/dist/chunk-5DEQ5I3U.js.map +0 -1
- package/dist/chunk-5VNWZADP.js.map +0 -1
- package/dist/chunk-6RGBKODV.js +0 -268
- package/dist/chunk-6RGBKODV.js.map +0 -1
- package/dist/chunk-7W4LMPUW.js.map +0 -1
- package/dist/chunk-DILMKOZ7.js +0 -91
- package/dist/chunk-DILMKOZ7.js.map +0 -1
- package/dist/chunk-K7Q23EQ4.js +0 -20
- package/dist/chunk-K7Q23EQ4.js.map +0 -1
- package/dist/chunk-LP7VQBRG.js.map +0 -1
- package/dist/chunk-MMH7CW5K.js.map +0 -1
- package/dist/chunk-NSDFA6M6.js +0 -198
- package/dist/chunk-NSDFA6M6.js.map +0 -1
- package/dist/chunk-ON24RKSE.js.map +0 -1
- package/dist/chunk-PS23H6KQ.js.map +0 -1
- package/dist/chunk-QLA76GIT.js.map +0 -1
- package/dist/chunk-S3FQN4SL.js.map +0 -1
- package/dist/chunk-SC3FAFZN.js.map +0 -1
- package/dist/chunk-TGG26XMK.js.map +0 -1
- package/dist/chunk-UV6UWGEO.js.map +0 -1
- package/dist/chunk-UYWUVEP6.js.map +0 -1
- package/dist/chunk-VLGARN6H.js +0 -202
- package/dist/chunk-VLGARN6H.js.map +0 -1
- package/dist/raft/demo.d.ts +0 -105
- package/dist/raft/demo.js +0 -172
- package/dist/raft/demo.js.map +0 -1
- package/dist/raft/index.d.ts +0 -548
- package/dist/raft/index.js +0 -7
- package/dist/raft/index.js.map +0 -1
- package/dist/raft/sim.d.ts +0 -222
- package/dist/raft/sim.js +0 -8
- package/dist/raft/sim.js.map +0 -1
- package/dist/raft/timeline.d.ts +0 -46
- package/dist/raft/timeline.js +0 -62
- package/dist/raft/timeline.js.map +0 -1
package/dist/do/index.js
CHANGED
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
import { status, agentBootMsg, agentEvents } from '../chunk-
|
|
2
|
-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
|
|
5
|
-
import '../chunk-
|
|
6
|
-
import '../chunk-
|
|
1
|
+
import { status, agentBootMsg, agentEvents } from '../chunk-WGGAMW7Y.js';
|
|
2
|
+
export { applyEffectEvent, emptyLedger, foldLedger, isOwed, pendingEffectsLedger, survivingEffects } from '../chunk-25LBDCBC.js';
|
|
3
|
+
import '../chunk-CAXMQJJ3.js';
|
|
4
|
+
import '../chunk-VBUCHVCV.js';
|
|
5
|
+
import '../chunk-MVY5DAMF.js';
|
|
6
|
+
import '../chunk-IXBKFQH5.js';
|
|
7
7
|
import '../chunk-JELSZN25.js';
|
|
8
|
-
import '../chunk-
|
|
9
|
-
import { createIntake } from '../chunk-
|
|
10
|
-
import '../chunk-
|
|
11
|
-
import { defaultRetryPolicy, initRetry, recordFailure, shouldRetry, nextDelayMs } from '../chunk-
|
|
12
|
-
import '../chunk-
|
|
8
|
+
import '../chunk-D736QUGF.js';
|
|
9
|
+
import { createIntake } from '../chunk-ZVJZ72HY.js';
|
|
10
|
+
import '../chunk-RMX4EOQK.js';
|
|
11
|
+
import { defaultRetryPolicy, initRetry, recordFailure, shouldRetry, nextDelayMs } from '../chunk-Q2UM7BXU.js';
|
|
12
|
+
import '../chunk-S2EGRPCM.js';
|
|
13
13
|
import '../chunk-BYQUGDD3.js';
|
|
14
14
|
import '../chunk-K575PT4S.js';
|
|
15
|
-
import '../chunk-
|
|
16
|
-
import '../chunk-
|
|
17
|
-
import '../chunk-
|
|
18
|
-
import '../chunk-
|
|
19
|
-
import '../chunk-
|
|
15
|
+
import '../chunk-UF4MZSLT.js';
|
|
16
|
+
import '../chunk-2KNLKQVN.js';
|
|
17
|
+
import '../chunk-MU6MCIAC.js';
|
|
18
|
+
import '../chunk-FV3Z5MBE.js';
|
|
19
|
+
import '../chunk-LYLDCIPH.js';
|
|
20
20
|
import '../chunk-2YFLOCWX.js';
|
|
21
|
-
import
|
|
22
|
-
import '../chunk-
|
|
21
|
+
import '../chunk-ZJ5AOYBH.js';
|
|
22
|
+
import '../chunk-G5E74IJB.js';
|
|
23
|
+
import { replay, run } from '../chunk-BP2R7TPP.js';
|
|
24
|
+
import '../chunk-PBDYW2TU.js';
|
|
23
25
|
|
|
24
26
|
// src/do/durable-timer.ts
|
|
25
27
|
function durableTimer(config) {
|
|
@@ -69,6 +71,10 @@ function doEventSourcedStore(storage, machine, ctx, opts = {}) {
|
|
|
69
71
|
const meta = JSON.parse(raw);
|
|
70
72
|
return typeof meta.lastSeq === "number" ? meta.lastSeq : 0;
|
|
71
73
|
}
|
|
74
|
+
async function ensureLastSeq() {
|
|
75
|
+
if (lastSeq === null) lastSeq = await readMeta();
|
|
76
|
+
return lastSeq;
|
|
77
|
+
}
|
|
72
78
|
async function readSnapshot() {
|
|
73
79
|
const raw = await storage.get(snapshotKey);
|
|
74
80
|
if (raw === void 0 || raw === null) return { state: null, seq: 0 };
|
|
@@ -126,8 +132,7 @@ function doEventSourcedStore(storage, machine, ctx, opts = {}) {
|
|
|
126
132
|
snapshotSeq = seq;
|
|
127
133
|
}
|
|
128
134
|
async function append(msg) {
|
|
129
|
-
|
|
130
|
-
const seq = lastSeq + 1;
|
|
135
|
+
const seq = await ensureLastSeq() + 1;
|
|
131
136
|
lastSeq = seq;
|
|
132
137
|
await storage.put(eventKey(eventPrefix, seq), JSON.stringify(msg));
|
|
133
138
|
await storage.put(
|
|
@@ -139,95 +144,15 @@ function doEventSourcedStore(storage, machine, ctx, opts = {}) {
|
|
|
139
144
|
}
|
|
140
145
|
}
|
|
141
146
|
async function snapshotNow() {
|
|
142
|
-
|
|
143
|
-
if (latestState === null ||
|
|
144
|
-
await writeSnapshot(
|
|
147
|
+
const seq = await ensureLastSeq();
|
|
148
|
+
if (latestState === null || seq <= snapshotSeq) return false;
|
|
149
|
+
await writeSnapshot(seq, latestState);
|
|
145
150
|
return true;
|
|
146
151
|
}
|
|
147
152
|
return { store, append, snapshotNow, readEvents };
|
|
148
153
|
}
|
|
149
154
|
|
|
150
|
-
// src/do/
|
|
151
|
-
function deferredGateway() {
|
|
152
|
-
const pending = /* @__PURE__ */ new Map();
|
|
153
|
-
return {
|
|
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);
|
|
208
|
-
}
|
|
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
|
-
}
|
|
155
|
+
// src/do/resume.ts
|
|
231
156
|
async function bootResume(booting, port, now = Date.now) {
|
|
232
157
|
const runtime = await booting.ready;
|
|
233
158
|
if (port.isResumable(runtime.getState())) {
|
|
@@ -244,44 +169,6 @@ async function autoBoot(booting, now = Date.now) {
|
|
|
244
169
|
now
|
|
245
170
|
);
|
|
246
171
|
}
|
|
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
172
|
function reissueSurvivingEffects(carrier, reissue) {
|
|
286
173
|
const reemitted = [];
|
|
287
174
|
for (const { effect } of carrier.recorder.surviving()) {
|
|
@@ -290,6 +177,8 @@ function reissueSurvivingEffects(carrier, reissue) {
|
|
|
290
177
|
}
|
|
291
178
|
return reemitted;
|
|
292
179
|
}
|
|
180
|
+
|
|
181
|
+
// src/do/sse.ts
|
|
293
182
|
function sseHub() {
|
|
294
183
|
const sinks = /* @__PURE__ */ new Set();
|
|
295
184
|
const encoder = new TextEncoder();
|
|
@@ -361,13 +250,14 @@ function sseFromAgentEvents(runtime, hub, toFrame) {
|
|
|
361
250
|
for (const off of offs) off();
|
|
362
251
|
};
|
|
363
252
|
}
|
|
253
|
+
|
|
254
|
+
// src/do/agent-host.ts
|
|
364
255
|
function createAgentHost(config) {
|
|
365
256
|
const sse = sseHub();
|
|
366
257
|
const now = config.now ?? Date.now;
|
|
367
258
|
const isTerminal = config.terminal ?? ((s) => s.run.phase === "done" || s.run.phase === "failed");
|
|
368
259
|
let cached = null;
|
|
369
|
-
async function
|
|
370
|
-
if (cached !== null) return cached;
|
|
260
|
+
async function build() {
|
|
371
261
|
const booting = run(config.buildMachine(), {
|
|
372
262
|
ctx: config.ctx,
|
|
373
263
|
store: config.store,
|
|
@@ -376,7 +266,15 @@ function createAgentHost(config) {
|
|
|
376
266
|
});
|
|
377
267
|
sseFromAgentEvents(booting, sse, config.toSseFrame);
|
|
378
268
|
await autoBoot(booting, now);
|
|
379
|
-
|
|
269
|
+
return booting.ready;
|
|
270
|
+
}
|
|
271
|
+
function runtime() {
|
|
272
|
+
if (cached !== null) return cached;
|
|
273
|
+
const building = build();
|
|
274
|
+
cached = building;
|
|
275
|
+
building.catch(() => {
|
|
276
|
+
if (cached === building) cached = null;
|
|
277
|
+
});
|
|
380
278
|
return cached;
|
|
381
279
|
}
|
|
382
280
|
return {
|
|
@@ -390,11 +288,171 @@ function createAgentHost(config) {
|
|
|
390
288
|
sse,
|
|
391
289
|
async reset() {
|
|
392
290
|
if (cached === null) return;
|
|
393
|
-
await cached.
|
|
291
|
+
const built = await cached.catch(() => null);
|
|
394
292
|
cached = null;
|
|
293
|
+
await built?.stop();
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// src/do/presence.ts
|
|
299
|
+
var WS_READY_STATE_OPEN = 1;
|
|
300
|
+
function broadcastFrame(sockets, frame, options) {
|
|
301
|
+
const serialize = options?.serialize ?? JSON.stringify;
|
|
302
|
+
const except = options?.except;
|
|
303
|
+
const json = serialize(frame);
|
|
304
|
+
let sent = 0;
|
|
305
|
+
let skipped = 0;
|
|
306
|
+
for (const ws of sockets) {
|
|
307
|
+
if (except !== void 0 && ws === except) {
|
|
308
|
+
skipped++;
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
if (ws.readyState !== void 0 && ws.readyState !== WS_READY_STATE_OPEN) {
|
|
312
|
+
skipped++;
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
try {
|
|
316
|
+
ws.send(json);
|
|
317
|
+
sent++;
|
|
318
|
+
} catch {
|
|
319
|
+
skipped++;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return { sent, skipped };
|
|
323
|
+
}
|
|
324
|
+
function registerHibernatableSocket(ctx, server, options) {
|
|
325
|
+
ctx.acceptWebSocket(
|
|
326
|
+
server,
|
|
327
|
+
options?.tags === void 0 ? void 0 : [...options.tags]
|
|
328
|
+
);
|
|
329
|
+
if (options?.attachment !== void 0) {
|
|
330
|
+
server.serializeAttachment(options.attachment);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
function acceptPresenceSocket(ctx, options) {
|
|
334
|
+
const pair = new WebSocketPair();
|
|
335
|
+
const client = pair[0];
|
|
336
|
+
const server = pair[1];
|
|
337
|
+
registerHibernatableSocket(ctx, server, options);
|
|
338
|
+
return {
|
|
339
|
+
server,
|
|
340
|
+
response: new Response(null, { status: 101, webSocket: client })
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
function presenceCount(ctx, tag) {
|
|
344
|
+
return ctx.getWebSockets(tag).length;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// src/do/command-socket.ts
|
|
348
|
+
function acceptCommandSocket(clients, onFrame) {
|
|
349
|
+
const pair = new WebSocketPair();
|
|
350
|
+
const [client, server] = [pair[0], pair[1]];
|
|
351
|
+
server.accept();
|
|
352
|
+
clients.add(server);
|
|
353
|
+
server.addEventListener("message", (ev) => {
|
|
354
|
+
if (typeof ev.data === "string") onFrame(ev.data);
|
|
355
|
+
});
|
|
356
|
+
server.addEventListener("close", () => clients.delete(server));
|
|
357
|
+
return new Response(null, { status: 101, webSocket: client });
|
|
358
|
+
}
|
|
359
|
+
function broadcast(clients, frame) {
|
|
360
|
+
broadcastFrame(clients, frame);
|
|
361
|
+
}
|
|
362
|
+
function acceptDurableCommandSocket(ctx) {
|
|
363
|
+
const pair = new WebSocketPair();
|
|
364
|
+
const [client, server] = [pair[0], pair[1]];
|
|
365
|
+
ctx.acceptWebSocket(server);
|
|
366
|
+
return new Response(null, { status: 101, webSocket: client });
|
|
367
|
+
}
|
|
368
|
+
function broadcastHibernatable(ctx, frame) {
|
|
369
|
+
broadcastFrame(ctx.getWebSockets(), frame);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// src/do/deferred-gateway.ts
|
|
373
|
+
function deferredGateway() {
|
|
374
|
+
const pending = /* @__PURE__ */ new Map();
|
|
375
|
+
return {
|
|
376
|
+
await(callId, send, deadlineMs) {
|
|
377
|
+
const existing = pending.get(callId);
|
|
378
|
+
if (existing !== void 0) return existing.promise;
|
|
379
|
+
let resolve;
|
|
380
|
+
let reject;
|
|
381
|
+
const promise = new Promise((res, rej) => {
|
|
382
|
+
resolve = res;
|
|
383
|
+
reject = rej;
|
|
384
|
+
});
|
|
385
|
+
const timer = setTimeout(() => {
|
|
386
|
+
if (pending.delete(callId)) {
|
|
387
|
+
reject(new Error(`deadline_exceeded after ${deadlineMs}ms`));
|
|
388
|
+
}
|
|
389
|
+
}, deadlineMs);
|
|
390
|
+
pending.set(callId, {
|
|
391
|
+
resolve: (v) => {
|
|
392
|
+
clearTimeout(timer);
|
|
393
|
+
resolve(v);
|
|
394
|
+
},
|
|
395
|
+
reject: (e) => {
|
|
396
|
+
clearTimeout(timer);
|
|
397
|
+
reject(e);
|
|
398
|
+
},
|
|
399
|
+
promise
|
|
400
|
+
});
|
|
401
|
+
send();
|
|
402
|
+
return promise;
|
|
403
|
+
},
|
|
404
|
+
settle(callId, result) {
|
|
405
|
+
const entry = pending.get(callId);
|
|
406
|
+
if (entry === void 0) return;
|
|
407
|
+
pending.delete(callId);
|
|
408
|
+
entry.resolve(result);
|
|
409
|
+
},
|
|
410
|
+
fail(callId, reason) {
|
|
411
|
+
const entry = pending.get(callId);
|
|
412
|
+
if (entry === void 0) return;
|
|
413
|
+
pending.delete(callId);
|
|
414
|
+
entry.reject(new Error(reason));
|
|
415
|
+
},
|
|
416
|
+
inFlight() {
|
|
417
|
+
return [...pending.keys()];
|
|
395
418
|
}
|
|
396
419
|
};
|
|
397
420
|
}
|
|
421
|
+
function durableDeferredGateway(inner, recorder, hooks) {
|
|
422
|
+
const idByCallId = /* @__PURE__ */ new Map();
|
|
423
|
+
return {
|
|
424
|
+
recorder,
|
|
425
|
+
await(callId, send, deadlineMs) {
|
|
426
|
+
if (!idByCallId.has(callId)) {
|
|
427
|
+
const { id, event } = recorder.owe({ callId });
|
|
428
|
+
idByCallId.set(callId, id);
|
|
429
|
+
hooks.recordOwed(callId, event);
|
|
430
|
+
}
|
|
431
|
+
return inner.await(callId, send, deadlineMs);
|
|
432
|
+
},
|
|
433
|
+
settle(callId, result) {
|
|
434
|
+
confirm(callId);
|
|
435
|
+
inner.settle(callId, result);
|
|
436
|
+
},
|
|
437
|
+
fail(callId, reason) {
|
|
438
|
+
confirm(callId);
|
|
439
|
+
inner.fail(callId, reason);
|
|
440
|
+
},
|
|
441
|
+
inFlight() {
|
|
442
|
+
return inner.inFlight();
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
function confirm(callId) {
|
|
446
|
+
const id = idByCallId.get(callId);
|
|
447
|
+
if (id === void 0) return;
|
|
448
|
+
idByCallId.delete(callId);
|
|
449
|
+
const { event } = recorder.confirm(id);
|
|
450
|
+
hooks.recordConfirmed(callId, event);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
function durableCommandCarrier(inner, recorder, hooks) {
|
|
454
|
+
return durableDeferredGateway(inner, recorder, hooks);
|
|
455
|
+
}
|
|
398
456
|
|
|
399
457
|
// src/do/idempotent-effect.ts
|
|
400
458
|
function emptyApplied() {
|
|
@@ -453,55 +511,6 @@ function appliedEffects(restore) {
|
|
|
453
511
|
};
|
|
454
512
|
}
|
|
455
513
|
|
|
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
514
|
// src/do/projection.ts
|
|
506
515
|
function projectionIdString(id) {
|
|
507
516
|
return `${id.name}-${id.key}`;
|
|
@@ -527,7 +536,7 @@ function runProjection(projection, startOffset = 0) {
|
|
|
527
536
|
}
|
|
528
537
|
};
|
|
529
538
|
}
|
|
530
|
-
function projectionRegistry() {
|
|
539
|
+
function projectionRegistry(onError) {
|
|
531
540
|
const runners = /* @__PURE__ */ new Set();
|
|
532
541
|
let counter = -1;
|
|
533
542
|
return {
|
|
@@ -542,7 +551,8 @@ function projectionRegistry() {
|
|
|
542
551
|
for (const runner of runners) {
|
|
543
552
|
try {
|
|
544
553
|
runner.present(update);
|
|
545
|
-
} catch {
|
|
554
|
+
} catch (err) {
|
|
555
|
+
onError?.(err, { id: runner.id });
|
|
546
556
|
}
|
|
547
557
|
}
|
|
548
558
|
return offset;
|
|
@@ -593,8 +603,12 @@ function constantTimeEqual(a, b) {
|
|
|
593
603
|
return diff === 0 && lengthMatches;
|
|
594
604
|
}
|
|
595
605
|
var DEFAULT_GIVE_UP_MS = 5 * 6e4;
|
|
606
|
+
function workingBody(retryAfterMs) {
|
|
607
|
+
return retryAfterMs === void 0 ? { done: false, working: true } : { done: false, working: true, retryAfterMs };
|
|
608
|
+
}
|
|
596
609
|
function stepHost(ctx, engine, config = {}) {
|
|
597
610
|
const giveUpAfterMs = config.giveUpAfterMs ?? DEFAULT_GIVE_UP_MS;
|
|
611
|
+
const deferResume = "deferResume" in config ? config.deferResume : null;
|
|
598
612
|
const intake = createIntake({
|
|
599
613
|
keyOf: (posted) => posted.callId
|
|
600
614
|
});
|
|
@@ -610,23 +624,31 @@ function stepHost(ctx, engine, config = {}) {
|
|
|
610
624
|
await ctx.storage.setAlarm(now + giveUpAfterMs);
|
|
611
625
|
const posted = request.posted;
|
|
612
626
|
if (posted !== null) {
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
627
|
+
if (deferResume === null) {
|
|
628
|
+
const [nextIntake, cmds] = intake.receive(
|
|
629
|
+
intakeState,
|
|
630
|
+
posted,
|
|
631
|
+
now,
|
|
632
|
+
posted.callId
|
|
633
|
+
);
|
|
634
|
+
intakeState = nextIntake;
|
|
635
|
+
for (const cmd of cmds) {
|
|
636
|
+
if (cmd.type === "intake:process") {
|
|
637
|
+
await engine.resume(request.runId, posted);
|
|
638
|
+
const [completed] = intake.complete(
|
|
639
|
+
intakeState,
|
|
640
|
+
cmd.key,
|
|
641
|
+
"settled",
|
|
642
|
+
now
|
|
643
|
+
);
|
|
644
|
+
intakeState = completed;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
} else {
|
|
648
|
+
const ready = await deferResume.settled(request.runId, posted.callId);
|
|
649
|
+
if (!ready) {
|
|
650
|
+
await deferResume.enqueue(request.runId, posted);
|
|
651
|
+
return { status: 200, body: workingBody(deferResume.retryAfterMs) };
|
|
630
652
|
}
|
|
631
653
|
}
|
|
632
654
|
}
|
|
@@ -646,6 +668,7 @@ async function runStepLoop(token, runId, transport, execute, config) {
|
|
|
646
668
|
const rng = config.rng;
|
|
647
669
|
const executed = /* @__PURE__ */ new Map();
|
|
648
670
|
let posted = null;
|
|
671
|
+
let pollRetry = initRetry();
|
|
649
672
|
for (; ; ) {
|
|
650
673
|
if (now() >= config.deadlineMs) return { kind: "deadline_exceeded" };
|
|
651
674
|
let response;
|
|
@@ -662,6 +685,13 @@ async function runStepLoop(token, runId, transport, execute, config) {
|
|
|
662
685
|
}
|
|
663
686
|
}
|
|
664
687
|
if (response.done) return { kind: "done", output: response.output };
|
|
688
|
+
if ("working" in response) {
|
|
689
|
+
pollRetry = recordFailure(pollRetry, "working");
|
|
690
|
+
if (now() >= config.deadlineMs) return { kind: "deadline_exceeded" };
|
|
691
|
+
await sleep(response.retryAfterMs ?? nextDelayMs(pollRetry, policy, rng));
|
|
692
|
+
continue;
|
|
693
|
+
}
|
|
694
|
+
pollRetry = initRetry();
|
|
665
695
|
const step = response.step;
|
|
666
696
|
const cached = executed.get(step.callId);
|
|
667
697
|
const result = cached !== void 0 ? cached : await execute(step);
|