@voltro/workflow 0.25.0 → 0.27.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.
- package/CHANGELOG.md +541 -0
- package/dist/cluster-BQ0H5M9n.js +131 -0
- package/dist/cluster.d.ts +140 -13
- package/dist/cluster.js +2 -2
- package/dist/clusterTestSuite.d.ts +34 -0
- package/dist/clusterTestSuite.js +22 -20
- package/dist/index.d.ts +70 -29
- package/dist/index.js +2 -2
- package/dist/primitives-Dgu3O55Q.js +164 -0
- package/dist/primitives.d.ts +63 -28
- package/dist/primitives.js +1 -1
- package/dist/{src-DQww25rP.js → src-KDx7NTsa.js} +97 -73
- package/package.json +3 -3
- package/dist/cluster-DuFweKq0.js +0 -58
- package/dist/primitives-CWy1iu5w.js +0 -111
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { C as e, S as t, b as n, x as r } from "./primitives-
|
|
1
|
+
import { C as e, S as t, b as n, x as r } from "./primitives-Dgu3O55Q.js";
|
|
2
2
|
import { Activity as i, DurableClock as a, DurableDeferred as o, Workflow as s, WorkflowEngine as c } from "@effect/workflow";
|
|
3
3
|
import { Cause as l, Effect as u, Exit as d, FiberRef as f, Layer as p, Schema as m } from "effect";
|
|
4
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
5
|
import { WorkflowInstance as ee } from "@effect/workflow/WorkflowEngine";
|
|
6
|
-
import { publishServerError as
|
|
6
|
+
import { publishServerError as D } from "@voltro/protocol";
|
|
7
7
|
//#region src/inMemoryLayer.ts
|
|
8
|
-
var
|
|
8
|
+
var O = c.layerMemory, k = w("_voltro_workflow_runs", {
|
|
9
9
|
id: v({ prefix: "wfrun" }),
|
|
10
10
|
tag: T(),
|
|
11
11
|
executionId: T().unique(),
|
|
@@ -25,6 +25,8 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
25
25
|
errorTag: T().nullable(),
|
|
26
26
|
errorMessage: T().nullable(),
|
|
27
27
|
cancelled: g().default(!1),
|
|
28
|
+
discardedAt: E().nullable(),
|
|
29
|
+
discardedBy: T().nullable(),
|
|
28
30
|
startedAt: E().default("now"),
|
|
29
31
|
completedAt: E().nullable(),
|
|
30
32
|
durationMs: y().nullable(),
|
|
@@ -35,9 +37,9 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
35
37
|
"terminate",
|
|
36
38
|
"abandon"
|
|
37
39
|
]).nullable()
|
|
38
|
-
}).index(["tag"]).index(["status"]).index(["source"]).index(["startedAt"]).index(["parentExecutionId"]).index(["parentClosePolicy"]),
|
|
40
|
+
}).index(["tag"]).index(["status"]).index(["source"]).index(["startedAt"]).index(["parentExecutionId"]).index(["parentClosePolicy"]), A = w("_voltro_workflow_run_steps", {
|
|
39
41
|
id: v({ prefix: "wfstep" }),
|
|
40
|
-
runId: C(() =>
|
|
42
|
+
runId: C(() => k, {
|
|
41
43
|
index: !1,
|
|
42
44
|
onDelete: "cascade"
|
|
43
45
|
}),
|
|
@@ -57,9 +59,9 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
57
59
|
startedAt: E().default("now"),
|
|
58
60
|
completedAt: E().nullable(),
|
|
59
61
|
durationMs: y().nullable()
|
|
60
|
-
}).index(["runId", "stepName"]).index(["startedAt"]),
|
|
62
|
+
}).index(["runId", "stepName"]).index(["startedAt"]), j = w("_voltro_workflow_run_events", {
|
|
61
63
|
id: v({ prefix: "wfev" }),
|
|
62
|
-
runId: C(() =>
|
|
64
|
+
runId: C(() => k, {
|
|
63
65
|
index: !1,
|
|
64
66
|
onDelete: "cascade"
|
|
65
67
|
}),
|
|
@@ -68,7 +70,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
68
70
|
occurredAt: E().default("now"),
|
|
69
71
|
stepName: T().nullable(),
|
|
70
72
|
attempt: y().nullable()
|
|
71
|
-
}).index(["runId", "occurredAt"]).index(["eventType"]),
|
|
73
|
+
}).index(["runId", "occurredAt"]).index(["eventType"]), M = w("_voltro_workflow_start_contexts", {
|
|
72
74
|
id: v({ prefix: "wfctx" }),
|
|
73
75
|
workflowName: T(),
|
|
74
76
|
executionId: T().unique(),
|
|
@@ -82,16 +84,16 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
82
84
|
"abandon"
|
|
83
85
|
]).nullable(),
|
|
84
86
|
createdAt: E().default("now")
|
|
85
|
-
}).index(["workflowName"]).index(["executionId"]).index(["parentExecutionId"]),
|
|
87
|
+
}).index(["workflowName"]).index(["executionId"]).index(["parentExecutionId"]), N = async (e, t) => {
|
|
86
88
|
if (e) try {
|
|
87
89
|
await e.recordEvent(t);
|
|
88
90
|
} catch {}
|
|
89
|
-
},
|
|
91
|
+
}, P = (t, n) => {
|
|
90
92
|
let a = u.gen(function* () {
|
|
91
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;
|
|
92
94
|
if (s === void 0) return yield* u.die(/* @__PURE__ */ Error("awaitSignal: no active workflow run id in scope"));
|
|
93
95
|
let d = s;
|
|
94
|
-
yield* u.promise(() =>
|
|
96
|
+
yield* u.promise(() => N(l, {
|
|
95
97
|
runId: d,
|
|
96
98
|
eventType: "signal-awaited",
|
|
97
99
|
payload: { signalName: n.name }
|
|
@@ -116,7 +118,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
116
118
|
})).find((e) => e.payload?.signalName === n.name);
|
|
117
119
|
if (i !== void 0) {
|
|
118
120
|
let e = yield* m.decodeUnknown(n.schema)(i.payload?.value);
|
|
119
|
-
return yield* u.promise(() =>
|
|
121
|
+
return yield* u.promise(() => N(l, {
|
|
120
122
|
runId: d,
|
|
121
123
|
eventType: "signal-received",
|
|
122
124
|
payload: {
|
|
@@ -133,7 +135,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
133
135
|
success: n.schema,
|
|
134
136
|
execute: a
|
|
135
137
|
});
|
|
136
|
-
},
|
|
138
|
+
}, te = (e) => new Promise((t) => setTimeout(t, e)), ne = () => {
|
|
137
139
|
let e = globalThis.crypto;
|
|
138
140
|
return typeof e?.randomUUID == "function" ? e.randomUUID() : `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
|
|
139
141
|
}, F = () => `wfu_${ne()}`, I = async (e, t) => {
|
|
@@ -206,15 +208,15 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
206
208
|
}), t;
|
|
207
209
|
}
|
|
208
210
|
if (Date.now() - i >= a) throw Error(`Timed out waiting for workflow update '${e.updateName}' (${n})`);
|
|
209
|
-
await
|
|
211
|
+
await te(o);
|
|
210
212
|
}
|
|
211
|
-
},
|
|
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) => {
|
|
212
214
|
if (e) try {
|
|
213
215
|
await e.recordEvent(t);
|
|
214
216
|
} catch {}
|
|
215
|
-
},
|
|
216
|
-
let t = n.timeoutMs ??
|
|
217
|
-
s !== void 0 && (yield* u.promise(() =>
|
|
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, {
|
|
218
220
|
runId: s,
|
|
219
221
|
eventType: "signal-awaited",
|
|
220
222
|
payload: { signalName: n.name }
|
|
@@ -223,7 +225,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
223
225
|
name: `await-signal-timeout/${n.name}`,
|
|
224
226
|
duration: `${t} millis`
|
|
225
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);
|
|
226
|
-
return s !== void 0 && (yield* u.promise(() =>
|
|
228
|
+
return s !== void 0 && (yield* u.promise(() => B(d, {
|
|
227
229
|
runId: s,
|
|
228
230
|
eventType: "signal-received",
|
|
229
231
|
payload: {
|
|
@@ -231,7 +233,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
231
233
|
value: h
|
|
232
234
|
}
|
|
233
235
|
}))), h;
|
|
234
|
-
}),
|
|
236
|
+
}), se = (e) => u.gen(function* () {
|
|
235
237
|
let t = e.target.executionId, n = e.target.workflowName;
|
|
236
238
|
if (t === void 0 || n === void 0) {
|
|
237
239
|
let r = e.store;
|
|
@@ -243,7 +245,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
243
245
|
t ??= i.executionId, n ??= i.tag;
|
|
244
246
|
}
|
|
245
247
|
if (t === void 0 || n === void 0) return { completed: !1 };
|
|
246
|
-
let r =
|
|
248
|
+
let r = R(n, e.signalName), i = z(r), a = new o.TokenParsed({
|
|
247
249
|
workflowName: n,
|
|
248
250
|
executionId: t,
|
|
249
251
|
deferredName: r
|
|
@@ -252,17 +254,17 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
252
254
|
token: a,
|
|
253
255
|
exit: d.succeed(e.payload)
|
|
254
256
|
}), { completed: !0 };
|
|
255
|
-
}),
|
|
257
|
+
}), V = async (e, t) => {
|
|
256
258
|
if (e) try {
|
|
257
259
|
await e.recordEvent(t);
|
|
258
260
|
} catch {}
|
|
259
|
-
},
|
|
261
|
+
}, H = (e) => {
|
|
260
262
|
let t = l.failureOption(e), n = Array.from(l.defects(e)), r = t._tag === "Some" ? t.value : n[0] ?? l.squash(e);
|
|
261
263
|
return {
|
|
262
264
|
errorTag: r && typeof r == "object" && "_tag" in r ? String(r._tag) : null,
|
|
263
265
|
errorMessage: r?.message ?? String(r)
|
|
264
266
|
};
|
|
265
|
-
},
|
|
267
|
+
}, U = (t, n) => {
|
|
266
268
|
let a = u.gen(function* () {
|
|
267
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;
|
|
268
270
|
if (s === void 0) return yield* u.die(/* @__PURE__ */ Error("awaitUpdate: no active workflow run id in scope"));
|
|
@@ -286,7 +288,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
286
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));
|
|
287
289
|
if (c !== void 0) {
|
|
288
290
|
let e = c.payload.updateId;
|
|
289
|
-
yield* u.promise(() =>
|
|
291
|
+
yield* u.promise(() => V(l, {
|
|
290
292
|
runId: d,
|
|
291
293
|
eventType: "update-received",
|
|
292
294
|
payload: {
|
|
@@ -294,24 +296,24 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
294
296
|
updateName: n.name
|
|
295
297
|
}
|
|
296
298
|
}));
|
|
297
|
-
let t = yield* m.decodeUnknown(n.schema)(c.payload?.value).pipe(u.tapErrorCause((t) => u.promise(() =>
|
|
299
|
+
let t = yield* m.decodeUnknown(n.schema)(c.payload?.value).pipe(u.tapErrorCause((t) => u.promise(() => V(l, {
|
|
298
300
|
runId: d,
|
|
299
301
|
eventType: "update-failed",
|
|
300
302
|
payload: {
|
|
301
303
|
updateId: e,
|
|
302
304
|
updateName: n.name,
|
|
303
|
-
...
|
|
305
|
+
...H(t)
|
|
304
306
|
}
|
|
305
|
-
})))), 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(() =>
|
|
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, {
|
|
306
308
|
runId: d,
|
|
307
309
|
eventType: "update-failed",
|
|
308
310
|
payload: {
|
|
309
311
|
updateId: e,
|
|
310
312
|
updateName: n.name,
|
|
311
|
-
...
|
|
313
|
+
...H(t)
|
|
312
314
|
}
|
|
313
315
|
}))));
|
|
314
|
-
return yield* u.promise(() =>
|
|
316
|
+
return yield* u.promise(() => V(l, {
|
|
315
317
|
runId: d,
|
|
316
318
|
eventType: "update-completed",
|
|
317
319
|
payload: {
|
|
@@ -329,10 +331,10 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
329
331
|
success: n.success ?? n.schema,
|
|
330
332
|
execute: a
|
|
331
333
|
});
|
|
332
|
-
},
|
|
334
|
+
}, W = 8 * 1024, G = () => {
|
|
333
335
|
let e = globalThis.crypto;
|
|
334
336
|
return typeof e?.randomUUID == "function" ? e.randomUUID() : `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
|
|
335
|
-
},
|
|
337
|
+
}, K = (e) => `${e}_${G()}`, q = (e, t = W) => {
|
|
336
338
|
if (e == null) return e;
|
|
337
339
|
try {
|
|
338
340
|
let n = JSON.stringify(e);
|
|
@@ -344,12 +346,12 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
344
346
|
} catch {
|
|
345
347
|
return { __unserialisable: String(e) };
|
|
346
348
|
}
|
|
347
|
-
},
|
|
349
|
+
}, J = (e) => {
|
|
348
350
|
let t = {};
|
|
349
351
|
for (let [n, r] of Object.entries(e)) t[n] = r instanceof Date ? r.toISOString() : r;
|
|
350
352
|
return t;
|
|
351
|
-
},
|
|
352
|
-
let t = e.truncateBytes ??
|
|
353
|
+
}, Y = (e) => {
|
|
354
|
+
let t = e.truncateBytes ?? W, n = e.makeId ?? K, r = (t, n) => e.log?.warn(t, n), i = e.emit;
|
|
353
355
|
return {
|
|
354
356
|
startStep: async ({ runId: a, stepName: o, attempt: s, stepInput: c, retryPolicy: l }) => {
|
|
355
357
|
try {
|
|
@@ -359,7 +361,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
359
361
|
stepName: o,
|
|
360
362
|
attempt: s,
|
|
361
363
|
status: "running",
|
|
362
|
-
input: c === void 0 ? null :
|
|
364
|
+
input: c === void 0 ? null : q(c, t),
|
|
363
365
|
retryPolicy: l ?? null,
|
|
364
366
|
output: null,
|
|
365
367
|
errorTag: null,
|
|
@@ -370,7 +372,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
370
372
|
});
|
|
371
373
|
return i?.("workflowSteps", {
|
|
372
374
|
op: "insert",
|
|
373
|
-
row:
|
|
375
|
+
row: J(r)
|
|
374
376
|
}), r.id;
|
|
375
377
|
} catch (e) {
|
|
376
378
|
r("failed to record step start (continuing)", {
|
|
@@ -386,13 +388,13 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
386
388
|
try {
|
|
387
389
|
let r = await e.store.update("_voltro_workflow_run_steps", n, {
|
|
388
390
|
status: "succeeded",
|
|
389
|
-
output:
|
|
391
|
+
output: q(a, t),
|
|
390
392
|
completedAt: /* @__PURE__ */ new Date(),
|
|
391
393
|
durationMs: o
|
|
392
394
|
});
|
|
393
395
|
r && i?.("workflowSteps", {
|
|
394
396
|
op: "update",
|
|
395
|
-
row:
|
|
397
|
+
row: J(r)
|
|
396
398
|
});
|
|
397
399
|
} catch (e) {
|
|
398
400
|
r("failed to record step success", {
|
|
@@ -407,13 +409,13 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
407
409
|
status: "failed",
|
|
408
410
|
errorTag: a,
|
|
409
411
|
errorMessage: o,
|
|
410
|
-
errorCause: s === void 0 ? null :
|
|
412
|
+
errorCause: s === void 0 ? null : q(s, t),
|
|
411
413
|
completedAt: /* @__PURE__ */ new Date(),
|
|
412
414
|
durationMs: c
|
|
413
415
|
});
|
|
414
416
|
r && i?.("workflowSteps", {
|
|
415
417
|
op: "update",
|
|
416
|
-
row:
|
|
418
|
+
row: J(r)
|
|
417
419
|
});
|
|
418
420
|
} catch (e) {
|
|
419
421
|
r("failed to record step failure", {
|
|
@@ -436,7 +438,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
436
438
|
});
|
|
437
439
|
i?.("workflowEvents", {
|
|
438
440
|
op: "insert",
|
|
439
|
-
row:
|
|
441
|
+
row: J(n)
|
|
440
442
|
});
|
|
441
443
|
} catch (e) {
|
|
442
444
|
r("failed to record workflow event (continuing)", {
|
|
@@ -452,8 +454,8 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
452
454
|
return { id: l };
|
|
453
455
|
}
|
|
454
456
|
};
|
|
455
|
-
},
|
|
456
|
-
let o = i.truncateBytes ??
|
|
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 () => {
|
|
457
459
|
if (i.onParentClose) try {
|
|
458
460
|
await i.onParentClose({
|
|
459
461
|
workflowName: i.name,
|
|
@@ -485,9 +487,9 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
485
487
|
projection: void 0,
|
|
486
488
|
skip: void 0,
|
|
487
489
|
take: 1
|
|
488
|
-
})) : [])[0],
|
|
489
|
-
if (E?.id !== void 0 &&
|
|
490
|
-
let e = `Workflow '${i.name}' run '${y}' was started on version ${
|
|
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, {
|
|
491
493
|
status: "failed",
|
|
492
494
|
errorTag: "WorkflowVersionIncompatible",
|
|
493
495
|
errorMessage: e,
|
|
@@ -495,7 +497,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
495
497
|
}));
|
|
496
498
|
return t && h?.("workflowRuns", {
|
|
497
499
|
op: "update",
|
|
498
|
-
row:
|
|
500
|
+
row: J(t)
|
|
499
501
|
}), yield* u.promise(() => p.recordEvent({
|
|
500
502
|
runId: E.id,
|
|
501
503
|
eventType: "run-failed",
|
|
@@ -504,7 +506,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
504
506
|
errorMessage: e,
|
|
505
507
|
workflowVersion: i.workflowVersion ?? null,
|
|
506
508
|
compatibleWith: i.workflowCompatibleVersions,
|
|
507
|
-
previousVersion:
|
|
509
|
+
previousVersion: O
|
|
508
510
|
}
|
|
509
511
|
})), yield* u.sync(() => i.recordRun?.({
|
|
510
512
|
name: i.name,
|
|
@@ -536,7 +538,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
536
538
|
}));
|
|
537
539
|
if (w = e.id, h?.("workflowRuns", {
|
|
538
540
|
op: "insert",
|
|
539
|
-
row:
|
|
541
|
+
row: J(e)
|
|
540
542
|
}), w) {
|
|
541
543
|
let e = w;
|
|
542
544
|
yield* u.promise(() => p.recordEvent({
|
|
@@ -554,26 +556,48 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
554
556
|
}));
|
|
555
557
|
}
|
|
556
558
|
}));
|
|
557
|
-
let
|
|
558
|
-
if (s.isResult(
|
|
559
|
-
|
|
560
|
-
|
|
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
|
+
}));
|
|
561
581
|
e && h?.("workflowRuns", {
|
|
562
582
|
op: "update",
|
|
563
|
-
row:
|
|
583
|
+
row: J(e)
|
|
564
584
|
}), yield* u.promise(() => p.recordEvent({
|
|
565
585
|
runId: w,
|
|
566
586
|
eventType: "run-suspended",
|
|
567
|
-
payload:
|
|
587
|
+
payload: t ? {
|
|
588
|
+
reason: "suspend-on-failure",
|
|
589
|
+
errorTag: r,
|
|
590
|
+
errorMessage: a
|
|
591
|
+
} : { reason: "workflow-suspend" }
|
|
568
592
|
}));
|
|
569
593
|
})));
|
|
570
|
-
let
|
|
571
|
-
return yield* s.suspend(
|
|
594
|
+
let o = yield* ee;
|
|
595
|
+
return yield* s.suspend(o);
|
|
572
596
|
}
|
|
573
|
-
let
|
|
574
|
-
if (d.isFailure(
|
|
575
|
-
let e =
|
|
576
|
-
return yield* u.sync(() =>
|
|
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({
|
|
577
601
|
error: n,
|
|
578
602
|
source: "workflow",
|
|
579
603
|
name: i.name,
|
|
@@ -593,7 +617,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
593
617
|
}));
|
|
594
618
|
e && h?.("workflowRuns", {
|
|
595
619
|
op: "update",
|
|
596
|
-
row:
|
|
620
|
+
row: J(e)
|
|
597
621
|
}), yield* u.promise(() => p.recordEvent({
|
|
598
622
|
runId: w,
|
|
599
623
|
eventType: "run-failed",
|
|
@@ -609,17 +633,17 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
609
633
|
durationMs: Date.now() - b
|
|
610
634
|
})), yield* u.failCause(e);
|
|
611
635
|
}
|
|
612
|
-
let
|
|
636
|
+
let P = N.exit.value;
|
|
613
637
|
return w && (yield* T("failed to record workflow success", u.gen(function* () {
|
|
614
638
|
let e = yield* u.promise(() => i.store.update("_voltro_workflow_runs", w, {
|
|
615
639
|
status: "succeeded",
|
|
616
|
-
output:
|
|
640
|
+
output: q(P, o),
|
|
617
641
|
completedAt: /* @__PURE__ */ new Date(),
|
|
618
642
|
durationMs: Date.now() - b
|
|
619
643
|
}));
|
|
620
644
|
e && h?.("workflowRuns", {
|
|
621
645
|
op: "update",
|
|
622
|
-
row:
|
|
646
|
+
row: J(e)
|
|
623
647
|
}), yield* u.promise(() => p.recordEvent({
|
|
624
648
|
runId: w,
|
|
625
649
|
eventType: "run-succeeded",
|
|
@@ -630,9 +654,9 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
630
654
|
status: "succeeded",
|
|
631
655
|
durationMs: Date.now() - b,
|
|
632
656
|
completedAtSec: Date.now() / 1e3
|
|
633
|
-
})),
|
|
657
|
+
})), P;
|
|
634
658
|
});
|
|
635
|
-
},
|
|
659
|
+
}, X = (e) => e === "cancel" || e === "terminate", le = (e) => e === "running" || e === "suspended", ue = async (e) => {
|
|
636
660
|
let t = await e.store.query({
|
|
637
661
|
table: "_voltro_workflow_runs",
|
|
638
662
|
order: [{
|
|
@@ -658,7 +682,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
658
682
|
});
|
|
659
683
|
continue;
|
|
660
684
|
}
|
|
661
|
-
if (!
|
|
685
|
+
if (!X(r.parentClosePolicy)) {
|
|
662
686
|
n.push({
|
|
663
687
|
...t,
|
|
664
688
|
action: "skipped",
|
|
@@ -683,7 +707,7 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
683
707
|
});
|
|
684
708
|
i && e.emit?.("workflowRuns", {
|
|
685
709
|
op: "update",
|
|
686
|
-
row:
|
|
710
|
+
row: J(i)
|
|
687
711
|
}), await e.recorder?.recordEvent({
|
|
688
712
|
runId: r.id,
|
|
689
713
|
eventType: "run-cancelled",
|
|
@@ -759,9 +783,9 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
759
783
|
}
|
|
760
784
|
return typeof e == "object" ? e : null;
|
|
761
785
|
}, pe = async (e, t) => {
|
|
762
|
-
let n = S(
|
|
786
|
+
let n = S(k), r = (await t.query(n.where(x(_("id", e), _("executionId", e))).limit(1).descriptor))[0];
|
|
763
787
|
if (r === void 0) return null;
|
|
764
|
-
let i = String(r.id), a = S(
|
|
788
|
+
let i = String(r.id), a = S(A), o = await t.query(a.where(_("runId", i)).descriptor);
|
|
765
789
|
return {
|
|
766
790
|
id: i,
|
|
767
791
|
executionId: $(r.executionId) ?? "",
|
|
@@ -827,4 +851,4 @@ var D = c.layerMemory, O = w("_voltro_workflow_runs", {
|
|
|
827
851
|
};
|
|
828
852
|
};
|
|
829
853
|
//#endregion
|
|
830
|
-
export {
|
|
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 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/workflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "Durable workflows for Voltro — the workflow() descriptor + step() / awaitSignal primitives over @effect/cluster, with a browser-safe define subpath.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"@effect/cluster": "^0.60.0",
|
|
51
51
|
"@effect/sql": "^0.52.0",
|
|
52
52
|
"@effect/workflow": "^0.19.0",
|
|
53
|
-
"@voltro/database": "0.
|
|
54
|
-
"@voltro/protocol": "0.
|
|
53
|
+
"@voltro/database": "0.27.0",
|
|
54
|
+
"@voltro/protocol": "0.27.0"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"effect": "^3.22.0",
|
package/dist/cluster-DuFweKq0.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { Duration as e, Effect as t, Layer as n, Option as r } from "effect";
|
|
2
|
-
import { ClusterCron as i, ClusterWorkflowEngine as a, RunnerAddress as o, SingleRunner as s } from "@effect/cluster";
|
|
3
|
-
import { SqlClient as c } from "@effect/sql";
|
|
4
|
-
//#region src/clusterLayer.ts
|
|
5
|
-
var l = 34e3, u = (e) => {
|
|
6
|
-
let t = e.runnerListenHost ?? process.env.POD_IP ?? process.env.VOLTRO_WORKFLOW_RUNNER_HOST ?? "localhost";
|
|
7
|
-
return {
|
|
8
|
-
host: t,
|
|
9
|
-
port: e.runnerListenPort ?? 34e3,
|
|
10
|
-
localhostRisk: e.runnerStorage === "sql" && (t === "localhost" || t === "127.0.0.1")
|
|
11
|
-
};
|
|
12
|
-
}, d = (e) => {
|
|
13
|
-
let t = e.sqliteFamily ? "memory" : "sql", n = e.override ?? process.env.VOLTRO_WORKFLOW_RUNNER_STORAGE;
|
|
14
|
-
if (n === void 0 || n.trim() === "") return t;
|
|
15
|
-
let r = n.trim().toLowerCase();
|
|
16
|
-
if (r !== "memory" && r !== "sql") throw Error(`VOLTRO_WORKFLOW_RUNNER_STORAGE must be 'memory' or 'sql', got '${n}'.`);
|
|
17
|
-
if (r === "sql" && e.sqliteFamily) throw Error("VOLTRO_WORKFLOW_RUNNER_STORAGE='sql' is unsupported on sqlite / turso — @effect/cluster has no sqlite advisory-lock branch. Use 'memory'.");
|
|
18
|
-
return r;
|
|
19
|
-
}, f = (e = process.env.VOLTRO_WORKFLOW_SHARD_LOCK) => {
|
|
20
|
-
if (e === void 0 || e.trim() === "") return "auto";
|
|
21
|
-
let t = e.trim().toLowerCase();
|
|
22
|
-
if (t === "auto" || t === "row" || t === "advisory") return t;
|
|
23
|
-
throw Error(`VOLTRO_WORKFLOW_SHARD_LOCK must be 'auto', 'row', or 'advisory', got '${e}'.`);
|
|
24
|
-
}, p = t.gen(function* () {
|
|
25
|
-
let e = yield* (yield* c.SqlClient)`SELECT @@wsrep_on AS wsrep`.pipe(t.catchAll(() => t.succeed([])));
|
|
26
|
-
if (e.length === 0) return !1;
|
|
27
|
-
let n = e[0].wsrep;
|
|
28
|
-
return n === 1 || n === "1" || n === !0 || n === "ON" || n === "on";
|
|
29
|
-
}), m = (e) => t.gen(function* () {
|
|
30
|
-
return e.runnerStorage === "memory" ? !1 : e.mode === "row" ? !0 : e.mode === "advisory" || e.dialectId !== "mysql" && e.dialectId !== "mariadb" ? !1 : yield* p;
|
|
31
|
-
}), h = (e) => {
|
|
32
|
-
let i = u({
|
|
33
|
-
runnerStorage: e.runnerStorage,
|
|
34
|
-
runnerListenHost: e.runnerListenHost,
|
|
35
|
-
runnerListenPort: e.runnerListenPort
|
|
36
|
-
}), c = i.host, l = i.port;
|
|
37
|
-
i.localhostRisk && process.stderr.write(`[voltro:workflow] runner host is '${c}' with SQL cluster storage — other pods cannot reach this runner, so a workflow cannot resume on another pod after a reschedule. Inject POD_IP via the K8s downward API (fieldRef: status.podIP) or set runnerListenHost / VOLTRO_WORKFLOW_RUNNER_HOST.
|
|
38
|
-
`);
|
|
39
|
-
let d = e.shardLockMode ?? f(), p = n.unwrapEffect(m({
|
|
40
|
-
dialectId: e.dialectId,
|
|
41
|
-
runnerStorage: e.runnerStorage,
|
|
42
|
-
mode: d
|
|
43
|
-
}).pipe(t.map((t) => (e.runnerStorage === "sql" && process.stderr.write(`[voltro:workflow] shard-lock coordination: ${t ? "row-based" : "advisory"} (dialect=${e.dialectId ?? "unknown"}, mode=${d}` + (t && d === "auto" ? ", wsrep/Galera cluster detected" : "") + ")\n"), s.layer({
|
|
44
|
-
runnerStorage: e.runnerStorage,
|
|
45
|
-
shardingConfig: {
|
|
46
|
-
runnerListenAddress: r.some(o.make(c, l)),
|
|
47
|
-
...t ? { shardLockDisableAdvisory: !0 } : {}
|
|
48
|
-
}
|
|
49
|
-
}))))).pipe(n.provide(e.sqlClientLayer)), h = e.extraShardingLayers ?? [];
|
|
50
|
-
return (h.length === 0 ? a.layer : n.mergeAll(a.layer, ...h)).pipe(n.provide(p));
|
|
51
|
-
}, g = (n) => i.make({
|
|
52
|
-
name: n.name,
|
|
53
|
-
cron: n.cron,
|
|
54
|
-
execute: t.promise(() => n.execute()),
|
|
55
|
-
skipIfOlderThan: n.skipIfOlderThan ?? e.days(1)
|
|
56
|
-
});
|
|
57
|
-
//#endregion
|
|
58
|
-
export { u as a, h as c, f as i, l as n, d as o, p as r, m as s, g as t };
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { Activity as e, Activity as t, DurableClock as n, DurableClock as r, DurableQueue as i, DurableQueue as a, DurableRateLimiter as o, DurableRateLimiter as s, Workflow as c, Workflow as l } from "@effect/workflow";
|
|
2
|
-
import { Cause as u, Context as d, Duration as f, Effect as p, FiberRef as m } from "effect";
|
|
3
|
-
//#region src/recorder.ts
|
|
4
|
-
var h = class extends d.Tag("@voltro/WorkflowRunRecorder")() {}, g = m.unsafeMake(void 0), _ = m.unsafeMake(void 0), v = m.unsafeMake(void 0), y = () => m.get(g), b = () => m.get(_), x = class extends d.Tag("@voltro/WorkflowStepInterceptor")() {}, S = Symbol.for("voltro.workflow.workerLayer"), C = Symbol.for("voltro.workflow.version"), w = "__voltroWorkflowMessages", T = (e) => typeof e == "object" && !!e && e[S] === !0, E = (e) => typeof e == "object" && e && e[C] !== void 0 ? e[C] : {
|
|
5
|
-
version: "1",
|
|
6
|
-
compatibleWith: ["1"],
|
|
7
|
-
patches: []
|
|
8
|
-
}, D = ((e) => {
|
|
9
|
-
let t = c.make(e), n = String(e.version ?? "1"), r = {
|
|
10
|
-
version: n,
|
|
11
|
-
compatibleWith: (e.compatibleWith ?? [n]).map(String),
|
|
12
|
-
patches: [...e.patches ?? []]
|
|
13
|
-
}, i = {
|
|
14
|
-
signals: { ...e.messages?.signals ?? {} },
|
|
15
|
-
updates: { ...e.messages?.updates ?? {} },
|
|
16
|
-
queries: { ...e.messages?.queries ?? {} }
|
|
17
|
-
};
|
|
18
|
-
return Object.defineProperty(t, C, {
|
|
19
|
-
value: r,
|
|
20
|
-
enumerable: !1
|
|
21
|
-
}), Object.defineProperty(t, w, {
|
|
22
|
-
value: i,
|
|
23
|
-
enumerable: !1
|
|
24
|
-
}), t;
|
|
25
|
-
}), O = i.make, k = i.process, A = ((...e) => {
|
|
26
|
-
let t = i.worker(...e);
|
|
27
|
-
return Object.defineProperty(t, S, {
|
|
28
|
-
value: !0,
|
|
29
|
-
enumerable: !1
|
|
30
|
-
}), t;
|
|
31
|
-
}), j = o.rateLimit, M = (e) => p.gen(function* () {
|
|
32
|
-
let t = yield* g, r = yield* p.serviceOption(h), i = f.toMillis(f.decode(e.duration));
|
|
33
|
-
if (t !== void 0 && r._tag === "Some") {
|
|
34
|
-
let a = r.value, o = new Date(Date.now() + i).toISOString(), s = yield* v;
|
|
35
|
-
yield* p.promise(() => a.recordEvent({
|
|
36
|
-
runId: t,
|
|
37
|
-
eventType: "timer-set",
|
|
38
|
-
payload: {
|
|
39
|
-
name: e.name,
|
|
40
|
-
durationMs: i,
|
|
41
|
-
scheduledWakeAt: o,
|
|
42
|
-
...s === void 0 ? {} : { tenantId: s }
|
|
43
|
-
}
|
|
44
|
-
}).catch(() => {}));
|
|
45
|
-
let c = Date.now();
|
|
46
|
-
yield* n.sleep(e), yield* p.promise(() => a.recordEvent({
|
|
47
|
-
runId: t,
|
|
48
|
-
eventType: "timer-fired",
|
|
49
|
-
payload: {
|
|
50
|
-
name: e.name,
|
|
51
|
-
actualDurationMs: Date.now() - c,
|
|
52
|
-
...s === void 0 ? {} : { tenantId: s }
|
|
53
|
-
}
|
|
54
|
-
}).catch(() => {}));
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
yield* n.sleep(e);
|
|
58
|
-
}), N = (t, n, r, i) => p.gen(function* () {
|
|
59
|
-
let a = yield* g, o = yield* e.CurrentAttempt, s = yield* p.serviceOption(h), c = yield* p.serviceOption(x), l = c._tag === "Some" ? c.value.interceptor(n, {
|
|
60
|
-
runId: a ?? "unrecorded",
|
|
61
|
-
stepName: t,
|
|
62
|
-
attempt: o
|
|
63
|
-
}) : n, d, f;
|
|
64
|
-
if (a !== void 0 && s._tag === "Some") {
|
|
65
|
-
f = s.value;
|
|
66
|
-
try {
|
|
67
|
-
d = yield* p.promise(() => f.startStep({
|
|
68
|
-
runId: a,
|
|
69
|
-
stepName: t,
|
|
70
|
-
attempt: o,
|
|
71
|
-
stepInput: r,
|
|
72
|
-
...i === void 0 ? {} : { retryPolicy: i }
|
|
73
|
-
}));
|
|
74
|
-
} catch {
|
|
75
|
-
d = void 0;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
let m = Date.now();
|
|
79
|
-
return yield* l.pipe(p.tap((e) => d && f ? p.promise(async () => {
|
|
80
|
-
try {
|
|
81
|
-
await f.endStepSuccess({
|
|
82
|
-
stepRecordId: d,
|
|
83
|
-
output: e,
|
|
84
|
-
durationMs: Date.now() - m
|
|
85
|
-
});
|
|
86
|
-
} catch {}
|
|
87
|
-
}) : p.void), p.tapErrorCause((e) => d && f && !u.isInterruptedOnly(e) ? p.promise(async () => {
|
|
88
|
-
try {
|
|
89
|
-
let t = u.failureOption(e), n = Array.from(u.failures(e)), r = Array.from(u.defects(e)), i = t._tag === "Some" ? t.value : r[0] ?? u.squash(e), a = i?.message ?? String(i), o = i && typeof i == "object" && "_tag" in i ? String(i._tag) : null;
|
|
90
|
-
await f.endStepFailure({
|
|
91
|
-
stepRecordId: d,
|
|
92
|
-
errorTag: o,
|
|
93
|
-
errorMessage: a,
|
|
94
|
-
errorCause: {
|
|
95
|
-
pretty: u.pretty(e),
|
|
96
|
-
failures: n,
|
|
97
|
-
defects: r
|
|
98
|
-
},
|
|
99
|
-
durationMs: Date.now() - m
|
|
100
|
-
});
|
|
101
|
-
} catch {}
|
|
102
|
-
}) : p.void));
|
|
103
|
-
}), P = (t) => {
|
|
104
|
-
let { input: n, retry: r, ...i } = t;
|
|
105
|
-
return e.make({
|
|
106
|
-
...i,
|
|
107
|
-
execute: N(i.name, i.execute, n, r)
|
|
108
|
-
});
|
|
109
|
-
}, F = c.withCompensation, I = e.idempotencyKey;
|
|
110
|
-
//#endregion
|
|
111
|
-
export { h as C, y as E, v as S, b as T, F as _, O as a, _ as b, E as c, A as d, j as f, t as g, I as h, r as i, T as l, P as m, C as n, a as o, M as p, S as r, s, w as t, k as u, D as v, x as w, g as x, l as y };
|