@fluidgrids/workflows 2026.1028.2 → 2026.1030.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 (154) hide show
  1. package/README.md +181 -11
  2. package/dist/{activation-BBh1p82z.d.cts → activation-DqUfpHzk.d.cts} +1 -1
  3. package/dist/{activation-DnhG7SmF.d.ts → activation-xpx1oWuo.d.ts} +1 -1
  4. package/dist/{chunk-VRHHBPT6.js → chunk-2D3MYIIF.js} +1212 -128
  5. package/dist/chunk-3U2NU7YC.cjs +124 -0
  6. package/dist/{chunk-NEIUQASE.cjs → chunk-4QKB4ARC.cjs} +3 -3
  7. package/dist/{chunk-GBQ33SIZ.cjs → chunk-54FLQNUM.cjs} +12 -1
  8. package/dist/chunk-5HIVIV53.js +330 -0
  9. package/dist/chunk-5MFVJM76.js +1222 -0
  10. package/dist/{chunk-JD2VQIDZ.cjs → chunk-672KMMBK.cjs} +2 -2
  11. package/dist/{chunk-C5OLWZ42.js → chunk-6A2FGSUS.js} +22 -14
  12. package/dist/{chunk-XKJA7KX3.js → chunk-6OLN6BMB.js} +52 -3
  13. package/dist/{chunk-6FSHT5IL.js → chunk-7EZIANC7.js} +1 -1
  14. package/dist/{chunk-2J6TF7YI.cjs → chunk-A5SXCA62.cjs} +10 -3
  15. package/dist/{chunk-BO6OVILK.js → chunk-AC6ZEXVR.js} +10 -4
  16. package/dist/{chunk-ABFZWYHT.js → chunk-AE5Q6ZAJ.js} +315 -50
  17. package/dist/chunk-C4F5KJTI.js +293 -0
  18. package/dist/{chunk-IISBRUWJ.js → chunk-G5H32GIG.js} +1 -1
  19. package/dist/chunk-GEQDGUGB.cjs +2719 -0
  20. package/dist/{chunk-XHXIDVEC.js → chunk-HCM7ZC7Q.js} +1 -1
  21. package/dist/chunk-HMZUGSMU.cjs +1554 -0
  22. package/dist/{chunk-SAOBPYYJ.cjs → chunk-IQPXHQQQ.cjs} +8 -4
  23. package/dist/{chunk-P6TA5EZT.cjs → chunk-ISOIA7NV.cjs} +335 -58
  24. package/dist/chunk-JSC75O5C.cjs +167 -0
  25. package/dist/chunk-M272AHEX.js +25 -0
  26. package/dist/{chunk-BD7ZPG53.js → chunk-NWQ5WRLE.js} +10 -2
  27. package/dist/chunk-ODZ2IAR2.cjs +1247 -0
  28. package/dist/chunk-Q4MWQNJK.cjs +28 -0
  29. package/dist/{chunk-HWJZVOG7.js → chunk-SR7TR5KX.js} +6 -2
  30. package/dist/{chunk-FEW3JBYA.cjs → chunk-TCTE7DX5.cjs} +3 -3
  31. package/dist/{chunk-623FVQSN.cjs → chunk-TYF56RGB.cjs} +123 -0
  32. package/dist/chunk-VA4OFR72.cjs +324 -0
  33. package/dist/chunk-VU5S5A7V.js +150 -0
  34. package/dist/chunk-YEHR4NNE.js +1522 -0
  35. package/dist/{chunk-FMSW2HDF.cjs → chunk-ZCGKGDCL.cjs} +23 -15
  36. package/dist/codegen/index.d.cts +2 -2
  37. package/dist/codegen/index.d.ts +2 -2
  38. package/dist/collect-6NIEufHd.d.ts +103 -0
  39. package/dist/collect-CcTCKqx6.d.cts +103 -0
  40. package/dist/{file-BOoHZgoQ.d.cts → file-BxYpwjRQ.d.cts} +1007 -21
  41. package/dist/{file-yuPCFU5b.d.ts → file-CFdPQJI9.d.ts} +1007 -21
  42. package/dist/history/index.cjs +375 -86
  43. package/dist/history/index.d.cts +590 -12
  44. package/dist/history/index.d.ts +590 -12
  45. package/dist/history/index.js +50 -4
  46. package/dist/index.cjs +156 -50
  47. package/dist/index.d.cts +38 -58
  48. package/dist/index.d.ts +38 -58
  49. package/dist/index.js +6 -4
  50. package/dist/interceptors-CNcr2dlk.d.ts +159 -0
  51. package/dist/interceptors-CqkNZVfI.d.cts +159 -0
  52. package/dist/ir/index.cjs +362 -38
  53. package/dist/ir/index.d.cts +282 -7
  54. package/dist/ir/index.d.ts +282 -7
  55. package/dist/ir/index.js +329 -23
  56. package/dist/{lower-BzmUz0sq.d.cts → lower-BtRfIW2A.d.cts} +56 -8
  57. package/dist/{lower-_-iT4HYs.d.ts → lower-CpsMFOFX.d.ts} +56 -8
  58. package/dist/{manifest-C8N6HDYl.d.ts → manifest-D-I_twys.d.ts} +1 -1
  59. package/dist/{manifest-0OLw0i7k.d.cts → manifest-DahBQVM8.d.cts} +1 -1
  60. package/dist/node-evaluator-DGQDPSPI.cjs +24 -0
  61. package/dist/node-evaluator-LEEVD7H7.js +14 -0
  62. package/dist/payload-fields-BVRQn2yH.d.cts +122 -0
  63. package/dist/payload-fields-oOBWxDiG.d.ts +122 -0
  64. package/dist/quickjs/index.cjs +28 -27
  65. package/dist/quickjs/index.d.cts +6 -6
  66. package/dist/quickjs/index.d.ts +6 -6
  67. package/dist/quickjs/index.js +10 -9
  68. package/dist/roundtrip/index.cjs +259 -51
  69. package/dist/roundtrip/index.d.cts +100 -9
  70. package/dist/roundtrip/index.d.ts +100 -9
  71. package/dist/roundtrip/index.js +177 -11
  72. package/dist/runtime/index.cjs +21 -20
  73. package/dist/runtime/index.d.cts +184 -15
  74. package/dist/runtime/index.d.ts +184 -15
  75. package/dist/runtime/index.js +8 -7
  76. package/dist/testing/index.cjs +1122 -115
  77. package/dist/testing/index.d.cts +294 -13
  78. package/dist/testing/index.d.ts +294 -13
  79. package/dist/testing/index.js +1086 -84
  80. package/dist/{types-DV-HX_Gt.d.ts → types-Bv2i4cBX.d.cts} +244 -33
  81. package/dist/{types-CpBBjaGX.d.cts → types-DGx-b9eq.d.ts} +244 -33
  82. package/dist/{types-BGoPzgcl.d.ts → types-V7jEEUaL.d.cts} +20 -1
  83. package/dist/{types-BGoPzgcl.d.cts → types-V7jEEUaL.d.ts} +20 -1
  84. package/dist/{workflow-Bpr3vnA_.d.ts → workflow-B18OeF7g.d.ts} +2 -2
  85. package/dist/workflow-BGnv8SS6.d.ts +803 -0
  86. package/dist/{workflow-FXUkpIBc.d.cts → workflow-BJPFv3cp.d.cts} +2 -2
  87. package/dist/workflow-DS32Gtws.d.cts +803 -0
  88. package/fixtures/histories/activity-options-updated.history.json +159 -0
  89. package/fixtures/histories/activity-paused-unpaused.history.json +160 -0
  90. package/fixtures/histories/auto-upgrade-patched.history.json +276 -0
  91. package/fixtures/histories/benign-failure.history.json +146 -0
  92. package/fixtures/histories/cancel-activity-try-cancel.history.json +150 -0
  93. package/fixtures/histories/child-cancel-wait-requested.history.json +217 -0
  94. package/fixtures/histories/child-options-roundtrip.history.json +192 -0
  95. package/fixtures/histories/codec-opaque.history.json +229 -0
  96. package/fixtures/histories/continue-as-new-last-result.history.json +86 -0
  97. package/fixtures/histories/continue-as-new-options.history.json +99 -0
  98. package/fixtures/histories/continue-as-new-r1-long-task-queue.history.json +78 -0
  99. package/fixtures/histories/continue-as-new-r1-retry-options.history.json +83 -0
  100. package/fixtures/histories/dynamic-workflow.history.json +150 -0
  101. package/fixtures/histories/execution-timeout-chain.history.json +98 -0
  102. package/fixtures/histories/external-cancel-resolved.history.json +123 -0
  103. package/fixtures/histories/external-cancel-unknown-target.history.json +127 -0
  104. package/fixtures/histories/failure-error-types-fails-run.history.json +144 -0
  105. package/fixtures/histories/handler-drain-warn.history.json +222 -0
  106. package/fixtures/histories/heartbeat-details-on-retry.history.json +145 -0
  107. package/fixtures/histories/interceptor-headers.history.json +339 -0
  108. package/fixtures/histories/local-activity-abandoned-at-completion.history.json +73 -0
  109. package/fixtures/histories/local-activity-cancelled-in-scope.history.json +118 -0
  110. package/fixtures/histories/local-activity-completed.history.json +157 -0
  111. package/fixtures/histories/local-activity-failed.history.json +93 -0
  112. package/fixtures/histories/local-activity-retry-in-task.history.json +88 -0
  113. package/fixtures/histories/query-custom.history.json +213 -0
  114. package/fixtures/histories/query-default-handler.history.json +120 -0
  115. package/fixtures/histories/reset-forked-reapplied-signals.history.json +239 -0
  116. package/fixtures/histories/reset-reapplied-update-admitted.history.json +228 -0
  117. package/fixtures/histories/run-retry-last-failure.history.json +90 -0
  118. package/fixtures/histories/run-timeout.history.json +159 -0
  119. package/fixtures/histories/schedule-to-start-timeout.history.json +132 -0
  120. package/fixtures/histories/search-attributes-upserted.history.json +177 -0
  121. package/fixtures/histories/start-delay-signal-ends-delay.history.json +155 -0
  122. package/fixtures/histories/typeerror-task-retry-100.history.json +137 -0
  123. package/fixtures/histories/update-accepted-completed.history.json +45 -30
  124. package/fixtures/histories/update-default-handler.history.json +246 -0
  125. package/fixtures/histories/update-handler-awaits-activity.history.json +196 -0
  126. package/fixtures/histories/update-not-handled.history.json +138 -0
  127. package/fixtures/histories/update-rejected-no-event.history.json +190 -0
  128. package/fixtures/histories/update-with-start-admitted.history.json +150 -0
  129. package/fixtures/histories/user-activity-cancel.history.json +149 -0
  130. package/fixtures/histories/user-activity-retry.history.json +143 -0
  131. package/fixtures/histories/user-activity.history.json +149 -0
  132. package/package.json +1 -1
  133. package/schema/bridge-v2.schema.json +1062 -0
  134. package/schema/history-file.schema.json +538 -83
  135. package/schema/ir-v2.schema.json +290 -0
  136. package/schema/payload-fields.json +162 -0
  137. package/schema/run-event.schema.json +503 -82
  138. package/schema/workflow-command.schema.json +372 -69
  139. package/schema/workflow-task.schema.json +924 -171
  140. package/dist/assemble-BLqQ8lSu.d.cts +0 -39
  141. package/dist/assemble-DWgaXHd-.d.ts +0 -39
  142. package/dist/chunk-DHTLALBL.cjs +0 -80
  143. package/dist/chunk-DJYMDLV5.js +0 -227
  144. package/dist/chunk-I5LR3D2K.js +0 -869
  145. package/dist/chunk-M4BBAERY.cjs +0 -1635
  146. package/dist/chunk-N23SKIG4.js +0 -73
  147. package/dist/chunk-PZCVF76Q.cjs +0 -868
  148. package/dist/chunk-QQ6ULXHI.cjs +0 -885
  149. package/dist/chunk-UK3WM7YZ.cjs +0 -75
  150. package/dist/chunk-VOKMAAJP.js +0 -848
  151. package/dist/node-evaluator-4MSDKWOG.cjs +0 -22
  152. package/dist/node-evaluator-SX4LEYQC.js +0 -12
  153. package/dist/workflow-C2a05WUJ.d.ts +0 -444
  154. package/dist/workflow-J-yYixny.d.cts +0 -444
