@voltro/workflow 0.29.0 → 0.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,854 +0,0 @@
1
- import { C as e, S as t, b as n, x as r } from "./primitives-Dgu3O55Q.js";
2
- import { Activity as i, DurableClock as a, DurableDeferred as o, Workflow as s, WorkflowEngine as c } from "@effect/workflow";
3
- import { Cause as l, Effect as u, Exit as d, FiberRef as f, Layer as p, Schema as m } from "effect";
4
- import { and as h, boolean as g, eq as _, id as v, integer as y, json as b, or as x, queryFor as S, reference as C, table as w, text as T, timestamp as E } from "@voltro/database";
5
- import { WorkflowInstance as ee } from "@effect/workflow/WorkflowEngine";
6
- import { publishServerError as D } from "@voltro/protocol";
7
- //#region src/inMemoryLayer.ts
8
- var O = c.layerMemory, k = w("_voltro_workflow_runs", {
9
- id: v({ prefix: "wfrun" }),
10
- tag: T(),
11
- executionId: T().unique(),
12
- status: T().oneOf([
13
- "running",
14
- "succeeded",
15
- "failed",
16
- "cancelled",
17
- "suspended"
18
- ]).default("running"),
19
- payload: b(),
20
- workflowVersion: T().nullable(),
21
- workflowPatches: b().nullable(),
22
- output: b().nullable(),
23
- subject: b().nullable(),
24
- source: T().nullable(),
25
- errorTag: T().nullable(),
26
- errorMessage: T().nullable(),
27
- cancelled: g().default(!1),
28
- discardedAt: E().nullable(),
29
- discardedBy: T().nullable(),
30
- startedAt: E().default("now"),
31
- completedAt: E().nullable(),
32
- durationMs: y().nullable(),
33
- traceId: T().nullable(),
34
- parentExecutionId: T().nullable(),
35
- parentClosePolicy: T().oneOf([
36
- "cancel",
37
- "terminate",
38
- "abandon"
39
- ]).nullable()
40
- }).index(["tag"]).index(["status"]).index(["source"]).index(["startedAt"]).index(["parentExecutionId"]).index(["parentClosePolicy"]), A = w("_voltro_workflow_run_steps", {
41
- id: v({ prefix: "wfstep" }),
42
- runId: C(() => k, {
43
- index: !1,
44
- onDelete: "cascade"
45
- }),
46
- stepName: T(),
47
- attempt: y().default(1),
48
- status: T().oneOf([
49
- "running",
50
- "succeeded",
51
- "failed"
52
- ]).default("running"),
53
- input: b().nullable(),
54
- retryPolicy: b().nullable(),
55
- output: b().nullable(),
56
- errorTag: T().nullable(),
57
- errorMessage: T().nullable(),
58
- errorCause: b().nullable(),
59
- startedAt: E().default("now"),
60
- completedAt: E().nullable(),
61
- durationMs: y().nullable()
62
- }).index(["runId", "stepName"]).index(["startedAt"]), j = w("_voltro_workflow_run_events", {
63
- id: v({ prefix: "wfev" }),
64
- runId: C(() => k, {
65
- index: !1,
66
- onDelete: "cascade"
67
- }),
68
- eventType: T(),
69
- payload: b().nullable(),
70
- occurredAt: E().default("now"),
71
- stepName: T().nullable(),
72
- attempt: y().nullable()
73
- }).index(["runId", "occurredAt"]).index(["eventType"]), M = w("_voltro_workflow_start_contexts", {
74
- id: v({ prefix: "wfctx" }),
75
- workflowName: T(),
76
- executionId: T().unique(),
77
- subject: b().nullable(),
78
- traceId: T().nullable(),
79
- source: T().nullable(),
80
- parentExecutionId: T().nullable(),
81
- parentClosePolicy: T().oneOf([
82
- "cancel",
83
- "terminate",
84
- "abandon"
85
- ]).nullable(),
86
- createdAt: E().default("now")
87
- }).index(["workflowName"]).index(["executionId"]).index(["parentExecutionId"]), N = async (e, t) => {
88
- if (e) try {
89
- await e.recordEvent(t);
90
- } catch {}
91
- }, P = (t, n) => {
92
- let a = u.gen(function* () {
93
- let i = n.pollIntervalMs ?? 200, a = n.maxPollIntervalMs ?? 5e3, o = n.timeoutMs ?? 1440 * 6e4, s = yield* r, c = yield* u.serviceOption(e), l = c._tag === "Some" ? c.value : void 0;
94
- if (s === void 0) return yield* u.die(/* @__PURE__ */ Error("awaitSignal: no active workflow run id in scope"));
95
- let d = s;
96
- yield* u.promise(() => N(l, {
97
- runId: d,
98
- eventType: "signal-awaited",
99
- payload: { signalName: n.name }
100
- }));
101
- let f = Date.now(), p = i;
102
- for (;;) {
103
- let e = Date.now() - f;
104
- if (e > o) return yield* u.die(/* @__PURE__ */ Error(`awaitSignal('${n.name}') timed out after ${e}ms`));
105
- let r = {
106
- table: "_voltro_workflow_run_events",
107
- order: [{
108
- column: "occurredAt",
109
- direction: "asc"
110
- }],
111
- predicate: h(_("runId", d), _("eventType", "signal-sent")),
112
- projection: void 0,
113
- skip: void 0,
114
- take: 1e3
115
- }, i = (yield* u.tryPromise({
116
- try: () => t.store.query(r),
117
- catch: (e) => e
118
- })).find((e) => e.payload?.signalName === n.name);
119
- if (i !== void 0) {
120
- let e = yield* m.decodeUnknown(n.schema)(i.payload?.value);
121
- return yield* u.promise(() => N(l, {
122
- runId: d,
123
- eventType: "signal-received",
124
- payload: {
125
- signalName: n.name,
126
- value: i.payload?.value
127
- }
128
- })), e;
129
- }
130
- yield* u.sleep(`${p} millis`), p = Math.min(p * 2, a);
131
- }
132
- });
133
- return i.make({
134
- name: `await-signal:${n.name}`,
135
- success: n.schema,
136
- execute: a
137
- });
138
- }, te = (e) => new Promise((t) => setTimeout(t, e)), ne = () => {
139
- let e = globalThis.crypto;
140
- return typeof e?.randomUUID == "function" ? e.randomUUID() : `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
141
- }, F = () => `wfu_${ne()}`, I = async (e, t) => {
142
- let n = t.id ?? t.executionId;
143
- if (!n) throw Error("workflow message target requires target.id or target.executionId");
144
- let r = await e.query({
145
- table: "_voltro_workflow_runs",
146
- order: [],
147
- predicate: _("id", n),
148
- projection: void 0,
149
- skip: void 0,
150
- take: 1
151
- });
152
- if (r[0]) return r[0];
153
- let i = (await e.query({
154
- table: "_voltro_workflow_runs",
155
- order: [],
156
- predicate: _("executionId", n),
157
- projection: void 0,
158
- skip: void 0,
159
- take: 1
160
- }))[0];
161
- if (!i) throw Error(`workflow message target not found: ${n}`);
162
- return i;
163
- }, re = async (e) => {
164
- let t = await I(e.store, e.target);
165
- return { eventId: (await e.recorder.recordEvent({
166
- runId: t.id,
167
- eventType: "signal-sent",
168
- payload: {
169
- signalName: e.signalName,
170
- value: e.payload
171
- }
172
- })).id };
173
- }, ie = async (e) => {
174
- let t = await I(e.store, e.target), n = F(), r = await e.recorder.recordEvent({
175
- runId: t.id,
176
- eventType: "update-requested",
177
- payload: {
178
- updateId: n,
179
- updateName: e.updateName,
180
- value: e.payload
181
- }
182
- }), i = Date.now(), a = e.options?.timeoutMs ?? 3e4, o = e.options?.pollIntervalMs ?? 100;
183
- for (;;) {
184
- let s = {
185
- table: "_voltro_workflow_run_events",
186
- order: [{
187
- column: "occurredAt",
188
- direction: "asc"
189
- }],
190
- predicate: _("runId", t.id),
191
- projection: void 0,
192
- skip: void 0,
193
- take: 1e3
194
- }, c = await e.store.query(s), l = c.find((e) => e.eventType === "update-completed" && e.payload?.updateId === n);
195
- if (l) return {
196
- eventId: r.id,
197
- updateId: n,
198
- completedEventId: l.id,
199
- result: l.payload?.result
200
- };
201
- let u = c.find((e) => e.eventType === "update-failed" && e.payload?.updateId === n);
202
- if (u) {
203
- let t = Error(u.payload?.errorMessage ?? `workflow update '${e.updateName}' failed`);
204
- throw Object.assign(t, {
205
- updateId: n,
206
- eventId: r.id,
207
- errorTag: u.payload?.errorTag ?? null
208
- }), t;
209
- }
210
- if (Date.now() - i >= a) throw Error(`Timed out waiting for workflow update '${e.updateName}' (${n})`);
211
- await te(o);
212
- }
213
- }, ae = 1440 * 6e4, L = "voltro/suspending-signal", R = (e, t) => `${L}/${e}/${t}`, z = (e) => o.make(e, { success: m.Unknown }), B = async (e, t) => {
214
- if (e) try {
215
- await e.recordEvent(t);
216
- } catch {}
217
- }, oe = (t, n) => u.gen(function* () {
218
- let t = n.timeoutMs ?? ae, i = z(R((yield* c.WorkflowInstance).workflow.name, n.name)), s = yield* r, l = yield* u.serviceOption(e), d = l._tag === "Some" ? l.value : void 0;
219
- s !== void 0 && (yield* u.promise(() => B(d, {
220
- runId: s,
221
- eventType: "signal-awaited",
222
- payload: { signalName: n.name }
223
- })));
224
- let f = o.await(i), p = Number.isFinite(t) ? yield* u.race(f, a.sleep({
225
- name: `await-signal-timeout/${n.name}`,
226
- duration: `${t} millis`
227
- }).pipe(u.andThen(u.die(/* @__PURE__ */ Error(`awaitSignalSuspending('${n.name}') timed out after ${t}ms`))))) : yield* f, h = yield* m.decodeUnknown(n.schema)(p);
228
- return s !== void 0 && (yield* u.promise(() => B(d, {
229
- runId: s,
230
- eventType: "signal-received",
231
- payload: {
232
- signalName: n.name,
233
- value: h
234
- }
235
- }))), h;
236
- }), se = (e) => u.gen(function* () {
237
- let t = e.target.executionId, n = e.target.workflowName;
238
- if (t === void 0 || n === void 0) {
239
- let r = e.store;
240
- if (r === void 0) return yield* u.die(/* @__PURE__ */ Error("completeSuspendingSignal: provide a store, or target.executionId AND target.workflowName"));
241
- let i = yield* u.tryPromise({
242
- try: () => I(r, e.target),
243
- catch: (e) => e
244
- });
245
- t ??= i.executionId, n ??= i.tag;
246
- }
247
- if (t === void 0 || n === void 0) return { completed: !1 };
248
- let r = R(n, e.signalName), i = z(r), a = new o.TokenParsed({
249
- workflowName: n,
250
- executionId: t,
251
- deferredName: r
252
- }).asToken;
253
- return yield* o.done(i, {
254
- token: a,
255
- exit: d.succeed(e.payload)
256
- }), { completed: !0 };
257
- }), V = async (e, t) => {
258
- if (e) try {
259
- await e.recordEvent(t);
260
- } catch {}
261
- }, H = (e) => {
262
- let t = l.failureOption(e), n = Array.from(l.defects(e)), r = t._tag === "Some" ? t.value : n[0] ?? l.squash(e);
263
- return {
264
- errorTag: r && typeof r == "object" && "_tag" in r ? String(r._tag) : null,
265
- errorMessage: r?.message ?? String(r)
266
- };
267
- }, U = (t, n) => {
268
- let a = u.gen(function* () {
269
- let i = n.pollIntervalMs ?? 200, a = n.maxPollIntervalMs ?? 5e3, o = n.timeoutMs ?? 3e4, s = yield* r, c = yield* u.serviceOption(e), l = c._tag === "Some" ? c.value : void 0;
270
- if (s === void 0) return yield* u.die(/* @__PURE__ */ Error("awaitUpdate: no active workflow run id in scope"));
271
- let d = s, f = Date.now(), p = i;
272
- for (;;) {
273
- let e = Date.now() - f;
274
- if (e > o) return yield* u.die(/* @__PURE__ */ Error(`awaitUpdate('${n.name}') timed out after ${e}ms`));
275
- let r = {
276
- table: "_voltro_workflow_run_events",
277
- order: [{
278
- column: "occurredAt",
279
- direction: "asc"
280
- }],
281
- predicate: _("runId", d),
282
- projection: void 0,
283
- skip: void 0,
284
- take: 1e3
285
- }, i = yield* u.tryPromise({
286
- try: () => t.store.query(r),
287
- catch: (e) => e
288
- }), s = new Set(i.filter((e) => e.eventType === "update-completed" || e.eventType === "update-failed").map((e) => e.payload?.updateId).filter((e) => typeof e == "string" && e.length > 0)), c = i.find((e) => e.eventType === "update-requested" && e.payload?.updateName === n.name && typeof e.payload.updateId == "string" && !s.has(e.payload.updateId));
289
- if (c !== void 0) {
290
- let e = c.payload.updateId;
291
- yield* u.promise(() => V(l, {
292
- runId: d,
293
- eventType: "update-received",
294
- payload: {
295
- updateId: e,
296
- updateName: n.name
297
- }
298
- }));
299
- let t = yield* m.decodeUnknown(n.schema)(c.payload?.value).pipe(u.tapErrorCause((t) => u.promise(() => V(l, {
300
- runId: d,
301
- eventType: "update-failed",
302
- payload: {
303
- updateId: e,
304
- updateName: n.name,
305
- ...H(t)
306
- }
307
- })))), r = yield* (n.handle ? n.handle(t) : u.succeed(t)).pipe(u.flatMap((e) => n.success ? m.decodeUnknown(n.success)(e) : u.succeed(e))).pipe(u.tapErrorCause((t) => u.promise(() => V(l, {
308
- runId: d,
309
- eventType: "update-failed",
310
- payload: {
311
- updateId: e,
312
- updateName: n.name,
313
- ...H(t)
314
- }
315
- }))));
316
- return yield* u.promise(() => V(l, {
317
- runId: d,
318
- eventType: "update-completed",
319
- payload: {
320
- updateId: e,
321
- updateName: n.name,
322
- result: r
323
- }
324
- })), r;
325
- }
326
- yield* u.sleep(`${p} millis`), p = Math.min(p * 2, a);
327
- }
328
- });
329
- return i.make({
330
- name: `await-update:${n.name}`,
331
- success: n.success ?? n.schema,
332
- execute: a
333
- });
334
- }, W = 8 * 1024, G = () => {
335
- let e = globalThis.crypto;
336
- return typeof e?.randomUUID == "function" ? e.randomUUID() : `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
337
- }, K = (e) => `${e}_${G()}`, q = (e, t = W) => {
338
- if (e == null) return e;
339
- try {
340
- let n = JSON.stringify(e);
341
- return n.length <= t ? e : {
342
- __truncated: !0,
343
- bytes: n.length,
344
- sample: n.slice(0, t)
345
- };
346
- } catch {
347
- return { __unserialisable: String(e) };
348
- }
349
- }, J = (e) => {
350
- let t = {};
351
- for (let [n, r] of Object.entries(e)) t[n] = r instanceof Date ? r.toISOString() : r;
352
- return t;
353
- }, Y = (e) => {
354
- let t = e.truncateBytes ?? W, n = e.makeId ?? K, r = (t, n) => e.log?.warn(t, n), i = e.emit;
355
- return {
356
- startStep: async ({ runId: a, stepName: o, attempt: s, stepInput: c, retryPolicy: l }) => {
357
- try {
358
- let r = await e.store.insert("_voltro_workflow_run_steps", {
359
- id: n("ws"),
360
- runId: a,
361
- stepName: o,
362
- attempt: s,
363
- status: "running",
364
- input: c === void 0 ? null : q(c, t),
365
- retryPolicy: l ?? null,
366
- output: null,
367
- errorTag: null,
368
- errorMessage: null,
369
- startedAt: /* @__PURE__ */ new Date(),
370
- completedAt: null,
371
- durationMs: null
372
- });
373
- return i?.("workflowSteps", {
374
- op: "insert",
375
- row: J(r)
376
- }), r.id;
377
- } catch (e) {
378
- r("failed to record step start (continuing)", {
379
- runId: a,
380
- stepName: o,
381
- attempt: s,
382
- reason: e?.message ?? String(e)
383
- });
384
- return;
385
- }
386
- },
387
- endStepSuccess: async ({ stepRecordId: n, output: a, durationMs: o }) => {
388
- try {
389
- let r = await e.store.update("_voltro_workflow_run_steps", n, {
390
- status: "succeeded",
391
- output: q(a, t),
392
- completedAt: /* @__PURE__ */ new Date(),
393
- durationMs: o
394
- });
395
- r && i?.("workflowSteps", {
396
- op: "update",
397
- row: J(r)
398
- });
399
- } catch (e) {
400
- r("failed to record step success", {
401
- stepRecordId: n,
402
- reason: e?.message ?? String(e)
403
- });
404
- }
405
- },
406
- endStepFailure: async ({ stepRecordId: n, errorTag: a, errorMessage: o, errorCause: s, durationMs: c }) => {
407
- try {
408
- let r = await e.store.update("_voltro_workflow_run_steps", n, {
409
- status: "failed",
410
- errorTag: a,
411
- errorMessage: o,
412
- errorCause: s === void 0 ? null : q(s, t),
413
- completedAt: /* @__PURE__ */ new Date(),
414
- durationMs: c
415
- });
416
- r && i?.("workflowSteps", {
417
- op: "update",
418
- row: J(r)
419
- });
420
- } catch (e) {
421
- r("failed to record step failure", {
422
- stepRecordId: n,
423
- reason: e?.message ?? String(e)
424
- });
425
- }
426
- },
427
- recordEvent: async ({ runId: t, eventType: a, payload: o, stepName: s, attempt: c }) => {
428
- let l = n("wfev");
429
- try {
430
- let n = await e.store.insert("_voltro_workflow_run_events", {
431
- id: l,
432
- runId: t,
433
- eventType: a,
434
- payload: o ?? null,
435
- occurredAt: /* @__PURE__ */ new Date(),
436
- stepName: s ?? null,
437
- attempt: c ?? null
438
- });
439
- i?.("workflowEvents", {
440
- op: "insert",
441
- row: J(n)
442
- });
443
- } catch (e) {
444
- r("failed to record workflow event (continuing)", {
445
- runId: t,
446
- eventType: a,
447
- reason: e?.message ?? String(e)
448
- });
449
- }
450
- if (e.wakeups !== void 0) {
451
- let n = o?.scheduledWakeAt, r = typeof n == "string" ? new Date(n) : void 0, i = o?.tenantId, s = typeof i == "string" ? i : void 0;
452
- a === "timer-set" && r !== void 0 && !Number.isNaN(r.getTime()) ? await e.wakeups.register(t, r, s).catch(() => {}) : (a === "timer-fired" || a === "run-succeeded" || a === "run-failed" || a === "run-cancelled") && await e.wakeups.cancel(t, s).catch(() => {});
453
- }
454
- return { id: l };
455
- }
456
- };
457
- }, ce = (i, a) => {
458
- let o = i.truncateBytes ?? W, c = i.makeId ?? K, p = i.recorder ?? Y(i), m = (e, t) => i.log?.warn(e, t), h = i.emit, g = (e, t, n) => u.promise(async () => {
459
- if (i.onParentClose) try {
460
- await i.onParentClose({
461
- workflowName: i.name,
462
- executionId: e,
463
- ...n === void 0 ? {} : { runId: n },
464
- status: t
465
- });
466
- } catch (n) {
467
- m("failed to apply workflow parent-close policy", {
468
- tag: i.name,
469
- executionId: e,
470
- status: t,
471
- reason: n?.message ?? String(n)
472
- });
473
- }
474
- });
475
- return (v, y) => u.gen(function* () {
476
- let b = Date.now(), x = yield* f.get(n), S = i.parentExecutionId ?? x ?? null, C = i.parentClosePolicy ?? null, w, T = (e, t) => t.pipe(u.catchAllCause((t) => l.isInterrupted(t) ? u.failCause(t) : u.sync(() => {
477
- let n = l.squash(t);
478
- m(e, {
479
- tag: i.name,
480
- executionId: y,
481
- reason: n?.message ?? String(n)
482
- });
483
- }))), E = (i.store.query ? yield* u.promise(() => i.store.query({
484
- table: "_voltro_workflow_runs",
485
- order: [],
486
- predicate: _("executionId", y),
487
- projection: void 0,
488
- skip: void 0,
489
- take: 1
490
- })) : [])[0], O = E?.workflowVersion ?? null;
491
- if (E?.id !== void 0 && O !== null && i.workflowCompatibleVersions !== void 0 && i.workflowCompatibleVersions !== null && !i.workflowCompatibleVersions.includes(O)) {
492
- let e = `Workflow '${i.name}' run '${y}' was started on version ${O}, but current code is compatible with ${i.workflowCompatibleVersions.join(", ")}`, t = yield* u.promise(() => i.store.update("_voltro_workflow_runs", E.id, {
493
- status: "failed",
494
- errorTag: "WorkflowVersionIncompatible",
495
- errorMessage: e,
496
- completedAt: /* @__PURE__ */ new Date()
497
- }));
498
- return t && h?.("workflowRuns", {
499
- op: "update",
500
- row: J(t)
501
- }), yield* u.promise(() => p.recordEvent({
502
- runId: E.id,
503
- eventType: "run-failed",
504
- payload: {
505
- errorTag: "WorkflowVersionIncompatible",
506
- errorMessage: e,
507
- workflowVersion: i.workflowVersion ?? null,
508
- compatibleWith: i.workflowCompatibleVersions,
509
- previousVersion: O
510
- }
511
- })), yield* u.sync(() => i.recordRun?.({
512
- name: i.name,
513
- status: "failed",
514
- durationMs: 0
515
- })), yield* u.fail(Error(e));
516
- }
517
- yield* T("failed to record workflow start (continuing)", u.gen(function* () {
518
- let e = yield* u.promise(() => i.store.insert("_voltro_workflow_runs", {
519
- id: c("wr"),
520
- tag: i.name,
521
- executionId: y,
522
- status: "running",
523
- payload: v,
524
- workflowVersion: i.workflowVersion ?? null,
525
- workflowPatches: i.workflowPatches ?? null,
526
- output: null,
527
- subject: i.subject ?? null,
528
- source: i.source ?? null,
529
- errorTag: null,
530
- errorMessage: null,
531
- cancelled: !1,
532
- startedAt: /* @__PURE__ */ new Date(),
533
- completedAt: null,
534
- durationMs: null,
535
- traceId: i.traceId ?? null,
536
- parentExecutionId: S,
537
- parentClosePolicy: C
538
- }));
539
- if (w = e.id, h?.("workflowRuns", {
540
- op: "insert",
541
- row: J(e)
542
- }), w) {
543
- let e = w;
544
- yield* u.promise(() => p.recordEvent({
545
- runId: e,
546
- eventType: "run-started",
547
- payload: {
548
- tag: i.name,
549
- executionId: y,
550
- source: i.source ?? null,
551
- workflowVersion: i.workflowVersion ?? null,
552
- workflowPatches: i.workflowPatches ?? null,
553
- parentExecutionId: S,
554
- parentClosePolicy: C
555
- }
556
- }));
557
- }
558
- }));
559
- let k = i.subject?.tenantId, A = a(v, y).pipe(u.locally(r, w), u.locally(n, y), u.locally(t, typeof k == "string" ? k : void 0), u.provideService(e, p)), j = i.pluginWorkflowStepLayer ? A.pipe(u.provide(i.pluginWorkflowStepLayer)) : A, M = yield* s.intoResult(j);
560
- if (s.isResult(M) && M._tag === "Suspended") {
561
- let e = M.cause, t = e !== void 0 && !l.isEmpty(e), n = t ? l.squash(e) : void 0, r = n && typeof n == "object" && "_tag" in n ? String(n._tag) : null, a = t ? n?.message ?? String(n) : null;
562
- t && (yield* u.sync(() => D({
563
- error: n,
564
- source: "workflow",
565
- name: i.name,
566
- ...i.traceId ? { traceId: i.traceId } : {},
567
- fields: {
568
- executionId: y,
569
- suspendedOnFailure: !0,
570
- ...r ? { errorTag: r } : {},
571
- ...w ? { runId: w } : {}
572
- }
573
- }))), w && (yield* T("failed to record workflow suspend", u.gen(function* () {
574
- let e = yield* u.promise(() => i.store.update("_voltro_workflow_runs", w, {
575
- status: "suspended",
576
- ...t ? {
577
- errorTag: r,
578
- errorMessage: a
579
- } : {}
580
- }));
581
- e && h?.("workflowRuns", {
582
- op: "update",
583
- row: J(e)
584
- }), yield* u.promise(() => p.recordEvent({
585
- runId: w,
586
- eventType: "run-suspended",
587
- payload: t ? {
588
- reason: "suspend-on-failure",
589
- errorTag: r,
590
- errorMessage: a
591
- } : { reason: "workflow-suspend" }
592
- }));
593
- })));
594
- let o = yield* ee;
595
- return yield* s.suspend(o);
596
- }
597
- let N = M;
598
- if (d.isFailure(N.exit)) {
599
- let e = N.exit.cause, t = l.failureOption(e), n = t._tag === "Some" ? t.value : l.squash(e), r = n && typeof n == "object" && "_tag" in n ? String(n._tag) : null, a = n?.message ?? String(n);
600
- return yield* u.sync(() => D({
601
- error: n,
602
- source: "workflow",
603
- name: i.name,
604
- ...i.traceId ? { traceId: i.traceId } : {},
605
- fields: {
606
- executionId: y,
607
- ...r ? { errorTag: r } : {},
608
- ...w ? { runId: w } : {}
609
- }
610
- })), w && (yield* T("failed to record workflow failure", u.gen(function* () {
611
- let e = yield* u.promise(() => i.store.update("_voltro_workflow_runs", w, {
612
- status: "failed",
613
- errorTag: r,
614
- errorMessage: a,
615
- completedAt: /* @__PURE__ */ new Date(),
616
- durationMs: Date.now() - b
617
- }));
618
- e && h?.("workflowRuns", {
619
- op: "update",
620
- row: J(e)
621
- }), yield* u.promise(() => p.recordEvent({
622
- runId: w,
623
- eventType: "run-failed",
624
- payload: {
625
- errorTag: r,
626
- errorMessage: a,
627
- durationMs: Date.now() - b
628
- }
629
- })), yield* g(y, "failed", w);
630
- }))), yield* u.sync(() => i.recordRun?.({
631
- name: i.name,
632
- status: "failed",
633
- durationMs: Date.now() - b
634
- })), yield* u.failCause(e);
635
- }
636
- let P = N.exit.value;
637
- return w && (yield* T("failed to record workflow success", u.gen(function* () {
638
- let e = yield* u.promise(() => i.store.update("_voltro_workflow_runs", w, {
639
- status: "succeeded",
640
- output: q(P, o),
641
- completedAt: /* @__PURE__ */ new Date(),
642
- durationMs: Date.now() - b
643
- }));
644
- e && h?.("workflowRuns", {
645
- op: "update",
646
- row: J(e)
647
- }), yield* u.promise(() => p.recordEvent({
648
- runId: w,
649
- eventType: "run-succeeded",
650
- payload: { durationMs: Date.now() - b }
651
- })), yield* g(y, "succeeded", w);
652
- }))), yield* u.sync(() => i.recordRun?.({
653
- name: i.name,
654
- status: "succeeded",
655
- durationMs: Date.now() - b,
656
- completedAtSec: Date.now() / 1e3
657
- })), P;
658
- });
659
- }, X = (e) => e === "cancel" || e === "terminate", le = (e) => e === "running" || e === "suspended", ue = async (e) => {
660
- let t = await e.store.query({
661
- table: "_voltro_workflow_runs",
662
- order: [{
663
- column: "startedAt",
664
- direction: "asc"
665
- }],
666
- predicate: _("parentExecutionId", e.parentExecutionId),
667
- projection: void 0,
668
- skip: void 0,
669
- take: e.limit ?? 1e3
670
- }), n = [];
671
- for (let r of t) {
672
- let t = {
673
- runId: r.id,
674
- workflowName: r.tag,
675
- executionId: r.executionId,
676
- policy: r.parentClosePolicy
677
- };
678
- if (r.parentClosePolicy === "abandon") {
679
- n.push({
680
- ...t,
681
- action: "abandoned"
682
- });
683
- continue;
684
- }
685
- if (!X(r.parentClosePolicy)) {
686
- n.push({
687
- ...t,
688
- action: "skipped",
689
- reason: "no-parent-close-policy"
690
- });
691
- continue;
692
- }
693
- if (!le(r.status)) {
694
- n.push({
695
- ...t,
696
- action: "skipped",
697
- reason: `status:${r.status}`
698
- });
699
- continue;
700
- }
701
- try {
702
- await e.interruptChild(r.tag, r.executionId, r.parentClosePolicy);
703
- let i = await e.store.update("_voltro_workflow_runs", r.id, {
704
- status: "cancelled",
705
- cancelled: !0,
706
- completedAt: /* @__PURE__ */ new Date()
707
- });
708
- i && e.emit?.("workflowRuns", {
709
- op: "update",
710
- row: J(i)
711
- }), await e.recorder?.recordEvent({
712
- runId: r.id,
713
- eventType: "run-cancelled",
714
- payload: {
715
- reason: "parent-close",
716
- parentExecutionId: e.parentExecutionId,
717
- parentStatus: e.parentStatus,
718
- parentClosePolicy: r.parentClosePolicy,
719
- action: r.parentClosePolicy
720
- }
721
- }), n.push({
722
- ...t,
723
- action: "cancelled"
724
- });
725
- } catch (i) {
726
- let a = i?.message ?? String(i);
727
- e.log?.warn("workflow.parentClose.childInterrupt failed", {
728
- parentExecutionId: e.parentExecutionId,
729
- childExecutionId: r.executionId,
730
- childWorkflowName: r.tag,
731
- parentClosePolicy: r.parentClosePolicy,
732
- reason: a
733
- }), n.push({
734
- ...t,
735
- action: "failed",
736
- reason: a
737
- });
738
- }
739
- }
740
- return n;
741
- }, Z = (e) => {
742
- if (e == null) return null;
743
- if (e instanceof Date) return e;
744
- if (typeof e == "string" || typeof e == "number") {
745
- let t = new Date(e);
746
- return Number.isNaN(t.getTime()) ? null : t;
747
- }
748
- return null;
749
- }, Q = (e) => typeof e == "number" ? e : e == null ? null : Number(e), $ = (e) => e == null ? null : String(e), de = (e) => {
750
- let t = /* @__PURE__ */ new Map();
751
- for (let n of e) {
752
- let e = String(n.stepName), r = t.get(e);
753
- r === void 0 ? t.set(e, [n]) : r.push(n);
754
- }
755
- let n = [];
756
- for (let [e, r] of t) {
757
- r.sort((e, t) => (Q(e.attempt) ?? 0) - (Q(t.attempt) ?? 0));
758
- let t = r[r.length - 1], i = $(t.errorTag), a = $(t.errorMessage), o = i !== null || a !== null ? {
759
- tag: i,
760
- message: a ?? ""
761
- } : null;
762
- n.push({
763
- name: e,
764
- attempt: Q(t.attempt) ?? r.length,
765
- attempts: r.length,
766
- status: t.status ?? "running",
767
- input: t.input ?? null,
768
- output: t.output ?? null,
769
- error: o,
770
- durationMs: Q(t.durationMs)
771
- });
772
- }
773
- return n.sort((t, n) => {
774
- let r = e.find((e) => String(e.stepName) === t.name), i = e.find((e) => String(e.stepName) === n.name);
775
- return (Z(r?.startedAt)?.getTime() ?? 0) - (Z(i?.startedAt)?.getTime() ?? 0);
776
- }), n;
777
- }, fe = (e) => {
778
- if (e == null) return null;
779
- if (typeof e == "string") try {
780
- return JSON.parse(e);
781
- } catch {
782
- return null;
783
- }
784
- return typeof e == "object" ? e : null;
785
- }, pe = async (e, t) => {
786
- let n = S(k), r = (await t.query(n.where(x(_("id", e), _("executionId", e))).limit(1).descriptor))[0];
787
- if (r === void 0) return null;
788
- let i = String(r.id), a = S(A), o = await t.query(a.where(_("runId", i)).descriptor);
789
- return {
790
- id: i,
791
- executionId: $(r.executionId) ?? "",
792
- name: $(r.tag) ?? "",
793
- status: r.status ?? "running",
794
- input: r.payload ?? null,
795
- output: r.output ?? null,
796
- subject: fe(r.subject),
797
- source: $(r.source),
798
- steps: de(o),
799
- startedAt: Z(r.startedAt) ?? /* @__PURE__ */ new Date(0),
800
- finishedAt: Z(r.completedAt),
801
- traceId: $(r.traceId),
802
- parentExecutionId: $(r.parentExecutionId),
803
- parentClosePolicy: $(r.parentClosePolicy)
804
- };
805
- }, me = () => {
806
- let t = [], n = [], r = 0, i = 0;
807
- return {
808
- layer: p.succeed(e, {
809
- startStep: async ({ runId: e, stepName: n, attempt: i, stepInput: a, retryPolicy: o }) => {
810
- let s = `wfstep_mem_${++r}`;
811
- return t.push({
812
- id: s,
813
- runId: e,
814
- stepName: n,
815
- attempt: i,
816
- status: "running",
817
- input: a ?? null,
818
- retryPolicy: o ?? null,
819
- output: null,
820
- errorTag: null,
821
- errorMessage: null,
822
- errorCause: null,
823
- startedAt: /* @__PURE__ */ new Date(),
824
- completedAt: null,
825
- durationMs: null
826
- }), s;
827
- },
828
- endStepSuccess: async ({ stepRecordId: e, output: n, durationMs: r }) => {
829
- let i = t.find((t) => t.id === e);
830
- i !== void 0 && (i.status = "succeeded", i.output = n, i.completedAt = /* @__PURE__ */ new Date(), i.durationMs = r);
831
- },
832
- endStepFailure: async ({ stepRecordId: e, errorTag: n, errorMessage: r, errorCause: i, durationMs: a }) => {
833
- let o = t.find((t) => t.id === e);
834
- o !== void 0 && (o.status = "failed", o.errorTag = n, o.errorMessage = r, o.errorCause = i ?? null, o.completedAt = /* @__PURE__ */ new Date(), o.durationMs = a);
835
- },
836
- recordEvent: async ({ runId: e, eventType: t, payload: r, stepName: a, attempt: o }) => {
837
- let s = `wfev_mem_${++i}`;
838
- return n.push({
839
- id: s,
840
- runId: e,
841
- eventType: t,
842
- payload: r ?? null,
843
- stepName: a ?? null,
844
- attempt: o ?? null,
845
- occurredAt: /* @__PURE__ */ new Date()
846
- }), { id: s };
847
- }
848
- }),
849
- readSteps: () => t,
850
- readEvents: () => n
851
- };
852
- };
853
- //#endregion
854
- export { M as _, J as a, k as b, U as c, R as d, F as f, P as g, ie as h, Y as i, oe as l, re as m, pe as n, q as o, I as p, ue as r, ce as s, me as t, se as u, j as v, O as x, A as y };