@fluidgrids/workflows 2026.1028.2 → 2026.1029.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.
- package/README.md +72 -10
- package/dist/{activation-DnhG7SmF.d.ts → activation-BnVQMv9y.d.ts} +1 -1
- package/dist/{activation-BBh1p82z.d.cts → activation-CESehfYi.d.cts} +1 -1
- package/dist/{chunk-XHXIDVEC.js → chunk-25BKWR2O.js} +1 -1
- package/dist/{chunk-UK3WM7YZ.cjs → chunk-2B37XAFQ.cjs} +44 -8
- package/dist/{chunk-DJYMDLV5.js → chunk-2DDULZFM.js} +93 -1
- package/dist/{chunk-623FVQSN.cjs → chunk-3FIDHONL.cjs} +104 -0
- package/dist/chunk-6QPOJZT6.cjs +1180 -0
- package/dist/chunk-7ILGCUI6.js +154 -0
- package/dist/chunk-A2OHX3UQ.js +1156 -0
- package/dist/{chunk-VOKMAAJP.js → chunk-A36CCOWS.js} +188 -19
- package/dist/{chunk-FMSW2HDF.cjs → chunk-ELL2RBML.cjs} +0 -14
- package/dist/{chunk-JD2VQIDZ.cjs → chunk-EWYADREB.cjs} +2 -2
- package/dist/{chunk-HWJZVOG7.js → chunk-FQSJI5NV.js} +1 -1
- package/dist/{chunk-ABFZWYHT.js → chunk-FWBRQWRX.js} +156 -48
- package/dist/{chunk-PZCVF76Q.cjs → chunk-I47EENR4.cjs} +209 -40
- package/dist/chunk-J3PYFGKA.cjs +166 -0
- package/dist/{chunk-C5OLWZ42.js → chunk-KXJDRQ6G.js} +1 -13
- package/dist/chunk-M272AHEX.js +25 -0
- package/dist/{chunk-VRHHBPT6.js → chunk-MJ5TGYVG.js} +333 -65
- package/dist/{chunk-SAOBPYYJ.cjs → chunk-NXFBVDOI.cjs} +3 -3
- package/dist/{chunk-XKJA7KX3.js → chunk-OIX4O6UR.js} +38 -2
- package/dist/{chunk-FEW3JBYA.cjs → chunk-OKX3FYIM.cjs} +3 -3
- package/dist/{chunk-M4BBAERY.cjs → chunk-OMY3CKUZ.cjs} +404 -136
- package/dist/chunk-PWIUEWC3.js +81 -0
- package/dist/chunk-Q4MWQNJK.cjs +28 -0
- package/dist/{chunk-P6TA5EZT.cjs → chunk-RUQIMTN5.cjs} +171 -57
- package/dist/{chunk-IISBRUWJ.js → chunk-WXXNCHUY.js} +1 -1
- package/dist/chunk-YHBVMOMK.cjs +87 -0
- package/dist/codegen/index.d.cts +2 -2
- package/dist/codegen/index.d.ts +2 -2
- package/dist/collect-BTHjQaSp.d.ts +86 -0
- package/dist/collect-CSyOg5XC.d.cts +86 -0
- package/dist/{file-BOoHZgoQ.d.cts → file-cgL9l9l8.d.cts} +765 -14
- package/dist/{file-yuPCFU5b.d.ts → file-olQudcx5.d.ts} +765 -14
- package/dist/history/index.cjs +198 -86
- package/dist/history/index.d.cts +49 -10
- package/dist/history/index.d.ts +49 -10
- package/dist/history/index.js +49 -4
- package/dist/index.cjs +64 -51
- package/dist/index.d.cts +9 -53
- package/dist/index.d.ts +9 -53
- package/dist/index.js +5 -4
- package/dist/ir/index.cjs +24 -3
- package/dist/ir/index.d.cts +43 -4
- package/dist/ir/index.d.ts +43 -4
- package/dist/ir/index.js +24 -3
- package/dist/{lower-BzmUz0sq.d.cts → lower-3S6PsqjJ.d.cts} +40 -6
- package/dist/{lower-_-iT4HYs.d.ts → lower-DmZpQ8hJ.d.ts} +40 -6
- package/dist/{manifest-C8N6HDYl.d.ts → manifest-BJjrQt77.d.ts} +1 -1
- package/dist/{manifest-0OLw0i7k.d.cts → manifest-gRI2Q5Fj.d.cts} +1 -1
- package/dist/node-evaluator-SOADN23V.js +14 -0
- package/dist/node-evaluator-YGDEXK4U.cjs +24 -0
- package/dist/quickjs/index.cjs +25 -24
- package/dist/quickjs/index.d.cts +6 -6
- package/dist/quickjs/index.d.ts +6 -6
- package/dist/quickjs/index.js +8 -7
- package/dist/roundtrip/index.cjs +245 -43
- package/dist/roundtrip/index.d.cts +86 -9
- package/dist/roundtrip/index.d.ts +86 -9
- package/dist/roundtrip/index.js +172 -8
- package/dist/runtime/index.cjs +21 -20
- package/dist/runtime/index.d.cts +49 -7
- package/dist/runtime/index.d.ts +49 -7
- package/dist/runtime/index.js +8 -7
- package/dist/testing/index.cjs +514 -74
- package/dist/testing/index.d.cts +127 -10
- package/dist/testing/index.d.ts +127 -10
- package/dist/testing/index.js +480 -42
- package/dist/{types-BGoPzgcl.d.ts → types-Bb2wRnJ5.d.cts} +20 -1
- package/dist/{types-BGoPzgcl.d.cts → types-Bb2wRnJ5.d.ts} +20 -1
- package/dist/{types-DV-HX_Gt.d.ts → types-CQKOhPTa.d.cts} +122 -14
- package/dist/{types-CpBBjaGX.d.cts → types-CnIOinoz.d.ts} +122 -14
- package/dist/{workflow-Bpr3vnA_.d.ts → workflow-8uRU9rhL.d.ts} +2 -2
- package/dist/{workflow-FXUkpIBc.d.cts → workflow-CZOXUlQ5.d.cts} +2 -2
- package/dist/{workflow-C2a05WUJ.d.ts → workflow-DWTPHFbt.d.ts} +124 -12
- package/dist/{workflow-J-yYixny.d.cts → workflow-O6e64ZcG.d.cts} +124 -12
- package/fixtures/histories/auto-upgrade-patched.history.json +276 -0
- package/fixtures/histories/benign-failure.history.json +146 -0
- package/fixtures/histories/cancel-activity-try-cancel.history.json +150 -0
- package/fixtures/histories/child-cancel-wait-requested.history.json +217 -0
- package/fixtures/histories/child-options-roundtrip.history.json +192 -0
- package/fixtures/histories/continue-as-new-last-result.history.json +86 -0
- package/fixtures/histories/continue-as-new-options.history.json +99 -0
- package/fixtures/histories/continue-as-new-r1-long-task-queue.history.json +78 -0
- package/fixtures/histories/continue-as-new-r1-retry-options.history.json +83 -0
- package/fixtures/histories/execution-timeout-chain.history.json +98 -0
- package/fixtures/histories/external-cancel-resolved.history.json +123 -0
- package/fixtures/histories/external-cancel-unknown-target.history.json +127 -0
- package/fixtures/histories/failure-error-types-fails-run.history.json +144 -0
- package/fixtures/histories/handler-drain-warn.history.json +222 -0
- package/fixtures/histories/heartbeat-details-on-retry.history.json +145 -0
- package/fixtures/histories/local-activity-abandoned-at-completion.history.json +73 -0
- package/fixtures/histories/local-activity-cancelled-in-scope.history.json +118 -0
- package/fixtures/histories/local-activity-completed.history.json +157 -0
- package/fixtures/histories/local-activity-failed.history.json +93 -0
- package/fixtures/histories/local-activity-retry-in-task.history.json +88 -0
- package/fixtures/histories/run-retry-last-failure.history.json +90 -0
- package/fixtures/histories/run-timeout.history.json +159 -0
- package/fixtures/histories/schedule-to-start-timeout.history.json +132 -0
- package/fixtures/histories/start-delay-signal-ends-delay.history.json +155 -0
- package/fixtures/histories/typeerror-task-retry-100.history.json +137 -0
- package/package.json +1 -1
- package/schema/history-file.schema.json +283 -2
- package/schema/ir-v2.schema.json +45 -0
- package/schema/run-event.schema.json +264 -2
- package/schema/workflow-command.schema.json +178 -1
- package/schema/workflow-task.schema.json +392 -4
- package/dist/assemble-BLqQ8lSu.d.cts +0 -39
- package/dist/assemble-DWgaXHd-.d.ts +0 -39
- package/dist/chunk-2J6TF7YI.cjs +0 -86
- package/dist/chunk-BO6OVILK.js +0 -79
- package/dist/chunk-DHTLALBL.cjs +0 -80
- package/dist/chunk-I5LR3D2K.js +0 -869
- package/dist/chunk-N23SKIG4.js +0 -73
- package/dist/chunk-QQ6ULXHI.cjs +0 -885
- package/dist/node-evaluator-4MSDKWOG.cjs +0 -22
- package/dist/node-evaluator-SX4LEYQC.js +0 -12
package/dist/testing/index.cjs
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkEWYADREB_cjs = require('../chunk-EWYADREB.cjs');
|
|
4
|
+
var chunkNXFBVDOI_cjs = require('../chunk-NXFBVDOI.cjs');
|
|
5
5
|
var chunkGBQ33SIZ_cjs = require('../chunk-GBQ33SIZ.cjs');
|
|
6
6
|
require('../chunk-G4UEPUGO.cjs');
|
|
7
7
|
require('../chunk-GVTZMA5C.cjs');
|
|
8
8
|
require('../chunk-QKZL3ONM.cjs');
|
|
9
9
|
require('../chunk-TBDXTV22.cjs');
|
|
10
|
-
var
|
|
10
|
+
var chunkI47EENR4_cjs = require('../chunk-I47EENR4.cjs');
|
|
11
11
|
var chunkSAENRNBJ_cjs = require('../chunk-SAENRNBJ.cjs');
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
require('../chunk-
|
|
12
|
+
var chunkOMY3CKUZ_cjs = require('../chunk-OMY3CKUZ.cjs');
|
|
13
|
+
var chunkELL2RBML_cjs = require('../chunk-ELL2RBML.cjs');
|
|
14
|
+
require('../chunk-Q4MWQNJK.cjs');
|
|
15
15
|
var chunkL24YIZY7_cjs = require('../chunk-L24YIZY7.cjs');
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
var
|
|
19
|
-
require('../chunk-
|
|
16
|
+
var chunkJ3PYFGKA_cjs = require('../chunk-J3PYFGKA.cjs');
|
|
17
|
+
require('../chunk-FR7KYWRO.cjs');
|
|
18
|
+
var chunkRUQIMTN5_cjs = require('../chunk-RUQIMTN5.cjs');
|
|
19
|
+
var chunk3FIDHONL_cjs = require('../chunk-3FIDHONL.cjs');
|
|
20
|
+
var chunkYHBVMOMK_cjs = require('../chunk-YHBVMOMK.cjs');
|
|
20
21
|
require('../chunk-Z2Y65YOY.cjs');
|
|
21
22
|
var vm = require('vm');
|
|
22
23
|
|
|
@@ -25,7 +26,7 @@ function drainJobs() {
|
|
|
25
26
|
return new Promise((resolve) => setImmediate(resolve));
|
|
26
27
|
}
|
|
27
28
|
function registryOf(workflows) {
|
|
28
|
-
return
|
|
29
|
+
return chunkOMY3CKUZ_cjs.buildWorkflowRegistry([["in-process", { ...workflows }]]);
|
|
29
30
|
}
|
|
30
31
|
async function hostLoop(abi, requestJson) {
|
|
31
32
|
abi.start(requestJson);
|
|
@@ -35,19 +36,45 @@ async function hostLoop(abi, requestJson) {
|
|
|
35
36
|
return abi.complete();
|
|
36
37
|
}
|
|
37
38
|
async function runWorkflowTaskInProcess(registry, request) {
|
|
38
|
-
const abi =
|
|
39
|
+
const abi = chunkOMY3CKUZ_cjs.createWorkflowRuntime(registry);
|
|
39
40
|
const json = await hostLoop(abi, JSON.stringify(request));
|
|
40
41
|
return JSON.parse(json);
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
// src/testing/environment.ts
|
|
45
|
+
var WorkflowAlreadyStartedError = class extends Error {
|
|
46
|
+
constructor(workflowKey, workflowId, existingRunId) {
|
|
47
|
+
super(
|
|
48
|
+
`Workflow ${workflowKey} already has a run with workflow id "${workflowId}" (${existingRunId})`
|
|
49
|
+
);
|
|
50
|
+
this.workflowKey = workflowKey;
|
|
51
|
+
this.workflowId = workflowId;
|
|
52
|
+
this.existingRunId = existingRunId;
|
|
53
|
+
this.name = "WorkflowAlreadyStartedError";
|
|
54
|
+
}
|
|
55
|
+
workflowKey;
|
|
56
|
+
workflowId;
|
|
57
|
+
existingRunId;
|
|
58
|
+
};
|
|
59
|
+
var UnfinishedHandlersError = class extends Error {
|
|
60
|
+
constructor(runId, handlers) {
|
|
61
|
+
super(
|
|
62
|
+
`Run ${runId} finished while handlers were still running: ${handlers.map((handler) => `${handler.kind} ${handler.name} x${handler.count}`).join(", ")} (await ctx.allHandlersFinished(), or set unfinishedPolicy: 'ABANDON')`
|
|
63
|
+
);
|
|
64
|
+
this.runId = runId;
|
|
65
|
+
this.handlers = handlers;
|
|
66
|
+
this.name = "UnfinishedHandlersError";
|
|
67
|
+
}
|
|
68
|
+
runId;
|
|
69
|
+
handlers;
|
|
70
|
+
};
|
|
44
71
|
var WorkflowFailedError = class extends Error {
|
|
45
72
|
constructor(runId, failure) {
|
|
46
73
|
super(`Run ${runId} failed: ${failure.message}`);
|
|
47
74
|
this.runId = runId;
|
|
48
75
|
this.failure = failure;
|
|
49
76
|
this.name = "WorkflowFailedError";
|
|
50
|
-
Object.defineProperty(this, "cause", { value:
|
|
77
|
+
Object.defineProperty(this, "cause", { value: chunkELL2RBML_cjs.failureToError(failure), enumerable: false });
|
|
51
78
|
}
|
|
52
79
|
runId;
|
|
53
80
|
failure;
|
|
@@ -89,7 +116,7 @@ var TestRunHandle = class {
|
|
|
89
116
|
}
|
|
90
117
|
/** Deliver a signal and run until idle (without skipping time). */
|
|
91
118
|
async signal(signal, payload) {
|
|
92
|
-
this.env.deliverSignal(this.runId,
|
|
119
|
+
this.env.deliverSignal(this.runId, chunkELL2RBML_cjs.signalName(signal), payload);
|
|
93
120
|
await this.env.runUntilIdle(false);
|
|
94
121
|
}
|
|
95
122
|
/** Request cancellation and run until idle (without skipping time). */
|
|
@@ -116,6 +143,15 @@ function toDate(value) {
|
|
|
116
143
|
if (value instanceof Date) return value.getTime();
|
|
117
144
|
return typeof value === "number" ? value : Date.parse(value);
|
|
118
145
|
}
|
|
146
|
+
function optionalDuration(value, what) {
|
|
147
|
+
return value === void 0 ? void 0 : chunkJ3PYFGKA_cjs.toMs(value, what);
|
|
148
|
+
}
|
|
149
|
+
var FAILED_STATUSES = /* @__PURE__ */ new Set([
|
|
150
|
+
"FAILED",
|
|
151
|
+
"CANCELLED",
|
|
152
|
+
"TERMINATED",
|
|
153
|
+
"TIMED_OUT"
|
|
154
|
+
]);
|
|
119
155
|
function toJsonValue(value) {
|
|
120
156
|
if (value === void 0) return null;
|
|
121
157
|
const text = JSON.stringify(value);
|
|
@@ -125,6 +161,10 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
125
161
|
clock;
|
|
126
162
|
timeSkipping;
|
|
127
163
|
enabled;
|
|
164
|
+
failOnUnfinishedHandlers;
|
|
165
|
+
historyRelease;
|
|
166
|
+
dues = [];
|
|
167
|
+
held = /* @__PURE__ */ new Set();
|
|
128
168
|
workspaceId;
|
|
129
169
|
runs = /* @__PURE__ */ new Map();
|
|
130
170
|
runOrder = [];
|
|
@@ -142,6 +182,8 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
142
182
|
this.clock = toDate(options.startTime);
|
|
143
183
|
this.timeSkipping = options.timeSkipping !== false;
|
|
144
184
|
this.enabled = options.enabled ?? "parity";
|
|
185
|
+
this.failOnUnfinishedHandlers = options.failOnUnfinishedHandlers !== false;
|
|
186
|
+
this.historyRelease = options.historyRelease ?? chunk3FIDHONL_cjs.RUNTIME_RELEASE;
|
|
145
187
|
this.workspaceId = options.workspaceId ?? "test-workspace";
|
|
146
188
|
this.workflows = { ...options.workflows ?? {} };
|
|
147
189
|
this.registry = registryOf(this.workflows);
|
|
@@ -165,6 +207,22 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
165
207
|
impl
|
|
166
208
|
);
|
|
167
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Hold the activity queue of a node type (every node type when omitted):
|
|
212
|
+
* attempts wait instead of starting, and a `scheduleToStartTimeout` expires
|
|
213
|
+
* (`ACTIVITY_TIMED_OUT { timeoutType: SCHEDULE_TO_START }`, not retried).
|
|
214
|
+
*/
|
|
215
|
+
holdActivities(nodeType = "*") {
|
|
216
|
+
this.held.add(nodeType);
|
|
217
|
+
}
|
|
218
|
+
/** Release held activity queues (all when no node type is given). */
|
|
219
|
+
releaseActivities(nodeType) {
|
|
220
|
+
if (nodeType === void 0) this.held.clear();
|
|
221
|
+
else this.held.delete(nodeType);
|
|
222
|
+
}
|
|
223
|
+
isHeld(nodeType) {
|
|
224
|
+
return this.held.has("*") || this.held.has(nodeType);
|
|
225
|
+
}
|
|
168
226
|
/** Mock a child workflow started by key (graph or durable). */
|
|
169
227
|
mockChild(workflowKey, impl) {
|
|
170
228
|
this.childMocks.set(workflowKey, impl);
|
|
@@ -175,20 +233,88 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
175
233
|
// A declared workflow is stored by its declaration; its input type is the caller's.
|
|
176
234
|
this.ensureRegistered(definition)
|
|
177
235
|
);
|
|
236
|
+
const declared = this.workflows[workflowFn]?.options ?? {};
|
|
237
|
+
const workflowKey = options.workflowKey ?? (typeof definition === "string" ? this.workflows[workflowFn]?.name ?? workflowFn : definition.name);
|
|
238
|
+
if (options.workflowId !== void 0) {
|
|
239
|
+
const existing = this.useExisting(workflowKey, options);
|
|
240
|
+
if (existing !== void 0) {
|
|
241
|
+
for (const signal of options.signals ?? [])
|
|
242
|
+
this.deliverSignal(existing, signal.name, signal.payload);
|
|
243
|
+
await this.runUntilIdle(false);
|
|
244
|
+
return new TestRunHandle(this, existing);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const executionTimeoutMs = optionalDuration(
|
|
248
|
+
options.executionTimeout ?? declared.executionTimeout,
|
|
249
|
+
"executionTimeout"
|
|
250
|
+
);
|
|
251
|
+
const retry = options.retry ?? declared.retry;
|
|
252
|
+
const config = {
|
|
253
|
+
workflowKey,
|
|
254
|
+
runAttempt: 1,
|
|
255
|
+
...options.workflowId !== void 0 ? { businessId: options.workflowId } : {},
|
|
256
|
+
...executionTimeoutMs !== void 0 ? { executionTimeoutMs, executionDeadline: this.clock + executionTimeoutMs } : {},
|
|
257
|
+
...this.durationConfig(options.runTimeout ?? declared.runTimeout, "runTimeoutMs"),
|
|
258
|
+
...this.durationConfig(
|
|
259
|
+
options.workflowTaskTimeout ?? declared.workflowTaskTimeout,
|
|
260
|
+
"workflowTaskTimeoutMs"
|
|
261
|
+
),
|
|
262
|
+
...this.durationConfig(options.startDelay, "startDelayMs"),
|
|
263
|
+
...retry !== void 0 ? { retry: chunkJ3PYFGKA_cjs.runRetryPolicyOf(retry) } : {},
|
|
264
|
+
...options.summary !== void 0 ? { summary: options.summary } : {},
|
|
265
|
+
...options.details !== void 0 ? { details: options.details } : {},
|
|
266
|
+
...options.memo !== void 0 ? { memo: toJsonValue(options.memo) } : {},
|
|
267
|
+
...(options.versioningBehavior ?? declared.versioningBehavior) !== void 0 ? { versioningBehavior: options.versioningBehavior ?? declared.versioningBehavior } : {}
|
|
268
|
+
};
|
|
178
269
|
const runId = this.createRun(
|
|
179
270
|
workflowFn,
|
|
180
271
|
toJsonValue(options.input),
|
|
181
272
|
{ ...options.info, ...options.runId !== void 0 ? { runId: options.runId } : {} },
|
|
182
|
-
void 0
|
|
273
|
+
void 0,
|
|
274
|
+
{},
|
|
275
|
+
config
|
|
183
276
|
);
|
|
184
277
|
for (const signal of options.signals ?? [])
|
|
185
278
|
this.deliverSignal(runId, signal.name, signal.payload);
|
|
186
279
|
await this.runUntilIdle(false);
|
|
187
280
|
return new TestRunHandle(this, runId);
|
|
188
281
|
}
|
|
282
|
+
durationConfig(value, key) {
|
|
283
|
+
const ms = optionalDuration(value, key);
|
|
284
|
+
if (ms === void 0) return {};
|
|
285
|
+
const out = {};
|
|
286
|
+
out[key] = ms;
|
|
287
|
+
return out;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* The workflow-id policies of a start (11 §2.1): the open run to use, or
|
|
291
|
+
* undefined to start a new run (after terminating the open one for
|
|
292
|
+
* `TERMINATE_EXISTING`). Throws {@link WorkflowAlreadyStartedError}.
|
|
293
|
+
*/
|
|
294
|
+
useExisting(workflowKey, options) {
|
|
295
|
+
const workflowId = options.workflowId ?? "";
|
|
296
|
+
const runs = this.runOrder.map((id) => this.run(id)).filter(
|
|
297
|
+
(run) => run.config.workflowKey === workflowKey && run.config.businessId === workflowId
|
|
298
|
+
);
|
|
299
|
+
const open = runs.find((run) => run.state.status === "RUNNING");
|
|
300
|
+
if (open) {
|
|
301
|
+
const conflict = options.idConflictPolicy ?? "FAIL";
|
|
302
|
+
if (conflict === "USE_EXISTING") return open.runId;
|
|
303
|
+
if (conflict === "FAIL")
|
|
304
|
+
throw new WorkflowAlreadyStartedError(workflowKey, workflowId, open.runId);
|
|
305
|
+
this.terminate(open.runId, "ID_CONFLICT");
|
|
306
|
+
return void 0;
|
|
307
|
+
}
|
|
308
|
+
const last = runs[runs.length - 1];
|
|
309
|
+
if (!last) return void 0;
|
|
310
|
+
const reuse = options.idReusePolicy ?? "ALLOW_DUPLICATE";
|
|
311
|
+
if (reuse === "REJECT_DUPLICATE" || reuse === "ALLOW_DUPLICATE_FAILED_ONLY" && !FAILED_STATUSES.has(last.state.status))
|
|
312
|
+
throw new WorkflowAlreadyStartedError(workflowKey, workflowId, last.runId);
|
|
313
|
+
return void 0;
|
|
314
|
+
}
|
|
189
315
|
/** Advance the clock by `duration`, firing timers and running work as it comes due. */
|
|
190
316
|
async sleep(duration) {
|
|
191
|
-
const until = this.clock +
|
|
317
|
+
const until = this.clock + chunkJ3PYFGKA_cjs.toMs(duration, "sleep duration");
|
|
192
318
|
await this.runUntilIdle(false);
|
|
193
319
|
for (; ; ) {
|
|
194
320
|
const next = this.nextDue();
|
|
@@ -210,7 +336,7 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
210
336
|
}
|
|
211
337
|
historyFileOf(runId, extra = {}) {
|
|
212
338
|
const run = this.run(runId);
|
|
213
|
-
return
|
|
339
|
+
return chunkI47EENR4_cjs.createHistoryFile(run.workflowFn, this.historyOf(runId), {
|
|
214
340
|
info: { ...run.info },
|
|
215
341
|
...extra
|
|
216
342
|
});
|
|
@@ -236,7 +362,7 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
236
362
|
if (!run) throw new Error(`Unknown run ${runId}`);
|
|
237
363
|
return run;
|
|
238
364
|
}
|
|
239
|
-
createRun(workflowFn, input, info, parent, extraStarted = {}) {
|
|
365
|
+
createRun(workflowFn, input, info, parent, extraStarted = {}, config = { workflowKey: workflowFn, runAttempt: 1 }) {
|
|
240
366
|
this.runCounter += 1;
|
|
241
367
|
const runId = info.runId ?? `run-${this.runCounter}`;
|
|
242
368
|
const snapshot = {
|
|
@@ -253,22 +379,66 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
253
379
|
runId,
|
|
254
380
|
workflowFn,
|
|
255
381
|
history: [],
|
|
256
|
-
state:
|
|
382
|
+
state: chunkRUQIMTN5_cjs.initialRunState(),
|
|
257
383
|
taskCounter: 0,
|
|
258
384
|
info: snapshot,
|
|
259
385
|
children: /* @__PURE__ */ new Map(),
|
|
386
|
+
config,
|
|
260
387
|
...parent ? { parent } : {}
|
|
261
388
|
};
|
|
389
|
+
const firstTaskDelay = config.startDelayMs ?? config.firstTaskDelayMs;
|
|
390
|
+
if (firstTaskDelay !== void 0 && firstTaskDelay > 0) {
|
|
391
|
+
run.delayedUntil = this.clock + firstTaskDelay;
|
|
392
|
+
this.dues.push({ runId, kind: "start", at: run.delayedUntil });
|
|
393
|
+
}
|
|
394
|
+
if (config.runTimeoutMs !== void 0)
|
|
395
|
+
this.dues.push({ runId, kind: "runTimeout", at: this.clock + config.runTimeoutMs });
|
|
396
|
+
if (config.executionDeadline !== void 0)
|
|
397
|
+
this.dues.push({ runId, kind: "executionTimeout", at: config.executionDeadline });
|
|
262
398
|
this.runs.set(runId, run);
|
|
263
399
|
this.runOrder.push(runId);
|
|
264
400
|
this.append(run, {
|
|
265
401
|
type: "WORKFLOW_STARTED",
|
|
266
402
|
// The service writes the seed of ctx.random()/ctx.uuid() into the start
|
|
267
403
|
// event so the history replays on its own; it uses the run id.
|
|
268
|
-
payload: {
|
|
404
|
+
payload: {
|
|
405
|
+
workflowFn,
|
|
406
|
+
input,
|
|
407
|
+
taskQueue: config.taskQueue ?? "managed",
|
|
408
|
+
randomnessSeed: runId,
|
|
409
|
+
...extraStarted,
|
|
410
|
+
...this.startedFields(config)
|
|
411
|
+
}
|
|
269
412
|
});
|
|
270
413
|
return runId;
|
|
271
414
|
}
|
|
415
|
+
/** The R2 fields of `WORKFLOW_STARTED`, each written only when it is set. */
|
|
416
|
+
startedFields(config) {
|
|
417
|
+
const out = {};
|
|
418
|
+
if (config.businessId !== void 0) {
|
|
419
|
+
out["businessId"] = config.businessId;
|
|
420
|
+
out["workflowId"] = config.businessId;
|
|
421
|
+
}
|
|
422
|
+
if (config.startDelayMs !== void 0) out["startDelayMs"] = config.startDelayMs;
|
|
423
|
+
if (config.retry !== void 0 || config.runAttempt > 1) out["runAttempt"] = config.runAttempt;
|
|
424
|
+
if (config.summary !== void 0) out["summary"] = config.summary;
|
|
425
|
+
if (config.details !== void 0) out["details"] = config.details;
|
|
426
|
+
if (config.memo !== void 0) out["context"] = config.memo;
|
|
427
|
+
const timeouts = {};
|
|
428
|
+
if (config.executionTimeoutMs !== void 0)
|
|
429
|
+
timeouts["executionTimeout"] = config.executionTimeoutMs;
|
|
430
|
+
if (config.runTimeoutMs !== void 0) timeouts["runTimeout"] = config.runTimeoutMs;
|
|
431
|
+
if (config.workflowTaskTimeoutMs !== void 0)
|
|
432
|
+
timeouts["workflowTaskTimeout"] = config.workflowTaskTimeoutMs;
|
|
433
|
+
if (Object.keys(timeouts).length > 0) out["timeouts"] = timeouts;
|
|
434
|
+
if (config.retry !== void 0) out["retry"] = toJsonValue(config.retry);
|
|
435
|
+
if (config.versioningBehavior !== void 0)
|
|
436
|
+
out["versioningBehavior"] = config.versioningBehavior;
|
|
437
|
+
if (config.lastCompletionResult !== void 0 && this.historyRelease >= 2)
|
|
438
|
+
out["lastCompletionResult"] = config.lastCompletionResult;
|
|
439
|
+
if (config.lastFailure !== void 0) out["lastFailure"] = toJsonValue(config.lastFailure);
|
|
440
|
+
return out;
|
|
441
|
+
}
|
|
272
442
|
append(run, draft) {
|
|
273
443
|
const event = {
|
|
274
444
|
seq: run.history.length + 1,
|
|
@@ -277,9 +447,10 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
277
447
|
createdAt: new Date(this.clock).toISOString(),
|
|
278
448
|
...draft.taskId !== void 0 ? { taskId: draft.taskId } : {}
|
|
279
449
|
};
|
|
280
|
-
|
|
450
|
+
chunkRUQIMTN5_cjs.applyEvent(run.state, event);
|
|
281
451
|
run.history.push(event);
|
|
282
|
-
if (
|
|
452
|
+
if (run.delayedUntil !== void 0 && event.type === "SIGNAL_RECEIVED") this.endDelay(run);
|
|
453
|
+
if (run.delayedUntil === void 0 && chunk3FIDHONL_cjs.isInputEvent(event) && run.state.status === "RUNNING" && run.state.task.state === "NONE") {
|
|
283
454
|
run.taskCounter += 1;
|
|
284
455
|
const taskId = `${run.runId}-task-${run.taskCounter}`;
|
|
285
456
|
const scheduled = {
|
|
@@ -288,11 +459,27 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
288
459
|
payload: { taskId },
|
|
289
460
|
createdAt: event.createdAt
|
|
290
461
|
};
|
|
291
|
-
|
|
462
|
+
chunkRUQIMTN5_cjs.applyEvent(run.state, scheduled);
|
|
292
463
|
run.history.push(scheduled);
|
|
293
464
|
}
|
|
294
465
|
return event;
|
|
295
466
|
}
|
|
467
|
+
/** End a start delay: the first workflow task is scheduled now. */
|
|
468
|
+
endDelay(run) {
|
|
469
|
+
run.delayedUntil = void 0;
|
|
470
|
+
this.dues = this.dues.filter((due) => !(due.runId === run.runId && due.kind === "start"));
|
|
471
|
+
if (run.state.status !== "RUNNING" || run.state.task.state !== "NONE") return;
|
|
472
|
+
run.taskCounter += 1;
|
|
473
|
+
const taskId = `${run.runId}-task-${run.taskCounter}`;
|
|
474
|
+
const scheduled = {
|
|
475
|
+
seq: run.history.length + 1,
|
|
476
|
+
type: "WORKFLOW_TASK_SCHEDULED",
|
|
477
|
+
payload: { taskId },
|
|
478
|
+
createdAt: new Date(this.clock).toISOString()
|
|
479
|
+
};
|
|
480
|
+
chunkRUQIMTN5_cjs.applyEvent(run.state, scheduled);
|
|
481
|
+
run.history.push(scheduled);
|
|
482
|
+
}
|
|
296
483
|
deliverSignal(runId, name, payload) {
|
|
297
484
|
const run = this.runs.get(runId);
|
|
298
485
|
if (!run || run.state.status !== "RUNNING") return false;
|
|
@@ -314,6 +501,11 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
314
501
|
type: "WORKFLOW_CANCEL_REQUESTED",
|
|
315
502
|
payload: reason !== void 0 ? { reason } : {}
|
|
316
503
|
});
|
|
504
|
+
if (run.delayedUntil !== void 0) {
|
|
505
|
+
run.delayedUntil = void 0;
|
|
506
|
+
this.append(run, { type: "WORKFLOW_CANCELLED", payload: {} });
|
|
507
|
+
this.onClosed(run);
|
|
508
|
+
}
|
|
317
509
|
return true;
|
|
318
510
|
}
|
|
319
511
|
terminate(runId, reason) {
|
|
@@ -333,7 +525,9 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
333
525
|
await this.runTask(task);
|
|
334
526
|
continue;
|
|
335
527
|
}
|
|
336
|
-
const attempt = this.attempts.find(
|
|
528
|
+
const attempt = this.attempts.find(
|
|
529
|
+
(entry) => entry.dueAt <= this.clock && !this.isHeld(entry.nodeType)
|
|
530
|
+
);
|
|
337
531
|
if (attempt) {
|
|
338
532
|
this.attempts = this.attempts.filter((entry) => entry !== attempt);
|
|
339
533
|
await this.runAttempt(attempt);
|
|
@@ -352,16 +546,78 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
352
546
|
}
|
|
353
547
|
throw new Error("The test environment did not settle after 100000 steps");
|
|
354
548
|
}
|
|
549
|
+
/** When a held attempt's schedule-to-start timeout expires, if it has one. */
|
|
550
|
+
heldDeadline(entry) {
|
|
551
|
+
return this.isHeld(entry.nodeType) && entry.scheduleToStart !== void 0 ? entry.dueAt + entry.scheduleToStart : void 0;
|
|
552
|
+
}
|
|
355
553
|
nextDue() {
|
|
356
|
-
const due = [
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
554
|
+
const due = [...this.timers.map((timer) => timer.fireAt)];
|
|
555
|
+
for (const entry of this.attempts) {
|
|
556
|
+
if (!this.isHeld(entry.nodeType)) due.push(entry.dueAt);
|
|
557
|
+
const deadline = this.heldDeadline(entry);
|
|
558
|
+
if (deadline !== void 0) due.push(deadline);
|
|
559
|
+
}
|
|
560
|
+
for (const entry of this.dues) due.push(entry.at);
|
|
360
561
|
return due.length === 0 ? void 0 : Math.min(...due);
|
|
361
562
|
}
|
|
563
|
+
/** Expire held attempts whose schedule-to-start timeout passed (not retried, 11 §2.3). */
|
|
564
|
+
expireHeld() {
|
|
565
|
+
const expired = this.attempts.filter((entry) => {
|
|
566
|
+
const deadline = this.heldDeadline(entry);
|
|
567
|
+
return deadline !== void 0 && deadline <= this.clock;
|
|
568
|
+
});
|
|
569
|
+
if (expired.length === 0) return false;
|
|
570
|
+
this.attempts = this.attempts.filter((entry) => !expired.includes(entry));
|
|
571
|
+
for (const entry of expired) {
|
|
572
|
+
const run = this.runs.get(entry.runId);
|
|
573
|
+
const activity = run?.state.activities[entry.activityId];
|
|
574
|
+
if (!run || run.state.status !== "RUNNING" || !activity || !chunkRUQIMTN5_cjs.isActivityOpen(activity))
|
|
575
|
+
continue;
|
|
576
|
+
this.append(run, {
|
|
577
|
+
type: "ACTIVITY_TIMED_OUT",
|
|
578
|
+
payload: {
|
|
579
|
+
activityId: entry.activityId,
|
|
580
|
+
attempt: entry.attempt,
|
|
581
|
+
timeoutType: "SCHEDULE_TO_START"
|
|
582
|
+
}
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
return true;
|
|
586
|
+
}
|
|
587
|
+
/** Fire run-level deadlines: the end of a start delay, run and execution timeouts. */
|
|
588
|
+
fireRunDues() {
|
|
589
|
+
const due = this.dues.filter((entry) => entry.at <= this.clock).sort((a, b) => a.at - b.at);
|
|
590
|
+
if (due.length === 0) return false;
|
|
591
|
+
this.dues = this.dues.filter((entry) => !due.includes(entry));
|
|
592
|
+
for (const entry of due) {
|
|
593
|
+
const run = this.runs.get(entry.runId);
|
|
594
|
+
if (!run || run.state.status !== "RUNNING") continue;
|
|
595
|
+
if (entry.kind === "start") {
|
|
596
|
+
if (run.delayedUntil !== void 0) this.endDelay(run);
|
|
597
|
+
continue;
|
|
598
|
+
}
|
|
599
|
+
const timeoutType = entry.kind === "runTimeout" ? "WORKFLOW_RUN" : "WORKFLOW_EXECUTION";
|
|
600
|
+
const failure = {
|
|
601
|
+
errorType: "TIMEOUT",
|
|
602
|
+
message: timeoutType === "WORKFLOW_RUN" ? "The run timeout expired" : "The execution timeout of the chain expired",
|
|
603
|
+
type: "TimeoutFailure",
|
|
604
|
+
timeoutType,
|
|
605
|
+
source: "engine"
|
|
606
|
+
};
|
|
607
|
+
run.delayedUntil = void 0;
|
|
608
|
+
this.append(run, {
|
|
609
|
+
type: "WORKFLOW_TIMED_OUT",
|
|
610
|
+
payload: { timeoutType, failure: toJsonValue(failure) }
|
|
611
|
+
});
|
|
612
|
+
this.onClosed(run);
|
|
613
|
+
}
|
|
614
|
+
return true;
|
|
615
|
+
}
|
|
362
616
|
fireDue() {
|
|
617
|
+
const expired = this.expireHeld();
|
|
618
|
+
const fired = this.fireRunDues();
|
|
363
619
|
const due = this.timers.filter((timer) => timer.fireAt <= this.clock).sort((a, b) => a.fireAt - b.fireAt);
|
|
364
|
-
if (due.length === 0) return
|
|
620
|
+
if (due.length === 0) return expired || fired;
|
|
365
621
|
this.timers = this.timers.filter((timer) => !due.includes(timer));
|
|
366
622
|
for (const timer of due) {
|
|
367
623
|
const run = this.runs.get(timer.runId);
|
|
@@ -375,14 +631,14 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
375
631
|
const taskId = run.state.task.taskId ?? `${run.runId}-task-${run.taskCounter}`;
|
|
376
632
|
this.append(run, { type: "WORKFLOW_TASK_STARTED", payload: { taskId, attempt: 1 } });
|
|
377
633
|
const request = {
|
|
378
|
-
protocol:
|
|
634
|
+
protocol: chunk3FIDHONL_cjs.HISTORY_PROTOCOL,
|
|
379
635
|
kind: "task",
|
|
380
636
|
workflowFn: run.workflowFn,
|
|
381
637
|
info: run.info,
|
|
382
638
|
history: run.history,
|
|
383
639
|
nowMs: this.clock
|
|
384
640
|
};
|
|
385
|
-
const result =
|
|
641
|
+
const result = await this.executeWithLocalActivities(run, request);
|
|
386
642
|
const fail = (cause, message) => {
|
|
387
643
|
this.append(run, {
|
|
388
644
|
type: "WORKFLOW_TASK_FAILED",
|
|
@@ -395,12 +651,12 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
395
651
|
run.taskFailure = result;
|
|
396
652
|
return;
|
|
397
653
|
}
|
|
398
|
-
const checked =
|
|
654
|
+
const checked = chunkI47EENR4_cjs.validateCommands(result.commands, { enabled: this.enabled });
|
|
399
655
|
if (!checked.ok) {
|
|
400
656
|
fail(checked.cause, checked.issues.map((issue) => issue.message).join("; "));
|
|
401
657
|
return;
|
|
402
658
|
}
|
|
403
|
-
const drafts =
|
|
659
|
+
const drafts = chunkRUQIMTN5_cjs.eventsForCommands(run.state, checked.commands, {
|
|
404
660
|
taskId,
|
|
405
661
|
nowMs: this.clock,
|
|
406
662
|
enabled: this.enabled
|
|
@@ -409,12 +665,69 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
409
665
|
fail(drafts.cause, drafts.issues.map((issue) => issue.message).join("; "));
|
|
410
666
|
return;
|
|
411
667
|
}
|
|
668
|
+
if (result.unfinishedHandlers !== void 0 && result.unfinishedHandlers.length > 0)
|
|
669
|
+
run.unfinishedHandlers = result.unfinishedHandlers;
|
|
412
670
|
this.append(run, { type: "WORKFLOW_TASK_COMPLETED", taskId, payload: { taskId } });
|
|
413
671
|
for (const draft of drafts.events) this.append(run, draft);
|
|
414
672
|
for (const command of checked.commands)
|
|
415
|
-
if (run.state.status === "RUNNING" ||
|
|
673
|
+
if (run.state.status === "RUNNING" || chunk3FIDHONL_cjs.TERMINAL_COMMANDS.has(command.type))
|
|
416
674
|
this.afterCommand(run, command);
|
|
417
675
|
}
|
|
676
|
+
execute(request) {
|
|
677
|
+
return this.executor ? this.executor(request) : runWorkflowTaskInProcess(this.registry, request);
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Run a workflow task as the worker does (11 §2.12): while it asks for
|
|
681
|
+
* local activities, run each through its mock and run the same task again
|
|
682
|
+
* with the outcomes, up to 1,000 rounds.
|
|
683
|
+
*/
|
|
684
|
+
async executeWithLocalActivities(run, request) {
|
|
685
|
+
const outcomes = /* @__PURE__ */ new Map();
|
|
686
|
+
let result = await this.execute(request);
|
|
687
|
+
for (let round = 0; result.outcome === "localActivityRequested"; round++) {
|
|
688
|
+
if (round >= 1e3)
|
|
689
|
+
return {
|
|
690
|
+
...result,
|
|
691
|
+
outcome: "failed",
|
|
692
|
+
commands: [],
|
|
693
|
+
failure: { cause: "INTERNAL", message: "The task asked for local activities 1000 times" }
|
|
694
|
+
};
|
|
695
|
+
for (const wanted of result.localActivityRequests ?? [])
|
|
696
|
+
outcomes.set(wanted.localActivityId, await this.runLocalActivity(run, wanted));
|
|
697
|
+
result = await this.execute({ ...request, localActivityResults: [...outcomes.values()] });
|
|
698
|
+
}
|
|
699
|
+
return result;
|
|
700
|
+
}
|
|
701
|
+
async runLocalActivity(run, wanted) {
|
|
702
|
+
const mock = this.mocks.get(`${wanted.nodeType}#${wanted.operation}`) ?? this.mocks.get(wanted.nodeType);
|
|
703
|
+
try {
|
|
704
|
+
if (!mock)
|
|
705
|
+
throw new chunkELL2RBML_cjs.ApplicationError(
|
|
706
|
+
`No mock for ${wanted.nodeType} ${wanted.operation} (use env.mock)`,
|
|
707
|
+
{ errorType: "VALIDATION", nonRetryable: true, type: "UnmockedActivity" }
|
|
708
|
+
);
|
|
709
|
+
const result = toJsonValue(
|
|
710
|
+
await mock(wanted.args, {
|
|
711
|
+
runId: run.runId,
|
|
712
|
+
activityId: wanted.localActivityId,
|
|
713
|
+
attempt: wanted.attempt,
|
|
714
|
+
nodeType: wanted.nodeType,
|
|
715
|
+
operation: wanted.operation,
|
|
716
|
+
local: true,
|
|
717
|
+
...wanted.connection !== void 0 ? { connection: wanted.connection } : {}
|
|
718
|
+
})
|
|
719
|
+
);
|
|
720
|
+
return { localActivityId: wanted.localActivityId, result, attempts: wanted.attempt };
|
|
721
|
+
} catch (error) {
|
|
722
|
+
const failure = chunkELL2RBML_cjs.errorToFailure(error, `node:${wanted.nodeType}`);
|
|
723
|
+
delete failure.stackTrace;
|
|
724
|
+
return {
|
|
725
|
+
localActivityId: wanted.localActivityId,
|
|
726
|
+
failure: toJsonValue(failure),
|
|
727
|
+
attempts: wanted.attempt
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
}
|
|
418
731
|
afterCommand(run, command) {
|
|
419
732
|
switch (command.type) {
|
|
420
733
|
case "SCHEDULE_ACTIVITY": {
|
|
@@ -430,7 +743,8 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
430
743
|
retry: command.retry,
|
|
431
744
|
cancelRequested: false,
|
|
432
745
|
...command.connection !== void 0 ? { connection: command.connection } : {},
|
|
433
|
-
...command.scheduleToCloseTimeout !== void 0 ? { scheduleToClose: command.scheduleToCloseTimeout } : {}
|
|
746
|
+
...command.scheduleToCloseTimeout !== void 0 ? { scheduleToClose: command.scheduleToCloseTimeout } : {},
|
|
747
|
+
...command.scheduleToStartTimeout !== void 0 ? { scheduleToStart: command.scheduleToStartTimeout } : {}
|
|
434
748
|
};
|
|
435
749
|
this.attempts.push(attempt);
|
|
436
750
|
return;
|
|
@@ -505,18 +819,25 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
505
819
|
return;
|
|
506
820
|
}
|
|
507
821
|
case "CONTINUE_AS_NEW": {
|
|
508
|
-
const
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
)
|
|
519
|
-
|
|
822
|
+
const options = command.options;
|
|
823
|
+
const config = {
|
|
824
|
+
...this.chainConfig(run.config),
|
|
825
|
+
// The run timeout restarts and the attempt count resets; the
|
|
826
|
+
// execution timeout of the chain carries over (11 §2.20).
|
|
827
|
+
lastCompletionResult: command.input
|
|
828
|
+
};
|
|
829
|
+
if (typeof options["taskQueue"] === "string") config.taskQueue = options["taskQueue"];
|
|
830
|
+
if (typeof options["workflowTaskTimeout"] === "number")
|
|
831
|
+
config.workflowTaskTimeoutMs = options["workflowTaskTimeout"];
|
|
832
|
+
if (options["versioningBehavior"] === "PINNED" || options["versioningBehavior"] === "AUTO_UPGRADE")
|
|
833
|
+
config.versioningBehavior = options["versioningBehavior"];
|
|
834
|
+
const memo = options["context"];
|
|
835
|
+
if (typeof memo === "object" && memo !== null && !Array.isArray(memo)) config.memo = memo;
|
|
836
|
+
else if (Object.keys(run.state.context).length > 0) config.memo = { ...run.state.context };
|
|
837
|
+
const retry = options["retry"];
|
|
838
|
+
if (chunkRUQIMTN5_cjs.continueAsNewRetryShape(options) === "run" && typeof retry === "object" && retry !== null && !Array.isArray(retry))
|
|
839
|
+
config.retry = retry;
|
|
840
|
+
this.startSuccessor(run, command.input, config);
|
|
520
841
|
this.onClosed(run);
|
|
521
842
|
return;
|
|
522
843
|
}
|
|
@@ -529,11 +850,62 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
529
850
|
return;
|
|
530
851
|
}
|
|
531
852
|
}
|
|
853
|
+
/** What a successor of a run inherits (continue-as-new, run retry). */
|
|
854
|
+
chainConfig(config) {
|
|
855
|
+
const out = { workflowKey: config.workflowKey, runAttempt: 1 };
|
|
856
|
+
for (const key of [
|
|
857
|
+
"businessId",
|
|
858
|
+
"executionDeadline",
|
|
859
|
+
"executionTimeoutMs",
|
|
860
|
+
"runTimeoutMs",
|
|
861
|
+
"workflowTaskTimeoutMs",
|
|
862
|
+
"retry",
|
|
863
|
+
"versioningBehavior",
|
|
864
|
+
"taskQueue",
|
|
865
|
+
"memo"
|
|
866
|
+
])
|
|
867
|
+
if (config[key] !== void 0) Object.assign(out, { [key]: config[key] });
|
|
868
|
+
return out;
|
|
869
|
+
}
|
|
870
|
+
/** Start the next run of a chain; the closed run's parent and handles follow it. */
|
|
871
|
+
startSuccessor(run, input, config) {
|
|
872
|
+
const next = this.createRun(
|
|
873
|
+
run.workflowFn,
|
|
874
|
+
input,
|
|
875
|
+
{
|
|
876
|
+
...run.info,
|
|
877
|
+
runId: void 0,
|
|
878
|
+
continuedFromRunId: run.runId,
|
|
879
|
+
firstRunId: run.info.firstRunId ?? run.runId
|
|
880
|
+
},
|
|
881
|
+
run.parent,
|
|
882
|
+
{},
|
|
883
|
+
config
|
|
884
|
+
);
|
|
885
|
+
run.continuedTo = next;
|
|
886
|
+
return next;
|
|
887
|
+
}
|
|
532
888
|
resolveTarget(run, target) {
|
|
533
889
|
if ("runId" in target) return target.runId;
|
|
534
890
|
if ("parent" in target) return run.parent?.runId ?? run.info.parentRunId ?? void 0;
|
|
535
|
-
if ("childId" in target)
|
|
536
|
-
|
|
891
|
+
if ("childId" in target) {
|
|
892
|
+
let childRunId = run.children.get(target.childId);
|
|
893
|
+
while (childRunId !== void 0) {
|
|
894
|
+
const next = this.runs.get(childRunId)?.continuedTo;
|
|
895
|
+
if (next === void 0) break;
|
|
896
|
+
childRunId = next;
|
|
897
|
+
}
|
|
898
|
+
return childRunId;
|
|
899
|
+
}
|
|
900
|
+
return this.resolveWorkflowId(target.workflowKey, target.workflowId, target.firstRunId);
|
|
901
|
+
}
|
|
902
|
+
/** The open run of a workflow id, else its latest run (11 §2.1). */
|
|
903
|
+
resolveWorkflowId(workflowKey, workflowId, firstRunId) {
|
|
904
|
+
const matching = this.runOrder.map((id) => this.run(id)).filter(
|
|
905
|
+
(candidate) => candidate.config.workflowKey === workflowKey && candidate.config.businessId === workflowId && (firstRunId === void 0 || (candidate.info.firstRunId ?? candidate.runId) === firstRunId)
|
|
906
|
+
);
|
|
907
|
+
const open = matching.find((candidate) => candidate.state.status === "RUNNING");
|
|
908
|
+
return (open ?? matching[matching.length - 1])?.runId;
|
|
537
909
|
}
|
|
538
910
|
startChild(run, command) {
|
|
539
911
|
const byFn = command.workflowFn !== void 0 && (this.executor !== void 0 || this.registry.byName.has(command.workflowFn));
|
|
@@ -566,6 +938,28 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
566
938
|
});
|
|
567
939
|
return;
|
|
568
940
|
}
|
|
941
|
+
const options = command.options;
|
|
942
|
+
const ms = (key) => typeof options[key] === "number" ? options[key] : void 0;
|
|
943
|
+
const executionTimeoutMs = ms("executionTimeout");
|
|
944
|
+
const childKey = command.workflowKey ?? this.registry.byName.get(workflowFn)?.name ?? workflowFn;
|
|
945
|
+
const config = { workflowKey: childKey, runAttempt: 1 };
|
|
946
|
+
if (typeof options.workflowId === "string") config.businessId = options.workflowId;
|
|
947
|
+
if (executionTimeoutMs !== void 0) {
|
|
948
|
+
config.executionTimeoutMs = executionTimeoutMs;
|
|
949
|
+
config.executionDeadline = this.clock + executionTimeoutMs;
|
|
950
|
+
}
|
|
951
|
+
const runTimeoutMs = ms("runTimeout");
|
|
952
|
+
if (runTimeoutMs !== void 0) config.runTimeoutMs = runTimeoutMs;
|
|
953
|
+
const taskTimeoutMs = ms("workflowTaskTimeout");
|
|
954
|
+
if (taskTimeoutMs !== void 0) config.workflowTaskTimeoutMs = taskTimeoutMs;
|
|
955
|
+
const startDelayMs = ms("startDelay");
|
|
956
|
+
if (startDelayMs !== void 0) config.startDelayMs = startDelayMs;
|
|
957
|
+
if (typeof options.summary === "string") config.summary = options.summary;
|
|
958
|
+
if (typeof options.details === "string") config.details = options.details;
|
|
959
|
+
if (options.context !== void 0) config.memo = options.context;
|
|
960
|
+
if (options.versioningBehavior !== void 0)
|
|
961
|
+
config.versioningBehavior = options.versioningBehavior;
|
|
962
|
+
if (options.retry !== void 0) config.retry = options.retry;
|
|
569
963
|
const childRunId = this.createRun(
|
|
570
964
|
workflowFn,
|
|
571
965
|
command.input,
|
|
@@ -574,7 +968,8 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
574
968
|
{
|
|
575
969
|
parentRunId: run.runId,
|
|
576
970
|
parentClosePolicy: command.options.parentClosePolicy
|
|
577
|
-
}
|
|
971
|
+
},
|
|
972
|
+
config
|
|
578
973
|
);
|
|
579
974
|
run.children.set(command.childId, childRunId);
|
|
580
975
|
this.append(run, {
|
|
@@ -607,7 +1002,7 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
607
1002
|
payload: {
|
|
608
1003
|
childId: entry.childId,
|
|
609
1004
|
childRunId,
|
|
610
|
-
failure: toJsonValue(
|
|
1005
|
+
failure: toJsonValue(chunkELL2RBML_cjs.errorToFailure(error, "engine"))
|
|
611
1006
|
}
|
|
612
1007
|
});
|
|
613
1008
|
}
|
|
@@ -616,7 +1011,7 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
616
1011
|
const run = this.runs.get(attempt.runId);
|
|
617
1012
|
if (!run || run.state.status !== "RUNNING") return;
|
|
618
1013
|
const activity = run.state.activities[attempt.activityId];
|
|
619
|
-
if (!activity || !
|
|
1014
|
+
if (!activity || !chunkRUQIMTN5_cjs.isActivityOpen(activity)) return;
|
|
620
1015
|
if (attempt.scheduleToClose !== void 0 && this.clock - attempt.scheduledAt > attempt.scheduleToClose) {
|
|
621
1016
|
this.append(run, {
|
|
622
1017
|
type: "ACTIVITY_TIMED_OUT",
|
|
@@ -631,9 +1026,10 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
631
1026
|
const mock = this.mocks.get(`${attempt.nodeType}#${attempt.operation}`) ?? this.mocks.get(attempt.nodeType);
|
|
632
1027
|
let failure;
|
|
633
1028
|
let result = null;
|
|
1029
|
+
let heartbeatDetails = attempt.heartbeatDetails;
|
|
634
1030
|
try {
|
|
635
1031
|
if (!mock)
|
|
636
|
-
throw new
|
|
1032
|
+
throw new chunkELL2RBML_cjs.ApplicationError(
|
|
637
1033
|
`No mock for ${attempt.nodeType} ${attempt.operation} (use env.mock)`,
|
|
638
1034
|
{
|
|
639
1035
|
errorType: "VALIDATION",
|
|
@@ -648,14 +1044,18 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
648
1044
|
attempt: attempt.attempt,
|
|
649
1045
|
nodeType: attempt.nodeType,
|
|
650
1046
|
operation: attempt.operation,
|
|
651
|
-
...attempt.connection !== void 0 ? { connection: attempt.connection } : {}
|
|
1047
|
+
...attempt.connection !== void 0 ? { connection: attempt.connection } : {},
|
|
1048
|
+
...attempt.heartbeatDetails !== void 0 ? { heartbeatDetails: attempt.heartbeatDetails } : {},
|
|
1049
|
+
heartbeat: (details) => {
|
|
1050
|
+
heartbeatDetails = toJsonValue(details);
|
|
1051
|
+
}
|
|
652
1052
|
})
|
|
653
1053
|
);
|
|
654
1054
|
} catch (error) {
|
|
655
|
-
failure =
|
|
1055
|
+
failure = chunkELL2RBML_cjs.errorToFailure(error, `node:${attempt.nodeType}`);
|
|
656
1056
|
delete failure.stackTrace;
|
|
657
1057
|
}
|
|
658
|
-
if (run.state.status !== "RUNNING" || !
|
|
1058
|
+
if (run.state.status !== "RUNNING" || !chunkRUQIMTN5_cjs.isActivityOpen(run.state.activities[attempt.activityId] ?? activity))
|
|
659
1059
|
return;
|
|
660
1060
|
const started = () => {
|
|
661
1061
|
this.append(run, {
|
|
@@ -672,7 +1072,7 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
672
1072
|
return;
|
|
673
1073
|
}
|
|
674
1074
|
if (failure.timeoutType !== void 0 || failure.type === "TimeoutFailure") {
|
|
675
|
-
const decision2 =
|
|
1075
|
+
const decision2 = chunkYHBVMOMK_cjs.computeRetryDelay(attempt.retry, attempt.attempt, failure);
|
|
676
1076
|
if (!decision2.retry) {
|
|
677
1077
|
started();
|
|
678
1078
|
this.append(run, {
|
|
@@ -689,16 +1089,18 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
689
1089
|
this.attempts.push({
|
|
690
1090
|
...attempt,
|
|
691
1091
|
attempt: attempt.attempt + 1,
|
|
692
|
-
dueAt: this.clock + decision2.delayMs
|
|
1092
|
+
dueAt: this.clock + decision2.delayMs,
|
|
1093
|
+
...heartbeatDetails !== void 0 ? { heartbeatDetails } : {}
|
|
693
1094
|
});
|
|
694
1095
|
return;
|
|
695
1096
|
}
|
|
696
|
-
const decision =
|
|
1097
|
+
const decision = chunkYHBVMOMK_cjs.computeRetryDelay(attempt.retry, attempt.attempt, failure);
|
|
697
1098
|
if (decision.retry) {
|
|
698
1099
|
this.attempts.push({
|
|
699
1100
|
...attempt,
|
|
700
1101
|
attempt: attempt.attempt + 1,
|
|
701
|
-
dueAt: this.clock + decision.delayMs
|
|
1102
|
+
dueAt: this.clock + decision.delayMs,
|
|
1103
|
+
...heartbeatDetails !== void 0 ? { heartbeatDetails } : {}
|
|
702
1104
|
});
|
|
703
1105
|
return;
|
|
704
1106
|
}
|
|
@@ -712,12 +1114,34 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
712
1114
|
}
|
|
713
1115
|
});
|
|
714
1116
|
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Run-level retry (11 §2.17): a failed or run-timed-out run whose policy
|
|
1119
|
+
* allows another attempt is followed by a new run of the chain after the
|
|
1120
|
+
* backoff, with `runAttempt + 1` and the failure as `lastFailure`.
|
|
1121
|
+
*/
|
|
1122
|
+
retryRun(run) {
|
|
1123
|
+
if (run.continuedTo !== void 0) return;
|
|
1124
|
+
const last = run.history[run.history.length - 1];
|
|
1125
|
+
if (!last || last.type !== "WORKFLOW_FAILED" && last.type !== "WORKFLOW_TIMED_OUT") return;
|
|
1126
|
+
const failure = last.payload["failure"] ?? { errorType: "TIMEOUT", message: "timed out", timeoutType: "WORKFLOW_RUN" };
|
|
1127
|
+
const decision = chunkYHBVMOMK_cjs.computeRunRetryDelay(run.config.retry, run.config.runAttempt, failure);
|
|
1128
|
+
if (!decision.retry) return;
|
|
1129
|
+
const config = {
|
|
1130
|
+
...this.chainConfig(run.config),
|
|
1131
|
+
runAttempt: run.config.runAttempt + 1,
|
|
1132
|
+
lastFailure: failure
|
|
1133
|
+
};
|
|
1134
|
+
if (decision.delayMs > 0) config.firstTaskDelayMs = decision.delayMs;
|
|
1135
|
+
this.startSuccessor(run, run.state.input ?? null, config);
|
|
1136
|
+
}
|
|
715
1137
|
onClosed(run) {
|
|
716
1138
|
this.timers = this.timers.filter((timer) => timer.runId !== run.runId);
|
|
717
1139
|
this.attempts = this.attempts.filter((entry) => entry.runId !== run.runId);
|
|
1140
|
+
this.dues = this.dues.filter((entry) => entry.runId !== run.runId);
|
|
1141
|
+
this.retryRun(run);
|
|
718
1142
|
for (const [childId2, childRunId] of run.children) {
|
|
719
1143
|
const child = run.state.children[childId2];
|
|
720
|
-
if (!child || !
|
|
1144
|
+
if (!child || !chunkRUQIMTN5_cjs.isChildOpen(child) || childRunId === void 0) continue;
|
|
721
1145
|
if (child.parentClosePolicy === "TERMINATE") this.terminate(childRunId, "parent closed");
|
|
722
1146
|
else if (child.parentClosePolicy === "REQUEST_CANCEL")
|
|
723
1147
|
this.requestCancel(childRunId, "parent closed");
|
|
@@ -726,7 +1150,7 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
726
1150
|
const parent = this.runs.get(run.parent.runId);
|
|
727
1151
|
if (!parent || parent.state.status !== "RUNNING") return;
|
|
728
1152
|
const childId = run.parent.childId;
|
|
729
|
-
if (!parent.state.children[childId] || !
|
|
1153
|
+
if (!parent.state.children[childId] || !chunkRUQIMTN5_cjs.isChildOpen(parent.state.children[childId])) return;
|
|
730
1154
|
const last = run.history[run.history.length - 1];
|
|
731
1155
|
if (!last) return;
|
|
732
1156
|
if (run.continuedTo !== void 0) {
|
|
@@ -769,7 +1193,10 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
769
1193
|
default:
|
|
770
1194
|
this.append(parent, {
|
|
771
1195
|
type: "CHILD_RUN_TIMED_OUT",
|
|
772
|
-
payload: {
|
|
1196
|
+
payload: {
|
|
1197
|
+
...base,
|
|
1198
|
+
timeoutType: last.payload["timeoutType"] === "WORKFLOW_EXECUTION" ? "WORKFLOW_EXECUTION" : "WORKFLOW_RUN"
|
|
1199
|
+
}
|
|
773
1200
|
});
|
|
774
1201
|
}
|
|
775
1202
|
}
|
|
@@ -778,17 +1205,28 @@ var TestWorkflowEnvironment = class _TestWorkflowEnvironment {
|
|
|
778
1205
|
let run = this.run(runId);
|
|
779
1206
|
while (run.continuedTo !== void 0) run = this.run(run.continuedTo);
|
|
780
1207
|
if (run.taskFailure) throw new WorkflowTaskFailedError(run.runId, run.taskFailure);
|
|
1208
|
+
if (this.failOnUnfinishedHandlers && run.unfinishedHandlers !== void 0)
|
|
1209
|
+
throw new UnfinishedHandlersError(run.runId, run.unfinishedHandlers);
|
|
781
1210
|
const last = run.history[run.history.length - 1];
|
|
782
1211
|
switch (run.state.status) {
|
|
783
1212
|
case "COMPLETED":
|
|
784
1213
|
return run.state.output ?? null;
|
|
1214
|
+
case "TIMED_OUT":
|
|
1215
|
+
throw new WorkflowFailedError(
|
|
1216
|
+
run.runId,
|
|
1217
|
+
last?.payload["failure"] ?? {
|
|
1218
|
+
errorType: "TIMEOUT",
|
|
1219
|
+
message: "timed out",
|
|
1220
|
+
type: "TimeoutFailure"
|
|
1221
|
+
}
|
|
1222
|
+
);
|
|
785
1223
|
case "FAILED":
|
|
786
1224
|
throw new WorkflowFailedError(
|
|
787
1225
|
run.runId,
|
|
788
1226
|
run.state.failure ?? { errorType: "UNKNOWN", message: "failed" }
|
|
789
1227
|
);
|
|
790
1228
|
case "CANCELLED":
|
|
791
|
-
throw new
|
|
1229
|
+
throw new chunkELL2RBML_cjs.CancelledFailure(`Run ${run.runId} was cancelled`);
|
|
792
1230
|
case "TERMINATED":
|
|
793
1231
|
throw new WorkflowFailedError(run.runId, {
|
|
794
1232
|
errorType: "PERMANENT",
|
|
@@ -819,7 +1257,7 @@ var ReplayError = class extends Error {
|
|
|
819
1257
|
function replayRequest(workflowFn, history, info = {}, nowMs) {
|
|
820
1258
|
const last = history[history.length - 1];
|
|
821
1259
|
return {
|
|
822
|
-
protocol:
|
|
1260
|
+
protocol: chunk3FIDHONL_cjs.HISTORY_PROTOCOL,
|
|
823
1261
|
kind: "verify",
|
|
824
1262
|
workflowFn,
|
|
825
1263
|
info: { runId: "replay", workspaceId: "replay", ...info },
|
|
@@ -829,14 +1267,14 @@ function replayRequest(workflowFn, history, info = {}, nowMs) {
|
|
|
829
1267
|
}
|
|
830
1268
|
function eventsOf(input) {
|
|
831
1269
|
if (Array.isArray(input)) return { events: input };
|
|
832
|
-
const file = typeof input === "string" ?
|
|
1270
|
+
const file = typeof input === "string" ? chunkI47EENR4_cjs.parseHistoryFile(input) : input;
|
|
833
1271
|
return { events: file.events, file };
|
|
834
1272
|
}
|
|
835
1273
|
async function replay(workflows, input, options = {}) {
|
|
836
1274
|
const { events, file } = eventsOf(input);
|
|
837
1275
|
const started = events[0]?.type === "WORKFLOW_STARTED" ? events[0].payload["workflowFn"] : void 0;
|
|
838
1276
|
const recordedFn = options.workflowFn ?? file?.workflowFn ?? (typeof started === "string" ? started : void 0);
|
|
839
|
-
const map =
|
|
1277
|
+
const map = chunkJ3PYFGKA_cjs.isDurableWorkflow(workflows) ? { [recordedFn ?? workflows.name]: workflows } : { ...workflows };
|
|
840
1278
|
const workflowFn = recordedFn ?? Object.keys(map)[0] ?? "";
|
|
841
1279
|
const result = await runWorkflowTaskInProcess(
|
|
842
1280
|
registryOf(map),
|
|
@@ -849,7 +1287,7 @@ async function replay(workflows, input, options = {}) {
|
|
|
849
1287
|
);
|
|
850
1288
|
if (result.outcome === "failed") {
|
|
851
1289
|
if (result.failure?.cause === "NON_DETERMINISM")
|
|
852
|
-
throw new
|
|
1290
|
+
throw new chunkELL2RBML_cjs.DeterminismViolation(result.failure.message);
|
|
853
1291
|
throw new ReplayError(result);
|
|
854
1292
|
}
|
|
855
1293
|
return result;
|
|
@@ -898,7 +1336,7 @@ function assertHistory(history, expected, options = {}) {
|
|
|
898
1336
|
);
|
|
899
1337
|
}
|
|
900
1338
|
function definitionOf(value) {
|
|
901
|
-
return chunkGBQ33SIZ_cjs.normalizeDefinition(
|
|
1339
|
+
return chunkGBQ33SIZ_cjs.normalizeDefinition(chunkNXFBVDOI_cjs.isTier1Workflow(value) ? chunkNXFBVDOI_cjs.toIR(value) : value);
|
|
902
1340
|
}
|
|
903
1341
|
function expectIR(value) {
|
|
904
1342
|
const definition = definitionOf(value);
|
|
@@ -1018,22 +1456,22 @@ async function runWorkflowTaskInVm(script, request, options = {}) {
|
|
|
1018
1456
|
await settle();
|
|
1019
1457
|
if (step !== "more") break;
|
|
1020
1458
|
if (Date.now() > deadline)
|
|
1021
|
-
return
|
|
1459
|
+
return chunkEWYADREB_cjs.failedTaskResult(
|
|
1022
1460
|
"TASK_TIMEOUT",
|
|
1023
1461
|
`The workflow task ran past its ${timeout} ms budget`
|
|
1024
1462
|
);
|
|
1025
1463
|
}
|
|
1026
1464
|
const json = run("globalThis.__fluidgridsRuntime.complete()", "complete.js");
|
|
1027
1465
|
if (typeof json !== "string")
|
|
1028
|
-
return
|
|
1466
|
+
return chunkEWYADREB_cjs.failedTaskResult("INTERNAL", "The runtime returned no result");
|
|
1029
1467
|
return JSON.parse(json);
|
|
1030
1468
|
} catch (error) {
|
|
1031
1469
|
const fields = typeof error === "object" && error !== null ? error : {};
|
|
1032
1470
|
const message = typeof fields.message === "string" ? fields.message : String(error);
|
|
1033
1471
|
const name = typeof fields.name === "string" ? fields.name : "";
|
|
1034
|
-
if (/timed out/i.test(message)) return
|
|
1035
|
-
if (name === "DeterminismViolation") return
|
|
1036
|
-
return
|
|
1472
|
+
if (/timed out/i.test(message)) return chunkEWYADREB_cjs.failedTaskResult("TASK_TIMEOUT", message);
|
|
1473
|
+
if (name === "DeterminismViolation") return chunkEWYADREB_cjs.failedTaskResult("NON_DETERMINISM", message);
|
|
1474
|
+
return chunkEWYADREB_cjs.failedTaskResult("WORKFLOW_CODE_ERROR", `${name || "Error"}: ${message}`);
|
|
1037
1475
|
}
|
|
1038
1476
|
}
|
|
1039
1477
|
|
|
@@ -1042,6 +1480,8 @@ exports.ReplayError = ReplayError;
|
|
|
1042
1480
|
exports.RunBlockedError = RunBlockedError;
|
|
1043
1481
|
exports.TestRunHandle = TestRunHandle;
|
|
1044
1482
|
exports.TestWorkflowEnvironment = TestWorkflowEnvironment;
|
|
1483
|
+
exports.UnfinishedHandlersError = UnfinishedHandlersError;
|
|
1484
|
+
exports.WorkflowAlreadyStartedError = WorkflowAlreadyStartedError;
|
|
1045
1485
|
exports.WorkflowFailedError = WorkflowFailedError;
|
|
1046
1486
|
exports.WorkflowTaskFailedError = WorkflowTaskFailedError;
|
|
1047
1487
|
exports.assertHistory = assertHistory;
|