@@ -1,15 +1,202 @@
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';
1
+ import { isActivityNodeTypeAllowed } from './chunk-AC6ZEXVR.js';
2
+ import { PHASE_C_COMMANDS, PHASE_B_CORE_COMMANDS, PHASE_B_PARITY_COMMANDS, TERMINAL_COMMANDS, isInputEvent, isCommandEvent } from './chunk-5HIVIV53.js';
3
3
 
4
4
  // src/history/commands.ts
5
+ var COMMAND_FEATURES = [
6
+ "core",
7
+ "parity.can",
8
+ "parity.context",
9
+ "parity.localActivity",
10
+ "parity.externalCancel",
11
+ "parity.childOptions",
12
+ "parity.canOptions",
13
+ "parity.workflowIdTarget",
14
+ "c.updates",
15
+ "c.searchAttributes",
16
+ "c.userActivity"
17
+ ];
18
+ var PHASE_B_CORE_FEATURES = /* @__PURE__ */ new Set([
19
+ "core",
20
+ "parity.can",
21
+ "parity.context"
22
+ ]);
23
+ var PHASE_B_PARITY_FEATURES = /* @__PURE__ */ new Set([
24
+ "core",
25
+ "parity.can",
26
+ "parity.context",
27
+ "parity.localActivity",
28
+ "parity.externalCancel",
29
+ "parity.childOptions",
30
+ "parity.canOptions",
31
+ "parity.workflowIdTarget"
32
+ ]);
33
+ var PHASE_C_FEATURES = [
34
+ "c.updates",
35
+ "c.searchAttributes",
36
+ "c.userActivity"
37
+ ];
38
+ var PHASE_C_FEATURE_FLAGS = {
39
+ "c.updates": "fluidgrids.run-control",
40
+ "c.searchAttributes": "fluidgrids.search-attributes",
41
+ "c.userActivity": "fluidgrids.self-hosted-workers"
42
+ };
43
+ var CODE_FEATURE_FLAGS = {
44
+ localActivity: "fluidgrids.durable-parity",
45
+ externalCancel: "fluidgrids.durable-parity",
46
+ childOptions: "fluidgrids.durable-parity",
47
+ canOptions: "fluidgrids.durable-parity",
48
+ autoUpgrade: "fluidgrids.durable-parity",
49
+ runRetry: "fluidgrids.durable-parity",
50
+ timeouts: "fluidgrids.durable-parity",
51
+ userActivity: "fluidgrids.self-hosted-workers",
52
+ updates: "fluidgrids.run-control",
53
+ queries: "fluidgrids.run-control",
54
+ dynamic: "fluidgrids.run-control",
55
+ interceptors: "fluidgrids.run-control",
56
+ searchAttributes: "fluidgrids.search-attributes"
57
+ };
58
+ var PHASE_C_CODE_FEATURES = [
59
+ "userActivity",
60
+ "updates",
61
+ "queries",
62
+ "searchAttributes",
63
+ "dynamic",
64
+ "interceptors"
65
+ ];
66
+ var CORE_CHILD_OPTIONS = /* @__PURE__ */ new Set([
67
+ "parentClosePolicy",
68
+ "cancellationType",
69
+ "taskQueue",
70
+ "workflowId",
71
+ "priority",
72
+ "summary",
73
+ "details",
74
+ "context",
75
+ "startDelay",
76
+ "executionTimeout",
77
+ "runTimeout",
78
+ "workflowTaskTimeout",
79
+ "fairnessKey",
80
+ "fairnessWeight"
81
+ ]);
82
+ var CORE_CAN_OPTIONS = /* @__PURE__ */ new Set([
83
+ "taskQueue",
84
+ "retry",
85
+ "workflowTaskTimeout",
86
+ "context",
87
+ "versioningBehavior"
88
+ ]);
89
+ var LEGACY_RETRY_KEYS = ["retryDelay", "maxRetries", "maxDelay"];
90
+ var RUN_RETRY_KEYS = ["initialDelayMs", "maxAttempts", "maxDelayMs"];
91
+ function continueAsNewRetryShape(options) {
92
+ const retry = options["retry"];
93
+ if (retry === void 0) return "none";
94
+ if (typeof retry !== "object" || retry === null || Array.isArray(retry)) return "invalid";
95
+ const keys = Object.keys(retry);
96
+ const run = keys.some((key) => RUN_RETRY_KEYS.includes(key));
97
+ const legacy = keys.some((key) => LEGACY_RETRY_KEYS.includes(key));
98
+ if (run === legacy) return "invalid";
99
+ return run ? "run" : "legacy";
100
+ }
101
+ function hasOtherKeys(value, allowed) {
102
+ return Object.entries(value).some(([key, entry]) => entry !== void 0 && !allowed.has(key));
103
+ }
104
+ function commandFeatures(command) {
105
+ const needed = /* @__PURE__ */ new Set();
106
+ switch (command.type) {
107
+ case "SCHEDULE_ACTIVITY":
108
+ needed.add(command.kind === "user" ? "c.userActivity" : "core");
109
+ break;
110
+ case "START_CHILD_RUN":
111
+ needed.add("core");
112
+ if (hasOtherKeys(command.options, CORE_CHILD_OPTIONS)) needed.add("parity.childOptions");
113
+ break;
114
+ case "SIGNAL_RUN":
115
+ needed.add("core");
116
+ if ("workflowId" in command.target) needed.add("parity.workflowIdTarget");
117
+ break;
118
+ case "REQUEST_CANCEL_EXTERNAL_RUN":
119
+ if ("childId" in command.target) needed.add("core");
120
+ else needed.add("parity.externalCancel");
121
+ if ("workflowId" in command.target) needed.add("parity.workflowIdTarget");
122
+ break;
123
+ case "CONTINUE_AS_NEW":
124
+ needed.add("parity.can");
125
+ if (hasOtherKeys(command.options, CORE_CAN_OPTIONS) || continueAsNewRetryShape(command.options) === "run")
126
+ needed.add("parity.canOptions");
127
+ break;
128
+ case "UPSERT_CONTEXT":
129
+ needed.add("parity.context");
130
+ break;
131
+ case "RECORD_LOCAL_ACTIVITY":
132
+ needed.add("parity.localActivity");
133
+ break;
134
+ case "UPSERT_SEARCH_ATTRIBUTES":
135
+ needed.add("c.searchAttributes");
136
+ break;
137
+ case "ACCEPT_UPDATE":
138
+ case "REJECT_UPDATE":
139
+ case "COMPLETE_UPDATE":
140
+ needed.add("c.updates");
141
+ break;
142
+ default:
143
+ needed.add("core");
144
+ }
145
+ return COMMAND_FEATURES.filter((feature) => needed.has(feature));
146
+ }
5
147
  function isCommandEnabled(type, enabled = "core") {
6
148
  if (PHASE_C_COMMANDS.has(type)) return false;
7
149
  if (PHASE_B_CORE_COMMANDS.has(type)) return true;
8
150
  return enabled === "parity" && PHASE_B_PARITY_COMMANDS.has(type);
9
151
  }
