@voltro/workflow 0.33.0 → 0.35.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/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { A as e, C as t, D as n, E as r, F as i, M as a, N as o, O as s, P as c, S 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, j as y, k as b, l as x, m as S, n as C, o as w, p as T, r as E, s as D, t as O, u as k, v as A, w as j, x as M, y as N } from "./primitives-Bp98_F5L.js";
2
- import { $ as P, A as F, B as I, C as L, D as R, E as z, F as B, G as V, H, I as U, J as W, K as G, L as K, M as q, N as J, O as Y, P as X, Q as Z, R as Q, S as $, T as ee, U as te, V as ne, W as re, X as ie, Y as ae, Z as oe, _ as se, a as ce, at as le, b as ue, c as de, ct as fe, d as pe, dt as me, et as he, f as ge, ft as _e, g as ve, h as ye, i as be, it as xe, j as Se, k as Ce, l as we, lt as Te, m as Ee, mt as De, n as Oe, nt as ke, o as Ae, ot as je, p as Me, pt as Ne, q as Pe, r as Fe, rt as Ie, s as Le, st as Re, t as ze, tt as Be, u as Ve, ut as He, v as Ue, w as We, x as Ge, y as Ke, z as qe } from "./src-CP61KZ9V.js";
3
- export { J as ADMISSIONS_TABLE, ue as CANCEL_ON_WATERMARK, t as CurrentWorkflowExecutionId, j as CurrentWorkflowRunId, Ge as DEFAULT_COLD_LOOKBACK_MS, Ue as DEFAULT_DRAIN_BATCH, $ as DEFAULT_EVENT_BATCH, X as DEFAULT_LEASE_MS, e as DEFERRING_CONTROLS, L as EVENTS_TABLE, P as FlowControlKeyError, B as PAUSES_TABLE, U as PENDING_TABLE, We as WATERMARKS_TABLE, O as WorkflowFlowControlProperty, C as WorkflowMessagesProperty, r as WorkflowRunRecorder, n as WorkflowStepInterceptorTag, E as WorkflowVersionTypeId, v as WorkflowWorkerLayerTypeId, Re as _voltroWorkflowAdmissionsTable, fe as _voltroWorkflowPausesTable, Te as _voltroWorkflowPendingTable, me as _voltroWorkflowRunEventsTable, _e as _voltroWorkflowRunStepsTable, Ne as _voltroWorkflowRunsTable, He as _voltroWorkflowStartContextsTable, F as _voltroWorkflowWatermarksTable, Se as admitStart, K as allIntents, y as assertConsistentPools, ve as awaitEvent, se as awaitSignal, we as awaitSignalSuspending, de as awaitUpdate, Fe as closeWorkflowChildrenForParent, he as comparePendingOrder, Ve as completeSuspendingSignal, Be as decideAdmission, a as deferringControlsOf, Q as deleteIntent, qe as discardIntent, Ke as drainTick, I as dueIntents, d as durableClock, w as durableQueue, D as durableQueueModule, p as durableRateLimiterModule, ne as evaluateAdmission, s as getCurrentWorkflowExecutionId, b as getCurrentWorkflowRunId, x as getWorkflowFlowControl, k as getWorkflowVersionMetadata, o as hasCancelOn, c as hasFlowControl, De as inMemoryWorkflowEngineLayer, Oe as inspectWorkflow, ke as isFinishExpired, Ie as isStartExpired, m as isWorkflowWorkerLayer, q as linkExecution, ze as makeInMemoryRecorder, be as makeWorkflowRunRecorder, ge as makeWorkflowUpdateId, Y as newestEventAt, xe as nextSlotAt, H as noteIntentAttempt, te as pauseWorkflow, re as pendingSlotId, V as pendingWindow, G as persistDefer, Ce as planCancellations, le as pooledConcurrencyKey, h as processQueue, Pe as pruneAdmissions, T as queueWorker, S as rateLimit, W as readAdmissionState, ae as readPausedWorkflows, ee as readWatermark, ie as recordAdmission, oe as releaseLease, je as resolveAdmissionKeys, Me as resolveWorkflowMessageRun, Z as resumeWorkflow, Ee as sendWorkflowSignal, ye as sendWorkflowUpdate, ce as serialiseWorkflowRowForWire, _ as sleep, g as sleepUntil, u as step, A as stepIdempotencyKey, N as stepModule, pe as suspendingSignalDeferredName, z as sweepCancelOn, Ae as truncateWorkflowValue, i as validateFlowControl, f as withCompensation, M as workflow, l as workflowModule, Le as wrapWorkflowExecuteWithRunRecording, R as writeWatermark };
1
+ import { A as e, B as t, C as n, D as r, E as i, G as a, H as o, I as s, L as c, M as l, N as u, O as d, P as f, R as p, S as m, T as h, U as g, V as _, W as v, _ as y, a as b, b as x, c as S, d as C, f as w, g as T, h as E, i as D, j as O, k, l as A, m as j, n as M, o as N, p as P, r as F, s as I, t as L, u as R, v as z, w as B, x as V, y as H, z as U } from "./primitives-CyQZeT1t.js";
2
+ import { $ as W, A as G, At as K, B as q, C as J, Ct as Y, D as X, Dt as Z, E as Q, Et as $, F as ee, Ft as te, G as ne, H as re, I as ie, It as ae, J as oe, K as se, L as ce, Lt as le, M as ue, Mt as de, N as fe, Nt as pe, O as me, Ot as he, P as ge, Pt as _e, Q as ve, R as ye, Rt as be, S as xe, St as Se, T as Ce, Tt as we, U as Te, V as Ee, W as De, X as Oe, Y as ke, Z as Ae, _ as je, _t as Me, a as Ne, at as Pe, b as Fe, bt as Ie, c as Le, ct as Re, d as ze, dt as Be, et as Ve, f as He, ft as Ue, g as We, gt as Ge, h as Ke, ht as qe, i as Je, it as Ye, j as Xe, jt as Ze, k as Qe, kt as $e, l as et, lt as tt, m as nt, mt as rt, n as it, nt as at, o as ot, ot as st, p as ct, pt as lt, q as ut, r as dt, rt as ft, s as pt, st as mt, t as ht, tt as gt, u as _t, ut as vt, v as yt, vt as bt, w as xt, wt as St, x as Ct, xt as wt, y as Tt, yt as Et, z as Dt, zt as Ot } from "./src-DPkbBZDD.js";
3
+ export { ft as ADMISSIONS_TABLE, ct as BUDGET_HOLDS_TABLE, nt as BudgetHoldExpired, De as CANCEL_ON_WATERMARK, l as CurrentWorkflowExecutionId, u as CurrentWorkflowPatches, B as CurrentWorkflowReplayShape, f as CurrentWorkflowRunId, Ke as DEFAULT_BUDGET_HOLD_TIMEOUT_MS, ne as DEFAULT_COLD_LOOKBACK_MS, ye as DEFAULT_DRAIN_BATCH, se as DEFAULT_EVENT_BATCH, Ye as DEFAULT_LEASE_MS, Je as DEFAULT_MAX_RUN_RECLAIMS, Ne as DEFAULT_REPLAY_SHAPE_LIMIT, q as DEFAULT_STALL_AFTER_MS, Ee as DEFAULT_STALL_EVENT_LOOKBACK, re as DEFAULT_STALL_RUN_PAGE, fe as DEFAULT_SUSPEND_HINT_MS, d as DEFAULT_WORKFLOW_SCHEDULE_MAX_RUNTIME_MS, t as DEFERRING_CONTROLS, ut as EVENTS_TABLE, St as FlowControlKeyError, Pe as PAUSES_TABLE, st as PENDING_TABLE, oe as WATERMARKS_TABLE, L as WorkflowFlowControlProperty, M as WorkflowMessagesProperty, s as WorkflowRunRecorder, k as WorkflowScheduleProperty, c as WorkflowStepInterceptorTag, F as WorkflowVersionTypeId, D as WorkflowWorkerLayerTypeId, We as _voltroBudgetHoldsTable, de as _voltroWorkflowAdmissionsTable, pe as _voltroWorkflowPausesTable, _e as _voltroWorkflowPendingTable, ae as _voltroWorkflowRunEventsTable, le as _voltroWorkflowRunStepsTable, be as _voltroWorkflowRunsTable, te as _voltroWorkflowStartContextsTable, Ve as _voltroWorkflowWatermarksTable, gt as admitStart, mt as allIntents, _ as assertConsistentPools, Xe as awaitEvent, ue as awaitSignal, xt as awaitSignalSuspending, He as awaitUpdate, je as budgetHoldGeneration, yt as budgetHoldKey, Tt as budgetHoldSignalName, dt as closeWorkflowChildrenForParent, we as comparePendingOrder, Ce as completeSuspendingSignal, $ as decideAdmission, o as deferringControlsOf, Re as deleteIntent, tt as discardIntent, Dt as drainTick, vt as dueIntents, b as durableClock, N as durableQueue, I as durableQueueModule, S as durableRateLimiterModule, Be as evaluateAdmission, p as getCurrentWorkflowExecutionId, U as getCurrentWorkflowRunId, A as getWorkflowFlowControl, e as getWorkflowSchedule, R as getWorkflowVersionMetadata, g as hasCancelOn, v as hasFlowControl, Fe as heldBudgets, Ot as inMemoryWorkflowEngineLayer, it as inspectWorkflow, Z as isFinishExpired, he as isStartExpired, C as isWorkflowWorkerLayer, at as linkExecution, ht as makeInMemoryRecorder, h as makeReplayShapeTracker, ot as makeWorkflowRunRecorder, X as makeWorkflowUpdateId, ge as maybeHintSuspendingSignal, ve as newestEventAt, $e as nextSlotAt, i as nondeterminismEventPayload, pt as normaliseWorkflowPatches, Ue as noteIntentAttempt, lt as parkDelayedStart, w as patch, rt as pauseWorkflow, Ct as pendingBudgetHolds, qe as pendingSlotId, Ge as pendingWindow, Me as persistDefer, W as planCancellations, K as pooledConcurrencyKey, P as processQueue, bt as pruneAdmissions, j as queueWorker, E as rateLimit, Et as readAdmissionState, Ie as readPausedWorkflows, ke as readWatermark, wt as recordAdmission, xe as releaseBudgetHolds, Se as releaseLease, r as reportNondeterminism, ee as resetSuspendHintsForTest, Ze as resolveAdmissionKeys, Le as resolveRunGuardTuning, ie as resolveSuspendHintMs, me as resolveWorkflowMessageRun, Y as resumeWorkflow, Qe as sendWorkflowSignal, G as sendWorkflowUpdate, et as serialiseWorkflowRowForWire, ce as setSuspendSignalHintMs, T as sleep, y as sleepUntil, z as step, H as stepIdempotencyKey, x as stepModule, J as suspendForBudget, Q as suspendingSignalDeferredName, Oe as sweepCancelOn, Te as sweepStalledRuns, _t as truncateWorkflowValue, a as validateFlowControl, O as validateWorkflowSchedule, V as withCompensation, m as workflow, n as workflowModule, ze as wrapWorkflowExecuteWithRunRecording, Ae as writeWatermark };
@@ -1,44 +1,44 @@
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 g, Schedule as _, Schema as v } from "effect";
2
+ import { Cause as u, Context as d, Cron as f, Duration as p, Effect as m, Either as h, Exit as ee, FiberRef as g, Option as te, Schedule as _, Schema as ne } from "effect";
3
3
  //#region src/flowControl.ts
