@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
@@ -0,0 +1,2719 @@
1
+ 'use strict';
2
+
3
+ var chunkZCGKGDCL_cjs = require('./chunk-ZCGKGDCL.cjs');
4
+ var chunkQ4MWQNJK_cjs = require('./chunk-Q4MWQNJK.cjs');
5
+ var chunkL24YIZY7_cjs = require('./chunk-L24YIZY7.cjs');
6
+ var chunkVA4OFR72_cjs = require('./chunk-VA4OFR72.cjs');
7
+ var chunkISOIA7NV_cjs = require('./chunk-ISOIA7NV.cjs');
8
+ var chunkA5SXCA62_cjs = require('./chunk-A5SXCA62.cjs');
9
+ var chunkTYF56RGB_cjs = require('./chunk-TYF56RGB.cjs');
10
+
11
+ // src/runtime/ids.ts
12
+ var CommandIds = class {
13
+ counters = {
14
+ a: 0,
15
+ t: 0,
16
+ c: 0,
17
+ s: 0,
18
+ x: 0,
19
+ m: 0,
20
+ l: 0
21
+ };
22
+ /** The next id of a kind: `a1`, `a2`, ... */
23
+ next(kind) {
24
+ this.counters[kind] += 1;
25
+ return `${kind}${this.counters[kind]}`;
26
+ }
27
+ };
28
+ function patchMarkerId(patchId) {
29
+ return `patch:${patchId}`;
30
+ }
31
+ function isPatchMarkerId(markerId) {
32
+ return markerId.startsWith("patch:");
33
+ }
34
+
35
+ // src/runtime/matcher.ts
36
+ function field(event, key) {
37
+ return event.payload[key];
38
+ }
39
+ function describeCommand(command) {
40
+ switch (command.type) {
41
+ case "SCHEDULE_ACTIVITY":
42
+ return command.kind === "user" ? `SCHEDULE_ACTIVITY ${command.activityId} (user ${command.activityName})` : `SCHEDULE_ACTIVITY ${command.activityId} (${command.nodeType} ${command.operation})`;
43
+ case "REQUEST_CANCEL_ACTIVITY":
44
+ return `REQUEST_CANCEL_ACTIVITY ${command.activityId}`;
45
+ case "START_TIMER":
46
+ case "CANCEL_TIMER":
47
+ return `${command.type} ${command.timerId}`;
48
+ case "START_CHILD_RUN":
49
+ return `START_CHILD_RUN ${command.childId} (${command.workflowKey ?? command.workflowFn ?? ""})`;
50
+ case "SIGNAL_RUN":
51
+ return `SIGNAL_RUN ${command.externalId} (${command.name})`;
52
+ case "REQUEST_CANCEL_EXTERNAL_RUN":
53
+ return `REQUEST_CANCEL_EXTERNAL_RUN ${command.externalId}`;
54
+ case "RECORD_SIDE_EFFECT":
55
+ return `RECORD_SIDE_EFFECT ${command.sideEffectId}`;
56
+ case "RECORD_MARKER":
57
+ return `RECORD_MARKER ${command.markerId}`;
58
+ case "RECORD_LOCAL_ACTIVITY":
59
+ return `RECORD_LOCAL_ACTIVITY ${command.localActivityId}${command.nodeType !== void 0 ? ` (${command.nodeType} ${command.operation ?? ""})` : ""}`;
60
+ case "ACCEPT_UPDATE":
61
+ case "REJECT_UPDATE":
62
+ case "COMPLETE_UPDATE":
63
+ return `${command.type} ${command.updateId}`;
64
+ default:
65
+ return command.type;
66
+ }
67
+ }
68
+ function describeEvent(event) {
69
+ const id = field(event, "activityId") ?? field(event, "timerId") ?? field(event, "childId") ?? field(event, "externalId") ?? field(event, "sideEffectId") ?? field(event, "markerId") ?? field(event, "localActivityId") ?? field(event, "updateId");
70
+ return `${event.type}${typeof id === "string" ? ` ${id}` : ""} (seq ${event.seq})`;
71
+ }
72
+ function mismatch(command, event) {
73
+ const expected = chunkTYF56RGB_cjs.COMMAND_EVENT_TYPES[command.type];
74
+ const typeOk = command.type === "RECORD_LOCAL_ACTIVITY" ? event.type === "LOCAL_ACTIVITY_COMPLETED" || event.type === "LOCAL_ACTIVITY_FAILED" : event.type === expected;
75
+ const differ = () => `the code issued ${describeCommand(command)} where the history has ${describeEvent(event)}`;
76
+ if (!typeOk) return differ();
77
+ switch (command.type) {
78
+ case "SCHEDULE_ACTIVITY": {
79
+ if (field(event, "activityId") !== command.activityId) return differ();
80
+ const kind = field(event, "kind") ?? "node";
81
+ if (command.kind === "user")
82
+ return kind === "user" && field(event, "activityName") === command.activityName ? void 0 : differ();
83
+ return kind === "node" && field(event, "nodeType") === command.nodeType && field(event, "operation") === command.operation ? void 0 : differ();
84
+ }
85
+ case "REQUEST_CANCEL_ACTIVITY":
86
+ return field(event, "activityId") === command.activityId ? void 0 : differ();
87
+ case "START_TIMER":
88
+ case "CANCEL_TIMER":
89
+ return field(event, "timerId") === command.timerId ? void 0 : differ();
90
+ case "START_CHILD_RUN":
91
+ return field(event, "childId") === command.childId && (field(event, "workflowKey") ?? null) === (command.workflowKey ?? null) && (field(event, "workflowFn") ?? null) === (command.workflowFn ?? null) ? void 0 : differ();
92
+ case "SIGNAL_RUN":
93
+ return field(event, "externalId") === command.externalId && field(event, "name") === command.name ? void 0 : differ();
94
+ case "REQUEST_CANCEL_EXTERNAL_RUN":
95
+ return field(event, "externalId") === command.externalId ? void 0 : differ();
96
+ case "RECORD_SIDE_EFFECT":
97
+ return field(event, "sideEffectId") === command.sideEffectId ? void 0 : differ();
98
+ case "RECORD_MARKER":
99
+ return field(event, "markerId") === command.markerId ? void 0 : differ();
100
+ case "ACCEPT_UPDATE":
101
+ case "COMPLETE_UPDATE":
102
+ return field(event, "updateId") === command.updateId ? void 0 : differ();
103
+ case "RECORD_LOCAL_ACTIVITY": {
104
+ const sameOperation = field(event, "nodeType") === void 0 || field(event, "nodeType") === command.nodeType && field(event, "operation") === command.operation;
105
+ return field(event, "localActivityId") === command.localActivityId && sameOperation ? void 0 : differ();
106
+ }
107
+ default:
108
+ return void 0;
109
+ }
110
+ }
111
+ function isSkippablePatch(event) {
112
+ const markerId = field(event, "markerId");
113
+ return event.type === "MARKER_RECORDED" && typeof markerId === "string" && isPatchMarkerId(markerId);
114
+ }
115
+ function matchActivation(commands, recorded) {
116
+ let position = 0;
117
+ for (const command of commands) {
118
+ if (chunkTYF56RGB_cjs.COMMAND_EVENT_TYPES[command.type] === null) continue;
119
+ let event = recorded[position];
120
+ while (event !== void 0 && isSkippablePatch(event) && !(command.type === "RECORD_MARKER" && command.markerId === field(event, "markerId"))) {
121
+ position += 1;
122
+ event = recorded[position];
123
+ }
124
+ if (event === void 0)
125
+ return {
126
+ message: `the code issued ${describeCommand(command)}, which the history does not have`
127
+ };
128
+ const reason = mismatch(command, event);
129
+ if (reason !== void 0) return { message: reason, seq: event.seq };
130
+ position += 1;
131
+ }
132
+ for (; position < recorded.length; position++) {
133
+ const event = recorded[position];
134
+ if (event !== void 0 && !isSkippablePatch(event))
135
+ return {
136
+ message: `the history has ${describeEvent(event)}, which the code did not issue`,
137
+ seq: event.seq
138
+ };
139
+ }
140
+ return void 0;
141
+ }
142
+
143
+ // src/runtime/scheduler.ts
144
+ var COMMAND_ID_CALLS = {
145
+ a: "Scheduling an activity",
146
+ t: "Starting a timer",
147
+ c: "Starting a child run",
148
+ s: "ctx.sideEffect()",
149
+ x: "Signalling or cancelling another run",
150
+ m: "ctx.setCurrentDetails()",
151
+ l: "Running a local activity"
152
+ };
153
+ function isBuiltInQuery(name) {
154
+ return chunkTYF56RGB_cjs.BUILT_IN_QUERIES.includes(name);
155
+ }
156
+ var SDK_NAME = "@fluidgrids/workflows";
157
+ var ContinueAsNewRequest = class {
158
+ constructor(input, options, headers = {}) {
159
+ this.input = input;
160
+ this.options = options;
161
+ this.headers = headers;
162
+ }
163
+ input;
164
+ options;
165
+ headers;
166
+ };
167
+ function checkPolicy(policy) {
168
+ const value = policy ?? "WARN_AND_ABANDON";
169
+ if (value !== "WARN_AND_ABANDON" && value !== "ABANDON")
170
+ throw new TypeError("unfinishedPolicy must be WARN_AND_ABANDON or ABANDON");
171
+ return value;
172
+ }
173
+ var TaskFailure = class {
174
+ constructor(cause, message, stackTrace, seq, errorType) {
175
+ this.cause = cause;
176
+ this.message = message;
177
+ this.stackTrace = stackTrace;
178
+ this.seq = seq;
179
+ this.errorType = errorType;
180
+ }
181
+ cause;
182
+ message;
183
+ stackTrace;
184
+ seq;
185
+ errorType;
186
+ };
187
+ var Scope = class {
188
+ constructor(parent, nonCancellable) {
189
+ this.parent = parent;
190
+ this.nonCancellable = nonCancellable;
191
+ this.cancelRequested = new Promise((_resolve, reject) => {
192
+ this.rejectRequested = reject;
193
+ });
194
+ this.cancelRequested.catch(() => void 0);
195
+ if (parent && !nonCancellable) {
196
+ parent.children.add(this);
197
+ if (parent.consideredCancelled) this.cancel();
198
+ }
199
+ }
200
+ parent;
201
+ nonCancellable;
202
+ consideredCancelled = false;
203
+ cancelRequested;
204
+ rejectRequested = () => void 0;
205
+ handlers = /* @__PURE__ */ new Set();
206
+ children = /* @__PURE__ */ new Set();
207
+ /** Register a reaction to cancellation; returns its removal. */
208
+ onCancel(handler) {
209
+ if (this.consideredCancelled) {
210
+ handler();
211
+ return () => void 0;
212
+ }
213
+ this.handlers.add(handler);
214
+ return () => this.handlers.delete(handler);
215
+ }
216
+ /**
217
+ * Cancel the scope and its children. Every handler and child runs even when
218
+ * one throws; the first error is rethrown once the fan-out is complete.
219
+ */
220
+ cancel() {
221
+ if (this.consideredCancelled) return;
222
+ this.consideredCancelled = true;
223
+ this.rejectRequested(new chunkZCGKGDCL_cjs.CancelledFailure("Cancellation requested"));
224
+ const errors = [];
225
+ const handlers = [...this.handlers];
226
+ this.handlers.clear();
227
+ for (const handler of handlers) {
228
+ try {
229
+ handler();
230
+ } catch (error) {
231
+ errors.push(error);
232
+ }
233
+ }
234
+ for (const child of [...this.children]) {
235
+ try {
236
+ child.cancel();
237
+ } catch (error) {
238
+ errors.push(error);
239
+ }
240
+ }
241
+ if (errors.length > 0) throw errors[0];
242
+ }
243
+ detach() {
244
+ this.parent?.children.delete(this);
245
+ }
246
+ };
247
+ function checkHandlerName(name, what) {
248
+ if (typeof name !== "string" || name === "" || name.startsWith("__"))
249
+ throw new TypeError(`${what} needs a name that does not start with "__"`);
250
+ return name;
251
+ }
252
+ function definitionName(value, what) {
253
+ return checkHandlerName(typeof value === "string" ? value : value?.name, what);
254
+ }
255
+ function isHeaders(value) {
256
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
257
+ }
258
+ function headersOf(value) {
259
+ return isHeaders(value) ? { ...value } : {};
260
+ }
261
+ function checkFairness(options) {
262
+ const key = options.fairnessKey;
263
+ if (key !== void 0 && (typeof key !== "string" || key === "" || key.length > chunkTYF56RGB_cjs.FAIRNESS_KEY_MAX_LENGTH))
264
+ throw new TypeError(
265
+ `fairnessKey must be a string of 1 to ${chunkTYF56RGB_cjs.FAIRNESS_KEY_MAX_LENGTH} characters`
266
+ );
267
+ const weight = options.fairnessWeight;
268
+ if (weight !== void 0 && (typeof weight !== "number" || !Number.isFinite(weight) || weight < chunkTYF56RGB_cjs.FAIRNESS_WEIGHT_MIN || weight > chunkTYF56RGB_cjs.FAIRNESS_WEIGHT_MAX))
269
+ throw new TypeError(
270
+ `fairnessWeight must be a number from ${chunkTYF56RGB_cjs.FAIRNESS_WEIGHT_MIN} to ${chunkTYF56RGB_cjs.FAIRNESS_WEIGHT_MAX}`
271
+ );
272
+ }
273
+ function toJson(value, what) {
274
+ if (value === void 0) return null;
275
+ if (typeof value === "function" || typeof value === "symbol")
276
+ throw new TypeError(`${what} is not JSON: it is a ${typeof value}`);
277
+ let text;
278
+ try {
279
+ text = JSON.stringify(value);
280
+ } catch (error) {
281
+ if (!(error instanceof TypeError)) throw error;
282
+ throw new TypeError(`${what} is not JSON: ${error.message}`);
283
+ }
284
+ if (text === void 0) return null;
285
+ const parsed = JSON.parse(text);
286
+ return parsed;
287
+ }
288
+ function randomnessSeedOf(request) {
289
+ const started = request.history[0];
290
+ const seed = started?.type === "WORKFLOW_STARTED" ? started.payload["randomnessSeed"] : void 0;
291
+ return typeof seed === "string" ? seed : request.info.runId;
292
+ }
293
+ function errorName(error) {
294
+ return error instanceof Error ? error.name : "";
295
+ }
296
+ function messageOf(error) {
297
+ return error instanceof Error ? error.message : String(error);
298
+ }
299
+ function stackTextOf(error) {
300
+ return error instanceof Error && typeof error.stack === "string" ? error.stack : void 0;
301
+ }
302
+ function isJsonObject(value) {
303
+ return typeof value === "object" && value !== null && !Array.isArray(value);
304
+ }
305
+ function asFailure(value) {
306
+ return isJsonObject(value) ? value : void 0;
307
+ }
308
+ function infoFromStarted(info, started) {
309
+ if (started?.type !== "WORKFLOW_STARTED") return { ...info };
310
+ const p = started.payload;
311
+ const out = { ...info };
312
+ if (Object.hasOwn(p, "lastCompletionResult")) out.lastResult = p["lastCompletionResult"] ?? null;
313
+ if (Object.hasOwn(p, "lastFailure")) out.lastFailure = asFailure(p["lastFailure"]) ?? null;
314
+ const businessId = typeof p["businessId"] === "string" ? p["businessId"] : void 0;
315
+ const workflowId = typeof p["workflowId"] === "string" ? p["workflowId"] : businessId;
316
+ if (businessId !== void 0) out.businessId = businessId;
317
+ if (workflowId !== void 0) out.workflowId = workflowId;
318
+ if (typeof p["runAttempt"] === "number") {
319
+ out.runAttempt = p["runAttempt"];
320
+ out.attempt = p["runAttempt"];
321
+ }
322
+ if (typeof p["summary"] === "string") out.summary = p["summary"];
323
+ if (typeof p["details"] === "string") out.details = p["details"];
324
+ if (isJsonObject(p["context"])) {
325
+ out.context = { ...p["context"] };
326
+ out.memo = { ...p["context"] };
327
+ }
328
+ const timeouts = {};
329
+ const nested = isJsonObject(p["timeouts"]) ? p["timeouts"] : {};
330
+ for (const key of ["executionTimeout", "runTimeout", "workflowTaskTimeout"]) {
331
+ const value = nested[key] ?? p[key];
332
+ if (typeof value === "number") timeouts[key] = value;
333
+ }
334
+ if (Object.keys(timeouts).length > 0) out.timeouts = timeouts;
335
+ if (p["versioningBehavior"] === "PINNED" || p["versioningBehavior"] === "AUTO_UPGRADE")
336
+ out.versioningBehavior = p["versioningBehavior"];
337
+ if (isJsonObject(p["retry"])) out.retry = p["retry"];
338
+ if (typeof p["priority"] === "number") out.priority = p["priority"];
339
+ if (typeof p["firstRunId"] === "string") out.firstRunId = p["firstRunId"];
340
+ if (typeof p["continuedFromRunId"] === "string") out.continuedFromRunId = p["continuedFromRunId"];
341
+ if (isHeaders(p["headers"])) out.headers = { ...p["headers"] };
342
+ if (isJsonObject(p["searchAttributes"]))
343
+ out.searchAttributes = chunkISOIA7NV_cjs.mergeSearchAttributes({}, p["searchAttributes"]);
344
+ if (typeof p["fairnessKey"] === "string") out.fairnessKey = p["fairnessKey"];
345
+ if (typeof p["fairnessWeight"] === "number") out.fairnessWeight = p["fairnessWeight"];
346
+ if (out.workflowId === void 0 && out.businessId !== void 0) out.workflowId = out.businessId;
347
+ if (out.runAttempt === void 0 && out.attempt !== void 0) out.runAttempt = out.attempt;
348
+ return out;
349
+ }
350
+ var WorkflowExecution = class {
351
+ request;
352
+ definition;
353
+ exportNames;
354
+ sdkVersion;
355
+ activations;
356
+ index = -1;
357
+ activationOpen = false;
358
+ replaying = false;
359
+ clock = 0;
360
+ randomSource;
361
+ ids = new CommandIds();
362
+ commands = [];
363
+ newCommands = [];
364
+ logs = [];
365
+ failure;
366
+ closed = false;
367
+ captureStacks;
368
+ /** History length and inline bytes the current activation reports (see `Activation.historyLength`). */
369
+ historyLength = 0;
370
+ historyBytes = 0;
371
+ /** `bytesUpTo[n]`: UTF-8 bytes of the payloads of events 1..n. */
372
+ bytesUpTo;
373
+ limitEvents;
374
+ limitBytes;
375
+ root = new Scope(void 0, false);
376
+ /**
377
+ * Scopes whose function is running synchronously right now, innermost
378
+ * last. The outer `ctx` uses the innermost one, else the root: a scope is
379
+ * ambient only during the synchronous part of its function, never across
380
+ * an await, so concurrent branches never see each other's scopes.
381
+ */
382
+ syncScopes = [];
383
+ /** A scope that is never cancelled, for waits that ignore cancellation. */
384
+ detachedScope = new Scope(void 0, true);
385
+ cancelRequested = false;
386
+ activities = /* @__PURE__ */ new Map();
387
+ timers = /* @__PURE__ */ new Map();
388
+ children = /* @__PURE__ */ new Map();
389
+ externals = /* @__PURE__ */ new Map();
390
+ issued = /* @__PURE__ */ new Set();
391
+ recordedSideEffects = /* @__PURE__ */ new Map();
392
+ recordedMarkers = /* @__PURE__ */ new Set();
393
+ patches = /* @__PURE__ */ new Map();
394
+ signalBuffers = /* @__PURE__ */ new Map();
395
+ signalOrder = [];
396
+ signalHandlers = /* @__PURE__ */ new Map();
397
+ signalWaiters = /* @__PURE__ */ new Map();
398
+ defaultSignalHandler;
399
+ defaultSignalPolicy = "WARN_AND_ABANDON";
400
+ signalPolicies = /* @__PURE__ */ new Map();
401
+ runningHandlers = 0;
402
+ /** Running asynchronous handlers by name, for the drain warning (11 §2.18). */
403
+ running = /* @__PURE__ */ new Map();
404
+ unfinished;
405
+ /** Updates delivered so far, by id (an update is delivered at most once per task). */
406
+ deliveredUpdates = /* @__PURE__ */ new Set();
407
+ /** Updates delivered in the current activation without a handler yet. */
408
+ bufferedUpdates = [];
409
+ updateHandlers = /* @__PURE__ */ new Map();
410
+ defaultUpdateHandler;
411
+ queryHandlers = /* @__PURE__ */ new Map();
412
+ defaultQueryHandler;
413
+ /** Set while a query handler or an update validator runs: commands and sinks throw. */
414
+ readOnly;
415
+ /** The first state-changing call a read-only handler made, even when it caught the error. */
416
+ readOnlyViolation;
417
+ searchAttributes;
418
+ startHeaders;
419
+ inbound;
420
+ outbound;
421
+ sinkCalls = [];
422
+ sinkCallsDropped = false;
423
+ recordedLocalActivities = /* @__PURE__ */ new Map();
424
+ localActivityResults = /* @__PURE__ */ new Map();
425
+ localActivities = /* @__PURE__ */ new Map();
426
+ memo;
427
+ conditions = [];
428
+ currentDetails;
429
+ context;
430
+ info;
431
+ constructor(input) {
432
+ this.request = input.request;
433
+ this.definition = input.definition;
434
+ this.exportNames = input.exportNames;
435
+ this.sdkVersion = input.sdkVersion;
436
+ const history = input.request.history;
437
+ this.bytesUpTo = [0];
438
+ let bytes = 0;
439
+ for (const event of history) {
440
+ bytes += chunkISOIA7NV_cjs.utf8Bytes(JSON.stringify(event.payload));
441
+ this.bytesUpTo.push(bytes);
442
+ }
443
+ this.historyLength = history.length;
444
+ this.historyBytes = bytes;
445
+ const limit = input.request.info.historyLimit ?? chunkTYF56RGB_cjs.DEFAULT_HISTORY_LIMIT;
446
+ this.limitEvents = limit.events;
447
+ this.limitBytes = limit.bytes;
448
+ this.captureStacks = input.request.kind === "query";
449
+ this.randomSource = chunkL24YIZY7_cjs.createRandom(chunkL24YIZY7_cjs.seedOf(randomnessSeedOf(input.request)));
450
+ for (const event of history) {
451
+ if (event.type === "SIDE_EFFECT_RECORDED") {
452
+ const id = event.payload["sideEffectId"];
453
+ if (typeof id === "string")
454
+ this.recordedSideEffects.set(id, event.payload["value"] ?? null);
455
+ } else if (event.type === "MARKER_RECORDED") {
456
+ const id = event.payload["markerId"];
457
+ if (typeof id === "string") this.recordedMarkers.add(id);
458
+ } else if (event.type === "LOCAL_ACTIVITY_COMPLETED" || event.type === "LOCAL_ACTIVITY_FAILED") {
459
+ const id = event.payload["localActivityId"];
460
+ const failure = asFailure(event.payload["failure"]);
461
+ const attempts = event.payload["attempts"];
462
+ if (typeof id === "string")
463
+ this.recordedLocalActivities.set(id, {
464
+ ...event.type === "LOCAL_ACTIVITY_FAILED" && failure ? { failure } : { result: event.payload["result"] ?? null },
465
+ attempts: typeof attempts === "number" ? attempts : 1
466
+ });
467
+ }
468
+ }
469
+ if (input.request.kind === "task")
470
+ for (const entry of input.request.localActivityResults ?? [])
471
+ this.localActivityResults.set(entry.localActivityId, {
472
+ ...entry.failure !== void 0 ? { failure: entry.failure } : { result: entry.result ?? null },
473
+ attempts: entry.attempts
474
+ });
475
+ this.activations = chunkISOIA7NV_cjs.splitActivations(
476
+ history,
477
+ input.request.nowMs,
478
+ input.request.kind !== "query"
479
+ );
480
+ const execution = this;
481
+ const snapshot = infoFromStarted(input.request.info, history[0]);
482
+ this.memo = { ...snapshot.memo ?? snapshot.context ?? {} };
483
+ this.searchAttributes = { ...snapshot.searchAttributes ?? {} };
484
+ this.startHeaders = { ...snapshot.headers ?? {} };
485
+ let inbound = [];
486
+ let outbound = [];
487
+ const factories = input.interceptors ?? [];
488
+ if (factories.length > 0 && input.request.kind === "task" && !(input.request.features ?? []).includes("interceptors"))
489
+ this.failTask(
490
+ "UNSUPPORTED_COMMAND",
491
+ "The bundle exports interceptors, which this workspace does not enable (needs the fluidgrids.run-control flag)"
492
+ );
493
+ else
494
+ try {
495
+ const resolved = chunkVA4OFR72_cjs.resolveWorkflowInterceptors(factories);
496
+ inbound = resolved.inbound;
497
+ outbound = resolved.outbound;
498
+ } catch (error) {
499
+ this.failTask(
500
+ "WORKFLOW_CODE_ERROR",
501
+ `The interceptors factory failed: ${messageOf(error)}`,
502
+ stackTextOf(error)
503
+ );
504
+ }
505
+ this.inbound = inbound;
506
+ this.outbound = outbound;
507
+ this.info = {
508
+ ...snapshot,
509
+ workflowFn: input.request.workflowFn,
510
+ get context() {
511
+ return { ...execution.memo };
512
+ },
513
+ get memo() {
514
+ return { ...execution.memo };
515
+ },
516
+ get searchAttributes() {
517
+ return { ...execution.searchAttributes };
518
+ },
519
+ get historyLength() {
520
+ return execution.historyLength;
521
+ },
522
+ get historyBytes() {
523
+ return execution.historyBytes;
524
+ },
525
+ get continueAsNewSuggested() {
526
+ return execution.continueAsNewSuggested();
527
+ },
528
+ get isReplaying() {
529
+ return execution.replaying;
530
+ }
531
+ };
532
+ this.context = this.contextFor(void 0);
533
+ }
534
+ continueAsNewSuggested() {
535
+ return this.historyLength >= this.limitEvents * chunkTYF56RGB_cjs.CONTINUE_AS_NEW_SUGGESTED_RATIO || this.historyBytes >= this.limitBytes * chunkTYF56RGB_cjs.CONTINUE_AS_NEW_SUGGESTED_RATIO;
536
+ }
537
+ /** The workflow clock. */
538
+ now() {
539
+ return this.clock;
540
+ }
541
+ /** The next deterministic random number (`Math.random()` and `crypto.getRandomValues()`). */
542
+ nextRandom() {
543
+ this.assertWritable("Math.random() or crypto.getRandomValues()");
544
+ return this.randomSource();
545
+ }
546
+ /** `ctx.random()`: advances the run's random source, so read-only handlers may not call it. */
547
+ random() {
548
+ this.assertWritable("ctx.random()");
549
+ return this.randomSource();
550
+ }
551
+ /**
552
+ * Throw `QueryHandlerSideEffect` when a query handler or an update validator
553
+ * calls something that changes the run's deterministic state (the random
554
+ * source, the command id counters, patches, details). Validators are not run
555
+ * again on replay, and a worker that keeps a run's state between tasks keeps
556
+ * whatever a query handler changed, so either would make the next replay
557
+ * diverge. The violation is remembered, so catching the error does not hide it.
558
+ */
559
+ assertWritable(what) {
560
+ if (this.readOnly === void 0) return;
561
+ this.readOnlyViolation ??= what;
562
+ throw new chunkZCGKGDCL_cjs.QueryHandlerSideEffect(`${what} (in ${this.readOnly})`);
563
+ }
564
+ /** The next command id of a kind; refused in read-only handlers (it advances a counter). */
565
+ nextId(kind) {
566
+ this.assertWritable(COMMAND_ID_CALLS[kind]);
567
+ return this.ids.next(kind);
568
+ }
569
+ /** Begin or finish an activation; `done` when there is nothing left to do. */
570
+ step() {
571
+ if (this.failure) return "done";
572
+ if (this.activationOpen) {
573
+ if (this.checkConditions()) return "more";
574
+ this.finishActivation();
575
+ if (this.failure) return "done";
576
+ }
577
+ const next = this.activations[this.index + 1];
578
+ if (!next) return "done";
579
+ this.index += 1;
580
+ this.beginActivation(next);
581
+ return this.failure ? "done" : "more";
582
+ }
583
+ /** The task's result. Call after `step()` returned `done` and jobs were drained. */
584
+ complete() {
585
+ if (!this.failure && this.activationOpen) {
586
+ this.checkConditions();
587
+ this.finishActivation();
588
+ }
589
+ const requests = this.pendingLocalActivityRequests();
590
+ if (requests.length > 0) {
591
+ const requested = {
592
+ protocol: chunkTYF56RGB_cjs.HISTORY_PROTOCOL,
593
+ outcome: "localActivityRequested",
594
+ commands: [],
595
+ localActivityRequests: requests,
596
+ logs: []
597
+ };
598
+ return requested;
599
+ }
600
+ const result = {
601
+ protocol: chunkTYF56RGB_cjs.HISTORY_PROTOCOL,
602
+ outcome: this.failure ? "failed" : "commands",
603
+ commands: this.failure ? [] : this.newCommands,
604
+ logs: this.logs
605
+ };
606
+ if (!this.failure && this.unfinished !== void 0) result.unfinishedHandlers = this.unfinished;
607
+ if (!this.failure && this.request.kind === "task" && this.sinkCalls.length > 0)
608
+ result.sinkCalls = this.sinkCalls;
609
+ if (this.failure) {
610
+ result.failure = { cause: this.failure.cause, message: this.failure.message };
611
+ if (this.failure.stackTrace !== void 0)
612
+ result.failure.stackTrace = this.failure.stackTrace;
613
+ if (this.failure.seq !== void 0) result.failure.seq = this.failure.seq;
614
+ if (this.failure.errorType !== void 0) result.failure.errorType = this.failure.errorType;
615
+ }
616
+ if (this.request.kind === "query" || (this.request.queries ?? []).length > 0)
617
+ result.queryResults = this.answerQueries();
618
+ return result;
619
+ }
620
+ /**
621
+ * The local activities the open activation waits for, when the task is a
622
+ * workflow task that has not failed or closed the run (a run that ends
623
+ * abandons a local activity it did not await).
624
+ */
625
+ pendingLocalActivityRequests() {
626
+ if (this.failure || this.closed || this.request.kind !== "task") return [];
627
+ return [...this.localActivities.values()].filter((entry) => !entry.replayed).map((entry) => entry.request);
628
+ }
629
+ /** Fail the task (the runtime's own failures and code errors). */
630
+ failTask(cause, message, stackTrace, seq, errorType) {
631
+ if (!this.failure) this.failure = new TaskFailure(cause, message, stackTrace, seq, errorType);
632
+ }
633
+ beginActivation(activation) {
634
+ this.activationOpen = true;
635
+ this.replaying = activation.recorded !== void 0;
636
+ this.clock = activation.timeMs;
637
+ this.historyLength = activation.historyLength;
638
+ this.historyBytes = this.bytesUpTo[Math.min(activation.historyLength, this.bytesUpTo.length - 1)] ?? 0;
639
+ this.commands = [];
640
+ for (const event of activation.inputs) {
641
+ if (this.failure) return;
642
+ this.deliver(event);
643
+ }
644
+ for (const update of this.updatesOf(activation)) {
645
+ if (this.failure) return;
646
+ this.deliverUpdate(update);
647
+ }
648
+ }
649
+ /**
650
+ * The updates an activation delivers after its inputs (C-ABI-H): a replayed
651
+ * activation re-delivers the updates its task accepted (validators
652
+ * skipped); the open activation of a workflow task delivers the lease's
653
+ * pending updates. Updates history admitted (`UPDATE_ADMITTED`) arrive as
654
+ * inputs instead.
655
+ */
656
+ updatesOf(activation) {
657
+ const out = [];
658
+ if (activation.recorded) {
659
+ for (const event of activation.recorded) {
660
+ if (event.type !== "UPDATE_ACCEPTED") continue;
661
+ const p = event.payload;
662
+ const updateId = typeof p["updateId"] === "string" ? p["updateId"] : "";
663
+ if (this.deliveredUpdates.has(updateId)) continue;
664
+ out.push({
665
+ updateId,
666
+ name: typeof p["name"] === "string" ? p["name"] : "",
667
+ args: p["args"] ?? null,
668
+ headers: headersOf(p["headers"]),
669
+ validate: false
670
+ });
671
+ }
672
+ return out;
673
+ }
674
+ if (this.request.kind === "query") return out;
675
+ for (const update of this.request.updates ?? []) {
676
+ if (update.admitted === true || this.deliveredUpdates.has(update.updateId)) continue;
677
+ out.push({
678
+ updateId: update.updateId,
679
+ name: update.name,
680
+ args: update.args ?? null,
681
+ headers: headersOf(update.headers),
682
+ validate: true
683
+ });
684
+ }
685
+ return out;
686
+ }
687
+ finishActivation() {
688
+ this.activationOpen = false;
689
+ const activation = this.activations[this.index];
690
+ if (!activation) return;
691
+ this.rejectUnhandledUpdates();
692
+ if (activation.recorded) {
693
+ const found = matchActivation(this.commands, activation.recorded);
694
+ if (found)
695
+ this.failTask(
696
+ "NON_DETERMINISM",
697
+ `Replay of workflow task ${activation.taskId ?? this.index + 1} diverged: ${found.message}`,
698
+ void 0,
699
+ found.seq
700
+ );
701
+ else this.checkReplayedLocalActivities();
702
+ } else {
703
+ this.newCommands = this.commands;
704
+ }
705
+ this.commands = [];
706
+ }
707
+ /**
708
+ * A local activity issued on a replayed activation without a recorded
709
+ * outcome is fine only when the first execution dropped it in that same
710
+ * activation: its scope was cancelled (the entry is gone) or the run closed.
711
+ * One still waiting means the first execution would have requested and
712
+ * recorded it, so the code diverged from the history.
713
+ */
714
+ checkReplayedLocalActivities() {
715
+ if (this.closed) return;
716
+ for (const entry of this.localActivities.values()) {
717
+ if (!entry.replayed) continue;
718
+ this.failTask(
719
+ "NON_DETERMINISM",
720
+ `Replay of ${entry.description ?? "a local activity"} found no recorded outcome: the code issued a local activity the history does not have`
721
+ );
722
+ return;
723
+ }
724
+ }
725
+ // ---- inputs ---------------------------------------------------------------
726
+ deliver(event) {
727
+ const p = event.payload;
728
+ const id = (key) => typeof p[key] === "string" ? p[key] : "";
729
+ switch (event.type) {
730
+ case "WORKFLOW_STARTED":
731
+ this.startFunction(p["input"] ?? null);
732
+ return;
733
+ case "ACTIVITY_COMPLETED":
734
+ case "ACTIVITY_FAILED":
735
+ case "ACTIVITY_TIMED_OUT":
736
+ case "ACTIVITY_CANCELLED":
737
+ this.settleActivity(event, id("activityId"));
738
+ return;
739
+ case "TIMER_FIRED": {
740
+ const timerId = id("timerId");
741
+ this.expectIssued(`timer:${timerId}`, event);
742
+ const pending = this.timers.get(timerId);
743
+ if (pending) {
744
+ this.timers.delete(timerId);
745
+ pending.release?.();
746
+ pending.resolve(void 0);
747
+ }
748
+ return;
749
+ }
750
+ case "SIGNAL_RECEIVED":
751
+ this.dispatchSignal(id("name"), p["payload"] ?? null, headersOf(p["headers"]));
752
+ return;
753
+ case "UPDATE_ADMITTED": {
754
+ const updateId = id("updateId");
755
+ if (this.deliveredUpdates.has(updateId)) return;
756
+ this.deliverUpdate({
757
+ updateId,
758
+ name: id("name"),
759
+ args: p["args"] ?? null,
760
+ headers: headersOf(p["headers"]),
761
+ validate: true
762
+ });
763
+ return;
764
+ }
765
+ case "CHILD_RUN_STARTED":
766
+ case "CHILD_RUN_COMPLETED":
767
+ case "CHILD_RUN_FAILED":
768
+ case "CHILD_RUN_CANCELLED":
769
+ case "CHILD_RUN_TERMINATED":
770
+ case "CHILD_RUN_TIMED_OUT":
771
+ this.settleChild(event, id("childId"));
772
+ return;
773
+ case "EXTERNAL_RUN_SIGNALED":
774
+ case "EXTERNAL_RUN_CANCEL_RESOLVED": {
775
+ const externalId = id("externalId");
776
+ this.expectIssued(`external:${externalId}`, event);
777
+ const pending = this.externals.get(externalId);
778
+ if (!pending) return;
779
+ this.externals.delete(externalId);
780
+ if (p["ok"] === true) pending.resolve(void 0);
781
+ else {
782
+ const failure = p["failure"];
783
+ pending.reject(
784
+ typeof failure === "object" && failure !== null && !Array.isArray(failure) ? chunkZCGKGDCL_cjs.failureToError(failure) : new chunkZCGKGDCL_cjs.ServerFailure(`${pending.description} was not delivered`)
785
+ );
786
+ }
787
+ return;
788
+ }
789
+ case "WORKFLOW_CANCEL_REQUESTED":
790
+ this.cancelRequested = true;
791
+ this.root.cancel();
792
+ return;
793
+ default:
794
+ return;
795
+ }
796
+ }
797
+ expectIssued(key, event) {
798
+ if (!this.issued.has(key))
799
+ this.failTask(
800
+ "NON_DETERMINISM",
801
+ `The history has ${event.type} (seq ${event.seq}) for ${key}, which the code never issued`,
802
+ void 0,
803
+ event.seq
804
+ );
805
+ }
806
+ settleActivity(event, activityId) {
807
+ this.expectIssued(`activity:${activityId}`, event);
808
+ const pending = this.activities.get(activityId);
809
+ if (!pending) return;
810
+ this.activities.delete(activityId);
811
+ pending.release?.();
812
+ const p = event.payload;
813
+ const failure = typeof p["failure"] === "object" && p["failure"] !== null && !Array.isArray(p["failure"]) ? p["failure"] : void 0;
814
+ const label = pending.activityName !== void 0 ? `user ${pending.activityName}` : `${pending.nodeType} ${pending.operation}`;
815
+ const wrap = (cause) => new chunkZCGKGDCL_cjs.ActivityFailure(
816
+ `Activity ${activityId} (${label}) failed: ${cause.message}`,
817
+ activityId,
818
+ pending.nodeType,
819
+ pending.operation,
820
+ cause,
821
+ pending.activityName
822
+ );
823
+ switch (event.type) {
824
+ case "ACTIVITY_COMPLETED":
825
+ pending.resolve(p["result"] ?? null);
826
+ return;
827
+ case "ACTIVITY_FAILED":
828
+ pending.reject(
829
+ wrap(
830
+ failure ? chunkZCGKGDCL_cjs.failureToError(failure) : new chunkZCGKGDCL_cjs.ApplicationError("Activity failed", { errorType: "UNKNOWN" })
831
+ )
832
+ );
833
+ return;
834
+ case "ACTIVITY_TIMED_OUT": {
835
+ const timeoutType = typeof p["timeoutType"] === "string" ? p["timeoutType"] : "UNKNOWN";
836
+ pending.reject(
837
+ wrap(new chunkZCGKGDCL_cjs.TimeoutFailure(`Activity timed out (${timeoutType})`, timeoutType))
838
+ );
839
+ return;
840
+ }
841
+ default:
842
+ pending.reject(wrap(new chunkZCGKGDCL_cjs.CancelledFailure("Activity cancelled")));
843
+ }
844
+ }
845
+ settleChild(event, childId) {
846
+ this.expectIssued(`child:${childId}`, event);
847
+ const child = this.children.get(childId);
848
+ if (!child) return;
849
+ const p = event.payload;
850
+ if (typeof p["childRunId"] === "string") child.runId = p["childRunId"];
851
+ if (event.type === "CHILD_RUN_STARTED") {
852
+ const started2 = child.started;
853
+ child.started = void 0;
854
+ started2?.resolve(child.runId);
855
+ return;
856
+ }
857
+ let outcome;
858
+ const failureValue = p["failure"];
859
+ const failure = typeof failureValue === "object" && failureValue !== null && !Array.isArray(failureValue) ? failureValue : void 0;
860
+ const wrap = (cause) => new chunkZCGKGDCL_cjs.ChildRunFailure(
861
+ `Child run ${childId} ${event.type.slice("CHILD_RUN_".length).toLowerCase().replace("_", " ")}: ${cause.message}`,
862
+ childId,
863
+ child.runId,
864
+ cause
865
+ );
866
+ switch (event.type) {
867
+ case "CHILD_RUN_COMPLETED":
868
+ outcome = { ok: true, value: p["result"] ?? null };
869
+ break;
870
+ case "CHILD_RUN_FAILED":
871
+ outcome = {
872
+ ok: false,
873
+ error: wrap(
874
+ failure ? chunkZCGKGDCL_cjs.failureToError(failure) : new chunkZCGKGDCL_cjs.ApplicationError("Child failed", { errorType: "UNKNOWN" })
875
+ )
876
+ };
877
+ break;
878
+ case "CHILD_RUN_CANCELLED":
879
+ outcome = { ok: false, error: wrap(new chunkZCGKGDCL_cjs.CancelledFailure("Child run cancelled")) };
880
+ break;
881
+ case "CHILD_RUN_TERMINATED":
882
+ outcome = {
883
+ ok: false,
884
+ error: wrap(
885
+ new chunkZCGKGDCL_cjs.TerminatedFailure(typeof p["reason"] === "string" ? p["reason"] : "Terminated")
886
+ )
887
+ };
888
+ break;
889
+ default: {
890
+ const timeoutType = typeof p["timeoutType"] === "string" ? p["timeoutType"] : "WORKFLOW_RUN";
891
+ outcome = {
892
+ ok: false,
893
+ error: wrap(new chunkZCGKGDCL_cjs.TimeoutFailure(`Child run timed out (${timeoutType})`, timeoutType))
894
+ };
895
+ }
896
+ }
897
+ child.settled = true;
898
+ child.outcome = outcome;
899
+ const started = child.started;
900
+ child.started = void 0;
901
+ if (started) {
902
+ if (outcome.ok) started.resolve(child.runId);
903
+ else started.reject(outcome.error);
904
+ }
905
+ const result = child.result;
906
+ child.result = void 0;
907
+ if (result) {
908
+ result.release?.();
909
+ if (outcome.ok) result.resolve(outcome.value);
910
+ else result.reject(outcome.error);
911
+ }
912
+ }
913
+ /** Run a signal handler through the inbound `handleSignal` interceptors. */
914
+ signalCall(name, payload, headers, handler) {
915
+ if (this.inbound.length === 0) return () => handler(payload);
916
+ const chain = chunkVA4OFR72_cjs.compose(
917
+ this.inbound,
918
+ "handleSignal",
919
+ (input) => handler(input.payload)
920
+ );
921
+ return () => chain({ name, payload, headers });
922
+ }
923
+ dispatchSignal(name, payload, headers = {}) {
924
+ const handler = this.signalHandlers.get(name);
925
+ if (handler) {
926
+ this.runHandler(
927
+ this.signalCall(name, payload, headers, handler),
928
+ name,
929
+ this.signalPolicies.get(name)
930
+ );
931
+ return;
932
+ }
933
+ const waiters = this.signalWaiters.get(name);
934
+ const waiter = waiters?.shift();
935
+ if (waiter) {
936
+ waiter.release?.();
937
+ waiter.resolve(payload);
938
+ return;
939
+ }
940
+ if (this.defaultSignalHandler) {
941
+ const fallback = this.defaultSignalHandler;
942
+ this.runHandler(
943
+ this.signalCall(name, payload, headers, (value) => fallback(name, value)),
944
+ name,
945
+ this.defaultSignalPolicy
946
+ );
947
+ return;
948
+ }
949
+ const buffer = this.signalBuffers.get(name) ?? [];
950
+ buffer.push(payload);
951
+ this.signalBuffers.set(name, buffer);
952
+ this.signalOrder.push({ name, payload });
953
+ }
954
+ takeBuffered(name) {
955
+ const buffer = this.signalBuffers.get(name);
956
+ if (!buffer || buffer.length === 0) return void 0;
957
+ const payload = buffer.shift();
958
+ const position = this.signalOrder.findIndex((entry) => entry.name === name);
959
+ if (position >= 0) this.signalOrder.splice(position, 1);
960
+ return payload;
961
+ }
962
+ runHandler(call, name, policy = "WARN_AND_ABANDON") {
963
+ let result;
964
+ try {
965
+ result = call();
966
+ } catch (error) {
967
+ this.onWorkflowError(error);
968
+ return;
969
+ }
970
+ if (result instanceof Promise) {
971
+ const done = this.trackHandler("signal", name, policy);
972
+ result.then(done, (error) => {
973
+ done();
974
+ this.onWorkflowError(error);
975
+ });
976
+ }
977
+ }
978
+ /** Count a running asynchronous handler (drain check, `allHandlersFinished`); returns its end. */
979
+ trackHandler(kind, name, policy) {
980
+ this.runningHandlers += 1;
981
+ const key = `${kind}:${name}`;
982
+ const entry = this.running.get(key) ?? { kind, name, count: 0, policy };
983
+ entry.count += 1;
984
+ entry.policy = policy;
985
+ this.running.set(key, entry);
986
+ return () => {
987
+ this.runningHandlers -= 1;
988
+ entry.count -= 1;
989
+ if (entry.count === 0) this.running.delete(key);
990
+ };
991
+ }
992
+ // ---- updates (Phase C) ----------------------------------------------------
993
+ deliverUpdate(update) {
994
+ this.deliveredUpdates.add(update.updateId);
995
+ const entry = this.updateHandlerFor(update.name);
996
+ if (!entry) {
997
+ this.bufferedUpdates.push(update);
998
+ return;
999
+ }
1000
+ this.runUpdate(update, entry);
1001
+ }
1002
+ updateHandlerFor(name) {
1003
+ const own = this.updateHandlers.get(name);
1004
+ if (own) return own;
1005
+ const fallback = this.defaultUpdateHandler;
1006
+ if (!fallback) return void 0;
1007
+ const validate = fallback.validate;
1008
+ return {
1009
+ handler: (args) => fallback.handler(name, args),
1010
+ ...validate !== void 0 ? { validate: (args) => validate(name, args) } : {},
1011
+ policy: fallback.policy
1012
+ };
1013
+ }
1014
+ /**
1015
+ * Run `fn` with commands, sinks and every other change to the run's
1016
+ * deterministic state refused (query handlers, update validators). A
1017
+ * refused call fails the whole call with `QueryHandlerSideEffect`, even
1018
+ * when the code caught the error it threw.
1019
+ */
1020
+ readOnlyCall(what, fn) {
1021
+ const previous = this.readOnly;
1022
+ const previousViolation = this.readOnlyViolation;
1023
+ this.readOnly = what;
1024
+ this.readOnlyViolation = void 0;
1025
+ try {
1026
+ let value;
1027
+ try {
1028
+ value = fn();
1029
+ } catch (error) {
1030
+ const violation2 = this.readOnlyViolation;
1031
+ if (violation2 !== void 0 && !(error instanceof chunkZCGKGDCL_cjs.QueryHandlerSideEffect))
1032
+ throw new chunkZCGKGDCL_cjs.QueryHandlerSideEffect(`${violation2} (in ${what})`);
1033
+ throw error;
1034
+ }
1035
+ const violation = this.readOnlyViolation;
1036
+ if (violation !== void 0) throw new chunkZCGKGDCL_cjs.QueryHandlerSideEffect(`${violation} (in ${what})`);
1037
+ return value;
1038
+ } finally {
1039
+ this.readOnly = previous;
1040
+ this.readOnlyViolation = previousViolation;
1041
+ }
1042
+ }
1043
+ /**
1044
+ * Validate, accept and run one update. A validator error rejects it
1045
+ * (`REJECT_UPDATE`, no history); otherwise `ACCEPT_UPDATE` is issued and
1046
+ * the handler's result or failure completes it (`COMPLETE_UPDATE`). A
1047
+ * handler that throws something other than a failure class fails the task,
1048
+ * as a signal handler does.
1049
+ */
1050
+ runUpdate(update, entry) {
1051
+ if (this.closed || this.failure) return;
1052
+ const input = {
1053
+ updateId: update.updateId,
1054
+ name: update.name,
1055
+ args: update.args,
1056
+ headers: update.headers
1057
+ };
1058
+ if (update.validate && (entry.validate !== void 0 || this.inbound.length > 0)) {
1059
+ const validate = chunkVA4OFR72_cjs.compose(
1060
+ this.inbound,
1061
+ "validateUpdate",
1062
+ (checked) => entry.validate?.(checked.args)
1063
+ );
1064
+ try {
1065
+ this.readOnlyCall(`The validator of update ${update.name}`, () => validate(input));
1066
+ } catch (error) {
1067
+ if (error instanceof chunkZCGKGDCL_cjs.QueryHandlerSideEffect) {
1068
+ this.failTask("WORKFLOW_CODE_ERROR", messageOf(error), stackTextOf(error));
1069
+ return;
1070
+ }
1071
+ const failure = chunkZCGKGDCL_cjs.errorToFailure(error);
1072
+ delete failure.stackTrace;
1073
+ this.commands.push({ type: "REJECT_UPDATE", updateId: update.updateId, failure });
1074
+ return;
1075
+ }
1076
+ }
1077
+ if (!this.push({ type: "ACCEPT_UPDATE", updateId: update.updateId })) return;
1078
+ const handle = chunkVA4OFR72_cjs.compose(
1079
+ this.inbound,
1080
+ "handleUpdate",
1081
+ (accepted) => entry.handler(accepted.args)
1082
+ );
1083
+ let result;
1084
+ try {
1085
+ result = handle(input);
1086
+ } catch (error) {
1087
+ this.completeUpdate(update, { ok: false, error });
1088
+ return;
1089
+ }
1090
+ if (result instanceof Promise) {
1091
+ const done = this.trackHandler("update", update.name, entry.policy);
1092
+ result.then(
1093
+ (value) => {
1094
+ done();
1095
+ this.completeUpdate(update, { ok: true, value });
1096
+ },
1097
+ (error) => {
1098
+ done();
1099
+ this.completeUpdate(update, { ok: false, error });
1100
+ }
1101
+ );
1102
+ return;
1103
+ }
1104
+ this.completeUpdate(update, { ok: true, value: result });
1105
+ }
1106
+ completeUpdate(update, outcome) {
1107
+ if (this.closed || this.failure) return;
1108
+ if (outcome.ok) {
1109
+ let value;
1110
+ try {
1111
+ value = toJson(outcome.value, `The result of update ${update.name}`);
1112
+ } catch (error2) {
1113
+ this.onWorkflowError(error2);
1114
+ return;
1115
+ }
1116
+ this.push({ type: "COMPLETE_UPDATE", updateId: update.updateId, result: value });
1117
+ return;
1118
+ }
1119
+ const error = outcome.error;
1120
+ if (error instanceof ContinueAsNewRequest || !(chunkZCGKGDCL_cjs.isRunFailure(error) || this.isFailureType(error))) {
1121
+ this.onWorkflowError(error);
1122
+ return;
1123
+ }
1124
+ const failure = chunkZCGKGDCL_cjs.errorToFailure(error);
1125
+ delete failure.stackTrace;
1126
+ this.push({ type: "COMPLETE_UPDATE", updateId: update.updateId, failure });
1127
+ }
1128
+ /** Reject the updates of this activation that no handler took (`UpdateNotHandled`). */
1129
+ rejectUnhandledUpdates() {
1130
+ const pending = this.bufferedUpdates;
1131
+ this.bufferedUpdates = [];
1132
+ if (this.closed || this.failure) return;
1133
+ for (const update of pending)
1134
+ this.commands.push({
1135
+ type: "REJECT_UPDATE",
1136
+ updateId: update.updateId,
1137
+ failure: {
1138
+ errorType: "VALIDATION",
1139
+ type: "UpdateNotHandled",
1140
+ message: `The workflow has no handler for update "${update.name}"`,
1141
+ source: "sdk-ts"
1142
+ }
1143
+ });
1144
+ }
1145
+ handleUpdate(update, handler, options = {}) {
1146
+ const name = definitionName(update, "ctx.handleUpdate");
1147
+ if (typeof handler !== "function")
1148
+ throw new TypeError("ctx.handleUpdate needs a handler function");
1149
+ if (options.validate !== void 0 && typeof options.validate !== "function")
1150
+ throw new TypeError("validate must be a function");
1151
+ const policy = checkPolicy(options.unfinishedPolicy);
1152
+ this.updateHandlers.set(name, {
1153
+ handler,
1154
+ ...options.validate !== void 0 ? { validate: options.validate } : {},
1155
+ policy
1156
+ });
1157
+ this.dispatchBufferedUpdates();
1158
+ }
1159
+ setDefaultUpdateHandler(first, second) {
1160
+ const handler = typeof first === "function" ? first : second;
1161
+ const options = (typeof first === "function" ? second : first) ?? {};
1162
+ if (typeof handler !== "function" || typeof options !== "object")
1163
+ throw new TypeError("ctx.setDefaultUpdateHandler needs a handler function");
1164
+ if (options.validate !== void 0 && typeof options.validate !== "function")
1165
+ throw new TypeError("validate must be a function");
1166
+ this.defaultUpdateHandler = {
1167
+ handler,
1168
+ ...options.validate !== void 0 ? { validate: options.validate } : {},
1169
+ policy: checkPolicy(options.unfinishedPolicy)
1170
+ };
1171
+ this.dispatchBufferedUpdates();
1172
+ }
1173
+ dispatchBufferedUpdates() {
1174
+ const pending = this.bufferedUpdates;
1175
+ this.bufferedUpdates = [];
1176
+ for (const update of pending) {
1177
+ const entry = this.updateHandlerFor(update.name);
1178
+ if (entry) this.runUpdate(update, entry);
1179
+ else this.bufferedUpdates.push(update);
1180
+ }
1181
+ }
1182
+ handleQuery(query, handler) {
1183
+ const name = definitionName(query, "ctx.handleQuery");
1184
+ if (typeof handler !== "function")
1185
+ throw new TypeError("ctx.handleQuery needs a handler function");
1186
+ this.queryHandlers.set(name, handler);
1187
+ }
1188
+ setDefaultQueryHandler(handler) {
1189
+ if (typeof handler !== "function")
1190
+ throw new TypeError("ctx.setDefaultQueryHandler needs a handler function");
1191
+ this.defaultQueryHandler = handler;
1192
+ }
1193
+ /**
1194
+ * The drain check of 11 §2.18 when the workflow finishes: handlers still
1195
+ * running with policy `WARN_AND_ABANDON` give one warning line and
1196
+ * `unfinishedHandlers` in the result. A replay never reports them.
1197
+ */
1198
+ checkUnfinishedHandlers(command) {
1199
+ if (this.replaying || command.type === "CANCEL_WORKFLOW") return;
1200
+ const unfinished = [...this.running.values()].filter((entry) => entry.count > 0 && entry.policy === "WARN_AND_ABANDON").map(
1201
+ (entry) => ({ kind: entry.kind, name: entry.name, count: entry.count })
1202
+ ).sort(
1203
+ (a, b) => a.kind !== b.kind ? a.kind < b.kind ? -1 : 1 : a.name < b.name ? -1 : a.name > b.name ? 1 : 0
1204
+ );
1205
+ if (unfinished.length === 0) return;
1206
+ this.unfinished = unfinished;
1207
+ const total = unfinished.reduce((sum, entry) => sum + entry.count, 0);
1208
+ const what = unfinished.every((entry) => entry.kind === "signal") ? "signal handler" : unfinished.every((entry) => entry.kind === "update") ? "update handler" : "signal or update handler";
1209
+ this.logs.push({
1210
+ level: "warn",
1211
+ message: `The workflow finished while ${total} ${what}${total === 1 ? " was" : "s were"} still running (${unfinished.map((entry) => `${entry.name} x${entry.count}`).join(
1212
+ ", "
1213
+ )}); await ctx.allHandlersFinished() before returning, or set unfinishedPolicy: 'ABANDON' on the handler`,
1214
+ data: unfinished.map((entry) => ({ kind: entry.kind, name: entry.name, count: entry.count }))
1215
+ });
1216
+ }
1217
+ // ---- the workflow function ------------------------------------------------
1218
+ startFunction(input) {
1219
+ let promise;
1220
+ try {
1221
+ const run = (value) => (
1222
+ // The input crossed the history as JSON; the function declared its type.
1223
+ Promise.resolve(this.definition.fn(this.context, value))
1224
+ );
1225
+ promise = this.inbound.length === 0 ? run(input) : chunkVA4OFR72_cjs.compose(
1226
+ this.inbound,
1227
+ "execute",
1228
+ (execute) => run(execute.input)
1229
+ )({ workflowFn: this.request.workflowFn, input, headers: { ...this.startHeaders } });
1230
+ } catch (error) {
1231
+ promise = Promise.reject(error);
1232
+ }
1233
+ promise.then(
1234
+ (value) => this.onReturn(value),
1235
+ (error) => this.onWorkflowError(error)
1236
+ );
1237
+ }
1238
+ onReturn(value) {
1239
+ if (this.closed || this.failure) return;
1240
+ let output;
1241
+ try {
1242
+ output = toJson(value, "The workflow output");
1243
+ } catch (error) {
1244
+ if (error instanceof TypeError)
1245
+ this.failTask("WORKFLOW_CODE_ERROR", messageOf(error), stackTextOf(error));
1246
+ else this.onWorkflowError(error);
1247
+ return;
1248
+ }
1249
+ this.pushTerminal({ type: "COMPLETE_WORKFLOW", output });
1250
+ }
1251
+ isFailureType(error) {
1252
+ const listed = this.definition.options.failureErrorTypes ?? [];
1253
+ return listed.some((type) => error instanceof type);
1254
+ }
1255
+ /** What an error thrown out of workflow code does (11 §2.25, §2.37). */
1256
+ onWorkflowError(error) {
1257
+ if (this.closed || this.failure) return;
1258
+ if (error instanceof ContinueAsNewRequest) {
1259
+ const command = {
1260
+ type: "CONTINUE_AS_NEW",
1261
+ input: error.input,
1262
+ options: error.options
1263
+ };
1264
+ if (Object.keys(error.headers).length > 0) command.headers = { ...error.headers };
1265
+ this.pushTerminal(command);
1266
+ return;
1267
+ }
1268
+ const name = errorName(error);
1269
+ if (error instanceof chunkZCGKGDCL_cjs.DeterminismViolation || name === "DeterminismViolation") {
1270
+ this.failTask("NON_DETERMINISM", messageOf(error), stackTextOf(error), void 0, name);
1271
+ return;
1272
+ }
1273
+ if (error instanceof chunkZCGKGDCL_cjs.HistoryLimitExceeded) {
1274
+ this.failTask("HISTORY_LIMIT", messageOf(error), stackTextOf(error));
1275
+ return;
1276
+ }
1277
+ if (name === "InternalError" && /out of memory/i.test(messageOf(error))) {
1278
+ this.failTask("ISOLATE_MEMORY", messageOf(error), stackTextOf(error), void 0, name);
1279
+ return;
1280
+ }
1281
+ if (error instanceof chunkZCGKGDCL_cjs.PhaseCFeatureError) {
1282
+ this.failTask("UNSUPPORTED_COMMAND", messageOf(error), stackTextOf(error));
1283
+ return;
1284
+ }
1285
+ if (error instanceof chunkZCGKGDCL_cjs.QueryHandlerSideEffect) {
1286
+ this.failTask("WORKFLOW_CODE_ERROR", messageOf(error), stackTextOf(error), void 0, name);
1287
+ return;
1288
+ }
1289
+ if (this.cancelRequested && chunkZCGKGDCL_cjs.isCancellation(error)) {
1290
+ this.pushTerminal({ type: "CANCEL_WORKFLOW" });
1291
+ return;
1292
+ }
1293
+ if (chunkZCGKGDCL_cjs.isRunFailure(error) || this.isFailureType(error)) {
1294
+ this.pushTerminal({ type: "FAIL_WORKFLOW", failure: chunkZCGKGDCL_cjs.errorToFailure(error) });
1295
+ return;
1296
+ }
1297
+ this.failTask(
1298
+ "WORKFLOW_CODE_ERROR",
1299
+ `${name || "Error"}: ${messageOf(error)}`,
1300
+ stackTextOf(error),
1301
+ void 0,
1302
+ name || void 0
1303
+ );
1304
+ }
1305
+ // ---- commands -------------------------------------------------------------
1306
+ currentScope() {
1307
+ return this.syncScopes[this.syncScopes.length - 1] ?? this.root;
1308
+ }
1309
+ /**
1310
+ * Throw `HistoryLimitExceeded` from 95 % of the cap. It runs on replay too:
1311
+ * the history length is the activation's cutoff and the command count is
1312
+ * the activation's own, so replay sees what the first execution saw.
1313
+ */
1314
+ checkLimit() {
1315
+ const events = this.historyLength + this.commands.length;
1316
+ if (events >= this.limitEvents * chunkTYF56RGB_cjs.HISTORY_LIMIT_EXCEEDED_RATIO || this.historyBytes >= this.limitBytes * chunkTYF56RGB_cjs.HISTORY_LIMIT_EXCEEDED_RATIO)
1317
+ throw new chunkZCGKGDCL_cjs.HistoryLimitExceeded(
1318
+ `The history has ${events} events and ${this.historyBytes} bytes, past 95 % of its limit (${this.limitEvents} events, ${this.limitBytes} bytes); continue as new`
1319
+ );
1320
+ }
1321
+ /** Issue a command; false when the run is already closed (the command is dropped). */
1322
+ push(command) {
1323
+ this.assertWritable(command.type);
1324
+ if (this.closed || this.failure) return false;
1325
+ this.checkLimit();
1326
+ this.commands.push(command);
1327
+ return true;
1328
+ }
1329
+ pushTerminal(command) {
1330
+ if (this.closed || this.failure) return;
1331
+ this.commands.push(command);
1332
+ this.closed = true;
1333
+ this.checkUnfinishedHandlers(command);
1334
+ }
1335
+ stack() {
1336
+ return this.captureStacks ? chunkQ4MWQNJK_cjs.captureStack() : void 0;
1337
+ }
1338
+ never() {
1339
+ return new Promise(() => void 0);
1340
+ }
1341
+ scheduleActivity(scope, operation, options) {
1342
+ if (typeof operation !== "object" || operation === null || typeof operation.nodeType !== "string")
1343
+ throw new TypeError("ctx.run needs a node operation (from nodes.* or the generated clients)");
1344
+ if (operation.role === "trigger" || !chunkA5SXCA62_cjs.isActivityNodeTypeAllowed(operation.nodeType))
1345
+ throw new chunkZCGKGDCL_cjs.ApplicationError(
1346
+ `${operation.nodeType} cannot run as a durable activity: only store and registry nodes and internal:http, internal:datatable, internal:set and internal:code can`,
1347
+ { type: "durable.activityTypeNotAllowed", errorType: "VALIDATION", nonRetryable: true }
1348
+ );
1349
+ const activityId = this.nextId("a");
1350
+ const operationName = options.operation ?? operation.operation ?? "execute";
1351
+ const nodeVersion = options.nodeVersion ?? operation.version;
1352
+ const cancellationType = options.cancellationType ?? "WAIT_CANCELLATION_COMPLETED";
1353
+ const command = {
1354
+ type: "SCHEDULE_ACTIVITY",
1355
+ activityId,
1356
+ kind: "node",
1357
+ nodeType: operation.nodeType,
1358
+ operation: operationName,
1359
+ args: toJson(options.args, `The args of ${operation.nodeType}`),
1360
+ retry: chunkTYF56RGB_cjs.explicitRetryPolicy(options.retry)
1361
+ };
1362
+ if (nodeVersion !== void 0) command.nodeVersion = nodeVersion;
1363
+ if (options.connection !== void 0) command.connection = options.connection;
1364
+ const startToClose = chunkVA4OFR72_cjs.optionalMs(options.startToCloseTimeout, "startToCloseTimeout");
1365
+ const scheduleToClose = chunkVA4OFR72_cjs.optionalMs(options.scheduleToCloseTimeout, "scheduleToCloseTimeout");
1366
+ const scheduleToStart = chunkVA4OFR72_cjs.optionalMs(options.scheduleToStartTimeout, "scheduleToStartTimeout");
1367
+ const heartbeat = chunkVA4OFR72_cjs.optionalMs(options.heartbeatTimeout, "heartbeatTimeout");
1368
+ if (startToClose !== void 0) command.startToCloseTimeout = startToClose;
1369
+ if (scheduleToClose !== void 0) command.scheduleToCloseTimeout = scheduleToClose;
1370
+ if (scheduleToStart !== void 0) command.scheduleToStartTimeout = scheduleToStart;
1371
+ if (heartbeat !== void 0) command.heartbeatTimeout = heartbeat;
1372
+ if (options.cancellationType !== void 0) command.cancellationType = options.cancellationType;
1373
+ if (options.priority !== void 0) command.priority = options.priority;
1374
+ if (options.summary !== void 0) command.summary = options.summary;
1375
+ if (options.runOn !== void 0) command.runOn = options.runOn;
1376
+ checkFairness(options);
1377
+ if (options.fairnessKey !== void 0) command.fairnessKey = options.fairnessKey;
1378
+ if (options.fairnessWeight !== void 0) command.fairnessWeight = options.fairnessWeight;
1379
+ return this.issueActivity(
1380
+ scope,
1381
+ command,
1382
+ options.headers,
1383
+ {
1384
+ description: `activity ${activityId} (${operation.nodeType} ${operationName})`,
1385
+ nodeType: operation.nodeType,
1386
+ operation: operationName,
1387
+ cancellationType
1388
+ },
1389
+ { kind: "node", name: operation.nodeType, operation: operationName }
1390
+ );
1391
+ }
1392
+ /**
1393
+ * `ctx.activity` (Phase C): a user activity on a self-hosted task queue
1394
+ * (`SCHEDULE_ACTIVITY` of kind `user`). The queue is the option, else the
1395
+ * declaration's, else the run's own.
1396
+ */
1397
+ userActivity(scope, activity, options) {
1398
+ if (typeof options !== "object" || options === null)
1399
+ throw new TypeError("ctx.activity needs options with args");
1400
+ let name;
1401
+ let declaredQueue;
1402
+ if (typeof activity === "string") name = activity;
1403
+ else if (chunkVA4OFR72_cjs.isActivityDefinition(activity)) {
1404
+ name = activity.name;
1405
+ declaredQueue = activity.options.taskQueue;
1406
+ } else throw new TypeError("ctx.activity needs an activity name or a declareActivity() value");
1407
+ chunkVA4OFR72_cjs.checkActivityName(name);
1408
+ const taskQueue = options.taskQueue ?? declaredQueue ?? this.info.taskQueue ?? "managed";
1409
+ chunkVA4OFR72_cjs.checkTaskQueueName(taskQueue);
1410
+ const connections = options.connections;
1411
+ if (connections !== void 0 && (!Array.isArray(connections) || connections.length > chunkTYF56RGB_cjs.MAX_ACTIVITY_CONNECTIONS || new Set(connections).size !== connections.length || !connections.every((entry) => typeof entry === "string" && entry !== "")))
1412
+ throw new TypeError(
1413
+ `connections must be at most ${chunkTYF56RGB_cjs.MAX_ACTIVITY_CONNECTIONS} distinct connection names`
1414
+ );
1415
+ checkFairness(options);
1416
+ const activityId = this.nextId("a");
1417
+ const cancellationType = options.cancellationType ?? "WAIT_CANCELLATION_COMPLETED";
1418
+ const command = {
1419
+ type: "SCHEDULE_ACTIVITY",
1420
+ activityId,
1421
+ kind: "user",
1422
+ activityName: name,
1423
+ taskQueue,
1424
+ args: toJson(options.args, `The args of activity ${name}`),
1425
+ retry: chunkTYF56RGB_cjs.explicitRetryPolicy(options.retry)
1426
+ };
1427
+ const startToClose = chunkVA4OFR72_cjs.optionalMs(options.startToCloseTimeout, "startToCloseTimeout");
1428
+ const scheduleToClose = chunkVA4OFR72_cjs.optionalMs(options.scheduleToCloseTimeout, "scheduleToCloseTimeout");
1429
+ const scheduleToStart = chunkVA4OFR72_cjs.optionalMs(options.scheduleToStartTimeout, "scheduleToStartTimeout");
1430
+ const heartbeat = chunkVA4OFR72_cjs.optionalMs(options.heartbeatTimeout, "heartbeatTimeout");
1431
+ if (startToClose !== void 0) command.startToCloseTimeout = startToClose;
1432
+ if (scheduleToClose !== void 0) command.scheduleToCloseTimeout = scheduleToClose;
1433
+ if (scheduleToStart !== void 0) command.scheduleToStartTimeout = scheduleToStart;
1434
+ if (heartbeat !== void 0) command.heartbeatTimeout = heartbeat;
1435
+ if (options.cancellationType !== void 0) command.cancellationType = options.cancellationType;
1436
+ if (options.priority !== void 0) command.priority = options.priority;
1437
+ if (options.summary !== void 0) command.summary = options.summary;
1438
+ if (options.fairnessKey !== void 0) command.fairnessKey = options.fairnessKey;
1439
+ if (options.fairnessWeight !== void 0) command.fairnessWeight = options.fairnessWeight;
1440
+ if (connections !== void 0) command.connections = [...connections];
1441
+ return this.issueActivity(
1442
+ scope,
1443
+ command,
1444
+ options.headers,
1445
+ {
1446
+ description: `activity ${activityId} (user ${name})`,
1447
+ nodeType: "",
1448
+ operation: name,
1449
+ activityName: name,
1450
+ cancellationType
1451
+ },
1452
+ { kind: "user", name }
1453
+ );
1454
+ }
1455
+ /** Run the outbound `scheduleActivity` interceptors, then issue the command. */
1456
+ issueActivity(scope, command, headers, pending, what) {
1457
+ if (this.outbound.length === 0) {
1458
+ if (headers !== void 0) command.headers = { ...headers };
1459
+ return this.pushActivity(scope, command, pending);
1460
+ }
1461
+ const chain = chunkVA4OFR72_cjs.compose(
1462
+ this.outbound,
1463
+ "scheduleActivity",
1464
+ (input) => {
1465
+ command.args = toJson(input.args, `The args of ${what.name}`);
1466
+ if (headers !== void 0 || Object.keys(input.headers).length > 0)
1467
+ command.headers = { ...input.headers };
1468
+ return this.pushActivity(scope, command, pending);
1469
+ }
1470
+ );
1471
+ return chain({
1472
+ activityId: command.activityId,
1473
+ kind: what.kind,
1474
+ name: what.name,
1475
+ ...what.operation !== void 0 ? { operation: what.operation } : {},
1476
+ args: command.args,
1477
+ headers: { ...headers ?? {} }
1478
+ });
1479
+ }
1480
+ pushActivity(scope, command, pending) {
1481
+ const activityId = command.activityId;
1482
+ const cancellationType = pending.cancellationType;
1483
+ if (scope.consideredCancelled)
1484
+ return Promise.reject(new chunkZCGKGDCL_cjs.CancelledFailure("Scope is cancelled"));
1485
+ if (!this.push(command)) return this.never();
1486
+ this.issued.add(`activity:${activityId}`);
1487
+ return new Promise((resolve, reject) => {
1488
+ const entry = { ...pending, resolve, reject };
1489
+ const stack = this.stack();
1490
+ if (stack !== void 0) entry.stack = stack;
1491
+ entry.release = scope.onCancel(() => {
1492
+ if (!this.activities.has(activityId)) return;
1493
+ const cancelled = new chunkZCGKGDCL_cjs.ActivityFailure(
1494
+ `Activity ${activityId} cancelled`,
1495
+ activityId,
1496
+ entry.nodeType,
1497
+ entry.operation,
1498
+ new chunkZCGKGDCL_cjs.CancelledFailure("Activity cancelled"),
1499
+ entry.activityName
1500
+ );
1501
+ if (cancellationType !== "ABANDON")
1502
+ this.push({ type: "REQUEST_CANCEL_ACTIVITY", activityId });
1503
+ if (cancellationType !== "WAIT_CANCELLATION_COMPLETED") {
1504
+ this.activities.delete(activityId);
1505
+ reject(cancelled);
1506
+ }
1507
+ });
1508
+ this.activities.set(activityId, entry);
1509
+ });
1510
+ }
1511
+ /**
1512
+ * `ctx.localActivity` (11 §2.12). A replayed activation returns the outcome
1513
+ * its history recorded; the open activation takes the outcome the worker
1514
+ * passed in `localActivityResults`, or asks for the local activity
1515
+ * (`localActivityRequested`) and waits for the same task to run again.
1516
+ * Either way the outcome is recorded with `RECORD_LOCAL_ACTIVITY` at the
1517
+ * call, so a replay issues the same command at the same position.
1518
+ */
1519
+ localActivity(scope, operation, options) {
1520
+ if (typeof operation === "function")
1521
+ throw new chunkZCGKGDCL_cjs.PhaseCFeatureError("ctx.localActivity with a function (user local activities)");
1522
+ if (typeof operation !== "object" || operation === null || typeof operation.nodeType !== "string")
1523
+ throw new TypeError(
1524
+ "ctx.localActivity needs a node operation (from nodes.* or the generated clients)"
1525
+ );
1526
+ const descriptor = operation;
1527
+ if (descriptor.role === "trigger" || !chunkA5SXCA62_cjs.isActivityNodeTypeAllowed(descriptor.nodeType))
1528
+ throw new chunkZCGKGDCL_cjs.ApplicationError(
1529
+ `${descriptor.nodeType} cannot run as a durable activity: only store and registry nodes and internal:http, internal:datatable, internal:set and internal:code can`,
1530
+ { type: "durable.activityTypeNotAllowed", errorType: "VALIDATION", nonRetryable: true }
1531
+ );
1532
+ if (typeof options !== "object" || options === null)
1533
+ throw new TypeError("ctx.localActivity needs options with args");
1534
+ const timeout = options.startToCloseTimeout === void 0 ? chunkTYF56RGB_cjs.LOCAL_ACTIVITY_MAX_TIMEOUT_MS : chunkVA4OFR72_cjs.toMs(options.startToCloseTimeout, "startToCloseTimeout");
1535
+ if (timeout < 1 || timeout > chunkTYF56RGB_cjs.LOCAL_ACTIVITY_MAX_TIMEOUT_MS)
1536
+ throw new TypeError(
1537
+ `A local activity's startToCloseTimeout must be between 1 ms and 30 s (got ${timeout} ms); use ctx.run for longer calls`
1538
+ );
1539
+ const localActivityId = this.nextId("l");
1540
+ const operationName = options.operation ?? descriptor.operation ?? "execute";
1541
+ const nodeVersion = options.nodeVersion ?? descriptor.version;
1542
+ const retry = chunkTYF56RGB_cjs.explicitRetryPolicy(options.retry);
1543
+ const args = toJson(options.args, `The args of ${descriptor.nodeType}`);
1544
+ const proceed = (args2) => {
1545
+ if (scope.consideredCancelled)
1546
+ return Promise.reject(new chunkZCGKGDCL_cjs.CancelledFailure("Scope is cancelled"));
1547
+ const label = `local activity ${localActivityId} (${descriptor.nodeType} ${operationName})`;
1548
+ const wrap = (cause) => new chunkZCGKGDCL_cjs.ActivityFailure(
1549
+ `Local activity ${localActivityId} (${descriptor.nodeType} ${operationName}) failed: ${cause.message}`,
1550
+ localActivityId,
1551
+ descriptor.nodeType,
1552
+ operationName,
1553
+ cause
1554
+ );
1555
+ const record = (outcome) => {
1556
+ const command = {
1557
+ type: "RECORD_LOCAL_ACTIVITY",
1558
+ localActivityId,
1559
+ attempts: Math.max(1, Math.round(outcome.attempts)),
1560
+ nodeType: descriptor.nodeType,
1561
+ operation: operationName,
1562
+ ...outcome.failure !== void 0 ? { failure: outcome.failure } : { result: outcome.result ?? null }
1563
+ };
1564
+ if (options.summary !== void 0) command.summary = options.summary;
1565
+ if (!this.push(command)) return this.never();
1566
+ if (outcome.failure !== void 0)
1567
+ return Promise.reject(wrap(chunkZCGKGDCL_cjs.failureToError(outcome.failure)));
1568
+ return Promise.resolve(outcome.result ?? null);
1569
+ };
1570
+ const replayed = this.replaying;
1571
+ if (replayed) {
1572
+ const recorded = this.recordedLocalActivities.get(localActivityId);
1573
+ if (recorded !== void 0) return record(recorded);
1574
+ }
1575
+ const given = replayed ? void 0 : this.localActivityResults.get(localActivityId);
1576
+ let attempt = 1;
1577
+ let backoffMs = 0;
1578
+ if (given !== void 0) {
1579
+ if (given.failure === void 0) return record(given);
1580
+ const decision = chunkTYF56RGB_cjs.computeRetryDelay(retry, given.attempts, given.failure);
1581
+ if (!decision.retry) return record(given);
1582
+ attempt = given.attempts + 1;
1583
+ backoffMs = decision.delayMs;
1584
+ }
1585
+ const request = {
1586
+ localActivityId,
1587
+ kind: "node",
1588
+ nodeType: descriptor.nodeType,
1589
+ operation: operationName,
1590
+ args: args2,
1591
+ retry,
1592
+ startToCloseTimeout: timeout,
1593
+ attempt,
1594
+ backoffMs
1595
+ };
1596
+ if (nodeVersion !== void 0) request.nodeVersion = nodeVersion;
1597
+ if (options.connection !== void 0) request.connection = options.connection;
1598
+ if (options.summary !== void 0) request.summary = options.summary;
1599
+ return new Promise((resolve, reject) => {
1600
+ const entry = {
1601
+ resolve,
1602
+ reject,
1603
+ description: label,
1604
+ request,
1605
+ replayed
1606
+ };
1607
+ const stack = this.stack();
1608
+ if (stack !== void 0) entry.stack = stack;
1609
+ entry.release = scope.onCancel(() => {
1610
+ if (!this.localActivities.delete(localActivityId)) return;
1611
+ reject(wrap(new chunkZCGKGDCL_cjs.CancelledFailure("Local activity cancelled")));
1612
+ });
1613
+ this.localActivities.set(localActivityId, entry);
1614
+ });
1615
+ };
1616
+ if (this.outbound.length === 0) return proceed(args);
1617
+ const chain = chunkVA4OFR72_cjs.compose(
1618
+ this.outbound,
1619
+ "scheduleLocalActivity",
1620
+ (input) => proceed(toJson(input.args, `The args of ${descriptor.nodeType}`))
1621
+ );
1622
+ return chain({
1623
+ localActivityId,
1624
+ nodeType: descriptor.nodeType,
1625
+ operation: operationName,
1626
+ args
1627
+ });
1628
+ }
1629
+ startTimer(scope, durationMs, summary) {
1630
+ return this.timer(scope, durationMs, summary).promise;
1631
+ }
1632
+ /** Start a durable timer; `timerId` is undefined when no timer was needed or issued. */
1633
+ timer(scope, durationMs, summary) {
1634
+ if (durationMs <= 0) return { promise: Promise.resolve() };
1635
+ if (scope.consideredCancelled)
1636
+ return { promise: Promise.reject(new chunkZCGKGDCL_cjs.CancelledFailure("Scope is cancelled")) };
1637
+ const timerId = this.nextId("t");
1638
+ const command = {
1639
+ type: "START_TIMER",
1640
+ timerId,
1641
+ durationMs: Math.max(1, Math.round(durationMs))
1642
+ };
1643
+ if (summary !== void 0) command.summary = summary;
1644
+ if (!this.push(command)) return { promise: this.never() };
1645
+ this.issued.add(`timer:${timerId}`);
1646
+ const promise = new Promise((resolve, reject) => {
1647
+ const entry = {
1648
+ resolve,
1649
+ reject,
1650
+ description: `timer ${timerId} (${durationMs} ms)`
1651
+ };
1652
+ const stack = this.stack();
1653
+ if (stack !== void 0) entry.stack = stack;
1654
+ entry.release = scope.onCancel(() => {
1655
+ if (!this.timers.has(timerId)) return;
1656
+ this.timers.delete(timerId);
1657
+ this.push({ type: "CANCEL_TIMER", timerId });
1658
+ reject(new chunkZCGKGDCL_cjs.CancelledFailure("Timer cancelled"));
1659
+ });
1660
+ this.timers.set(timerId, entry);
1661
+ });
1662
+ return { promise, timerId };
1663
+ }
1664
+ /** Cancel a pending timer the runtime started for itself (condition and scope timeouts). */
1665
+ cancelOwnTimer(timerId) {
1666
+ if (timerId === void 0) return;
1667
+ const pending = this.timers.get(timerId);
1668
+ if (!pending) return;
1669
+ this.timers.delete(timerId);
1670
+ pending.release?.();
1671
+ this.push({ type: "CANCEL_TIMER", timerId });
1672
+ }
1673
+ condition(scope, predicate, timeout) {
1674
+ if (predicate()) return Promise.resolve(true);
1675
+ if (scope.consideredCancelled)
1676
+ return Promise.reject(new chunkZCGKGDCL_cjs.CancelledFailure("Scope is cancelled"));
1677
+ return new Promise((resolve, reject) => {
1678
+ const condition = { predicate, resolve, reject };
1679
+ const stack = this.stack();
1680
+ if (stack !== void 0) condition.stack = stack;
1681
+ this.conditions.push(condition);
1682
+ if (timeout !== void 0) {
1683
+ const timer = this.timer(scope, chunkVA4OFR72_cjs.toMs(timeout, "condition timeout"), void 0);
1684
+ if (timer.timerId !== void 0) condition.timerId = timer.timerId;
1685
+ timer.promise.then(
1686
+ () => {
1687
+ if (!this.conditions.includes(condition)) return;
1688
+ this.conditions = this.conditions.filter((entry) => entry !== condition);
1689
+ condition.release?.();
1690
+ resolve(false);
1691
+ },
1692
+ () => void 0
1693
+ );
1694
+ }
1695
+ condition.release = scope.onCancel(() => {
1696
+ if (!this.conditions.includes(condition)) return;
1697
+ this.conditions = this.conditions.filter((entry) => entry !== condition);
1698
+ this.cancelOwnTimer(condition.timerId);
1699
+ reject(new chunkZCGKGDCL_cjs.CancelledFailure("Condition cancelled"));
1700
+ });
1701
+ });
1702
+ }
1703
+ /** Resolve conditions whose predicate now holds; true when any did. */
1704
+ checkConditions() {
1705
+ let fired = false;
1706
+ for (const condition of [...this.conditions]) {
1707
+ let holds = false;
1708
+ try {
1709
+ holds = condition.predicate();
1710
+ } catch (error) {
1711
+ this.conditions = this.conditions.filter((entry) => entry !== condition);
1712
+ condition.release?.();
1713
+ condition.reject(error);
1714
+ fired = true;
1715
+ continue;
1716
+ }
1717
+ if (!holds) continue;
1718
+ this.conditions = this.conditions.filter((entry) => entry !== condition);
1719
+ condition.release?.();
1720
+ this.cancelOwnTimer(condition.timerId);
1721
+ condition.resolve(true);
1722
+ fired = true;
1723
+ }
1724
+ return fired;
1725
+ }
1726
+ signalReceived(scope, signal) {
1727
+ const name = chunkZCGKGDCL_cjs.signalName(signal);
1728
+ const buffered = this.takeBuffered(name);
1729
+ if (buffered !== void 0) return Promise.resolve(buffered);
1730
+ return new Promise((resolve, reject) => {
1731
+ const entry = {
1732
+ resolve,
1733
+ reject,
1734
+ description: `signal ${name}`
1735
+ };
1736
+ const stack = this.stack();
1737
+ if (stack !== void 0) entry.stack = stack;
1738
+ const waiters = this.signalWaiters.get(name) ?? [];
1739
+ waiters.push(entry);
1740
+ this.signalWaiters.set(name, waiters);
1741
+ entry.release = scope.onCancel(() => {
1742
+ const list = this.signalWaiters.get(name) ?? [];
1743
+ const position = list.indexOf(entry);
1744
+ if (position < 0) return;
1745
+ list.splice(position, 1);
1746
+ reject(new chunkZCGKGDCL_cjs.CancelledFailure("Signal wait cancelled"));
1747
+ });
1748
+ });
1749
+ }
1750
+ onSignal(signal, handler, options = {}) {
1751
+ if (typeof handler !== "function") throw new TypeError("ctx.onSignal needs a handler function");
1752
+ const policy = checkPolicy(options.unfinishedPolicy);
1753
+ const name = chunkZCGKGDCL_cjs.signalName(signal);
1754
+ this.signalHandlers.set(name, handler);
1755
+ this.signalPolicies.set(name, policy);
1756
+ let payload = this.takeBuffered(name);
1757
+ while (payload !== void 0) {
1758
+ const value = payload;
1759
+ this.runHandler(() => handler(value), name, policy);
1760
+ payload = this.takeBuffered(name);
1761
+ }
1762
+ }
1763
+ setDefaultSignalHandler(handler) {
1764
+ this.defaultSignalHandler = handler;
1765
+ const buffered = [...this.signalOrder];
1766
+ for (const entry of buffered) {
1767
+ if (this.signalHandlers.has(entry.name)) continue;
1768
+ const payload = this.takeBuffered(entry.name);
1769
+ if (payload !== void 0)
1770
+ this.runHandler(() => handler(entry.name, payload), entry.name, this.defaultSignalPolicy);
1771
+ }
1772
+ }
1773
+ /** The command target of a run handle (11 §2.1, §2.24). */
1774
+ externalTarget(target) {
1775
+ if (typeof target === "string") {
1776
+ if (target === "") throw new TypeError("A run handle needs a run id");
1777
+ return { runId: target };
1778
+ }
1779
+ if (typeof target === "object" && target !== null) {
1780
+ if ("runId" in target && typeof target.runId === "string" && target.runId !== "")
1781
+ return { runId: target.runId };
1782
+ if ("workflowKey" in target && typeof target.workflowKey === "string" && target.workflowKey !== "" && typeof target.workflowId === "string" && target.workflowId !== "") {
1783
+ const out = { workflowKey: target.workflowKey, workflowId: target.workflowId };
1784
+ if (typeof target.firstRunId === "string" && target.firstRunId !== "")
1785
+ out.firstRunId = target.firstRunId;
1786
+ return out;
1787
+ }
1788
+ }
1789
+ throw new TypeError("A run handle needs a run id or { workflowKey, workflowId }");
1790
+ }
1791
+ runHandle(target) {
1792
+ const resolved = this.externalTarget(target);
1793
+ return {
1794
+ runId: "runId" in resolved ? resolved.runId : "",
1795
+ ..."workflowId" in resolved ? { workflowKey: resolved.workflowKey, workflowId: resolved.workflowId } : {},
1796
+ signal: (signal, payload) => this.signalExternal(resolved, chunkZCGKGDCL_cjs.signalName(signal), payload),
1797
+ cancel: () => this.cancelExternal(resolved)
1798
+ };
1799
+ }
1800
+ childTarget(target) {
1801
+ if (typeof target === "string") {
1802
+ if (target === "") throw new TypeError("ctx.child needs a workflow key or function");
1803
+ return { workflowKey: target };
1804
+ }
1805
+ if (chunkVA4OFR72_cjs.isDurableWorkflow(target)) {
1806
+ const exportName = this.exportNames.get(target);
1807
+ if (exportName === void 0)
1808
+ throw new TypeError(
1809
+ `workflow("${target.name}") is not exported by any module of this bundle; export it to start it as a child (in the test environment, pass it in \`workflows\`)`
1810
+ );
1811
+ return { workflowFn: exportName };
1812
+ }
1813
+ throw new TypeError("ctx.child needs a workflow key or a workflow() function");
1814
+ }
1815
+ childCommand(childId, target, options, defaultPolicy) {
1816
+ const opts = { parentClosePolicy: options.parentClosePolicy ?? defaultPolicy };
1817
+ if (options.cancellationType !== void 0) opts["cancellationType"] = options.cancellationType;
1818
+ if (options.taskQueue !== void 0) opts["taskQueue"] = options.taskQueue;
1819
+ if (options.workflowId !== void 0) opts["workflowId"] = options.workflowId;
1820
+ if (options.priority !== void 0) opts["priority"] = options.priority;
1821
+ if (options.summary !== void 0) opts["summary"] = options.summary;
1822
+ if (options.details !== void 0) opts["details"] = options.details;
1823
+ if (options.context !== void 0)
1824
+ opts["context"] = toJson(options.context, "The child context");
1825
+ if (options.retry !== void 0)
1826
+ opts["retry"] = toJson(chunkVA4OFR72_cjs.runRetryPolicyOf(options.retry), "The child retry policy");
1827
+ if (options.versioningBehavior !== void 0)
1828
+ opts["versioningBehavior"] = options.versioningBehavior;
1829
+ if (options.idReusePolicy !== void 0) opts["idReusePolicy"] = options.idReusePolicy;
1830
+ if (options.idConflictPolicy !== void 0) opts["idConflictPolicy"] = options.idConflictPolicy;
1831
+ const durations = [
1832
+ ["startDelay", "startDelay"],
1833
+ ["executionTimeout", "executionTimeout"],
1834
+ ["runTimeout", "runTimeout"],
1835
+ ["workflowTaskTimeout", "workflowTaskTimeout"]
1836
+ ];
1837
+ for (const [key, name] of durations) {
1838
+ const value = options[key];
1839
+ if (value !== void 0 && (typeof value === "number" || typeof value === "string"))
1840
+ opts[name] = chunkVA4OFR72_cjs.toMs(value, name);
1841
+ }
1842
+ const command = {
1843
+ type: "START_CHILD_RUN",
1844
+ childId,
1845
+ ...this.childTarget(target),
1846
+ input: toJson(options.input, "The child input"),
1847
+ options: {
1848
+ parentClosePolicy: opts["parentClosePolicy"] === "ABANDON" ? "ABANDON" : opts["parentClosePolicy"] === "REQUEST_CANCEL" ? "REQUEST_CANCEL" : "TERMINATE",
1849
+ ...opts
1850
+ }
1851
+ };
1852
+ checkFairness(options);
1853
+ if (options.fairnessKey !== void 0) command.options.fairnessKey = options.fairnessKey;
1854
+ if (options.fairnessWeight !== void 0)
1855
+ command.options.fairnessWeight = options.fairnessWeight;
1856
+ if (options.version !== void 0) command.version = options.version;
1857
+ if (options.headers !== void 0) command.headers = { ...options.headers };
1858
+ return command;
1859
+ }
1860
+ /**
1861
+ * Run the outbound `startChild` interceptors around a child start. `go`
1862
+ * starts the child with the options the interceptors leave (input and
1863
+ * headers).
1864
+ */
1865
+ interceptChild(target, options, go) {
1866
+ if (this.outbound.length === 0) return go(options);
1867
+ const chain = chunkVA4OFR72_cjs.compose(
1868
+ this.outbound,
1869
+ "startChild",
1870
+ (input) => go({
1871
+ ...options,
1872
+ input: input.input,
1873
+ ...options.headers !== void 0 || Object.keys(input.headers).length > 0 ? { headers: { ...input.headers } } : {}
1874
+ })
1875
+ );
1876
+ return chain({
1877
+ ...this.childTarget(target),
1878
+ input: toJson(options.input, "The child input"),
1879
+ headers: { ...options.headers ?? {} }
1880
+ });
1881
+ }
1882
+ startChildRun(scope, target, options, defaultPolicy) {
1883
+ if (scope.consideredCancelled) return void 0;
1884
+ const childId = this.nextId("c");
1885
+ const command = this.childCommand(childId, target, options, defaultPolicy);
1886
+ if (!this.push(command)) return void 0;
1887
+ this.issued.add(`child:${childId}`);
1888
+ const child = { childId, settled: false, scope };
1889
+ if (options.cancellationType !== void 0) child.cancellationType = options.cancellationType;
1890
+ this.children.set(childId, child);
1891
+ return child;
1892
+ }
1893
+ /** What cancelling the scope of a child's awaitable does (see `ChildOptions.cancellationType`). */
1894
+ onChildCancel(child, entry) {
1895
+ return () => {
1896
+ if (child.settled) return;
1897
+ const type = child.cancellationType ?? chunkISOIA7NV_cjs.CHILD_DEFAULT_CANCELLATION_TYPE;
1898
+ const error = new chunkZCGKGDCL_cjs.ChildRunFailure(
1899
+ `Child run ${child.childId} cancelled`,
1900
+ child.childId,
1901
+ child.runId,
1902
+ new chunkZCGKGDCL_cjs.CancelledFailure("Child run cancelled")
1903
+ );
1904
+ if (type === "ABANDON") {
1905
+ child.result = void 0;
1906
+ entry.reject(error);
1907
+ return;
1908
+ }
1909
+ const externalId = this.nextId("x");
1910
+ if (this.push({
1911
+ type: "REQUEST_CANCEL_EXTERNAL_RUN",
1912
+ externalId,
1913
+ target: { childId: child.childId }
1914
+ })) {
1915
+ this.issued.add(`external:${externalId}`);
1916
+ if (type === "WAIT_CANCELLATION_REQUESTED") {
1917
+ this.externals.set(externalId, {
1918
+ resolve: () => {
1919
+ child.result = void 0;
1920
+ entry.reject(error);
1921
+ },
1922
+ reject: () => {
1923
+ child.result = void 0;
1924
+ entry.reject(error);
1925
+ },
1926
+ description: `cancel of child ${child.childId}`
1927
+ });
1928
+ } else {
1929
+ this.externals.set(externalId, {
1930
+ resolve: () => void 0,
1931
+ reject: () => void 0,
1932
+ description: `cancel of child ${child.childId}`
1933
+ });
1934
+ }
1935
+ }
1936
+ if (type === "TRY_CANCEL") {
1937
+ child.result = void 0;
1938
+ entry.reject(error);
1939
+ }
1940
+ };
1941
+ }
1942
+ child(scope, target, options) {
1943
+ return this.interceptChild(target, options, (opts) => {
1944
+ const child = this.startChildRun(
1945
+ scope,
1946
+ target,
1947
+ opts,
1948
+ chunkISOIA7NV_cjs.CHILD_DEFAULT_PARENT_CLOSE_POLICY.child
1949
+ );
1950
+ if (!child)
1951
+ return scope.consideredCancelled ? Promise.reject(new chunkZCGKGDCL_cjs.CancelledFailure("Scope is cancelled")) : this.never();
1952
+ return this.childResult(child);
1953
+ });
1954
+ }
1955
+ childResult(child) {
1956
+ if (child.settled && child.outcome) {
1957
+ const outcome = child.outcome;
1958
+ return outcome.ok ? Promise.resolve(outcome.value) : Promise.reject(outcome.error);
1959
+ }
1960
+ return new Promise((resolve, reject) => {
1961
+ const entry = {
1962
+ resolve,
1963
+ reject,
1964
+ description: `child run ${child.childId}`
1965
+ };
1966
+ const stack = this.stack();
1967
+ if (stack !== void 0) entry.stack = stack;
1968
+ entry.release = child.scope.onCancel(this.onChildCancel(child, entry));
1969
+ child.result = entry;
1970
+ });
1971
+ }
1972
+ startChild(scope, target, options) {
1973
+ return this.interceptChild(
1974
+ target,
1975
+ options,
1976
+ (opts) => this.startChildHandle(scope, target, opts)
1977
+ );
1978
+ }
1979
+ startChildHandle(scope, target, options) {
1980
+ const child = this.startChildRun(
1981
+ scope,
1982
+ target,
1983
+ options,
1984
+ chunkISOIA7NV_cjs.CHILD_DEFAULT_PARENT_CLOSE_POLICY.startChild
1985
+ );
1986
+ if (!child)
1987
+ return scope.consideredCancelled ? Promise.reject(new chunkZCGKGDCL_cjs.CancelledFailure("Scope is cancelled")) : this.never();
1988
+ return new Promise((resolve, reject) => {
1989
+ const entry = {
1990
+ resolve,
1991
+ reject,
1992
+ description: `start of child run ${child.childId}`
1993
+ };
1994
+ const stack = this.stack();
1995
+ if (stack !== void 0) entry.stack = stack;
1996
+ child.started = entry;
1997
+ }).then((runId) => {
1998
+ const handle = {
1999
+ childId: child.childId,
2000
+ runId: runId ?? child.runId ?? "",
2001
+ result: () => this.childResult(child),
2002
+ signal: (signal, payload) => this.signalExternal({ childId: child.childId }, chunkZCGKGDCL_cjs.signalName(signal), payload),
2003
+ cancel: () => this.cancelExternal({ childId: child.childId })
2004
+ };
2005
+ return handle;
2006
+ });
2007
+ }
2008
+ signalExternal(target, name, payload) {
2009
+ if (this.outbound.length === 0) return this.pushSignal(target, name, payload, void 0);
2010
+ const chain = chunkVA4OFR72_cjs.compose(
2011
+ this.outbound,
2012
+ "signalRun",
2013
+ (input) => this.pushSignal(input.target, input.name, input.payload, input.headers)
2014
+ );
2015
+ return chain({
2016
+ target,
2017
+ name,
2018
+ payload: toJson(payload, `The payload of signal ${name}`),
2019
+ headers: {}
2020
+ });
2021
+ }
2022
+ pushSignal(target, name, payload, headers) {
2023
+ const externalId = this.nextId("x");
2024
+ const command = {
2025
+ type: "SIGNAL_RUN",
2026
+ externalId,
2027
+ target,
2028
+ name,
2029
+ payload: toJson(payload, `The payload of signal ${name}`)
2030
+ };
2031
+ if (headers !== void 0 && Object.keys(headers).length > 0) command.headers = { ...headers };
2032
+ if (!this.push(command)) return this.never();
2033
+ this.issued.add(`external:${externalId}`);
2034
+ return new Promise((resolve, reject) => {
2035
+ const entry = {
2036
+ resolve,
2037
+ reject,
2038
+ description: `signal ${name}`
2039
+ };
2040
+ const stack = this.stack();
2041
+ if (stack !== void 0) entry.stack = stack;
2042
+ this.externals.set(externalId, entry);
2043
+ });
2044
+ }
2045
+ cancelExternal(target) {
2046
+ if (this.outbound.length === 0) return this.pushCancel(target);
2047
+ return chunkVA4OFR72_cjs.compose(
2048
+ this.outbound,
2049
+ "cancelRun",
2050
+ (input) => this.pushCancel(input.target)
2051
+ )({ target });
2052
+ }
2053
+ pushCancel(target) {
2054
+ const externalId = this.nextId("x");
2055
+ if (!this.push({ type: "REQUEST_CANCEL_EXTERNAL_RUN", externalId, target }))
2056
+ return this.never();
2057
+ this.issued.add(`external:${externalId}`);
2058
+ return new Promise((resolve, reject) => {
2059
+ const entry = {
2060
+ resolve,
2061
+ reject,
2062
+ description: `cancel request ${externalId}`
2063
+ };
2064
+ const stack = this.stack();
2065
+ if (stack !== void 0) entry.stack = stack;
2066
+ this.externals.set(externalId, entry);
2067
+ });
2068
+ }
2069
+ sideEffect(fn) {
2070
+ if (this.outbound.length === 0) return this.recordSideEffect(fn);
2071
+ return chunkVA4OFR72_cjs.compose(
2072
+ this.outbound,
2073
+ "sideEffect",
2074
+ () => this.recordSideEffect(fn)
2075
+ )({});
2076
+ }
2077
+ recordSideEffect(fn) {
2078
+ const sideEffectId = this.nextId("s");
2079
+ let value;
2080
+ if (this.replaying && this.recordedSideEffects.has(sideEffectId)) {
2081
+ value = this.recordedSideEffects.get(sideEffectId) ?? null;
2082
+ } else {
2083
+ value = toJson(fn(), "The side effect value");
2084
+ }
2085
+ this.push({ type: "RECORD_SIDE_EFFECT", sideEffectId, value });
2086
+ return toJson(value, "The side effect value");
2087
+ }
2088
+ patched(patchId, deprecated) {
2089
+ if (typeof patchId !== "string" || patchId === "") throw new TypeError("A patch needs an id");
2090
+ const known = this.patches.get(patchId);
2091
+ if (known !== void 0) return known;
2092
+ this.assertWritable(deprecated ? "ctx.deprecatePatch()" : "ctx.patched()");
2093
+ const markerId = patchMarkerId(patchId);
2094
+ let result;
2095
+ if (this.replaying) {
2096
+ result = this.recordedMarkers.has(markerId);
2097
+ if (result)
2098
+ this.push({
2099
+ type: "RECORD_MARKER",
2100
+ markerId,
2101
+ data: { patchId, ...deprecated ? { deprecated: true } : {} }
2102
+ });
2103
+ } else {
2104
+ result = true;
2105
+ if (!this.recordedMarkers.has(markerId)) {
2106
+ this.push({
2107
+ type: "RECORD_MARKER",
2108
+ markerId,
2109
+ data: { patchId, ...deprecated ? { deprecated: true } : {} }
2110
+ });
2111
+ this.recordedMarkers.add(markerId);
2112
+ }
2113
+ }
2114
+ this.patches.set(patchId, result);
2115
+ return result;
2116
+ }
2117
+ setCurrentDetails(markdown) {
2118
+ if (typeof markdown !== "string") throw new TypeError("setCurrentDetails takes Markdown text");
2119
+ this.assertWritable("ctx.setCurrentDetails()");
2120
+ this.currentDetails = markdown;
2121
+ this.push({
2122
+ type: "RECORD_MARKER",
2123
+ markerId: this.nextId("m"),
2124
+ data: { currentDetails: markdown }
2125
+ });
2126
+ }
2127
+ upsertContext(entries) {
2128
+ const json = toJson(entries, "The context entries");
2129
+ if (!isJsonObject(json)) throw new TypeError("ctx.upsertContext takes an object");
2130
+ const apply = (input) => {
2131
+ const final = toJson(input.entries, "The context entries");
2132
+ if (!isJsonObject(final)) throw new TypeError("ctx.upsertContext takes an object");
2133
+ if (this.push({ type: "UPSERT_CONTEXT", entries: final }))
2134
+ this.memo = { ...this.memo, ...final };
2135
+ };
2136
+ if (this.outbound.length === 0) apply({ entries: json });
2137
+ else
2138
+ chunkVA4OFR72_cjs.compose(
2139
+ this.outbound,
2140
+ "upsertContext",
2141
+ apply
2142
+ )({ entries: json });
2143
+ }
2144
+ /** `ctx.upsertSearchAttributes` (Phase C): a null value removes an attribute. */
2145
+ upsertSearchAttributes(attributes) {
2146
+ const json = toJson(attributes, "The search attributes");
2147
+ if (!isJsonObject(json) || Object.keys(json).length === 0)
2148
+ throw new TypeError("ctx.upsertSearchAttributes takes an object with at least one attribute");
2149
+ for (const key of Object.keys(json))
2150
+ if (key.trim() === "") throw new TypeError("A search attribute needs a name");
2151
+ const apply = (input) => {
2152
+ const final = toJson(input.attributes, "The search attributes");
2153
+ if (!isJsonObject(final)) throw new TypeError("ctx.upsertSearchAttributes takes an object");
2154
+ if (this.push({ type: "UPSERT_SEARCH_ATTRIBUTES", attributes: final }))
2155
+ this.searchAttributes = chunkISOIA7NV_cjs.mergeSearchAttributes(this.searchAttributes, final);
2156
+ };
2157
+ if (this.outbound.length === 0) apply({ attributes: json });
2158
+ else
2159
+ chunkVA4OFR72_cjs.compose(
2160
+ this.outbound,
2161
+ "upsertSearchAttributes",
2162
+ apply
2163
+ )({ attributes: json });
2164
+ }
2165
+ /** A `ctx.sinks.<sink>.<fn>(...args)` call: recorded once, never on replay (11 §2.31). */
2166
+ callSink(sink, fn, args) {
2167
+ this.assertWritable(`The sink call ${sink}.${fn}`);
2168
+ if (this.replaying || this.closed || this.failure || this.request.kind !== "task") return;
2169
+ if (this.sinkCalls.length >= chunkTYF56RGB_cjs.MAX_SINK_CALLS) {
2170
+ if (!this.sinkCallsDropped) {
2171
+ this.sinkCallsDropped = true;
2172
+ this.logs.push({
2173
+ level: "warn",
2174
+ message: `More than ${chunkTYF56RGB_cjs.MAX_SINK_CALLS} sink calls in one workflow task; the rest were dropped`
2175
+ });
2176
+ }
2177
+ return;
2178
+ }
2179
+ this.sinkCalls.push({
2180
+ sink,
2181
+ fn,
2182
+ args: args.map((arg, index) => toJson(arg, `Argument ${index + 1} of ${sink}.${fn}`))
2183
+ });
2184
+ }
2185
+ sinksProxy() {
2186
+ const execution = this;
2187
+ const sinkOf = (sink) => new Proxy(
2188
+ {},
2189
+ {
2190
+ get(_target, fn) {
2191
+ if (typeof fn !== "string" || fn === "then") return void 0;
2192
+ return (...args) => execution.callSink(sink, fn, args);
2193
+ }
2194
+ }
2195
+ );
2196
+ return new Proxy(
2197
+ {},
2198
+ {
2199
+ get(_target, sink) {
2200
+ if (typeof sink !== "string" || sink === "then") return void 0;
2201
+ return sinkOf(sink);
2202
+ }
2203
+ }
2204
+ );
2205
+ }
2206
+ /** `ctx.continueAsNew`: a rejection with the request, after the outbound interceptors. */
2207
+ continueAsNewCall(input, options) {
2208
+ let request;
2209
+ try {
2210
+ request = this.continueAsNew(input, options);
2211
+ } catch (error) {
2212
+ return Promise.reject(error);
2213
+ }
2214
+ if (this.outbound.length === 0) return Promise.reject(request);
2215
+ return chunkVA4OFR72_cjs.compose(
2216
+ this.outbound,
2217
+ "continueAsNew",
2218
+ (changed) => Promise.reject(
2219
+ new ContinueAsNewRequest(
2220
+ toJson(changed.input, "The continue-as-new input"),
2221
+ changed.options,
2222
+ headersOf(changed.headers)
2223
+ )
2224
+ )
2225
+ )({ input: request.input, options: { ...request.options }, headers: {} });
2226
+ }
2227
+ /** The request a `ctx.continueAsNew` call throws; the run ends with `CONTINUE_AS_NEW`. */
2228
+ continueAsNew(input, options) {
2229
+ const opts = {};
2230
+ if (options.taskQueue !== void 0) opts["taskQueue"] = options.taskQueue;
2231
+ if (options.retry !== void 0)
2232
+ opts["retry"] = toJson(chunkVA4OFR72_cjs.continueAsNewRetryOf(options.retry), "retry");
2233
+ if (options.workflowTaskTimeout !== void 0)
2234
+ opts["workflowTaskTimeout"] = chunkVA4OFR72_cjs.toMs(options.workflowTaskTimeout, "workflowTaskTimeout");
2235
+ if (options.context !== void 0) opts["context"] = toJson(options.context, "context");
2236
+ if (options.versioningBehavior !== void 0)
2237
+ opts["versioningBehavior"] = options.versioningBehavior;
2238
+ return new ContinueAsNewRequest(toJson(input, "The continue-as-new input"), opts);
2239
+ }
2240
+ async cancellationScope(parent, fn, options) {
2241
+ const scope = new Scope(parent, options.nonCancellable === true);
2242
+ let timerId;
2243
+ if (options.timeout !== void 0) {
2244
+ const timer = this.timer(parent, chunkVA4OFR72_cjs.toMs(options.timeout, "scope timeout"), void 0);
2245
+ timerId = timer.timerId;
2246
+ timer.promise.then(
2247
+ () => scope.cancel(),
2248
+ () => void 0
2249
+ );
2250
+ }
2251
+ this.syncScopes.push(scope);
2252
+ let promise;
2253
+ try {
2254
+ promise = Promise.resolve(fn(this.contextFor(scope)));
2255
+ } catch (error) {
2256
+ promise = Promise.reject(error);
2257
+ } finally {
2258
+ this.syncScopes.pop();
2259
+ }
2260
+ try {
2261
+ return await promise;
2262
+ } finally {
2263
+ scope.detach();
2264
+ if (timerId !== void 0 && this.timers.has(timerId)) this.cancelOwnTimer(timerId);
2265
+ }
2266
+ }
2267
+ /** Waits for the signal handlers regardless of cancellation, as Temporal does. */
2268
+ allHandlersFinished() {
2269
+ return this.condition(this.detachedScope, () => this.runningHandlers === 0, void 0).then(
2270
+ () => void 0
2271
+ );
2272
+ }
2273
+ // ---- queries --------------------------------------------------------------
2274
+ pendingStacks() {
2275
+ const out = [];
2276
+ const add = (entry, fallback) => {
2277
+ if (!entry) return;
2278
+ out.push({ description: entry.description ?? fallback, stack: entry.stack ?? "" });
2279
+ };
2280
+ for (const entry of this.activities.values()) add(entry, "activity");
2281
+ for (const entry of this.localActivities.values()) add(entry, "local activity");
2282
+ for (const entry of this.timers.values()) add(entry, "timer");
2283
+ for (const child of this.children.values()) {
2284
+ add(child.started, "child start");
2285
+ add(child.result, "child result");
2286
+ }
2287
+ for (const entry of this.externals.values()) add(entry, "external");
2288
+ for (const list of this.signalWaiters.values()) for (const entry of list) add(entry, "signal");
2289
+ for (const condition of this.conditions)
2290
+ add(
2291
+ {
2292
+ description: "condition",
2293
+ ...condition.stack !== void 0 ? { stack: condition.stack } : {}
2294
+ },
2295
+ "condition"
2296
+ );
2297
+ return out;
2298
+ }
2299
+ /**
2300
+ * Answer a custom query (Phase C): the handler registered for the name, else
2301
+ * the default handler, run read-only through the inbound `handleQuery`
2302
+ * interceptors. No handler gives `rejected`.
2303
+ */
2304
+ answerCustomQuery(query) {
2305
+ if (this.failure)
2306
+ return { queryId: query.queryId, error: `The replay failed: ${this.failure.message}` };
2307
+ const own = this.queryHandlers.get(query.name);
2308
+ const fallback = this.defaultQueryHandler;
2309
+ const handler = own ?? (fallback !== void 0 ? (args) => fallback(query.name, args) : void 0);
2310
+ if (handler === void 0)
2311
+ return {
2312
+ queryId: query.queryId,
2313
+ rejected: true,
2314
+ error: `The workflow has no handler for query "${query.name}"`
2315
+ };
2316
+ const chain = chunkVA4OFR72_cjs.compose(
2317
+ this.inbound,
2318
+ "handleQuery",
2319
+ (input) => handler(input.args)
2320
+ );
2321
+ try {
2322
+ const value = this.readOnlyCall(
2323
+ `the handler of query ${query.name}`,
2324
+ () => chain({ queryId: query.queryId, name: query.name, args: query.args ?? null })
2325
+ );
2326
+ if (typeof value === "object" && value !== null && typeof value.then === "function")
2327
+ return {
2328
+ queryId: query.queryId,
2329
+ error: `The handler of query "${query.name}" returned a promise; query handlers must return a value`
2330
+ };
2331
+ return { queryId: query.queryId, value: toJson(value, `The result of query ${query.name}`) };
2332
+ } catch (error) {
2333
+ return {
2334
+ queryId: query.queryId,
2335
+ error: `${errorName(error) || "Error"}: ${messageOf(error)}`
2336
+ };
2337
+ }
2338
+ }
2339
+ answerQueries() {
2340
+ return (this.request.queries ?? []).map((query) => {
2341
+ if (!isBuiltInQuery(query.name)) return this.answerCustomQuery(query);
2342
+ if (this.failure)
2343
+ return { queryId: query.queryId, error: `The replay failed: ${this.failure.message}` };
2344
+ if (query.name === "__stack_trace")
2345
+ return {
2346
+ queryId: query.queryId,
2347
+ value: this.pendingStacks().map((entry) => `${entry.description}
2348
+ ${entry.stack}`).join("\n\n")
2349
+ };
2350
+ if (query.name === "__enhanced_stack_trace")
2351
+ return {
2352
+ queryId: query.queryId,
2353
+ value: {
2354
+ sdk: { name: SDK_NAME, version: this.sdkVersion },
2355
+ stacks: this.pendingStacks().map((entry) => ({
2356
+ description: entry.description,
2357
+ locations: chunkQ4MWQNJK_cjs.parseStack(entry.stack).map((location) => {
2358
+ const out = {};
2359
+ if (location.filePath !== void 0) out["filePath"] = location.filePath;
2360
+ if (location.line !== void 0) out["line"] = location.line;
2361
+ if (location.column !== void 0) out["column"] = location.column;
2362
+ if (location.functionName !== void 0)
2363
+ out["functionName"] = location.functionName;
2364
+ return out;
2365
+ })
2366
+ }))
2367
+ }
2368
+ };
2369
+ const options = this.definition.options;
2370
+ const describe = (items) => (items ?? []).map((item) => ({ name: item.name, description: item.description ?? null }));
2371
+ return {
2372
+ queryId: query.queryId,
2373
+ value: {
2374
+ definition: {
2375
+ name: this.definition.name,
2376
+ signals: describe(options.signals),
2377
+ queries: describe(options.queries),
2378
+ updates: describe(options.updates)
2379
+ },
2380
+ currentDetails: this.currentDetails ?? null
2381
+ }
2382
+ };
2383
+ });
2384
+ }
2385
+ // ---- the context ----------------------------------------------------------
2386
+ contextFor(bound) {
2387
+ const scope = () => bound ?? this.currentScope();
2388
+ const log = (level) => (message, data) => {
2389
+ if (this.replaying || this.readOnly !== void 0) return;
2390
+ const line = { level, message: String(message) };
2391
+ const payload = data !== void 0 ? toJson(data, "The log data") : void 0;
2392
+ const attributes = this.outbound.length === 0 ? {} : chunkVA4OFR72_cjs.compose(
2393
+ this.outbound,
2394
+ "getLogAttributes",
2395
+ (input) => input
2396
+ )({});
2397
+ if (Object.keys(attributes).length === 0) {
2398
+ if (payload !== void 0) line.data = payload;
2399
+ } else {
2400
+ const extra = toJson(attributes, "The log attributes");
2401
+ line.data = payload === void 0 ? extra : isJsonObject(payload) && isJsonObject(extra) ? { ...extra, ...payload } : { ...isJsonObject(extra) ? extra : {}, data: payload };
2402
+ }
2403
+ this.logs.push(line);
2404
+ };
2405
+ const logger = {
2406
+ debug: log("debug"),
2407
+ info: log("info"),
2408
+ warn: log("warn"),
2409
+ error: log("error")
2410
+ };
2411
+ const scopeFn = ((fn, options = {}) => this.cancellationScope(scope(), fn, options));
2412
+ scopeFn.current = () => scope();
2413
+ const context = {
2414
+ info: this.info,
2415
+ log: logger,
2416
+ run: (operation, options) => this.scheduleActivity(scope(), operation, options),
2417
+ sleep: (duration, options = {}) => {
2418
+ const durationMs = chunkVA4OFR72_cjs.toMs(duration, "sleep duration");
2419
+ if (this.outbound.length === 0)
2420
+ return this.startTimer(scope(), durationMs, options.summary);
2421
+ const current = scope();
2422
+ return chunkVA4OFR72_cjs.compose(
2423
+ this.outbound,
2424
+ "startTimer",
2425
+ (input) => this.startTimer(current, chunkVA4OFR72_cjs.toMs(input.durationMs, "sleep duration"), input.summary)
2426
+ )({ durationMs, ...options.summary !== void 0 ? { summary: options.summary } : {} });
2427
+ },
2428
+ condition: (predicate, timeout) => this.condition(scope(), predicate, timeout),
2429
+ signalReceived: (signal) => this.signalReceived(scope(), signal),
2430
+ onSignal: ((signal, optionsOrHandler, maybeHandler) => {
2431
+ if (typeof optionsOrHandler === "function") this.onSignal(signal, optionsOrHandler);
2432
+ else if (maybeHandler !== void 0)
2433
+ this.onSignal(signal, maybeHandler, optionsOrHandler ?? {});
2434
+ else throw new TypeError("ctx.onSignal needs a handler function");
2435
+ }),
2436
+ setDefaultSignalHandler: (handler) => this.setDefaultSignalHandler(handler),
2437
+ child: (target, options = {}) => this.child(scope(), target, options),
2438
+ startChild: (target, options = {}) => this.startChild(scope(), target, options),
2439
+ signalRun: (target, signal, payload) => this.signalExternal(this.externalTarget(target), chunkZCGKGDCL_cjs.signalName(signal), payload),
2440
+ signalParent: (signal, payload) => this.signalExternal({ parent: true }, chunkZCGKGDCL_cjs.signalName(signal), payload),
2441
+ getRunHandle: (target) => this.runHandle(target),
2442
+ cancelRun: (target) => this.cancelExternal(this.externalTarget(target)),
2443
+ now: () => this.clock,
2444
+ random: () => this.random(),
2445
+ uuid: () => {
2446
+ this.assertWritable("ctx.uuid()");
2447
+ return chunkL24YIZY7_cjs.uuidFrom(this.randomSource);
2448
+ },
2449
+ sideEffect: (fn) => this.sideEffect(fn),
2450
+ patched: (patchId) => this.patched(patchId, false),
2451
+ deprecatePatch: (patchId) => {
2452
+ this.patched(patchId, true);
2453
+ },
2454
+ setCurrentDetails: (markdown) => this.setCurrentDetails(markdown),
2455
+ upsertContext: (entries) => this.upsertContext(entries),
2456
+ continueAsNew: (input, options = {}) => this.continueAsNewCall(input, options),
2457
+ cancellationScope: scopeFn,
2458
+ nonCancellable: (fn) => this.cancellationScope(scope(), fn, { nonCancellable: true }),
2459
+ onCancel: (fn) => {
2460
+ scope().onCancel(() => {
2461
+ try {
2462
+ fn();
2463
+ } catch (error) {
2464
+ this.onWorkflowError(error);
2465
+ }
2466
+ });
2467
+ },
2468
+ isCancellation: (error) => chunkZCGKGDCL_cjs.isCancellation(error),
2469
+ saga: () => {
2470
+ const compensations = [];
2471
+ return {
2472
+ add: (compensation) => {
2473
+ compensations.push(compensation);
2474
+ },
2475
+ // Each compensation runs in its own non-cancellable scope, so it
2476
+ // still runs after a cancel request; it gets that scope's `ctx`.
2477
+ compensate: async () => {
2478
+ const pending = [...compensations].reverse();
2479
+ compensations.length = 0;
2480
+ for (const compensation of pending)
2481
+ await this.cancellationScope(
2482
+ scope(),
2483
+ async (scoped) => {
2484
+ await compensation(scoped);
2485
+ },
2486
+ { nonCancellable: true }
2487
+ );
2488
+ }
2489
+ };
2490
+ },
2491
+ allHandlersFinished: () => this.allHandlersFinished(),
2492
+ activity: (activity, options) => this.userActivity(scope(), activity, options),
2493
+ localActivity: ((operation, options) => this.localActivity(scope(), operation, options)),
2494
+ handleQuery: ((query, handler) => this.handleQuery(query, handler)),
2495
+ setDefaultQueryHandler: (handler) => this.setDefaultQueryHandler(handler),
2496
+ handleUpdate: ((update, handler, options) => this.handleUpdate(update, handler, options)),
2497
+ setDefaultUpdateHandler: ((first, second) => this.setDefaultUpdateHandler(first, second)),
2498
+ upsertSearchAttributes: (attributes) => this.upsertSearchAttributes(attributes),
2499
+ sinks: this.sinksProxy()
2500
+ };
2501
+ return Object.freeze(context);
2502
+ }
2503
+ };
2504
+
2505
+ // src/runtime/index.ts
2506
+ var RUNTIME_GLOBAL = "__fluidgridsRuntime";
2507
+ function buildWorkflowRegistry(modules) {
2508
+ const byName = /* @__PURE__ */ new Map();
2509
+ const exportNames = /* @__PURE__ */ new Map();
2510
+ const ambiguous = /* @__PURE__ */ new Set();
2511
+ const interceptors = [];
2512
+ let dynamic;
2513
+ let dynamicAmbiguous = false;
2514
+ for (const [, namespace] of modules) {
2515
+ for (const exportName of Object.keys(namespace).sort()) {
2516
+ const value = namespace[exportName];
2517
+ if (exportName === "interceptors") {
2518
+ const factory = chunkVA4OFR72_cjs.interceptorsFactoryOf(value);
2519
+ if (factory !== void 0 && !interceptors.includes(factory)) interceptors.push(factory);
2520
+ continue;
2521
+ }
2522
+ if (!chunkVA4OFR72_cjs.isDurableWorkflow(value)) continue;
2523
+ const existing = byName.get(exportName);
2524
+ if (existing && existing !== value) ambiguous.add(exportName);
2525
+ byName.set(exportName, value);
2526
+ if (!exportNames.has(value)) exportNames.set(value, exportName);
2527
+ if (value.dynamic === true) {
2528
+ if (dynamic !== void 0 && dynamic !== value) dynamicAmbiguous = true;
2529
+ dynamic ??= value;
2530
+ }
2531
+ }
2532
+ }
2533
+ return {
2534
+ byName,
2535
+ exportNames,
2536
+ ambiguous,
2537
+ ...dynamic !== void 0 ? { dynamic } : {},
2538
+ ...dynamicAmbiguous ? { dynamicAmbiguous } : {},
2539
+ ...interceptors.length > 0 ? { interceptors } : {}
2540
+ };
2541
+ }
2542
+ function failedResult(cause, message) {
2543
+ return {
2544
+ protocol: chunkTYF56RGB_cjs.HISTORY_PROTOCOL,
2545
+ outcome: "failed",
2546
+ commands: [],
2547
+ failure: { cause, message },
2548
+ logs: []
2549
+ };
2550
+ }
2551
+ function isObject(value) {
2552
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2553
+ }
2554
+ function checkRequest(value) {
2555
+ if (!isObject(value)) return "the request is not an object";
2556
+ if (typeof value["workflowFn"] !== "string" || value["workflowFn"] === "")
2557
+ return "workflowFn is missing";
2558
+ if (value["kind"] !== "task" && value["kind"] !== "query" && value["kind"] !== "verify")
2559
+ return "kind must be task, query or verify";
2560
+ const info = value["info"];
2561
+ if (!isObject(info) || typeof info["runId"] !== "string") return "info.runId is missing";
2562
+ if (!Array.isArray(value["history"])) return "history must be an array";
2563
+ for (const [index, event] of value["history"].entries()) {
2564
+ if (!isObject(event) || typeof event["type"] !== "string" || typeof event["seq"] !== "number" || !isObject(event["payload"]) || typeof event["createdAt"] !== "string")
2565
+ return `history[${index}] is not an event`;
2566
+ }
2567
+ if (typeof value["nowMs"] !== "number" || !Number.isFinite(value["nowMs"]))
2568
+ return "nowMs must be a number";
2569
+ const updates = value["updates"];
2570
+ if (updates !== void 0) {
2571
+ if (!Array.isArray(updates)) return "updates must be an array";
2572
+ for (const [index, update] of updates.entries())
2573
+ if (!isObject(update) || typeof update["updateId"] !== "string" || update["updateId"] === "" || typeof update["name"] !== "string")
2574
+ return `updates[${index}] needs an updateId and a name`;
2575
+ }
2576
+ const queries = value["queries"];
2577
+ if (queries !== void 0) {
2578
+ if (!Array.isArray(queries)) return "queries must be an array";
2579
+ for (const [index, query] of queries.entries())
2580
+ if (!isObject(query) || typeof query["queryId"] !== "string" || typeof query["name"] !== "string")
2581
+ return `queries[${index}] needs a queryId and a name`;
2582
+ }
2583
+ const features = value["features"];
2584
+ if (features !== void 0 && (!Array.isArray(features) || !features.every((feature) => typeof feature === "string")))
2585
+ return "features must be an array of strings";
2586
+ return value;
2587
+ }
2588
+ function createWorkflowRuntime(registry, shims = void 0) {
2589
+ let execution;
2590
+ let early;
2591
+ const internalFailure = (error) => {
2592
+ const message = error instanceof Error ? error.message : String(error);
2593
+ const stack = error instanceof Error ? error.stack : void 0;
2594
+ if (error instanceof chunkZCGKGDCL_cjs.HistoryLimitExceeded) execution?.failTask("HISTORY_LIMIT", message, stack);
2595
+ else if (error instanceof chunkZCGKGDCL_cjs.DeterminismViolation || error instanceof Error && error.name === "DeterminismViolation")
2596
+ execution?.failTask("NON_DETERMINISM", message, stack);
2597
+ else execution?.failTask("INTERNAL", message, stack);
2598
+ };
2599
+ return Object.freeze({
2600
+ protocol: chunkTYF56RGB_cjs.HISTORY_PROTOCOL,
2601
+ sdkVersion: chunkVA4OFR72_cjs.SDK_VERSION,
2602
+ capabilities: Object.freeze([...chunkTYF56RGB_cjs.RUNTIME_CAPABILITIES]),
2603
+ start(requestJson) {
2604
+ shims?.detach();
2605
+ execution = void 0;
2606
+ early = void 0;
2607
+ let parsed;
2608
+ try {
2609
+ parsed = JSON.parse(requestJson);
2610
+ } catch (error) {
2611
+ early = failedResult(
2612
+ "INVALID_REQUEST",
2613
+ `The request is not JSON: ${error instanceof Error ? error.message : String(error)}`
2614
+ );
2615
+ return;
2616
+ }
2617
+ if (isObject(parsed) && parsed["protocol"] !== chunkTYF56RGB_cjs.HISTORY_PROTOCOL) {
2618
+ early = failedResult(
2619
+ "PROTOCOL_MISMATCH",
2620
+ `This bundle speaks runtime protocol ${chunkTYF56RGB_cjs.HISTORY_PROTOCOL}; the request uses ${String(parsed["protocol"])}`
2621
+ );
2622
+ return;
2623
+ }
2624
+ const request = checkRequest(parsed);
2625
+ if (typeof request === "string") {
2626
+ early = failedResult("INVALID_REQUEST", `Invalid workflow task request: ${request}`);
2627
+ return;
2628
+ }
2629
+ if (registry.ambiguous.has(request.workflowFn)) {
2630
+ early = failedResult(
2631
+ "INVALID_REQUEST",
2632
+ `More than one module exports a workflow named "${request.workflowFn}"`
2633
+ );
2634
+ return;
2635
+ }
2636
+ const exported = registry.byName.get(request.workflowFn);
2637
+ if (!exported && registry.dynamic !== void 0 && registry.dynamicAmbiguous === true) {
2638
+ early = failedResult(
2639
+ "INVALID_REQUEST",
2640
+ `More than one module exports a dynamic workflow; "${request.workflowFn}" cannot be served`
2641
+ );
2642
+ return;
2643
+ }
2644
+ const definition = exported ?? registry.dynamic;
2645
+ if (!definition) {
2646
+ early = failedResult(
2647
+ "INVALID_REQUEST",
2648
+ `The bundle exports no workflow named "${request.workflowFn}"`
2649
+ );
2650
+ return;
2651
+ }
2652
+ try {
2653
+ const created = new WorkflowExecution({
2654
+ definition,
2655
+ exportNames: registry.exportNames,
2656
+ request,
2657
+ sdkVersion: chunkVA4OFR72_cjs.SDK_VERSION,
2658
+ ...registry.interceptors !== void 0 ? { interceptors: registry.interceptors } : {}
2659
+ });
2660
+ execution = created;
2661
+ shims?.attach({ now: () => created.now(), random: () => created.nextRandom() });
2662
+ } catch (error) {
2663
+ early = failedResult("INTERNAL", error instanceof Error ? error.message : String(error));
2664
+ }
2665
+ },
2666
+ step() {
2667
+ if (!execution) return "done";
2668
+ try {
2669
+ return execution.step();
2670
+ } catch (error) {
2671
+ internalFailure(error);
2672
+ return "done";
2673
+ }
2674
+ },
2675
+ complete() {
2676
+ try {
2677
+ if (early || !execution)
2678
+ return JSON.stringify(early ?? failedResult("INVALID_REQUEST", "start() was not called"));
2679
+ try {
2680
+ return JSON.stringify(execution.complete());
2681
+ } catch (error) {
2682
+ internalFailure(error);
2683
+ return JSON.stringify(execution.complete());
2684
+ }
2685
+ } finally {
2686
+ shims?.detach();
2687
+ execution = void 0;
2688
+ early = void 0;
2689
+ }
2690
+ }
2691
+ });
2692
+ }
2693
+ function installWorkflowRuntime(modules) {
2694
+ const holder = globalThis;
2695
+ if (holder[RUNTIME_GLOBAL] !== void 0) return;
2696
+ const runtime = createWorkflowRuntime(buildWorkflowRegistry(modules), chunkL24YIZY7_cjs.takeShimControl());
2697
+ Object.defineProperty(globalThis, RUNTIME_GLOBAL, {
2698
+ value: runtime,
2699
+ writable: false,
2700
+ enumerable: false,
2701
+ configurable: false
2702
+ });
2703
+ }
2704
+ function isRuntimeAbi(value) {
2705
+ return isObject(value) && typeof value["start"] === "function" && typeof value["step"] === "function" && typeof value["complete"] === "function";
2706
+ }
2707
+
2708
+ exports.CommandIds = CommandIds;
2709
+ exports.RUNTIME_GLOBAL = RUNTIME_GLOBAL;
2710
+ exports.SDK_NAME = SDK_NAME;
2711
+ exports.WorkflowExecution = WorkflowExecution;
2712
+ exports.buildWorkflowRegistry = buildWorkflowRegistry;
2713
+ exports.createWorkflowRuntime = createWorkflowRuntime;
2714
+ exports.installWorkflowRuntime = installWorkflowRuntime;
2715
+ exports.isPatchMarkerId = isPatchMarkerId;
2716
+ exports.isRuntimeAbi = isRuntimeAbi;
2717
+ exports.matchActivation = matchActivation;
2718
+ exports.mismatch = mismatch;
2719
+ exports.patchMarkerId = patchMarkerId;