152
+ function phaseCFeaturesOf(command) {
153
+ return commandFeatures(command).filter((feature) => feature.startsWith("c."));
154
+ }
10
155
  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);
156
+ if (typeof enabled === "string") {
157
+ if (phaseCFeaturesOf(command).length > 0) return false;
158
+ if (command.type === "REQUEST_CANCEL_EXTERNAL_RUN" && "childId" in command.target) return true;
159
+ return isCommandEnabled(command.type, enabled);
160
+ }
161
+ return commandFeatures(command).every((feature) => enabled.has(feature));
162
+ }
163
+ function codeFeaturesEnabledBy(enabled) {
164
+ if (typeof enabled === "string") return [];
165
+ const flags = /* @__PURE__ */ new Set(["fluidgrids.durable-functions"]);
166
+ for (const feature of enabled) {
167
+ if (PHASE_B_PARITY_FEATURES.has(feature) && !PHASE_B_CORE_FEATURES.has(feature))
168
+ flags.add("fluidgrids.durable-parity");
169
+ const flag = PHASE_C_FEATURE_FLAGS[feature];
170
+ if (flag !== void 0) flags.add(flag);
171
+ }
172
+ return Object.keys(CODE_FEATURE_FLAGS).filter((feature) => flags.has(CODE_FEATURE_FLAGS[feature] ?? "")).sort();
173
+ }
174
+ function unsupportedMessage(command, enabled = "core") {
175
+ const missing = typeof enabled === "string" ? phaseCFeaturesOf(command) : commandFeatures(command).filter((feature) => !enabled.has(feature));
176
+ if (missing.length === 0) return `${command.type} is not supported in this release`;
177
+ const flags = /* @__PURE__ */ new Set();
178
+ if (missing.some((feature) => feature.startsWith("parity.")))
179
+ flags.add("fluidgrids.durable-parity");
180
+ for (const feature of missing) {
181
+ const flag2 = PHASE_C_FEATURE_FLAGS[feature];
182
+ if (flag2 !== void 0) flags.add(flag2);
183
+ }
184
+ const names = [...flags];
185
+ const flag = names.length === 0 ? "" : ` (needs the ${names.join(" and ")} flag${names.length === 1 ? "" : "s"})`;
186
+ return `${command.type} needs ${missing.join(", ")}, which this workspace does not enable${flag}`;
187
+ }
188
+ function isReliefCommand(command, lease) {
189
+ switch (command.type) {
190
+ case "RECORD_LOCAL_ACTIVITY":
191
+ return lease.grantedLocalActivityIds.includes(command.localActivityId);
192
+ case "ACCEPT_UPDATE":
193
+ case "REJECT_UPDATE":
194
+ return lease.deliveredUpdateIds.includes(command.updateId);
195
+ case "COMPLETE_UPDATE":
196
+ return true;
197
+ default:
198
+ return false;
199
+ }
13
200
  }