4
- var y = (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), b = (e) => e?.cancelOn !== void 0 && e.cancelOn.length > 0, x = [
4
+ var re = (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), v = (e) => e?.cancelOn !== void 0 && e.cancelOn.length > 0, y = [
5
5
  "debounce",
6
6
  "batch",
7
7
  "throttle",
8
8
  "concurrency"
9
- ], S = (e) => {
9
+ ], b = (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
- }, C = (e, t, n) => {
13
+ }, x = (e, t, n) => {
14
14
  let r;
15
15
  try {
16
- r = f.toMillis(f.decode(e));
16
+ r = p.toMillis(p.decode(e));
17
17
  } catch {
18
18
  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.`);
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
- }, w = (e, t, n) => {
22
+ }, S = (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
- }, T = (e, t, n) => {
25
+ }, C = (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
- }, E = (e) => {
28
+ }, w = (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
- }, D = (e) => {
33
+ }, T = (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 = C(e.period, "debounce.period", t), a = e.timeout === void 0 ? void 0 : C(e.timeout, "debounce.timeout", t);
38
+ let e = n.debounce, i = x(e.period, "debounce.period", t), a = e.timeout === void 0 ? void 0 : x(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: T(e.key, "debounce.key", t),
41
+ key: C(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: T(e.key, "singleton.key", t),
50
+ key: C(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: w(e.limit, "concurrency.limit", t),
59
- ...e.key === void 0 ? {} : { key: T(e.key, "concurrency.key", t) },
58
+ limit: S(e.limit, "concurrency.limit", t),
59
+ ...e.key === void 0 ? {} : { key: C(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: w(e.limit, "throttle.limit", t),
67
- periodMs: C(e.period, "throttle.period", t),
68
- ...e.key === void 0 ? {} : { key: T(e.key, "throttle.key", t) }
66
+ limit: S(e.limit, "throttle.limit", t),
67
+ periodMs: x(e.period, "throttle.period", t),
68
+ ...e.key === void 0 ? {} : { key: C(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: w(e.limit, "rateLimit.limit", t),
75
- periodMs: C(e.period, "rateLimit.period", t),
76
- ...e.key === void 0 ? {} : { key: T(e.key, "rateLimit.key", t) }
74
+ limit: S(e.limit, "rateLimit.limit", t),
75
+ periodMs: x(e.period, "rateLimit.period", t),
76
+ ...e.key === void 0 ? {} : { key: C(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 && !E(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.`);
81
+ if (e.payloadSchema !== void 0 && !w(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: T(i.key, "batch.key", t) },
84
- maxSize: w(i.maxSize, "batch.maxSize", t),
85
- timeoutMs: C(i.timeout, "batch.timeout", t),
83
+ ...i.key === void 0 ? {} : { key: C(i.key, "batch.key", t) },
84
+ maxSize: S(i.maxSize, "batch.maxSize", t),
85
+ timeoutMs: x(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 : C(e.start, "timeouts.start", t), a = e.finish === void 0 ? void 0 : C(e.finish, "timeouts.finish", t);
94
+ let e = n.timeouts, i = e.start === void 0 ? void 0 : x(e.start, "timeouts.start", t), a = e.finish === void 0 ? void 0 : x(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 : C(e.within, `${r}.within`, t);
114
+ let i = e.within === void 0 ? void 0 : x(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 && S(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.`);
125
+ if (r.timeouts?.startMs !== void 0 && b(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
- }, ee = (e) => {
127
+ }, E = (e) => {
128
128
  let t = /* @__PURE__ */ new Map();
129
129
  for (let n of e) {
130
130
  let e = n?.concurrency;
@@ -137,103 +137,191 @@ 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), N = () => h.get(A), P = class extends d.Tag("@voltro/WorkflowStepInterceptor")() {}, F = (e) => {
140
+ }, D = class extends d.Tag("@voltro/WorkflowRunRecorder")() {}, O = g.unsafeMake(void 0), k = g.unsafeMake(void 0), A = g.unsafeMake(void 0), j = g.unsafeMake([]), M = () => g.get(O), N = () => g.get(k), P = class extends d.Tag("@voltro/WorkflowStepInterceptor")() {}, F = 1440 * 6e4, ie = /* @__PURE__ */ new Set([
141
+ "skip",
142
+ "buffer",
143
+ "cancelOther"
144
+ ]), ae = /* @__PURE__ */ new Set([
145
+ "skip",
146
+ "latest",
147
+ "all"
148
+ ]), I = (e, t) => {
149
+ if (t === void 0) return;
150
+ 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.`);
151
+ let n = f.parse(t.cron, t.timezone);
152
+ if (h.isLeft(n)) throw Error(`workflow '${e}': schedule.cron "${t.cron}" (tz="${t.timezone}") is not a valid cron expression — ${String(n.left)}`);
153
+ let r = t.onOverlap ?? "skip";
154
+ if (!ie.has(r)) throw Error(`workflow '${e}': schedule.onOverlap must be 'skip' | 'buffer' | 'cancelOther', got ${JSON.stringify(r)}`);
155
+ let i = t.backfill ?? "skip";
156
+ if (!ae.has(i)) throw Error(`workflow '${e}': schedule.backfill must be 'skip' | 'latest' | 'all', got ${JSON.stringify(i)}`);
157
+ let a = F;
158
+ return t.maxRuntime !== void 0 && (a = L(t.maxRuntime, e)), {
159
+ cron: t.cron,
160
+ timezone: t.timezone,
161
+ ...t.payload === void 0 ? {} : { payload: t.payload },
162
+ onOverlap: r,
163
+ backfill: i,
164
+ maxRuntimeMs: a
165
+ };
166
+ }, L = (e, t) => {
167
+ let n;
168
+ try {
169
+ n = p.toMillis(p.decode(e));
170
+ } catch {
171
+ 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.`);
172
+ }
173
+ if (!Number.isFinite(n) || n <= 0) throw Error(`workflow '${t}': schedule.maxRuntime must be a positive finite duration`);
174
+ return n;
175
+ }, R = "__voltroWorkflowSchedule", z = (e) => {
176
+ if (typeof e != "object" || !e) return;
177
+ let t = e[R];
178
+ return t === void 0 ? void 0 : t;
179
+ }, B = (e) => {
180
+ let t = /* @__PURE__ */ new Map();
181
+ for (let n of e) t.set(n.stepName, (t.get(n.stepName) ?? 0) + 1);
182
+ let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set(), i = (e) => r.has(e) ? !1 : (r.add(e), !0);
183
+ return {
184
+ reach: (e) => {
185
+ let r = (n.get(e) ?? 0) + 1;
186
+ n.set(e, r);
187
+ let a = t.get(e) ?? 0;
188
+ if (a !== 0 && !(r <= a) && i(`extra:${e}`)) return {
189
+ kind: "extra-step-occurrence",
190
+ stepName: e,
191
+ recorded: a,
192
+ reached: r,
193
+ 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.`
194
+ };
195
+ },
196
+ settle: () => {
197
+ let e = [];
198
+ for (let [r, a] of t) (n.get(r) ?? 0) > 0 || i(`unreached:${r}`) && e.push({
199
+ kind: "unreached-step",
200
+ stepName: r,
201
+ recorded: a,
202
+ reached: 0,
203
+ 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.`
204
+ });
205
+ return e;
206
+ }
207
+ };
208
+ }, V = g.unsafeMake(void 0), H = (e) => ({
209
+ kind: e.kind,
210
+ stepName: e.stepName,
211
+ recorded: e.recorded,
212
+ reached: e.reached,
213
+ detail: e.detail
214
+ }), U = (e) => m.gen(function* () {
215
+ if (e.length === 0) return;
216
+ let t = yield* g.get(O), n = yield* m.serviceOption(D);
217
+ if (t === void 0 || n._tag !== "Some") return;
218
+ let r = n.value;
219
+ for (let n of e) yield* m.promise(() => r.recordEvent({
220
+ runId: t,
221
+ eventType: "nondeterminism-suspected",
222
+ payload: H(n)
223
+ }).then(() => void 0).catch(() => void 0));
224
+ }), W = (e) => {
141
225
  if (typeof e != "object" || !e) return;
142
226
  let t = e.retryAfterMillis;
143
- if (typeof t == "number" && Number.isFinite(t) && t >= 0) return f.millis(t);
227
+ if (typeof t == "number" && Number.isFinite(t) && t >= 0) return p.millis(t);
144
228
  let n = e.retryAfter;
145
- if (typeof n == "number" && Number.isFinite(n) && n >= 0) return f.seconds(n);
146
- }, I = (e) => f.decode(e), L = (e) => typeof e == "object" && e && "_tag" in e ? String(e._tag) : void 0, R = (e) => e !== void 0 && (e.maxAttempts ?? 3) > 1, z = (e) => {
229
+ if (typeof n == "number" && Number.isFinite(n) && n >= 0) return p.seconds(n);
230
+ }, G = (e) => p.decode(e), K = (e) => typeof e == "object" && e && "_tag" in e ? String(e._tag) : void 0, q = (e) => e !== void 0 && (e.maxAttempts ?? 3) > 1, J = (e) => {
147
231
  if (e.retryable) return e.retryable;
148
232
  if (e.retryableErrors && e.retryableErrors.length > 0) {
149
233
  let t = new Set(e.retryableErrors);
150
234
  return (e) => {
151
- let n = L(e);
235
+ let n = K(e);
152
236
  return n !== void 0 && t.has(n);
153
237
  };
154
238
  }
155
239
  return () => !0;
156
- }, B = (e) => {
157
- let t = e.baseDelay ?? "200 millis", n = e.strategy ?? "exponential", r = e.maxAttempts ?? 3, i = n === "linear" ? _.linear(I(e.step ?? t)) : n === "fixed" ? _.spaced(I(t)) : _.exponential(I(t), e.factor ?? 2);
240
+ }, oe = (e) => {
241
+ let t = e.baseDelay ?? "200 millis", n = e.strategy ?? "exponential", r = e.maxAttempts ?? 3, i = n === "linear" ? _.linear(G(e.step ?? t)) : n === "fixed" ? _.spaced(G(t)) : _.exponential(G(t), e.factor ?? 2);
158
242
  if (e.maxDelay !== void 0) {
159
- let t = I(e.maxDelay);
160
- i = _.modifyDelay(i, (e, n) => f.min(n, t));
243
+ let t = G(e.maxDelay);
244
+ i = _.modifyDelay(i, (e, n) => p.min(n, t));
161
245
  }
162
246
  (e.jitter ?? !0) === !0 && (i = _.jittered(i));
163
247
  let a = _.intersect(i, _.recurs(Math.max(0, r - 1)));
164
- return e.maxElapsed !== void 0 && (a = _.upTo(I(e.maxElapsed))(a)), a;
165
- }, V = (e, t) => {
166
- let n = f.toMillis(I(e.baseDelay ?? "200 millis")), r = e.strategy ?? "exponential", i = r === "fixed" ? n : r === "linear" ? n + f.toMillis(I(e.step ?? e.baseDelay ?? "200 millis")) * (t - 1) : n * (e.factor ?? 2) ** (t - 1);
167
- return e.maxDelay !== void 0 && (i = Math.min(i, f.toMillis(I(e.maxDelay)))), (e.jitter ?? !0) === !0 && (i *= Math.random()), i;
168
- }, H = (e, t, n, r) => p.gen(function* () {
169
- let i = t.maxAttempts ?? 3, a = t.maxElapsed === void 0 ? Infinity : f.toMillis(I(t.maxElapsed)), o = yield* p.sync(() => Date.now()), s = 0;
248
+ return e.maxElapsed !== void 0 && (a = _.upTo(G(e.maxElapsed))(a)), a;
249
+ }, se = (e, t) => {
250
+ let n = p.toMillis(G(e.baseDelay ?? "200 millis")), r = e.strategy ?? "exponential", i = r === "fixed" ? n : r === "linear" ? n + p.toMillis(G(e.step ?? e.baseDelay ?? "200 millis")) * (t - 1) : n * (e.factor ?? 2) ** (t - 1);
251
+ return e.maxDelay !== void 0 && (i = Math.min(i, p.toMillis(G(e.maxDelay)))), (e.jitter ?? !0) === !0 && (i *= Math.random()), i;
252
+ }, ce = (e, t, n, r) => m.gen(function* () {
253
+ let i = t.maxAttempts ?? 3, a = t.maxElapsed === void 0 ? Infinity : p.toMillis(G(t.maxElapsed)), o = yield* m.sync(() => Date.now()), s = 0;
170
254
  for (;;) {
171
- let c = yield* p.exit(e);
172
- if (m.isSuccess(c)) return c.value;
173
- let l = c.cause, d = u.failureOption(l), h = g.isSome(d) ? d.value : u.squash(l);
255
+ let c = yield* m.exit(e);
256
+ if (ee.isSuccess(c)) return c.value;
257
+ let l = c.cause, d = u.failureOption(l), f = te.isSome(d) ? d.value : u.squash(l);
174
258
  s += 1;
175
- let _ = (yield* p.sync(() => Date.now())) - o;
176
- if (s >= i || !n(h) || _ >= a) return yield* p.failCause(l);
177
- r?.(h);
178
- let v = F(h), y = v === void 0 ? V(t, s) : f.toMillis(v);
179
- yield* p.sleep(f.millis(y));
259
+ let h = (yield* m.sync(() => Date.now())) - o;
260
+ if (s >= i || !n(f) || h >= a) return yield* m.failCause(l);
261
+ r?.(f);
262
+ let g = W(f), _ = g === void 0 ? se(t, s) : p.toMillis(g);
263
+ yield* m.sleep(p.millis(_));
180
264
  }
181
- }), U = (e, t, n) => {
182
- if (!R(t)) return e;
183
- let r = z(t);
184
- if (t.respectRetryAfter === !0) return H(e, t, r, n);
185
- let i = B(t), a = n ? p.tapError(e, (e) => p.sync(() => {
265
+ }), le = (e, t, n) => {
266
+ if (!q(t)) return e;
267
+ let r = J(t);
268
+ if (t.respectRetryAfter === !0) return ce(e, t, r, n);
269
+ let i = oe(t), a = n ? m.tapError(e, (e) => m.sync(() => {
186
270
  r(e) && n(e);
187
271
  })) : e;
188
- return p.retry(a, {
272
+ return m.retry(a, {
189
273
  schedule: i,
190
274
  while: r
191
275
  });
192
- }, W = Symbol.for("voltro.workflow.workerLayer"), G = Symbol.for("voltro.workflow.version"), K = "__voltroWorkflowMessages", q = "__voltroWorkflowFlowControl", J = (e) => typeof e == "object" && !!e && e[W] === !0, Y = (e) => typeof e == "object" && e && e[G] !== void 0 ? e[G] : {
276
+ }, Y = Symbol.for("voltro.workflow.workerLayer"), X = Symbol.for("voltro.workflow.version"), Z = "__voltroWorkflowMessages", Q = "__voltroWorkflowFlowControl", ue = (e) => typeof e == "object" && !!e && e[Y] === !0, de = (e) => typeof e == "object" && e && e[X] !== void 0 ? e[X] : {
193
277
  version: "1",
194
278
  compatibleWith: ["1"],
195
279
  patches: []
196
- }, X = ((e) => {
280
+ }, fe = ((e) => {
197
281
  let t = c.make(e), n = e.suspendOnFailure === !0 ? t.annotate(c.SuspendOnFailure, !0) : t, r = String(e.version ?? "1"), i = {
198
282
  version: r,
199
283
  compatibleWith: (e.compatibleWith ?? [r]).map(String),
200
284
  patches: [...e.patches ?? []]
201
285
  }, a = {
202
286
  signals: { ...e.messages?.signals ?? {} },
203
- updates: { ...e.messages?.updates ?? {} },
204
- queries: { ...e.messages?.queries ?? {} }
287
+ updates: { ...e.messages?.updates ?? {} }
205
288
  };
206
- Object.defineProperty(n, G, {
289
+ Object.defineProperty(n, X, {
207
290
  value: i,
208
291
  enumerable: !1
209
- }), Object.defineProperty(n, K, {
292
+ }), Object.defineProperty(n, Z, {
210
293
  value: a,
211
294
  enumerable: !1
212
295
  });
213
- let o = D({
296
+ let o = T({
214
297
  workflowName: e.name,
215
298
  payloadSchema: e.payload,
216
299
  control: e
217
300
  });
218
- return o !== void 0 && Object.defineProperty(n, q, {
301
+ o !== void 0 && Object.defineProperty(n, Q, {
219
302
  value: o,
220
303
  enumerable: !1
304
+ });
305
+ let s = I(e.name, e.schedule);
306
+ return s !== void 0 && Object.defineProperty(n, R, {
307
+ value: s,
308
+ enumerable: !1
221
309
  }), n;
222
- }), Z = (e) => {
310
+ }), pe = (e) => {
223
311
  if (typeof e != "object" || !e) return;
224
- let t = e[q];
312
+ let t = e[Q];
225
313
  return t === void 0 ? void 0 : t;
226
- }, Q = i.make, te = i.process, ne = ((...e) => {
314
+ }, me = i.make, he = i.process, ge = ((...e) => {
227
315
  let t = i.worker(...e);
228
- return Object.defineProperty(t, W, {
316
+ return Object.defineProperty(t, Y, {
229
317
  value: !0,
230
318
  enumerable: !1
231
319
  }), t;
232
- }), re = o.rateLimit, $ = (e) => p.gen(function* () {
233
- let t = yield* k, r = yield* p.serviceOption(O), i = f.toMillis(f.decode(e.duration));
320
+ }), _e = o.rateLimit, $ = (e) => m.gen(function* () {
321
+ let t = yield* O, r = yield* m.serviceOption(D), i = p.toMillis(p.decode(e.duration));
234
322
  if (t !== void 0 && r._tag === "Some") {
235
- let a = r.value, o = new Date(Date.now() + i).toISOString(), s = yield* j;
236
- yield* p.promise(() => a.recordEvent({
323
+ let a = r.value, o = new Date(Date.now() + i).toISOString(), s = yield* A;
324
+ yield* m.promise(() => a.recordEvent({
237
325
  runId: t,
238
326
  eventType: "timer-set",
239
327
  payload: {
@@ -244,7 +332,7 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
244
332
  }
245
333
  }).catch(() => {}));
246
334
  let c = Date.now();
247
- yield* n.sleep(e), yield* p.promise(() => a.recordEvent({
335
+ yield* n.sleep(e), yield* m.promise(() => a.recordEvent({
248
336
  runId: t,
249
337
  eventType: "timer-fired",
250
338
  payload: {
@@ -256,18 +344,18 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
256
344
  return;
257
345
  }
258
346
  yield* n.sleep(e);
259
- }), ie = (t) => p.gen(function* () {
347
+ }), ve = (t) => m.gen(function* () {
260
348
  let n = (yield* e.make({
261
349
  name: `sleepUntil:${t.name}`,
262
- success: v.Number,
263
- execute: p.sync(() => t.until instanceof Date ? t.until.getTime() : t.until)
350
+ success: ne.Number,
351
+ execute: m.sync(() => t.until instanceof Date ? t.until.getTime() : t.until)
264
352
  })) - Date.now();
265
353
  n <= 0 || (yield* $({
266
354
  name: t.name,
267
355
  duration: `${n} millis`
268
356
  }));
269
- }), ae = (t, n, r, i) => p.gen(function* () {
270
- let a = yield* k, o = yield* e.CurrentAttempt, s = yield* p.serviceOption(O), c = yield* p.serviceOption(P), l = c._tag === "Some" ? c.value.interceptor(n, {
357
+ }), ye = (t, n, r, i) => m.gen(function* () {
358
+ let a = yield* O, o = yield* e.CurrentAttempt, s = yield* m.serviceOption(D), c = yield* m.serviceOption(P), l = c._tag === "Some" ? c.value.interceptor(n, {
271
359
  runId: a ?? "unrecorded",
272
360
  stepName: t,
273
361
  attempt: o
@@ -276,7 +364,7 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
276
364
  f = s.value;
277
365
  let e = i === void 0 ? void 0 : (({ retryable: e, ...t }) => t)(i);
278
366
  try {
279
- d = yield* p.promise(() => f.startStep({
367
+ d = yield* m.promise(() => f.startStep({
280
368
  runId: a,
281
369
  stepName: t,
282
370
  attempt: o,
@@ -287,16 +375,16 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
287
375
  d = void 0;
288
376
  }
289
377
  }
290
- let m = Date.now();
291
- return yield* U(l, i).pipe(p.tap((e) => d && f ? p.promise(async () => {
378
+ let p = Date.now();
379
+ return yield* le(l, i).pipe(m.tap((e) => d && f ? m.promise(async () => {
292
380
  try {
293
381
  await f.endStepSuccess({
294
382
  stepRecordId: d,
295
383
  output: e,
296
- durationMs: Date.now() - m
384
+ durationMs: Date.now() - p
297
385
  });
298
386
  } catch {}
299
- }) : p.void), p.tapErrorCause((e) => d && f && !u.isInterruptedOnly(e) ? p.promise(async () => {
387
+ }) : m.void), m.tapErrorCause((e) => d && f && !u.isInterruptedOnly(e) ? m.promise(async () => {
300
388
  try {
301
389
  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;
302
390
  await f.endStepFailure({
@@ -308,16 +396,27 @@ var y = (e) => e !== void 0 && (e.debounce !== void 0 || e.singleton !== void 0
308
396
  failures: n,
309
397
  defects: r
310
398
  },
311
- durationMs: Date.now() - m
399
+ durationMs: Date.now() - p
312
400
  });
313
401
  } catch {}
314
- }) : p.void));
315
- }), oe = (t) => {
402
+ }) : m.void));
403
+ }), be = (e) => m.gen(function* () {
404
+ let t = yield* g.get(V);
405
+ if (t === void 0) return;
406
+ let n = t.reach(e);
407
+ n !== void 0 && (yield* U([n]));
408
+ }), xe = (e, t) => {
409
+ let n = e;
410
+ return {
411
+ ...e,
412
+ commit: () => m.zipRight(be(t), n)
413
+ };
414
+ }, Se = (t) => {
316
415
  let { input: n, retry: r, ...i } = t;
317
- return e.make({
416
+ return xe(e.make({
318
417
  ...i,
319
- execute: ae(i.name, i.execute, n, r)
320
- });
321
- }, se = c.withCompensation, ce = e.idempotencyKey;
418
+ execute: ye(i.name, i.execute, n, r)
419
+ }), i.name);
420
+ }, Ce = (e) => m.map(g.get(j), (t) => t.includes(e)), we = c.withCompensation, Te = e.idempotencyKey;
322
421
  //#endregion
323
- export { x as A, A as C, P as D, O as E, D as F, S as M, b as N, N as O, y as P, l as S, j as T, oe as _, r as a, se as b, s as c, J as d, te as f, ie as g, $ as h, W as i, ee as j, M as k, Z as l, re as m, K as n, Q as o, ne as p, G as r, a as s, q as t, Y as u, ce as v, k as w, X as x, t as y };
422
+ export { z as A, y as B, l as C, U as D, H as E, A as F, T as G, b as H, D as I, P as L, k as M, j as N, F as O, O as P, N as R, fe as S, B as T, v as U, E as V, re as W, ve as _, r as a, t as b, s as c, ue as d, Ce as f, $ as g, _e as h, Y as i, I as j, R as k, pe as l, ge as m, Z as n, me as o, he as p, X as r, a as s, Q as t, de as u, Se as v, V as w, we as x, Te as y, M as z };