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