14
201
 
15
202
  // src/history/activation.ts
@@ -107,12 +294,23 @@ function initialRunState() {
107
294
  timers: {},
108
295
  children: {},
109
296
  externals: {},
297
+ localActivities: {},
110
298
  sideEffects: {},
111
299
  markers: {},
112
300
  signalsReceived: 0,
113
- context: {}
301
+ context: {},
302
+ updates: {},
303
+ searchAttributes: {}
114
304
  };
115
305
  }
306
+ function mergeSearchAttributes(current, entries) {
307
+ const out = { ...current };
308
+ for (const [key, value] of Object.entries(entries)) {
309
+ if (value === null) delete out[key];
310
+ else out[key] = value;
311
+ }
312
+ return out;
313
+ }
116
314
  function utf8Bytes(text) {
117
315
  let bytes = 0;
118
316
  for (let index = 0; index < text.length; index++) {
@@ -187,6 +385,8 @@ function applyEvent(state, event) {
187
385
  state.input = p["input"] ?? null;
188
386
  if (typeof p["context"] === "object" && p["context"] !== null && !Array.isArray(p["context"]))
189
387
  state.context = { ...p["context"] };
388
+ if (typeof p["searchAttributes"] === "object" && p["searchAttributes"] !== null && !Array.isArray(p["searchAttributes"]))
389
+ state.searchAttributes = mergeSearchAttributes({}, p["searchAttributes"]);
190
390
  break;
191
391
  case "WORKFLOW_TASK_SCHEDULED":
192
392
  state.task = { state: "SCHEDULED", taskId: str(p, "taskId"), attempt: state.task.attempt };
@@ -211,11 +411,14 @@ function applyEvent(state, event) {
211
411
  const id = str(p, "activityId");
212
412
  if (state.activities[id])
213
413
  throw new HistoryStateError(`Activity "${id}" is scheduled twice`, event.seq);
414
+ const user = p["kind"] === "user";
214
415
  state.activities[id] = {
215
416
  status: "SCHEDULED",
216
417
  attempt: 0,
418
+ kind: user ? "user" : "node",
217
419
  nodeType: str(p, "nodeType"),
218
420
  operation: str(p, "operation"),
421
+ ...user ? { activityName: str(p, "activityName"), taskQueue: str(p, "taskQueue") } : {},
219
422
  scheduledSeq: event.seq,
220
423
  ...typeof p["cancellationType"] === "string" ? { cancellationType: p["cancellationType"] } : {},
221
424
  ...typeof p["summary"] === "string" ? { summary: p["summary"] } : {}
@@ -346,9 +549,61 @@ function applyEvent(state, event) {
346
549
  case "SIDE_EFFECT_RECORDED":
347
550
  state.sideEffects[str(p, "sideEffectId")] = p["value"] ?? null;
348
551
  break;
552
+ case "LOCAL_ACTIVITY_COMPLETED":
553
+ case "LOCAL_ACTIVITY_FAILED": {
554
+ const id = str(p, "localActivityId");
555
+ if (state.localActivities[id])
556
+ throw new HistoryStateError(`Local activity "${id}" is recorded twice`, event.seq);
557
+ state.localActivities[id] = {
558
+ status: event.type === "LOCAL_ACTIVITY_COMPLETED" ? "COMPLETED" : "FAILED",
559
+ attempts: typeof p["attempts"] === "number" ? p["attempts"] : 1,
560
+ recordedSeq: event.seq,
561
+ ...typeof p["nodeType"] === "string" ? { nodeType: p["nodeType"] } : {},
562
+ ...typeof p["operation"] === "string" ? { operation: p["operation"] } : {},
563
+ ...typeof p["summary"] === "string" ? { summary: p["summary"] } : {}
564
+ };
565
+ break;
566
+ }
349
567
  case "MARKER_RECORDED":
350
568
  state.markers[str(p, "markerId")] = p["data"] ?? null;
351
569
  break;
570
+ case "UPDATE_ADMITTED": {
571
+ const id = str(p, "updateId");
572
+ if (state.updates[id])
573
+ throw new HistoryStateError(`Update "${id}" is admitted twice`, event.seq);
574
+ state.updates[id] = { status: "ADMITTED", name: str(p, "name"), seq: event.seq };
575
+ break;
576
+ }
577
+ case "UPDATE_ACCEPTED": {
578
+ const id = str(p, "updateId");
579
+ const found = state.updates[id];
580
+ if (found && found.status !== "ADMITTED")
581
+ throw new HistoryStateError(`Update "${id}" is accepted twice`, event.seq);
582
+ state.updates[id] = {
583
+ status: "ACCEPTED",
584
+ name: found?.name ?? str(p, "name"),
585
+ seq: found?.seq ?? event.seq
586
+ };
587
+ break;
588
+ }
589
+ case "UPDATE_COMPLETED": {
590
+ const id = str(p, "updateId");
591
+ const found = state.updates[id];
592
+ if (!found || found.status !== "ACCEPTED")
593
+ throw new HistoryStateError(
594
+ `UPDATE_COMPLETED for update "${id}" that is not accepted`,
595
+ event.seq
596
+ );
597
+ found.status = "COMPLETED";
598
+ if (failureOf(p)) found.failed = true;
599
+ break;
600
+ }
601
+ case "SEARCH_ATTRIBUTES_UPSERTED": {
602
+ const attributes = p["attributes"];
603
+ if (typeof attributes === "object" && attributes !== null && !Array.isArray(attributes))
604
+ state.searchAttributes = mergeSearchAttributes(state.searchAttributes, attributes);
605
+ break;
606
+ }
352
607
  case "CONTEXT_UPSERTED": {
353
608
  const entries = p["entries"];
354
609
  if (typeof entries === "object" && entries !== null && !Array.isArray(entries))
@@ -404,6 +659,11 @@ function payloadOf(command) {
404
659
  }
405
660
  return out;
406
661
  }
662
+ function completedPayload(command) {
663
+ if (command.failure !== void 0)
664
+ return { updateId: command.updateId, failure: command.failure };
665
+ return { updateId: command.updateId, result: command.result ?? null };
666
+ }
407
667
  function eventsForCommands(state, commands, context) {
408
668
  const issues = [];
409
669
  const events = [];
@@ -421,11 +681,14 @@ function eventsForCommands(state, commands, context) {
421
681
  const children = new Set(Object.keys(state.children));
422
682
  const externals = new Set(Object.keys(state.externals));
423
683
  const sideEffects = new Set(Object.keys(state.sideEffects));
684
+ const localActivities = new Set(Object.keys(state.localActivities));
685
+ const updates = new Map(Object.entries(state.updates).map(([id, u]) => [id, u.status]));
686
+ const answered = /* @__PURE__ */ new Set();
424
687
  let unsupported = false;
425
688
  commands.forEach((command, index) => {
426
- if (!isWorkflowCommandEnabled(command, context.enabled)) {
689
+ if (!isWorkflowCommandEnabled(command, context.enabled) && !(context.relief !== void 0 && isReliefCommand(command, context.relief))) {
427
690
  unsupported = true;
428
- reject(index, "commands.unsupported", `${command.type} is not supported in this release`);
691
+ reject(index, "commands.unsupported", unsupportedMessage(command, context.enabled));
429
692
  return;
430
693
  }
431
694
  if (TERMINAL_COMMANDS.has(command.type) && index !== commands.length - 1)
@@ -435,7 +698,7 @@ function eventsForCommands(state, commands, context) {
435
698
  case "SCHEDULE_ACTIVITY":
436
699
  if (activities.has(command.activityId))
437
700
  reject(index, "activity.duplicate", `Activity "${command.activityId}" already exists`);
438
- if (!isActivityNodeTypeAllowed(command.nodeType))
701
+ if (command.kind === "node" && !isActivityNodeTypeAllowed(command.nodeType))
439
702
  reject(
440
703
  index,
441
704
  "durable.activityTypeNotAllowed",
@@ -516,6 +779,13 @@ function eventsForCommands(state, commands, context) {
516
779
  events.push({ ...base, type: "CONTEXT_UPSERTED", payload: payloadOf(command) });
517
780
  break;
518
781
  case "RECORD_LOCAL_ACTIVITY":
782
+ if (localActivities.has(command.localActivityId))
783
+ reject(
784
+ index,
785
+ "localActivity.duplicate",
786
+ `Local activity "${command.localActivityId}" is already recorded`
787
+ );
788
+ localActivities.add(command.localActivityId);
519
789
  events.push({
520
790
  ...base,
521
791
  type: command.failure ? "LOCAL_ACTIVITY_FAILED" : "LOCAL_ACTIVITY_COMPLETED",
@@ -525,6 +795,42 @@ function eventsForCommands(state, commands, context) {
525
795
  case "CONTINUE_AS_NEW":
526
796
  events.push({ ...base, type: "WORKFLOW_CONTINUED_AS_NEW", payload: payloadOf(command) });
527
797
  break;
798
+ case "UPSERT_SEARCH_ATTRIBUTES":
799
+ events.push({ ...base, type: "SEARCH_ATTRIBUTES_UPSERTED", payload: payloadOf(command) });
800
+ break;
801
+ case "ACCEPT_UPDATE":
802
+ case "REJECT_UPDATE": {
803
+ const id = command.updateId;
804
+ const status = updates.get(id);
805
+ const delivered = context.updates?.[id];
806
+ if (answered.has(id) || status !== void 0 && status !== "ADMITTED") {
807
+ reject(index, "update.answered", `Update "${id}" is already answered`);
808
+ break;
809
+ }
810
+ if (status === void 0 && delivered === void 0) {
811
+ reject(index, "update.unknown", `Update "${id}" was not delivered to this task`);
812
+ break;
813
+ }
814
+ answered.add(id);
815
+ if (command.type === "REJECT_UPDATE") break;
816
+ updates.set(id, "ACCEPTED");
817
+ const admitted = state.updates[id];
818
+ const payload = { updateId: id, name: admitted?.name ?? delivered?.name ?? "" };
819
+ if (delivered?.args !== void 0) payload["args"] = delivered.args;
820
+ if (delivered?.headers !== void 0) payload["headers"] = { ...delivered.headers };
821
+ events.push({ ...base, type: "UPDATE_ACCEPTED", payload });
822
+ break;
823
+ }
824
+ case "COMPLETE_UPDATE": {
825
+ const id = command.updateId;
826
+ if (updates.get(id) !== "ACCEPTED") {
827
+ reject(index, "update.notAccepted", `Update "${id}" is not accepted`);
828
+ break;
829
+ }
830
+ updates.set(id, "COMPLETED");
831
+ events.push({ ...base, type: "UPDATE_COMPLETED", payload: completedPayload(command) });
832
+ break;
833
+ }
528
834
  }
529
835
  });
530
836
  if (issues.length > 0)
@@ -559,47 +865,6 @@ function hasUnprocessedInput(history) {
559
865
  return unseenInputs(history).length > 0;
560
866
  }
561
867
 
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
868
  // src/history/defaults.ts
604
869
  function codeWorkflowParentClosePolicy(state) {
605
870
  const policy = state.parentClosePolicy;
@@ -609,4 +874,4 @@ function codeWorkflowParentClosePolicy(state) {
609
874
  var CHILD_DEFAULT_PARENT_CLOSE_POLICY = Object.freeze({ child: "TERMINATE", startChild: "ABANDON" });
610
875
  var CHILD_DEFAULT_CANCELLATION_TYPE = "WAIT_CANCELLATION_COMPLETED";
611
876
 
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 };
877
+ export { CHILD_DEFAULT_CANCELLATION_TYPE, CHILD_DEFAULT_PARENT_CLOSE_POLICY, CODE_FEATURE_FLAGS, COMMAND_FEATURES, CORE_CAN_OPTIONS, CORE_CHILD_OPTIONS, HistoryStateError, PHASE_B_CORE_FEATURES, PHASE_B_PARITY_FEATURES, PHASE_C_CODE_FEATURES, PHASE_C_FEATURES, PHASE_C_FEATURE_FLAGS, applyEvent, codeFeaturesEnabledBy, codeWorkflowParentClosePolicy, commandFeatures, continueAsNewRetryShape, eventsForCommands, hasUnprocessedInput, initialRunState, isActivityOpen, isChildOpen, isCommandEnabled, isReliefCommand, isWorkflowCommandEnabled, mergeSearchAttributes, pendingCounts, projectRunState, splitActivations, taskCompletedEvents, unseenInputs, unsupportedMessage, utf8Bytes };