@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.
- package/README.md +181 -11
- package/dist/{activation-BBh1p82z.d.cts → activation-DqUfpHzk.d.cts} +1 -1
- package/dist/{activation-DnhG7SmF.d.ts → activation-xpx1oWuo.d.ts} +1 -1
- package/dist/{chunk-VRHHBPT6.js → chunk-2D3MYIIF.js} +1212 -128
- package/dist/chunk-3U2NU7YC.cjs +124 -0
- package/dist/{chunk-NEIUQASE.cjs → chunk-4QKB4ARC.cjs} +3 -3
- package/dist/{chunk-GBQ33SIZ.cjs → chunk-54FLQNUM.cjs} +12 -1
- package/dist/chunk-5HIVIV53.js +330 -0
- package/dist/chunk-5MFVJM76.js +1222 -0
- package/dist/{chunk-JD2VQIDZ.cjs → chunk-672KMMBK.cjs} +2 -2
- package/dist/{chunk-C5OLWZ42.js → chunk-6A2FGSUS.js} +22 -14
- package/dist/{chunk-XKJA7KX3.js → chunk-6OLN6BMB.js} +52 -3
- package/dist/{chunk-6FSHT5IL.js → chunk-7EZIANC7.js} +1 -1
- package/dist/{chunk-2J6TF7YI.cjs → chunk-A5SXCA62.cjs} +10 -3
- package/dist/{chunk-BO6OVILK.js → chunk-AC6ZEXVR.js} +10 -4
- package/dist/{chunk-ABFZWYHT.js → chunk-AE5Q6ZAJ.js} +315 -50
- package/dist/chunk-C4F5KJTI.js +293 -0
- package/dist/{chunk-IISBRUWJ.js → chunk-G5H32GIG.js} +1 -1
- package/dist/chunk-GEQDGUGB.cjs +2719 -0
- package/dist/{chunk-XHXIDVEC.js → chunk-HCM7ZC7Q.js} +1 -1
- package/dist/chunk-HMZUGSMU.cjs +1554 -0
- package/dist/{chunk-SAOBPYYJ.cjs → chunk-IQPXHQQQ.cjs} +8 -4
- package/dist/{chunk-P6TA5EZT.cjs → chunk-ISOIA7NV.cjs} +335 -58
- package/dist/chunk-JSC75O5C.cjs +167 -0
- package/dist/chunk-M272AHEX.js +25 -0
- package/dist/{chunk-BD7ZPG53.js → chunk-NWQ5WRLE.js} +10 -2
- package/dist/chunk-ODZ2IAR2.cjs +1247 -0
- package/dist/chunk-Q4MWQNJK.cjs +28 -0
- package/dist/{chunk-HWJZVOG7.js → chunk-SR7TR5KX.js} +6 -2
- package/dist/{chunk-FEW3JBYA.cjs → chunk-TCTE7DX5.cjs} +3 -3
- package/dist/{chunk-623FVQSN.cjs → chunk-TYF56RGB.cjs} +123 -0
- package/dist/chunk-VA4OFR72.cjs +324 -0
- package/dist/chunk-VU5S5A7V.js +150 -0
- package/dist/chunk-YEHR4NNE.js +1522 -0
- package/dist/{chunk-FMSW2HDF.cjs → chunk-ZCGKGDCL.cjs} +23 -15
- package/dist/codegen/index.d.cts +2 -2
- package/dist/codegen/index.d.ts +2 -2
- package/dist/collect-6NIEufHd.d.ts +103 -0
- package/dist/collect-CcTCKqx6.d.cts +103 -0
- package/dist/{file-BOoHZgoQ.d.cts → file-BxYpwjRQ.d.cts} +1007 -21
- package/dist/{file-yuPCFU5b.d.ts → file-CFdPQJI9.d.ts} +1007 -21
- package/dist/history/index.cjs +375 -86
- package/dist/history/index.d.cts +590 -12
- package/dist/history/index.d.ts +590 -12
- package/dist/history/index.js +50 -4
- package/dist/index.cjs +156 -50
- package/dist/index.d.cts +38 -58
- package/dist/index.d.ts +38 -58
- package/dist/index.js +6 -4
- package/dist/interceptors-CNcr2dlk.d.ts +159 -0
- package/dist/interceptors-CqkNZVfI.d.cts +159 -0
- package/dist/ir/index.cjs +362 -38
- package/dist/ir/index.d.cts +282 -7
- package/dist/ir/index.d.ts +282 -7
- package/dist/ir/index.js +329 -23
- package/dist/{lower-BzmUz0sq.d.cts → lower-BtRfIW2A.d.cts} +56 -8
- package/dist/{lower-_-iT4HYs.d.ts → lower-CpsMFOFX.d.ts} +56 -8
- package/dist/{manifest-C8N6HDYl.d.ts → manifest-D-I_twys.d.ts} +1 -1
- package/dist/{manifest-0OLw0i7k.d.cts → manifest-DahBQVM8.d.cts} +1 -1
- package/dist/node-evaluator-DGQDPSPI.cjs +24 -0
- package/dist/node-evaluator-LEEVD7H7.js +14 -0
- package/dist/payload-fields-BVRQn2yH.d.cts +122 -0
- package/dist/payload-fields-oOBWxDiG.d.ts +122 -0
- package/dist/quickjs/index.cjs +28 -27
- package/dist/quickjs/index.d.cts +6 -6
- package/dist/quickjs/index.d.ts +6 -6
- package/dist/quickjs/index.js +10 -9
- package/dist/roundtrip/index.cjs +259 -51
- package/dist/roundtrip/index.d.cts +100 -9
- package/dist/roundtrip/index.d.ts +100 -9
- package/dist/roundtrip/index.js +177 -11
- package/dist/runtime/index.cjs +21 -20
- package/dist/runtime/index.d.cts +184 -15
- package/dist/runtime/index.d.ts +184 -15
- package/dist/runtime/index.js +8 -7
- package/dist/testing/index.cjs +1122 -115
- package/dist/testing/index.d.cts +294 -13
- package/dist/testing/index.d.ts +294 -13
- package/dist/testing/index.js +1086 -84
- package/dist/{types-DV-HX_Gt.d.ts → types-Bv2i4cBX.d.cts} +244 -33
- package/dist/{types-CpBBjaGX.d.cts → types-DGx-b9eq.d.ts} +244 -33
- package/dist/{types-BGoPzgcl.d.ts → types-V7jEEUaL.d.cts} +20 -1
- package/dist/{types-BGoPzgcl.d.cts → types-V7jEEUaL.d.ts} +20 -1
- package/dist/{workflow-Bpr3vnA_.d.ts → workflow-B18OeF7g.d.ts} +2 -2
- package/dist/workflow-BGnv8SS6.d.ts +803 -0
- package/dist/{workflow-FXUkpIBc.d.cts → workflow-BJPFv3cp.d.cts} +2 -2
- package/dist/workflow-DS32Gtws.d.cts +803 -0
- package/fixtures/histories/activity-options-updated.history.json +159 -0
- package/fixtures/histories/activity-paused-unpaused.history.json +160 -0
- 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/codec-opaque.history.json +229 -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/dynamic-workflow.history.json +150 -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/interceptor-headers.history.json +339 -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/query-custom.history.json +213 -0
- package/fixtures/histories/query-default-handler.history.json +120 -0
- package/fixtures/histories/reset-forked-reapplied-signals.history.json +239 -0
- package/fixtures/histories/reset-reapplied-update-admitted.history.json +228 -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/search-attributes-upserted.history.json +177 -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/fixtures/histories/update-accepted-completed.history.json +45 -30
- package/fixtures/histories/update-default-handler.history.json +246 -0
- package/fixtures/histories/update-handler-awaits-activity.history.json +196 -0
- package/fixtures/histories/update-not-handled.history.json +138 -0
- package/fixtures/histories/update-rejected-no-event.history.json +190 -0
- package/fixtures/histories/update-with-start-admitted.history.json +150 -0
- package/fixtures/histories/user-activity-cancel.history.json +149 -0
- package/fixtures/histories/user-activity-retry.history.json +143 -0
- package/fixtures/histories/user-activity.history.json +149 -0
- package/package.json +1 -1
- package/schema/bridge-v2.schema.json +1062 -0
- package/schema/history-file.schema.json +538 -83
- package/schema/ir-v2.schema.json +290 -0
- package/schema/payload-fields.json +162 -0
- package/schema/run-event.schema.json +503 -82
- package/schema/workflow-command.schema.json +372 -69
- package/schema/workflow-task.schema.json +924 -171
- package/dist/assemble-BLqQ8lSu.d.cts +0 -39
- package/dist/assemble-DWgaXHd-.d.ts +0 -39
- package/dist/chunk-DHTLALBL.cjs +0 -80
- package/dist/chunk-DJYMDLV5.js +0 -227
- package/dist/chunk-I5LR3D2K.js +0 -869
- package/dist/chunk-M4BBAERY.cjs +0 -1635
- package/dist/chunk-N23SKIG4.js +0 -73
- package/dist/chunk-PZCVF76Q.cjs +0 -868
- package/dist/chunk-QQ6ULXHI.cjs +0 -885
- package/dist/chunk-UK3WM7YZ.cjs +0 -75
- package/dist/chunk-VOKMAAJP.js +0 -848
- package/dist/node-evaluator-4MSDKWOG.cjs +0 -22
- package/dist/node-evaluator-SX4LEYQC.js +0 -12
- package/dist/workflow-C2a05WUJ.d.ts +0 -444
- 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;
|