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