@voltro/workflow 0.84.0 → 0.85.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 +549 -0
- package/THIRD-PARTY-NOTICES.md +1 -119
- package/dist/cluster-F_bhqVP7.js +679 -0
- package/dist/cluster.d.ts +304 -280
- package/dist/cluster.js +2 -2
- package/dist/clusterTestSuite.d.ts +11 -11
- package/dist/clusterTestSuite.js +256 -256
- package/dist/index.d.ts +376 -354
- package/dist/index.js +5 -5
- package/dist/journalEncryption-DTyhUzaS.js +154 -0
- package/dist/{primitives-Btjhjm8P.js → primitives-DX04WTWh.js} +223 -199
- package/dist/primitives.d.ts +56 -31
- package/dist/primitives.js +2 -2
- package/dist/{src-DP-lKqaG.js → src-C2NEyUM8.js} +1111 -1053
- package/dist/{clusterDiagnostics-CGUtnJkX.js → workflowReadSelections-CZAUjP7f.js} +58 -46
- package/package.json +6 -9
- package/dist/cluster-i3frC3Da.js +0 -646
- package/dist/journalEncryption--n5VDdYO.js +0 -148
|
@@ -1,55 +1,56 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Activity as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { O as e, T as t, d as n, f as r, p as i, s as a, t as o, w as s, y as c } from "./journalEncryption-DTyhUzaS.js";
|
|
2
|
+
import { Activity as l, Activity as u, DurableClock as d, DurableClock as f, DurableQueue as p, DurableQueue as m, Workflow as h, Workflow as ee, WorkflowEngine as te } from "effect/workflow";
|
|
3
|
+
import { RateLimiter as g } from "effect/persistence";
|
|
4
|
+
import { Cause as _, Context as v, Cron as ne, Duration as y, Effect as b, Effectable as re, Exit as x, Option as ie, Result as ae, Schedule as S, Schema as C } from "effect";
|
|
5
|
+
import { attachWorkflowAccess as oe, resolveWorkflowAccess as se } from "@voltro/protocol";
|
|
5
6
|
//#region src/preparedExecution.ts
|
|
6
|
-
var
|
|
7
|
-
Object.defineProperty(e,
|
|
7
|
+
var w = Symbol.for("@voltro/workflow/PreparedExecution"), T = (e, t) => {
|
|
8
|
+
Object.defineProperty(e, w, {
|
|
8
9
|
value: t,
|
|
9
10
|
enumerable: !0
|
|
10
11
|
});
|
|
11
|
-
},
|
|
12
|
-
if (n.length === 0) return
|
|
13
|
-
let i = e[
|
|
14
|
-
return typeof i == "function" ? i(t, n, r?.discard ?? !0) :
|
|
15
|
-
}),
|
|
12
|
+
}, ce = (e) => (typeof e == "object" || typeof e == "function") && e !== null && typeof e[w] == "function", le = (e, t, n, r) => b.suspend(() => {
|
|
13
|
+
if (n.length === 0) return b.die(/* @__PURE__ */ Error("Prepared workflow execution requires a non-empty identity"));
|
|
14
|
+
let i = e[w];
|
|
15
|
+
return typeof i == "function" ? i(t, n, r?.discard ?? !0) : b.die(/* @__PURE__ */ Error("Workflow definition has no prepared-execution capability"));
|
|
16
|
+
}), ue = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0 || e.concurrency !== void 0 || e.throttle !== void 0 || e.rateLimit !== void 0 || e.batch !== void 0 || e.timeouts?.startMs !== void 0 || e.timeouts?.finishMs !== void 0), de = (e) => e?.cancelOn !== void 0 && e.cancelOn.length > 0, fe = [
|
|
16
17
|
"debounce",
|
|
17
18
|
"batch",
|
|
18
19
|
"throttle",
|
|
19
20
|
"concurrency"
|
|
20
|
-
],
|
|
21
|
+
], E = (e) => {
|
|
21
22
|
if (e === void 0) return [];
|
|
22
23
|
let t = [];
|
|
23
24
|
return e.debounce !== void 0 && t.push("debounce"), e.batch !== void 0 && t.push("batch"), e.throttle !== void 0 && t.push("throttle"), e.concurrency !== void 0 && t.push("concurrency"), t;
|
|
24
|
-
},
|
|
25
|
+
}, D = (e, t, n) => {
|
|
25
26
|
let r;
|
|
26
27
|
try {
|
|
27
|
-
r =
|
|
28
|
+
r = y.toMillis(y.fromInputUnsafe(e));
|
|
28
29
|
} catch {
|
|
29
30
|
throw Error(`workflow '${n}': ${t} is not a duration Effect can read (got ${JSON.stringify(e)}). Use a spelled-out unit ('15 minutes', '1 hour', '30 seconds'), a number of milliseconds, or a Duration — the abbreviated forms ('15m', '1h') are NOT accepted.`);
|
|
30
31
|
}
|
|
31
32
|
if (!Number.isFinite(r) || r <= 0) throw Error(`workflow '${n}': ${t} must be a positive finite duration, got ${String(e)}`);
|
|
32
33
|
return r;
|
|
33
|
-
},
|
|
34
|
+
}, O = (e, t, n) => {
|
|
34
35
|
if (!Number.isInteger(e) || e <= 0) throw Error(`workflow '${n}': ${t} must be a positive integer, got ${String(e)}`);
|
|
35
36
|
return e;
|
|
36
|
-
},
|
|
37
|
+
}, k = (e, t, n) => {
|
|
37
38
|
if (typeof e != "function") throw Error(`workflow '${n}': ${t} must be a function of the payload`);
|
|
38
39
|
return e;
|
|
39
|
-
},
|
|
40
|
+
}, pe = (e) => {
|
|
40
41
|
let t = e?.ast?.propertySignatures;
|
|
41
42
|
if (!Array.isArray(t)) return !1;
|
|
42
43
|
let n = t.find((e) => e.name === "items");
|
|
43
|
-
return n !== void 0 && n.type?._tag === "
|
|
44
|
-
},
|
|
45
|
-
let { workflowName: n, control: r } =
|
|
44
|
+
return n !== void 0 && n.type?._tag === "Arrays";
|
|
45
|
+
}, A = (e) => {
|
|
46
|
+
let { workflowName: n, control: r } = e;
|
|
46
47
|
if (r === void 0) return;
|
|
47
48
|
let i = { workflowName: n };
|
|
48
49
|
if (r.debounce !== void 0) {
|
|
49
|
-
let e = r.debounce, t =
|
|
50
|
+
let e = r.debounce, t = D(e.period, "debounce.period", n), a = e.timeout === void 0 ? void 0 : D(e.timeout, "debounce.timeout", n);
|
|
50
51
|
if (a !== void 0 && a < t) throw Error(`workflow '${n}': debounce.timeout (${a}ms) is shorter than debounce.period (${t}ms), so the burst can never be collapsed — the run would be admitted before the quiet period could ever elapse. Raise the timeout or lower the period.`);
|
|
51
52
|
i.debounce = {
|
|
52
|
-
key:
|
|
53
|
+
key: k(e.key, "debounce.key", n),
|
|
53
54
|
periodMs: t,
|
|
54
55
|
...a === void 0 ? {} : { timeoutMs: a }
|
|
55
56
|
};
|
|
@@ -58,7 +59,7 @@ var T = Symbol.for("@voltro/workflow/PreparedExecution"), E = (e, t) => {
|
|
|
58
59
|
let e = r.singleton;
|
|
59
60
|
if (e.mode !== "skip" && e.mode !== "cancel") throw Error(`workflow '${n}': singleton.mode must be 'skip' or 'cancel'. There is no default — 'skip' discards the incoming request and 'cancel' discards the running one, and choosing for you would silently throw away work either way.`);
|
|
60
61
|
i.singleton = {
|
|
61
|
-
key:
|
|
62
|
+
key: k(e.key, "singleton.key", n),
|
|
62
63
|
mode: e.mode
|
|
63
64
|
};
|
|
64
65
|
}
|
|
@@ -66,35 +67,35 @@ var T = Symbol.for("@voltro/workflow/PreparedExecution"), E = (e, t) => {
|
|
|
66
67
|
let e = r.concurrency;
|
|
67
68
|
if (e.pool !== void 0 && (typeof e.pool != "string" || e.pool.trim() === "")) throw Error(`workflow '${n}': concurrency.pool must be a non-empty name — it is the identity other workflows declare to share this budget, and an empty one would silently merge every empty-named pool in the deployment into one.`);
|
|
68
69
|
i.concurrency = {
|
|
69
|
-
limit:
|
|
70
|
-
...e.key === void 0 ? {} : { key:
|
|
70
|
+
limit: O(e.limit, "concurrency.limit", n),
|
|
71
|
+
...e.key === void 0 ? {} : { key: k(e.key, "concurrency.key", n) },
|
|
71
72
|
...e.pool === void 0 ? {} : { pool: e.pool.trim() }
|
|
72
73
|
};
|
|
73
74
|
}
|
|
74
75
|
if (r.throttle !== void 0) {
|
|
75
76
|
let e = r.throttle;
|
|
76
77
|
i.throttle = {
|
|
77
|
-
limit:
|
|
78
|
-
periodMs:
|
|
79
|
-
...e.key === void 0 ? {} : { key:
|
|
78
|
+
limit: O(e.limit, "throttle.limit", n),
|
|
79
|
+
periodMs: D(e.period, "throttle.period", n),
|
|
80
|
+
...e.key === void 0 ? {} : { key: k(e.key, "throttle.key", n) }
|
|
80
81
|
};
|
|
81
82
|
}
|
|
82
83
|
if (r.rateLimit !== void 0) {
|
|
83
84
|
let e = r.rateLimit;
|
|
84
85
|
i.rateLimit = {
|
|
85
|
-
limit:
|
|
86
|
-
periodMs:
|
|
87
|
-
...e.key === void 0 ? {} : { key:
|
|
86
|
+
limit: O(e.limit, "rateLimit.limit", n),
|
|
87
|
+
periodMs: D(e.period, "rateLimit.period", n),
|
|
88
|
+
...e.key === void 0 ? {} : { key: k(e.key, "rateLimit.key", n) }
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
91
|
if (r.batch !== void 0) {
|
|
91
92
|
let a = r.batch;
|
|
92
|
-
if (
|
|
93
|
+
if (e.payloadSchema !== void 0 && !pe(e.payloadSchema)) throw Error(`workflow '${n}': batch is declared, so the workflow's own \`payload\` must be the BATCH shape — \`Schema.Struct({ items: Schema.Array(Item) })\` — while callers start it with a SINGLE item. Declare the item's schema as \`batch.item\`. Checked here rather than at admission because a decode failure on the batching replica is a failure nobody is watching.`);
|
|
93
94
|
i.batch = {
|
|
94
|
-
...a.key === void 0 ? {} : { key:
|
|
95
|
-
maxSize:
|
|
96
|
-
timeoutMs:
|
|
97
|
-
...a.item === void 0 ? {} : { item: r.encrypted === !0 && C.isSchema(a.item) ?
|
|
95
|
+
...a.key === void 0 ? {} : { key: k(a.key, "batch.key", n) },
|
|
96
|
+
maxSize: O(a.maxSize, "batch.maxSize", n),
|
|
97
|
+
timeoutMs: D(a.timeout, "batch.timeout", n),
|
|
98
|
+
...a.item === void 0 ? {} : { item: r.encrypted === !0 && C.isSchema(a.item) ? t(a.item, `workflow '${n}' batch item`) : a.item }
|
|
98
99
|
};
|
|
99
100
|
}
|
|
100
101
|
if (r.priority !== void 0) {
|
|
@@ -102,7 +103,7 @@ var T = Symbol.for("@voltro/workflow/PreparedExecution"), E = (e, t) => {
|
|
|
102
103
|
i.priority = r.priority;
|
|
103
104
|
}
|
|
104
105
|
if (r.timeouts !== void 0) {
|
|
105
|
-
let e = r.timeouts, t = e.start === void 0 ? void 0 :
|
|
106
|
+
let e = r.timeouts, t = e.start === void 0 ? void 0 : D(e.start, "timeouts.start", n), a = e.finish === void 0 ? void 0 : D(e.finish, "timeouts.finish", n);
|
|
106
107
|
(t !== void 0 || a !== void 0) && (i.timeouts = {
|
|
107
108
|
...t === void 0 ? {} : { startMs: t },
|
|
108
109
|
...a === void 0 ? {} : { finishMs: a }
|
|
@@ -122,7 +123,7 @@ var T = Symbol.for("@voltro/workflow/PreparedExecution"), E = (e, t) => {
|
|
|
122
123
|
if (typeof e?.event != "string" || e.event.length === 0) throw Error(`workflow '${n}': ${r}.event must be a non-empty event name, exactly as ctx.events.publish writes it.`);
|
|
123
124
|
if (e.schema === void 0 || typeof e.schema.ast != "object") throw Error(`workflow '${n}': ${r}.schema must be a Schema for the event payload. It is decoded before \`match\` runs, so the predicate reads the domain type rather than raw JSON.`);
|
|
124
125
|
if (typeof e.match != "function") throw Error(`workflow '${n}': ${r}.match is required. Omitting it would mean "cancel every live run of this workflow whenever '${e.event}' is published" — write \`match: () => true\` if that is what you mean, so it is visible in review.`);
|
|
125
|
-
let i = e.within === void 0 ? void 0 :
|
|
126
|
+
let i = e.within === void 0 ? void 0 : D(e.within, `${r}.within`, n);
|
|
126
127
|
return {
|
|
127
128
|
event: e.event,
|
|
128
129
|
schema: e.schema,
|
|
@@ -133,9 +134,9 @@ var T = Symbol.for("@voltro/workflow/PreparedExecution"), E = (e, t) => {
|
|
|
133
134
|
});
|
|
134
135
|
e.length > 0 && (i.cancelOn = e);
|
|
135
136
|
}
|
|
136
|
-
if (i.timeouts?.startMs !== void 0 &&
|
|
137
|
+
if (i.timeouts?.startMs !== void 0 && E(i).length === 0) throw Error(`workflow '${n}': timeouts.start bounds how long a run may sit in the ADMISSION queue, but this workflow declares no control that can defer one (debounce, batch, throttle, concurrency). It would never fire. Use timeouts.finish to bound the run itself.`);
|
|
137
138
|
return i;
|
|
138
|
-
},
|
|
139
|
+
}, me = (e) => {
|
|
139
140
|
let t = /* @__PURE__ */ new Map();
|
|
140
141
|
for (let n of e) {
|
|
141
142
|
let e = n?.concurrency;
|
|
@@ -148,31 +149,31 @@ var T = Symbol.for("@voltro/workflow/PreparedExecution"), E = (e, t) => {
|
|
|
148
149
|
else if (r.limit !== e.limit) throw Error(`concurrency pool '${e.pool}': '${n.workflowName}' declares limit ${e.limit}, but ${r.workflows.map((e) => `'${e}'`).join(", ")} declare${r.workflows.length === 1 ? "s" : ""} limit ${r.limit}. A pool is ONE budget — every member must declare the same number, or the enforced limit would depend on which workflow's start arrived first. Align the limits, or give the workflows different pool names if they were never meant to share.`);
|
|
149
150
|
else r.workflows.push(n.workflowName);
|
|
150
151
|
}
|
|
151
|
-
},
|
|
152
|
-
let e = yield*
|
|
152
|
+
}, j = class extends v.Service()("@voltro/WorkflowRunRecorder") {}, M = v.Reference("@voltro/workflow/CurrentWorkflowRunId", { defaultValue: () => void 0 }), N = v.Reference("@voltro/workflow/CurrentWorkflowExecutionId", { defaultValue: () => void 0 }), P = v.Reference("@voltro/workflow/CurrentWorkflowStep", { defaultValue: () => void 0 }), he = b.gen(function* () {
|
|
153
|
+
let e = yield* N, t = yield* P;
|
|
153
154
|
return e === void 0 || t === void 0 ? void 0 : {
|
|
154
155
|
executionId: e,
|
|
155
156
|
step: t
|
|
156
157
|
};
|
|
157
|
-
}),
|
|
158
|
+
}), ge = v.Reference("@voltro/workflow/CurrentWorkflowGeneration", { defaultValue: () => void 0 }), F = v.Reference("@voltro/workflow/CurrentWorkflowWakeTenant", { defaultValue: () => void 0 }), I = v.Reference("@voltro/workflow/CurrentWorkflowPatches", { defaultValue: () => [] }), L = () => M, _e = () => N, R = class extends v.Service()("@voltro/WorkflowStepInterceptor") {}, z = 864e5, ve = /* @__PURE__ */ new Set([
|
|
158
159
|
"skip",
|
|
159
160
|
"buffer",
|
|
160
161
|
"cancelOther"
|
|
161
|
-
]),
|
|
162
|
+
]), ye = /* @__PURE__ */ new Set([
|
|
162
163
|
"skip",
|
|
163
164
|
"latest",
|
|
164
165
|
"all"
|
|
165
|
-
]),
|
|
166
|
+
]), B = (e, t) => {
|
|
166
167
|
if (t === void 0) return;
|
|
167
168
|
if (typeof t.timezone != "string" || t.timezone.trim() === "") throw Error(`workflow '${e}': schedule.timezone is required (e.g. "UTC", "Europe/Berlin") — never server-local, which differs between your machine and the container.`);
|
|
168
|
-
let n =
|
|
169
|
-
if (
|
|
169
|
+
let n = ne.parse(t.cron, t.timezone);
|
|
170
|
+
if (ae.isFailure(n)) throw Error(`workflow '${e}': schedule.cron "${t.cron}" (tz="${t.timezone}") is not a valid cron expression — ${String(n.failure)}`);
|
|
170
171
|
let r = t.onOverlap ?? "skip";
|
|
171
|
-
if (!
|
|
172
|
+
if (!ve.has(r)) throw Error(`workflow '${e}': schedule.onOverlap must be 'skip' | 'buffer' | 'cancelOther', got ${JSON.stringify(r)}`);
|
|
172
173
|
let i = t.backfill ?? "skip";
|
|
173
|
-
if (!
|
|
174
|
-
let a =
|
|
175
|
-
return t.maxRuntime !== void 0 && (a =
|
|
174
|
+
if (!ye.has(i)) throw Error(`workflow '${e}': schedule.backfill must be 'skip' | 'latest' | 'all', got ${JSON.stringify(i)}`);
|
|
175
|
+
let a = z;
|
|
176
|
+
return t.maxRuntime !== void 0 && (a = be(t.maxRuntime, e)), {
|
|
176
177
|
cron: t.cron,
|
|
177
178
|
timezone: t.timezone,
|
|
178
179
|
...t.payload === void 0 ? {} : { payload: t.payload },
|
|
@@ -180,20 +181,20 @@ var T = Symbol.for("@voltro/workflow/PreparedExecution"), E = (e, t) => {
|
|
|
180
181
|
backfill: i,
|
|
181
182
|
maxRuntimeMs: a
|
|
182
183
|
};
|
|
183
|
-
},
|
|
184
|
+
}, be = (e, t) => {
|
|
184
185
|
let n;
|
|
185
186
|
try {
|
|
186
|
-
n =
|
|
187
|
+
n = y.toMillis(y.fromInputUnsafe(e));
|
|
187
188
|
} catch {
|
|
188
189
|
throw Error(`workflow '${t}': schedule.maxRuntime is not a duration Effect can read (got ${JSON.stringify(e)}). Use '2 hours', a number of milliseconds, or a Duration.`);
|
|
189
190
|
}
|
|
190
191
|
if (!Number.isFinite(n) || n <= 0) throw Error(`workflow '${t}': schedule.maxRuntime must be a positive finite duration`);
|
|
191
192
|
return n;
|
|
192
|
-
},
|
|
193
|
-
if (typeof e != "object" ||
|
|
194
|
-
let t = e[
|
|
193
|
+
}, V = "__voltroWorkflowSchedule", xe = (e) => {
|
|
194
|
+
if (typeof e != "object" && typeof e != "function" || e === null) return;
|
|
195
|
+
let t = e[V];
|
|
195
196
|
return t === void 0 ? void 0 : t;
|
|
196
|
-
},
|
|
197
|
+
}, Se = (e) => {
|
|
197
198
|
let t = /* @__PURE__ */ new Map();
|
|
198
199
|
for (let n of e) t.set(n.stepName, (t.get(n.stepName) ?? 0) + 1);
|
|
199
200
|
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set(), i = (e) => !r.has(e) && (r.add(e), !0);
|
|
@@ -222,158 +223,178 @@ var T = Symbol.for("@voltro/workflow/PreparedExecution"), E = (e, t) => {
|
|
|
222
223
|
return e;
|
|
223
224
|
}
|
|
224
225
|
};
|
|
225
|
-
},
|
|
226
|
+
}, H = v.Reference("@voltro/workflow/CurrentWorkflowReplayShape", { defaultValue: () => void 0 }), U = (e) => ({
|
|
226
227
|
kind: e.kind,
|
|
227
228
|
stepName: e.stepName,
|
|
228
229
|
recorded: e.recorded,
|
|
229
230
|
reached: e.reached,
|
|
230
231
|
detail: e.detail
|
|
231
|
-
}),
|
|
232
|
+
}), W = (e) => b.gen(function* () {
|
|
232
233
|
if (e.length === 0) return;
|
|
233
|
-
let t = yield*
|
|
234
|
+
let t = yield* M, n = yield* b.serviceOption(j);
|
|
234
235
|
if (t === void 0 || n._tag !== "Some") return;
|
|
235
236
|
let r = n.value;
|
|
236
|
-
for (let n of e) yield*
|
|
237
|
+
for (let n of e) yield* b.promise(() => r.recordEvent({
|
|
237
238
|
runId: t,
|
|
238
239
|
eventType: "nondeterminism-suspected",
|
|
239
|
-
payload:
|
|
240
|
+
payload: U(n)
|
|
240
241
|
}).then(() => void 0).catch(() => void 0));
|
|
241
|
-
}),
|
|
242
|
+
}), Ce = (e) => {
|
|
242
243
|
if (typeof e != "object" || !e) return;
|
|
243
244
|
let t = e.retryAfterMillis;
|
|
244
|
-
if (typeof t == "number" && Number.isFinite(t) && t >= 0) return
|
|
245
|
+
if (typeof t == "number" && Number.isFinite(t) && t >= 0) return y.millis(t);
|
|
245
246
|
let n = e.retryAfter;
|
|
246
|
-
if (typeof n == "number" && Number.isFinite(n) && n >= 0) return
|
|
247
|
-
},
|
|
247
|
+
if (typeof n == "number" && Number.isFinite(n) && n >= 0) return y.seconds(n);
|
|
248
|
+
}, G = (e) => y.fromInputUnsafe(e), we = (e) => typeof e == "object" && e && "_tag" in e ? String(e._tag) : void 0, Te = (e) => e !== void 0 && (e.maxAttempts ?? 3) > 1, Ee = (e) => {
|
|
248
249
|
if (e.retryable) return e.retryable;
|
|
249
250
|
if (e.retryableErrors && e.retryableErrors.length > 0) {
|
|
250
251
|
let t = new Set(e.retryableErrors);
|
|
251
252
|
return (e) => {
|
|
252
|
-
let n =
|
|
253
|
+
let n = we(e);
|
|
253
254
|
return n !== void 0 && t.has(n);
|
|
254
255
|
};
|
|
255
256
|
}
|
|
256
257
|
return () => !0;
|
|
257
|
-
},
|
|
258
|
-
let t = e.baseDelay ?? "200 millis", n = e.strategy ?? "exponential", r = e.maxAttempts ?? 3, i = n === "linear" ? S.
|
|
258
|
+
}, De = (e) => {
|
|
259
|
+
let t = e.baseDelay ?? "200 millis", n = e.strategy ?? "exponential", r = e.maxAttempts ?? 3, i = n === "linear" ? S.modifyDelay(S.spaced(G(e.step ?? t)), (n) => b.succeed(y.times(G(e.step ?? t), n.attempt))) : n === "fixed" ? S.spaced(G(t)) : S.exponential(G(t), e.factor ?? 2);
|
|
259
260
|
if (e.maxDelay !== void 0) {
|
|
260
|
-
let t =
|
|
261
|
-
i = S.modifyDelay(i, (e
|
|
261
|
+
let t = G(e.maxDelay);
|
|
262
|
+
i = S.modifyDelay(i, (e) => b.succeed(y.min(e.duration, t)));
|
|
262
263
|
}
|
|
263
264
|
(e.jitter ?? !0) === !0 && (i = S.jittered(i));
|
|
264
|
-
let a = S.
|
|
265
|
-
return e.maxElapsed !== void 0 && (a = S.upTo(
|
|
266
|
-
},
|
|
267
|
-
let n =
|
|
268
|
-
return e.maxDelay !== void 0 && (i = Math.min(i,
|
|
269
|
-
},
|
|
270
|
-
let i = t.maxAttempts ?? 3, a = t.maxElapsed === void 0 ? Infinity :
|
|
265
|
+
let a = S.max([i, S.recurs(Math.max(0, r - 1))]);
|
|
266
|
+
return e.maxElapsed !== void 0 && (a = S.upTo({ duration: G(e.maxElapsed) })(a)), a;
|
|
267
|
+
}, Oe = (e, t) => {
|
|
268
|
+
let n = y.toMillis(G(e.baseDelay ?? "200 millis")), r = e.strategy ?? "exponential", i = r === "fixed" ? n : r === "linear" ? n + y.toMillis(G(e.step ?? e.baseDelay ?? "200 millis")) * (t - 1) : n * (e.factor ?? 2) ** (t - 1);
|
|
269
|
+
return e.maxDelay !== void 0 && (i = Math.min(i, y.toMillis(G(e.maxDelay)))), (e.jitter ?? !0) === !0 && (i *= Math.random()), i;
|
|
270
|
+
}, ke = (e, t, n, r) => b.gen(function* () {
|
|
271
|
+
let i = t.maxAttempts ?? 3, a = t.maxElapsed === void 0 ? Infinity : y.toMillis(G(t.maxElapsed)), o = yield* b.sync(() => Date.now()), s = 0;
|
|
271
272
|
for (;;) {
|
|
272
|
-
let c = yield*
|
|
273
|
-
if (
|
|
274
|
-
let l = c.cause, u =
|
|
273
|
+
let c = yield* b.exit(e);
|
|
274
|
+
if (x.isSuccess(c)) return c.value;
|
|
275
|
+
let l = c.cause, u = _.findErrorOption(l), d = ie.isSome(u) ? u.value : _.squash(l);
|
|
275
276
|
s += 1;
|
|
276
|
-
let f = (yield*
|
|
277
|
-
if (s >= i || !n(d) || f >= a) return yield*
|
|
277
|
+
let f = (yield* b.sync(() => Date.now())) - o;
|
|
278
|
+
if (s >= i || !n(d) || f >= a) return yield* b.failCause(l);
|
|
278
279
|
r?.(d);
|
|
279
|
-
let p =
|
|
280
|
-
yield*
|
|
280
|
+
let p = Ce(d), m = p === void 0 ? Oe(t, s) : y.toMillis(p);
|
|
281
|
+
yield* b.sleep(y.millis(m));
|
|
281
282
|
}
|
|
282
|
-
}),
|
|
283
|
-
if (!
|
|
284
|
-
let r =
|
|
285
|
-
if (t.respectRetryAfter === !0) return
|
|
286
|
-
let i =
|
|
283
|
+
}), Ae = (e, t, n) => {
|
|
284
|
+
if (!Te(t)) return e;
|
|
285
|
+
let r = Ee(t);
|
|
286
|
+
if (t.respectRetryAfter === !0) return ke(e, t, r, n);
|
|
287
|
+
let i = De(t), a = n ? b.tapError(e, (e) => b.sync(() => {
|
|
287
288
|
r(e) && n(e);
|
|
288
289
|
})) : e;
|
|
289
|
-
return
|
|
290
|
+
return b.retry(a, {
|
|
290
291
|
schedule: i,
|
|
291
292
|
while: r
|
|
292
293
|
});
|
|
293
|
-
},
|
|
294
|
+
}, K = Symbol.for("voltro.workflow.workerLayer"), q = Symbol.for("voltro.workflow.version"), J = "__voltroWorkflowMessages", Y = "__voltroWorkflowFlowControl", je = (e) => typeof e == "object" && !!e && e[K] === !0, X = (e) => (typeof e == "object" || typeof e == "function") && e !== null, Me = (e) => X(e) && e[q] !== void 0 ? e[q] : {
|
|
294
295
|
version: "1",
|
|
295
296
|
compatibleWith: ["1"],
|
|
296
297
|
patches: []
|
|
297
298
|
}, Z = (e) => {
|
|
298
299
|
let t = e, n = `workflow '${e.name}' defect`;
|
|
299
300
|
return Object.assign(Object.create(Object.getPrototypeOf(e)), e, {
|
|
300
|
-
toLayer: (e) => t.toLayer((t, r) =>
|
|
301
|
-
execute: (...e) => t.execute(...e).pipe(
|
|
301
|
+
toLayer: (e) => t.toLayer((t, r) => b.provideService(e(t, r), o, !0).pipe(b.catchDefect((e) => b.die(c(e, n))))),
|
|
302
|
+
execute: (...e) => t.execute(...e).pipe(b.catchDefect((e) => b.die(i(e, n)))),
|
|
302
303
|
annotate: (...e) => Z(t.annotate(...e)),
|
|
303
304
|
annotateContext: (...e) => Z(t.annotateContext(...e))
|
|
304
305
|
});
|
|
305
|
-
},
|
|
306
|
-
let
|
|
307
|
-
...
|
|
308
|
-
payload:
|
|
309
|
-
...
|
|
310
|
-
...
|
|
311
|
-
} :
|
|
312
|
-
|
|
313
|
-
let a =
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
306
|
+
}, Ne = ((e) => {
|
|
307
|
+
let n = e.encrypted === !0, i = h.make(e.name, n ? {
|
|
308
|
+
...e,
|
|
309
|
+
payload: s(e.name, e.payload),
|
|
310
|
+
...e.success === void 0 ? {} : { success: t(e.success, `workflow '${e.name}' result`) },
|
|
311
|
+
...e.error === void 0 ? {} : { error: t(e.error, `workflow '${e.name}' failure`) }
|
|
312
|
+
} : e);
|
|
313
|
+
n && r(e.name);
|
|
314
|
+
let a = e.suspendOnFailure === !0 ? i.annotate(h.SuspendOnFailure, !0) : i, o = n ? Z(a) : a;
|
|
315
|
+
Object.defineProperty(o, "name", {
|
|
316
|
+
value: e.name,
|
|
317
|
+
enumerable: !0
|
|
318
|
+
}), T(o, (t, n, r) => b.gen(function* () {
|
|
319
|
+
let i = o.payloadSchema.make(t), a = yield* te.WorkflowEngine;
|
|
320
|
+
return yield* b.annotateCurrentSpan({ executionId: n }), yield* a.execute(o, {
|
|
317
321
|
executionId: n,
|
|
318
322
|
payload: i,
|
|
319
323
|
discard: r,
|
|
320
|
-
suspendedRetrySchedule:
|
|
324
|
+
suspendedRetrySchedule: e.suspendedRetrySchedule
|
|
321
325
|
});
|
|
322
|
-
}).pipe(
|
|
323
|
-
let c = String(
|
|
326
|
+
}).pipe(b.withSpan(`${e.name}.execute`)));
|
|
327
|
+
let c = String(e.version ?? "1"), l = {
|
|
324
328
|
version: c,
|
|
325
|
-
compatibleWith: (
|
|
326
|
-
patches: [...
|
|
329
|
+
compatibleWith: (e.compatibleWith ?? [c]).map(String),
|
|
330
|
+
patches: [...e.patches ?? []]
|
|
327
331
|
}, u = {
|
|
328
|
-
signals: { ...
|
|
329
|
-
updates: { ...
|
|
332
|
+
signals: { ...e.messages?.signals ?? {} },
|
|
333
|
+
updates: { ...e.messages?.updates ?? {} }
|
|
330
334
|
};
|
|
331
|
-
Object.defineProperty(
|
|
335
|
+
Object.defineProperty(o, q, {
|
|
332
336
|
value: l,
|
|
333
337
|
enumerable: !1
|
|
334
|
-
}), Object.defineProperty(
|
|
338
|
+
}), Object.defineProperty(o, J, {
|
|
335
339
|
value: u,
|
|
336
340
|
enumerable: !1
|
|
337
|
-
}),
|
|
338
|
-
let d =
|
|
339
|
-
workflowName:
|
|
340
|
-
payloadSchema: C.isSchema(
|
|
341
|
-
control:
|
|
341
|
+
}), oe(o, se(e.name, e));
|
|
342
|
+
let d = A({
|
|
343
|
+
workflowName: e.name,
|
|
344
|
+
payloadSchema: C.isSchema(e.payload) ? e.payload : C.Struct(e.payload),
|
|
345
|
+
control: e
|
|
342
346
|
});
|
|
343
|
-
d !== void 0 && Object.defineProperty(
|
|
347
|
+
d !== void 0 && Object.defineProperty(o, Y, {
|
|
344
348
|
value: d,
|
|
345
349
|
enumerable: !1
|
|
346
350
|
});
|
|
347
|
-
let f =
|
|
348
|
-
return f !== void 0 && Object.defineProperty(
|
|
351
|
+
let f = B(e.name, e.schedule);
|
|
352
|
+
return f !== void 0 && Object.defineProperty(o, V, {
|
|
349
353
|
value: f,
|
|
350
354
|
enumerable: !1
|
|
351
|
-
}),
|
|
352
|
-
}),
|
|
353
|
-
if (
|
|
354
|
-
let t = e[
|
|
355
|
+
}), o;
|
|
356
|
+
}), Pe = (e) => {
|
|
357
|
+
if (!X(e)) return;
|
|
358
|
+
let t = e[Y];
|
|
355
359
|
return t === void 0 ? void 0 : t;
|
|
356
|
-
}, Q = (
|
|
357
|
-
if (
|
|
358
|
-
|
|
359
|
-
let r = C.isSchema(
|
|
360
|
-
return
|
|
361
|
-
...
|
|
362
|
-
payload:
|
|
363
|
-
success: e
|
|
364
|
-
error: e
|
|
360
|
+
}, Q = (e) => {
|
|
361
|
+
if (e.encrypted !== !0) return p.make(e);
|
|
362
|
+
n(e.name);
|
|
363
|
+
let r = C.isSchema(e.payload) ? e.payload : C.Struct(e.payload);
|
|
364
|
+
return p.make({
|
|
365
|
+
...e,
|
|
366
|
+
payload: t(r, `queue '${e.name}' payload`),
|
|
367
|
+
success: t(e.success ?? C.Void, `queue '${e.name}' result`),
|
|
368
|
+
error: t(e.error ?? C.Never, `queue '${e.name}' failure`)
|
|
365
369
|
});
|
|
366
|
-
}
|
|
367
|
-
let t =
|
|
368
|
-
return Object.defineProperty(t,
|
|
370
|
+
}, Fe = ((e, ...t) => b.flatMap(o, (n) => n && !a(e.name) ? b.die(/* @__PURE__ */ Error(`an encrypted workflow enqueued into durable queue '${e.name}', which is not encrypted: the queue's journal would hold the value in plaintext. Declare \`durableQueue({ …, encrypted: true })\`.`)) : p.process(e, ...t))), Ie = ((...e) => {
|
|
371
|
+
let t = p.worker(...e);
|
|
372
|
+
return Object.defineProperty(t, K, {
|
|
369
373
|
value: !0,
|
|
370
374
|
enumerable: !1
|
|
371
375
|
}), t;
|
|
372
|
-
}),
|
|
373
|
-
let t = yield*
|
|
376
|
+
}), Le = (e) => b.gen(function* () {
|
|
377
|
+
let t = yield* l.make({
|
|
378
|
+
name: `${e.name}/rateLimit`,
|
|
379
|
+
success: C.Number,
|
|
380
|
+
error: g.RateLimiterError,
|
|
381
|
+
execute: b.gen(function* () {
|
|
382
|
+
let t = yield* (yield* g.RateLimiter).consume({
|
|
383
|
+
...e,
|
|
384
|
+
onExceeded: "delay"
|
|
385
|
+
});
|
|
386
|
+
return y.toMillis(t.delay);
|
|
387
|
+
})
|
|
388
|
+
});
|
|
389
|
+
t > 0 && (yield* d.sleep({
|
|
390
|
+
name: `${e.name}/rateLimit`,
|
|
391
|
+
duration: y.millis(t)
|
|
392
|
+
}));
|
|
393
|
+
}), $ = (e) => b.gen(function* () {
|
|
394
|
+
let t = yield* M, n = yield* b.serviceOption(j), r = y.toMillis(y.fromInputUnsafe(e.duration));
|
|
374
395
|
if (t !== void 0 && n._tag === "Some") {
|
|
375
|
-
let i = n.value, a = new Date(Date.now() + r).toISOString(), o = yield*
|
|
376
|
-
yield*
|
|
396
|
+
let i = n.value, a = new Date(Date.now() + r).toISOString(), o = yield* F;
|
|
397
|
+
yield* b.promise(() => i.recordEvent({
|
|
377
398
|
runId: t,
|
|
378
399
|
eventType: "timer-set",
|
|
379
400
|
payload: {
|
|
@@ -384,7 +405,7 @@ var T = Symbol.for("@voltro/workflow/PreparedExecution"), E = (e, t) => {
|
|
|
384
405
|
}
|
|
385
406
|
}).catch(() => {}));
|
|
386
407
|
let s = Date.now();
|
|
387
|
-
yield*
|
|
408
|
+
yield* d.sleep(e), yield* b.promise(() => i.recordEvent({
|
|
388
409
|
runId: t,
|
|
389
410
|
eventType: "timer-fired",
|
|
390
411
|
payload: {
|
|
@@ -395,89 +416,92 @@ var T = Symbol.for("@voltro/workflow/PreparedExecution"), E = (e, t) => {
|
|
|
395
416
|
}).catch(() => {}));
|
|
396
417
|
return;
|
|
397
418
|
}
|
|
398
|
-
yield*
|
|
399
|
-
}),
|
|
400
|
-
let t = (yield*
|
|
419
|
+
yield* d.sleep(e);
|
|
420
|
+
}), Re = (e) => b.gen(function* () {
|
|
421
|
+
let t = (yield* l.make({
|
|
401
422
|
name: `sleepUntil:${e.name}`,
|
|
402
423
|
success: C.Number,
|
|
403
|
-
execute:
|
|
424
|
+
execute: b.sync(() => e.until instanceof Date ? e.until.getTime() : e.until)
|
|
404
425
|
})) - Date.now();
|
|
405
426
|
t <= 0 || (yield* $({
|
|
406
427
|
name: e.name,
|
|
407
428
|
duration: `${t} millis`
|
|
408
429
|
}));
|
|
409
|
-
}),
|
|
410
|
-
let
|
|
411
|
-
runId:
|
|
412
|
-
stepName:
|
|
413
|
-
attempt:
|
|
414
|
-
}) :
|
|
415
|
-
if (
|
|
416
|
-
|
|
417
|
-
let
|
|
418
|
-
|
|
430
|
+
}), ze = (t, n, r, i) => b.gen(function* () {
|
|
431
|
+
let a = yield* M, s = yield* l.CurrentAttempt, c = yield* b.serviceOption(j), u = yield* b.serviceOption(R), d = u._tag === "Some" ? u.value.interceptor(n, {
|
|
432
|
+
runId: a ?? "unrecorded",
|
|
433
|
+
stepName: t,
|
|
434
|
+
attempt: s
|
|
435
|
+
}) : n, f, p, m = !1;
|
|
436
|
+
if (a !== void 0 && c._tag === "Some") {
|
|
437
|
+
p = c.value;
|
|
438
|
+
let e = i === void 0 ? void 0 : (({ retryable: e, ...t }) => t)(i);
|
|
439
|
+
m = yield* o;
|
|
419
440
|
try {
|
|
420
|
-
|
|
421
|
-
runId:
|
|
422
|
-
stepName:
|
|
423
|
-
attempt:
|
|
424
|
-
stepInput:
|
|
425
|
-
sealed:
|
|
426
|
-
...
|
|
441
|
+
f = yield* b.promise(() => p.startStep({
|
|
442
|
+
runId: a,
|
|
443
|
+
stepName: t,
|
|
444
|
+
attempt: s,
|
|
445
|
+
stepInput: r,
|
|
446
|
+
sealed: m,
|
|
447
|
+
...e === void 0 ? {} : { retryPolicy: e }
|
|
427
448
|
}));
|
|
428
449
|
} catch {
|
|
429
|
-
|
|
450
|
+
f = void 0;
|
|
430
451
|
}
|
|
431
452
|
}
|
|
432
|
-
let
|
|
433
|
-
return yield*
|
|
453
|
+
let h = Date.now();
|
|
454
|
+
return yield* b.provideService(Ae(d, i), P, t).pipe(b.tap((e) => f && p ? b.promise(async () => {
|
|
434
455
|
try {
|
|
435
|
-
await
|
|
436
|
-
stepRecordId:
|
|
437
|
-
sealed:
|
|
456
|
+
await p.endStepSuccess({
|
|
457
|
+
stepRecordId: f,
|
|
458
|
+
sealed: m,
|
|
438
459
|
output: e,
|
|
439
|
-
durationMs: Date.now() -
|
|
460
|
+
durationMs: Date.now() - h
|
|
440
461
|
});
|
|
441
462
|
} catch {}
|
|
442
|
-
}) :
|
|
463
|
+
}) : b.void), b.tapCause((t) => f && p && !_.hasInterruptsOnly(t) ? b.promise(async () => {
|
|
443
464
|
try {
|
|
444
|
-
let
|
|
445
|
-
await
|
|
446
|
-
stepRecordId:
|
|
447
|
-
sealed:
|
|
448
|
-
errorTag:
|
|
449
|
-
errorMessage:
|
|
465
|
+
let n = _.findErrorOption(t), r = t.reasons.filter(_.isFailReason).map((e) => e.error), i = t.reasons.filter(_.isDieReason).map((e) => e.defect), a = n._tag === "Some" ? n.value : i[0] ?? _.squash(t), o = e(a), s = a && typeof a == "object" && "_tag" in a ? String(a._tag) : null;
|
|
466
|
+
await p.endStepFailure({
|
|
467
|
+
stepRecordId: f,
|
|
468
|
+
sealed: m,
|
|
469
|
+
errorTag: s,
|
|
470
|
+
errorMessage: o,
|
|
450
471
|
errorCause: {
|
|
451
|
-
pretty:
|
|
452
|
-
failures:
|
|
453
|
-
defects:
|
|
472
|
+
pretty: _.pretty(t),
|
|
473
|
+
failures: r,
|
|
474
|
+
defects: i
|
|
454
475
|
},
|
|
455
|
-
durationMs: Date.now() -
|
|
476
|
+
durationMs: Date.now() - h
|
|
456
477
|
});
|
|
457
478
|
} catch {}
|
|
458
|
-
}) :
|
|
459
|
-
}),
|
|
460
|
-
let t = yield*
|
|
479
|
+
}) : b.void));
|
|
480
|
+
}), Be = (e) => b.gen(function* () {
|
|
481
|
+
let t = yield* H;
|
|
461
482
|
if (t === void 0) return;
|
|
462
483
|
let n = t.reach(e);
|
|
463
|
-
n !== void 0 && (yield*
|
|
464
|
-
}),
|
|
465
|
-
let
|
|
484
|
+
n !== void 0 && (yield* W([n]));
|
|
485
|
+
}), Ve = (e, t, n) => {
|
|
486
|
+
let r = e;
|
|
466
487
|
return {
|
|
467
488
|
...e,
|
|
468
|
-
|
|
489
|
+
...re.Prototype({
|
|
490
|
+
label: "Activity",
|
|
491
|
+
evaluate: () => b.andThen(Be(t), n === void 0 ? r : b.flatMap(o, (e) => e ? n().pipe(b.catchDefect((e) => b.die(i(e, `step '${t}' defect`)))) : r))
|
|
492
|
+
})
|
|
469
493
|
};
|
|
470
|
-
},
|
|
471
|
-
let { input: n, retry: r, ...i } =
|
|
494
|
+
}, He = (e) => {
|
|
495
|
+
let { input: n, retry: r, ...i } = e, a = ze(i.name, i.execute, n, r), o = l.make({
|
|
472
496
|
...i,
|
|
473
497
|
execute: a
|
|
474
|
-
}),
|
|
475
|
-
return
|
|
498
|
+
}), s, u = `step '${i.name}' defect`;
|
|
499
|
+
return Ve(o, i.name, () => s ??= l.make({
|
|
476
500
|
...i,
|
|
477
|
-
success:
|
|
478
|
-
error:
|
|
479
|
-
execute: a.pipe(
|
|
501
|
+
success: t(i.success ?? C.Void, `step '${i.name}' result`),
|
|
502
|
+
error: t(i.error ?? C.Never, `step '${i.name}' failure`),
|
|
503
|
+
execute: a.pipe(b.catchDefect((e) => b.die(c(e, u))))
|
|
480
504
|
}));
|
|
481
|
-
},
|
|
505
|
+
}, Ue = (e) => b.map(I, (t) => t.includes(e)), We = h.withCompensation, Ge = l.idempotencyKey;
|
|
482
506
|
//#endregion
|
|
483
|
-
export {
|
|
507
|
+
export { xe as A, he as B, ee as C, W as D, U as E, M as F, E as G, L as H, P as I, A as J, de as K, F as L, N as M, ge as N, z as O, I as P, j as R, Ne as S, Se as T, fe as U, _e as V, me as W, le as X, T as Y, ce as Z, Re as _, f as a, u as b, Pe as c, je as d, Ue as f, $ as g, Le as h, K as i, B as j, V as k, Me as l, Ie as m, J as n, Q as o, Fe as p, ue as q, q as r, m as s, Y as t, X as u, He as v, H as w, We as x, Ge as y, R as z };
|