@fluidgrids/workflows 2026.1027.0 → 2026.1028.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/README.md +170 -18
  2. package/dist/activation-BBh1p82z.d.cts +57 -0
  3. package/dist/activation-DnhG7SmF.d.ts +57 -0
  4. package/dist/assemble-BLqQ8lSu.d.cts +39 -0
  5. package/dist/assemble-DWgaXHd-.d.ts +39 -0
  6. package/dist/chunk-2DP2Y6EU.cjs +832 -0
  7. package/dist/chunk-2J6TF7YI.cjs +86 -0
  8. package/dist/chunk-3FOTFQ3J.js +1622 -0
  9. package/dist/chunk-4LYSEANA.js +199 -0
  10. package/dist/{chunk-KUTMY2IO.cjs → chunk-57MSZ24T.cjs} +162 -98
  11. package/dist/{chunk-BWSLWF2E.js → chunk-5HDSBTBX.js} +99 -32
  12. package/dist/chunk-623FVQSN.cjs +251 -0
  13. package/dist/{chunk-4DPEGDPW.js → chunk-6FSHT5IL.js} +4 -4
  14. package/dist/{chunk-REV7ZOA4.js → chunk-7AAZGVKD.js} +1 -35
  15. package/dist/chunk-7NQ37GZU.js +73 -0
  16. package/dist/chunk-ABFZWYHT.js +612 -0
  17. package/dist/{chunk-SS4LT2IP.js → chunk-BD7ZPG53.js} +5 -10
  18. package/dist/chunk-BO6OVILK.js +79 -0
  19. package/dist/chunk-C5OLWZ42.js +245 -0
  20. package/dist/chunk-CBL5JSCC.cjs +75 -0
  21. package/dist/{chunk-LSKSBVL4.cjs → chunk-CPDK3K5N.cjs} +6 -6
  22. package/dist/chunk-CSNWNFKU.cjs +1635 -0
  23. package/dist/chunk-DJYMDLV5.js +227 -0
  24. package/dist/{chunk-X4HKU3MX.js → chunk-E2VK7J2C.js} +3 -1
  25. package/dist/chunk-FMSW2HDF.cjs +267 -0
  26. package/dist/chunk-FQIHX7YI.cjs +80 -0
  27. package/dist/chunk-FR7KYWRO.cjs +41 -0
  28. package/dist/{chunk-AU3YW7FZ.cjs → chunk-GBQ33SIZ.cjs} +46 -51
  29. package/dist/{chunk-RRQ5HOBF.cjs → chunk-GVTZMA5C.cjs} +4 -4
  30. package/dist/chunk-H7KEVW2M.js +816 -0
  31. package/dist/chunk-HR3BN4C4.cjs +27 -0
  32. package/dist/chunk-IISBRUWJ.js +13 -0
  33. package/dist/chunk-JD2VQIDZ.cjs +15 -0
  34. package/dist/{chunk-PL73GJR4.js → chunk-JZ4TOOLN.js} +1 -1
  35. package/dist/chunk-L24YIZY7.cjs +207 -0
  36. package/dist/chunk-LNUQE6D6.js +39 -0
  37. package/dist/{chunk-BYJ7QTLY.cjs → chunk-NEIUQASE.cjs} +13 -13
  38. package/dist/chunk-P6TA5EZT.cjs +634 -0
  39. package/dist/chunk-PDHLTDZB.js +72 -0
  40. package/dist/chunk-PMCM2OH4.js +46 -0
  41. package/dist/chunk-PZCVF76Q.cjs +868 -0
  42. package/dist/{chunk-GO34UHSY.js → chunk-QAN5MZEM.js} +3 -3
  43. package/dist/{chunk-27HASETB.cjs → chunk-QKZL3ONM.cjs} +3 -1
  44. package/dist/chunk-SAENRNBJ.cjs +52 -0
  45. package/dist/{chunk-LMX35GNQ.js → chunk-SMCANK3F.js} +5 -4
  46. package/dist/{chunk-IZQNUNSU.cjs → chunk-SX2PNKKT.cjs} +18 -17
  47. package/dist/{chunk-LRM6JXJA.cjs → chunk-TBDXTV22.cjs} +0 -37
  48. package/dist/chunk-VOKMAAJP.js +848 -0
  49. package/dist/chunk-XB53G2DK.js +25 -0
  50. package/dist/chunk-Z2Y65YOY.cjs +7 -0
  51. package/dist/codegen/index.cjs +9 -7
  52. package/dist/codegen/index.d.cts +2 -2
  53. package/dist/codegen/index.d.ts +2 -2
  54. package/dist/codegen/index.js +6 -5
  55. package/dist/file-BOoHZgoQ.d.cts +1557 -0
  56. package/dist/file-yuPCFU5b.d.ts +1557 -0
  57. package/dist/history/index.cjs +287 -0
  58. package/dist/history/index.d.cts +157 -0
  59. package/dist/history/index.d.ts +157 -0
  60. package/dist/history/index.js +5 -0
  61. package/dist/index.cjs +134 -36
  62. package/dist/index.d.cts +137 -9
  63. package/dist/index.d.ts +137 -9
  64. package/dist/index.js +8 -3
  65. package/dist/ir/index.cjs +161 -165
  66. package/dist/ir/index.d.cts +32 -12
  67. package/dist/ir/index.d.ts +32 -12
  68. package/dist/ir/index.js +54 -61
  69. package/dist/lower-BuSvAFqi.d.cts +129 -0
  70. package/dist/lower-C_Qv_34S.d.ts +129 -0
  71. package/dist/lower-types-nofRXw9c.d.cts +15 -0
  72. package/dist/lower-types-nofRXw9c.d.ts +15 -0
  73. package/dist/{manifest-Duf-gHdO.d.cts → manifest-0OLw0i7k.d.cts} +1 -1
  74. package/dist/{manifest-Bp9ZJlav.d.ts → manifest-C8N6HDYl.d.ts} +1 -1
  75. package/dist/node-evaluator-CJNP4GHX.js +12 -0
  76. package/dist/node-evaluator-DMKPKUWA.cjs +22 -0
  77. package/dist/quickjs/index.cjs +256 -78
  78. package/dist/quickjs/index.d.cts +48 -7
  79. package/dist/quickjs/index.d.ts +48 -7
  80. package/dist/quickjs/index.js +254 -79
  81. package/dist/roundtrip/index.cjs +404 -129
  82. package/dist/roundtrip/index.d.cts +43 -8
  83. package/dist/roundtrip/index.d.ts +43 -8
  84. package/dist/roundtrip/index.js +260 -19
  85. package/dist/runtime/index.cjs +90 -0
  86. package/dist/runtime/index.d.cts +297 -0
  87. package/dist/runtime/index.d.ts +297 -0
  88. package/dist/runtime/index.js +8 -0
  89. package/dist/testing/index.cjs +1057 -0
  90. package/dist/testing/index.d.cts +305 -0
  91. package/dist/testing/index.d.ts +305 -0
  92. package/dist/testing/index.js +1037 -0
  93. package/dist/{types-Dr2Fn1Ax.d.ts → types-BGoPzgcl.d.cts} +1 -1
  94. package/dist/{types-Dr2Fn1Ax.d.cts → types-BGoPzgcl.d.ts} +1 -1
  95. package/dist/types-CpBBjaGX.d.cts +380 -0
  96. package/dist/types-DV-HX_Gt.d.ts +380 -0
  97. package/dist/{assemble-DMOuaxRI.d.ts → workflow-Bpr3vnA_.d.ts} +60 -162
  98. package/dist/workflow-C2a05WUJ.d.ts +444 -0
  99. package/dist/{assemble-BJo9TECS.d.cts → workflow-FXUkpIBc.d.cts} +60 -162
  100. package/dist/workflow-J-yYixny.d.cts +444 -0
  101. package/fixtures/README.md +128 -0
  102. package/fixtures/histories/activity-failure-fails-run.history.json +163 -0
  103. package/fixtures/histories/activity-retry-then-success.history.json +147 -0
  104. package/fixtures/histories/cancel-activity-abandon.history.json +126 -0
  105. package/fixtures/histories/cancel-activity-compensate.history.json +307 -0
  106. package/fixtures/histories/cancel-concurrent-non-cancellable.history.json +234 -0
  107. package/fixtures/histories/cancel-concurrent-scope-timeout.history.json +184 -0
  108. package/fixtures/histories/cancel-condition-after-cancel.history.json +200 -0
  109. package/fixtures/histories/cancel-during-timer.history.json +123 -0
  110. package/fixtures/histories/cancel-saga-compensations.history.json +325 -0
  111. package/fixtures/histories/cancel-scope-timeout.history.json +148 -0
  112. package/fixtures/histories/child-abandon-outlives-parent.history.json +191 -0
  113. package/fixtures/histories/child-cancel-default.history.json +234 -0
  114. package/fixtures/histories/child-cancel-request.history.json +206 -0
  115. package/fixtures/histories/child-durable-child-side.history.json +124 -0
  116. package/fixtures/histories/child-durable-result.history.json +163 -0
  117. package/fixtures/histories/child-failure-caught.history.json +166 -0
  118. package/fixtures/histories/child-graph-by-key.history.json +138 -0
  119. package/fixtures/histories/child-terminated-by-parent-close.history.json +85 -0
  120. package/fixtures/histories/continue-as-new-first-run.history.json +146 -0
  121. package/fixtures/histories/continue-as-new-history-limit.history.json +489 -0
  122. package/fixtures/histories/continue-as-new-last-run.history.json +147 -0
  123. package/fixtures/histories/continue-as-new-suggested.history.json +352 -0
  124. package/fixtures/histories/details-and-context.history.json +176 -0
  125. package/fixtures/histories/deterministic-values.history.json +128 -0
  126. package/fixtures/histories/engine-builtins.history.json +172 -0
  127. package/fixtures/histories/gather-activities.history.json +291 -0
  128. package/fixtures/histories/gather-all-settled.history.json +219 -0
  129. package/fixtures/histories/gather-mixed.history.json +281 -0
  130. package/fixtures/histories/input-during-running-task.history.json +111 -0
  131. package/fixtures/histories/nondeterminism-reordered.history.json +218 -0
  132. package/fixtures/histories/patched-deprecated.history.json +271 -0
  133. package/fixtures/histories/patched-new-run.history.json +270 -0
  134. package/fixtures/histories/patched-old-history.history.json +190 -0
  135. package/fixtures/histories/race-activity-wins.history.json +152 -0
  136. package/fixtures/histories/race-signal-beats-child.history.json +161 -0
  137. package/fixtures/histories/race-timeout-wins.history.json +118 -0
  138. package/fixtures/histories/side-effect-recorded.history.json +153 -0
  139. package/fixtures/histories/signal-buffered-at-start.history.json +157 -0
  140. package/fixtures/histories/signal-default-handler.history.json +187 -0
  141. package/fixtures/histories/signal-handler.history.json +191 -0
  142. package/fixtures/histories/signal-parent-child-side.history.json +132 -0
  143. package/fixtures/histories/signal-parent.history.json +202 -0
  144. package/fixtures/histories/signal-run-delivered.history.json +128 -0
  145. package/fixtures/histories/signal-run-undelivered.history.json +134 -0
  146. package/fixtures/histories/signal-wait.history.json +111 -0
  147. package/fixtures/histories/task-failure-code-error.history.json +137 -0
  148. package/fixtures/histories/task-failure-then-transient-attempt.history.json +140 -0
  149. package/fixtures/histories/timer-condition-met.history.json +201 -0
  150. package/fixtures/histories/timer-condition-timeout.history.json +118 -0
  151. package/fixtures/histories/timer-sleep-once.history.json +118 -0
  152. package/fixtures/histories/timer-sleep-sequence.history.json +210 -0
  153. package/fixtures/histories/update-accepted-completed.history.json +149 -0
  154. package/fixtures/histories/update-with-start-rejected-validation.history.json +91 -0
  155. package/package.json +85 -20
  156. package/schema/history-file.schema.json +2544 -0
  157. package/schema/ir-v2.schema.json +16 -0
  158. package/schema/run-event.schema.json +2374 -0
  159. package/schema/workflow-command.schema.json +1095 -0
  160. package/schema/workflow-task.schema.json +3560 -0
  161. package/dist/chunk-265J2FCH.cjs +0 -33
  162. package/dist/chunk-LUXCXFOE.cjs +0 -269
  163. package/dist/chunk-S34NJE3A.js +0 -262
  164. package/dist/chunk-SRQRLWOS.js +0 -31
  165. package/dist/lower-DcOY8ux0.d.cts +0 -49
  166. package/dist/lower-Dw5grNrI.d.ts +0 -49
  167. package/dist/node-evaluator-2GTUZVPK.cjs +0 -17
  168. package/dist/node-evaluator-RMYEWCXZ.js +0 -8
