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