@voltro/workflow 0.33.0 → 0.34.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 +1801 -0
- package/dist/clusterTestSuite.js +28 -28
- package/dist/index.d.ts +509 -6
- package/dist/index.js +3 -3
- package/dist/{primitives-Bp98_F5L.js → primitives-oLKOTbvJ.js} +131 -76
- package/dist/primitives.d.ts +145 -5
- package/dist/primitives.js +2 -2
- package/dist/{src-CP61KZ9V.js → src-BXObaqb-.js} +912 -493
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as e,
|
|
2
|
-
import { $ as
|
|
3
|
-
export {
|
|
1
|
+
import { A as e, B as t, C as n, D as r, E as i, F as a, I as o, L as s, M as c, N as l, O as u, P as d, R as f, S as p, T as m, V as h, _ as g, a as _, b as v, c as y, d as b, f as x, g as S, h as C, i as w, k as T, l as E, m as D, n as O, o as k, p as A, r as j, s as M, t as N, u as P, v as F, w as I, x as L, y as R, z } from "./primitives-oLKOTbvJ.js";
|
|
2
|
+
import { $ as B, A as V, At as H, B as U, C as W, Ct as G, D as K, Dt as q, E as J, Et as Y, F as X, G as Z, H as Q, I as $, J as ee, K as te, L as ne, M as re, Mt as ie, N as ae, Nt as oe, O as se, Ot as ce, P as le, Q as ue, R as de, S as fe, St as pe, T as me, Tt as he, U as ge, V as _e, W as ve, X as ye, Y as be, Z as xe, _ as Se, _t as Ce, a as we, at as Te, b as Ee, bt as De, c as Oe, ct as ke, d as Ae, dt as je, et as Me, f as Ne, ft as Pe, g as Fe, gt as Ie, h as Le, ht as Re, i as ze, it as Be, j as Ve, jt as He, k as Ue, kt as We, l as Ge, lt as Ke, m as qe, mt as Je, n as Ye, nt as Xe, o as Ze, ot as Qe, p as $e, pt as et, q as tt, r as nt, rt, s as it, st as at, t as ot, tt as st, u as ct, ut as lt, v as ut, vt as dt, w as ft, wt as pt, x as mt, xt as ht, y as gt, yt as _t, z as vt } from "./src-BXObaqb-.js";
|
|
3
|
+
export { ue as ADMISSIONS_TABLE, $e as BUDGET_HOLDS_TABLE, qe as BudgetHoldExpired, vt as CANCEL_ON_WATERMARK, u as CurrentWorkflowExecutionId, T as CurrentWorkflowPatches, I as CurrentWorkflowReplayShape, e as CurrentWorkflowRunId, Le as DEFAULT_BUDGET_HOLD_TIMEOUT_MS, U as DEFAULT_COLD_LOOKBACK_MS, ae as DEFAULT_DRAIN_BATCH, _e as DEFAULT_EVENT_BATCH, B as DEFAULT_LEASE_MS, ze as DEFAULT_MAX_RUN_RECLAIMS, we as DEFAULT_REPLAY_SHAPE_LIMIT, X as DEFAULT_STALL_AFTER_MS, $ as DEFAULT_STALL_EVENT_LOOKBACK, ne as DEFAULT_STALL_RUN_PAGE, o as DEFERRING_CONTROLS, Q as EVENTS_TABLE, dt as FlowControlKeyError, Me as PAUSES_TABLE, st as PENDING_TABLE, ge as WATERMARKS_TABLE, N as WorkflowFlowControlProperty, O as WorkflowMessagesProperty, c as WorkflowRunRecorder, l as WorkflowStepInterceptorTag, j as WorkflowVersionTypeId, w as WorkflowWorkerLayerTypeId, Fe as _voltroBudgetHoldsTable, Y as _voltroWorkflowAdmissionsTable, q as _voltroWorkflowPausesTable, ce as _voltroWorkflowPendingTable, H as _voltroWorkflowRunEventsTable, He as _voltroWorkflowRunStepsTable, ie as _voltroWorkflowRunsTable, We as _voltroWorkflowStartContextsTable, be as _voltroWorkflowWatermarksTable, ye as admitStart, Xe as allIntents, s as assertConsistentPools, Ve as awaitEvent, re as awaitSignal, ft as awaitSignalSuspending, Ne as awaitUpdate, Se as budgetHoldGeneration, ut as budgetHoldKey, gt as budgetHoldSignalName, nt as closeWorkflowChildrenForParent, _t as comparePendingOrder, me as completeSuspendingSignal, De as decideAdmission, f as deferringControlsOf, rt as deleteIntent, Be as discardIntent, le as drainTick, Te as dueIntents, _ as durableClock, k as durableQueue, M as durableQueueModule, y as durableRateLimiterModule, Qe as evaluateAdmission, d as getCurrentWorkflowExecutionId, a as getCurrentWorkflowRunId, E as getWorkflowFlowControl, P as getWorkflowVersionMetadata, z as hasCancelOn, t as hasFlowControl, Ee as heldBudgets, oe as inMemoryWorkflowEngineLayer, Ye as inspectWorkflow, ht as isFinishExpired, pe as isStartExpired, b as isWorkflowWorkerLayer, xe as linkExecution, ot as makeInMemoryRecorder, m as makeReplayShapeTracker, Ze as makeWorkflowRunRecorder, K as makeWorkflowUpdateId, tt as newestEventAt, G as nextSlotAt, i as nondeterminismEventPayload, it as normaliseWorkflowPatches, at as noteIntentAttempt, x as patch, ke as pauseWorkflow, mt as pendingBudgetHolds, Ke as pendingSlotId, lt as pendingWindow, je as persistDefer, ee as planCancellations, pt as pooledConcurrencyKey, A as processQueue, Pe as pruneAdmissions, D as queueWorker, C as rateLimit, et as readAdmissionState, Je as readPausedWorkflows, ve as readWatermark, Re as recordAdmission, fe as releaseBudgetHolds, Ie as releaseLease, r as reportNondeterminism, he as resolveAdmissionKeys, Oe as resolveRunGuardTuning, se as resolveWorkflowMessageRun, Ce as resumeWorkflow, Ue as sendWorkflowSignal, V as sendWorkflowUpdate, Ge as serialiseWorkflowRowForWire, S as sleep, g as sleepUntil, F as step, R as stepIdempotencyKey, v as stepModule, W as suspendForBudget, J as suspendingSignalDeferredName, Z as sweepCancelOn, de as sweepStalledRuns, ct as truncateWorkflowValue, h as validateFlowControl, L as withCompensation, p as workflow, n as workflowModule, Ae as wrapWorkflowExecuteWithRunRecording, te as writeWatermark };
|
|
@@ -1,16 +1,16 @@
|
|
|
1
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, Exit as m, FiberRef as h, Option as
|
|
2
|
+
import { Cause as u, Context as d, Duration as f, Effect as p, Exit as m, FiberRef as h, Option as ee, Schedule as g, Schema as _ } from "effect";
|
|
3
3
|
//#region src/flowControl.ts
|
|
4
|
-
var
|
|
4
|
+
var v = (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), y = (e) => e?.cancelOn !== void 0 && e.cancelOn.length > 0, b = [
|
|
5
5
|
"debounce",
|
|
6
6
|
"batch",
|
|
7
7
|
"throttle",
|
|
8
8
|
"concurrency"
|
|
9
|
-
],
|
|
9
|
+
], x = (e) => {
|
|
10
10
|
if (e === void 0) return [];
|
|
11
11
|
let t = [];
|
|
12
12
|
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;
|
|
13
|
-
},
|
|
13
|
+
}, S = (e, t, n) => {
|
|
14
14
|
let r;
|
|
15
15
|
try {
|
|
16
16
|
r = f.toMillis(f.decode(e));
|
|
@@ -19,26 +19,26 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
|
|
|
19
19
|
}
|
|
20
20
|
if (!Number.isFinite(r) || r <= 0) throw Error(`workflow '${n}': ${t} must be a positive finite duration, got ${String(e)}`);
|
|
21
21
|
return r;
|
|
22
|
-
},
|
|
22
|
+
}, C = (e, t, n) => {
|
|
23
23
|
if (!Number.isInteger(e) || e <= 0) throw Error(`workflow '${n}': ${t} must be a positive integer, got ${String(e)}`);
|
|
24
24
|
return e;
|
|
25
|
-
},
|
|
25
|
+
}, w = (e, t, n) => {
|
|
26
26
|
if (typeof e != "function") throw Error(`workflow '${n}': ${t} must be a function of the payload`);
|
|
27
27
|
return e;
|
|
28
|
-
},
|
|
28
|
+
}, T = (e) => {
|
|
29
29
|
let t = e?.ast?.propertySignatures;
|
|
30
30
|
if (!Array.isArray(t)) return !1;
|
|
31
31
|
let n = t.find((e) => e.name === "items");
|
|
32
32
|
return n !== void 0 && n.type?._tag === "TupleType";
|
|
33
|
-
},
|
|
33
|
+
}, E = (e) => {
|
|
34
34
|
let { workflowName: t, control: n } = e;
|
|
35
35
|
if (n === void 0) return;
|
|
36
36
|
let r = { workflowName: t };
|
|
37
37
|
if (n.debounce !== void 0) {
|
|
38
|
-
let e = n.debounce, i =
|
|
38
|
+
let e = n.debounce, i = S(e.period, "debounce.period", t), a = e.timeout === void 0 ? void 0 : S(e.timeout, "debounce.timeout", t);
|
|
39
39
|
if (a !== void 0 && a < i) throw Error(`workflow '${t}': debounce.timeout (${a}ms) is shorter than debounce.period (${i}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.`);
|
|
40
40
|
r.debounce = {
|
|
41
|
-
key:
|
|
41
|
+
key: w(e.key, "debounce.key", t),
|
|
42
42
|
periodMs: i,
|
|
43
43
|
...a === void 0 ? {} : { timeoutMs: a }
|
|
44
44
|
};
|
|
@@ -47,7 +47,7 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
|
|
|
47
47
|
let e = n.singleton;
|
|
48
48
|
if (e.mode !== "skip" && e.mode !== "cancel") throw Error(`workflow '${t}': 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.`);
|
|
49
49
|
r.singleton = {
|
|
50
|
-
key:
|
|
50
|
+
key: w(e.key, "singleton.key", t),
|
|
51
51
|
mode: e.mode
|
|
52
52
|
};
|
|
53
53
|
}
|
|
@@ -55,34 +55,34 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
|
|
|
55
55
|
let e = n.concurrency;
|
|
56
56
|
if (e.pool !== void 0 && (typeof e.pool != "string" || e.pool.trim() === "")) throw Error(`workflow '${t}': 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.`);
|
|
57
57
|
r.concurrency = {
|
|
58
|
-
limit:
|
|
59
|
-
...e.key === void 0 ? {} : { key:
|
|
58
|
+
limit: C(e.limit, "concurrency.limit", t),
|
|
59
|
+
...e.key === void 0 ? {} : { key: w(e.key, "concurrency.key", t) },
|
|
60
60
|
...e.pool === void 0 ? {} : { pool: e.pool.trim() }
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
63
|
if (n.throttle !== void 0) {
|
|
64
64
|
let e = n.throttle;
|
|
65
65
|
r.throttle = {
|
|
66
|
-
limit:
|
|
67
|
-
periodMs:
|
|
68
|
-
...e.key === void 0 ? {} : { key:
|
|
66
|
+
limit: C(e.limit, "throttle.limit", t),
|
|
67
|
+
periodMs: S(e.period, "throttle.period", t),
|
|
68
|
+
...e.key === void 0 ? {} : { key: w(e.key, "throttle.key", t) }
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
if (n.rateLimit !== void 0) {
|
|
72
72
|
let e = n.rateLimit;
|
|
73
73
|
r.rateLimit = {
|
|
74
|
-
limit:
|
|
75
|
-
periodMs:
|
|
76
|
-
...e.key === void 0 ? {} : { key:
|
|
74
|
+
limit: C(e.limit, "rateLimit.limit", t),
|
|
75
|
+
periodMs: S(e.period, "rateLimit.period", t),
|
|
76
|
+
...e.key === void 0 ? {} : { key: w(e.key, "rateLimit.key", t) }
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
if (n.batch !== void 0) {
|
|
80
80
|
let i = n.batch;
|
|
81
|
-
if (e.payloadSchema !== void 0 && !
|
|
81
|
+
if (e.payloadSchema !== void 0 && !T(e.payloadSchema)) throw Error(`workflow '${t}': 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.`);
|
|
82
82
|
r.batch = {
|
|
83
|
-
...i.key === void 0 ? {} : { key:
|
|
84
|
-
maxSize:
|
|
85
|
-
timeoutMs:
|
|
83
|
+
...i.key === void 0 ? {} : { key: w(i.key, "batch.key", t) },
|
|
84
|
+
maxSize: C(i.maxSize, "batch.maxSize", t),
|
|
85
|
+
timeoutMs: S(i.timeout, "batch.timeout", t),
|
|
86
86
|
...i.item === void 0 ? {} : { item: i.item }
|
|
87
87
|
};
|
|
88
88
|
}
|
|
@@ -91,7 +91,7 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
|
|
|
91
91
|
r.priority = n.priority;
|
|
92
92
|
}
|
|
93
93
|
if (n.timeouts !== void 0) {
|
|
94
|
-
let e = n.timeouts, i = e.start === void 0 ? void 0 :
|
|
94
|
+
let e = n.timeouts, i = e.start === void 0 ? void 0 : S(e.start, "timeouts.start", t), a = e.finish === void 0 ? void 0 : S(e.finish, "timeouts.finish", t);
|
|
95
95
|
(i !== void 0 || a !== void 0) && (r.timeouts = {
|
|
96
96
|
...i === void 0 ? {} : { startMs: i },
|
|
97
97
|
...a === void 0 ? {} : { finishMs: a }
|
|
@@ -111,7 +111,7 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
|
|
|
111
111
|
if (typeof e?.event != "string" || e.event.length === 0) throw Error(`workflow '${t}': ${r}.event must be a non-empty event name, exactly as ctx.events.publish writes it.`);
|
|
112
112
|
if (e.schema === void 0 || typeof e.schema.ast != "object") throw Error(`workflow '${t}': ${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.`);
|
|
113
113
|
if (typeof e.match != "function") throw Error(`workflow '${t}': ${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.`);
|
|
114
|
-
let i = e.within === void 0 ? void 0 :
|
|
114
|
+
let i = e.within === void 0 ? void 0 : S(e.within, `${r}.within`, t);
|
|
115
115
|
return {
|
|
116
116
|
event: e.event,
|
|
117
117
|
schema: e.schema,
|
|
@@ -122,9 +122,9 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
|
|
|
122
122
|
});
|
|
123
123
|
e.length > 0 && (r.cancelOn = e);
|
|
124
124
|
}
|
|
125
|
-
if (r.timeouts?.startMs !== void 0 &&
|
|
125
|
+
if (r.timeouts?.startMs !== void 0 && x(r).length === 0) throw Error(`workflow '${t}': 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.`);
|
|
126
126
|
return r;
|
|
127
|
-
},
|
|
127
|
+
}, D = (e) => {
|
|
128
128
|
let t = /* @__PURE__ */ new Map();
|
|
129
129
|
for (let n of e) {
|
|
130
130
|
let e = n?.concurrency;
|
|
@@ -137,99 +137,143 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
|
|
|
137
137
|
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.`);
|
|
138
138
|
else r.workflows.push(n.workflowName);
|
|
139
139
|
}
|
|
140
|
-
}, O = class extends d.Tag("@voltro/WorkflowRunRecorder")() {}, k = h.unsafeMake(void 0), A = h.unsafeMake(void 0), j = h.unsafeMake(void 0), M = () => h.get(k),
|
|
140
|
+
}, O = class extends d.Tag("@voltro/WorkflowRunRecorder")() {}, k = h.unsafeMake(void 0), A = h.unsafeMake(void 0), j = h.unsafeMake(void 0), M = h.unsafeMake([]), N = () => h.get(k), P = () => h.get(A), F = class extends d.Tag("@voltro/WorkflowStepInterceptor")() {}, I = (e) => {
|
|
141
|
+
let t = /* @__PURE__ */ new Map();
|
|
142
|
+
for (let n of e) t.set(n.stepName, (t.get(n.stepName) ?? 0) + 1);
|
|
143
|
+
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set(), i = (e) => r.has(e) ? !1 : (r.add(e), !0);
|
|
144
|
+
return {
|
|
145
|
+
reach: (e) => {
|
|
146
|
+
let r = (n.get(e) ?? 0) + 1;
|
|
147
|
+
n.set(e, r);
|
|
148
|
+
let a = t.get(e) ?? 0;
|
|
149
|
+
if (a !== 0 && !(r <= a) && i(`extra:${e}`)) return {
|
|
150
|
+
kind: "extra-step-occurrence",
|
|
151
|
+
stepName: e,
|
|
152
|
+
recorded: a,
|
|
153
|
+
reached: r,
|
|
154
|
+
detail: `step '${e}' was reached ${r} time(s) on this attempt but this run only ever recorded ${a} — the body may have changed how often it runs this step (a loop bound), so the journal replays a result for an iteration the code no longer means.`
|
|
155
|
+
};
|
|
156
|
+
},
|
|
157
|
+
settle: () => {
|
|
158
|
+
let e = [];
|
|
159
|
+
for (let [r, a] of t) (n.get(r) ?? 0) > 0 || i(`unreached:${r}`) && e.push({
|
|
160
|
+
kind: "unreached-step",
|
|
161
|
+
stepName: r,
|
|
162
|
+
recorded: a,
|
|
163
|
+
reached: 0,
|
|
164
|
+
detail: `step '${r}' ran on an earlier attempt of this run but the current code never reaches it — the step was renamed, removed, or moved behind a branch, so its journaled result is orphaned and any step that replaced it executed fresh.`
|
|
165
|
+
});
|
|
166
|
+
return e;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}, L = h.unsafeMake(void 0), R = (e) => ({
|
|
170
|
+
kind: e.kind,
|
|
171
|
+
stepName: e.stepName,
|
|
172
|
+
recorded: e.recorded,
|
|
173
|
+
reached: e.reached,
|
|
174
|
+
detail: e.detail
|
|
175
|
+
}), z = (e) => p.gen(function* () {
|
|
176
|
+
if (e.length === 0) return;
|
|
177
|
+
let t = yield* h.get(k), n = yield* p.serviceOption(O);
|
|
178
|
+
if (t === void 0 || n._tag !== "Some") return;
|
|
179
|
+
let r = n.value;
|
|
180
|
+
for (let n of e) yield* p.promise(() => r.recordEvent({
|
|
181
|
+
runId: t,
|
|
182
|
+
eventType: "nondeterminism-suspected",
|
|
183
|
+
payload: R(n)
|
|
184
|
+
}).then(() => void 0).catch(() => void 0));
|
|
185
|
+
}), B = (e) => {
|
|
141
186
|
if (typeof e != "object" || !e) return;
|
|
142
187
|
let t = e.retryAfterMillis;
|
|
143
188
|
if (typeof t == "number" && Number.isFinite(t) && t >= 0) return f.millis(t);
|
|
144
189
|
let n = e.retryAfter;
|
|
145
190
|
if (typeof n == "number" && Number.isFinite(n) && n >= 0) return f.seconds(n);
|
|
146
|
-
},
|
|
191
|
+
}, V = (e) => f.decode(e), H = (e) => typeof e == "object" && e && "_tag" in e ? String(e._tag) : void 0, U = (e) => e !== void 0 && (e.maxAttempts ?? 3) > 1, W = (e) => {
|
|
147
192
|
if (e.retryable) return e.retryable;
|
|
148
193
|
if (e.retryableErrors && e.retryableErrors.length > 0) {
|
|
149
194
|
let t = new Set(e.retryableErrors);
|
|
150
195
|
return (e) => {
|
|
151
|
-
let n =
|
|
196
|
+
let n = H(e);
|
|
152
197
|
return n !== void 0 && t.has(n);
|
|
153
198
|
};
|
|
154
199
|
}
|
|
155
200
|
return () => !0;
|
|
156
|
-
},
|
|
157
|
-
let t = e.baseDelay ?? "200 millis", n = e.strategy ?? "exponential", r = e.maxAttempts ?? 3, i = n === "linear" ?
|
|
201
|
+
}, G = (e) => {
|
|
202
|
+
let t = e.baseDelay ?? "200 millis", n = e.strategy ?? "exponential", r = e.maxAttempts ?? 3, i = n === "linear" ? g.linear(V(e.step ?? t)) : n === "fixed" ? g.spaced(V(t)) : g.exponential(V(t), e.factor ?? 2);
|
|
158
203
|
if (e.maxDelay !== void 0) {
|
|
159
|
-
let t =
|
|
160
|
-
i =
|
|
204
|
+
let t = V(e.maxDelay);
|
|
205
|
+
i = g.modifyDelay(i, (e, n) => f.min(n, t));
|
|
161
206
|
}
|
|
162
|
-
(e.jitter ?? !0) === !0 && (i =
|
|
163
|
-
let a =
|
|
164
|
-
return e.maxElapsed !== void 0 && (a =
|
|
165
|
-
},
|
|
166
|
-
let n = f.toMillis(
|
|
167
|
-
return e.maxDelay !== void 0 && (i = Math.min(i, f.toMillis(
|
|
168
|
-
},
|
|
169
|
-
let i = t.maxAttempts ?? 3, a = t.maxElapsed === void 0 ? Infinity : f.toMillis(
|
|
207
|
+
(e.jitter ?? !0) === !0 && (i = g.jittered(i));
|
|
208
|
+
let a = g.intersect(i, g.recurs(Math.max(0, r - 1)));
|
|
209
|
+
return e.maxElapsed !== void 0 && (a = g.upTo(V(e.maxElapsed))(a)), a;
|
|
210
|
+
}, K = (e, t) => {
|
|
211
|
+
let n = f.toMillis(V(e.baseDelay ?? "200 millis")), r = e.strategy ?? "exponential", i = r === "fixed" ? n : r === "linear" ? n + f.toMillis(V(e.step ?? e.baseDelay ?? "200 millis")) * (t - 1) : n * (e.factor ?? 2) ** (t - 1);
|
|
212
|
+
return e.maxDelay !== void 0 && (i = Math.min(i, f.toMillis(V(e.maxDelay)))), (e.jitter ?? !0) === !0 && (i *= Math.random()), i;
|
|
213
|
+
}, q = (e, t, n, r) => p.gen(function* () {
|
|
214
|
+
let i = t.maxAttempts ?? 3, a = t.maxElapsed === void 0 ? Infinity : f.toMillis(V(t.maxElapsed)), o = yield* p.sync(() => Date.now()), s = 0;
|
|
170
215
|
for (;;) {
|
|
171
216
|
let c = yield* p.exit(e);
|
|
172
217
|
if (m.isSuccess(c)) return c.value;
|
|
173
|
-
let l = c.cause, d = u.failureOption(l), h =
|
|
218
|
+
let l = c.cause, d = u.failureOption(l), h = ee.isSome(d) ? d.value : u.squash(l);
|
|
174
219
|
s += 1;
|
|
175
|
-
let
|
|
176
|
-
if (s >= i || !n(h) ||
|
|
220
|
+
let g = (yield* p.sync(() => Date.now())) - o;
|
|
221
|
+
if (s >= i || !n(h) || g >= a) return yield* p.failCause(l);
|
|
177
222
|
r?.(h);
|
|
178
|
-
let
|
|
179
|
-
yield* p.sleep(f.millis(
|
|
223
|
+
let _ = B(h), v = _ === void 0 ? K(t, s) : f.toMillis(_);
|
|
224
|
+
yield* p.sleep(f.millis(v));
|
|
180
225
|
}
|
|
181
|
-
}),
|
|
182
|
-
if (!
|
|
183
|
-
let r =
|
|
184
|
-
if (t.respectRetryAfter === !0) return
|
|
185
|
-
let i =
|
|
226
|
+
}), J = (e, t, n) => {
|
|
227
|
+
if (!U(t)) return e;
|
|
228
|
+
let r = W(t);
|
|
229
|
+
if (t.respectRetryAfter === !0) return q(e, t, r, n);
|
|
230
|
+
let i = G(t), a = n ? p.tapError(e, (e) => p.sync(() => {
|
|
186
231
|
r(e) && n(e);
|
|
187
232
|
})) : e;
|
|
188
233
|
return p.retry(a, {
|
|
189
234
|
schedule: i,
|
|
190
235
|
while: r
|
|
191
236
|
});
|
|
192
|
-
},
|
|
237
|
+
}, Y = Symbol.for("voltro.workflow.workerLayer"), X = Symbol.for("voltro.workflow.version"), Z = "__voltroWorkflowMessages", Q = "__voltroWorkflowFlowControl", te = (e) => typeof e == "object" && !!e && e[Y] === !0, ne = (e) => typeof e == "object" && e && e[X] !== void 0 ? e[X] : {
|
|
193
238
|
version: "1",
|
|
194
239
|
compatibleWith: ["1"],
|
|
195
240
|
patches: []
|
|
196
|
-
},
|
|
241
|
+
}, re = ((e) => {
|
|
197
242
|
let t = c.make(e), n = e.suspendOnFailure === !0 ? t.annotate(c.SuspendOnFailure, !0) : t, r = String(e.version ?? "1"), i = {
|
|
198
243
|
version: r,
|
|
199
244
|
compatibleWith: (e.compatibleWith ?? [r]).map(String),
|
|
200
245
|
patches: [...e.patches ?? []]
|
|
201
246
|
}, a = {
|
|
202
247
|
signals: { ...e.messages?.signals ?? {} },
|
|
203
|
-
updates: { ...e.messages?.updates ?? {} }
|
|
204
|
-
queries: { ...e.messages?.queries ?? {} }
|
|
248
|
+
updates: { ...e.messages?.updates ?? {} }
|
|
205
249
|
};
|
|
206
|
-
Object.defineProperty(n,
|
|
250
|
+
Object.defineProperty(n, X, {
|
|
207
251
|
value: i,
|
|
208
252
|
enumerable: !1
|
|
209
|
-
}), Object.defineProperty(n,
|
|
253
|
+
}), Object.defineProperty(n, Z, {
|
|
210
254
|
value: a,
|
|
211
255
|
enumerable: !1
|
|
212
256
|
});
|
|
213
|
-
let o =
|
|
257
|
+
let o = E({
|
|
214
258
|
workflowName: e.name,
|
|
215
259
|
payloadSchema: e.payload,
|
|
216
260
|
control: e
|
|
217
261
|
});
|
|
218
|
-
return o !== void 0 && Object.defineProperty(n,
|
|
262
|
+
return o !== void 0 && Object.defineProperty(n, Q, {
|
|
219
263
|
value: o,
|
|
220
264
|
enumerable: !1
|
|
221
265
|
}), n;
|
|
222
|
-
}),
|
|
266
|
+
}), ie = (e) => {
|
|
223
267
|
if (typeof e != "object" || !e) return;
|
|
224
|
-
let t = e[
|
|
268
|
+
let t = e[Q];
|
|
225
269
|
return t === void 0 ? void 0 : t;
|
|
226
|
-
},
|
|
270
|
+
}, ae = i.make, oe = i.process, se = ((...e) => {
|
|
227
271
|
let t = i.worker(...e);
|
|
228
|
-
return Object.defineProperty(t,
|
|
272
|
+
return Object.defineProperty(t, Y, {
|
|
229
273
|
value: !0,
|
|
230
274
|
enumerable: !1
|
|
231
275
|
}), t;
|
|
232
|
-
}),
|
|
276
|
+
}), ce = o.rateLimit, $ = (e) => p.gen(function* () {
|
|
233
277
|
let t = yield* k, r = yield* p.serviceOption(O), i = f.toMillis(f.decode(e.duration));
|
|
234
278
|
if (t !== void 0 && r._tag === "Some") {
|
|
235
279
|
let a = r.value, o = new Date(Date.now() + i).toISOString(), s = yield* j;
|
|
@@ -256,18 +300,18 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
|
|
|
256
300
|
return;
|
|
257
301
|
}
|
|
258
302
|
yield* n.sleep(e);
|
|
259
|
-
}),
|
|
303
|
+
}), le = (t) => p.gen(function* () {
|
|
260
304
|
let n = (yield* e.make({
|
|
261
305
|
name: `sleepUntil:${t.name}`,
|
|
262
|
-
success:
|
|
306
|
+
success: _.Number,
|
|
263
307
|
execute: p.sync(() => t.until instanceof Date ? t.until.getTime() : t.until)
|
|
264
308
|
})) - Date.now();
|
|
265
309
|
n <= 0 || (yield* $({
|
|
266
310
|
name: t.name,
|
|
267
311
|
duration: `${n} millis`
|
|
268
312
|
}));
|
|
269
|
-
}),
|
|
270
|
-
let a = yield* k, o = yield* e.CurrentAttempt, s = yield* p.serviceOption(O), c = yield* p.serviceOption(
|
|
313
|
+
}), ue = (t, n, r, i) => p.gen(function* () {
|
|
314
|
+
let a = yield* k, o = yield* e.CurrentAttempt, s = yield* p.serviceOption(O), c = yield* p.serviceOption(F), l = c._tag === "Some" ? c.value.interceptor(n, {
|
|
271
315
|
runId: a ?? "unrecorded",
|
|
272
316
|
stepName: t,
|
|
273
317
|
attempt: o
|
|
@@ -288,7 +332,7 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
|
|
|
288
332
|
}
|
|
289
333
|
}
|
|
290
334
|
let m = Date.now();
|
|
291
|
-
return yield*
|
|
335
|
+
return yield* J(l, i).pipe(p.tap((e) => d && f ? p.promise(async () => {
|
|
292
336
|
try {
|
|
293
337
|
await f.endStepSuccess({
|
|
294
338
|
stepRecordId: d,
|
|
@@ -312,12 +356,23 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
|
|
|
312
356
|
});
|
|
313
357
|
} catch {}
|
|
314
358
|
}) : p.void));
|
|
315
|
-
}),
|
|
359
|
+
}), de = (e) => p.gen(function* () {
|
|
360
|
+
let t = yield* h.get(L);
|
|
361
|
+
if (t === void 0) return;
|
|
362
|
+
let n = t.reach(e);
|
|
363
|
+
n !== void 0 && (yield* z([n]));
|
|
364
|
+
}), fe = (e, t) => {
|
|
365
|
+
let n = e;
|
|
366
|
+
return {
|
|
367
|
+
...e,
|
|
368
|
+
commit: () => p.zipRight(de(t), n)
|
|
369
|
+
};
|
|
370
|
+
}, pe = (t) => {
|
|
316
371
|
let { input: n, retry: r, ...i } = t;
|
|
317
|
-
return e.make({
|
|
372
|
+
return fe(e.make({
|
|
318
373
|
...i,
|
|
319
|
-
execute:
|
|
320
|
-
});
|
|
321
|
-
},
|
|
374
|
+
execute: ue(i.name, i.execute, n, r)
|
|
375
|
+
}), i.name);
|
|
376
|
+
}, me = (e) => p.map(h.get(M), (t) => t.includes(e)), he = c.withCompensation, ge = e.idempotencyKey;
|
|
322
377
|
//#endregion
|
|
323
|
-
export {
|
|
378
|
+
export { k as A, v as B, l as C, z as D, R as E, N as F, b as I, D as L, O as M, F as N, A as O, P, x as R, re as S, I as T, E as V, le as _, r as a, t as b, s as c, te as d, me as f, $ as g, ce as h, Y as i, j, M as k, ie as l, se as m, Z as n, ae as o, oe as p, X as r, a as s, Q as t, ne as u, pe as v, L as w, he as x, ge as y, y as z };
|
package/dist/primitives.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { DurableQueue as durableQueueModule } from '@effect/workflow';
|
|
|
3
3
|
import { DurableRateLimiter as durableRateLimiterModule } from '@effect/workflow';
|
|
4
4
|
import { Duration } from 'effect';
|
|
5
5
|
import { Effect } from 'effect';
|
|
6
|
+
import { FiberRef } from 'effect';
|
|
6
7
|
import { Schema } from 'effect';
|
|
7
8
|
import { Activity as stepModule } from '@effect/workflow';
|
|
8
9
|
import { Workflow as workflowModule } from '@effect/workflow';
|
|
@@ -24,6 +25,16 @@ import { Workflow as workflowModule } from '@effect/workflow';
|
|
|
24
25
|
*/
|
|
25
26
|
export declare const assertConsistentPools: (controls: ReadonlyArray<ResolvedFlowControl | undefined>) => void;
|
|
26
27
|
|
|
28
|
+
/**
|
|
29
|
+
* The tracker for the CURRENT body entry, or `undefined` when there is nothing
|
|
30
|
+
* to compare against.
|
|
31
|
+
*
|
|
32
|
+
* Installed by `wrapWorkflowExecuteWithRunRecording` ONLY on a re-entry (a run
|
|
33
|
+
* whose row already exists). A first entry has no prior shape, so the whole
|
|
34
|
+
* mechanism costs one `FiberRef` read per step and nothing else.
|
|
35
|
+
*/
|
|
36
|
+
export declare const CurrentWorkflowReplayShape: FiberRef.FiberRef<ReplayShapeTracker | undefined>;
|
|
37
|
+
|
|
27
38
|
/** The DECODED payload type. Mirrors `Workflow.make`'s own `idempotencyKey`
|
|
28
39
|
* parameter, so the two never disagree about what a payload is. */
|
|
29
40
|
declare type DecodedPayload<P> = P extends Schema.Struct.Fields ? Schema.Struct.Type<P> : P extends {
|
|
@@ -84,6 +95,34 @@ export declare const hasFlowControl: (control: ResolvedFlowControl | undefined)
|
|
|
84
95
|
|
|
85
96
|
export declare const isWorkflowWorkerLayer: (value: unknown) => value is WorkflowWorkerLayerBrand;
|
|
86
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Build a tracker from the step rows this run recorded on EARLIER body entries.
|
|
100
|
+
*
|
|
101
|
+
* Pass the rows as they are: one row per step ATTEMPT, so a step that retried
|
|
102
|
+
* three times contributes three. Counting rows rather than distinct names is
|
|
103
|
+
* what makes the per-name sequence rule work, and the asymmetry is deliberate —
|
|
104
|
+
* only reaching a name MORE often than recorded is a finding. Fewer is normal
|
|
105
|
+
* (a crash mid-step records two rows for one logical reach).
|
|
106
|
+
*/
|
|
107
|
+
export declare const makeReplayShapeTracker: (recordedRows: ReadonlyArray<RecordedStepShape>) => ReplayShapeTracker;
|
|
108
|
+
|
|
109
|
+
/** The `nondeterminism-suspected` event body. Kept here so the two emit sites
|
|
110
|
+
* (the step wrapper, and the run wrapper's `settle`) cannot drift. */
|
|
111
|
+
export declare const nondeterminismEventPayload: (finding: NondeterminismFinding) => Record<string, unknown>;
|
|
112
|
+
|
|
113
|
+
export declare interface NondeterminismFinding {
|
|
114
|
+
readonly kind: NondeterminismKind;
|
|
115
|
+
readonly stepName: string;
|
|
116
|
+
/** How many rows this run recorded for `stepName` on EARLIER body entries. */
|
|
117
|
+
readonly recorded: number;
|
|
118
|
+
/** How many times the CURRENT body entry reached it. */
|
|
119
|
+
readonly reached: number;
|
|
120
|
+
/** One sentence an operator can act on, without opening the code. */
|
|
121
|
+
readonly detail: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export declare type NondeterminismKind = 'unreached-step' | 'extra-step-occurrence';
|
|
125
|
+
|
|
87
126
|
declare type NormaliseWorkflowMessages<M extends WorkflowMessageSchemas | undefined> = {
|
|
88
127
|
readonly signals: M extends {
|
|
89
128
|
readonly signals: infer Signals;
|
|
@@ -91,11 +130,60 @@ declare type NormaliseWorkflowMessages<M extends WorkflowMessageSchemas | undefi
|
|
|
91
130
|
readonly updates: M extends {
|
|
92
131
|
readonly updates: infer Updates;
|
|
93
132
|
} ? NonNullable<Updates> & Readonly<Record<string, WorkflowMessagePairSchemas>> : {};
|
|
94
|
-
readonly queries: M extends {
|
|
95
|
-
readonly queries: infer Queries;
|
|
96
|
-
} ? NonNullable<Queries> & Readonly<Record<string, WorkflowMessagePairSchemas>> : {};
|
|
97
133
|
};
|
|
98
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Is a named change marker in effect for the run currently executing?
|
|
137
|
+
*
|
|
138
|
+
* This is the escape valve for the versioning trap. `compatibleWith` is
|
|
139
|
+
* all-or-nothing: leave an old version out and every in-flight run on it is
|
|
140
|
+
* terminally failed; leave it in and the old runs replay against the new body
|
|
141
|
+
* with no detection. `patch` is the third option — the body itself branches, so
|
|
142
|
+
* runs that started BEFORE the change keep taking the old path to completion
|
|
143
|
+
* while new runs take the new one.
|
|
144
|
+
*
|
|
145
|
+
* ```ts
|
|
146
|
+
* export const Charge = workflow({
|
|
147
|
+
* name: 'billing.charge',
|
|
148
|
+
* payload: { orderId: Schema.String },
|
|
149
|
+
* idempotencyKey: ({ orderId }) => `billing.charge:${orderId}`,
|
|
150
|
+
* patches: ['split-tax-calculation'], // ← declare it
|
|
151
|
+
* })
|
|
152
|
+
*
|
|
153
|
+
* // inside the body:
|
|
154
|
+
* if (yield* patch('split-tax-calculation')) {
|
|
155
|
+
* const net = yield* step({ name: 'net-total', execute })
|
|
156
|
+
* const tax = yield* step({ name: 'tax', execute })
|
|
157
|
+
* return net + tax
|
|
158
|
+
* }
|
|
159
|
+
* return yield* step({ name: 'total', execute }) // the pre-patch path
|
|
160
|
+
* ```
|
|
161
|
+
*
|
|
162
|
+
* ── The answer is pinned to the RUN, not to the code ────────────────────────
|
|
163
|
+
*
|
|
164
|
+
* `patches` is stamped onto `_voltro_workflow_runs.workflowPatches` when the
|
|
165
|
+
* run starts and read back from that row on every resume. So a run started
|
|
166
|
+
* before you added the marker answers `false` for the rest of its life,
|
|
167
|
+
* however many times it replays and whatever the deployed code says — which is
|
|
168
|
+
* the property that makes the branch deterministic across a redeploy.
|
|
169
|
+
*
|
|
170
|
+
* Under `@effect/workflow` the naive implementation does the opposite: an
|
|
171
|
+
* activity that is ABSENT from an old run's journal EXECUTES on replay (the
|
|
172
|
+
* journal is keyed name/attempt), so a marker journaled by an activity would
|
|
173
|
+
* answer `true` for exactly the old runs it must answer `false` for. Reading
|
|
174
|
+
* the run row sidesteps that entirely.
|
|
175
|
+
*
|
|
176
|
+
* ── Retiring a patch ───────────────────────────────────────────────────────
|
|
177
|
+
*
|
|
178
|
+
* Once no run predating the marker can still be in flight, delete the old
|
|
179
|
+
* branch and the entry from `patches`. Runs that stamped it keep the marker on
|
|
180
|
+
* their row for the audit trail; `patch()` simply stops being called.
|
|
181
|
+
*
|
|
182
|
+
* Outside a recorded workflow body (a unit test, a bare `step()` call) this is
|
|
183
|
+
* `false` — the pre-patch branch, which is the safe direction.
|
|
184
|
+
*/
|
|
185
|
+
export declare const patch: (id: string) => Effect.Effect<boolean>;
|
|
186
|
+
|
|
99
187
|
/** The SCHEMA a payload input denotes — `Fields` lifted into a `Struct`. */
|
|
100
188
|
declare type PayloadSchemaOf<P> = P extends Schema.Struct.Fields ? Schema.Struct<P> : P;
|
|
101
189
|
|
|
@@ -114,6 +202,39 @@ export declare const queueWorker: typeof durableQueueModule.worker;
|
|
|
114
202
|
/** Durable rate limiter activity. Delays through the workflow clock. */
|
|
115
203
|
export declare const rateLimit: typeof durableRateLimiterModule.rateLimit;
|
|
116
204
|
|
|
205
|
+
/** The slice of a `_voltro_workflow_run_steps` row this needs. */
|
|
206
|
+
export declare interface RecordedStepShape {
|
|
207
|
+
readonly stepName: string;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export declare interface ReplayShapeTracker {
|
|
211
|
+
/**
|
|
212
|
+
* The body reached `stepName`. Returns a finding the FIRST time that reach
|
|
213
|
+
* is anomalous, `undefined` otherwise — so a step in a hot loop reports once
|
|
214
|
+
* rather than once per iteration.
|
|
215
|
+
*/
|
|
216
|
+
readonly reach: (stepName: string) => NondeterminismFinding | undefined;
|
|
217
|
+
/**
|
|
218
|
+
* The body ran to a COMPLETE outcome. Returns the set-membership findings —
|
|
219
|
+
* recorded names the body never reached.
|
|
220
|
+
*
|
|
221
|
+
* Call this ONLY on success/failure, never on a suspend: a suspended body
|
|
222
|
+
* stopped partway through on purpose, so everything after the suspension
|
|
223
|
+
* point is legitimately unreached.
|
|
224
|
+
*/
|
|
225
|
+
readonly settle: () => ReadonlyArray<NondeterminismFinding>;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Emit findings from INSIDE the workflow body, where the run id and the
|
|
230
|
+
* recorder are only reachable through the fiber context.
|
|
231
|
+
*
|
|
232
|
+
* Best-effort in the strongest sense: no recorder, no run id, or a rejecting
|
|
233
|
+
* write all resolve to "nothing happened". A tripwire that can break the run it
|
|
234
|
+
* is watching is not a tripwire.
|
|
235
|
+
*/
|
|
236
|
+
export declare const reportNondeterminism: (findings: ReadonlyArray<NondeterminismFinding>) => Effect.Effect<void>;
|
|
237
|
+
|
|
117
238
|
/** One resolved `cancelOn` entry. The schema is kept (not pre-compiled into a
|
|
118
239
|
* decoder) so the sweeper can report a decode failure naming the event, which
|
|
119
240
|
* is the difference between "the predicate said no" and "we could not read the
|
|
@@ -742,16 +863,24 @@ export declare interface WorkflowMessagesCarrier<M extends WorkflowMessagesMetad
|
|
|
742
863
|
readonly [WorkflowMessagesProperty]: M;
|
|
743
864
|
}
|
|
744
865
|
|
|
866
|
+
/**
|
|
867
|
+
* The message channels a workflow declares.
|
|
868
|
+
*
|
|
869
|
+
* TWO, not three. `queries` used to sit here as a third channel and there was
|
|
870
|
+
* never a send path for it — no `sendWorkflowQuery`, no `awaitQuery`, nothing
|
|
871
|
+
* to receive one. It was normalised into metadata, projected into the generated
|
|
872
|
+
* rpcGroup and carried on the client's `WorkflowState`, so a user got a fully
|
|
873
|
+
* typed record they could not invoke from anywhere. Signals (fire-and-forget)
|
|
874
|
+
* and updates (synchronous, with a result) are the channels that exist.
|
|
875
|
+
*/
|
|
745
876
|
export declare interface WorkflowMessageSchemas {
|
|
746
877
|
readonly signals?: Readonly<Record<string, Schema.Schema.Any>>;
|
|
747
878
|
readonly updates?: Readonly<Record<string, WorkflowMessagePairSchemas>>;
|
|
748
|
-
readonly queries?: Readonly<Record<string, WorkflowMessagePairSchemas>>;
|
|
749
879
|
}
|
|
750
880
|
|
|
751
881
|
export declare interface WorkflowMessagesMetadata {
|
|
752
882
|
readonly signals: Readonly<Record<string, Schema.Schema.Any>>;
|
|
753
883
|
readonly updates: Readonly<Record<string, WorkflowMessagePairSchemas>>;
|
|
754
|
-
readonly queries: Readonly<Record<string, WorkflowMessagePairSchemas>>;
|
|
755
884
|
}
|
|
756
885
|
|
|
757
886
|
export declare const WorkflowMessagesProperty = "__voltroWorkflowMessages";
|
|
@@ -841,6 +970,17 @@ export declare interface WorkflowVersionMetadata {
|
|
|
841
970
|
export declare interface WorkflowVersionOptions {
|
|
842
971
|
readonly version?: string | number;
|
|
843
972
|
readonly compatibleWith?: ReadonlyArray<string | number>;
|
|
973
|
+
/**
|
|
974
|
+
* Named change markers this workflow's body may branch on, via
|
|
975
|
+
* {@link patch}. Declaring one here is what makes `yield* patch('id')`
|
|
976
|
+
* answer `true` for runs started from now on and `false` for runs that were
|
|
977
|
+
* already in flight — see {@link patch} for the semantics and the worked
|
|
978
|
+
* example.
|
|
979
|
+
*
|
|
980
|
+
* The declared set is stamped onto `_voltro_workflow_runs.workflowPatches`
|
|
981
|
+
* at run start and read back from THERE on every resume, so the answer is
|
|
982
|
+
* pinned to the run and cannot change under a redeploy.
|
|
983
|
+
*/
|
|
844
984
|
readonly patches?: ReadonlyArray<string>;
|
|
845
985
|
/**
|
|
846
986
|
* When `true`, a workflow whose top-level body FAILS does not become a
|
package/dist/primitives.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { B as e, C as t, D as n, E as r, I as i, L as a, R as o, S as s, T as c, V as l, _ as u, a as d, b as f, c as p, d as m, f as h, g, h as _, i as v, l as y, m as b, n as x, o as S, p as C, r as w, s as T, t as E, u as D, v as O, w as k, x as A, y as j, z as M } from "./primitives-oLKOTbvJ.js";
|
|
2
|
+
export { k as CurrentWorkflowReplayShape, i as DEFERRING_CONTROLS, E as WorkflowFlowControlProperty, x as WorkflowMessagesProperty, w as WorkflowVersionTypeId, v as WorkflowWorkerLayerTypeId, a as assertConsistentPools, o as deferringControlsOf, d as durableClock, S as durableQueue, T as durableQueueModule, p as durableRateLimiterModule, y as getWorkflowFlowControl, D as getWorkflowVersionMetadata, M as hasCancelOn, e as hasFlowControl, m as isWorkflowWorkerLayer, c as makeReplayShapeTracker, r as nondeterminismEventPayload, h as patch, C as processQueue, b as queueWorker, _ as rateLimit, n as reportNondeterminism, g as sleep, u as sleepUntil, O as step, j as stepIdempotencyKey, f as stepModule, l as validateFlowControl, A as withCompensation, s as workflow, t as workflowModule };
|