@@ -0,0 +1,612 @@
1
+ import { PHASE_C_COMMANDS, PHASE_B_CORE_COMMANDS, PHASE_B_PARITY_COMMANDS, TERMINAL_COMMANDS, isInputEvent, isCommandEvent } from './chunk-DJYMDLV5.js';
2
+ import { isActivityNodeTypeAllowed } from './chunk-BO6OVILK.js';
3
+
4
+ // src/history/commands.ts
5
+ function isCommandEnabled(type, enabled = "core") {
6
+ if (PHASE_C_COMMANDS.has(type)) return false;
7
+ if (PHASE_B_CORE_COMMANDS.has(type)) return true;
8
+ return enabled === "parity" && PHASE_B_PARITY_COMMANDS.has(type);
9
+ }
10
+ function isWorkflowCommandEnabled(command, enabled = "core") {
11
+ if (command.type === "REQUEST_CANCEL_EXTERNAL_RUN" && "childId" in command.target) return true;
12
+ return isCommandEnabled(command.type, enabled);
13
+ }
14
+
15
+ // src/history/activation.ts
16
+ function timeOf(event) {
17
+ const startedAt = event.payload["startedAt"];
18
+ const text = typeof startedAt === "string" ? startedAt : event.createdAt;
19
+ const ms = Date.parse(text);
20
+ return Number.isFinite(ms) ? ms : 0;
21
+ }
22
+ function cutoffOf(event) {
23
+ const leased = event.payload["historyLength"];
24
+ return typeof leased === "number" && leased < event.seq ? leased : event.seq;
25
+ }
26
+ function walk(history) {
27
+ const activations = [];
28
+ let pending = [];
29
+ let started;
30
+ let afterStarted = [];
31
+ let last;
32
+ for (const event of history) {
33
+ switch (event.type) {
34
+ case "WORKFLOW_TASK_STARTED":
35
+ if (started) pending.push(...afterStarted);
36
+ started = event;
37
+ afterStarted = [];
38
+ continue;
39
+ case "WORKFLOW_TASK_FAILED":
40
+ case "WORKFLOW_TASK_TIMED_OUT":
41
+ if (started) pending.push(...afterStarted);
42
+ started = void 0;
43
+ afterStarted = [];
44
+ continue;
45
+ case "WORKFLOW_TASK_COMPLETED": {
46
+ const taskId = typeof event.payload["taskId"] === "string" ? event.payload["taskId"] : "";
47
+ const boundary = started !== void 0 && started.payload["taskId"] === event.payload["taskId"] ? started : event;
48
+ const cutoff = boundary === event ? event.seq : cutoffOf(boundary);
49
+ const seen = pending.filter((input) => input.seq <= cutoff);
50
+ const later = pending.filter((input) => input.seq > cutoff);
51
+ last = {
52
+ inputs: seen,
53
+ recorded: [],
54
+ timeMs: timeOf(boundary),
55
+ taskId,
56
+ historyLength: cutoff
57
+ };
58
+ activations.push(last);
59
+ pending = [...later, ...afterStarted];
60
+ started = void 0;
61
+ afterStarted = [];
62
+ continue;
63
+ }
64
+ }
65
+ if (isInputEvent(event)) {
66
+ if (started) afterStarted.push(event);
67
+ else pending.push(event);
68
+ } else if (isCommandEvent(event) && last?.recorded) {
69
+ last.recorded.push(event);
70
+ }
71
+ }
72
+ return { activations, pending, started, afterStarted };
73
+ }
74
+ function splitActivations(history, nowMs, includeOpen) {
75
+ const { activations, pending, started } = walk(history);
76
+ if (includeOpen) {
77
+ const cutoff = started ? cutoffOf(started) : history.length;
78
+ const inputs = pending.filter((input) => input.seq <= cutoff);
79
+ activations.push({ inputs, recorded: void 0, timeMs: nowMs, historyLength: cutoff });
80
+ }
81
+ return activations;
82
+ }
83
+ function unseenInputs(history) {
84
+ const { pending, afterStarted } = walk(history);
85
+ return [...pending, ...afterStarted].sort((a, b) => a.seq - b.seq);
86
+ }
87
+
88
+ // src/history/apply.ts
89
+ var HistoryStateError = class extends Error {
90
+ constructor(message, seq) {
91
+ super(message);
92
+ this.seq = seq;
93
+ this.name = "HistoryStateError";
94
+ }
95
+ seq;
96
+ };
97
+ function initialRunState() {
98
+ return {
99
+ status: "RUNNING",
100
+ historyLength: 0,
101
+ historyBytes: 0,
102
+ cancelRequested: false,
103
+ task: { state: "NONE", attempt: 0 },
104
+ completedTasks: 0,
105
+ taskFailures: 0,
106
+ activities: {},
107
+ timers: {},
108
+ children: {},
109
+ externals: {},
110
+ sideEffects: {},
111
+ markers: {},
112
+ signalsReceived: 0,
113
+ context: {}
114
+ };
115
+ }
116
+ function utf8Bytes(text) {
117
+ let bytes = 0;
118
+ for (let index = 0; index < text.length; index++) {
119
+ const unit = text.charCodeAt(index);
120
+ if (unit < 128) bytes += 1;
121
+ else if (unit < 2048) bytes += 2;
122
+ else if (unit >= 55296 && unit <= 56319 && index + 1 < text.length) {
123
+ const next = text.charCodeAt(index + 1);
124
+ if (next >= 56320 && next <= 57343) {
125
+ bytes += 4;
126
+ index++;
127
+ } else bytes += 3;
128
+ } else bytes += 3;
129
+ }
130
+ return bytes;
131
+ }
132
+ function str(payload, key) {
133
+ const value = payload[key];
134
+ return typeof value === "string" ? value : "";
135
+ }
136
+ function failureOf(payload) {
137
+ const value = payload["failure"];
138
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
139
+ return value;
140
+ }
141
+ var OPEN_ACTIVITY = /* @__PURE__ */ new Set([
142
+ "SCHEDULED",
143
+ "STARTED",
144
+ "CANCEL_REQUESTED"
145
+ ]);
146
+ function isActivityOpen(activity2) {
147
+ return OPEN_ACTIVITY.has(activity2.status);
148
+ }
149
+ function isChildOpen(child2) {
150
+ return child2.status === "INITIATED" || child2.status === "STARTED";
151
+ }
152
+ function activity(state, event) {
153
+ const id = str(event.payload, "activityId");
154
+ const found = state.activities[id];
155
+ if (!found) throw new HistoryStateError(`${event.type} for unknown activity "${id}"`, event.seq);
156
+ return found;
157
+ }
158
+ function child(state, event) {
159
+ const id = str(event.payload, "childId");
160
+ const found = state.children[id];
161
+ if (!found) throw new HistoryStateError(`${event.type} for unknown child "${id}"`, event.seq);
162
+ return found;
163
+ }
164
+ function timer(state, event) {
165
+ const id = str(event.payload, "timerId");
166
+ const found = state.timers[id];
167
+ if (!found) throw new HistoryStateError(`${event.type} for unknown timer "${id}"`, event.seq);
168
+ return found;
169
+ }
170
+ function applyEvent(state, event) {
171
+ if (event.seq !== state.historyLength + 1)
172
+ throw new HistoryStateError(
173
+ `Event seq ${event.seq} follows ${state.historyLength}; history must be gapless`,
174
+ event.seq
175
+ );
176
+ if (state.status !== "RUNNING" && event.type !== "WORKFLOW_TASK_FAILED")
177
+ throw new HistoryStateError(`${event.type} after the run ended (${state.status})`, event.seq);
178
+ state.historyLength = event.seq;
179
+ state.historyBytes += utf8Bytes(JSON.stringify(event.payload));
180
+ state.lastEventAt = event.createdAt;
181
+ const p = event.payload;
182
+ switch (event.type) {
183
+ case "WORKFLOW_STARTED":
184
+ if (event.seq !== 1)
185
+ throw new HistoryStateError("WORKFLOW_STARTED must be the first event", event.seq);
186
+ state.workflowFn = str(p, "workflowFn");
187
+ state.input = p["input"] ?? null;
188
+ if (typeof p["context"] === "object" && p["context"] !== null && !Array.isArray(p["context"]))
189
+ state.context = { ...p["context"] };
190
+ break;
191
+ case "WORKFLOW_TASK_SCHEDULED":
192
+ state.task = { state: "SCHEDULED", taskId: str(p, "taskId"), attempt: state.task.attempt };
193
+ break;
194
+ case "WORKFLOW_TASK_STARTED": {
195
+ const attempt = typeof p["attempt"] === "number" ? p["attempt"] : 1;
196
+ state.task = { state: "STARTED", taskId: str(p, "taskId"), attempt };
197
+ break;
198
+ }
199
+ case "WORKFLOW_TASK_COMPLETED":
200
+ state.task = { state: "NONE", attempt: 0 };
201
+ state.completedTasks += 1;
202
+ state.taskFailures = 0;
203
+ break;
204
+ case "WORKFLOW_TASK_FAILED":
205
+ case "WORKFLOW_TASK_TIMED_OUT":
206
+ state.taskFailures += 1;
207
+ if (state.status === "RUNNING")
208
+ state.task = { state: "SCHEDULED", taskId: str(p, "taskId"), attempt: state.task.attempt };
209
+ break;
210
+ case "ACTIVITY_SCHEDULED": {
211
+ const id = str(p, "activityId");
212
+ if (state.activities[id])
213
+ throw new HistoryStateError(`Activity "${id}" is scheduled twice`, event.seq);
214
+ state.activities[id] = {
215
+ status: "SCHEDULED",
216
+ attempt: 0,
217
+ nodeType: str(p, "nodeType"),
218
+ operation: str(p, "operation"),
219
+ scheduledSeq: event.seq,
220
+ ...typeof p["cancellationType"] === "string" ? { cancellationType: p["cancellationType"] } : {},
221
+ ...typeof p["summary"] === "string" ? { summary: p["summary"] } : {}
222
+ };
223
+ break;
224
+ }
225
+ case "ACTIVITY_STARTED": {
226
+ const found = activity(state, event);
227
+ if (found.status === "SCHEDULED") found.status = "STARTED";
228
+ found.attempt = typeof p["attempt"] === "number" ? p["attempt"] : found.attempt + 1;
229
+ break;
230
+ }
231
+ case "ACTIVITY_HEARTBEAT":
232
+ case "ACTIVITY_PAUSED":
233
+ case "ACTIVITY_UNPAUSED":
234
+ case "ACTIVITY_RESET":
235
+ case "ACTIVITY_OPTIONS_UPDATED":
236
+ activity(state, event);
237
+ break;
238
+ case "ACTIVITY_COMPLETED":
239
+ case "ACTIVITY_FAILED":
240
+ case "ACTIVITY_TIMED_OUT":
241
+ case "ACTIVITY_CANCELLED": {
242
+ const found = activity(state, event);
243
+ if (!isActivityOpen(found))
244
+ throw new HistoryStateError(
245
+ `${event.type} for activity "${str(p, "activityId")}" that is already ${found.status}`,
246
+ event.seq
247
+ );
248
+ found.status = event.type === "ACTIVITY_COMPLETED" ? "COMPLETED" : event.type === "ACTIVITY_FAILED" ? "FAILED" : event.type === "ACTIVITY_TIMED_OUT" ? "TIMED_OUT" : "CANCELLED";
249
+ if (typeof p["attempt"] === "number") found.attempt = p["attempt"];
250
+ const failure = failureOf(p);
251
+ if (failure) found.lastFailure = failure;
252
+ break;
253
+ }
254
+ case "ACTIVITY_CANCEL_REQUESTED": {
255
+ const found = activity(state, event);
256
+ if (isActivityOpen(found)) found.status = "CANCEL_REQUESTED";
257
+ break;
258
+ }
259
+ case "TIMER_STARTED": {
260
+ const id = str(p, "timerId");
261
+ if (state.timers[id])
262
+ throw new HistoryStateError(`Timer "${id}" is started twice`, event.seq);
263
+ state.timers[id] = {
264
+ status: "PENDING",
265
+ durationMs: typeof p["durationMs"] === "number" ? p["durationMs"] : 0,
266
+ fireAt: str(p, "fireAt"),
267
+ startedSeq: event.seq,
268
+ ...typeof p["summary"] === "string" ? { summary: p["summary"] } : {}
269
+ };
270
+ break;
271
+ }
272
+ case "TIMER_FIRED":
273
+ case "TIMER_CANCELLED": {
274
+ const found = timer(state, event);
275
+ if (found.status !== "PENDING")
276
+ throw new HistoryStateError(
277
+ `${event.type} for timer "${str(p, "timerId")}" that is already ${found.status}`,
278
+ event.seq
279
+ );
280
+ found.status = event.type === "TIMER_FIRED" ? "FIRED" : "CANCELLED";
281
+ break;
282
+ }
283
+ case "SIGNAL_RECEIVED":
284
+ state.signalsReceived += 1;
285
+ break;
286
+ case "CHILD_RUN_INITIATED": {
287
+ const id = str(p, "childId");
288
+ if (state.children[id])
289
+ throw new HistoryStateError(`Child "${id}" is started twice`, event.seq);
290
+ const options = p["options"];
291
+ const policy = typeof options === "object" && options !== null && !Array.isArray(options) ? options["parentClosePolicy"] : void 0;
292
+ state.children[id] = {
293
+ status: "INITIATED",
294
+ parentClosePolicy: policy === "ABANDON" || policy === "REQUEST_CANCEL" ? policy : "TERMINATE",
295
+ initiatedSeq: event.seq,
296
+ ...typeof p["workflowKey"] === "string" ? { workflowKey: p["workflowKey"] } : {},
297
+ ...typeof p["workflowFn"] === "string" ? { workflowFn: p["workflowFn"] } : {},
298
+ ...typeof p["childRunId"] === "string" ? { childRunId: p["childRunId"] } : {}
299
+ };
300
+ break;
301
+ }
302
+ case "CHILD_RUN_STARTED": {
303
+ const found = child(state, event);
304
+ if (found.status !== "INITIATED")
305
+ throw new HistoryStateError(`Child "${str(p, "childId")}" started twice`, event.seq);
306
+ found.status = "STARTED";
307
+ found.childRunId = str(p, "childRunId");
308
+ break;
309
+ }
310
+ case "CHILD_RUN_COMPLETED":
311
+ case "CHILD_RUN_FAILED":
312
+ case "CHILD_RUN_CANCELLED":
313
+ case "CHILD_RUN_TERMINATED":
314
+ case "CHILD_RUN_TIMED_OUT": {
315
+ const found = child(state, event);
316
+ if (!isChildOpen(found))
317
+ throw new HistoryStateError(
318
+ `${event.type} for child "${str(p, "childId")}" that is already ${found.status}`,
319
+ event.seq
320
+ );
321
+ found.status = event.type.slice("CHILD_RUN_".length);
322
+ if (typeof p["childRunId"] === "string") found.childRunId = p["childRunId"];
323
+ break;
324
+ }
325
+ case "EXTERNAL_RUN_SIGNALED":
326
+ case "EXTERNAL_RUN_CANCEL_REQUESTED":
327
+ case "EXTERNAL_RUN_CANCEL_RESOLVED": {
328
+ const id = str(p, "externalId");
329
+ const resolving = event.type === "EXTERNAL_RUN_CANCEL_RESOLVED" || event.type === "EXTERNAL_RUN_SIGNALED" && p["resolved"] === true;
330
+ if (resolving) {
331
+ const found = state.externals[id];
332
+ if (!found || found.status !== "PENDING")
333
+ throw new HistoryStateError(`${event.type} for unknown or resolved "${id}"`, event.seq);
334
+ found.status = "RESOLVED";
335
+ found.ok = p["ok"] === true;
336
+ } else {
337
+ if (state.externals[id])
338
+ throw new HistoryStateError(`External operation "${id}" is issued twice`, event.seq);
339
+ state.externals[id] = {
340
+ kind: event.type === "EXTERNAL_RUN_SIGNALED" ? "signal" : "cancel",
341
+ status: "PENDING"
342
+ };
343
+ }
344
+ break;
345
+ }
346
+ case "SIDE_EFFECT_RECORDED":
347
+ state.sideEffects[str(p, "sideEffectId")] = p["value"] ?? null;
348
+ break;
349
+ case "MARKER_RECORDED":
350
+ state.markers[str(p, "markerId")] = p["data"] ?? null;
351
+ break;
352
+ case "CONTEXT_UPSERTED": {
353
+ const entries = p["entries"];
354
+ if (typeof entries === "object" && entries !== null && !Array.isArray(entries))
355
+ state.context = { ...state.context, ...entries };
356
+ break;
357
+ }
358
+ case "WORKFLOW_CANCEL_REQUESTED":
359
+ state.cancelRequested = true;
360
+ break;
361
+ case "WORKFLOW_COMPLETED":
362
+ state.status = "COMPLETED";
363
+ state.output = p["output"] ?? null;
364
+ break;
365
+ case "WORKFLOW_FAILED": {
366
+ state.status = "FAILED";
367
+ const failure = failureOf(p);
368
+ if (failure) state.failure = failure;
369
+ break;
370
+ }
371
+ case "WORKFLOW_CANCELLED":
372
+ state.status = "CANCELLED";
373
+ break;
374
+ case "WORKFLOW_TERMINATED":
375
+ state.status = "TERMINATED";
376
+ break;
377
+ case "WORKFLOW_TIMED_OUT":
378
+ state.status = "TIMED_OUT";
379
+ break;
380
+ case "WORKFLOW_CONTINUED_AS_NEW":
381
+ state.status = "CONTINUED_AS_NEW";
382
+ break;
383
+ }
384
+ if (state.status !== "RUNNING") state.task = { state: "NONE", attempt: 0 };
385
+ return state;
386
+ }
387
+ function projectRunState(history) {
388
+ const state = initialRunState();
389
+ for (const event of history) applyEvent(state, event);
390
+ return state;
391
+ }
392
+ function pendingCounts(state) {
393
+ return {
394
+ activities: Object.values(state.activities).filter(isActivityOpen).length,
395
+ timers: Object.values(state.timers).filter((t) => t.status === "PENDING").length,
396
+ children: Object.values(state.children).filter(isChildOpen).length
397
+ };
398
+ }
399
+ function payloadOf(command) {
400
+ const out = {};
401
+ for (const [key, value] of Object.entries(command)) {
402
+ if (key === "type" || value === void 0) continue;
403
+ out[key] = value;
404
+ }
405
+ return out;
406
+ }
407
+ function eventsForCommands(state, commands, context) {
408
+ const issues = [];
409
+ const events = [];
410
+ const reject = (index, code, message) => {
411
+ issues.push({ index, code, message });
412
+ };
413
+ if (state.status !== "RUNNING" && commands.length > 0)
414
+ return {
415
+ ok: false,
416
+ cause: "INVALID_REQUEST",
417
+ issues: [{ index: 0, code: "run.closed", message: `The run is ${state.status}` }]
418
+ };
419
+ const activities = new Map(Object.entries(state.activities).map(([id, a]) => [id, a.status]));
420
+ const timers = new Map(Object.entries(state.timers).map(([id, t]) => [id, t.status]));
421
+ const children = new Set(Object.keys(state.children));
422
+ const externals = new Set(Object.keys(state.externals));
423
+ const sideEffects = new Set(Object.keys(state.sideEffects));
424
+ let unsupported = false;
425
+ commands.forEach((command, index) => {
426
+ if (!isWorkflowCommandEnabled(command, context.enabled)) {
427
+ unsupported = true;
428
+ reject(index, "commands.unsupported", `${command.type} is not supported in this release`);
429
+ return;
430
+ }
431
+ if (TERMINAL_COMMANDS.has(command.type) && index !== commands.length - 1)
432
+ reject(index, "commands.terminalNotLast", `${command.type} must be last`);
433
+ const base = { taskId: context.taskId };
434
+ switch (command.type) {
435
+ case "SCHEDULE_ACTIVITY":
436
+ if (activities.has(command.activityId))
437
+ reject(index, "activity.duplicate", `Activity "${command.activityId}" already exists`);
438
+ if (!isActivityNodeTypeAllowed(command.nodeType))
439
+ reject(
440
+ index,
441
+ "durable.activityTypeNotAllowed",
442
+ `${command.nodeType} cannot run as a durable activity`
443
+ );
444
+ activities.set(command.activityId, "SCHEDULED");
445
+ events.push({ ...base, type: "ACTIVITY_SCHEDULED", payload: payloadOf(command) });
446
+ break;
447
+ case "REQUEST_CANCEL_ACTIVITY": {
448
+ const status = activities.get(command.activityId);
449
+ if (status === void 0 || !OPEN_ACTIVITY.has(status))
450
+ reject(index, "activity.notOpen", `Activity "${command.activityId}" is not open`);
451
+ activities.set(command.activityId, "CANCEL_REQUESTED");
452
+ events.push({ ...base, type: "ACTIVITY_CANCEL_REQUESTED", payload: payloadOf(command) });
453
+ break;
454
+ }
455
+ case "START_TIMER":
456
+ if (timers.has(command.timerId))
457
+ reject(index, "timer.duplicate", `Timer "${command.timerId}" already exists`);
458
+ timers.set(command.timerId, "PENDING");
459
+ events.push({
460
+ ...base,
461
+ type: "TIMER_STARTED",
462
+ payload: {
463
+ ...payloadOf(command),
464
+ fireAt: new Date(context.nowMs + command.durationMs).toISOString()
465
+ }
466
+ });
467
+ break;
468
+ case "CANCEL_TIMER":
469
+ if (timers.get(command.timerId) !== "PENDING")
470
+ reject(index, "timer.notPending", `Timer "${command.timerId}" is not pending`);
471
+ timers.set(command.timerId, "CANCELLED");
472
+ events.push({ ...base, type: "TIMER_CANCELLED", payload: payloadOf(command) });
473
+ break;
474
+ case "START_CHILD_RUN":
475
+ if (children.has(command.childId))
476
+ reject(index, "child.duplicate", `Child "${command.childId}" already exists`);
477
+ children.add(command.childId);
478
+ events.push({ ...base, type: "CHILD_RUN_INITIATED", payload: payloadOf(command) });
479
+ break;
480
+ case "SIGNAL_RUN":
481
+ case "REQUEST_CANCEL_EXTERNAL_RUN":
482
+ if (externals.has(command.externalId))
483
+ reject(index, "external.duplicate", `"${command.externalId}" already exists`);
484
+ if ("childId" in command.target && !children.has(command.target.childId))
485
+ reject(index, "external.unknownChild", `Unknown child "${command.target.childId}"`);
486
+ externals.add(command.externalId);
487
+ events.push({
488
+ ...base,
489
+ type: command.type === "SIGNAL_RUN" ? "EXTERNAL_RUN_SIGNALED" : "EXTERNAL_RUN_CANCEL_REQUESTED",
490
+ payload: payloadOf(command)
491
+ });
492
+ break;
493
+ case "RECORD_SIDE_EFFECT":
494
+ if (sideEffects.has(command.sideEffectId))
495
+ reject(index, "sideEffect.duplicate", `"${command.sideEffectId}" is already recorded`);
496
+ sideEffects.add(command.sideEffectId);
497
+ events.push({ ...base, type: "SIDE_EFFECT_RECORDED", payload: payloadOf(command) });
498
+ break;
499
+ case "RECORD_MARKER":
500
+ events.push({ ...base, type: "MARKER_RECORDED", payload: payloadOf(command) });
501
+ break;
502
+ case "COMPLETE_WORKFLOW":
503
+ events.push({
504
+ ...base,
505
+ type: "WORKFLOW_COMPLETED",
506
+ payload: { output: command.output ?? null }
507
+ });
508
+ break;
509
+ case "FAIL_WORKFLOW":
510
+ events.push({ ...base, type: "WORKFLOW_FAILED", payload: payloadOf(command) });
511
+ break;
512
+ case "CANCEL_WORKFLOW":
513
+ events.push({ ...base, type: "WORKFLOW_CANCELLED", payload: {} });
514
+ break;
515
+ case "UPSERT_CONTEXT":
516
+ events.push({ ...base, type: "CONTEXT_UPSERTED", payload: payloadOf(command) });
517
+ break;
518
+ case "RECORD_LOCAL_ACTIVITY":
519
+ events.push({
520
+ ...base,
521
+ type: command.failure ? "LOCAL_ACTIVITY_FAILED" : "LOCAL_ACTIVITY_COMPLETED",
522
+ payload: payloadOf(command)
523
+ });
524
+ break;
525
+ case "CONTINUE_AS_NEW":
526
+ events.push({ ...base, type: "WORKFLOW_CONTINUED_AS_NEW", payload: payloadOf(command) });
527
+ break;
528
+ }
529
+ });
530
+ if (issues.length > 0)
531
+ return { ok: false, cause: unsupported ? "UNSUPPORTED_COMMAND" : "INVALID_REQUEST", issues };
532
+ return { ok: true, events };
533
+ }
534
+ function taskCompletedEvents(options) {
535
+ const extra = {};
536
+ if (options.buildId !== void 0) extra["buildId"] = options.buildId;
537
+ if (options.workerId !== void 0) extra["workerId"] = options.workerId;
538
+ const events = [];
539
+ if (options.transient)
540
+ events.push({
541
+ type: "WORKFLOW_TASK_STARTED",
542
+ taskId: options.taskId,
543
+ payload: {
544
+ taskId: options.taskId,
545
+ attempt: options.attempt,
546
+ startedAt: options.startedAt,
547
+ historyLength: options.historyLength,
548
+ ...extra
549
+ }
550
+ });
551
+ events.push({
552
+ type: "WORKFLOW_TASK_COMPLETED",
553
+ taskId: options.taskId,
554
+ payload: { taskId: options.taskId, ...extra }
555
+ });
556
+ return events;
557
+ }
558
+ function hasUnprocessedInput(history) {
559
+ return unseenInputs(history).length > 0;
560
+ }
561
+
562
+ // src/history/retry.ts
563
+ var DEFAULT_ACTIVITY_RETRY = Object.freeze({
564
+ retryDelay: 1e3,
565
+ backoffMultiplier: 2,
566
+ maxDelay: 1e5
567
+ });
568
+ var FINAL_TIMEOUTS = /* @__PURE__ */ new Set(["SCHEDULE_TO_START", "SCHEDULE_TO_CLOSE"]);
569
+ function computeRetryDelay(policy, attempt, failure) {
570
+ if (failure?.nonRetryable === true) return { retry: false, reason: "nonRetryable" };
571
+ if (failure?.timeoutType !== void 0 && FINAL_TIMEOUTS.has(failure.timeoutType))
572
+ return { retry: false, reason: "finalTimeout" };
573
+ if (failure?.type !== void 0 && policy.nonRetryableErrorTypes !== void 0 && policy.nonRetryableErrorTypes.includes(failure.type))
574
+ return { retry: false, reason: "typeDenied" };
575
+ if (failure !== void 0 && policy.retryOnErrorTypes !== void 0 && policy.retryOnErrorTypes.length > 0 && !policy.retryOnErrorTypes.includes(failure.errorType))
576
+ return { retry: false, reason: "errorTypeNotListed" };
577
+ if (policy.maxRetries !== void 0 && attempt > policy.maxRetries)
578
+ return { retry: false, reason: "maxRetries" };
579
+ if (failure?.nextRetryDelayMs !== void 0)
580
+ return { retry: true, delayMs: Math.max(0, Math.round(failure.nextRetryDelayMs)) };
581
+ const base = Math.max(0, policy.retryDelay);
582
+ const multiplier = policy.backoffMultiplier ?? 2;
583
+ const cap = policy.maxDelay ?? base * 100;
584
+ const exponent = Math.max(0, attempt - 1);
585
+ const delay = Math.min(base * Math.pow(multiplier, exponent), cap);
586
+ return { retry: true, delayMs: Math.round(Number.isFinite(delay) ? delay : cap) };
587
+ }
588
+ function explicitRetryPolicy(policy) {
589
+ const retryDelay = policy?.retryDelay ?? DEFAULT_ACTIVITY_RETRY.retryDelay;
590
+ const out = {
591
+ retryDelay,
592
+ backoffMultiplier: policy?.backoffMultiplier ?? DEFAULT_ACTIVITY_RETRY.backoffMultiplier ?? 2,
593
+ maxDelay: policy?.maxDelay ?? (policy?.retryDelay === void 0 ? 1e5 : Math.max(retryDelay, retryDelay * 100))
594
+ };
595
+ if (policy?.maxRetries !== void 0) out.maxRetries = policy.maxRetries;
596
+ if (policy?.retryOnErrorTypes !== void 0)
597
+ out.retryOnErrorTypes = [...policy.retryOnErrorTypes];
598
+ if (policy?.nonRetryableErrorTypes !== void 0)
599
+ out.nonRetryableErrorTypes = [...policy.nonRetryableErrorTypes];
600
+ return out;
601
+ }
602
+
603
+ // src/history/defaults.ts
604
+ function codeWorkflowParentClosePolicy(state) {
605
+ const policy = state.parentClosePolicy;
606
+ if (policy === "TERMINATE" || policy === "ABANDON" || policy === "REQUEST_CANCEL") return policy;
607
+ return state.waitForCompletion === false ? "ABANDON" : "TERMINATE";
608
+ }
609
+ var CHILD_DEFAULT_PARENT_CLOSE_POLICY = Object.freeze({ child: "TERMINATE", startChild: "ABANDON" });
610
+ var CHILD_DEFAULT_CANCELLATION_TYPE = "WAIT_CANCELLATION_COMPLETED";
611
+
612
+ export { CHILD_DEFAULT_CANCELLATION_TYPE, CHILD_DEFAULT_PARENT_CLOSE_POLICY, DEFAULT_ACTIVITY_RETRY, HistoryStateError, applyEvent, codeWorkflowParentClosePolicy, computeRetryDelay, eventsForCommands, explicitRetryPolicy, hasUnprocessedInput, initialRunState, isActivityOpen, isChildOpen, isCommandEnabled, isWorkflowCommandEnabled, pendingCounts, projectRunState, splitActivations, taskCompletedEvents, unseenInputs, utf8Bytes };
@@ -1,6 +1,6 @@
1
1
  import { autoLayout } from './chunk-5LUIDMF4.js';
