@voltro/workflow 0.69.1 → 0.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4842 @@
1
+ import { E as e, F as t, I as n, L as r, M as i, N as a, P as o, T as s, w as c } from "./primitives-DsMsMr5S.js";
2
+ import { d as l, f as u, h as d, i as f, m as p, p as m, s as h, u as g } from "./clusterDiagnostics-jpkNVay6.js";
3
+ import { Activity as _, DurableClock as v, DurableDeferred as y, Workflow as ee, WorkflowEngine as b } from "@effect/workflow";
4
+ import { Cause as x, Effect as S, Either as C, Exit as te, Fiber as ne, FiberRef as re, Layer as ie, Schema as w } from "effect";
5
+ import { WorkflowQueuedCancellationResultSchema as ae, WorkflowStartTerminalOutcomeSchema as oe, publishServerError as se } from "@voltro/protocol";
6
+ import { and as T, boolean as E, derivedRowId as D, eq as O, generateId as ce, gt as k, gte as le, id as A, inSet as ue, integer as j, isNotNull as de, isNull as M, json as N, lt as fe, or as pe, queryFor as me, reference as he, registerRetention as ge, retentionTtlMsFromEnv as _e, table as P, text as F, timestamp as I } from "@voltro/database";
7
+ import { createHash as ve, randomUUID as L } from "node:crypto";
8
+ import { WorkflowInstance as ye } from "@effect/workflow/WorkflowEngine";
9
+ //#region src/inMemoryLayer.ts
10
+ var be = b.layerMemory, xe = P("_voltro_workflow_runs", {
11
+ id: A({ prefix: "wfrun" }),
12
+ tag: F(),
13
+ executionId: F().unique(),
14
+ status: F().oneOf([
15
+ "running",
16
+ "succeeded",
17
+ "failed",
18
+ "cancelled",
19
+ "suspended"
20
+ ]).default("running"),
21
+ payload: N(),
22
+ workflowVersion: F().nullable(),
23
+ workflowPatches: N().nullable(),
24
+ runnerEnteredAt: I().nullable(),
25
+ runnerGeneration: F().nullable(),
26
+ engineDelivery: N().nullable(),
27
+ reclaimCount: j().default(0),
28
+ output: N().nullable(),
29
+ subject: N().nullable(),
30
+ source: F().nullable(),
31
+ errorTag: F().nullable(),
32
+ errorMessage: F().nullable(),
33
+ cancelled: E().default(!1),
34
+ discardedAt: I().nullable(),
35
+ discardedBy: F().nullable(),
36
+ startedAt: I().default("now"),
37
+ completedAt: I().nullable(),
38
+ durationMs: j().nullable(),
39
+ traceId: F().nullable(),
40
+ parentExecutionId: F().nullable(),
41
+ parentGeneration: F().nullable(),
42
+ parentClosePolicy: F().oneOf([
43
+ "cancel",
44
+ "terminate",
45
+ "abandon"
46
+ ]).nullable()
47
+ }).index(["tag"]).index(["status"]).index(["source"]).index(["startedAt"]).index(["parentExecutionId"]).index(["parentClosePolicy"]), Se = P("_voltro_workflow_run_steps", {
48
+ id: A({ prefix: "wfstep" }),
49
+ runId: he(() => xe, {
50
+ index: !1,
51
+ onDelete: "cascade"
52
+ }),
53
+ stepName: F(),
54
+ attempt: j().default(1),
55
+ status: F().oneOf([
56
+ "running",
57
+ "succeeded",
58
+ "failed"
59
+ ]).default("running"),
60
+ input: N().nullable(),
61
+ retryPolicy: N().nullable(),
62
+ output: N().nullable(),
63
+ errorTag: F().nullable(),
64
+ errorMessage: F().nullable(),
65
+ errorCause: N().nullable(),
66
+ startedAt: I().default("now"),
67
+ completedAt: I().nullable(),
68
+ durationMs: j().nullable()
69
+ }).index(["runId", "stepName"]).index(["startedAt"]), Ce = P("_voltro_workflow_run_events", {
70
+ id: A({ prefix: "wfev" }),
71
+ runId: he(() => xe, {
72
+ index: !1,
73
+ onDelete: "cascade"
74
+ }),
75
+ eventType: F(),
76
+ payload: N().nullable(),
77
+ occurredAt: I().default("now"),
78
+ stepName: F().nullable(),
79
+ attempt: j().nullable()
80
+ }).index(["runId", "occurredAt"]).index(["eventType"]), we = P("_voltro_workflow_start_contexts", {
81
+ id: A({ prefix: "wfctx" }),
82
+ workflowName: F(),
83
+ executionId: F().unique(),
84
+ subject: N().nullable(),
85
+ traceId: F().nullable(),
86
+ source: F().nullable(),
87
+ parentExecutionId: F().nullable(),
88
+ parentGeneration: F().nullable(),
89
+ parentClosePolicy: F().oneOf([
90
+ "cancel",
91
+ "terminate",
92
+ "abandon"
93
+ ]).nullable(),
94
+ createdAt: I().default("now")
95
+ }).index(["workflowName"]).index(["executionId"]).index(["parentExecutionId"]), Te = P("_voltro_workflow_admission_locks", {
96
+ id: A({ prefix: "wfalk" }),
97
+ nonce: F()
98
+ }).nonReactive(), Ee = P("_voltro_workflow_parent_closures", {
99
+ id: A({ prefix: "wfpc" }),
100
+ runId: F(),
101
+ workflowName: F(),
102
+ executionId: F(),
103
+ generation: F(),
104
+ parentStatus: F().oneOf([
105
+ "succeeded",
106
+ "failed",
107
+ "cancelled"
108
+ ]),
109
+ closedAt: I(),
110
+ afterChildId: F().nullable(),
111
+ scanHasOpenChildren: E().default(!1),
112
+ completedAt: I().nullable()
113
+ }).index(["executionId"]).index(["completedAt", "id"]).nonReactive(), De = P("_voltro_workflow_control_requests", {
114
+ id: A({ prefix: "wfctl" }),
115
+ runId: F(),
116
+ workflowName: F(),
117
+ executionId: F(),
118
+ generation: F(),
119
+ operation: F().oneOf([
120
+ "cancel",
121
+ "terminate",
122
+ "resume"
123
+ ]),
124
+ requestedAt: I(),
125
+ owner: N().nullable(),
126
+ cause: N().nullable(),
127
+ parentClosureId: F().nullable(),
128
+ resumeJournal: N().nullable(),
129
+ dispatchAttempts: j().default(0),
130
+ result: N().nullable()
131
+ }).index(["runId"]).index(["parentClosureId", "id"]).nonReactive(), Oe = P("_voltro_workflow_failure_reports", {
132
+ id: A({ prefix: "wffr" }),
133
+ workflowName: F(),
134
+ tenantId: F().nullable(),
135
+ sourceId: F(),
136
+ sourceKind: F().oneOf([
137
+ "submission",
138
+ "intent",
139
+ "run"
140
+ ]),
141
+ handler: F().nullable(),
142
+ callerContext: N().nullable(),
143
+ report: N(),
144
+ handoffReceiptId: F().nullable(),
145
+ handoffAttempt: j().default(0),
146
+ acceptedExecutionId: F().nullable()
147
+ }).index(["sourceKind", "sourceId"]).nonReactive(), ke = P("_voltro_workflow_submissions", {
148
+ id: A({ prefix: "wfsub" }),
149
+ workflowName: F(),
150
+ tenantId: F().nullable(),
151
+ ledgerId: F(),
152
+ executionId: F().nullable(),
153
+ runId: F().nullable(),
154
+ receiptsBound: E().default(!1),
155
+ preparedExecutionId: F().nullable(),
156
+ dispatchAttempts: j().default(0),
157
+ failureId: F().nullable(),
158
+ retry: N(),
159
+ payload: N(),
160
+ callerContext: N().nullable(),
161
+ intentIds: N(),
162
+ eviction: N().nullable()
163
+ }).nonReactive(), Ae = P("_voltro_workflow_start_receipts", {
164
+ id: A({ prefix: "wfrc" }),
165
+ workflowName: F(),
166
+ tenantId: F().nullable(),
167
+ pendingId: F().maxLength(64),
168
+ submissionId: F().maxLength(64).nullable(),
169
+ terminal: N().nullable()
170
+ }).index(["pendingId"]).nonReactive(), je = P("_voltro_workflow_pending", {
171
+ id: A({ prefix: "wfp" }),
172
+ tenantId: F().nullable(),
173
+ workflowName: F(),
174
+ controlKey: F(),
175
+ mode: F().oneOf([
176
+ "debounce",
177
+ "batch",
178
+ "throttle",
179
+ "concurrency",
180
+ "paused",
181
+ "delayed"
182
+ ]),
183
+ payload: N(),
184
+ callerContext: N().nullable(),
185
+ queuedAppVersion: F().nullable(),
186
+ queuedSchemaFingerprint: F().nullable(),
187
+ priority: j().default(0),
188
+ dueAt: I(),
189
+ deadlineAt: I().nullable(),
190
+ collapsed: j().default(1),
191
+ firstSeenAt: I().default("now"),
192
+ updatedAt: I().default("now"),
193
+ attempts: j().default(0),
194
+ lastError: F().nullable(),
195
+ deadLetteredAt: I().nullable()
196
+ }).index(["workflowName", "controlKey"]).index(["dueAt"]).index(["workflowName", "mode"]).index(["tenantId"]), Me = P("_voltro_workflow_admissions", {
197
+ id: A({ prefix: "wfadm" }),
198
+ tenantId: F().nullable(),
199
+ workflowName: F(),
200
+ outcome: F().oneOf([
201
+ "admitted",
202
+ "dropped",
203
+ "skipped",
204
+ "evicted",
205
+ "expired",
206
+ "discarded"
207
+ ]),
208
+ mode: F().nullable(),
209
+ reason: F().nullable(),
210
+ collapsed: j().default(1),
211
+ waitedMs: j().nullable(),
212
+ executionId: F().nullable(),
213
+ runId: F().nullable(),
214
+ singletonKey: F().nullable(),
215
+ concurrencyKey: F().nullable(),
216
+ concurrencyReservation: N().nullable(),
217
+ rateKey: F().nullable(),
218
+ admittedAt: I().default("now"),
219
+ expiresAt: I().nullable(),
220
+ releasedAt: I().nullable()
221
+ }).index(["workflowName", "admittedAt"]).index(["concurrencyKey", "releasedAt"]).index(["singletonKey", "releasedAt"]).index(["rateKey", "admittedAt"]).index(["executionId"]).index(["tenantId"]), Ne = P("_voltro_workflow_pauses", {
222
+ id: A({ prefix: "wfpause" }),
223
+ pausedAt: I().default("now"),
224
+ pausedBy: F().nullable(),
225
+ reason: F().nullable()
226
+ }), Pe = "_voltro_workflow_admission_locks", Fe = "deployment", Ie = async (e, t) => (await e.insertIgnoreWithOutcome(Pe, {
227
+ id: Fe,
228
+ nonce: L()
229
+ }, { conflictColumns: ["id"] }), e.transactional(async (e) => {
230
+ if ((await e.query({
231
+ table: "_voltro_workflow_admission_locks",
232
+ predicate: O("id", Fe),
233
+ lock: "update",
234
+ order: [],
235
+ take: 1,
236
+ skip: void 0,
237
+ projection: void 0
238
+ })).length !== 1) throw Error("Admission coordinator row is missing; refusing an unlocked decision");
239
+ if (await e.update("_voltro_workflow_admission_locks", Fe, { nonce: L() }) === null) throw Error("Admission coordinator row disappeared; refusing an unlocked decision");
240
+ return t(e);
241
+ })), Le = class extends Error {
242
+ workflowName;
243
+ field;
244
+ constructor(e, t, n) {
245
+ super(`workflow '${e}': ${t}(payload) threw — a flow-control key function must be total over every payload the workflow accepts, because it runs before the run exists and there is nowhere to report a partial failure to. Cause: ${n instanceof Error ? n.message : String(n)}`), this.name = "FlowControlKeyError", this.workflowName = e, this.field = t, this.cause = n;
246
+ }
247
+ }, Re = (e, t, n, r) => {
248
+ try {
249
+ let e = n(r);
250
+ if (typeof e != "string" || e.length === 0) throw Error(`returned ${e === "" ? "an empty string" : String(e)}; expected a non-empty string`);
251
+ return e;
252
+ } catch (n) {
253
+ throw new Le(e, t, n);
254
+ }
255
+ }, ze = (e, t) => JSON.stringify([e ?? null, t]), R = (e, t) => {
256
+ let n = e.workflowName, r = 0;
257
+ if (e.priority !== void 0) try {
258
+ let n = e.priority(t);
259
+ if (!Number.isFinite(n)) throw Error(`returned ${String(n)}; expected a finite number`);
260
+ r = Math.trunc(n);
261
+ } catch (e) {
262
+ throw new Le(n, "priority", e);
263
+ }
264
+ return {
265
+ ...e.debounce === void 0 ? {} : { debounceKey: Re(n, "debounce.key", e.debounce.key, t) },
266
+ ...e.singleton === void 0 ? {} : { singletonKey: Re(n, "singleton.key", e.singleton.key, t) },
267
+ ...e.concurrency === void 0 ? {} : { concurrencyKey: ze(e.concurrency.pool, e.concurrency.key === void 0 ? "" : Re(n, "concurrency.key", e.concurrency.key, t)) },
268
+ ...e.throttle?.key === void 0 ? e.throttle === void 0 ? {} : { throttleKey: "" } : { throttleKey: Re(n, "throttle.key", e.throttle.key, t) },
269
+ ...e.rateLimit?.key === void 0 ? e.rateLimit === void 0 ? {} : { rateLimitKey: "" } : { rateLimitKey: Re(n, "rateLimit.key", e.rateLimit.key, t) },
270
+ ...e.batch?.key === void 0 ? e.batch === void 0 ? {} : { batchKey: "" } : { batchKey: Re(n, "batch.key", e.batch.key, t) },
271
+ priority: r
272
+ };
273
+ }, Be = (e, t, n, r) => {
274
+ let i = e.filter((e) => e > r - n);
275
+ if (i.length < t) return;
276
+ let a = [...i].sort((e, t) => t - e)[t - 1];
277
+ if (a !== void 0) return a + n;
278
+ }, Ve = (e) => {
279
+ let { control: t, keys: n, state: r, now: i, reconsidering: a } = e;
280
+ if (r.paused === !0) return {
281
+ kind: "defer",
282
+ mode: "paused",
283
+ dueAt: i,
284
+ collapse: a ? "hold" : "append",
285
+ keys: n
286
+ };
287
+ if (t.rateLimit !== void 0) {
288
+ let e = Be(r.recentAdmissions ?? [], t.rateLimit.limit, t.rateLimit.periodMs, i);
289
+ if (e !== void 0) return {
290
+ kind: "drop",
291
+ reason: "rate-limit",
292
+ retryAfterMs: Math.max(0, e - i),
293
+ keys: n
294
+ };
295
+ }
296
+ if (t.singleton !== void 0 && r.singletonUnacknowledged === !0) return {
297
+ kind: "defer",
298
+ mode: "singleton",
299
+ dueAt: i,
300
+ collapse: a ? "hold" : "append",
301
+ keys: n
302
+ };
303
+ if (t.singleton !== void 0 && t.singleton.mode === "skip" && r.singletonHolder !== void 0) return {
304
+ kind: "skip",
305
+ incumbent: r.singletonHolder,
306
+ keys: n
307
+ };
308
+ if (t.debounce !== void 0) {
309
+ let e = r.debouncePending, o = e?.firstSeenAt ?? i, s = e?.deadlineAt ?? (t.debounce.timeoutMs === void 0 ? void 0 : o + t.debounce.timeoutMs);
310
+ return a ? s !== void 0 && i >= s ? {
311
+ kind: "admit",
312
+ reason: "debounce-deadline",
313
+ keys: n,
314
+ ...Ue(t, r)
315
+ } : {
316
+ kind: "admit",
317
+ reason: "debounce-elapsed",
318
+ keys: n,
319
+ ...Ue(t, r)
320
+ } : {
321
+ kind: "defer",
322
+ mode: "debounce",
323
+ dueAt: s === void 0 ? i + t.debounce.periodMs : Math.min(i + t.debounce.periodMs, s),
324
+ ...s === void 0 ? {} : { deadlineAt: s },
325
+ collapse: "replace",
326
+ keys: n
327
+ };
328
+ }
329
+ if (t.batch !== void 0) {
330
+ let e = r.batchPending, o = (e?.count ?? 0) + +!a, s = (e?.firstSeenAt ?? i) + t.batch.timeoutMs;
331
+ return o >= t.batch.maxSize ? {
332
+ kind: "admit",
333
+ reason: "batch-full",
334
+ keys: n,
335
+ ...Ue(t, r)
336
+ } : a && i >= s ? {
337
+ kind: "admit",
338
+ reason: "batch-timeout",
339
+ keys: n,
340
+ ...Ue(t, r)
341
+ } : {
342
+ kind: "defer",
343
+ mode: "batch",
344
+ dueAt: s,
345
+ collapse: a ? "hold" : "append",
346
+ keys: n
347
+ };
348
+ }
349
+ if (t.throttle !== void 0) {
350
+ let e = Be(r.recentAdmissions ?? [], t.throttle.limit, t.throttle.periodMs, i);
351
+ if (e !== void 0) return {
352
+ kind: "defer",
353
+ mode: "throttle",
354
+ dueAt: e,
355
+ collapse: a ? "hold" : "append",
356
+ keys: n
357
+ };
358
+ }
359
+ return t.concurrency !== void 0 && (r.inFlight ?? 0) >= t.concurrency.limit ? {
360
+ kind: "defer",
361
+ mode: "concurrency",
362
+ dueAt: i,
363
+ collapse: a ? "hold" : "append",
364
+ keys: n
365
+ } : {
366
+ kind: "admit",
367
+ reason: He(t) ? "under-limits" : "no-controls",
368
+ keys: n,
369
+ ...Ue(t, r)
370
+ };
371
+ }, He = (e) => e.debounce !== void 0 || e.singleton !== void 0 || e.concurrency !== void 0 || e.throttle !== void 0 || e.rateLimit !== void 0 || e.batch !== void 0, Ue = (e, t) => e.singleton?.mode === "cancel" && t.singletonHolder !== void 0 ? { evict: t.singletonHolder } : {}, We = (e, t, n) => {
372
+ let r = e.timeouts?.startMs;
373
+ return r !== void 0 && n - t.firstSeenAt >= r;
374
+ }, Ge = (e, t, n) => {
375
+ let r = e.timeouts?.finishMs;
376
+ return r === void 0 || t.terminal ? !1 : n - t.startedAt >= r;
377
+ }, Ke = (e, t) => e.priority === t.priority ? e.firstSeenAt === t.firstSeenAt ? e.id < t.id ? -1 : +(e.id > t.id) : e.firstSeenAt - t.firstSeenAt : t.priority - e.priority, qe = "_voltro_workflow_failure_reports", Je = w.Struct({
378
+ id: w.String,
379
+ workflowName: w.String,
380
+ tenantId: w.NullOr(w.String),
381
+ sourceId: w.String,
382
+ sourceKind: w.Literal("submission", "intent", "run"),
383
+ handler: w.NullOr(w.String),
384
+ callerContext: w.Unknown,
385
+ report: w.Struct({
386
+ workflow: w.String,
387
+ payload: w.Unknown,
388
+ errorTag: w.NullOr(w.String),
389
+ errorMessage: w.NullOr(w.String),
390
+ runId: w.NullOr(w.String),
391
+ executionId: w.NullOr(w.String),
392
+ reason: w.String,
393
+ failedAt: w.Number
394
+ })
395
+ }), z = async (e, t) => {
396
+ let n = await e.query({
397
+ table: qe,
398
+ predicate: O("id", t),
399
+ order: [],
400
+ take: 1,
401
+ skip: void 0,
402
+ projection: void 0
403
+ });
404
+ return n[0] === void 0 ? void 0 : w.decodeUnknownSync(Je)(n[0]);
405
+ }, Ye = async (e, t) => {
406
+ if (t.id.length === 0 || t.sourceId.length === 0) throw Error("Workflow failure requires a stable report and source identity");
407
+ let n = await z(e, t.id);
408
+ if (n !== void 0) {
409
+ if (n.workflowName !== t.workflowName || n.tenantId !== t.tenantId || n.sourceId !== t.sourceId || n.sourceKind !== t.sourceKind) throw Error("Workflow failure identity belongs to a different source, workflow or tenant");
410
+ return n;
411
+ }
412
+ let r = w.decodeUnknownSync(Je)(t);
413
+ if (r.report.workflow !== r.workflowName) throw Error("Workflow failure report does not describe its owning workflow");
414
+ return await e.insert(qe, {
415
+ ...r,
416
+ handoffReceiptId: null,
417
+ handoffAttempt: 0,
418
+ acceptedExecutionId: null
419
+ }), r;
420
+ }, Xe = async (e, t, n) => {
421
+ let r, i = t === "submissionId" ? O(t, n) : T(O(t, n), M("submissionId"), M("terminal"));
422
+ for (;;) {
423
+ let t = await e.query({
424
+ table: Tt,
425
+ predicate: r === void 0 ? i : T(i, k("id", r)),
426
+ order: [{
427
+ column: "id",
428
+ direction: "asc"
429
+ }],
430
+ take: 100,
431
+ skip: void 0,
432
+ projection: void 0
433
+ });
434
+ if (t.length === 0) return !1;
435
+ for (let n of t) {
436
+ let t = V(n), i = await e.query({
437
+ table: qe,
438
+ predicate: O("handoffReceiptId", t.id),
439
+ order: [],
440
+ take: 1,
441
+ skip: void 0,
442
+ projection: void 0
443
+ });
444
+ if (i.length !== 0) {
445
+ if (i[0]?.handler !== t.workflowName || i[0]?.tenantId !== t.tenantId) throw Error("Failure delivery receipt belongs to a different workflow or tenant");
446
+ return !0;
447
+ }
448
+ r = t.id;
449
+ }
450
+ }
451
+ }, Ze = (e, t) => Xe(e, "submissionId", t), Qe = (e, t) => Xe(e, "pendingId", t), $e = async (e, t, n, r) => {
452
+ for await (let i of ft(e, t, n)) {
453
+ if (i.tenantId !== r) throw Error("Failure delivery belongs to a different resident tenant");
454
+ if (await Ze(e, i.id)) return !0;
455
+ }
456
+ return !1;
457
+ }, et = w.Struct({
458
+ handoffReceiptId: w.NullOr(w.String),
459
+ handoffAttempt: w.NonNegativeInt,
460
+ acceptedExecutionId: w.NullOr(w.NonEmptyString)
461
+ }), tt = (e, t) => `wfrc_${ve("sha256").update(JSON.stringify([
462
+ "failure",
463
+ e,
464
+ t
465
+ ])).digest("hex").slice(0, 40)}`, nt = async (e, t) => {
466
+ let n = await e.query({
467
+ table: qe,
468
+ predicate: O("id", t),
469
+ order: [],
470
+ take: 1,
471
+ skip: void 0,
472
+ projection: void 0
473
+ }), r = w.decodeUnknownSync(et)(n[0]);
474
+ if (r.handoffReceiptId === null && (r.handoffAttempt !== 0 || r.acceptedExecutionId !== null)) throw Error("Failure report has contradictory unstarted handoff metadata");
475
+ return r;
476
+ }, rt = async (e, t, n, r, i) => {
477
+ if (t.handler === null || t.handler.length === 0) throw Error("Cannot queue an unconfigured failure handler");
478
+ if (!Number.isSafeInteger(n) || n < 0) throw Error("Failure handoff attempt exhausted");
479
+ if (!Number.isFinite(r)) throw Error("Failure handoff retry deadline is invalid");
480
+ let a = await Ht({
481
+ store: e,
482
+ workflowName: t.handler,
483
+ payload: t.report,
484
+ callerContext: t.callerContext,
485
+ tenantId: t.tenantId,
486
+ at: r,
487
+ now: i
488
+ }), o = await kt(e, {
489
+ id: tt(t.id, n),
490
+ workflowName: t.handler,
491
+ tenantId: t.tenantId,
492
+ pendingId: a.intentId
493
+ });
494
+ if (await e.update("_voltro_workflow_failure_reports", t.id, {
495
+ handoffReceiptId: o.id,
496
+ handoffAttempt: n
497
+ }) === null) throw Error("Failure report disappeared during durable handoff");
498
+ return {
499
+ kind: "queued",
500
+ receiptId: o.id,
501
+ intentId: o.pendingId
502
+ };
503
+ }, it = async (e, t, n) => {
504
+ if (!Number.isFinite(n)) throw Error("Failure handoff requires a finite timestamp");
505
+ let r = await z(e, t);
506
+ if (r === void 0) throw Error("Cannot hand off an unknown workflow failure");
507
+ let { handoffReceiptId: i, handoffAttempt: a, acceptedExecutionId: o } = await nt(e, t);
508
+ if (r.handler === null) {
509
+ if (i !== null || o !== null) throw Error("Unconfigured failure report has a contradictory handoff");
510
+ return { kind: "unconfigured" };
511
+ }
512
+ if (r.handler.length === 0) throw Error("Failure report has an empty handler");
513
+ let s = tt(t, a);
514
+ if (i !== null) {
515
+ if (i !== s) throw Error("Failure handoff receipt belongs to a different report");
516
+ let t = await Dt(e, i);
517
+ if (t === void 0 || t.workflowName !== r.handler || t.tenantId !== r.tenantId) throw Error("Failure report has no matching durable start receipt");
518
+ return {
519
+ kind: "queued",
520
+ receiptId: t.id,
521
+ intentId: t.pendingId
522
+ };
523
+ }
524
+ return rt(e, r, 0, n, n);
525
+ }, at = class extends Error {
526
+ reason;
527
+ constructor(e) {
528
+ super(`Workflow failure delivery requires reconciliation: ${e}`), this.reason = e;
529
+ }
530
+ }, ot = async (e, t, n) => {
531
+ let r = await it(e, t, n);
532
+ if (r.kind === "unconfigured") return r;
533
+ let i = await nt(e, t), a = await Dt(e, r.receiptId);
534
+ if (a === void 0) throw Error("Failure handoff receipt disappeared during reconciliation");
535
+ if (i.acceptedExecutionId !== null) {
536
+ if (a.terminal !== null || a.submissionId === null) throw Error("Accepted failure report has no submitted receipt");
537
+ return {
538
+ kind: "accepted",
539
+ executionId: i.acceptedExecutionId
540
+ };
541
+ }
542
+ if (a.terminal !== null) {
543
+ if (a.terminal.kind === "cancelled") return {
544
+ kind: "cancelled",
545
+ receiptId: a.id
546
+ };
547
+ let r = await z(e, t);
548
+ if (r === void 0) throw Error("Failure report disappeared during retry");
549
+ let o = i.handoffAttempt + 1, s = Math.max(Zt(o, () => 1), a.terminal.kind === "dropped" ? a.terminal.retryAfterMs : 0);
550
+ return rt(e, r, o, Math.max(n, a.terminal.at + s), n);
551
+ }
552
+ if (a.submissionId === null) {
553
+ let t = (await e.query({
554
+ table: U,
555
+ predicate: O("id", a.pendingId),
556
+ order: [],
557
+ take: 1,
558
+ skip: void 0,
559
+ projection: void 0
560
+ }))[0];
561
+ if (t === void 0) throw new at("arrival-missing");
562
+ if (t.workflowName !== a.workflowName || t.tenantId !== a.tenantId) throw new at("arrival-owner-mismatch");
563
+ if (t.deadLetteredAt !== null) throw new at("arrival-dead-lettered");
564
+ return r;
565
+ }
566
+ let o = await B(e, a.submissionId);
567
+ if (o === void 0 || !o.receiptsBound || o.workflowName !== a.workflowName || o.tenantId !== a.tenantId || !o.intentIds.includes(a.pendingId)) throw Error("Failure handoff receipt has no matching admission submission");
568
+ if (o.failureId !== null) {
569
+ let r = await z(e, o.failureId);
570
+ if (o.executionId !== null || o.dispatchAttempts > 1 || r === void 0 || r.sourceKind !== "submission" || r.sourceId !== o.id || r.workflowName !== o.workflowName || r.tenantId !== o.tenantId || r.report.executionId !== null || r.report.runId !== null) throw new at("rejection-proof-invalid");
571
+ let a = await z(e, t);
572
+ if (a === void 0) throw Error("Failure report disappeared during rejected handler retry");
573
+ let s = i.handoffAttempt + 1;
574
+ return rt(e, a, s, Math.max(n, r.report.failedAt + Zt(s, () => 1)), n);
575
+ }
576
+ if (o.executionId === null) return r;
577
+ if (o.failureId !== null || o.executionId.length === 0 || o.preparedExecutionId !== o.executionId) throw Error("Failure handler acknowledgement contradicts its prepared submission");
578
+ if (await e.update("_voltro_workflow_failure_reports", t, { acceptedExecutionId: o.executionId }) === null) throw Error("Failure report disappeared during acceptance acknowledgement");
579
+ return {
580
+ kind: "accepted",
581
+ executionId: o.executionId
582
+ };
583
+ }, st = w.Struct({
584
+ runId: w.NonEmptyString,
585
+ workflowName: w.NonEmptyString,
586
+ executionId: w.NonEmptyString,
587
+ generation: w.NonEmptyString,
588
+ parentStatus: w.Literal("succeeded", "failed", "cancelled"),
589
+ closedAt: w.DateFromSelf
590
+ }), ct = async (e, t, n) => {
591
+ let [r] = await e.query({
592
+ table: "_voltro_workflow_runs",
593
+ predicate: O("executionId", n),
594
+ lock: "update",
595
+ order: [],
596
+ take: 1,
597
+ skip: void 0,
598
+ projection: void 0
599
+ });
600
+ if (r !== void 0) {
601
+ if (r.tag !== t) throw Error("Admission acknowledgement belongs to a different resident workflow");
602
+ if (typeof r.id != "string" || r.id.length === 0) throw Error("Resident execution has no run identity");
603
+ if (r.status === "running" || r.status === "suspended") return {
604
+ runId: r.id,
605
+ completedAt: null
606
+ };
607
+ if (r.status !== "succeeded" && r.status !== "failed" && r.status !== "cancelled") throw Error("Resident execution has an unrecognized status");
608
+ if (!(r.completedAt instanceof Date) || !Number.isFinite(r.completedAt.getTime())) throw Error("Terminal workflow has no valid completion timestamp for lease release");
609
+ return {
610
+ runId: r.id,
611
+ completedAt: r.completedAt
612
+ };
613
+ }
614
+ let [i] = await e.query({
615
+ table: "_voltro_workflow_parent_closures",
616
+ predicate: O("executionId", n),
617
+ lock: "update",
618
+ order: [{
619
+ column: "closedAt",
620
+ direction: "desc"
621
+ }, {
622
+ column: "id",
623
+ direction: "desc"
624
+ }],
625
+ take: 1,
626
+ skip: void 0,
627
+ projection: void 0
628
+ });
629
+ if (i === void 0) return;
630
+ let a = w.decodeUnknownSync(st)(i);
631
+ if (a.workflowName !== t || a.executionId !== n) throw Error("Admission acknowledgement belongs to a different resident workflow");
632
+ if (!Number.isFinite(a.closedAt.getTime())) throw Error("Workflow closure has no valid completion timestamp");
633
+ return {
634
+ runId: a.runId,
635
+ completedAt: a.closedAt
636
+ };
637
+ }, lt = "_voltro_workflow_submissions", ut = w.Struct({
638
+ id: w.String,
639
+ workflowName: w.String,
640
+ tenantId: w.NullOr(w.String),
641
+ ledgerId: w.String,
642
+ preparedExecutionId: w.NullOr(w.String),
643
+ executionId: w.NullOr(w.String),
644
+ runId: w.NullOr(w.String),
645
+ receiptsBound: w.Boolean,
646
+ dispatchAttempts: w.NonNegativeInt,
647
+ failureId: w.NullOr(w.String),
648
+ retry: w.Struct({
649
+ attempts: w.Int,
650
+ after: w.Number,
651
+ lastError: w.NullOr(w.String),
652
+ stoppedAt: w.NullOr(w.Number)
653
+ }),
654
+ payload: w.Unknown,
655
+ callerContext: w.Unknown,
656
+ intentIds: w.Array(w.String),
657
+ eviction: w.NullOr(w.Struct({
658
+ executionId: w.String,
659
+ runId: w.String
660
+ }))
661
+ }), dt = w.decodeUnknownSync(ut);
662
+ async function* ft(e, t, n) {
663
+ let r;
664
+ for (;;) {
665
+ let i = T(O("preparedExecutionId", t), k("dispatchAttempts", 0)), a = await e.query({
666
+ table: lt,
667
+ predicate: r === void 0 ? i : T(i, k("id", r)),
668
+ order: [{
669
+ column: "id",
670
+ direction: "asc"
671
+ }],
672
+ take: 100,
673
+ skip: void 0,
674
+ projection: void 0
675
+ });
676
+ if (a.length === 0) return;
677
+ for (let e of a) {
678
+ let i = dt(e);
679
+ if (i.workflowName !== n || !i.receiptsBound || i.failureId !== null || i.executionId !== null && i.executionId !== t) throw Error("Workflow completion has an inconsistent resident submission owner");
680
+ yield i, r = i.id;
681
+ }
682
+ }
683
+ }
684
+ var pt = async (e, t, n) => (await mt(e, t, n)).map((e) => dt(e)), mt = async (e, t, n) => {
685
+ if (!Number.isSafeInteger(t) || t < 1) throw Error("Submission recovery requires a positive page size");
686
+ return e.query({
687
+ table: lt,
688
+ predicate: n === void 0 ? T(O("receiptsBound", !0), M("executionId"), M("failureId")) : T(O("receiptsBound", !0), M("executionId"), M("failureId"), k("id", n)),
689
+ order: [{
690
+ column: "id",
691
+ direction: "asc"
692
+ }],
693
+ take: t,
694
+ skip: void 0,
695
+ projection: void 0
696
+ });
697
+ }, B = async (e, t) => {
698
+ let n = await e.query({
699
+ table: lt,
700
+ predicate: O("id", t),
701
+ order: [],
702
+ take: 1,
703
+ skip: void 0,
704
+ projection: void 0
705
+ });
706
+ return n[0] === void 0 ? void 0 : w.decodeUnknownSync(ut)(n[0]);
707
+ }, ht = async (e, t) => Ie(e, (e) => gt(e, t)), gt = async (e, t) => {
708
+ if (t.id.length === 0) throw Error("Admission submission requires a stable non-empty identity");
709
+ let n = await e.query({
710
+ table: lt,
711
+ predicate: O("id", t.id),
712
+ order: [],
713
+ take: 1,
714
+ skip: void 0,
715
+ projection: void 0
716
+ });
717
+ if (n[0] !== void 0) {
718
+ let e = w.decodeUnknownSync(ut)(n[0]);
719
+ if (e.workflowName !== t.control.workflowName || e.tenantId !== t.tenantId) throw Error("Admission submission identity belongs to a different workflow or tenant");
720
+ return {
721
+ kind: "reserved",
722
+ submission: e,
723
+ reused: !0
724
+ };
725
+ }
726
+ let r = R(t.control, t.keyPayload), i = await tn({
727
+ store: e,
728
+ control: t.control,
729
+ keys: r,
730
+ paused: t.paused,
731
+ now: t.now,
732
+ reconsidering: !0
733
+ });
734
+ if (i.kind !== "admit") return {
735
+ kind: "not-admitted",
736
+ decision: i
737
+ };
738
+ let a = await Y({
739
+ store: e,
740
+ control: t.control,
741
+ keys: r,
742
+ outcome: "admitted",
743
+ mode: t.mode,
744
+ reason: i.reason,
745
+ collapsed: t.collapsed,
746
+ waitedMs: t.now - t.firstSeenAt,
747
+ executionId: null,
748
+ runId: null,
749
+ tenantId: t.tenantId,
750
+ now: t.now
751
+ });
752
+ if (a === void 0) throw Error("Admission reservation has no ledger identity");
753
+ return {
754
+ kind: "reserved",
755
+ submission: await _t(e, {
756
+ id: t.id,
757
+ workflowName: t.control.workflowName,
758
+ tenantId: t.tenantId,
759
+ ledgerId: a,
760
+ payload: t.encodedPayload,
761
+ callerContext: t.callerContext,
762
+ intentIds: t.intentIds,
763
+ eviction: i.evict ?? null
764
+ }),
765
+ reused: !1
766
+ };
767
+ }, _t = async (e, t) => {
768
+ if (t.id.length === 0 || t.ledgerId.length === 0) throw Error("Submission requires its reserved admission identity");
769
+ let n = {
770
+ ...t,
771
+ callerContext: t.callerContext ?? null,
772
+ intentIds: [...t.intentIds],
773
+ preparedExecutionId: null,
774
+ executionId: null,
775
+ runId: null,
776
+ receiptsBound: !1,
777
+ dispatchAttempts: 0,
778
+ failureId: null,
779
+ retry: {
780
+ attempts: 0,
781
+ after: 0,
782
+ lastError: null,
783
+ stoppedAt: null
784
+ }
785
+ };
786
+ return await e.insert(lt, n), n;
787
+ }, vt = async (e, t, n) => Ie(e, (e) => yt(e, t, n)), yt = async (e, t, n) => {
788
+ if (n.executionId.length === 0) throw Error("Engine acknowledgement requires an execution identity");
789
+ let r = await e.query({
790
+ table: lt,
791
+ predicate: O("id", t),
792
+ order: [],
793
+ take: 1,
794
+ skip: void 0,
795
+ projection: void 0
796
+ });
797
+ if (r[0] === void 0) throw Error("Cannot acknowledge an unknown admission submission");
798
+ let i = w.decodeUnknownSync(ut)(r[0]);
799
+ if (i.failureId !== null) throw Error("Cannot acknowledge a permanently rejected admission submission");
800
+ if (i.preparedExecutionId !== null && i.preparedExecutionId !== n.executionId) throw Error("Engine acknowledgement contradicts the prepared execution identity");
801
+ if (i.executionId !== null && i.executionId !== n.executionId || i.runId !== null && n.runId !== null && i.runId !== n.runId) throw Error("Admission submission already belongs to a different execution or run");
802
+ let a = await ct(e, i.workflowName, n.executionId), o = i.runId ?? n.runId;
803
+ if (a !== void 0 && o !== null && a.runId !== o) throw Error("Admission acknowledgement belongs to a different resident run");
804
+ let s = {
805
+ executionId: n.executionId,
806
+ runId: o ?? a?.runId ?? null
807
+ }, c = a?.completedAt ?? void 0;
808
+ if (await e.update("_voltro_workflow_admissions", i.ledgerId, {
809
+ ...s,
810
+ ...c === void 0 ? {} : { releasedAt: c }
811
+ }) === null) throw Error("Admission submission has no lease to acknowledge");
812
+ if (await e.update("_voltro_workflow_submissions", t, s) === null) throw Error("Admission submission disappeared during acknowledgement");
813
+ return {
814
+ ...i,
815
+ ...s
816
+ };
817
+ }, bt = async (e, t, n) => {
818
+ if (n.length === 0) throw Error("Prepared submission requires a non-empty execution identity");
819
+ let r = await B(e, t);
820
+ if (r === void 0) throw Error("Cannot prepare an unknown admission submission");
821
+ if (!r.receiptsBound || r.failureId !== null) throw Error("Cannot prepare an incomplete or terminal admission submission");
822
+ if (r.preparedExecutionId !== null) {
823
+ if (r.executionId !== null && r.executionId !== r.preparedExecutionId) throw Error("Submission acceptance contradicts its prepared identity");
824
+ return r;
825
+ }
826
+ if (r.executionId !== null) throw Error("Cannot prepare an accepted submission without its prepared identity");
827
+ if (r.dispatchAttempts !== 0) throw Error("Cannot choose an execution identity after an unbound dispatch");
828
+ if (r.retry.stoppedAt !== null) throw Error("Cannot prepare a stopped admission submission");
829
+ if (await e.update("_voltro_workflow_submissions", t, { preparedExecutionId: n }) === null) throw Error("Admission submission disappeared while preparing execution");
830
+ return {
831
+ ...r,
832
+ preparedExecutionId: n
833
+ };
834
+ }, xt = async (e, t, n, r, i = !1) => {
835
+ if (i !== !1 && (!Number.isSafeInteger(i) || i < 1)) throw Error("Submission retry limit must be a positive integer or false");
836
+ let a = await B(e, t);
837
+ if (a === void 0) throw Error("Cannot record failure for an unknown submission");
838
+ if (a.executionId !== null || a.failureId !== null || a.retry.stoppedAt !== null) return a;
839
+ let o = a.retry.attempts + 1, s = {
840
+ attempts: o,
841
+ lastError: n,
842
+ after: r + Zt(o),
843
+ stoppedAt: i !== !1 && o >= i ? r : null
844
+ };
845
+ if (await e.update("_voltro_workflow_submissions", t, { retry: s }) === null) throw Error("Admission submission disappeared while recording failure");
846
+ return {
847
+ ...a,
848
+ retry: s
849
+ };
850
+ }, St = async (e, t, n) => {
851
+ let r = await B(e, t);
852
+ if (r === void 0) throw Error("Cannot dispatch an unknown admission submission");
853
+ if (!r.receiptsBound || r.executionId !== null || r.failureId !== null || r.retry.stoppedAt !== null || r.retry.after > n) return null;
854
+ let i = r.dispatchAttempts + 1;
855
+ if (!Number.isSafeInteger(i)) throw Error("Submission dispatch counter exhausted");
856
+ if (await e.update("_voltro_workflow_submissions", t, { dispatchAttempts: i }) === null) throw Error("Admission submission disappeared before dispatch");
857
+ return {
858
+ ...r,
859
+ dispatchAttempts: i
860
+ };
861
+ }, Ct = async (e, t, n, r) => {
862
+ if (!Number.isSafeInteger(n) || n < 0) throw Error("Invalid submission dispatch attempt");
863
+ let i = await B(e, t);
864
+ if (i === void 0) throw Error("Cannot reject an unknown admission submission");
865
+ if (i.failureId !== null) {
866
+ let n = await z(e, i.failureId);
867
+ if (n === void 0 || n.sourceKind !== "submission" || n.sourceId !== t || n.workflowName !== i.workflowName || n.tenantId !== i.tenantId) throw Error("Rejected submission has no matching durable failure report");
868
+ return await it(e, n.id, r.now), n;
869
+ }
870
+ if (!i.receiptsBound || i.executionId !== null || i.dispatchAttempts !== n || n > 1) return;
871
+ let a = `wffr_${ve("sha256").update(JSON.stringify(["submission", t])).digest("hex").slice(0, 40)}`, o = await Ye(e, {
872
+ id: a,
873
+ sourceKind: "submission",
874
+ sourceId: t,
875
+ workflowName: i.workflowName,
876
+ tenantId: i.tenantId,
877
+ handler: await Ze(e, t) ? null : r.handler,
878
+ callerContext: i.callerContext,
879
+ report: {
880
+ workflow: i.workflowName,
881
+ payload: i.payload,
882
+ errorTag: "WorkflowPayloadError",
883
+ errorMessage: r.errorMessage,
884
+ reason: "permanent input rejection before engine acceptance",
885
+ failedAt: r.now,
886
+ runId: null,
887
+ executionId: null
888
+ }
889
+ });
890
+ if (await e.update("_voltro_workflow_admissions", i.ledgerId, { releasedAt: new Date(r.now) }) === null) throw Error("Rejected admission submission has no lease");
891
+ if (await e.update("_voltro_workflow_submissions", t, { failureId: a }) === null) throw Error("Admission submission disappeared during rejection");
892
+ return await it(e, o.id, r.now), o;
893
+ }, wt = async (e, t) => {
894
+ if (t.failureId === null) throw Error("Workflow submission has no rejection marker");
895
+ let n = await z(e, t.failureId);
896
+ if (t.executionId !== null || t.dispatchAttempts > 1 || n === void 0 || n.sourceKind !== "submission" || n.sourceId !== t.id || n.workflowName !== t.workflowName || n.tenantId !== t.tenantId || n.report.executionId !== null || n.report.runId !== null) throw Error("Workflow start rejection has contradictory ownership or execution evidence");
897
+ return n.id;
898
+ }, Tt = "_voltro_workflow_start_receipts", Et = w.Struct({
899
+ id: w.String,
900
+ workflowName: w.String,
901
+ tenantId: w.NullOr(w.String),
902
+ pendingId: w.String,
903
+ submissionId: w.NullOr(w.String),
904
+ terminal: w.NullOr(oe)
905
+ }).pipe(w.filter((e) => e.submissionId === null || e.terminal === null, { message: () => "A start receipt cannot be both submitted and terminal before admission" })), V = w.decodeUnknownSync(Et), Dt = async (e, t) => {
906
+ let n = await e.query({
907
+ table: Tt,
908
+ predicate: O("id", t),
909
+ order: [],
910
+ take: 1,
911
+ skip: void 0,
912
+ projection: void 0
913
+ });
914
+ return n[0] === void 0 ? void 0 : V(n[0]);
915
+ }, Ot = async (e, t) => {
916
+ let n = await Dt(e, t.receiptId);
917
+ if (n === void 0 || n.workflowName !== t.workflowName || n.tenantId !== t.tenantId) throw Error("Workflow start receipt is missing or belongs to another workflow or tenant");
918
+ if (n.terminal !== null) {
919
+ if (n.terminal.kind === "abandoned") {
920
+ let t = await z(e, n.terminal.failureId);
921
+ if (t === void 0 || t.workflowName !== n.workflowName || t.tenantId !== n.tenantId || t.sourceKind !== "intent" || t.report.executionId !== null || t.report.runId !== null) throw Error("Abandoned workflow receipt has no matching failure report");
922
+ }
923
+ return {
924
+ kind: "terminal",
925
+ outcome: n.terminal
926
+ };
927
+ }
928
+ if (n.submissionId === null) {
929
+ let t = await e.query({
930
+ table: U,
931
+ predicate: O("id", n.pendingId),
932
+ order: [],
933
+ take: 1,
934
+ skip: void 0,
935
+ projection: void 0
936
+ });
937
+ if (t[0] === void 0) throw Error("Workflow receipt has no pending input or submission");
938
+ let r = q(t[0]);
939
+ if (r.workflowName !== n.workflowName || r.tenantId !== n.tenantId) throw Error("Workflow receipt pending input belongs to another workflow or tenant");
940
+ if (r.deadLetteredAt !== void 0) throw Error("Workflow receipt input is dead-lettered; reconciliation required");
941
+ return { kind: "pending" };
942
+ }
943
+ let r = await B(e, n.submissionId);
944
+ if (r === void 0 || !r.receiptsBound || r.workflowName !== n.workflowName || r.tenantId !== n.tenantId || !r.intentIds.includes(n.pendingId)) throw Error("Workflow receipt has no matching admission submission");
945
+ if (r.failureId !== null) return {
946
+ kind: "rejected",
947
+ failureId: await wt(e, r)
948
+ };
949
+ if (r.executionId === null) {
950
+ if (r.retry.stoppedAt !== null) throw Error("Workflow start acceptance is unresolved; reconciliation required");
951
+ return { kind: "pending" };
952
+ }
953
+ if (r.executionId.length === 0 || r.executionId !== r.preparedExecutionId) throw Error("Workflow start acknowledgement contradicts its prepared identity");
954
+ return {
955
+ kind: "accepted",
956
+ executionId: r.executionId
957
+ };
958
+ }, kt = async (e, t) => {
959
+ if (t.id.length === 0 || t.id === t.pendingId) throw Error("Workflow start receipt requires an identity distinct from its queue slot");
960
+ let n = V((await e.insertIgnoreWithOutcome(Tt, {
961
+ ...t,
962
+ submissionId: null,
963
+ terminal: null
964
+ }, { conflictColumns: ["id"] })).row);
965
+ if (n.workflowName !== t.workflowName || n.tenantId !== t.tenantId || n.pendingId !== t.pendingId) throw Error("Workflow start receipt identity belongs to a different start");
966
+ return n;
967
+ }, At = async (e, t) => {
968
+ let n = await B(e, t);
969
+ if (n === void 0) throw Error("Cannot bind receipts to an unknown admission submission");
970
+ if (n.receiptsBound) return 0;
971
+ let r = 0;
972
+ for (let t of new Set(n.intentIds)) for (;;) {
973
+ let i = await e.query({
974
+ table: Tt,
975
+ predicate: T(O("pendingId", t), M("submissionId"), M("terminal")),
976
+ order: [{
977
+ column: "id",
978
+ direction: "asc"
979
+ }],
980
+ take: 100,
981
+ skip: void 0,
982
+ projection: void 0
983
+ });
984
+ if (i.length === 0) break;
985
+ for (let t of i) {
986
+ let i = V(t);
987
+ if (i.workflowName !== n.workflowName || i.tenantId !== n.tenantId) throw Error("Pending receipt belongs to a different workflow or tenant");
988
+ if (await e.update("_voltro_workflow_start_receipts", i.id, { submissionId: n.id }) === null) throw Error("Workflow start receipt disappeared during queue transfer");
989
+ r++;
990
+ }
991
+ }
992
+ if (await e.update("_voltro_workflow_submissions", t, { receiptsBound: !0 }) === null) throw Error("Admission submission disappeared during receipt binding");
993
+ return r;
994
+ }, H = async (e, t) => {
995
+ let n = w.decodeUnknownSync(oe)(t.terminal);
996
+ for (;;) {
997
+ let r = await e.query({
998
+ table: Tt,
999
+ predicate: T(O("pendingId", t.pendingId), M("submissionId"), M("terminal")),
1000
+ order: [{
1001
+ column: "id",
1002
+ direction: "asc"
1003
+ }],
1004
+ take: 100,
1005
+ skip: void 0,
1006
+ projection: void 0
1007
+ });
1008
+ if (r.length === 0) return;
1009
+ for (let i of r) {
1010
+ let r = V(i);
1011
+ if (r.workflowName !== t.workflowName || r.tenantId !== t.tenantId) throw Error("Terminal receipt belongs to a different workflow or tenant");
1012
+ if (await e.update("_voltro_workflow_start_receipts", r.id, { terminal: n }) === null) throw Error("Start receipt disappeared while recording its terminal outcome");
1013
+ }
1014
+ }
1015
+ }, U = "_voltro_workflow_pending", W = "_voltro_workflow_admissions", jt = "_voltro_workflow_pauses", Mt = (e, t, n) => e.encodeWorkflowPayload === void 0 ? n : e.encodeWorkflowPayload(t, n), G = (e, t, n) => e.decodeWorkflowPayload === void 0 ? n : e.decodeWorkflowPayload(t, n), Nt = 864e5, Pt = (e, t, n) => `wfp_${ve("sha256").update(`${e}\u0000${t}\u0000${n}`).digest("hex").slice(0, 40)}`, K = (e) => {
1016
+ if (e instanceof Date) return e.getTime();
1017
+ if (typeof e == "number") return e;
1018
+ let t = Date.parse(String(e));
1019
+ return Number.isNaN(t) ? 0 : t;
1020
+ }, Ft = (e, t) => {
1021
+ let n = typeof e == "number" ? e : Number(e);
1022
+ return Number.isFinite(n) ? Math.trunc(n) : t;
1023
+ }, q = (e) => ({
1024
+ id: String(e.id),
1025
+ tenantId: e.tenantId === null || e.tenantId === void 0 ? null : String(e.tenantId),
1026
+ workflowName: String(e.workflowName),
1027
+ controlKey: String(e.controlKey ?? ""),
1028
+ mode: String(e.mode),
1029
+ payload: e.payload,
1030
+ callerContext: e.callerContext ?? null,
1031
+ queuedAppVersion: e.queuedAppVersion === null || e.queuedAppVersion === void 0 ? null : String(e.queuedAppVersion),
1032
+ queuedSchemaFingerprint: e.queuedSchemaFingerprint === null || e.queuedSchemaFingerprint === void 0 ? null : String(e.queuedSchemaFingerprint),
1033
+ priority: Ft(e.priority, 0),
1034
+ dueAt: K(e.dueAt),
1035
+ deadlineAt: e.deadlineAt === null || e.deadlineAt === void 0 ? void 0 : K(e.deadlineAt),
1036
+ collapsed: Ft(e.collapsed, 1),
1037
+ firstSeenAt: K(e.firstSeenAt),
1038
+ attempts: Ft(e.attempts, 0),
1039
+ lastError: e.lastError === null || e.lastError === void 0 ? null : String(e.lastError),
1040
+ deadLetteredAt: e.deadLetteredAt === null || e.deadLetteredAt === void 0 ? void 0 : K(e.deadLetteredAt)
1041
+ }), J = (e, t, n, r) => ({
1042
+ table: e,
1043
+ predicate: t,
1044
+ order: n,
1045
+ take: r,
1046
+ skip: void 0,
1047
+ projection: void 0
1048
+ }), It = async (e) => {
1049
+ let t = await e.query(J(jt, void 0, [], 1e3));
1050
+ return new Set(t.map((e) => String(e.id)));
1051
+ }, Lt = async (e, t, n, r) => {
1052
+ await e.upsert(jt, {
1053
+ id: t,
1054
+ pausedAt: /* @__PURE__ */ new Date(),
1055
+ pausedBy: n,
1056
+ reason: r
1057
+ }, {
1058
+ conflictColumns: ["id"],
1059
+ update: [
1060
+ "pausedAt",
1061
+ "pausedBy",
1062
+ "reason"
1063
+ ]
1064
+ });
1065
+ }, Rt = async (e, t) => e.delete(jt, t), zt = async (e) => {
1066
+ let { store: t, control: n, keys: r, now: i } = e, a = { paused: e.paused }, o = [];
1067
+ n.debounce !== void 0 && r.debounceKey !== void 0 && o.push((async () => {
1068
+ let e = (await t.query(J(U, T(O("workflowName", n.workflowName), O("controlKey", r.debounceKey), O("mode", "debounce")), [], 1)))[0];
1069
+ if (e === void 0) return;
1070
+ let i = e.deadlineAt === null || e.deadlineAt === void 0 ? void 0 : K(e.deadlineAt);
1071
+ a.debouncePending = {
1072
+ firstSeenAt: K(e.firstSeenAt),
1073
+ collapsed: Ft(e.collapsed, 1),
1074
+ ...i === void 0 ? {} : { deadlineAt: i }
1075
+ };
1076
+ })()), n.batch !== void 0 && r.batchKey !== void 0 && o.push((async () => {
1077
+ let e = await t.query(J(U, T(O("workflowName", n.workflowName), O("controlKey", r.batchKey), O("mode", "batch")), [{
1078
+ column: "firstSeenAt",
1079
+ direction: "asc"
1080
+ }], n.batch.maxSize + 1));
1081
+ e.length !== 0 && (a.batchPending = {
1082
+ count: e.length,
1083
+ firstSeenAt: K(e[0].firstSeenAt)
1084
+ });
1085
+ })()), n.singleton !== void 0 && r.singletonKey !== void 0 && o.push((async () => {
1086
+ let e = await Bt(t, n.workflowName, r.singletonKey, i);
1087
+ e === "unacknowledged" ? a.singletonUnacknowledged = !0 : e !== void 0 && (a.singletonHolder = e);
1088
+ })()), n.concurrency !== void 0 && r.concurrencyKey !== void 0 && o.push((async () => {
1089
+ let e = n.concurrency.pool === void 0 ? [O("workflowName", n.workflowName)] : [], o = await t.query(J(W, T(...e, O("concurrencyKey", r.concurrencyKey), M("releasedAt"), pe(M("executionId"), k("expiresAt", new Date(i)))), [], n.concurrency.limit));
1090
+ a.inFlight = o.length;
1091
+ })());
1092
+ let s = n.rateLimit ?? n.throttle, c = r.rateLimitKey ?? r.throttleKey;
1093
+ return s !== void 0 && c !== void 0 && o.push((async () => {
1094
+ let e = await t.query(J(W, T(O("workflowName", n.workflowName), O("rateKey", c), O("outcome", "admitted"), k("admittedAt", new Date(i - s.periodMs))), [{
1095
+ column: "admittedAt",
1096
+ direction: "desc"
1097
+ }], s.limit));
1098
+ a.recentAdmissions = e.map((e) => K(e.admittedAt));
1099
+ })()), await Promise.all(o), a;
1100
+ }, Bt = async (e, t, n, r) => {
1101
+ if ((await e.query(J("_voltro_workflow_admissions", T(O("workflowName", t), O("singletonKey", n), M("releasedAt"), M("executionId")), [], 1))).length > 0) return "unacknowledged";
1102
+ let i = (await e.query(J(W, T(O("workflowName", t), O("singletonKey", n), M("releasedAt"), k("expiresAt", new Date(r))), [{
1103
+ column: "admittedAt",
1104
+ direction: "desc"
1105
+ }], 1)))[0];
1106
+ if (i === void 0) return;
1107
+ let a = i.executionId;
1108
+ if (a != null) return {
1109
+ executionId: String(a),
1110
+ runId: i.runId === null || i.runId === void 0 ? "" : String(i.runId),
1111
+ admittedAt: K(i.admittedAt)
1112
+ };
1113
+ }, Vt = async (e) => {
1114
+ let { store: t, control: n, decision: r, now: i } = e, a = Ut(r.mode, r.keys);
1115
+ if (r.collapse === "hold") {
1116
+ let o = e.existingId ?? Pt(n.workflowName, r.mode, a);
1117
+ return await t.update(U, o, {
1118
+ dueAt: new Date(r.dueAt),
1119
+ updatedAt: new Date(i)
1120
+ }), o;
1121
+ }
1122
+ if (r.collapse === "replace") {
1123
+ let o = Pt(n.workflowName, r.mode, a);
1124
+ return await H(t, {
1125
+ pendingId: o,
1126
+ workflowName: n.workflowName,
1127
+ tenantId: e.tenantId,
1128
+ terminal: {
1129
+ kind: "superseded",
1130
+ at: i
1131
+ }
1132
+ }), await t.upsert(U, {
1133
+ id: o,
1134
+ tenantId: e.tenantId,
1135
+ workflowName: n.workflowName,
1136
+ controlKey: a,
1137
+ mode: r.mode,
1138
+ payload: Mt(t, n.workflowName, e.payload),
1139
+ callerContext: e.callerContext ?? null,
1140
+ queuedAppVersion: e.queuedAppVersion ?? null,
1141
+ queuedSchemaFingerprint: e.queuedSchemaFingerprint ?? null,
1142
+ priority: r.keys.priority,
1143
+ dueAt: new Date(r.dueAt),
1144
+ deadlineAt: r.deadlineAt === void 0 ? null : new Date(r.deadlineAt),
1145
+ collapsed: 1,
1146
+ firstSeenAt: new Date(i),
1147
+ updatedAt: new Date(i),
1148
+ attempts: 0,
1149
+ lastError: null,
1150
+ deadLetteredAt: null
1151
+ }, {
1152
+ conflictColumns: ["id"],
1153
+ update: (a) => ({
1154
+ payload: Mt(t, n.workflowName, e.payload),
1155
+ callerContext: e.callerContext ?? null,
1156
+ queuedAppVersion: e.queuedAppVersion ?? null,
1157
+ queuedSchemaFingerprint: e.queuedSchemaFingerprint ?? null,
1158
+ priority: r.keys.priority,
1159
+ dueAt: new Date(r.dueAt),
1160
+ deadlineAt: r.deadlineAt === void 0 ? a.deadlineAt ?? null : new Date(r.deadlineAt),
1161
+ collapsed: Ft(a.collapsed, 1) + 1,
1162
+ updatedAt: new Date(i),
1163
+ attempts: 0,
1164
+ lastError: null,
1165
+ deadLetteredAt: null
1166
+ })
1167
+ }), o;
1168
+ }
1169
+ let o = await t.insert(U, {
1170
+ id: `wfpi_${L()}`,
1171
+ tenantId: e.tenantId,
1172
+ workflowName: n.workflowName,
1173
+ controlKey: a,
1174
+ mode: r.mode,
1175
+ payload: Mt(t, n.workflowName, e.payload),
1176
+ callerContext: e.callerContext ?? null,
1177
+ queuedAppVersion: e.queuedAppVersion ?? null,
1178
+ queuedSchemaFingerprint: e.queuedSchemaFingerprint ?? null,
1179
+ priority: r.keys.priority,
1180
+ dueAt: new Date(r.dueAt),
1181
+ deadlineAt: r.deadlineAt === void 0 ? null : new Date(r.deadlineAt),
1182
+ collapsed: 1,
1183
+ firstSeenAt: new Date(i),
1184
+ updatedAt: new Date(i),
1185
+ attempts: 0,
1186
+ lastError: null,
1187
+ deadLetteredAt: null
1188
+ });
1189
+ return String(o.id);
1190
+ }, Ht = async (e) => {
1191
+ let t = await e.store.insert(U, {
1192
+ id: `wfpi_${L()}`,
1193
+ tenantId: e.tenantId,
1194
+ workflowName: e.workflowName,
1195
+ controlKey: "",
1196
+ mode: "delayed",
1197
+ payload: Mt(e.store, e.workflowName, e.payload),
1198
+ callerContext: e.callerContext ?? null,
1199
+ queuedAppVersion: e.queuedAppVersion ?? null,
1200
+ queuedSchemaFingerprint: e.queuedSchemaFingerprint ?? null,
1201
+ priority: 0,
1202
+ dueAt: new Date(e.at),
1203
+ deadlineAt: null,
1204
+ collapsed: 1,
1205
+ firstSeenAt: new Date(e.now),
1206
+ updatedAt: new Date(e.now),
1207
+ attempts: 0,
1208
+ lastError: null,
1209
+ deadLetteredAt: null
1210
+ });
1211
+ return {
1212
+ intentId: String(t.id),
1213
+ dueAt: e.at
1214
+ };
1215
+ }, Ut = (e, t) => {
1216
+ switch (e) {
1217
+ case "debounce": return t.debounceKey ?? "";
1218
+ case "batch": return t.batchKey ?? "";
1219
+ case "throttle": return t.throttleKey ?? "";
1220
+ case "concurrency": return t.concurrencyKey ?? "";
1221
+ case "singleton": return t.singletonKey ?? "";
1222
+ default: return "";
1223
+ }
1224
+ }, Y = async (e) => {
1225
+ let { control: t, keys: n, now: r } = e, i = t.timeouts?.finishMs ?? 864e5, a = await e.store.insert(W, {
1226
+ id: `wfad_${L()}`,
1227
+ tenantId: e.tenantId,
1228
+ workflowName: t.workflowName,
1229
+ outcome: e.outcome,
1230
+ mode: e.mode,
1231
+ reason: e.reason,
1232
+ collapsed: e.collapsed,
1233
+ waitedMs: e.waitedMs,
1234
+ executionId: e.executionId,
1235
+ runId: e.runId,
1236
+ singletonKey: n.singletonKey ?? null,
1237
+ concurrencyKey: n.concurrencyKey ?? null,
1238
+ concurrencyReservation: t.concurrency === void 0 ? null : {
1239
+ pool: t.concurrency.pool ?? null,
1240
+ key: n.concurrencyKey ?? null,
1241
+ limit: t.concurrency.limit
1242
+ },
1243
+ rateKey: n.rateLimitKey ?? n.throttleKey ?? null,
1244
+ admittedAt: new Date(r),
1245
+ expiresAt: e.outcome === "admitted" ? new Date(r + i) : null,
1246
+ releasedAt: e.outcome === "admitted" ? null : new Date(r)
1247
+ });
1248
+ return String(a.id);
1249
+ }, Wt = async (e, t, n) => {
1250
+ let r = !1;
1251
+ for (;;) {
1252
+ let i = await e.query(J(W, T(O("executionId", t), O("outcome", "admitted"), M("releasedAt")), [], 10));
1253
+ if (i.length === 0) return r;
1254
+ for (let t of i) if (await e.update("_voltro_workflow_admissions", String(t.id), { releasedAt: new Date(n) }) === null) throw Error("Admission lease disappeared during release");
1255
+ r = !0;
1256
+ }
1257
+ }, Gt = async (e, t, n) => (await Kt(e, t, n)).due, Kt = async (e, t, n) => {
1258
+ let r = (await e.query(J(U, M("deadLetteredAt"), [{
1259
+ column: "priority",
1260
+ direction: "desc"
1261
+ }, {
1262
+ column: "firstSeenAt",
1263
+ direction: "asc"
1264
+ }], n))).map(q), i;
1265
+ for (let e of r) e.dueAt <= t || (i === void 0 || e.dueAt < i) && (i = e.dueAt);
1266
+ return {
1267
+ due: r.filter((e) => e.dueAt <= t).sort(Ke),
1268
+ nextDueAt: i
1269
+ };
1270
+ }, qt = async (e, t) => (await e.query(J(U, void 0, [{
1271
+ column: "firstSeenAt",
1272
+ direction: "asc"
1273
+ }], t))).map(q), Jt = async (e, t) => e.delete(U, t), Yt = async (e, t, n, r) => Ie(e, (e) => Xt(e, t, n, r)), Xt = async (e, t, n, r) => {
1274
+ let i = (await e.query(J(U, O("id", t), [], 1)))[0];
1275
+ if (i === void 0) return !1;
1276
+ let a = q(i);
1277
+ if (await e.insert(W, {
1278
+ id: `wfa_${L()}`,
1279
+ tenantId: a.tenantId,
1280
+ workflowName: a.workflowName,
1281
+ outcome: "discarded",
1282
+ mode: a.mode,
1283
+ reason: n,
1284
+ collapsed: a.collapsed,
1285
+ waitedMs: Math.max(0, r - a.firstSeenAt),
1286
+ executionId: null,
1287
+ runId: null,
1288
+ singletonKey: null,
1289
+ concurrencyKey: a.controlKey === "" ? null : a.controlKey,
1290
+ rateKey: null,
1291
+ admittedAt: new Date(r),
1292
+ expiresAt: null,
1293
+ releasedAt: new Date(r)
1294
+ }), await H(e, {
1295
+ pendingId: t,
1296
+ workflowName: a.workflowName,
1297
+ tenantId: a.tenantId,
1298
+ terminal: {
1299
+ kind: "cancelled",
1300
+ at: r
1301
+ }
1302
+ }), !await e.delete("_voltro_workflow_pending", t)) throw Error("Pending intent disappeared during discard");
1303
+ return !0;
1304
+ }, Zt = (e, t = Math.random) => {
1305
+ let n = Math.min(1e3 * 2 ** Math.max(0, e - 1), 3e5);
1306
+ return Math.round(n / 2 + t() * (n / 2));
1307
+ }, Qt = async (e, t, n, r) => {
1308
+ let i = t.attempts + 1;
1309
+ await e.update(U, t.id, {
1310
+ attempts: i,
1311
+ lastError: n.slice(0, 500),
1312
+ dueAt: new Date(r + Zt(i)),
1313
+ updatedAt: new Date(r)
1314
+ });
1315
+ }, $t = async (e, t, n, r) => await e.update(U, t.id, {
1316
+ attempts: t.attempts + 1,
1317
+ lastError: n.slice(0, 500),
1318
+ deadLetteredAt: new Date(r),
1319
+ updatedAt: new Date(r)
1320
+ }) !== null, en = async (e, t, n) => {
1321
+ let r = (await e.query(J(U, O("id", t), [], 1)))[0];
1322
+ return r === void 0 || r.deadLetteredAt === null || r.deadLetteredAt === void 0 ? !1 : await e.update(U, t, {
1323
+ attempts: 0,
1324
+ lastError: null,
1325
+ deadLetteredAt: null,
1326
+ dueAt: new Date(n),
1327
+ updatedAt: new Date(n)
1328
+ }) !== null;
1329
+ }, tn = async (e) => {
1330
+ let t = await zt({
1331
+ store: e.store,
1332
+ control: e.control,
1333
+ keys: e.keys,
1334
+ now: e.now,
1335
+ paused: e.paused
1336
+ });
1337
+ return Ve({
1338
+ control: e.control,
1339
+ keys: e.keys,
1340
+ state: t,
1341
+ now: e.now,
1342
+ reconsidering: e.reconsidering
1343
+ });
1344
+ }, nn = async (e, t, n = 1e3) => {
1345
+ let r = await e.query(J(W, void 0, [{
1346
+ column: "admittedAt",
1347
+ direction: "asc"
1348
+ }], n)), i = t.getTime(), a = r.filter((e) => e.releasedAt != null && K(e.admittedAt) < i);
1349
+ return await Promise.all(a.map((t) => e.delete(W, String(t.id)))), a.length;
1350
+ }, rn = async (e, t) => {
1351
+ if (!Number.isFinite(t.now) || !Number.isFinite(new Date(t.now).getTime())) throw Error("Queued cancellation requires a valid timestamp");
1352
+ let n = await Dt(e, t.receiptId);
1353
+ if (n === void 0 || n.workflowName !== t.workflowName || n.tenantId !== t.tenantId) throw Error("Queued cancellation receipt is missing or belongs to another workflow or tenant");
1354
+ if (n.terminal !== null) return {
1355
+ kind: "terminal",
1356
+ outcome: n.terminal
1357
+ };
1358
+ if (n.submissionId !== null) {
1359
+ let t = await B(e, n.submissionId);
1360
+ if (t === void 0 || !t.receiptsBound || t.workflowName !== n.workflowName || t.tenantId !== n.tenantId || !t.intentIds.includes(n.pendingId)) throw Error("Queued cancellation receipt has no matching submission");
1361
+ return {
1362
+ kind: "submitted",
1363
+ submissionId: t.id
1364
+ };
1365
+ }
1366
+ let [r] = await e.query({
1367
+ table: U,
1368
+ predicate: O("id", n.pendingId),
1369
+ lock: "update",
1370
+ order: [],
1371
+ take: 1,
1372
+ skip: void 0,
1373
+ projection: void 0
1374
+ });
1375
+ if (r === void 0) throw Error("Queued cancellation has no pending input or submission");
1376
+ let i = q(r);
1377
+ if (i.workflowName !== n.workflowName || i.tenantId !== n.tenantId || i.deadLetteredAt !== void 0) throw Error("Queued cancellation input has contradictory ownership or is dead-lettered");
1378
+ let a = {
1379
+ kind: "cancelled",
1380
+ at: t.now
1381
+ };
1382
+ if (await H(e, {
1383
+ pendingId: n.pendingId,
1384
+ workflowName: n.workflowName,
1385
+ tenantId: n.tenantId,
1386
+ terminal: a
1387
+ }), !await e.delete("_voltro_workflow_pending", n.pendingId)) throw Error("Queued cancellation lost its pending input");
1388
+ return {
1389
+ kind: "terminal",
1390
+ outcome: a
1391
+ };
1392
+ }, an = "_voltro_workflow_parent_closures", X = w.NonEmptyString, on = w.Struct({
1393
+ id: X,
1394
+ runId: X,
1395
+ workflowName: X,
1396
+ executionId: X,
1397
+ generation: X,
1398
+ parentStatus: w.Literal("succeeded", "failed", "cancelled"),
1399
+ closedAt: w.DateFromSelf,
1400
+ afterChildId: w.NullOr(X),
1401
+ scanHasOpenChildren: w.Boolean,
1402
+ completedAt: w.NullOr(w.DateFromSelf)
1403
+ }), sn = w.Struct({
1404
+ id: X,
1405
+ tag: X,
1406
+ executionId: X,
1407
+ status: w.Literal("running", "suspended", "succeeded", "failed", "cancelled"),
1408
+ runnerGeneration: w.optional(w.NullOr(X)),
1409
+ parentGeneration: w.optional(w.NullOr(X)),
1410
+ parentClosePolicy: w.NullOr(w.Literal("cancel", "terminate", "abandon"))
1411
+ }), cn = async (e, t, n) => {
1412
+ if (t.parentClosePolicy !== "cancel" && t.parentClosePolicy !== "terminate") return !1;
1413
+ if (typeof t.parentExecutionId != "string" || t.parentExecutionId.length === 0 || typeof t.parentGeneration != "string" || t.parentGeneration.length === 0) throw Error("Child entry requires its original parent execution and generation");
1414
+ let r = n ?? (await e.query({
1415
+ table: an,
1416
+ predicate: T(O("executionId", t.parentExecutionId), O("generation", t.parentGeneration)),
1417
+ lock: "update",
1418
+ order: [],
1419
+ take: 1,
1420
+ skip: void 0,
1421
+ projection: void 0
1422
+ }))[0];
1423
+ if (r === void 0) return !1;
1424
+ let i = w.decodeUnknownSync(on)(r);
1425
+ if (i.executionId !== t.parentExecutionId || i.generation !== t.parentGeneration) return !1;
1426
+ let a = w.decodeUnknownSync(sn)(t), o = D("wfctl", JSON.stringify([
1427
+ "parent-close",
1428
+ i.id,
1429
+ a.id
1430
+ ])), s = await m(e, o);
1431
+ if (s !== void 0) {
1432
+ if (s.runId !== a.id || s.workflowName !== a.tag || s.executionId !== a.executionId || s.operation === "resume" || s.cause?.reason !== "parent-close" || s.cause.detail?.closureId !== i.id) throw Error("Parent closure receipt belongs to another child");
1433
+ } else {
1434
+ if (a.status !== "running" && a.status !== "suspended") return !1;
1435
+ if (a.runnerGeneration === void 0 || a.runnerGeneration === null) throw Error("Child entry requires its own generation");
1436
+ await h(e, {
1437
+ id: o,
1438
+ runId: a.id,
1439
+ workflowName: a.tag,
1440
+ executionId: a.executionId,
1441
+ generation: a.runnerGeneration,
1442
+ operation: t.parentClosePolicy,
1443
+ requestedAt: i.closedAt.getTime(),
1444
+ cause: {
1445
+ reason: "parent-close",
1446
+ detail: {
1447
+ closureId: i.id,
1448
+ parentRunId: i.runId,
1449
+ parentExecutionId: i.executionId,
1450
+ parentGeneration: i.generation,
1451
+ parentStatus: i.parentStatus,
1452
+ parentClosePolicy: t.parentClosePolicy
1453
+ }
1454
+ }
1455
+ });
1456
+ }
1457
+ return !0;
1458
+ }, ln = async (e, t, n = Date.now()) => {
1459
+ let [r] = await e.query({
1460
+ table: an,
1461
+ predicate: O("id", t),
1462
+ lock: "update",
1463
+ order: [],
1464
+ take: 1,
1465
+ skip: void 0,
1466
+ projection: void 0
1467
+ });
1468
+ if (r === void 0) throw Error("Parent closure is missing");
1469
+ let i = w.decodeUnknownSync(on)(r);
1470
+ if (i.completedAt !== null) return {
1471
+ scanned: 0,
1472
+ controls: 0,
1473
+ wrapped: !1
1474
+ };
1475
+ if (!Number.isFinite(n)) throw Error("Parent closure requires a finite completion timestamp");
1476
+ let a = await e.query({
1477
+ table: "_voltro_workflow_runs",
1478
+ predicate: T(O("parentExecutionId", i.executionId), ...i.afterChildId === null ? [] : [k("id", i.afterChildId)]),
1479
+ lock: "update",
1480
+ order: [{
1481
+ column: "id",
1482
+ direction: "asc"
1483
+ }],
1484
+ take: 100,
1485
+ skip: void 0,
1486
+ projection: void 0
1487
+ }), o = 0, s = i.scanHasOpenChildren, c = null;
1488
+ for (let t of a) {
1489
+ let r = w.decodeUnknownSync(sn)(t);
1490
+ if (c = r.id, r.parentClosePolicy !== null && r.parentClosePolicy !== "abandon") {
1491
+ if (r.parentGeneration === void 0 || r.parentGeneration === null) throw Error("Parent closure cannot attribute a child without its parent generation");
1492
+ r.parentGeneration === i.generation && ((r.status === "running" || r.status === "suspended") && (s = !0), await cn(e, t, i) && (o++, r.status === "suspended" && typeof r.runnerGeneration == "string" && await hn(e, {
1493
+ runId: r.id,
1494
+ workflowName: r.tag,
1495
+ executionId: r.executionId,
1496
+ generation: r.runnerGeneration
1497
+ }, n)));
1498
+ }
1499
+ }
1500
+ let u = a.length < 100, d = u && !s && !await l(e, i.id);
1501
+ if (await e.update(an, i.id, {
1502
+ afterChildId: u ? null : c,
1503
+ scanHasOpenChildren: !u && s,
1504
+ completedAt: d ? new Date(n) : null
1505
+ }) === null) throw Error("Parent closure disappeared before saving its cursor");
1506
+ return {
1507
+ scanned: a.length,
1508
+ controls: o,
1509
+ wrapped: u
1510
+ };
1511
+ }, un = "_voltro_workflow_runs", dn = w.NullOr(w.Struct({
1512
+ requestId: w.NonEmptyString,
1513
+ restartToken: w.NullOr(w.NonEmptyString)
1514
+ })), fn = async (e, t, n, r) => {
1515
+ if (typeof t.id != "string") throw Error("Child entry has no allocated run identity");
1516
+ let i = {
1517
+ runId: t.id,
1518
+ workflowName: n.workflowName,
1519
+ executionId: n.executionId,
1520
+ generation: n.generation
1521
+ }, a = await An(e, i), o = await cn(e, t);
1522
+ if (!a && !o) return;
1523
+ let s = await _n(e, {
1524
+ owner: i,
1525
+ now: n.now,
1526
+ durationMs: 0,
1527
+ outcome: { status: "cancelled" }
1528
+ }, "running");
1529
+ if (s.kind !== "committed") throw Error("Child entry cancellation lost its resident owner");
1530
+ return {
1531
+ kind: "cancelled",
1532
+ row: s.row,
1533
+ previous: r,
1534
+ terminalEvent: s.terminalEvent
1535
+ };
1536
+ }, pn = async (e, t) => {
1537
+ if ([
1538
+ t.workflowName,
1539
+ t.executionId,
1540
+ t.generation
1541
+ ].some((e) => e.length === 0) || typeof t.initialRow.id != "string" || t.initialRow.id.length === 0 || !Number.isFinite(t.now)) throw Error("Workflow entry requires allocated identities and a finite timestamp");
1542
+ let n = (await e.query({
1543
+ table: un,
1544
+ predicate: O("executionId", t.executionId),
1545
+ lock: "update",
1546
+ order: [],
1547
+ take: 1,
1548
+ skip: void 0,
1549
+ projection: void 0
1550
+ }))[0], r = w.decodeUnknownSync(dn)(t.delivery ?? null), i = (r) => fn(e, r, t, n);
1551
+ if (n === void 0) {
1552
+ if (r !== null && r.restartToken !== null) throw Error("Workflow restart delivery has no resident authorization");
1553
+ if ((await e.query({
1554
+ table: "_voltro_workflow_parent_closures",
1555
+ predicate: O("executionId", t.executionId),
1556
+ lock: "update",
1557
+ order: [],
1558
+ take: 1,
1559
+ skip: void 0,
1560
+ projection: ["id"]
1561
+ })).length !== 0) throw Error("Workflow execution is already terminal; restore its engine journal instead of re-entering the body");
1562
+ let n = await e.insert(un, {
1563
+ ...t.initialRow,
1564
+ tag: t.workflowName,
1565
+ executionId: t.executionId,
1566
+ runnerGeneration: t.generation,
1567
+ engineDelivery: r,
1568
+ status: "running",
1569
+ runnerEnteredAt: new Date(t.now),
1570
+ reclaimCount: 0
1571
+ });
1572
+ return await i(n) ?? {
1573
+ kind: "created",
1574
+ row: n,
1575
+ previous: void 0
1576
+ };
1577
+ }
1578
+ if (n.tag !== t.workflowName || typeof n.id != "string") throw Error("Workflow entry execution belongs to a different resident run");
1579
+ let a = w.decodeUnknownSync(dn)(n.engineDelivery ?? null);
1580
+ if (a?.requestId !== r?.requestId || a?.restartToken !== r?.restartToken) throw Error("Workflow delivery does not match its resident owner");
1581
+ if (n.status === "cancelled") return {
1582
+ kind: "already-cancelled",
1583
+ row: n,
1584
+ previous: n
1585
+ };
1586
+ if (n.status === "succeeded" || n.status === "failed") throw Error("Workflow execution is already terminal; restore its engine journal instead of re-entering the body");
1587
+ if (n.status === "suspended" && n.runnerEnteredAt === null && typeof n.runnerGeneration == "string") {
1588
+ let r = {
1589
+ runId: n.id,
1590
+ workflowName: t.workflowName,
1591
+ executionId: t.executionId,
1592
+ generation: n.runnerGeneration
1593
+ };
1594
+ if (await g(e, r)) {
1595
+ let i = await _n(e, {
1596
+ owner: r,
1597
+ now: t.now,
1598
+ durationMs: 0,
1599
+ outcome: { status: "cancelled" }
1600
+ }, "suspended");
1601
+ if (i.kind !== "committed") throw Error("Suspended cancellation lost its resident owner");
1602
+ return {
1603
+ kind: "cancelled",
1604
+ row: i.row,
1605
+ previous: n,
1606
+ terminalEvent: i.terminalEvent
1607
+ };
1608
+ }
1609
+ }
1610
+ if (n.runnerGeneration === t.generation) return {
1611
+ kind: "replayed",
1612
+ row: n,
1613
+ previous: void 0
1614
+ };
1615
+ let o = n.runnerEnteredAt !== null && n.runnerEnteredAt !== void 0, s = n.reclaimCount;
1616
+ if (typeof s != "number" || !Number.isSafeInteger(s) || s < 0) throw Error("Workflow entry has an invalid resident reclaim counter");
1617
+ let c = o ? s + 1 : 0;
1618
+ if (!Number.isSafeInteger(c)) throw Error("Workflow reclaim counter exhausted");
1619
+ let l = await e.update(un, n.id, {
1620
+ runnerGeneration: t.generation,
1621
+ runnerEnteredAt: new Date(t.now),
1622
+ reclaimCount: c,
1623
+ status: "running",
1624
+ errorTag: null,
1625
+ errorMessage: null,
1626
+ output: null,
1627
+ completedAt: null
1628
+ });
1629
+ if (l === null) throw Error("Workflow run disappeared while entering its new generation");
1630
+ let u = await i(l);
1631
+ return u === void 0 ? (n.status === "suspended" && n.runnerEnteredAt === null && typeof n.runnerGeneration == "string" && await d(e, {
1632
+ runId: n.id,
1633
+ workflowName: t.workflowName,
1634
+ executionId: t.executionId,
1635
+ generation: n.runnerGeneration
1636
+ }, t.generation, t.now), {
1637
+ kind: "entered",
1638
+ row: l,
1639
+ previous: n
1640
+ }) : u;
1641
+ }, mn = async (e, t) => {
1642
+ if ([
1643
+ t.runId,
1644
+ t.workflowName,
1645
+ t.executionId,
1646
+ t.generation
1647
+ ].some((e) => e.length === 0)) throw Error("Workflow runner ownership requires non-empty identities");
1648
+ let n = (await e.query({
1649
+ table: un,
1650
+ predicate: O("id", t.runId),
1651
+ lock: "update",
1652
+ order: [],
1653
+ take: 1,
1654
+ skip: void 0,
1655
+ projection: void 0
1656
+ }))[0];
1657
+ if (n === void 0 || n.tag !== t.workflowName || n.executionId !== t.executionId) throw Error("Workflow runner ownership does not match its resident run");
1658
+ return n;
1659
+ }, hn = async (e, t, n) => {
1660
+ let r = await mn(e, t);
1661
+ if (r.runnerGeneration !== t.generation || r.status !== "suspended" || r.runnerEnteredAt !== null || !await g(e, t)) return !1;
1662
+ if ((await _n(e, {
1663
+ owner: t,
1664
+ now: n,
1665
+ durationMs: 0,
1666
+ outcome: { status: "cancelled" }
1667
+ }, "suspended")).kind !== "committed") throw Error("Suspended cancellation lost its resident owner");
1668
+ return !0;
1669
+ }, gn = async (e, t, n) => {
1670
+ let r = await mn(e, t);
1671
+ if (r.runnerGeneration !== t.generation) return { kind: "superseded" };
1672
+ if (r.status !== "running") return { kind: "not-running" };
1673
+ let i = await e.update(un, t.runId, {
1674
+ status: "suspended",
1675
+ runnerEnteredAt: null,
1676
+ errorTag: n.errorTag,
1677
+ errorMessage: n.errorMessage
1678
+ });
1679
+ if (i === null) throw Error("Workflow run disappeared during suspension recording");
1680
+ return {
1681
+ kind: "committed",
1682
+ row: i
1683
+ };
1684
+ }, _n = async (e, t, n) => {
1685
+ let r = await mn(e, t.owner);
1686
+ if (r.runnerGeneration !== t.owner.generation) return { kind: "superseded" };
1687
+ if (r.status !== n) return { kind: "not-running" };
1688
+ if (!Number.isFinite(t.now) || !Number.isFinite(t.durationMs) || t.durationMs < 0) throw Error("Workflow completion requires finite time and non-negative duration");
1689
+ let i = t.outcome, a = null;
1690
+ i.status === "failed" && (a = `wffr_${ve("sha256").update(JSON.stringify([
1691
+ "run",
1692
+ t.owner.workflowName,
1693
+ t.owner.runId,
1694
+ t.owner.generation
1695
+ ])).digest("hex").slice(0, 40)}`, await Ye(e, {
1696
+ id: a,
1697
+ sourceKind: "run",
1698
+ sourceId: t.owner.runId,
1699
+ workflowName: t.owner.workflowName,
1700
+ tenantId: i.tenantId,
1701
+ handler: await $e(e, t.owner.executionId, t.owner.workflowName, i.tenantId) ? null : i.handler,
1702
+ callerContext: i.callerContext,
1703
+ report: {
1704
+ workflow: t.owner.workflowName,
1705
+ payload: r.payload,
1706
+ errorTag: i.errorTag,
1707
+ errorMessage: i.errorMessage,
1708
+ runId: t.owner.runId,
1709
+ executionId: t.owner.executionId,
1710
+ reason: "the run failed",
1711
+ failedAt: t.now
1712
+ }
1713
+ }), await it(e, a, t.now));
1714
+ let o = await e.update(un, t.owner.runId, {
1715
+ status: i.status,
1716
+ completedAt: new Date(t.now),
1717
+ durationMs: t.durationMs,
1718
+ cancelled: i.status === "cancelled",
1719
+ runnerEnteredAt: null,
1720
+ output: i.status === "succeeded" ? i.output : null,
1721
+ errorTag: i.status === "failed" ? i.errorTag : null,
1722
+ errorMessage: i.status === "failed" ? i.errorMessage : null
1723
+ });
1724
+ if (o === null) throw Error("Workflow run disappeared during terminal recording");
1725
+ await e.insert("_voltro_workflow_parent_closures", {
1726
+ id: D("wfpc", JSON.stringify([t.owner.runId, t.owner.generation])),
1727
+ runId: t.owner.runId,
1728
+ workflowName: t.owner.workflowName,
1729
+ executionId: t.owner.executionId,
1730
+ generation: t.owner.generation,
1731
+ parentStatus: i.status,
1732
+ closedAt: new Date(t.now),
1733
+ afterChildId: null,
1734
+ scanHasOpenChildren: !1,
1735
+ completedAt: null
1736
+ });
1737
+ let s = await e.insert("_voltro_workflow_run_events", {
1738
+ id: D("wfev", JSON.stringify([
1739
+ "terminal",
1740
+ t.owner.runId,
1741
+ t.owner.generation
1742
+ ])),
1743
+ runId: t.owner.runId,
1744
+ eventType: `run-${i.status}`,
1745
+ occurredAt: new Date(t.now),
1746
+ stepName: null,
1747
+ attempt: null,
1748
+ payload: {
1749
+ executionId: t.owner.executionId,
1750
+ generation: t.owner.generation,
1751
+ durationMs: t.durationMs,
1752
+ ...i.status === "failed" ? {
1753
+ errorTag: i.errorTag,
1754
+ errorMessage: i.errorMessage
1755
+ } : {}
1756
+ }
1757
+ });
1758
+ await p(e, t), await Wt(e, t.owner.executionId, t.now);
1759
+ for await (let n of ft(e, t.owner.executionId, t.owner.workflowName)) {
1760
+ let [r] = await e.query({
1761
+ table: W,
1762
+ predicate: O("id", n.ledgerId),
1763
+ lock: "update",
1764
+ order: [],
1765
+ take: 1,
1766
+ skip: void 0,
1767
+ projection: void 0
1768
+ });
1769
+ if (r === void 0 || r.workflowName !== n.workflowName || r.tenantId !== n.tenantId || r.outcome !== "admitted" || r.executionId !== null && r.executionId !== t.owner.executionId) throw Error("Workflow terminal reservation does not match its resident submission");
1770
+ if (r.releasedAt === null && await e.update("_voltro_workflow_admissions", n.ledgerId, { releasedAt: new Date(t.now) }) === null) throw Error("Workflow terminal reservation disappeared during release");
1771
+ }
1772
+ return {
1773
+ kind: "committed",
1774
+ row: o,
1775
+ failureId: a,
1776
+ terminalEvent: s
1777
+ };
1778
+ }, vn = (e, t) => _n(e, t, "running"), yn = P("_voltro_workflow_queued_cancellations", {
1779
+ id: A({ prefix: "wfqc" }),
1780
+ receiptId: F(),
1781
+ workflowName: F(),
1782
+ tenantId: F().nullable(),
1783
+ requestedAt: I(),
1784
+ cause: N().nullable(),
1785
+ target: N(),
1786
+ controlBinding: N().nullable()
1787
+ }).index(["receiptId"]).index(["workflowName", "id"]).nonReactive(), bn = w.NullOr(w.Struct({
1788
+ reason: w.NonEmptyString,
1789
+ detail: w.optional(w.Record({
1790
+ key: w.String,
1791
+ value: w.Unknown
1792
+ }))
1793
+ })), xn = w.Struct({
1794
+ id: w.NonEmptyString,
1795
+ receiptId: w.NonEmptyString,
1796
+ workflowName: w.NonEmptyString,
1797
+ tenantId: w.NullOr(w.String),
1798
+ requestedAt: w.DateFromSelf,
1799
+ cause: bn,
1800
+ controlBinding: w.NullOr(w.Struct({
1801
+ controlId: w.NonEmptyString,
1802
+ runId: w.NonEmptyString,
1803
+ executionId: w.NonEmptyString,
1804
+ generation: w.NonEmptyString
1805
+ })),
1806
+ target: w.Union(w.Struct({
1807
+ kind: w.Literal("submission"),
1808
+ submissionId: w.NonEmptyString
1809
+ }), w.Struct({
1810
+ kind: w.Literal("terminal"),
1811
+ receipt: w.Unknown
1812
+ }))
1813
+ }), Sn = (e) => {
1814
+ let t = w.decodeUnknownSync(xn)(e);
1815
+ if (!Number.isFinite(t.requestedAt.getTime())) throw Error("Queued cancellation request has an invalid timestamp");
1816
+ if (t.target.kind === "submission") return {
1817
+ ...t,
1818
+ target: t.target
1819
+ };
1820
+ let n = V(t.target.receipt);
1821
+ if (t.controlBinding !== null) throw Error("A non-executed start cannot have a run control binding");
1822
+ if (n.id !== t.receiptId || n.workflowName !== t.workflowName || n.tenantId !== t.tenantId || n.terminal === null) throw Error("Queued cancellation terminal evidence belongs to another start or is not terminal");
1823
+ return {
1824
+ ...t,
1825
+ target: {
1826
+ kind: "terminal",
1827
+ receipt: n
1828
+ }
1829
+ };
1830
+ }, Cn = async (e, t) => {
1831
+ let [n] = await e.query({
1832
+ table: yn.tableName,
1833
+ predicate: O("id", t),
1834
+ lock: "update",
1835
+ order: [],
1836
+ take: 1,
1837
+ skip: void 0,
1838
+ projection: void 0
1839
+ });
1840
+ return n === void 0 ? void 0 : Sn(n);
1841
+ }, wn = async (e, t) => {
1842
+ let n = t.controlBinding;
1843
+ if (n === null) throw Error("Queued cancellation has no control binding");
1844
+ let r = await m(e, n.controlId);
1845
+ if (r === void 0 || r.operation !== "cancel" || r.workflowName !== t.workflowName || r.runId !== n.runId || r.executionId !== n.executionId || r.generation !== n.generation || r.owner?.tenantId !== t.tenantId || r.result?.status === "running") throw Error("Queued cancellation lost its original resident control owner");
1846
+ return r;
1847
+ }, Tn = async (e, t, n) => {
1848
+ if (t.controlBinding === null) return;
1849
+ let r = await wn(e, t);
1850
+ if (r.result !== null) return;
1851
+ let [i] = await e.query({
1852
+ table: "_voltro_workflow_runs",
1853
+ predicate: O("id", r.runId),
1854
+ lock: "update",
1855
+ order: [],
1856
+ take: 1,
1857
+ skip: void 0,
1858
+ projection: void 0
1859
+ });
1860
+ i !== void 0 && await hn(e, {
1861
+ runId: r.runId,
1862
+ workflowName: r.workflowName,
1863
+ executionId: r.executionId,
1864
+ generation: r.generation
1865
+ }, n);
1866
+ }, En = async (e, t) => {
1867
+ let n = await Cn(e, t.requestId);
1868
+ if (n === void 0) return {
1869
+ kind: "unknown",
1870
+ reason: "missing-request"
1871
+ };
1872
+ if (n.workflowName !== t.workflowName || n.tenantId !== t.tenantId) throw Error("Queued cancellation request belongs to another workflow or tenant");
1873
+ if (n.target.kind === "terminal") {
1874
+ let e = n.target.receipt.terminal;
1875
+ if (e === null) throw Error("Queued cancellation has no terminal evidence");
1876
+ return {
1877
+ kind: e.kind === "cancelled" ? "confirmed" : "already-terminal",
1878
+ request: n,
1879
+ outcome: e
1880
+ };
1881
+ }
1882
+ if (n.controlBinding !== null) {
1883
+ let t = await wn(e, n);
1884
+ if (t.result !== null) return {
1885
+ kind: t.result.kind,
1886
+ request: n,
1887
+ control: t
1888
+ };
1889
+ let [r] = await e.query({
1890
+ table: "_voltro_workflow_runs",
1891
+ predicate: O("id", t.runId),
1892
+ lock: "update",
1893
+ order: [],
1894
+ take: 1,
1895
+ skip: void 0,
1896
+ projection: void 0
1897
+ });
1898
+ if (r === void 0) return {
1899
+ kind: "unknown",
1900
+ reason: "missing-run",
1901
+ request: n,
1902
+ control: t
1903
+ };
1904
+ if (r.tag !== t.workflowName || r.executionId !== t.executionId) throw Error("Queued cancellation control belongs to another resident execution");
1905
+ return r.runnerGeneration !== t.generation || r.status !== "running" && r.status !== "suspended" ? {
1906
+ kind: "unknown",
1907
+ reason: "unconfirmed-generation",
1908
+ request: n,
1909
+ control: t
1910
+ } : {
1911
+ kind: "accepted",
1912
+ request: n,
1913
+ control: t,
1914
+ run: r
1915
+ };
1916
+ }
1917
+ let r = await B(e, n.target.submissionId);
1918
+ if (r === void 0 || !r.receiptsBound || r.workflowName !== n.workflowName || r.tenantId !== n.tenantId) throw Error("Queued cancellation has no matching submission evidence");
1919
+ return r.failureId === null ? r.retry.stoppedAt !== null || r.runId !== null ? {
1920
+ kind: "unknown",
1921
+ reason: "unbound-submission",
1922
+ request: n
1923
+ } : {
1924
+ kind: "accepted",
1925
+ request: n
1926
+ } : {
1927
+ kind: "already-terminal",
1928
+ request: n,
1929
+ outcome: {
1930
+ kind: "rejected",
1931
+ failureId: await wt(e, r)
1932
+ }
1933
+ };
1934
+ }, Dn = (e, t) => {
1935
+ let n = "request" in t ? t.request : void 0;
1936
+ if (n !== void 0 && (n.id !== e.requestId || n.receiptId !== e.receiptId || n.workflowName !== e.workflowName)) throw Error("Queued control result belongs to another request or receipt");
1937
+ let r = {
1938
+ operation: "cancel",
1939
+ workflowName: e.workflowName,
1940
+ receiptId: e.receiptId,
1941
+ requestId: n?.id ?? null,
1942
+ kind: t.kind
1943
+ }, i = w.decodeUnknownSync(ae);
1944
+ if (t.kind === "unknown") return i({
1945
+ ...r,
1946
+ observation: {
1947
+ kind: "unavailable",
1948
+ reason: t.reason
1949
+ }
1950
+ });
1951
+ if ("outcome" in t && t.outcome !== void 0) return i({
1952
+ ...r,
1953
+ observation: {
1954
+ kind: "admission",
1955
+ outcome: t.outcome
1956
+ }
1957
+ });
1958
+ if ("control" in t && t.control !== void 0) {
1959
+ let e = t.control, n = e.result;
1960
+ return i({
1961
+ ...r,
1962
+ observation: {
1963
+ kind: "execution",
1964
+ snapshot: {
1965
+ id: e.runId,
1966
+ workflowName: e.workflowName,
1967
+ executionId: e.executionId,
1968
+ status: n?.status ?? ("run" in t ? t.run?.status : void 0),
1969
+ ...n !== null && n.status === "succeeded" ? { output: n.output } : {},
1970
+ ...n !== null && n.status === "failed" && n.errorMessage !== null ? { error: {
1971
+ tag: n.errorTag,
1972
+ message: n.errorMessage
1973
+ } } : {}
1974
+ }
1975
+ }
1976
+ });
1977
+ }
1978
+ return i({
1979
+ ...r,
1980
+ observation: { kind: "pending" }
1981
+ });
1982
+ }, On = async (e, t) => {
1983
+ let n = w.decodeUnknownSync(w.Struct({
1984
+ id: w.NonEmptyString,
1985
+ receiptId: w.NonEmptyString,
1986
+ workflowName: w.NonEmptyString,
1987
+ tenantId: w.NullOr(w.String),
1988
+ requestedAt: w.DateFromSelf,
1989
+ cause: bn
1990
+ }))({
1991
+ id: t.requestId,
1992
+ receiptId: t.receiptId,
1993
+ workflowName: t.workflowName,
1994
+ tenantId: t.tenantId,
1995
+ requestedAt: new Date(t.now),
1996
+ cause: t.cause ?? null
1997
+ });
1998
+ if (!Number.isFinite(n.requestedAt.getTime())) throw Error("Queued cancellation request requires a valid timestamp");
1999
+ let r = await Cn(e, n.id);
2000
+ if (r !== void 0) {
2001
+ if (r.receiptId !== n.receiptId || r.workflowName !== n.workflowName || r.tenantId !== n.tenantId) throw Error("Queued cancellation identity belongs to a different start or owner");
2002
+ return await Tn(e, r, t.now), r;
2003
+ }
2004
+ let i = await rn(e, t), a;
2005
+ if (i.kind === "submitted") a = {
2006
+ kind: "submission",
2007
+ submissionId: i.submissionId
2008
+ };
2009
+ else {
2010
+ let n = await Dt(e, t.receiptId);
2011
+ if (n === void 0) throw Error("Cancelled start receipt disappeared during request acceptance");
2012
+ a = {
2013
+ kind: "terminal",
2014
+ receipt: n
2015
+ };
2016
+ }
2017
+ let o = Sn({
2018
+ ...n,
2019
+ target: a,
2020
+ controlBinding: null
2021
+ });
2022
+ if (await e.insert(yn.tableName, o), a.kind === "submission") {
2023
+ let n = await B(e, a.submissionId);
2024
+ if (n === void 0) throw Error("Queued cancellation submission disappeared during acceptance");
2025
+ if (n.preparedExecutionId !== null && n.dispatchAttempts > 0) {
2026
+ let [r] = await e.query({
2027
+ table: "_voltro_workflow_runs",
2028
+ predicate: O("executionId", n.preparedExecutionId),
2029
+ lock: "update",
2030
+ order: [],
2031
+ take: 1,
2032
+ skip: void 0,
2033
+ projection: void 0
2034
+ });
2035
+ if (r !== void 0) {
2036
+ let n = w.decodeUnknownSync(w.Struct({
2037
+ id: w.NonEmptyString,
2038
+ tag: w.NonEmptyString,
2039
+ executionId: w.NonEmptyString,
2040
+ runnerGeneration: w.NonEmptyString
2041
+ }))(r), i = {
2042
+ runId: n.id,
2043
+ workflowName: n.tag,
2044
+ executionId: n.executionId,
2045
+ generation: n.runnerGeneration
2046
+ }, a = await kn(e, o.id, i);
2047
+ return await Tn(e, a.request, t.now), a.request;
2048
+ }
2049
+ }
2050
+ }
2051
+ return o;
2052
+ }, kn = async (e, t, n) => {
2053
+ let r = await Cn(e, t);
2054
+ if (r === void 0) throw Error("Queued cancellation request is missing");
2055
+ if (r.target.kind === "terminal") return {
2056
+ kind: "terminal",
2057
+ request: r
2058
+ };
2059
+ if (r.controlBinding !== null) return {
2060
+ kind: "bound",
2061
+ request: r,
2062
+ control: await wn(e, r)
2063
+ };
2064
+ let i = await B(e, r.target.submissionId);
2065
+ if (i === void 0 || i.workflowName !== r.workflowName || i.tenantId !== r.tenantId || !i.receiptsBound || i.failureId !== null || i.dispatchAttempts === 0 || i.preparedExecutionId !== n.executionId || i.executionId !== null && i.executionId !== n.executionId || i.runId !== null && i.runId !== n.runId || n.workflowName !== r.workflowName) throw Error("Queued cancellation has no dispatched submission for this resident execution");
2066
+ let [a] = await e.query({
2067
+ table: "_voltro_workflow_runs",
2068
+ predicate: O("id", n.runId),
2069
+ lock: "update",
2070
+ order: [],
2071
+ take: 1,
2072
+ skip: void 0,
2073
+ projection: void 0
2074
+ }), o = w.decodeUnknownOption(w.Struct({ tenantId: w.NullOr(w.String) }))(a?.subject);
2075
+ if (a === void 0 || a.tag !== n.workflowName || a.executionId !== n.executionId || a.runnerGeneration !== n.generation || o._tag === "None" || o.value.tenantId !== r.tenantId || ![
2076
+ "running",
2077
+ "suspended",
2078
+ "succeeded",
2079
+ "failed",
2080
+ "cancelled"
2081
+ ].includes(String(a.status))) throw Error("Queued cancellation generation or tenant does not match the resident run");
2082
+ let s = {
2083
+ controlId: D("wfctl", JSON.stringify(["queued-cancel", r.id])),
2084
+ runId: n.runId,
2085
+ executionId: n.executionId,
2086
+ generation: n.generation
2087
+ }, c = await h(e, {
2088
+ id: s.controlId,
2089
+ ...n,
2090
+ operation: "cancel",
2091
+ requestedAt: r.requestedAt.getTime(),
2092
+ cause: r.cause
2093
+ });
2094
+ if (await e.update(yn.tableName, r.id, { controlBinding: s }) === null) throw Error("Queued cancellation request disappeared during run binding");
2095
+ return {
2096
+ kind: "bound",
2097
+ request: {
2098
+ ...r,
2099
+ controlBinding: s
2100
+ },
2101
+ control: c
2102
+ };
2103
+ }, An = async (e, t) => {
2104
+ let n = /* @__PURE__ */ new Set();
2105
+ for await (let r of ft(e, t.executionId, t.workflowName)) n.add(r.id);
2106
+ if (n.size === 0) return !1;
2107
+ let r, i = !1;
2108
+ for (;;) {
2109
+ let a = await e.query({
2110
+ table: yn.tableName,
2111
+ predicate: T(O("workflowName", t.workflowName), ...r === void 0 ? [] : [k("id", r)]),
2112
+ lock: "update",
2113
+ order: [{
2114
+ column: "id",
2115
+ direction: "asc"
2116
+ }],
2117
+ take: 100,
2118
+ skip: void 0,
2119
+ projection: void 0
2120
+ });
2121
+ for (let o of a) {
2122
+ let a = Sn(o);
2123
+ if (r = a.id, a.target.kind !== "submission" || !n.has(a.target.submissionId)) continue;
2124
+ let s = await kn(e, a.id, t);
2125
+ if (s.kind === "bound") {
2126
+ if (s.control.runId !== t.runId || s.control.executionId !== t.executionId || s.control.workflowName !== t.workflowName) throw Error("Queued cancellation entry does not match its original resident execution");
2127
+ s.control.result === null && (i = !0);
2128
+ }
2129
+ }
2130
+ if (a.length < 100) return i;
2131
+ }
2132
+ }, jn = w.Struct({
2133
+ requestId: w.NonEmptyString,
2134
+ receiptId: w.NonEmptyString,
2135
+ workflowName: w.NonEmptyString,
2136
+ tenantId: w.NullOr(w.String)
2137
+ }), Mn = async (e, t) => {
2138
+ let n = w.decodeUnknownSync(jn)(t);
2139
+ return await On(e, {
2140
+ ...n,
2141
+ now: t.now,
2142
+ ...t.cause === void 0 ? {} : { cause: t.cause }
2143
+ }), Nn(e, n);
2144
+ }, Nn = async (e, t) => {
2145
+ let n = w.decodeUnknownSync(jn)(t);
2146
+ return Dn(n, await En(e, n));
2147
+ }, Pn = async (e, t) => {
2148
+ if (new Set(t.intentIds).size !== t.intentIds.length) throw Error("Admitted transfer requires distinct pending identities");
2149
+ let n = await B(e, t.id);
2150
+ if (n !== void 0) {
2151
+ if (n.workflowName !== t.workflowName || n.tenantId !== t.tenantId || n.ledgerId !== t.ledgerId || !n.receiptsBound) throw Error("Admitted transfer contradicts its existing submission");
2152
+ return n;
2153
+ }
2154
+ for (let n of t.intentIds) {
2155
+ let r = await e.query({
2156
+ table: U,
2157
+ predicate: O("id", n),
2158
+ order: [],
2159
+ take: 1,
2160
+ skip: void 0,
2161
+ projection: void 0,
2162
+ lock: "update"
2163
+ });
2164
+ if (r[0] === void 0) throw Error("Admitted transfer lost a selected input");
2165
+ let i = q(r[0]);
2166
+ if (i.workflowName !== t.workflowName || i.tenantId !== t.tenantId || i.deadLetteredAt !== void 0) throw Error("Admitted transfer selected a foreign or dead-lettered input");
2167
+ }
2168
+ let r = await _t(e, t);
2169
+ await At(e, r.id);
2170
+ for (let t of r.intentIds) if (!await e.delete("_voltro_workflow_pending", t)) throw Error("Admitted input disappeared during submission transfer");
2171
+ return {
2172
+ ...r,
2173
+ receiptsBound: !0
2174
+ };
2175
+ }, Fn = async (e, t) => Ie(e, (e) => In(e, t)), In = async (e, t) => {
2176
+ if (t.id.length === 0 || t.intentIds.length === 0 || new Set(t.intentIds).size !== t.intentIds.length) throw Error("Queue transfer requires a submission identity and distinct pending identities");
2177
+ let n = await B(e, t.id);
2178
+ if (n !== void 0) {
2179
+ if (n.workflowName !== t.workflowName || n.tenantId !== t.tenantId) throw Error("Admission submission identity belongs to a different workflow or tenant");
2180
+ if (!n.receiptsBound) throw Error("Submission exists without completed queue transfer");
2181
+ return {
2182
+ kind: "reserved",
2183
+ submission: n,
2184
+ reused: !0
2185
+ };
2186
+ }
2187
+ let r = [];
2188
+ for (let n of t.intentIds) {
2189
+ let i = await e.query({
2190
+ table: U,
2191
+ predicate: O("id", n),
2192
+ order: [],
2193
+ take: 1,
2194
+ skip: void 0,
2195
+ projection: void 0,
2196
+ lock: "update"
2197
+ });
2198
+ if (i[0] === void 0) return { kind: "selection-unavailable" };
2199
+ let a = q(i[0]);
2200
+ if (a.workflowName !== t.workflowName || a.tenantId !== t.tenantId) throw Error("Selected pending start belongs to a different workflow or tenant");
2201
+ if (a.deadLetteredAt !== void 0 || a.dueAt > t.now) return { kind: "selection-unavailable" };
2202
+ r.push(a);
2203
+ }
2204
+ let i = t.prepare(r);
2205
+ if (i.control.workflowName !== t.workflowName) throw Error("Prepared submission belongs to a different workflow");
2206
+ let a = await gt(e, {
2207
+ ...i,
2208
+ id: t.id,
2209
+ tenantId: t.tenantId,
2210
+ intentIds: t.intentIds,
2211
+ now: t.now
2212
+ });
2213
+ if (a.kind !== "reserved") return a;
2214
+ await At(e, t.id);
2215
+ for (let t of r) if (!await e.delete("_voltro_workflow_pending", t.id)) throw Error("Pending start disappeared during queue transfer");
2216
+ return {
2217
+ ...a,
2218
+ submission: {
2219
+ ...a.submission,
2220
+ receiptsBound: !0
2221
+ }
2222
+ };
2223
+ }, Ln = async (e) => {
2224
+ let { store: t, control: n, now: r } = e, i = R(n, e.payload), a = await tn({
2225
+ store: t,
2226
+ control: n,
2227
+ keys: i,
2228
+ paused: e.paused,
2229
+ now: r,
2230
+ reconsidering: !1
2231
+ });
2232
+ if (a.kind === "drop") return await Y({
2233
+ store: t,
2234
+ control: n,
2235
+ keys: i,
2236
+ outcome: "dropped",
2237
+ mode: "rateLimit",
2238
+ reason: `rate limit reached; retry after ${a.retryAfterMs}ms`,
2239
+ collapsed: 1,
2240
+ waitedMs: 0,
2241
+ executionId: null,
2242
+ runId: null,
2243
+ tenantId: e.tenantId,
2244
+ now: r
2245
+ }), {
2246
+ kind: "dropped",
2247
+ retryAfterMs: a.retryAfterMs
2248
+ };
2249
+ if (a.kind === "skip") return await Y({
2250
+ store: t,
2251
+ control: n,
2252
+ keys: i,
2253
+ outcome: "skipped",
2254
+ mode: "singleton",
2255
+ reason: `singleton key held by ${a.incumbent.executionId}`,
2256
+ collapsed: 1,
2257
+ waitedMs: 0,
2258
+ executionId: a.incumbent.executionId,
2259
+ runId: a.incumbent.runId || null,
2260
+ tenantId: e.tenantId,
2261
+ now: r
2262
+ }), {
2263
+ kind: "skipped",
2264
+ executionId: a.incumbent.executionId,
2265
+ runId: a.incumbent.runId
2266
+ };
2267
+ if (a.kind === "defer") return {
2268
+ kind: "queued",
2269
+ intentId: await Vt({
2270
+ store: t,
2271
+ control: n,
2272
+ decision: a,
2273
+ payload: e.payload,
2274
+ callerContext: e.callerContext,
2275
+ tenantId: e.tenantId,
2276
+ now: r,
2277
+ ...e.queuedAppVersion === void 0 ? {} : { queuedAppVersion: e.queuedAppVersion },
2278
+ ...e.queuedSchemaFingerprint === void 0 ? {} : { queuedSchemaFingerprint: e.queuedSchemaFingerprint }
2279
+ }),
2280
+ mode: a.mode,
2281
+ dueAt: a.dueAt
2282
+ };
2283
+ let o = e.payload, s = [], c = 1;
2284
+ if (n.batch !== void 0 && i.batchKey !== void 0) {
2285
+ let r = await Rn(t, n.workflowName, i.batchKey, n.batch.maxSize);
2286
+ o = { items: [...r.map((e) => e.payload), e.payload] }, s = r.map((e) => e.id), c = r.length + 1;
2287
+ }
2288
+ return {
2289
+ kind: "start",
2290
+ ledgerId: await Y({
2291
+ store: t,
2292
+ control: n,
2293
+ keys: i,
2294
+ outcome: "admitted",
2295
+ mode: e.waiting ? "immediate" : null,
2296
+ reason: a.reason,
2297
+ collapsed: c,
2298
+ waitedMs: 0,
2299
+ executionId: null,
2300
+ runId: null,
2301
+ tenantId: e.tenantId,
2302
+ now: r
2303
+ }),
2304
+ keys: i,
2305
+ payload: o,
2306
+ consume: s,
2307
+ collapsed: c,
2308
+ ...a.evict === void 0 ? {} : { evict: {
2309
+ executionId: a.evict.executionId,
2310
+ runId: a.evict.runId
2311
+ } }
2312
+ };
2313
+ }, Rn = async (e, t, n, r) => (await e.query({
2314
+ table: "_voltro_workflow_pending",
2315
+ predicate: T(O("workflowName", t), O("controlKey", n), O("mode", "batch")),
2316
+ order: [{
2317
+ column: "firstSeenAt",
2318
+ direction: "asc"
2319
+ }],
2320
+ take: r,
2321
+ skip: void 0,
2322
+ projection: void 0
2323
+ })).map((n) => ({
2324
+ id: String(n.id),
2325
+ payload: G(e, t, n.payload)
2326
+ })), zn = async (e, t, n, r) => {
2327
+ await e.update("_voltro_workflow_admissions", t, {
2328
+ executionId: n,
2329
+ runId: r
2330
+ });
2331
+ }, Bn = P("_voltro_workflow_watermarks", {
2332
+ id: A({ prefix: "wfwm" }),
2333
+ positionAt: I(),
2334
+ updatedAt: I().default("now")
2335
+ }), Vn = (e) => {
2336
+ let t = e instanceof Error ? e.message : String(e);
2337
+ return t.length > 400 ? `${t.slice(0, 400)}…` : t;
2338
+ }, Hn = (e) => {
2339
+ let t = [], n = [], r = [], i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = e.payloadSchema === void 0 ? (e) => C.right(e) : (t) => {
2340
+ let n = w.decodeUnknownEither(e.payloadSchema)(t);
2341
+ return C.isRight(n) ? C.right(n.right) : C.left(Vn(n.left));
2342
+ }, s = e.runs.map((e) => ({
2343
+ run: e,
2344
+ decoded: o(e.payload)
2345
+ })), c = e.intents.map((e) => ({
2346
+ intent: e,
2347
+ decoded: o(e.payload)
2348
+ }));
2349
+ for (let o of e.entries) for (let l of e.events) {
2350
+ if (l.name !== o.event) continue;
2351
+ let u = w.decodeUnknownEither(o.schema)(l.payload);
2352
+ if (C.isLeft(u)) {
2353
+ r.push({
2354
+ kind: "event-decode",
2355
+ workflowName: e.workflowName,
2356
+ event: o.event,
2357
+ subject: l.id,
2358
+ detail: Vn(u.left)
2359
+ });
2360
+ continue;
2361
+ }
2362
+ let d = u.right, f = (e) => e.getTime() > l.occurredAt.getTime() ? !1 : o.withinMs === void 0 || l.occurredAt.getTime() - e.getTime() <= o.withinMs, p = (t, n) => {
2363
+ if (C.isLeft(t)) return r.push({
2364
+ kind: "payload-decode",
2365
+ workflowName: e.workflowName,
2366
+ event: o.event,
2367
+ subject: n,
2368
+ detail: t.left
2369
+ }), !1;
2370
+ try {
2371
+ return o.match(d, t.right) === !0;
2372
+ } catch (t) {
2373
+ return r.push({
2374
+ kind: "match-threw",
2375
+ workflowName: e.workflowName,
2376
+ event: o.event,
2377
+ subject: n,
2378
+ detail: Vn(t)
2379
+ }), !1;
2380
+ }
2381
+ };
2382
+ for (let { run: e, decoded: n } of s) i.has(e.runId) || f(e.startedAt) && p(n, e.runId) && (i.add(e.runId), t.push({
2383
+ runId: e.runId,
2384
+ executionId: e.executionId,
2385
+ reason: o.reason,
2386
+ event: o.event,
2387
+ eventId: l.id
2388
+ }));
2389
+ for (let { intent: e, decoded: t } of c) a.has(e.intentId) || f(e.firstSeenAt) && p(t, e.intentId) && (a.add(e.intentId), n.push({
2390
+ intentId: e.intentId,
2391
+ reason: o.reason,
2392
+ event: o.event,
2393
+ eventId: l.id
2394
+ }));
2395
+ }
2396
+ return {
2397
+ cancels: t,
2398
+ discards: n,
2399
+ problems: r
2400
+ };
2401
+ }, Un = (e) => {
2402
+ let t;
2403
+ for (let n of e) (t === void 0 || n.occurredAt.getTime() > t.getTime()) && (t = n.occurredAt);
2404
+ return t;
2405
+ }, Wn = "_voltro_workflow_watermarks", Gn = "_voltro_workflow_events", Kn = "cancelOn", qn = 36e5, Jn = 500, Yn = (e) => {
2406
+ if (e instanceof Date) return e;
2407
+ if (typeof e == "number") return new Date(e);
2408
+ if (typeof e == "string") {
2409
+ let t = new Date(e);
2410
+ if (!Number.isNaN(t.getTime())) return t;
2411
+ }
2412
+ }, Xn = (e) => e instanceof Error ? e.message : String(e), Zn = async (e, t) => Yn((await e.query({
2413
+ table: Wn,
2414
+ predicate: O("id", t),
2415
+ order: [],
2416
+ take: 1,
2417
+ skip: void 0,
2418
+ projection: void 0
2419
+ }))[0]?.positionAt), Qn = async (e, t, n) => {
2420
+ await e.upsert(Wn, {
2421
+ id: t,
2422
+ positionAt: n,
2423
+ updatedAt: /* @__PURE__ */ new Date()
2424
+ }, {
2425
+ conflictColumns: ["id"],
2426
+ update: (e) => {
2427
+ let t = Yn(e.positionAt);
2428
+ return t !== void 0 && t.getTime() >= n.getTime() ? {
2429
+ positionAt: t,
2430
+ updatedAt: /* @__PURE__ */ new Date()
2431
+ } : {
2432
+ positionAt: n,
2433
+ updatedAt: /* @__PURE__ */ new Date()
2434
+ };
2435
+ }
2436
+ });
2437
+ }, $n = async (e, t, n) => {
2438
+ let r = async (r) => e.query({
2439
+ table: "_voltro_workflow_runs",
2440
+ predicate: T(O("tag", t), O("status", r)),
2441
+ order: [{
2442
+ column: "startedAt",
2443
+ direction: "asc"
2444
+ }],
2445
+ take: n,
2446
+ skip: void 0,
2447
+ projection: void 0
2448
+ });
2449
+ return [...await r("running"), ...await r("suspended")].flatMap((e) => {
2450
+ let t = e, n = Yn(t.startedAt);
2451
+ return typeof t.id != "string" || typeof t.executionId != "string" || n === void 0 ? [] : [{
2452
+ runId: t.id,
2453
+ executionId: t.executionId,
2454
+ payload: t.payload,
2455
+ startedAt: n
2456
+ }];
2457
+ });
2458
+ }, er = async (e, t, n) => (await e.query({
2459
+ table: "_voltro_workflow_pending",
2460
+ predicate: O("workflowName", t),
2461
+ order: [{
2462
+ column: "firstSeenAt",
2463
+ direction: "asc"
2464
+ }],
2465
+ take: n,
2466
+ skip: void 0,
2467
+ projection: void 0
2468
+ })).flatMap((e) => {
2469
+ let t = e, n = Yn(t.firstSeenAt);
2470
+ return typeof t.id != "string" || n === void 0 ? [] : [{
2471
+ intentId: t.id,
2472
+ payload: t.payload,
2473
+ firstSeenAt: n
2474
+ }];
2475
+ }), tr = async (e, t) => {
2476
+ let n = t.workflows.filter((e) => e.entries.length > 0);
2477
+ if (n.length === 0) return {
2478
+ examined: !1,
2479
+ events: 0,
2480
+ cancelled: 0,
2481
+ discarded: 0,
2482
+ catchingUp: !1,
2483
+ sawFullRunPage: !1,
2484
+ problems: [],
2485
+ failures: [],
2486
+ watermark: void 0
2487
+ };
2488
+ let r = e.now?.() ?? Date.now(), i = t.batch ?? 500, a = t.coldLookbackMs ?? 36e5, o = /* @__PURE__ */ new Set();
2489
+ for (let e of n) for (let t of e.entries) o.add(t.event);
2490
+ let s = await Zn(e.store, Kn), c = s ?? new Date(r - a);
2491
+ s === void 0 && (await Qn(e.store, Kn, c), s = c);
2492
+ let l = await e.store.query({
2493
+ table: Gn,
2494
+ predicate: le("occurredAt", c),
2495
+ order: [{
2496
+ column: "occurredAt",
2497
+ direction: "asc"
2498
+ }],
2499
+ take: i,
2500
+ skip: void 0,
2501
+ projection: void 0
2502
+ }), u = [];
2503
+ for (let e of l) {
2504
+ let t = e, n = Yn(t.occurredAt);
2505
+ typeof t.id == "string" && typeof t.name == "string" && n !== void 0 && o.has(t.name) && u.push({
2506
+ id: t.id,
2507
+ name: t.name,
2508
+ payload: t.payload,
2509
+ occurredAt: n
2510
+ });
2511
+ }
2512
+ let d = [], f = [], p = 0, m = 0, h = !1, g = !1, _ = t.runPage ?? 2e3;
2513
+ if (u.length > 0) for (let t of n) {
2514
+ let n = u.filter((e) => t.entries.some((t) => t.event === e.name));
2515
+ if (n.length === 0) continue;
2516
+ let r = [], i = [];
2517
+ try {
2518
+ r = await $n(e.store, t.workflowName, _), i = await er(e.store, t.workflowName, _), (r.length >= _ || i.length >= _) && (h = !0);
2519
+ } catch (e) {
2520
+ f.push({
2521
+ subject: t.workflowName,
2522
+ detail: Xn(e)
2523
+ }), g = !0;
2524
+ continue;
2525
+ }
2526
+ let a = Hn({
2527
+ workflowName: t.workflowName,
2528
+ entries: t.entries,
2529
+ payloadSchema: t.payloadSchema,
2530
+ events: n,
2531
+ runs: r,
2532
+ intents: i
2533
+ });
2534
+ d.push(...a.problems);
2535
+ for (let n of a.cancels) try {
2536
+ await e.cancelRun({
2537
+ ...n,
2538
+ workflowName: t.workflowName
2539
+ }), p += 1, e.log?.info("workflow.cancelOn: run cancelled", {
2540
+ workflow: t.workflowName,
2541
+ runId: n.runId,
2542
+ event: n.event,
2543
+ eventId: n.eventId
2544
+ });
2545
+ } catch (e) {
2546
+ f.push({
2547
+ subject: n.runId,
2548
+ detail: Xn(e)
2549
+ }), g = !0;
2550
+ }
2551
+ for (let n of a.discards) try {
2552
+ await e.discardIntent({
2553
+ ...n,
2554
+ workflowName: t.workflowName
2555
+ }), m += 1;
2556
+ } catch (e) {
2557
+ f.push({
2558
+ subject: n.intentId,
2559
+ detail: Xn(e)
2560
+ }), g = !0;
2561
+ }
2562
+ }
2563
+ let v = Un(u), y = s;
2564
+ if (g) e.log?.warn("workflow.cancelOn: holding the watermark — evaluation or delivery remains incomplete", { failures: f.length });
2565
+ else if (v !== void 0) try {
2566
+ await Qn(e.store, Kn, v), y = v;
2567
+ } catch (e) {
2568
+ f.push({
2569
+ subject: Kn,
2570
+ detail: Xn(e)
2571
+ });
2572
+ }
2573
+ return d.length > 0 && e.log?.warn("workflow.cancelOn: some events could not be evaluated", {
2574
+ count: d.length,
2575
+ first: d[0]
2576
+ }), {
2577
+ examined: !0,
2578
+ events: u.length,
2579
+ cancelled: p,
2580
+ discarded: m,
2581
+ catchingUp: l.length >= i,
2582
+ sawFullRunPage: h,
2583
+ problems: d,
2584
+ failures: f,
2585
+ watermark: y
2586
+ };
2587
+ }, nr = 18e5, rr = 200, ir = 20, ar = (e) => {
2588
+ if (e instanceof Date) return e;
2589
+ if (typeof e == "number") return new Date(e);
2590
+ if (typeof e == "string") {
2591
+ let t = new Date(e);
2592
+ if (!Number.isNaN(t.getTime())) return t;
2593
+ }
2594
+ }, or = (e) => e instanceof Error ? e.message : String(e), sr = async (e, t, n) => (await e.query({
2595
+ table: "_voltro_workflow_run_events",
2596
+ predicate: O("runId", t),
2597
+ order: [{
2598
+ column: "occurredAt",
2599
+ direction: "desc"
2600
+ }],
2601
+ take: n,
2602
+ skip: void 0,
2603
+ projection: void 0
2604
+ })).flatMap((e) => {
2605
+ let t = e, n = ar(t.occurredAt);
2606
+ return typeof t.eventType != "string" || n === void 0 ? [] : [{
2607
+ eventType: t.eventType,
2608
+ occurredAt: n,
2609
+ payload: t.payload
2610
+ }];
2611
+ }), cr = async (e, t) => {
2612
+ let n = (await e.query({
2613
+ table: "_voltro_workflow_run_steps",
2614
+ predicate: O("runId", t),
2615
+ order: [{
2616
+ column: "startedAt",
2617
+ direction: "desc"
2618
+ }],
2619
+ take: 1,
2620
+ skip: void 0,
2621
+ projection: void 0
2622
+ }))[0];
2623
+ if (n === void 0) return;
2624
+ let r = ar(n.startedAt), i = ar(n.completedAt);
2625
+ return r === void 0 ? i : i === void 0 ? r : i.getTime() > r.getTime() ? i : r;
2626
+ }, lr = (e, t) => {
2627
+ for (let n of e) {
2628
+ if (n.eventType === "timer-fired") return !1;
2629
+ if (n.eventType !== "timer-set") continue;
2630
+ let e = ar(n.payload?.scheduledWakeAt);
2631
+ return e !== void 0 && e.getTime() > t;
2632
+ }
2633
+ return !1;
2634
+ }, ur = (e, t) => {
2635
+ if (e !== "suspended") return "no-progress";
2636
+ for (let e of t) {
2637
+ if (e.eventType === "signal-received" || e.eventType === "signal-sent") return "suspended";
2638
+ if (e.eventType === "signal-awaited") return "awaiting-signal";
2639
+ }
2640
+ return "suspended";
2641
+ }, dr = async (e, t = {}) => {
2642
+ let n = e.now?.() ?? Date.now(), r = t.stallAfterMs ?? 18e5, i = t.runPage ?? 200, a = t.eventLookback ?? 20, o = new Date(n - r), s = [], c = [], l = 0, u = 0, d, f;
2643
+ try {
2644
+ if (!Number.isSafeInteger(i) || i < 1) throw Error("Staleness run page must be a positive integer");
2645
+ let n = t.afterRun;
2646
+ if (n !== void 0 && (!(n.startedAt instanceof Date) || !Number.isFinite(n.startedAt.getTime()) || typeof n.runId != "string" || n.runId.length === 0)) throw Error("Invalid staleness run cursor");
2647
+ d = await e.store.query({
2648
+ table: "_voltro_workflow_runs",
2649
+ predicate: T(ue("status", ["running", "suspended"]), fe("startedAt", o), ...n === void 0 ? [] : [pe(k("startedAt", n.startedAt), T(O("startedAt", n.startedAt), k("id", n.runId)))]),
2650
+ order: [{
2651
+ column: "startedAt",
2652
+ direction: "asc"
2653
+ }, {
2654
+ column: "id",
2655
+ direction: "asc"
2656
+ }],
2657
+ take: i,
2658
+ skip: void 0,
2659
+ projection: void 0
2660
+ });
2661
+ let r = n;
2662
+ for (let e of d) {
2663
+ let t = ar(e.startedAt);
2664
+ if (t === void 0 || !Number.isFinite(t.getTime()) || typeof e.id != "string" || e.id.length === 0) throw Error("Staleness candidate has no valid pagination identity");
2665
+ if (r !== void 0 && (t.getTime() < r.startedAt.getTime() || t.getTime() === r.startedAt.getTime() && e.id <= r.runId)) throw Error("Staleness candidate page did not advance");
2666
+ r = {
2667
+ startedAt: t,
2668
+ runId: e.id
2669
+ };
2670
+ }
2671
+ d.length >= i && (f = r);
2672
+ } catch (e) {
2673
+ return {
2674
+ examined: 0,
2675
+ stalled: [],
2676
+ alreadyReported: 0,
2677
+ waitingOnTimer: 0,
2678
+ sawFullRunPage: !1,
2679
+ failures: [{
2680
+ subject: "_voltro_workflow_runs",
2681
+ detail: or(e)
2682
+ }]
2683
+ };
2684
+ }
2685
+ for (let t of d) {
2686
+ let i = t, o = ar(i.startedAt);
2687
+ if (typeof i.id != "string" || typeof i.tag != "string" || typeof i.executionId != "string" || typeof i.status != "string" || o === void 0) continue;
2688
+ let d, f;
2689
+ try {
2690
+ d = await sr(e.store, i.id, a), f = await cr(e.store, i.id);
2691
+ } catch (e) {
2692
+ s.push({
2693
+ subject: i.id,
2694
+ detail: or(e)
2695
+ });
2696
+ continue;
2697
+ }
2698
+ if (lr(d, n)) {
2699
+ u += 1;
2700
+ continue;
2701
+ }
2702
+ let p = d.find((e) => e.eventType !== "run-stalled")?.occurredAt, m = o;
2703
+ for (let e of [f, p]) e !== void 0 && e.getTime() > m.getTime() && (m = e);
2704
+ let h = n - m.getTime();
2705
+ if (h < r) continue;
2706
+ if (d.some((e) => e.eventType === "run-stalled" && e.occurredAt.getTime() > m.getTime())) {
2707
+ l += 1;
2708
+ continue;
2709
+ }
2710
+ let g = {
2711
+ runId: i.id,
2712
+ tag: i.tag,
2713
+ executionId: i.executionId,
2714
+ status: i.status,
2715
+ lastProgressAt: m,
2716
+ idleMs: h,
2717
+ reason: ur(i.status, d)
2718
+ };
2719
+ c.push(g);
2720
+ let _ = {};
2721
+ if (e.describeRun !== void 0) try {
2722
+ _ = await e.describeRun(g) ?? {};
2723
+ } catch (e) {
2724
+ s.push({
2725
+ subject: `${g.runId}:describeRun`,
2726
+ detail: or(e)
2727
+ });
2728
+ }
2729
+ if (e.log?.warn("workflow.staleness: run has made no progress", {
2730
+ workflow: g.tag,
2731
+ runId: g.runId,
2732
+ idleMs: g.idleMs,
2733
+ reason: g.reason,
2734
+ ..._
2735
+ }), e.recordEvent !== void 0) try {
2736
+ await e.recordEvent({
2737
+ runId: g.runId,
2738
+ eventType: "run-stalled",
2739
+ payload: {
2740
+ idleMs: g.idleMs,
2741
+ stallAfterMs: r,
2742
+ lastProgressAt: g.lastProgressAt.toISOString(),
2743
+ reason: g.reason,
2744
+ tag: g.tag,
2745
+ executionId: g.executionId,
2746
+ ..._
2747
+ }
2748
+ });
2749
+ } catch (e) {
2750
+ s.push({
2751
+ subject: g.runId,
2752
+ detail: or(e)
2753
+ });
2754
+ }
2755
+ if (e.onStalled !== void 0) try {
2756
+ await e.onStalled(g);
2757
+ } catch (e) {
2758
+ s.push({
2759
+ subject: `${g.runId}:onStalled`,
2760
+ detail: or(e)
2761
+ });
2762
+ }
2763
+ }
2764
+ return {
2765
+ examined: d.length,
2766
+ stalled: c,
2767
+ alreadyReported: l,
2768
+ waitingOnTimer: u,
2769
+ sawFullRunPage: d.length >= i,
2770
+ failures: s,
2771
+ ...f === void 0 ? {} : { nextRun: f }
2772
+ };
2773
+ }, fr = async (e, t, n) => {
2774
+ let r = await e.transaction((e) => B(e, t.id));
2775
+ if (r === void 0 || r.workflowName !== t.workflowName || r.tenantId !== t.tenantId || r.ledgerId !== t.ledgerId) throw Error("Submission dispatch lost its resident owner");
2776
+ if (!r.receiptsBound || r.failureId !== null) throw Error("Cannot dispatch an incomplete or rejected submission");
2777
+ if (r.preparedExecutionId !== null) {
2778
+ if (r.executionId !== null && r.executionId !== r.preparedExecutionId) throw Error("Submission acceptance contradicts its prepared identity");
2779
+ return r.preparedExecutionId;
2780
+ }
2781
+ if (r.dispatchAttempts !== 0 || r.executionId !== null) throw Error("Submission has an unbound prior dispatch; reconciliation required");
2782
+ let i = await e.resolveExecutionId(t.workflowName, n), a = await e.transaction((e) => bt(e, t.id, i));
2783
+ if (a.preparedExecutionId === null) throw Error("Submission preparation returned no execution identity");
2784
+ return a.preparedExecutionId;
2785
+ }, pr = /* @__PURE__ */ new WeakMap(), mr = async (e, t, n, r) => {
2786
+ let i = pr.get(e), a = await mt(e.store, n, i?.afterId), o = 0, s = 0, c = 0, l = 0, u = i?.nextDueAt, d = (e) => {
2787
+ u = Math.min(u ?? e, e);
2788
+ };
2789
+ for (let n of a) {
2790
+ let i;
2791
+ try {
2792
+ i = dt(n);
2793
+ } catch {
2794
+ o++, c++, d(t + Zt(1)), e.log?.warn?.("workflow submission metadata is invalid", { submissionId: typeof n.id == "string" ? n.id : null });
2795
+ continue;
2796
+ }
2797
+ o++;
2798
+ let a = i.dispatchAttempts === 0 ? 0 : void 0;
2799
+ try {
2800
+ let n = i.preparedExecutionId, r = n === null || i.dispatchAttempts === 0 ? void 0 : await e.transaction(async (e) => {
2801
+ let t = await ct(e, i.workflowName, n);
2802
+ return t === void 0 ? void 0 : {
2803
+ executionId: n,
2804
+ runId: t.runId
2805
+ };
2806
+ });
2807
+ if (r === void 0 && i.retry.stoppedAt !== null) {
2808
+ o--;
2809
+ continue;
2810
+ }
2811
+ if (r === void 0 && i.retry.after > t) {
2812
+ o--, d(i.retry.after);
2813
+ continue;
2814
+ }
2815
+ if (r === void 0 && e.acquireSubmissionCapacity !== void 0 && !await e.acquireSubmissionCapacity(i)) {
2816
+ d(t + 1e3);
2817
+ continue;
2818
+ }
2819
+ let c = r ?? await (async () => {
2820
+ let n = e.controls.get(i.workflowName)?.batch === void 0 ? G(e.store, i.workflowName, i.payload) : { items: w.decodeUnknownSync(w.Struct({ items: w.Array(w.Unknown) }))(i.payload).items.map((t) => G(e.store, i.workflowName, t)) }, r = await fr(e, i, n), o = await e.transaction((e) => St(e, i.id, t));
2821
+ if (o === null) return;
2822
+ a = o.dispatchAttempts === 1 ? 1 : void 0;
2823
+ let s = await e.startAdmitted(i.workflowName, n, i.callerContext, r);
2824
+ if (a = void 0, s.executionId !== r) throw Error("Engine returned a different prepared execution identity");
2825
+ return s;
2826
+ })();
2827
+ if (c === void 0) continue;
2828
+ a = void 0, i.eviction !== null && (await e.cancelRun({
2829
+ workflowName: i.workflowName,
2830
+ ...i.eviction,
2831
+ reason: "cancelled to make room for a newer start (singleton mode 'cancel')",
2832
+ detail: {
2833
+ source: "flow-control",
2834
+ mode: "singleton"
2835
+ }
2836
+ }), await Wt(e.store, i.eviction.executionId, t)), await e.transaction((e) => yt(e, i.id, {
2837
+ executionId: c.executionId,
2838
+ runId: c.runId ?? null
2839
+ })), s++;
2840
+ } catch (n) {
2841
+ c++;
2842
+ let o;
2843
+ try {
2844
+ if (a !== void 0 && e.isPermanentStartError?.(n) === !0) {
2845
+ let r = a, o = await e.transaction((a) => Ct(a, i.id, r, {
2846
+ handler: e.controls.get(i.workflowName)?.onFailure ?? null,
2847
+ errorMessage: String(n),
2848
+ now: t
2849
+ }));
2850
+ if (o !== void 0) {
2851
+ l++, e.log?.warn?.("workflow submission rejected; failure report retained", {
2852
+ workflow: i.workflowName,
2853
+ submissionId: i.id,
2854
+ failureId: o.id
2855
+ });
2856
+ continue;
2857
+ }
2858
+ }
2859
+ o = await e.transaction((e) => xt(e, i.id, String(n), t, r));
2860
+ } catch (r) {
2861
+ d(t), e.log?.warn?.("workflow submission retry state could not be recorded", {
2862
+ workflow: i.workflowName,
2863
+ submissionId: i.id,
2864
+ cause: String(n),
2865
+ recordingCause: String(r)
2866
+ });
2867
+ continue;
2868
+ }
2869
+ o.retry.stoppedAt === null && d(o.retry.after), e.log?.warn?.("workflow submission remains unacknowledged", {
2870
+ workflow: i.workflowName,
2871
+ submissionId: i.id,
2872
+ cause: String(n),
2873
+ retryStoppedAt: o.retry.stoppedAt,
2874
+ acceptance: "unknown"
2875
+ });
2876
+ }
2877
+ }
2878
+ let f = a.at(-1);
2879
+ return a.length === n && f !== void 0 && typeof f.id == "string" ? (pr.set(e, {
2880
+ afterId: f.id,
2881
+ nextDueAt: u
2882
+ }), {
2883
+ scanned: o,
2884
+ admitted: s,
2885
+ failed: c,
2886
+ rejected: l,
2887
+ nextDueAt: t,
2888
+ examined: !0
2889
+ }) : (pr.delete(e), {
2890
+ scanned: o,
2891
+ admitted: s,
2892
+ failed: c,
2893
+ rejected: l,
2894
+ nextDueAt: u,
2895
+ examined: a.length > 0
2896
+ });
2897
+ }, hr = /* @__PURE__ */ new WeakMap(), gr = async (e, t, n) => {
2898
+ let r = hr.get(e), i = await e.store.query({
2899
+ table: qe,
2900
+ predicate: T(de("handler"), M("acceptedExecutionId"), ...r === void 0 ? [] : [k("id", r.afterId)]),
2901
+ order: [{
2902
+ column: "id",
2903
+ direction: "asc"
2904
+ }],
2905
+ take: n,
2906
+ skip: void 0,
2907
+ projection: void 0
2908
+ }), a = 0, o = !1, s = r?.nextDueAt, c = () => {
2909
+ let e = t + Zt(1, () => 1);
2910
+ s = Math.min(s ?? e, e);
2911
+ };
2912
+ for (let n of i) try {
2913
+ if (typeof n.id != "string" || n.id.length === 0) throw Error("Failure report has no identity");
2914
+ let r = n.id;
2915
+ (await e.transaction((e) => ot(e, r, t))).kind === "queued" && (o = !0, c());
2916
+ } catch (t) {
2917
+ a++, c(), e.log?.warn?.("workflow failure delivery could not be reconciled", {
2918
+ failureId: typeof n.id == "string" ? n.id : null,
2919
+ ...t instanceof at ? { reason: t.reason } : {}
2920
+ });
2921
+ }
2922
+ let l = i.at(-1);
2923
+ return i.length === n && l !== void 0 && typeof l.id == "string" ? (hr.set(e, {
2924
+ afterId: l.id,
2925
+ nextDueAt: s
2926
+ }), {
2927
+ scanned: i.length,
2928
+ failed: a,
2929
+ hasPending: o,
2930
+ nextDueAt: t,
2931
+ examined: !0
2932
+ }) : (hr.delete(e), {
2933
+ scanned: i.length,
2934
+ failed: a,
2935
+ hasPending: o,
2936
+ nextDueAt: s,
2937
+ examined: i.length > 0
2938
+ });
2939
+ }, _r = "_voltro_workflow_parent_closures", vr = /* @__PURE__ */ new WeakMap(), yr = async (e, t, n) => {
2940
+ let r = vr.get(e), i = await e.store.query({
2941
+ table: _r,
2942
+ predicate: T(M("completedAt"), ...r === void 0 ? [] : [k("id", r.afterId)]),
2943
+ order: [{
2944
+ column: "id",
2945
+ direction: "asc"
2946
+ }],
2947
+ take: n,
2948
+ skip: void 0,
2949
+ projection: void 0
2950
+ }), a = 0, o = r?.nextDueAt, s = () => {
2951
+ o = Math.min(o ?? t + 1e3, t + 1e3);
2952
+ };
2953
+ for (let n of i) try {
2954
+ if (typeof n.id != "string" || n.id.length === 0) throw Error("Parent closure has no identity");
2955
+ let r = n.id;
2956
+ await e.transaction(async (e) => {
2957
+ await ln(e, r, t);
2958
+ let [n] = await e.query({
2959
+ table: _r,
2960
+ predicate: O("id", r),
2961
+ order: [],
2962
+ take: 1,
2963
+ skip: void 0,
2964
+ projection: ["completedAt"]
2965
+ });
2966
+ if (n === void 0) throw Error("Parent closure disappeared");
2967
+ return n.completedAt instanceof Date && Number.isFinite(n.completedAt.getTime());
2968
+ }) || s();
2969
+ } catch {
2970
+ a++, s(), e.log?.warn?.("workflow parent closure could not be reconciled", { closureId: typeof n.id == "string" ? n.id : null });
2971
+ }
2972
+ let c = i.at(-1);
2973
+ return i.length === n && typeof c?.id == "string" ? (vr.set(e, {
2974
+ afterId: c.id,
2975
+ nextDueAt: o
2976
+ }), {
2977
+ scanned: i.length,
2978
+ failed: a,
2979
+ nextDueAt: t,
2980
+ examined: !0
2981
+ }) : (vr.delete(e), {
2982
+ scanned: i.length,
2983
+ failed: a,
2984
+ nextDueAt: o,
2985
+ examined: i.length > 0
2986
+ });
2987
+ }, br = async (e, t) => {
2988
+ if (t.from === t.to) throw Error("Queue transfer requires distinct source and target");
2989
+ let n = await e.query({
2990
+ table: U,
2991
+ predicate: O("id", t.to),
2992
+ order: [],
2993
+ take: 1,
2994
+ skip: void 0,
2995
+ projection: void 0
2996
+ }), r = w.decodeUnknownSync(w.Struct({
2997
+ workflowName: w.String,
2998
+ tenantId: w.NullOr(w.String)
2999
+ }))(n[0]);
3000
+ if (r.workflowName !== t.workflowName || r.tenantId !== t.tenantId) throw Error("Receipt target belongs to a different workflow or tenant");
3001
+ for (;;) {
3002
+ let n = await e.query({
3003
+ table: Tt,
3004
+ predicate: T(O("pendingId", t.from), M("submissionId"), M("terminal")),
3005
+ order: [{
3006
+ column: "id",
3007
+ direction: "asc"
3008
+ }],
3009
+ take: 100,
3010
+ skip: void 0,
3011
+ projection: void 0
3012
+ });
3013
+ if (n.length === 0) return;
3014
+ for (let r of n) {
3015
+ let n = V(r);
3016
+ if (n.workflowName !== t.workflowName || n.tenantId !== t.tenantId) throw Error("Forwarded receipt belongs to a different workflow or tenant");
3017
+ if (await e.update("_voltro_workflow_start_receipts", n.id, { pendingId: t.to }) === null) throw Error("Start receipt disappeared during queue transfer");
3018
+ }
3019
+ }
3020
+ }, xr = {
3021
+ scanned: 0,
3022
+ admitted: 0,
3023
+ deferred: 0,
3024
+ dropped: 0,
3025
+ skipped: 0,
3026
+ expired: 0,
3027
+ evicted: 0,
3028
+ failed: 0,
3029
+ deadLettered: 0,
3030
+ timedOut: 0,
3031
+ examined: !1
3032
+ }, Sr = 200, Cr = class extends Error {
3033
+ submissionId;
3034
+ rejected;
3035
+ constructor(e, t, n = !1) {
3036
+ super(n ? `Submission ${e} rejected; failure report retained` : `Submission ${e} remains unacknowledged`, { cause: t }), this.submissionId = e, this.rejected = n;
3037
+ }
3038
+ }, wr = async (e, t = {}) => {
3039
+ let n = e.now ?? (() => Date.now()), r = e.log, i = t.batchSize ?? 200, a, o, s, c, l, u;
3040
+ try {
3041
+ c = await mr(e, n(), i, e.deadLetterAfterAttempts ?? 50), l = await gr(e, n(), i), u = await yr(e, n(), i), a = await (e.readPauses?.() ?? It(e.store));
3042
+ let r = t.skipPending === !0 && !l.hasPending ? {
3043
+ due: [],
3044
+ nextDueAt: void 0
3045
+ } : await Kt(e.store, n(), i);
3046
+ o = r.due, s = c.nextDueAt === void 0 ? r.nextDueAt : Math.min(r.nextDueAt ?? c.nextDueAt, c.nextDueAt), l.nextDueAt !== void 0 && (s = Math.min(s ?? l.nextDueAt, l.nextDueAt)), u.nextDueAt !== void 0 && (s = Math.min(s ?? u.nextDueAt, u.nextDueAt));
3047
+ } catch (e) {
3048
+ return r?.warn?.("workflow flow control: could not read the admission queue", { cause: String(e) }), {
3049
+ ...xr,
3050
+ scanned: (c?.scanned ?? 0) + (l?.scanned ?? 0) + (u?.scanned ?? 0),
3051
+ admitted: c?.admitted ?? 0,
3052
+ deadLettered: c?.rejected ?? 0,
3053
+ failed: (c?.failed ?? 0) + (l?.failed ?? 0) + (u?.failed ?? 0) + 1,
3054
+ nextDueAt: n()
3055
+ };
3056
+ }
3057
+ let d = {
3058
+ scanned: o.length + c.scanned + l.scanned + u.scanned,
3059
+ admitted: c.admitted,
3060
+ deferred: 0,
3061
+ dropped: 0,
3062
+ skipped: 0,
3063
+ expired: 0,
3064
+ evicted: 0,
3065
+ failed: c.failed + l.failed + u.failed,
3066
+ deadLettered: c.rejected,
3067
+ timedOut: 0
3068
+ }, f = /* @__PURE__ */ new Map(), p = [];
3069
+ for (let e of o) {
3070
+ if (e.mode === "batch") {
3071
+ let t = `${e.workflowName}\u0000${e.controlKey}`, n = f.get(t);
3072
+ n === void 0 ? f.set(t, [e]) : n.push(e);
3073
+ continue;
3074
+ }
3075
+ p.push(e);
3076
+ }
3077
+ let m = e.deadLetterAfterAttempts === void 0 ? 50 : e.deadLetterAfterAttempts, h = (t, n, r) => {
3078
+ if (e.isPermanentStartError?.(n) === !0) return `pending ${r} was dead-lettered after a permanent start failure: ${String(n)}`;
3079
+ if (m !== !1 && t.attempts + 1 >= m) return `pending ${r} was dead-lettered after ${t.attempts + 1} failed attempts: ${String(n)}`;
3080
+ };
3081
+ for (let t of p) try {
3082
+ await Dr(e, t, a, d, n());
3083
+ } catch (i) {
3084
+ if (d.failed++, i instanceof Cr) {
3085
+ i.rejected && d.deadLettered++, r?.warn?.(i.message, {
3086
+ submissionId: i.submissionId,
3087
+ cause: String(i.cause)
3088
+ });
3089
+ continue;
3090
+ }
3091
+ let a = h(t, i, "intent");
3092
+ if (a !== void 0) {
3093
+ let o = n(), s = String(i);
3094
+ if (!await e.onAbandoned({
3095
+ workflowName: t.workflowName,
3096
+ payload: t.payload,
3097
+ callerContext: t.callerContext,
3098
+ reason: a,
3099
+ runId: null,
3100
+ executionId: null
3101
+ }).then(() => !0, (e) => (r?.warn?.("workflow flow control: permanent failure could not signal onFailure", {
3102
+ workflow: t.workflowName,
3103
+ intent: t.id,
3104
+ cause: String(e)
3105
+ }), !1))) {
3106
+ await Qt(e.store, t, s, o).catch(() => {});
3107
+ continue;
3108
+ }
3109
+ if (await $t(e.store, t, s, o).catch(() => !1)) {
3110
+ d.deadLettered++, r?.warn?.("workflow flow control: intent dead-lettered", {
3111
+ workflow: t.workflowName,
3112
+ intent: t.id,
3113
+ cause: s
3114
+ });
3115
+ continue;
3116
+ }
3117
+ }
3118
+ r?.warn?.("workflow flow control: an intent failed to drain", {
3119
+ workflow: t.workflowName,
3120
+ intent: t.id,
3121
+ cause: String(i)
3122
+ }), await Qt(e.store, t, String(i), n()).catch(() => {});
3123
+ }
3124
+ for (let t of f.values()) try {
3125
+ await kr(e, t, a, d, n());
3126
+ } catch (i) {
3127
+ if (d.failed++, i instanceof Cr) {
3128
+ i.rejected && d.deadLettered++, r?.warn?.(i.message, {
3129
+ submissionId: i.submissionId,
3130
+ cause: String(i.cause)
3131
+ });
3132
+ continue;
3133
+ }
3134
+ let a = t[0], o = a === void 0 ? void 0 : h(a, i, "batch");
3135
+ if (a !== void 0 && o !== void 0) {
3136
+ let s = n(), c = String(i);
3137
+ if (!await e.onAbandoned({
3138
+ workflowName: a.workflowName,
3139
+ payload: { items: t.map((e) => e.payload) },
3140
+ callerContext: a.callerContext,
3141
+ reason: o,
3142
+ runId: null,
3143
+ executionId: null
3144
+ }).then(() => !0, (e) => (r?.warn?.("workflow flow control: permanent batch failure could not signal onFailure", {
3145
+ workflow: a.workflowName,
3146
+ intents: t.map((e) => e.id),
3147
+ size: t.length,
3148
+ cause: String(e)
3149
+ }), !1))) {
3150
+ await Promise.all(t.map((t) => Qt(e.store, t, c, s).catch(() => {})));
3151
+ continue;
3152
+ }
3153
+ if ((await Promise.all(t.map((t) => $t(e.store, t, c, s).catch(() => !1)))).every(Boolean)) {
3154
+ d.deadLettered += t.length, r?.warn?.("workflow flow control: batch dead-lettered", {
3155
+ workflow: a.workflowName,
3156
+ intents: t.map((e) => e.id),
3157
+ size: t.length,
3158
+ cause: c
3159
+ });
3160
+ continue;
3161
+ }
3162
+ }
3163
+ r?.warn?.("workflow flow control: a batch failed to drain", {
3164
+ workflow: a?.workflowName,
3165
+ size: t.length,
3166
+ cause: String(i)
3167
+ });
3168
+ let s = n(), c = Math.random();
3169
+ await e.transaction(async (e) => {
3170
+ let n = [];
3171
+ for (let r of t) {
3172
+ let t = await e.query({
3173
+ table: U,
3174
+ predicate: O("id", r.id),
3175
+ order: [],
3176
+ take: 1,
3177
+ skip: void 0,
3178
+ projection: void 0,
3179
+ lock: "update"
3180
+ });
3181
+ if (t[0] === void 0) return;
3182
+ let i = q(t[0]);
3183
+ if (i.workflowName !== r.workflowName || i.tenantId !== r.tenantId || i.mode !== r.mode || i.firstSeenAt !== r.firstSeenAt || i.dueAt !== r.dueAt || i.deadLetteredAt !== void 0) return;
3184
+ n.push(i);
3185
+ }
3186
+ let r = new Date(s + Zt(Math.max(...n.map((e) => e.attempts + 1)), () => c));
3187
+ for (let t of n) if (await e.update("_voltro_workflow_pending", t.id, {
3188
+ attempts: t.attempts + 1,
3189
+ lastError: String(i).slice(0, 500),
3190
+ dueAt: r,
3191
+ updatedAt: new Date(s)
3192
+ }) === null) throw Error("Batch input disappeared while recording the shared retry deadline");
3193
+ }).catch((e) => r?.warn?.("workflow flow control: batch retry could not be persisted", {
3194
+ workflow: a?.workflowName,
3195
+ intents: t.map((e) => e.id),
3196
+ cause: String(e)
3197
+ }));
3198
+ }
3199
+ let g = await Nr(e, n()).catch(() => ({ cancelled: 0 }));
3200
+ return d.timedOut = g.cancelled, g.nextDeadlineAt !== void 0 && (s === void 0 || g.nextDeadlineAt < s) && (s = g.nextDeadlineAt), {
3201
+ ...d,
3202
+ examined: t.skipPending !== !0 || c.examined || l.examined || u.examined,
3203
+ ...s === void 0 ? {} : { nextDueAt: s }
3204
+ };
3205
+ }, Tr = async (e, t, n) => {
3206
+ let r = t.map((e) => ({
3207
+ intent: e,
3208
+ failureId: `wff_${L()}`
3209
+ }));
3210
+ return e.transaction(async (e) => {
3211
+ let t = 0;
3212
+ for (let { intent: i, failureId: a } of r) {
3213
+ let r = (await e.query({
3214
+ table: U,
3215
+ predicate: O("id", i.id),
3216
+ order: [],
3217
+ take: 1,
3218
+ skip: void 0,
3219
+ projection: void 0,
3220
+ lock: "update"
3221
+ }))[0];
3222
+ if (r === void 0) continue;
3223
+ let o = q(r);
3224
+ if (o.workflowName !== i.workflowName || o.tenantId !== i.tenantId) throw Error("Abandoned queue selection belongs to another workflow or tenant");
3225
+ if (o.dueAt > n || o.deadLetteredAt !== void 0) continue;
3226
+ let s = `workflow '${o.workflowName}' no longer has its queued declaration`;
3227
+ if (await Ye(e, {
3228
+ id: a,
3229
+ sourceKind: "intent",
3230
+ sourceId: o.id,
3231
+ workflowName: o.workflowName,
3232
+ tenantId: o.tenantId,
3233
+ handler: null,
3234
+ callerContext: o.callerContext,
3235
+ report: {
3236
+ workflow: o.workflowName,
3237
+ payload: o.payload,
3238
+ reason: s,
3239
+ failedAt: n,
3240
+ errorTag: null,
3241
+ errorMessage: null,
3242
+ runId: null,
3243
+ executionId: null
3244
+ }
3245
+ }), await H(e, {
3246
+ pendingId: o.id,
3247
+ workflowName: o.workflowName,
3248
+ tenantId: o.tenantId,
3249
+ terminal: {
3250
+ kind: "abandoned",
3251
+ at: n,
3252
+ failureId: a
3253
+ }
3254
+ }), !await e.delete("_voltro_workflow_pending", o.id)) throw Error("Abandoned queue row disappeared before deletion");
3255
+ t++;
3256
+ }
3257
+ return t;
3258
+ });
3259
+ }, Er = async (e, t, n, r, i) => {
3260
+ let a = `wff_${L()}`;
3261
+ return e.transaction(async (e) => {
3262
+ let o = [];
3263
+ for (let i of t) {
3264
+ let t = await e.query({
3265
+ table: U,
3266
+ predicate: O("id", i.id),
3267
+ order: [],
3268
+ take: 1,
3269
+ skip: void 0,
3270
+ projection: void 0,
3271
+ lock: "update"
3272
+ });
3273
+ if (t[0] === void 0) return 0;
3274
+ let a = q(t[0]);
3275
+ if (a.workflowName !== n.workflowName || a.tenantId !== i.tenantId) throw Error("Expired queue selection belongs to another workflow or tenant");
3276
+ if (a.mode !== i.mode || a.dueAt > r || a.deadLetteredAt !== void 0) return 0;
3277
+ o.push(a);
3278
+ }
3279
+ o.sort((e, t) => e.firstSeenAt - t.firstSeenAt || e.id.localeCompare(t.id));
3280
+ let s = o[0];
3281
+ if (s === void 0 || !We(n, s, r)) return 0;
3282
+ let c = await Promise.all(o.map((t) => Qe(e, t.id)));
3283
+ if (c.some(Boolean) && !c.every(Boolean)) throw Error("Expired batch mixes failure delivery and ordinary callers; reconciliation required");
3284
+ let l = `timeouts.start (${n.timeouts?.startMs}ms) elapsed while ${o.length} queued input(s) waited`;
3285
+ await Ye(e, {
3286
+ id: a,
3287
+ sourceKind: "intent",
3288
+ sourceId: s.id,
3289
+ workflowName: s.workflowName,
3290
+ tenantId: s.tenantId,
3291
+ handler: c.every(Boolean) ? null : n.onFailure ?? null,
3292
+ callerContext: s.callerContext,
3293
+ report: {
3294
+ workflow: s.workflowName,
3295
+ payload: i ? { items: o.map((e) => e.payload) } : s.payload,
3296
+ reason: l,
3297
+ failedAt: r,
3298
+ errorTag: null,
3299
+ errorMessage: null,
3300
+ runId: null,
3301
+ executionId: null
3302
+ }
3303
+ }), await Y({
3304
+ store: e,
3305
+ control: n,
3306
+ keys: R(n, G(e, s.workflowName, s.payload)),
3307
+ outcome: "expired",
3308
+ mode: s.mode,
3309
+ reason: l,
3310
+ collapsed: o.reduce((e, t) => e + t.collapsed, 0),
3311
+ waitedMs: r - s.firstSeenAt,
3312
+ executionId: null,
3313
+ runId: null,
3314
+ tenantId: s.tenantId,
3315
+ now: r
3316
+ });
3317
+ for (let t of o) if (await H(e, {
3318
+ pendingId: t.id,
3319
+ workflowName: t.workflowName,
3320
+ tenantId: t.tenantId,
3321
+ terminal: {
3322
+ kind: "abandoned",
3323
+ at: r,
3324
+ failureId: a
3325
+ }
3326
+ }), !await e.delete("_voltro_workflow_pending", t.id)) throw Error("Expired queue row disappeared before deletion");
3327
+ return await it(e, a, r), o.length;
3328
+ });
3329
+ }, Dr = async (e, t, n, r, i) => {
3330
+ if (t = {
3331
+ ...t,
3332
+ payload: G(e.store, t.workflowName, t.payload)
3333
+ }, t.mode === "delayed") return Or(e, t, n, r, i);
3334
+ let a = e.controls.get(t.workflowName);
3335
+ if (a === void 0) {
3336
+ r.expired += await Tr(e, [t], i);
3337
+ return;
3338
+ }
3339
+ if (We(a, t, i)) {
3340
+ r.expired += await Er(e, [t], a, i, !1);
3341
+ return;
3342
+ }
3343
+ let o = R(a, t.payload), s = await tn({
3344
+ store: e.store,
3345
+ control: a,
3346
+ keys: o,
3347
+ paused: n.has(t.workflowName),
3348
+ now: i,
3349
+ reconsidering: !0
3350
+ });
3351
+ await Ar(e, {
3352
+ control: a,
3353
+ intent: t,
3354
+ decision: s,
3355
+ keys: o,
3356
+ counters: r,
3357
+ now: i,
3358
+ paused: n,
3359
+ items: void 0
3360
+ });
3361
+ }, Or = async (e, t, n, r, i) => {
3362
+ if (e.registeredWorkflows !== void 0 && !e.registeredWorkflows.has(t.workflowName)) {
3363
+ r.expired += await Tr(e, [t], i);
3364
+ return;
3365
+ }
3366
+ let a = e.controls.get(t.workflowName) ?? { workflowName: t.workflowName }, o = `wfsub_${L()}`, s = await e.transaction(async (e) => {
3367
+ let r = await e.query({
3368
+ table: U,
3369
+ predicate: O("id", t.id),
3370
+ lock: "update",
3371
+ order: [],
3372
+ take: 1,
3373
+ skip: void 0,
3374
+ projection: void 0
3375
+ });
3376
+ if (r[0] === void 0) return;
3377
+ let s = q(r[0]);
3378
+ if (s.workflowName !== t.workflowName || s.tenantId !== t.tenantId) throw Error("Delayed arrival belongs to a different workflow or tenant");
3379
+ if (s.mode !== "delayed" || s.deadLetteredAt !== void 0 || s.dueAt > i) return;
3380
+ let c = await Ln({
3381
+ store: e,
3382
+ control: a,
3383
+ payload: G(e, s.workflowName, s.payload),
3384
+ callerContext: s.callerContext,
3385
+ tenantId: s.tenantId,
3386
+ paused: n.has(s.workflowName),
3387
+ now: i,
3388
+ waiting: !1
3389
+ });
3390
+ if (c.kind === "queued" && (await br(e, {
3391
+ from: s.id,
3392
+ to: c.intentId,
3393
+ workflowName: s.workflowName,
3394
+ tenantId: s.tenantId
3395
+ }), !await Jt(e, s.id))) throw Error("Delayed arrival disappeared during queue transfer");
3396
+ if (c.kind === "start") {
3397
+ if (c.ledgerId === void 0) throw Error("Delayed arrival has no admission reservation");
3398
+ let t = a.batch === void 0 ? Mt(e, s.workflowName, c.payload) : { items: w.decodeUnknownSync(w.Struct({ items: w.Array(w.Unknown) }))(c.payload).items.map((t) => Mt(e, s.workflowName, t)) };
3399
+ return {
3400
+ kind: "submission",
3401
+ submission: await Pn(e, {
3402
+ id: o,
3403
+ workflowName: s.workflowName,
3404
+ tenantId: s.tenantId,
3405
+ ledgerId: c.ledgerId,
3406
+ payload: t,
3407
+ callerContext: s.callerContext,
3408
+ intentIds: [.../* @__PURE__ */ new Set([s.id, ...c.consume])],
3409
+ eviction: c.evict ?? null
3410
+ }),
3411
+ keys: c.keys
3412
+ };
3413
+ }
3414
+ if ((c.kind === "dropped" || c.kind === "skipped") && (await H(e, {
3415
+ pendingId: s.id,
3416
+ workflowName: s.workflowName,
3417
+ tenantId: s.tenantId,
3418
+ terminal: {
3419
+ ...c,
3420
+ at: i
3421
+ }
3422
+ }), !await Jt(e, s.id))) throw Error("Delayed arrival disappeared while recording its outcome");
3423
+ return c;
3424
+ });
3425
+ if (s !== void 0) {
3426
+ if (s.kind === "queued") {
3427
+ r.deferred++;
3428
+ return;
3429
+ }
3430
+ if (s.kind === "dropped") {
3431
+ r.dropped++;
3432
+ return;
3433
+ }
3434
+ if (s.kind === "skipped") {
3435
+ r.skipped++;
3436
+ return;
3437
+ }
3438
+ await Mr(e, s.submission, a, r, i, a.batch !== void 0, s.keys);
3439
+ }
3440
+ }, kr = async (e, t, n, r, i) => {
3441
+ t = t.map((t) => ({
3442
+ ...t,
3443
+ payload: G(e.store, t.workflowName, t.payload)
3444
+ }));
3445
+ let a = t[0];
3446
+ if (a === void 0) return;
3447
+ let o = e.controls.get(a.workflowName);
3448
+ if (o === void 0 || o.batch === void 0) {
3449
+ r.expired += await Tr(e, t, i);
3450
+ return;
3451
+ }
3452
+ let s = [...t].sort((e, t) => e.firstSeenAt - t.firstSeenAt), c = s[0];
3453
+ if (We(o, c, i)) {
3454
+ r.expired += await Er(e, s, o, i, !0);
3455
+ return;
3456
+ }
3457
+ let l = R(o, c.payload);
3458
+ await Ar(e, {
3459
+ control: o,
3460
+ intent: c,
3461
+ decision: await tn({
3462
+ store: e.store,
3463
+ control: o,
3464
+ keys: l,
3465
+ paused: n.has(a.workflowName),
3466
+ now: i,
3467
+ reconsidering: !0
3468
+ }),
3469
+ keys: l,
3470
+ counters: r,
3471
+ now: i,
3472
+ paused: n,
3473
+ items: s
3474
+ });
3475
+ }, Ar = async (e, t) => {
3476
+ let { control: n, intent: r, decision: i, keys: a, counters: o, now: s, items: c, paused: l } = t;
3477
+ if (i.kind === "defer") {
3478
+ await Vt({
3479
+ store: e.store,
3480
+ control: n,
3481
+ decision: i,
3482
+ payload: r.payload,
3483
+ callerContext: r.callerContext,
3484
+ tenantId: r.tenantId,
3485
+ now: s,
3486
+ existingId: r.id
3487
+ }), o.deferred++;
3488
+ return;
3489
+ }
3490
+ if (i.kind === "drop" || i.kind === "skip") {
3491
+ let t = await e.transaction(async (e) => {
3492
+ let t = [];
3493
+ for (let i of c ?? [r]) {
3494
+ let a = await e.query({
3495
+ table: U,
3496
+ predicate: O("id", i.id),
3497
+ lock: "update",
3498
+ order: [],
3499
+ take: 1,
3500
+ skip: void 0,
3501
+ projection: void 0
3502
+ });
3503
+ if (a[0] === void 0) return;
3504
+ let o = q(a[0]);
3505
+ if (o.workflowName !== n.workflowName || o.tenantId !== r.tenantId) throw Error("Terminal queue selection belongs to a different workflow or tenant");
3506
+ if (o.dueAt > s || o.deadLetteredAt !== void 0 || o.mode !== i.mode) return;
3507
+ t.push(o);
3508
+ }
3509
+ t.sort((e, t) => e.firstSeenAt - t.firstSeenAt);
3510
+ let i = t[0], a = R(n, G(e, n.workflowName, i.payload)), o = await tn({
3511
+ store: e,
3512
+ control: n,
3513
+ keys: a,
3514
+ paused: l.has(n.workflowName) || (await It(e)).has(n.workflowName),
3515
+ now: s,
3516
+ reconsidering: !0
3517
+ });
3518
+ if (o.kind !== "drop" && o.kind !== "skip") return;
3519
+ let u = o.kind === "drop" ? {
3520
+ kind: "dropped",
3521
+ at: s,
3522
+ retryAfterMs: o.retryAfterMs
3523
+ } : {
3524
+ kind: "skipped",
3525
+ at: s,
3526
+ executionId: o.incumbent.executionId,
3527
+ runId: o.incumbent.runId
3528
+ };
3529
+ await Y({
3530
+ store: e,
3531
+ control: n,
3532
+ keys: a,
3533
+ outcome: u.kind,
3534
+ mode: u.kind === "dropped" ? "rateLimit" : "singleton",
3535
+ reason: u.kind === "dropped" ? `rate limit reached while queued; retry after ${u.retryAfterMs}ms` : `singleton key held by ${u.executionId}`,
3536
+ collapsed: t.reduce((e, t) => e + t.collapsed, 0),
3537
+ waitedMs: s - i.firstSeenAt,
3538
+ executionId: u.kind === "skipped" ? u.executionId : null,
3539
+ runId: u.kind === "skipped" && u.runId || null,
3540
+ tenantId: r.tenantId,
3541
+ now: s
3542
+ });
3543
+ for (let n of t) if (await H(e, {
3544
+ pendingId: n.id,
3545
+ workflowName: n.workflowName,
3546
+ tenantId: n.tenantId,
3547
+ terminal: u
3548
+ }), !await Jt(e, n.id)) throw Error("Queued input disappeared while recording its terminal outcome");
3549
+ return u.kind;
3550
+ });
3551
+ t !== void 0 && o[t]++;
3552
+ return;
3553
+ }
3554
+ let u = `wfsub_${L()}`, d = await e.transaction((t) => In(t, {
3555
+ id: u,
3556
+ workflowName: n.workflowName,
3557
+ tenantId: r.tenantId,
3558
+ intentIds: (c ?? [r]).map((e) => e.id),
3559
+ now: s,
3560
+ prepare: (t) => {
3561
+ let r = [...t].sort((e, t) => e.firstSeenAt - t.firstSeenAt), i = r[0], a = G(e.store, n.workflowName, i.payload);
3562
+ return {
3563
+ control: n,
3564
+ keyPayload: a,
3565
+ encodedPayload: c === void 0 ? i.payload : { items: r.map((e) => e.payload) },
3566
+ callerContext: i.callerContext,
3567
+ paused: l.has(n.workflowName),
3568
+ firstSeenAt: i.firstSeenAt,
3569
+ collapsed: r.reduce((e, t) => e + t.collapsed, 0),
3570
+ mode: i.mode
3571
+ };
3572
+ }
3573
+ }));
3574
+ if (d.kind !== "selection-unavailable") {
3575
+ if (d.kind === "not-admitted") {
3576
+ o.deferred++;
3577
+ return;
3578
+ }
3579
+ await Mr(e, d.submission, n, o, s, c !== void 0, a);
3580
+ }
3581
+ }, jr = async (e, t, n, r, i) => {
3582
+ let a = await e.transaction((e) => B(e, t.id));
3583
+ if (a === void 0 || !a.receiptsBound || a.workflowName !== n.workflowName || a.workflowName !== t.workflowName || a.tenantId !== t.tenantId || a.ledgerId !== t.ledgerId) throw Error("Admission acceptance callback no longer has its resident submission owner");
3584
+ if (a.executionId !== null) {
3585
+ if (a.failureId !== null || a.executionId.length === 0 || a.executionId !== a.preparedExecutionId) throw Error("Admission acceptance has contradictory resident execution evidence");
3586
+ return a.executionId;
3587
+ }
3588
+ await Mr(e, a, n, {
3589
+ admitted: 0,
3590
+ deferred: 0,
3591
+ dropped: 0,
3592
+ skipped: 0,
3593
+ expired: 0,
3594
+ evicted: 0
3595
+ }, i, n.batch !== void 0, r);
3596
+ let o = await e.transaction((e) => B(e, t.id));
3597
+ if (o?.executionId == null || o.executionId !== o.preparedExecutionId) throw Error("Admission submission has no confirmed engine acceptance");
3598
+ return o.executionId;
3599
+ }, Mr = async (e, t, n, r, i, a, o) => {
3600
+ let s = t.dispatchAttempts === 0 ? 0 : void 0;
3601
+ try {
3602
+ if (e.acquireSubmissionCapacity !== void 0 && !await e.acquireSubmissionCapacity(t)) {
3603
+ r.deferred++;
3604
+ return;
3605
+ }
3606
+ let c = a ? { items: w.decodeUnknownSync(w.Struct({ items: w.Array(w.Unknown) }))(t.payload).items.map((t) => G(e.store, n.workflowName, t)) } : G(e.store, n.workflowName, t.payload), l = await fr(e, t, c), u = await e.transaction((e) => St(e, t.id, i));
3607
+ if (u === null) return;
3608
+ s = u.dispatchAttempts === 1 ? 1 : void 0;
3609
+ let d = await e.startAdmitted(n.workflowName, c, t.callerContext, l);
3610
+ if (s = void 0, d.executionId !== l) throw Error("Engine returned a different prepared execution identity");
3611
+ t.eviction !== null && (await e.cancelRun({
3612
+ workflowName: n.workflowName,
3613
+ runId: t.eviction.runId,
3614
+ executionId: t.eviction.executionId,
3615
+ reason: "cancelled to make room for a newer start (singleton mode 'cancel')",
3616
+ detail: {
3617
+ source: "flow-control",
3618
+ mode: "singleton"
3619
+ }
3620
+ }), await Wt(e.store, t.eviction.executionId, i), await Y({
3621
+ store: e.store,
3622
+ control: n,
3623
+ keys: o,
3624
+ outcome: "evicted",
3625
+ mode: "singleton",
3626
+ reason: "cancelled to make room for a newer start (singleton mode 'cancel')",
3627
+ collapsed: 1,
3628
+ waitedMs: null,
3629
+ executionId: t.eviction.executionId,
3630
+ runId: t.eviction.runId || null,
3631
+ tenantId: t.tenantId,
3632
+ now: i
3633
+ }), r.evicted++), await e.transaction((e) => yt(e, t.id, {
3634
+ executionId: d.executionId,
3635
+ runId: d.runId ?? null
3636
+ })), r.admitted++;
3637
+ } catch (r) {
3638
+ let a = !1;
3639
+ try {
3640
+ if (s !== void 0 && e.isPermanentStartError?.(r) === !0) {
3641
+ let o = s;
3642
+ a = await e.transaction((e) => Ct(e, t.id, o, {
3643
+ handler: n.onFailure ?? null,
3644
+ errorMessage: String(r),
3645
+ now: i
3646
+ })) !== void 0;
3647
+ }
3648
+ if (!a) {
3649
+ let n = await e.transaction((n) => xt(n, t.id, String(r), i, e.deadLetterAfterAttempts ?? 50));
3650
+ n.retry.stoppedAt !== null && e.log?.warn?.("workflow submission automatic retry stopped; engine acceptance unknown", {
3651
+ submissionId: t.id,
3652
+ workflow: t.workflowName,
3653
+ attempts: n.retry.attempts
3654
+ });
3655
+ }
3656
+ } catch (e) {
3657
+ throw new Cr(t.id, AggregateError([r, e], "Submission and retry recording failed"));
3658
+ }
3659
+ throw new Cr(t.id, r, a);
3660
+ }
3661
+ }, Nr = async (e, t) => {
3662
+ if (e.listRunningRuns === void 0) return { cancelled: 0 };
3663
+ let n = 0, r;
3664
+ for (let i of e.controls.values()) {
3665
+ if (i.timeouts?.finishMs === void 0) continue;
3666
+ let a = await e.listRunningRuns(i.workflowName);
3667
+ for (let o of a) {
3668
+ if (!Ge(i, {
3669
+ startedAt: o.startedAt,
3670
+ terminal: !1
3671
+ }, t)) {
3672
+ let e = o.startedAt + i.timeouts.finishMs;
3673
+ (r === void 0 || e < r) && (r = e);
3674
+ continue;
3675
+ }
3676
+ let a = `timeouts.finish (${i.timeouts.finishMs}ms) elapsed; the run was cancelled after ${t - o.startedAt}ms`;
3677
+ await e.cancelRun({
3678
+ workflowName: o.workflowName,
3679
+ runId: o.runId,
3680
+ executionId: o.executionId,
3681
+ reason: a,
3682
+ detail: {
3683
+ source: "flow-control",
3684
+ timeout: "finish"
3685
+ }
3686
+ }) && (await Wt(e.store, o.executionId, t), await e.onAbandoned({
3687
+ workflowName: o.workflowName,
3688
+ payload: o.payload,
3689
+ callerContext: null,
3690
+ reason: a,
3691
+ runId: o.runId,
3692
+ executionId: o.executionId
3693
+ }), n++);
3694
+ }
3695
+ }
3696
+ return {
3697
+ cancelled: n,
3698
+ ...r === void 0 ? {} : { nextDeadlineAt: r }
3699
+ };
3700
+ }, Pr = 3e5, Fr, Ir = (e) => {
3701
+ Fr = e !== void 0 && Number.isFinite(e) && e > 0 ? e : void 0;
3702
+ }, Lr = () => {
3703
+ let e = process.env.VOLTRO_WORKFLOW_SUSPEND_HINT_MS;
3704
+ if (e !== void 0) {
3705
+ let t = Number(e);
3706
+ if (Number.isFinite(t) && t > 0) return t;
3707
+ }
3708
+ return Fr ?? 3e5;
3709
+ }, Rr = /* @__PURE__ */ new Set(), zr = () => {
3710
+ Rr.clear();
3711
+ }, Br = (e) => {
3712
+ let t = Lr();
3713
+ if (!(e.timeoutMs > t)) return !1;
3714
+ let n = `${e.workflowName ?? ""}\u0000${e.signalName}`;
3715
+ if (Rr.has(n)) return !1;
3716
+ Rr.add(n);
3717
+ let r = e.workflowName === void 0 ? "" : ` in workflow '${e.workflowName}'`;
3718
+ return (e.warn ?? ((e) => console.warn(e)))(`awaitSignal('${e.signalName}')${r} declares a ${Math.round(e.timeoutMs / 1e3)}s timeout — a wait that long holds a worker fiber for its whole duration. For human-approval-length waits, awaitSignalSuspending (same call shape, from @voltro/workflow) SUSPENDS the run and frees the slot until the signal arrives. This is a hint, not a behaviour change; it is logged once per workflow. Threshold: workflows.suspendSignalHintMs in app.config.ts, or VOLTRO_WORKFLOW_SUSPEND_HINT_MS.`), !0;
3719
+ }, Vr = async (e, t) => {
3720
+ if (e) try {
3721
+ await e.recordEvent(t);
3722
+ } catch {}
3723
+ }, Hr = (e, n) => {
3724
+ let i = S.gen(function* () {
3725
+ let i = n.pollIntervalMs ?? 200, a = n.maxPollIntervalMs ?? 5e3, o = n.timeoutMs ?? 864e5, s = yield* S.serviceOption(ye), c;
3726
+ Br({
3727
+ workflowName: s._tag === "Some" ? s.value.workflow.name : void 0,
3728
+ signalName: n.name,
3729
+ timeoutMs: o,
3730
+ warn: (e) => {
3731
+ c = e;
3732
+ }
3733
+ }), c !== void 0 && (yield* S.logWarning(c));
3734
+ let l = yield* t, u = yield* S.serviceOption(r), d = u._tag === "Some" ? u.value : void 0;
3735
+ if (l === void 0) return yield* S.die(/* @__PURE__ */ Error("awaitSignal: no active workflow run id in scope"));
3736
+ let f = l;
3737
+ yield* S.promise(() => Vr(d, {
3738
+ runId: f,
3739
+ eventType: "signal-awaited",
3740
+ payload: { signalName: n.name }
3741
+ }));
3742
+ let p = Date.now(), m = i;
3743
+ for (;;) {
3744
+ let t = Date.now() - p;
3745
+ if (t > o) return yield* S.die(/* @__PURE__ */ Error(`awaitSignal('${n.name}') timed out after ${t}ms`));
3746
+ let r = {
3747
+ table: "_voltro_workflow_run_events",
3748
+ order: [{
3749
+ column: "occurredAt",
3750
+ direction: "asc"
3751
+ }],
3752
+ predicate: T(O("runId", f), O("eventType", "signal-sent")),
3753
+ projection: void 0,
3754
+ skip: void 0,
3755
+ take: 1e3
3756
+ }, i = (yield* S.tryPromise({
3757
+ try: () => e.store.query(r),
3758
+ catch: (e) => e
3759
+ })).find((e) => e.payload?.signalName === n.name);
3760
+ if (i !== void 0) {
3761
+ let e = yield* w.decodeUnknown(n.schema)(i.payload?.value);
3762
+ return yield* S.promise(() => Vr(d, {
3763
+ runId: f,
3764
+ eventType: "signal-received",
3765
+ payload: {
3766
+ signalName: n.name,
3767
+ value: i.payload?.value
3768
+ }
3769
+ })), e;
3770
+ }
3771
+ yield* S.sleep(`${m} millis`), m = Math.min(m * 2, a);
3772
+ }
3773
+ });
3774
+ return _.make({
3775
+ name: `await-signal:${n.name}`,
3776
+ success: n.schema,
3777
+ execute: i
3778
+ });
3779
+ }, Ur = async (e, t) => {
3780
+ if (e !== void 0) try {
3781
+ await e.recordEvent(t);
3782
+ } catch {}
3783
+ }, Wr = (e, n) => {
3784
+ let i = S.gen(function* () {
3785
+ let i = n.pollIntervalMs ?? 200, a = n.maxPollIntervalMs ?? 5e3, o = n.timeoutMs ?? 864e5, s = n.take ?? 500, c = yield* t, l = yield* S.serviceOption(r), u = l._tag === "Some" ? l.value : void 0;
3786
+ if (c === void 0) return yield* S.die(/* @__PURE__ */ Error("awaitEvent: no active workflow run id in scope"));
3787
+ let d = c, f = yield* n.since === "run-start" ? Gr(e, d) : S.succeed(/* @__PURE__ */ new Date());
3788
+ yield* S.promise(() => Ur(u, {
3789
+ runId: d,
3790
+ eventType: "event-awaited",
3791
+ payload: {
3792
+ event: n.event,
3793
+ since: n.since ?? "wait-start",
3794
+ cutoff: f.toISOString()
3795
+ }
3796
+ }));
3797
+ let p = Date.now(), m = i, h = 0;
3798
+ for (;;) {
3799
+ let t = Date.now() - p;
3800
+ if (t > o) return yield* S.die(/* @__PURE__ */ Error(`awaitEvent('${n.event}') timed out after ${t}ms having examined ${h} candidate event(s). ${h === 0 ? "NONE were published under that name in the window — check the spelling against ctx.events.publish, and consider since: 'run-start' if the event may have arrived before this step began." : "The predicate rejected all of them — log one payload and compare it with what `match` expects."}`));
3801
+ let r = {
3802
+ table: "_voltro_workflow_events",
3803
+ predicate: T(O("name", n.event), le("occurredAt", f)),
3804
+ order: [{
3805
+ column: "occurredAt",
3806
+ direction: "asc"
3807
+ }],
3808
+ take: s,
3809
+ skip: void 0,
3810
+ projection: void 0
3811
+ }, i = yield* S.tryPromise({
3812
+ try: () => e.store.query(r),
3813
+ catch: (e) => e
3814
+ });
3815
+ h = i.length;
3816
+ for (let e of i) {
3817
+ let t = yield* w.decodeUnknown(n.schema)(e.payload);
3818
+ if (n.match(t)) return yield* S.promise(() => Ur(u, {
3819
+ runId: d,
3820
+ eventType: "event-received",
3821
+ payload: {
3822
+ event: n.event,
3823
+ eventId: e.id
3824
+ }
3825
+ })), t;
3826
+ }
3827
+ yield* S.sleep(`${m} millis`), m = Math.min(m * 2, a);
3828
+ }
3829
+ });
3830
+ return _.make({
3831
+ name: `awaitEvent:${n.event}`,
3832
+ success: n.schema,
3833
+ execute: i
3834
+ });
3835
+ }, Gr = (e, t) => S.gen(function* () {
3836
+ let n = (yield* S.tryPromise({
3837
+ try: () => e.store.query({
3838
+ table: "_voltro_workflow_runs",
3839
+ predicate: O("id", t),
3840
+ order: [],
3841
+ take: 1,
3842
+ skip: void 0,
3843
+ projection: void 0
3844
+ }),
3845
+ catch: (e) => e
3846
+ }))[0]?.startedAt;
3847
+ if (n instanceof Date) return n;
3848
+ if (typeof n == "string" || typeof n == "number") {
3849
+ let e = new Date(n);
3850
+ if (!Number.isNaN(e.getTime())) return e;
3851
+ }
3852
+ return /* @__PURE__ */ new Date(0);
3853
+ }), Kr = (e) => new Promise((t) => setTimeout(t, e)), qr = () => {
3854
+ let e = globalThis.crypto;
3855
+ return typeof e?.randomUUID == "function" ? e.randomUUID() : `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
3856
+ }, Jr = () => `wfu_${qr()}`, Yr = async (e, t) => {
3857
+ let n = t.id ?? t.executionId;
3858
+ if (!n) throw Error("workflow message target requires target.id or target.executionId");
3859
+ let r = await e.query({
3860
+ table: "_voltro_workflow_runs",
3861
+ order: [],
3862
+ predicate: O("id", n),
3863
+ projection: void 0,
3864
+ skip: void 0,
3865
+ take: 1
3866
+ });
3867
+ if (r[0]) return r[0];
3868
+ let i = (await e.query({
3869
+ table: "_voltro_workflow_runs",
3870
+ order: [],
3871
+ predicate: O("executionId", n),
3872
+ projection: void 0,
3873
+ skip: void 0,
3874
+ take: 1
3875
+ }))[0];
3876
+ if (!i) throw Error(`workflow message target not found: ${n}`);
3877
+ return i;
3878
+ }, Xr = async (e) => {
3879
+ let t = await Yr(e.store, e.target);
3880
+ return { eventId: (await e.recorder.recordEvent({
3881
+ runId: t.id,
3882
+ eventType: "signal-sent",
3883
+ payload: {
3884
+ signalName: e.signalName,
3885
+ value: e.payload
3886
+ }
3887
+ })).id };
3888
+ }, Zr = async (e) => {
3889
+ let t = await Yr(e.store, e.target), n = Jr(), r = await e.recorder.recordEvent({
3890
+ runId: t.id,
3891
+ eventType: "update-requested",
3892
+ payload: {
3893
+ updateId: n,
3894
+ updateName: e.updateName,
3895
+ value: e.payload
3896
+ }
3897
+ }), i = Date.now(), a = e.options?.timeoutMs ?? 3e4, o = e.options?.pollIntervalMs ?? 100;
3898
+ for (;;) {
3899
+ let s = {
3900
+ table: "_voltro_workflow_run_events",
3901
+ order: [{
3902
+ column: "occurredAt",
3903
+ direction: "asc"
3904
+ }],
3905
+ predicate: O("runId", t.id),
3906
+ projection: void 0,
3907
+ skip: void 0,
3908
+ take: 1e3
3909
+ }, c = await e.store.query(s), l = c.find((e) => e.eventType === "update-completed" && e.payload?.updateId === n);
3910
+ if (l) return {
3911
+ eventId: r.id,
3912
+ updateId: n,
3913
+ completedEventId: l.id,
3914
+ result: l.payload?.result
3915
+ };
3916
+ let u = c.find((e) => e.eventType === "update-failed" && e.payload?.updateId === n);
3917
+ if (u) {
3918
+ let t = Error(u.payload?.errorMessage ?? `workflow update '${e.updateName}' failed`);
3919
+ throw Object.assign(t, {
3920
+ updateId: n,
3921
+ eventId: r.id,
3922
+ errorTag: u.payload?.errorTag ?? null
3923
+ }), t;
3924
+ }
3925
+ if (Date.now() - i >= a) throw Error(`Timed out waiting for workflow update '${e.updateName}' (${n})`);
3926
+ await Kr(o);
3927
+ }
3928
+ }, Qr = 864e5, $r = "voltro/suspending-signal", ei = (e, t) => `${$r}/${e}/${t}`, ti = (e) => y.make(e, { success: w.Unknown }), ni = async (e, t) => {
3929
+ if (e) try {
3930
+ await e.recordEvent(t);
3931
+ } catch {}
3932
+ }, ri = (e, n) => S.gen(function* () {
3933
+ let e = n.timeoutMs ?? Qr, i = ti(ei((yield* b.WorkflowInstance).workflow.name, n.name)), a = yield* t, o = yield* S.serviceOption(r), s = o._tag === "Some" ? o.value : void 0;
3934
+ a !== void 0 && (yield* S.promise(() => ni(s, {
3935
+ runId: a,
3936
+ eventType: "signal-awaited",
3937
+ payload: { signalName: n.name }
3938
+ })));
3939
+ let c = y.await(i), l = Number.isFinite(e) ? yield* S.race(c, v.sleep({
3940
+ name: `await-signal-timeout/${n.name}`,
3941
+ duration: `${e} millis`
3942
+ }).pipe(S.andThen(S.die(/* @__PURE__ */ Error(`awaitSignalSuspending('${n.name}') timed out after ${e}ms`))))) : yield* c, u = yield* w.decodeUnknown(n.schema)(l);
3943
+ return a !== void 0 && (yield* S.promise(() => ni(s, {
3944
+ runId: a,
3945
+ eventType: "signal-received",
3946
+ payload: {
3947
+ signalName: n.name,
3948
+ value: u
3949
+ }
3950
+ }))), u;
3951
+ }), ii = (e) => S.gen(function* () {
3952
+ let t = e.target.executionId, n = e.target.workflowName;
3953
+ if (t === void 0 || n === void 0) {
3954
+ let r = e.store;
3955
+ if (r === void 0) return yield* S.die(/* @__PURE__ */ Error("completeSuspendingSignal: provide a store, or target.executionId AND target.workflowName"));
3956
+ let i = yield* S.tryPromise({
3957
+ try: () => Yr(r, e.target),
3958
+ catch: (e) => e
3959
+ });
3960
+ t ??= i.executionId, n ??= i.tag;
3961
+ }
3962
+ if (t === void 0 || n === void 0) return { completed: !1 };
3963
+ let r = ei(n, e.signalName), i = ti(r), a = new y.TokenParsed({
3964
+ workflowName: n,
3965
+ executionId: t,
3966
+ deferredName: r
3967
+ }).asToken;
3968
+ return yield* y.done(i, {
3969
+ token: a,
3970
+ exit: te.succeed(e.payload)
3971
+ }), { completed: !0 };
3972
+ }), Z = "_voltro_budget_holds", ai = "budget-hold", oi = (e) => `${ai}:${e}`, si = (e) => `${e.executionId}/${e.stepName}/${e.budget}#${e.generation}`, ci = async (e, t) => (await e.query({
3973
+ table: Z,
3974
+ predicate: T(O("executionId", t.executionId), O("stepName", t.stepName), O("budget", t.budget)),
3975
+ order: []
3976
+ })).length, li = P(Z, {
3977
+ id: A({ prefix: "bhd" }),
3978
+ holdKey: F().maxLength(191),
3979
+ budget: F(),
3980
+ tenantId: F().nullable(),
3981
+ executionId: F(),
3982
+ workflowName: F(),
3983
+ signalName: F(),
3984
+ stepName: F(),
3985
+ spentMicroUsd: F().nullable(),
3986
+ limitMicroUsd: F().nullable(),
3987
+ heldAt: I().default("now"),
3988
+ releasedAt: I().nullable(),
3989
+ outcome: F().nullable()
3990
+ }).index(["budget", "releasedAt"]), ui = () => {
3991
+ ge({
3992
+ source: "framework",
3993
+ table: Z,
3994
+ timeColumn: "releasedAt",
3995
+ ttlMs: _e(process.env.VOLTRO_BUDGET_HOLDS_TTL_HOURS, 720)
3996
+ });
3997
+ }, di = class extends Error {
3998
+ budget;
3999
+ holdKey;
4000
+ constructor(e, t, n) {
4001
+ super(`budget '${e}': the run was suspended waiting for headroom and gave up after ${n}ms (hold ${t}). Nothing was spent. Raise the budget, reset its window, or lift the hold, then re-drive the run.`), this.name = "BudgetHoldExpired", this.budget = e, this.holdKey = t;
4002
+ }
4003
+ }, fi = 6048e5, pi = (e) => S.gen(function* () {
4004
+ ui();
4005
+ let t = e.timeoutMs ?? 6048e5, n = e.recheckEveryMs ?? 9e5, r = {
4006
+ executionId: e.executionId,
4007
+ stepName: e.stepName,
4008
+ budget: e.budget
4009
+ };
4010
+ for (;;) {
4011
+ let i = yield* S.promise(() => hi(e.store, r)), a = i.length, o = i.length === 0 ? Date.now() : mi(i[0]?.heldAt), s = Number.isFinite(t) ? t - (Date.now() - o) : Infinity, c = si({
4012
+ ...r,
4013
+ generation: a
4014
+ });
4015
+ if (s <= 0) return yield* S.promise(() => gi(e.store, r, "expired")), yield* S.fail(new di(e.budget, c, t));
4016
+ let l = oi(c);
4017
+ yield* S.promise(() => e.store.insertIgnore(Z, {
4018
+ id: ce({
4019
+ kind: "typeid",
4020
+ prefix: "bhd"
4021
+ }, Z),
4022
+ holdKey: c,
4023
+ budget: e.budget,
4024
+ tenantId: e.tenantId,
4025
+ executionId: e.executionId,
4026
+ workflowName: e.workflowName,
4027
+ signalName: l,
4028
+ stepName: e.stepName,
4029
+ spentMicroUsd: e.spentMicroUsd === void 0 ? null : String(Math.round(e.spentMicroUsd)),
4030
+ limitMicroUsd: e.limitMicroUsd === void 0 ? null : String(Math.round(e.limitMicroUsd)),
4031
+ heldAt: /* @__PURE__ */ new Date(),
4032
+ releasedAt: null,
4033
+ outcome: null
4034
+ }, { conflictColumns: ["holdKey"] }));
4035
+ let u = Math.min(n, s);
4036
+ if (yield* ri({ store: e.store }, {
4037
+ name: l,
4038
+ schema: w.Unknown,
4039
+ timeoutMs: u
4040
+ }).pipe(S.catchAllCause((e) => x.isInterruptedOnly(e) ? S.failCause(e) : S.void)), yield* S.promise(() => e.store.updateMany(Z, {
4041
+ releasedAt: /* @__PURE__ */ new Date(),
4042
+ outcome: "recheck"
4043
+ }, { where: T(O("holdKey", c), M("releasedAt")) })), yield* e.hasHeadroom) return;
4044
+ }
4045
+ }), mi = (e) => e instanceof Date ? e.getTime() : typeof e == "string" ? Date.parse(e) : Date.now(), hi = async (e, t) => [...await e.query({
4046
+ table: Z,
4047
+ predicate: T(O("executionId", t.executionId), O("stepName", t.stepName), O("budget", t.budget)),
4048
+ order: []
4049
+ })].sort((e, t) => String(e.id).localeCompare(String(t.id))), gi = async (e, t, n) => {
4050
+ await e.updateMany(Z, {
4051
+ releasedAt: /* @__PURE__ */ new Date(),
4052
+ outcome: n
4053
+ }, { where: T(O("executionId", t.executionId), O("stepName", t.stepName), O("budget", t.budget), M("releasedAt")) });
4054
+ }, _i = (e) => S.gen(function* () {
4055
+ let t = e.tenantId === void 0 ? T(O("budget", e.budget), M("releasedAt")) : T(O("budget", e.budget), O("tenantId", e.tenantId), M("releasedAt")), n = yield* S.promise(() => e.store.query({
4056
+ table: Z,
4057
+ predicate: t,
4058
+ order: []
4059
+ })), r = 0;
4060
+ for (let t of n) (yield* S.promise(() => e.store.updateMany("_voltro_budget_holds", {
4061
+ releasedAt: /* @__PURE__ */ new Date(),
4062
+ outcome: e.outcome ?? "released"
4063
+ }, { where: T(O("id", String(t.id)), M("releasedAt")) }))) === 1 && (yield* ii({
4064
+ target: {
4065
+ executionId: String(t.executionId),
4066
+ workflowName: String(t.workflowName)
4067
+ },
4068
+ signalName: String(t.signalName),
4069
+ payload: {
4070
+ released: !0,
4071
+ budget: e.budget
4072
+ }
4073
+ }).pipe(S.catchAll(() => S.succeed({ completed: !1 }))), r += 1);
4074
+ return { released: r };
4075
+ }), vi = async (e, t) => {
4076
+ let n = t?.budget === void 0 ? M("releasedAt") : T(O("budget", t.budget), M("releasedAt"));
4077
+ return (await e.query({
4078
+ table: Z,
4079
+ predicate: n,
4080
+ order: []
4081
+ })).map((e) => ({
4082
+ id: String(e.id),
4083
+ holdKey: String(e.holdKey),
4084
+ budget: String(e.budget),
4085
+ tenantId: e.tenantId ?? null,
4086
+ executionId: String(e.executionId),
4087
+ workflowName: String(e.workflowName),
4088
+ stepName: String(e.stepName),
4089
+ heldAt: e.heldAt instanceof Date ? e.heldAt.toISOString() : String(e.heldAt ?? "")
4090
+ }));
4091
+ }, yi = async (e) => {
4092
+ let t = await vi(e), n = /* @__PURE__ */ new Map();
4093
+ for (let e of t) {
4094
+ let t = `${e.budget}\u0000${e.tenantId ?? ""}`;
4095
+ n.has(t) || n.set(t, {
4096
+ budget: e.budget,
4097
+ tenantId: e.tenantId
4098
+ });
4099
+ }
4100
+ return [...n.values()];
4101
+ }, bi = async (e, t) => {
4102
+ if (e) try {
4103
+ await e.recordEvent(t);
4104
+ } catch {}
4105
+ }, xi = (e) => {
4106
+ let t = x.failureOption(e), n = Array.from(x.defects(e)), r = t._tag === "Some" ? t.value : n[0] ?? x.squash(e);
4107
+ return {
4108
+ errorTag: r && typeof r == "object" && "_tag" in r ? String(r._tag) : null,
4109
+ errorMessage: r?.message ?? String(r)
4110
+ };
4111
+ }, Si = (e, n) => {
4112
+ let i = S.gen(function* () {
4113
+ let i = n.pollIntervalMs ?? 200, a = n.maxPollIntervalMs ?? 5e3, o = n.timeoutMs ?? 3e4, s = yield* t, c = yield* S.serviceOption(r), l = c._tag === "Some" ? c.value : void 0;
4114
+ if (s === void 0) return yield* S.die(/* @__PURE__ */ Error("awaitUpdate: no active workflow run id in scope"));
4115
+ let u = s, d = Date.now(), f = i;
4116
+ for (;;) {
4117
+ let t = Date.now() - d;
4118
+ if (t > o) return yield* S.die(/* @__PURE__ */ Error(`awaitUpdate('${n.name}') timed out after ${t}ms`));
4119
+ let r = {
4120
+ table: "_voltro_workflow_run_events",
4121
+ order: [{
4122
+ column: "occurredAt",
4123
+ direction: "asc"
4124
+ }],
4125
+ predicate: O("runId", u),
4126
+ projection: void 0,
4127
+ skip: void 0,
4128
+ take: 1e3
4129
+ }, i = yield* S.tryPromise({
4130
+ try: () => e.store.query(r),
4131
+ catch: (e) => e
4132
+ }), s = new Set(i.filter((e) => e.eventType === "update-completed" || e.eventType === "update-failed").map((e) => e.payload?.updateId).filter((e) => typeof e == "string" && e.length > 0)), c = i.find((e) => e.eventType === "update-requested" && e.payload?.updateName === n.name && typeof e.payload.updateId == "string" && !s.has(e.payload.updateId));
4133
+ if (c !== void 0) {
4134
+ let e = c.payload.updateId;
4135
+ yield* S.promise(() => bi(l, {
4136
+ runId: u,
4137
+ eventType: "update-received",
4138
+ payload: {
4139
+ updateId: e,
4140
+ updateName: n.name
4141
+ }
4142
+ }));
4143
+ let t = yield* w.decodeUnknown(n.schema)(c.payload?.value).pipe(S.tapErrorCause((t) => S.promise(() => bi(l, {
4144
+ runId: u,
4145
+ eventType: "update-failed",
4146
+ payload: {
4147
+ updateId: e,
4148
+ updateName: n.name,
4149
+ ...xi(t)
4150
+ }
4151
+ })))), r = yield* (n.handle ? n.handle(t) : S.succeed(t)).pipe(S.flatMap((e) => n.success ? w.decodeUnknown(n.success)(e) : S.succeed(e))).pipe(S.tapErrorCause((t) => S.promise(() => bi(l, {
4152
+ runId: u,
4153
+ eventType: "update-failed",
4154
+ payload: {
4155
+ updateId: e,
4156
+ updateName: n.name,
4157
+ ...xi(t)
4158
+ }
4159
+ }))));
4160
+ return yield* S.promise(() => bi(l, {
4161
+ runId: u,
4162
+ eventType: "update-completed",
4163
+ payload: {
4164
+ updateId: e,
4165
+ updateName: n.name,
4166
+ result: r
4167
+ }
4168
+ })), r;
4169
+ }
4170
+ yield* S.sleep(`${f} millis`), f = Math.min(f * 2, a);
4171
+ }
4172
+ });
4173
+ return _.make({
4174
+ name: `await-update:${n.name}`,
4175
+ success: n.success ?? n.schema,
4176
+ execute: i
4177
+ });
4178
+ }, Ci = (e) => {
4179
+ if (e == null) return null;
4180
+ if (e instanceof Date) return e;
4181
+ if (typeof e == "string" || typeof e == "number") {
4182
+ let t = new Date(e);
4183
+ return Number.isNaN(t.getTime()) ? null : t;
4184
+ }
4185
+ return null;
4186
+ }, wi = (e) => typeof e == "number" ? e : e == null ? null : Number(e), Q = (e) => e == null ? null : String(e), Ti = (e) => {
4187
+ let t = /* @__PURE__ */ new Map();
4188
+ for (let n of e) {
4189
+ let e = String(n.stepName), r = t.get(e);
4190
+ r === void 0 ? t.set(e, [n]) : r.push(n);
4191
+ }
4192
+ let n = [];
4193
+ for (let [e, r] of t) {
4194
+ r.sort((e, t) => (wi(e.attempt) ?? 0) - (wi(t.attempt) ?? 0));
4195
+ let t = r[r.length - 1], i = Q(t.errorTag), a = Q(t.errorMessage), o = i !== null || a !== null ? {
4196
+ tag: i,
4197
+ message: a ?? ""
4198
+ } : null;
4199
+ n.push({
4200
+ name: e,
4201
+ attempt: wi(t.attempt) ?? r.length,
4202
+ attempts: r.length,
4203
+ status: t.status ?? "running",
4204
+ input: t.input ?? null,
4205
+ output: t.output ?? null,
4206
+ error: o,
4207
+ durationMs: wi(t.durationMs)
4208
+ });
4209
+ }
4210
+ return n.sort((t, n) => {
4211
+ let r = e.find((e) => String(e.stepName) === t.name), i = e.find((e) => String(e.stepName) === n.name);
4212
+ return (Ci(r?.startedAt)?.getTime() ?? 0) - (Ci(i?.startedAt)?.getTime() ?? 0);
4213
+ }), n;
4214
+ }, Ei = (e) => {
4215
+ if (e == null) return null;
4216
+ if (typeof e == "string") try {
4217
+ return JSON.parse(e);
4218
+ } catch {
4219
+ return null;
4220
+ }
4221
+ return typeof e == "object" ? e : null;
4222
+ }, Di = async (e, t) => {
4223
+ let n = me(xe), r = (await t.query(n.where(pe(O("id", e), O("executionId", e))).limit(1).descriptor))[0];
4224
+ if (r === void 0) return null;
4225
+ let i = String(r.id), a = me(Se), o = await t.query(a.where(O("runId", i)).descriptor);
4226
+ return {
4227
+ id: i,
4228
+ executionId: Q(r.executionId) ?? "",
4229
+ name: Q(r.tag) ?? "",
4230
+ status: r.status ?? "running",
4231
+ input: r.payload ?? null,
4232
+ output: r.output ?? null,
4233
+ subject: Ei(r.subject),
4234
+ source: Q(r.source),
4235
+ steps: Ti(o),
4236
+ startedAt: Ci(r.startedAt) ?? /* @__PURE__ */ new Date(0),
4237
+ finishedAt: Ci(r.completedAt),
4238
+ traceId: Q(r.traceId),
4239
+ parentExecutionId: Q(r.parentExecutionId),
4240
+ parentClosePolicy: Q(r.parentClosePolicy)
4241
+ };
4242
+ }, Oi = () => {
4243
+ let e = [], t = [], n = 0, i = 0;
4244
+ return {
4245
+ layer: ie.succeed(r, {
4246
+ startStep: async ({ runId: t, stepName: r, attempt: i, stepInput: a, retryPolicy: o }) => {
4247
+ let s = `wfstep_mem_${++n}`;
4248
+ return e.push({
4249
+ id: s,
4250
+ runId: t,
4251
+ stepName: r,
4252
+ attempt: i,
4253
+ status: "running",
4254
+ input: a ?? null,
4255
+ retryPolicy: o ?? null,
4256
+ output: null,
4257
+ errorTag: null,
4258
+ errorMessage: null,
4259
+ errorCause: null,
4260
+ startedAt: /* @__PURE__ */ new Date(),
4261
+ completedAt: null,
4262
+ durationMs: null
4263
+ }), s;
4264
+ },
4265
+ endStepSuccess: async ({ stepRecordId: t, output: n, durationMs: r }) => {
4266
+ let i = e.find((e) => e.id === t);
4267
+ i !== void 0 && (i.status = "succeeded", i.output = n, i.completedAt = /* @__PURE__ */ new Date(), i.durationMs = r);
4268
+ },
4269
+ endStepFailure: async ({ stepRecordId: t, errorTag: n, errorMessage: r, errorCause: i, durationMs: a }) => {
4270
+ let o = e.find((e) => e.id === t);
4271
+ o !== void 0 && (o.status = "failed", o.errorTag = n, o.errorMessage = r, o.errorCause = i ?? null, o.completedAt = /* @__PURE__ */ new Date(), o.durationMs = a);
4272
+ },
4273
+ recordEvent: async ({ runId: e, eventType: n, payload: r, stepName: a, attempt: o }) => {
4274
+ let s = `wfev_mem_${++i}`;
4275
+ return t.push({
4276
+ id: s,
4277
+ runId: e,
4278
+ eventType: n,
4279
+ payload: r ?? null,
4280
+ stepName: a ?? null,
4281
+ attempt: o ?? null,
4282
+ occurredAt: /* @__PURE__ */ new Date()
4283
+ }), { id: s };
4284
+ }
4285
+ }),
4286
+ readSteps: () => e,
4287
+ readEvents: () => t
4288
+ };
4289
+ }, ki = (e, t, n) => S.gen(function* () {
4290
+ let r = yield* ye;
4291
+ for (;;) {
4292
+ if (yield* S.tryPromise(() => u(t, e)).pipe(S.catchAll(() => S.sync(() => (n(), !1))))) return r.interrupted = !0, yield* S.interrupt;
4293
+ yield* S.sleep(1e3);
4294
+ }
4295
+ }), Ai = 8192, ji = 3, Mi = 2e3, Ni = () => {
4296
+ let e = (e) => {
4297
+ if (e === void 0) return;
4298
+ let t = Number(e);
4299
+ return Number.isFinite(t) && t > 0 ? Math.floor(t) : void 0;
4300
+ }, t = e(process.env.VOLTRO_WORKFLOW_MAX_RECLAIMS), n = e(process.env.VOLTRO_WORKFLOW_REPLAY_SHAPE_LIMIT);
4301
+ return {
4302
+ ...t === void 0 ? {} : { maxRunReclaims: t },
4303
+ ...n === void 0 ? {} : { replayShapeLimit: n }
4304
+ };
4305
+ }, Pi = (e) => {
4306
+ let t = typeof e == "string" ? (() => {
4307
+ try {
4308
+ return JSON.parse(e);
4309
+ } catch {
4310
+ return;
4311
+ }
4312
+ })() : e;
4313
+ if (Array.isArray(t)) return t.filter((e) => typeof e == "string");
4314
+ }, Fi = () => {
4315
+ let e = globalThis.crypto;
4316
+ return typeof e?.randomUUID == "function" ? e.randomUUID() : `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
4317
+ }, Ii = (e) => `${e}_${Fi()}`, Li = (e, t = Ai) => {
4318
+ if (e == null) return e;
4319
+ try {
4320
+ let n = JSON.stringify(e);
4321
+ return n.length <= t ? e : {
4322
+ __truncated: !0,
4323
+ bytes: n.length,
4324
+ sample: n.slice(0, t)
4325
+ };
4326
+ } catch {
4327
+ return { __unserialisable: String(e) };
4328
+ }
4329
+ }, $ = (e) => {
4330
+ let t = {};
4331
+ for (let [n, r] of Object.entries(e)) t[n] = r instanceof Date ? r.toISOString() : r;
4332
+ return t;
4333
+ }, Ri = (e) => {
4334
+ let t = e.truncateBytes ?? Ai, n = e.makeId ?? Ii, r = (t, n) => e.log?.warn(t, n), i = e.encryptStepPayload ?? ((e) => e), a = e.emit, o = e.recording === "coarse";
4335
+ return {
4336
+ startStep: async ({ runId: s, stepName: c, attempt: l, stepInput: u, retryPolicy: d }) => {
4337
+ if (!o) try {
4338
+ let r = await e.store.insert("_voltro_workflow_run_steps", {
4339
+ id: n("ws"),
4340
+ runId: s,
4341
+ stepName: c,
4342
+ attempt: l,
4343
+ status: "running",
4344
+ input: u === void 0 ? null : i(Li(u, t)),
4345
+ retryPolicy: d ?? null,
4346
+ output: null,
4347
+ errorTag: null,
4348
+ errorMessage: null,
4349
+ startedAt: /* @__PURE__ */ new Date(),
4350
+ completedAt: null,
4351
+ durationMs: null
4352
+ });
4353
+ return a?.("workflowSteps", {
4354
+ op: "insert",
4355
+ row: $(r)
4356
+ }), r.id;
4357
+ } catch (e) {
4358
+ r("failed to record step start (continuing)", {
4359
+ runId: s,
4360
+ stepName: c,
4361
+ attempt: l,
4362
+ reason: e?.message ?? String(e)
4363
+ });
4364
+ return;
4365
+ }
4366
+ },
4367
+ endStepSuccess: async ({ stepRecordId: n, output: s, durationMs: c }) => {
4368
+ if (!o) try {
4369
+ let r = await e.store.update("_voltro_workflow_run_steps", n, {
4370
+ status: "succeeded",
4371
+ output: i(Li(s, t)),
4372
+ completedAt: /* @__PURE__ */ new Date(),
4373
+ durationMs: c
4374
+ });
4375
+ r && a?.("workflowSteps", {
4376
+ op: "update",
4377
+ row: $(r)
4378
+ });
4379
+ } catch (e) {
4380
+ r("failed to record step success", {
4381
+ stepRecordId: n,
4382
+ reason: e?.message ?? String(e)
4383
+ });
4384
+ }
4385
+ },
4386
+ endStepFailure: async ({ stepRecordId: n, errorTag: s, errorMessage: c, errorCause: l, durationMs: u }) => {
4387
+ if (!o) try {
4388
+ let r = await e.store.update("_voltro_workflow_run_steps", n, {
4389
+ status: "failed",
4390
+ errorTag: s,
4391
+ errorMessage: c,
4392
+ errorCause: l === void 0 ? null : i(Li(l, t)),
4393
+ completedAt: /* @__PURE__ */ new Date(),
4394
+ durationMs: u
4395
+ });
4396
+ r && a?.("workflowSteps", {
4397
+ op: "update",
4398
+ row: $(r)
4399
+ });
4400
+ } catch (e) {
4401
+ r("failed to record step failure", {
4402
+ stepRecordId: n,
4403
+ reason: e?.message ?? String(e)
4404
+ });
4405
+ }
4406
+ },
4407
+ recordEvent: async ({ runId: t, eventType: i, payload: o, stepName: s, attempt: c }) => {
4408
+ let l = n("wfev");
4409
+ try {
4410
+ let n = await e.store.insert("_voltro_workflow_run_events", {
4411
+ id: l,
4412
+ runId: t,
4413
+ eventType: i,
4414
+ payload: o ?? null,
4415
+ occurredAt: /* @__PURE__ */ new Date(),
4416
+ stepName: s ?? null,
4417
+ attempt: c ?? null
4418
+ });
4419
+ a?.("workflowEvents", {
4420
+ op: "insert",
4421
+ row: $(n)
4422
+ });
4423
+ } catch (e) {
4424
+ r("failed to record workflow event (continuing)", {
4425
+ runId: t,
4426
+ eventType: i,
4427
+ reason: e?.message ?? String(e)
4428
+ });
4429
+ }
4430
+ if (e.wakeups !== void 0) {
4431
+ let n = o?.scheduledWakeAt, r = typeof n == "string" ? new Date(n) : void 0, a = o?.tenantId, s = typeof a == "string" ? a : void 0;
4432
+ i === "timer-set" && r !== void 0 && !Number.isNaN(r.getTime()) ? await e.wakeups.register(t, r, s).catch(() => {}) : (i === "timer-fired" || i === "run-succeeded" || i === "run-failed" || i === "run-cancelled") && await e.wakeups.cancel(t, s).catch(() => {});
4433
+ }
4434
+ return { id: l };
4435
+ }
4436
+ };
4437
+ }, zi = (e, t, n) => S.gen(function* () {
4438
+ let r = e.store.query;
4439
+ if (r === void 0) return;
4440
+ let i = e.replayShapeLimit ?? 2e3, a = yield* S.promise(() => r.call(e.store, {
4441
+ table: "_voltro_workflow_run_steps",
4442
+ order: [{
4443
+ column: "startedAt",
4444
+ direction: "asc"
4445
+ }],
4446
+ predicate: O("runId", t),
4447
+ projection: ["stepName"],
4448
+ skip: void 0,
4449
+ take: i + 1
4450
+ }).catch((e) => (n("failed to read the replay shape (nondeterminism tripwire disabled for this attempt)", {
4451
+ runId: t,
4452
+ reason: e?.message ?? String(e)
4453
+ }), [])));
4454
+ if (a.length === 0) return;
4455
+ if (a.length > i) {
4456
+ n("replay shape exceeds the step limit — nondeterminism tripwire disabled for this run", {
4457
+ runId: t,
4458
+ limit: i
4459
+ });
4460
+ return;
4461
+ }
4462
+ let o = a.flatMap((e) => {
4463
+ let t = e.stepName;
4464
+ return typeof t == "string" ? [{ stepName: t }] : [];
4465
+ });
4466
+ return o.length === 0 ? void 0 : s(o);
4467
+ }), Bi = (s, l) => {
4468
+ let u = s.truncateBytes ?? Ai, d = s.makeId ?? Ii, p = s.recorder ?? Ri(s), m = (e, t) => s.log?.warn(e, t), h = s.emit, g = (e) => S.gen(function* () {
4469
+ yield* S.sync(() => h?.("workflowEvents", {
4470
+ op: "insert",
4471
+ row: $(e)
4472
+ }));
4473
+ let t = s.wakeups, n = e.runId;
4474
+ if (t !== void 0 && typeof n == "string") {
4475
+ let e = s.subject?.tenantId;
4476
+ yield* S.promise(() => t.cancel(n, typeof e == "string" ? e : void 0).catch(() => {
4477
+ m("failed to clear terminal workflow wakeup", { runId: n });
4478
+ }));
4479
+ }
4480
+ }), _ = (e, t, n) => S.promise(async () => {
4481
+ if (s.onParentClose) try {
4482
+ await s.onParentClose({
4483
+ workflowName: s.name,
4484
+ executionId: e,
4485
+ ...n === void 0 ? {} : { runId: n },
4486
+ status: t
4487
+ });
4488
+ } catch (n) {
4489
+ m("failed to apply workflow parent-close policy", {
4490
+ tag: s.name,
4491
+ executionId: e,
4492
+ status: t,
4493
+ reason: n?.message ?? String(n)
4494
+ });
4495
+ }
4496
+ }), v = (e, t, n, r) => S.promise(async () => {
4497
+ if (s.onTerminal) try {
4498
+ await s.onTerminal({
4499
+ workflowName: s.name,
4500
+ executionId: e,
4501
+ ...n === void 0 ? {} : { runId: n },
4502
+ status: t,
4503
+ ...r === void 0 ? {} : r
4504
+ });
4505
+ } catch (n) {
4506
+ m("workflow terminal observer failed", {
4507
+ tag: s.name,
4508
+ executionId: e,
4509
+ status: t,
4510
+ reason: n?.message ?? String(n)
4511
+ });
4512
+ }
4513
+ });
4514
+ return (y, b) => S.gen(function* () {
4515
+ let C = Date.now(), ie = yield* re.get(i), w = yield* re.get(a), ae = s.parentExecutionId ?? ie ?? null, oe = s.parentGeneration ?? (s.parentExecutionId == null ? w : void 0) ?? null, T = s.parentClosePolicy ?? null, E, D = (e, t) => t.pipe(S.catchAllCause((t) => x.isInterrupted(t) ? S.failCause(t) : S.sync(() => {
4516
+ let n = x.squash(t);
4517
+ m(e, {
4518
+ tag: s.name,
4519
+ executionId: b,
4520
+ reason: n?.message ?? String(n)
4521
+ });
4522
+ }))), O = `wfrg_${Fi()}`, ce = yield* S.serviceOption(f), k = d("wr"), le = yield* S.sync(() => s.encodePayload === void 0 ? y : s.encodePayload(y)), A = yield* S.promise(() => s.transaction((e) => pn(e, {
4523
+ workflowName: s.name,
4524
+ executionId: b,
4525
+ generation: O,
4526
+ now: C,
4527
+ delivery: ce._tag === "Some" ? ce.value : null,
4528
+ initialRow: {
4529
+ id: k,
4530
+ payload: le,
4531
+ workflowVersion: s.workflowVersion ?? null,
4532
+ workflowPatches: s.workflowPatches ?? null,
4533
+ output: null,
4534
+ subject: s.subject ?? null,
4535
+ source: s.source ?? null,
4536
+ errorTag: null,
4537
+ errorMessage: null,
4538
+ cancelled: !1,
4539
+ startedAt: new Date(C),
4540
+ completedAt: null,
4541
+ durationMs: null,
4542
+ traceId: s.traceId ?? null,
4543
+ parentExecutionId: ae,
4544
+ parentGeneration: oe,
4545
+ parentClosePolicy: T
4546
+ }
4547
+ })));
4548
+ if (typeof A.row.id != "string") return yield* S.die(/* @__PURE__ */ Error("Recorded workflow entry has no run identity"));
4549
+ if (E = A.row.id, A.kind === "cancelled" || A.kind === "already-cancelled") {
4550
+ let e = yield* ye;
4551
+ return e.interrupted = !0, A.kind === "cancelled" && (yield* D("failed to observe suspended workflow cancellation", S.gen(function* () {
4552
+ if (h?.("workflowRuns", {
4553
+ op: "update",
4554
+ row: $(A.row)
4555
+ }), A.terminalEvent === void 0) return yield* S.die(/* @__PURE__ */ Error("Cancelled entry has no terminal event"));
4556
+ yield* g(A.terminalEvent), yield* _(b, "cancelled", E);
4557
+ })), yield* v(b, "cancelled", E), yield* S.sync(() => s.recordRun?.({
4558
+ name: s.name,
4559
+ status: "cancelled",
4560
+ durationMs: 0
4561
+ }))), yield* S.interrupt;
4562
+ }
4563
+ let ue = A.previous, j = ue?.workflowVersion ?? null;
4564
+ if (ue?.id !== void 0 && j !== null && s.workflowCompatibleVersions !== void 0 && s.workflowCompatibleVersions !== null && !s.workflowCompatibleVersions.includes(j)) {
4565
+ let e = `Workflow '${s.name}' run '${b}' was started on version ${j}, but current code is compatible with ${s.workflowCompatibleVersions.join(", ")}`, t = s.failureContext ?? {
4566
+ handler: null,
4567
+ callerContext: null,
4568
+ tenantId: null
4569
+ }, n = yield* S.promise(() => s.transaction((n) => vn(n, {
4570
+ owner: {
4571
+ runId: E,
4572
+ workflowName: s.name,
4573
+ executionId: b,
4574
+ generation: O
4575
+ },
4576
+ now: Date.now(),
4577
+ durationMs: 0,
4578
+ outcome: {
4579
+ status: "failed",
4580
+ errorTag: "WorkflowVersionIncompatible",
4581
+ errorMessage: e,
4582
+ ...t
4583
+ }
4584
+ })));
4585
+ return n.kind === "committed" && (yield* D("failed to observe workflow version rejection", S.gen(function* () {
4586
+ h?.("workflowRuns", {
4587
+ op: "update",
4588
+ row: $(n.row)
4589
+ }), yield* g(n.terminalEvent), yield* _(b, "failed", E);
4590
+ })), yield* v(b, "failed", E, {
4591
+ payload: A.row.payload,
4592
+ errorTag: "WorkflowVersionIncompatible",
4593
+ errorMessage: e
4594
+ }), yield* S.sync(() => s.recordRun?.({
4595
+ name: s.name,
4596
+ status: "failed",
4597
+ durationMs: 0
4598
+ }))), yield* S.fail(Error(e));
4599
+ }
4600
+ let de = s.workflowPatches ?? [], M;
4601
+ if (ue?.id !== void 0) {
4602
+ E = ue.id, de = Pi(ue.workflowPatches) ?? de;
4603
+ let e = A.row.reclaimCount;
4604
+ if (typeof e != "number" || !Number.isSafeInteger(e) || e < 0) return yield* S.die(/* @__PURE__ */ Error("Recorded workflow entry has an invalid reclaim counter"));
4605
+ let t = e > 0, n = s.maxRunReclaims ?? 3;
4606
+ if (t && e >= n) {
4607
+ let t = `Workflow '${s.name}' run '${b}' killed its runner ${e} times in a row; parked instead of reclaimed again (maxRunReclaims=${n}).`, r = yield* S.promise(() => s.transaction((e) => gn(e, {
4608
+ runId: E,
4609
+ workflowName: s.name,
4610
+ executionId: b,
4611
+ generation: O
4612
+ }, {
4613
+ errorTag: "WorkflowCrashLooped",
4614
+ errorMessage: t
4615
+ })));
4616
+ r.kind === "committed" && (yield* D("failed to observe workflow crash-loop park", S.gen(function* () {
4617
+ h?.("workflowRuns", {
4618
+ op: "update",
4619
+ row: $(r.row)
4620
+ }), yield* S.promise(() => p.recordEvent({
4621
+ runId: E,
4622
+ eventType: "run-crashlooped",
4623
+ payload: {
4624
+ reclaimCount: e,
4625
+ maxRunReclaims: n,
4626
+ executionId: b,
4627
+ tag: s.name
4628
+ }
4629
+ }));
4630
+ })), m("workflow run parked after repeated runner deaths", {
4631
+ tag: s.name,
4632
+ executionId: b,
4633
+ runId: E,
4634
+ reclaimCount: e,
4635
+ maxRunReclaims: n
4636
+ }));
4637
+ let i = yield* ye;
4638
+ return yield* ee.suspend(i);
4639
+ }
4640
+ M = yield* zi(s, E, m), yield* D("failed to record workflow re-entry", S.gen(function* () {
4641
+ h?.("workflowRuns", {
4642
+ op: "update",
4643
+ row: $(A.row)
4644
+ }), t && (yield* S.promise(() => p.recordEvent({
4645
+ runId: E,
4646
+ eventType: "run-resumed",
4647
+ payload: {
4648
+ reason: "runner-reclaim",
4649
+ reclaimCount: e,
4650
+ maxRunReclaims: n
4651
+ }
4652
+ })));
4653
+ }));
4654
+ } else yield* D("failed to emit recorded workflow start", S.gen(function* () {
4655
+ if (h?.("workflowRuns", {
4656
+ op: "insert",
4657
+ row: $(A.row)
4658
+ }), E) {
4659
+ let e = E;
4660
+ yield* S.promise(() => p.recordEvent({
4661
+ runId: e,
4662
+ eventType: "run-started",
4663
+ payload: {
4664
+ tag: s.name,
4665
+ executionId: b,
4666
+ source: s.source ?? null,
4667
+ workflowVersion: s.workflowVersion ?? null,
4668
+ workflowPatches: s.workflowPatches ?? null,
4669
+ parentExecutionId: ae,
4670
+ parentClosePolicy: T
4671
+ }
4672
+ }));
4673
+ }
4674
+ }));
4675
+ let N = s.subject?.tenantId, fe = S.suspend(() => l(y, b, O)).pipe(S.locally(t, E), S.locally(i, b), S.locally(a, O), S.locally(n, typeof N == "string" ? N : void 0), S.locally(o, de), S.locally(c, M), S.provideService(r, p)), pe = s.pluginWorkflowStepLayer ? fe.pipe(S.provide(s.pluginWorkflowStepLayer)) : fe, me = yield* ee.intoResult(S.raceWith(pe, ki({
4676
+ runId: E,
4677
+ workflowName: s.name,
4678
+ executionId: b,
4679
+ generation: O
4680
+ }, async (e) => s.store.query(e), () => m("workflow control read failed; retrying without claiming cancellation", {
4681
+ executionId: b,
4682
+ runId: E
4683
+ })).pipe(S.interruptible), {
4684
+ onSelfDone: (e, t) => ne.interrupt(t).pipe(S.zipRight(e)),
4685
+ onOtherDone: (e, t) => ne.interrupt(t).pipe(S.zipRight(e))
4686
+ }));
4687
+ if (ee.isResult(me) && me._tag === "Suspended") {
4688
+ let e = me.cause, t = e !== void 0 && !x.isEmpty(e), n = t ? x.squash(e) : void 0, r = n && typeof n == "object" && "_tag" in n ? String(n._tag) : null, i = t ? n?.message ?? String(n) : null, a = yield* S.promise(() => s.transaction((e) => gn(e, {
4689
+ runId: E,
4690
+ workflowName: s.name,
4691
+ executionId: b,
4692
+ generation: O
4693
+ }, {
4694
+ errorTag: r,
4695
+ errorMessage: i
4696
+ })));
4697
+ a.kind === "committed" && t && (yield* S.sync(() => se({
4698
+ error: n,
4699
+ source: "workflow",
4700
+ name: s.name,
4701
+ ...s.traceId ? { traceId: s.traceId } : {},
4702
+ fields: {
4703
+ executionId: b,
4704
+ suspendedOnFailure: !0,
4705
+ ...r ? { errorTag: r } : {},
4706
+ ...E ? { runId: E } : {}
4707
+ }
4708
+ }))), a.kind === "committed" && (yield* D("failed to observe workflow suspend", S.gen(function* () {
4709
+ h?.("workflowRuns", {
4710
+ op: "update",
4711
+ row: $(a.row)
4712
+ }), yield* S.promise(() => p.recordEvent({
4713
+ runId: E,
4714
+ eventType: "run-suspended",
4715
+ payload: t ? {
4716
+ reason: "suspend-on-failure",
4717
+ errorTag: r,
4718
+ errorMessage: i
4719
+ } : { reason: "workflow-suspend" }
4720
+ }));
4721
+ })));
4722
+ let o = yield* ye;
4723
+ return yield* ee.suspend(o);
4724
+ }
4725
+ let he = me;
4726
+ if (M !== void 0 && E !== void 0) {
4727
+ let t = M.settle();
4728
+ if (t.length > 0) {
4729
+ let n = E;
4730
+ m("workflow replay reached a different step shape than this run recorded", {
4731
+ tag: s.name,
4732
+ executionId: b,
4733
+ runId: n,
4734
+ findings: t.map((e) => `${e.kind}:${e.stepName}`)
4735
+ }), yield* D("failed to record nondeterminism findings", S.promise(async () => {
4736
+ for (let r of t) await p.recordEvent({
4737
+ runId: n,
4738
+ eventType: "nondeterminism-suspected",
4739
+ payload: e(r)
4740
+ }).catch(() => void 0);
4741
+ }));
4742
+ }
4743
+ }
4744
+ if (te.isFailure(he.exit)) {
4745
+ let e = he.exit.cause;
4746
+ if ((yield* ye).interrupted && x.isInterruptedOnly(e)) {
4747
+ let t = Date.now(), n = yield* S.promise(() => s.transaction((e) => vn(e, {
4748
+ owner: {
4749
+ runId: E,
4750
+ workflowName: s.name,
4751
+ executionId: b,
4752
+ generation: O
4753
+ },
4754
+ now: t,
4755
+ durationMs: t - C,
4756
+ outcome: { status: "cancelled" }
4757
+ })));
4758
+ return n.kind === "committed" && (yield* D("failed to observe workflow cancellation", S.gen(function* () {
4759
+ h?.("workflowRuns", {
4760
+ op: "update",
4761
+ row: $(n.row)
4762
+ }), yield* g(n.terminalEvent), yield* _(b, "cancelled", E);
4763
+ })), yield* v(b, "cancelled", E), yield* S.sync(() => s.recordRun?.({
4764
+ name: s.name,
4765
+ status: "cancelled",
4766
+ durationMs: t - C
4767
+ }))), yield* S.failCause(e);
4768
+ }
4769
+ let t = x.failureOption(e), n = t._tag === "Some" ? t.value : x.squash(e), r = n && typeof n == "object" && "_tag" in n ? String(n._tag) : null, i = n?.message ?? String(n), a = Date.now(), o = s.failureContext ?? {
4770
+ handler: null,
4771
+ callerContext: null,
4772
+ tenantId: null
4773
+ }, c = yield* S.promise(() => s.transaction((e) => vn(e, {
4774
+ owner: {
4775
+ runId: E,
4776
+ workflowName: s.name,
4777
+ executionId: b,
4778
+ generation: O
4779
+ },
4780
+ now: a,
4781
+ durationMs: a - C,
4782
+ outcome: {
4783
+ status: "failed",
4784
+ errorTag: r,
4785
+ errorMessage: i,
4786
+ ...o
4787
+ }
4788
+ })));
4789
+ return c.kind === "committed" ? (yield* S.sync(() => se({
4790
+ error: n,
4791
+ source: "workflow",
4792
+ name: s.name,
4793
+ ...s.traceId ? { traceId: s.traceId } : {},
4794
+ fields: {
4795
+ executionId: b,
4796
+ ...r ? { errorTag: r } : {},
4797
+ ...E ? { runId: E } : {}
4798
+ }
4799
+ })), E && (yield* D("failed to record workflow failure", S.gen(function* () {
4800
+ h?.("workflowRuns", {
4801
+ op: "update",
4802
+ row: $(c.row)
4803
+ }), yield* g(c.terminalEvent), yield* _(b, "failed", E);
4804
+ }))), yield* v(b, "failed", E, {
4805
+ payload: y,
4806
+ errorTag: r,
4807
+ errorMessage: i
4808
+ }), yield* S.sync(() => s.recordRun?.({
4809
+ name: s.name,
4810
+ status: "failed",
4811
+ durationMs: Date.now() - C
4812
+ })), yield* S.failCause(e)) : yield* S.failCause(e);
4813
+ }
4814
+ let ge = he.exit.value, _e = Date.now(), P = yield* S.promise(() => s.transaction((e) => vn(e, {
4815
+ owner: {
4816
+ runId: E,
4817
+ workflowName: s.name,
4818
+ executionId: b,
4819
+ generation: O
4820
+ },
4821
+ now: _e,
4822
+ durationMs: _e - C,
4823
+ outcome: {
4824
+ status: "succeeded",
4825
+ output: Li(ge, u)
4826
+ }
4827
+ })));
4828
+ return P.kind === "committed" ? (E && (yield* D("failed to record workflow success", S.gen(function* () {
4829
+ h?.("workflowRuns", {
4830
+ op: "update",
4831
+ row: $(P.row)
4832
+ }), yield* g(P.terminalEvent), yield* _(b, "succeeded", E);
4833
+ }))), yield* v(b, "succeeded", E), yield* S.sync(() => s.recordRun?.({
4834
+ name: s.name,
4835
+ status: "succeeded",
4836
+ durationMs: Date.now() - C,
4837
+ completedAtSec: Date.now() / 1e3
4838
+ })), ge) : ge;
4839
+ });
4840
+ };
4841
+ //#endregion
4842
+ export { Hn as $, Ke as $t, Wr as A, zt as At, nr as B, vt as Bt, ri as C, Qt as Ct, Yr as D, Kt as Dt, Jr as E, Pt as Et, Lr as F, en as Ft, qn as G, B as Gt, rr as H, xt as Ht, Ir as I, At as It, Wn as J, it as Jt, Jn as K, Ct as Kt, Sr as L, Dt as Lt, Pr as M, Y as Mt, Br as N, Wt as Nt, Xr as O, Vt as Ot, zr as P, Rt as Pt, Un as Q, Le as Qt, jr as R, kt as Rt, pi as S, tn as St, ei as T, Lt as Tt, dr as U, pt as Ut, ir as V, St as Vt, Kn as W, bt as Wt, tr as X, z as Xt, Zn as Y, ot as Yt, Qn as Z, Ye as Zt, si as _, Ce as _n, $t as _t, Ni as a, R as an, Mn as at, vi as b, be as bn, Xt as bt, Bi as c, Me as cn, hn as ct, Si as d, Ee as dn, ln as dt, Ve as en, Bn as et, Z as f, Ne as fn, W as ft, ci as g, we as gn, qt as gt, li as h, ke as hn, U as ht, Pi as i, ze as in, Fn as it, Hr as j, It as jt, Zr as k, nn as kt, Oi as l, De as ln, vn as lt, fi as m, Ae as mn, jt as mt, Mi as n, We as nn, zn as nt, $ as o, Ie as on, Nn as ot, di as p, je as pn, Nt as pt, Gn as q, ht as qt, Ri as r, Be as rn, Pn as rt, Li as s, Te as sn, yn as st, ji as t, Ge as tn, Ln as tt, Di as u, Oe as un, pn as ut, oi as v, Se as vn, Jt as vt, ii as w, Ht as wt, _i as x, Gt as xt, yi as y, xe as yn, Yt as yt, wr as z, Ot as zt };