2
- import { sha256Tagged, canonicalJson } from './chunk-X4HKU3MX.js';
3
- import { isRecord, cloneJson, deepEqual } from './chunk-REV7ZOA4.js';
2
+ import { sha256Tagged, canonicalJson } from './chunk-E2VK7J2C.js';
3
+ import { isRecord, cloneJson, deepEqual, setOwn } from './chunk-PMCM2OH4.js';
4
4
 
5
5
  // src/ir/node-types.ts
6
6
  var EXECUTOR_INTERNAL_TYPES = /* @__PURE__ */ new Set([
@@ -97,16 +97,11 @@ function normalizeOperation(node, data) {
97
97
  if (!isNonEmptyString(node["operation_name"]) && isNonEmptyString(data["operation_name"])) {
98
98
  node["operation_name"] = data["operation_name"];
99
99
  }
100
- if (data["operation_name"] !== void 0 && deepEqual(data["operation_name"], node["operation_name"])) {
101
- delete data["operation_name"];
102
- }
103
100
  }
104
101
  function normalizeVersion(node, data, merged) {
105
102
  if (merged) return;
106
103
  const effective = firstTruthy(data["version"], node["version"]);
107
104
  if (typeof effective === "string") node["version"] = effective;
108
- if (data["version"] !== void 0 && deepEqual(data["version"], node["version"]))
109
- delete data["version"];
110
105
  if (data["nodeVersion"] !== void 0 && deepEqual(data["nodeVersion"], node["version"])) {
111
106
  delete data["nodeVersion"];
112
107
  }
@@ -114,7 +109,7 @@ function normalizeVersion(node, data, merged) {
114
109
  function normalizeExternalState(node, data) {
115
110
  const args = isRecord(node["args"]) ? node["args"] : void 0;
116
111
  const dataArgs = isRecord(data["args"]) ? data["args"] : void 0;
117
- const effective = firstTruthy(args?.["state"], dataArgs?.["state"], data["state"]);
112
+ const effective = firstTruthy(args?.["state"], dataArgs?.["state"]);
118
113
  if (effective !== void 0 && args?.["state"] === void 0) {
119
114
  const nextArgs = args ?? {};
120
115
  nextArgs["state"] = effective;
@@ -124,7 +119,6 @@ function normalizeExternalState(node, data) {
124
119
  if (dataArgs && dataArgs["state"] !== void 0 && deepEqual(dataArgs["state"], rootState)) {
125
120
  delete dataArgs["state"];
126
121
  }
127
- if (data["state"] !== void 0 && deepEqual(data["state"], rootState)) delete data["state"];
128
122
  }
129
123
  function normalizeMergedState(node, data) {
130
124
  const args = isRecord(node["args"]) ? node["args"] : {};
@@ -163,6 +157,7 @@ function normalizeErrorConfig(node, data) {
163
157
  const dataState = isRecord(dataArgs?.["state"]) ? dataArgs["state"] : void 0;
164
158
  const effective = node["errorConfig"] ?? data["errorConfig"] ?? dataState?.["errorConfig"];
165
159
  if (effective !== void 0 && effective !== null) node["errorConfig"] = effective;
160
+ else if (node["errorConfig"] === null) delete node["errorConfig"];
166
161
  if (data["errorConfig"] !== void 0 && deepEqual(data["errorConfig"], node["errorConfig"])) {
167
162
  delete data["errorConfig"];
168
163
  }
@@ -173,7 +168,7 @@ function normalizeExecutionSettings(node, data) {
173
168
  if (!root && !mirror) return;
174
169
  const merged = { ...root };
175
170
  for (const [key, value] of Object.entries(mirror ?? {}))
176
- if (!Object.hasOwn(merged, key)) merged[key] = value;
171
+ if (!Object.hasOwn(merged, key)) setOwn(merged, key, value);
177
172
  if (root?.["executeOnce"] === true || mirror?.["executeOnce"] === true)
178
173
  merged["executeOnce"] = true;
179
174
  if (mirror && Object.hasOwn(mirror, "runOn")) {