@fluidgrids/workflows 2026.1029.1 → 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 +112 -4
- package/dist/{activation-CESehfYi.d.cts → activation-DqUfpHzk.d.cts} +1 -1
- package/dist/{activation-BnVQMv9y.d.ts → activation-xpx1oWuo.d.ts} +1 -1
- package/dist/{chunk-MJ5TGYVG.js → chunk-2D3MYIIF.js} +969 -153
- package/dist/{chunk-2B37XAFQ.cjs → chunk-3U2NU7YC.cjs} +24 -11
- package/dist/{chunk-NEIUQASE.cjs → chunk-4QKB4ARC.cjs} +3 -3
- package/dist/{chunk-GBQ33SIZ.cjs → chunk-54FLQNUM.cjs} +12 -1
- package/dist/{chunk-2DDULZFM.js → chunk-5HIVIV53.js} +86 -75
- package/dist/chunk-5MFVJM76.js +1222 -0
- package/dist/{chunk-EWYADREB.cjs → chunk-672KMMBK.cjs} +2 -2
- package/dist/{chunk-KXJDRQ6G.js → chunk-6A2FGSUS.js} +22 -2
- package/dist/{chunk-OIX4O6UR.js → chunk-6OLN6BMB.js} +16 -3
- package/dist/{chunk-6FSHT5IL.js → chunk-7EZIANC7.js} +1 -1
- package/dist/chunk-A5SXCA62.cjs +93 -0
- package/dist/chunk-AC6ZEXVR.js +85 -0
- package/dist/{chunk-FWBRQWRX.js → chunk-AE5Q6ZAJ.js} +167 -10
- package/dist/{chunk-7ILGCUI6.js → chunk-C4F5KJTI.js} +142 -3
- package/dist/{chunk-WXXNCHUY.js → chunk-G5H32GIG.js} +1 -1
- package/dist/{chunk-OMY3CKUZ.cjs → chunk-GEQDGUGB.cjs} +1042 -226
- package/dist/{chunk-25BKWR2O.js → chunk-HCM7ZC7Q.js} +1 -1
- package/dist/{chunk-I47EENR4.cjs → chunk-HMZUGSMU.cjs} +673 -156
- package/dist/{chunk-NXFBVDOI.cjs → chunk-IQPXHQQQ.cjs} +8 -4
- package/dist/{chunk-RUQIMTN5.cjs → chunk-ISOIA7NV.cjs} +178 -15
- package/dist/chunk-JSC75O5C.cjs +167 -0
- package/dist/{chunk-BD7ZPG53.js → chunk-NWQ5WRLE.js} +10 -2
- package/dist/chunk-ODZ2IAR2.cjs +1247 -0
- package/dist/{chunk-FQSJI5NV.js → chunk-SR7TR5KX.js} +6 -2
- package/dist/{chunk-OKX3FYIM.cjs → chunk-TCTE7DX5.cjs} +3 -3
- package/dist/{chunk-3FIDHONL.cjs → chunk-TYF56RGB.cjs} +99 -80
- package/dist/{chunk-J3PYFGKA.cjs → chunk-VA4OFR72.cjs} +162 -4
- package/dist/chunk-VU5S5A7V.js +150 -0
- package/dist/{chunk-A36CCOWS.js → chunk-YEHR4NNE.js} +633 -128
- package/dist/{chunk-ELL2RBML.cjs → chunk-ZCGKGDCL.cjs} +23 -1
- package/dist/codegen/index.d.cts +2 -2
- package/dist/codegen/index.d.ts +2 -2
- package/dist/{collect-BTHjQaSp.d.ts → collect-6NIEufHd.d.ts} +20 -3
- package/dist/{collect-CSyOg5XC.d.cts → collect-CcTCKqx6.d.cts} +20 -3
- package/dist/{file-cgL9l9l8.d.cts → file-BxYpwjRQ.d.cts} +250 -15
- package/dist/{file-olQudcx5.d.ts → file-CFdPQJI9.d.ts} +250 -15
- package/dist/history/index.cjs +283 -106
- package/dist/history/index.d.cts +549 -10
- package/dist/history/index.d.ts +549 -10
- package/dist/history/index.js +5 -4
- package/dist/index.cjs +146 -53
- package/dist/index.d.cts +38 -14
- package/dist/index.d.ts +38 -14
- package/dist/index.js +6 -5
- package/dist/interceptors-CNcr2dlk.d.ts +159 -0
- package/dist/interceptors-CqkNZVfI.d.cts +159 -0
- package/dist/ir/index.cjs +339 -36
- package/dist/ir/index.d.cts +244 -8
- package/dist/ir/index.d.ts +244 -8
- package/dist/ir/index.js +306 -21
- package/dist/{lower-3S6PsqjJ.d.cts → lower-BtRfIW2A.d.cts} +23 -9
- package/dist/{lower-DmZpQ8hJ.d.ts → lower-CpsMFOFX.d.ts} +23 -9
- package/dist/{manifest-BJjrQt77.d.ts → manifest-D-I_twys.d.ts} +1 -1
- package/dist/{manifest-gRI2Q5Fj.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 +27 -27
- package/dist/quickjs/index.d.cts +6 -6
- package/dist/quickjs/index.d.ts +6 -6
- package/dist/quickjs/index.js +9 -9
- package/dist/roundtrip/index.cjs +72 -66
- package/dist/roundtrip/index.d.cts +25 -11
- package/dist/roundtrip/index.d.ts +25 -11
- package/dist/roundtrip/index.js +13 -11
- package/dist/runtime/index.cjs +19 -19
- package/dist/runtime/index.d.cts +139 -12
- package/dist/runtime/index.d.ts +139 -12
- package/dist/runtime/index.js +6 -6
- package/dist/testing/index.cjs +688 -121
- package/dist/testing/index.d.cts +174 -10
- package/dist/testing/index.d.ts +174 -10
- package/dist/testing/index.js +646 -82
- package/dist/{types-CnIOinoz.d.ts → types-Bv2i4cBX.d.cts} +126 -23
- package/dist/{types-CQKOhPTa.d.cts → types-DGx-b9eq.d.ts} +126 -23
- package/dist/{types-Bb2wRnJ5.d.cts → types-V7jEEUaL.d.cts} +1 -1
- package/dist/{types-Bb2wRnJ5.d.ts → types-V7jEEUaL.d.ts} +1 -1
- package/dist/{workflow-8uRU9rhL.d.ts → workflow-B18OeF7g.d.ts} +2 -2
- package/dist/{workflow-DWTPHFbt.d.ts → workflow-BGnv8SS6.d.ts} +261 -14
- package/dist/{workflow-CZOXUlQ5.d.cts → workflow-BJPFv3cp.d.cts} +2 -2
- package/dist/{workflow-O6e64ZcG.d.cts → workflow-DS32Gtws.d.cts} +261 -14
- package/fixtures/histories/activity-options-updated.history.json +159 -0
- package/fixtures/histories/activity-paused-unpaused.history.json +160 -0
- package/fixtures/histories/codec-opaque.history.json +229 -0
- package/fixtures/histories/dynamic-workflow.history.json +150 -0
- package/fixtures/histories/interceptor-headers.history.json +339 -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/search-attributes-upserted.history.json +177 -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 +255 -81
- package/schema/ir-v2.schema.json +246 -1
- package/schema/payload-fields.json +162 -0
- package/schema/run-event.schema.json +239 -80
- package/schema/workflow-command.schema.json +210 -84
- package/schema/workflow-task.schema.json +532 -167
- package/dist/chunk-6QPOJZT6.cjs +0 -1180
- package/dist/chunk-A2OHX3UQ.js +0 -1156
- package/dist/chunk-PWIUEWC3.js +0 -81
- package/dist/chunk-YHBVMOMK.cjs +0 -87
- package/dist/node-evaluator-SOADN23V.js +0 -14
- package/dist/node-evaluator-YGDEXK4U.cjs +0 -24
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkTYF56RGB_cjs = require('./chunk-TYF56RGB.cjs');
|
|
4
4
|
|
|
5
5
|
function failedTaskResult(cause, message) {
|
|
6
6
|
return {
|
|
7
|
-
protocol:
|
|
7
|
+
protocol: chunkTYF56RGB_cjs.HISTORY_PROTOCOL,
|
|
8
8
|
outcome: "failed",
|
|
9
9
|
commands: [],
|
|
10
10
|
failure: { cause, message },
|
|
@@ -82,16 +82,36 @@ var ApplicationError = class extends WorkflowFailure {
|
|
|
82
82
|
}
|
|
83
83
|
};
|
|
84
84
|
var ActivityFailure = class extends WorkflowFailure {
|
|
85
|
-
constructor(message, activityId, nodeType, operation, cause) {
|
|
85
|
+
constructor(message, activityId, nodeType, operation, cause, activityName) {
|
|
86
86
|
super(message, cause instanceof WorkflowFailure ? cause.errorType : "UNKNOWN", { cause });
|
|
87
87
|
this.activityId = activityId;
|
|
88
88
|
this.nodeType = nodeType;
|
|
89
89
|
this.operation = operation;
|
|
90
|
+
this.activityName = activityName;
|
|
90
91
|
this.name = "ActivityFailure";
|
|
91
92
|
}
|
|
92
93
|
activityId;
|
|
93
94
|
nodeType;
|
|
94
95
|
operation;
|
|
96
|
+
activityName;
|
|
97
|
+
};
|
|
98
|
+
var ActivityPausedError = class extends ApplicationError {
|
|
99
|
+
constructor(message = "The activity was paused", details) {
|
|
100
|
+
super(message, {
|
|
101
|
+
type: "ActivityPausedError",
|
|
102
|
+
errorType: "TRANSIENT",
|
|
103
|
+
...details !== void 0 ? { details } : {}
|
|
104
|
+
});
|
|
105
|
+
this.name = "ActivityPausedError";
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
var QueryHandlerSideEffect = class extends Error {
|
|
109
|
+
constructor(what) {
|
|
110
|
+
super(
|
|
111
|
+
`${what} is not allowed in a query handler or an update validator; they must not change the run`
|
|
112
|
+
);
|
|
113
|
+
this.name = "QueryHandlerSideEffect";
|
|
114
|
+
}
|
|
95
115
|
};
|
|
96
116
|
var ChildRunFailure = class extends WorkflowFailure {
|
|
97
117
|
constructor(message, childId, childRunId, cause) {
|
|
@@ -230,4 +250,4 @@ function failureToError(failure, depth = 0) {
|
|
|
230
250
|
return error;
|
|
231
251
|
}
|
|
232
252
|
|
|
233
|
-
export { ActivityFailure, ApplicationError, CancelledFailure, ChildRunFailure, DeterminismViolation, HistoryLimitExceeded, PhaseCFeatureError, ServerFailure, TerminatedFailure, TimeoutFailure, WorkflowFailure, defineQuery, defineSignal, defineUpdate, errorToFailure, failureToError, isCancellation, isRunFailure, signalName };
|
|
253
|
+
export { ActivityFailure, ActivityPausedError, ApplicationError, CancelledFailure, ChildRunFailure, DeterminismViolation, HistoryLimitExceeded, PhaseCFeatureError, QueryHandlerSideEffect, ServerFailure, TerminatedFailure, TimeoutFailure, WorkflowFailure, defineQuery, defineSignal, defineUpdate, errorToFailure, failureToError, isCancellation, isRunFailure, signalName };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { isTier1Workflow, isOperation } from './chunk-
|
|
1
|
+
import { isTier1Workflow, isOperation } from './chunk-SR7TR5KX.js';
|
|
2
2
|
import { BuilderError } from './chunk-JZ4TOOLN.js';
|
|
3
3
|
import { isRecord, setOwn } from './chunk-PMCM2OH4.js';
|
|
4
|
-
import { isDurableWorkflow, interfaceOf, toMs } from './chunk-
|
|
4
|
+
import { isActivityImplementation, isDurableWorkflow, interfaceOf, toMs } from './chunk-C4F5KJTI.js';
|
|
5
5
|
|
|
6
6
|
// src/builder/collect.ts
|
|
7
7
|
var COLLECTION_FORMAT = "fluidgrids.tier1-collection";
|
|
@@ -55,9 +55,16 @@ function triggerOf(spec, where) {
|
|
|
55
55
|
function collectWorkflowExports(modules) {
|
|
56
56
|
const exportNames = /* @__PURE__ */ new Map();
|
|
57
57
|
const durable = [];
|
|
58
|
+
const implementations = [];
|
|
59
|
+
const interceptorModules = [];
|
|
58
60
|
for (const [module, namespace] of modules) {
|
|
61
|
+
if (Object.hasOwn(namespace, "interceptors")) interceptorModules.push(module);
|
|
59
62
|
for (const exportName of Object.keys(namespace).sort()) {
|
|
60
63
|
const value = namespace[exportName];
|
|
64
|
+
if (isActivityImplementation(value)) {
|
|
65
|
+
implementations.push({ module, exportName, name: value.name });
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
61
68
|
if (!isDurableWorkflow(value) || exportNames.has(value)) continue;
|
|
62
69
|
exportNames.set(value, exportName);
|
|
63
70
|
const options = value.options;
|
|
@@ -74,6 +81,10 @@ function collectWorkflowExports(modules) {
|
|
|
74
81
|
const trigger = triggerOf(options.trigger, `workflow("${value.name}")`);
|
|
75
82
|
if (trigger) entry.trigger = trigger;
|
|
76
83
|
const settings = runSettingsOf(options);
|
|
84
|
+
if (value.dynamic === true) {
|
|
85
|
+
entry.dynamic = true;
|
|
86
|
+
settings.features.push("dynamic");
|
|
87
|
+
}
|
|
77
88
|
if (Object.keys(settings.config).length > 0) entry.config = settings.config;
|
|
78
89
|
if (settings.features.length > 0) entry.features = settings.features;
|
|
79
90
|
durable.push(entry);
|
|
@@ -100,7 +111,9 @@ function collectWorkflowExports(modules) {
|
|
|
100
111
|
const collection = {
|
|
101
112
|
format: COLLECTION_FORMAT,
|
|
102
113
|
workflows,
|
|
103
|
-
...durable.length > 0 ? { durable } : {}
|
|
114
|
+
...durable.length > 0 ? { durable } : {},
|
|
115
|
+
...implementations.length > 0 ? { activityImplementations: implementations } : {},
|
|
116
|
+
...interceptorModules.length > 0 ? { interceptorModules } : {}
|
|
104
117
|
};
|
|
105
118
|
return JSON.stringify(collection);
|
|
106
119
|
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/history/allowlist.ts
|
|
4
|
+
var ACTIVITY_INTERNAL_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
5
|
+
"internal:http",
|
|
6
|
+
"internal:datatable",
|
|
7
|
+
"internal:set",
|
|
8
|
+
"internal:code"
|
|
9
|
+
]);
|
|
10
|
+
var ACTIVITY_NODE_DENYLIST = /* @__PURE__ */ new Set([
|
|
11
|
+
"internal:end",
|
|
12
|
+
"internal:if",
|
|
13
|
+
"internal:switch",
|
|
14
|
+
"internal:loop",
|
|
15
|
+
"internal:merge",
|
|
16
|
+
"internal:wait",
|
|
17
|
+
"internal:subworkflow",
|
|
18
|
+
"internal:code-workflow",
|
|
19
|
+
"internal:wait-for-signal",
|
|
20
|
+
"internal:send-and-wait",
|
|
21
|
+
"internal:respond-to-webhook",
|
|
22
|
+
"internal:failure-triage"
|
|
23
|
+
]);
|
|
24
|
+
var ACTIVITY_NODE_ALLOWLIST = {
|
|
25
|
+
internal: ACTIVITY_INTERNAL_ALLOWLIST,
|
|
26
|
+
refused: ACTIVITY_NODE_DENYLIST,
|
|
27
|
+
/** Non-built-in node types (store and registry nodes) are allowed. */
|
|
28
|
+
external: "allowed"
|
|
29
|
+
};
|
|
30
|
+
var LEGACY_SHORT_NAMES = /* @__PURE__ */ new Set([
|
|
31
|
+
"if",
|
|
32
|
+
"switch",
|
|
33
|
+
"loop",
|
|
34
|
+
"merge",
|
|
35
|
+
"set",
|
|
36
|
+
"filter",
|
|
37
|
+
"aggregate",
|
|
38
|
+
"wait",
|
|
39
|
+
"noop",
|
|
40
|
+
"code",
|
|
41
|
+
"http",
|
|
42
|
+
"transform",
|
|
43
|
+
"validate",
|
|
44
|
+
"log",
|
|
45
|
+
"error",
|
|
46
|
+
"subworkflow",
|
|
47
|
+
"end",
|
|
48
|
+
"trigger",
|
|
49
|
+
"webhook",
|
|
50
|
+
"schedule",
|
|
51
|
+
"manual",
|
|
52
|
+
"api"
|
|
53
|
+
]);
|
|
54
|
+
function canonicalType(nodeType) {
|
|
55
|
+
const lower = nodeType.trim().toLowerCase();
|
|
56
|
+
return LEGACY_SHORT_NAMES.has(lower) ? `internal:${lower}` : lower;
|
|
57
|
+
}
|
|
58
|
+
var ACTIVITY_ASYNC_COMPLETION_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
59
|
+
"internal:send-and-wait"
|
|
60
|
+
]);
|
|
61
|
+
function isActivityNodeTypeAllowed(nodeType, options = {}) {
|
|
62
|
+
if (typeof nodeType !== "string" || nodeType.trim() === "") return false;
|
|
63
|
+
const type = canonicalType(nodeType);
|
|
64
|
+
if (!type.startsWith("internal:")) return true;
|
|
65
|
+
if (options.asyncCompletion === true && ACTIVITY_ASYNC_COMPLETION_ALLOWLIST.has(type))
|
|
66
|
+
return true;
|
|
67
|
+
return ACTIVITY_INTERNAL_ALLOWLIST.has(type);
|
|
68
|
+
}
|
|
69
|
+
var ActivityNodeTypeNotAllowedError = class extends Error {
|
|
70
|
+
constructor(nodeType) {
|
|
71
|
+
super(
|
|
72
|
+
`${nodeType} cannot run as a durable activity: only store and registry nodes and internal:http, internal:datatable, internal:set and internal:code can`
|
|
73
|
+
);
|
|
74
|
+
this.nodeType = nodeType;
|
|
75
|
+
this.name = "ActivityNodeTypeNotAllowedError";
|
|
76
|
+
}
|
|
77
|
+
nodeType;
|
|
78
|
+
code = "durable.activityTypeNotAllowed";
|
|
79
|
+
errorType = "VALIDATION";
|
|
80
|
+
nonRetryable = true;
|
|
81
|
+
};
|
|
82
|
+
function assertActivityNodeType(nodeType, options = {}) {
|
|
83
|
+
if (!isActivityNodeTypeAllowed(nodeType, options))
|
|
84
|
+
throw new ActivityNodeTypeNotAllowedError(nodeType);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
exports.ACTIVITY_ASYNC_COMPLETION_ALLOWLIST = ACTIVITY_ASYNC_COMPLETION_ALLOWLIST;
|
|
88
|
+
exports.ACTIVITY_INTERNAL_ALLOWLIST = ACTIVITY_INTERNAL_ALLOWLIST;
|
|
89
|
+
exports.ACTIVITY_NODE_ALLOWLIST = ACTIVITY_NODE_ALLOWLIST;
|
|
90
|
+
exports.ACTIVITY_NODE_DENYLIST = ACTIVITY_NODE_DENYLIST;
|
|
91
|
+
exports.ActivityNodeTypeNotAllowedError = ActivityNodeTypeNotAllowedError;
|
|
92
|
+
exports.assertActivityNodeType = assertActivityNodeType;
|
|
93
|
+
exports.isActivityNodeTypeAllowed = isActivityNodeTypeAllowed;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// src/history/allowlist.ts
|
|
2
|
+
var ACTIVITY_INTERNAL_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
3
|
+
"internal:http",
|
|
4
|
+
"internal:datatable",
|
|
5
|
+
"internal:set",
|
|
6
|
+
"internal:code"
|
|
7
|
+
]);
|
|
8
|
+
var ACTIVITY_NODE_DENYLIST = /* @__PURE__ */ new Set([
|
|
9
|
+
"internal:end",
|
|
10
|
+
"internal:if",
|
|
11
|
+
"internal:switch",
|
|
12
|
+
"internal:loop",
|
|
13
|
+
"internal:merge",
|
|
14
|
+
"internal:wait",
|
|
15
|
+
"internal:subworkflow",
|
|
16
|
+
"internal:code-workflow",
|
|
17
|
+
"internal:wait-for-signal",
|
|
18
|
+
"internal:send-and-wait",
|
|
19
|
+
"internal:respond-to-webhook",
|
|
20
|
+
"internal:failure-triage"
|
|
21
|
+
]);
|
|
22
|
+
var ACTIVITY_NODE_ALLOWLIST = {
|
|
23
|
+
internal: ACTIVITY_INTERNAL_ALLOWLIST,
|
|
24
|
+
refused: ACTIVITY_NODE_DENYLIST,
|
|
25
|
+
/** Non-built-in node types (store and registry nodes) are allowed. */
|
|
26
|
+
external: "allowed"
|
|
27
|
+
};
|
|
28
|
+
var LEGACY_SHORT_NAMES = /* @__PURE__ */ new Set([
|
|
29
|
+
"if",
|
|
30
|
+
"switch",
|
|
31
|
+
"loop",
|
|
32
|
+
"merge",
|
|
33
|
+
"set",
|
|
34
|
+
"filter",
|
|
35
|
+
"aggregate",
|
|
36
|
+
"wait",
|
|
37
|
+
"noop",
|
|
38
|
+
"code",
|
|
39
|
+
"http",
|
|
40
|
+
"transform",
|
|
41
|
+
"validate",
|
|
42
|
+
"log",
|
|
43
|
+
"error",
|
|
44
|
+
"subworkflow",
|
|
45
|
+
"end",
|
|
46
|
+
"trigger",
|
|
47
|
+
"webhook",
|
|
48
|
+
"schedule",
|
|
49
|
+
"manual",
|
|
50
|
+
"api"
|
|
51
|
+
]);
|
|
52
|
+
function canonicalType(nodeType) {
|
|
53
|
+
const lower = nodeType.trim().toLowerCase();
|
|
54
|
+
return LEGACY_SHORT_NAMES.has(lower) ? `internal:${lower}` : lower;
|
|
55
|
+
}
|
|
56
|
+
var ACTIVITY_ASYNC_COMPLETION_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
57
|
+
"internal:send-and-wait"
|
|
58
|
+
]);
|
|
59
|
+
function isActivityNodeTypeAllowed(nodeType, options = {}) {
|
|
60
|
+
if (typeof nodeType !== "string" || nodeType.trim() === "") return false;
|
|
61
|
+
const type = canonicalType(nodeType);
|
|
62
|
+
if (!type.startsWith("internal:")) return true;
|
|
63
|
+
if (options.asyncCompletion === true && ACTIVITY_ASYNC_COMPLETION_ALLOWLIST.has(type))
|
|
64
|
+
return true;
|
|
65
|
+
return ACTIVITY_INTERNAL_ALLOWLIST.has(type);
|
|
66
|
+
}
|
|
67
|
+
var ActivityNodeTypeNotAllowedError = class extends Error {
|
|
68
|
+
constructor(nodeType) {
|
|
69
|
+
super(
|
|
70
|
+
`${nodeType} cannot run as a durable activity: only store and registry nodes and internal:http, internal:datatable, internal:set and internal:code can`
|
|
71
|
+
);
|
|
72
|
+
this.nodeType = nodeType;
|
|
73
|
+
this.name = "ActivityNodeTypeNotAllowedError";
|
|
74
|
+
}
|
|
75
|
+
nodeType;
|
|
76
|
+
code = "durable.activityTypeNotAllowed";
|
|
77
|
+
errorType = "VALIDATION";
|
|
78
|
+
nonRetryable = true;
|
|
79
|
+
};
|
|
80
|
+
function assertActivityNodeType(nodeType, options = {}) {
|
|
81
|
+
if (!isActivityNodeTypeAllowed(nodeType, options))
|
|
82
|
+
throw new ActivityNodeTypeNotAllowedError(nodeType);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export { ACTIVITY_ASYNC_COMPLETION_ALLOWLIST, ACTIVITY_INTERNAL_ALLOWLIST, ACTIVITY_NODE_ALLOWLIST, ACTIVITY_NODE_DENYLIST, ActivityNodeTypeNotAllowedError, assertActivityNodeType, isActivityNodeTypeAllowed };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isActivityNodeTypeAllowed } from './chunk-AC6ZEXVR.js';
|
|
2
|
+
import { PHASE_C_COMMANDS, PHASE_B_CORE_COMMANDS, PHASE_B_PARITY_COMMANDS, TERMINAL_COMMANDS, isInputEvent, isCommandEvent } from './chunk-5HIVIV53.js';
|
|
2
3
|
|
|
3
4
|
// src/history/commands.ts
|
|
4
5
|
var COMMAND_FEATURES = [
|
|
@@ -29,6 +30,39 @@ var PHASE_B_PARITY_FEATURES = /* @__PURE__ */ new Set([
|
|
|
29
30
|
"parity.canOptions",
|
|
30
31
|
"parity.workflowIdTarget"
|
|
31
32
|
]);
|
|
33
|
+
var PHASE_C_FEATURES = [
|
|
34
|
+
"c.updates",
|
|
35
|
+
"c.searchAttributes",
|
|
36
|
+
"c.userActivity"
|
|
37
|
+
];
|
|
38
|
+
var PHASE_C_FEATURE_FLAGS = {
|
|
39
|
+
"c.updates": "fluidgrids.run-control",
|
|
40
|
+
"c.searchAttributes": "fluidgrids.search-attributes",
|
|
41
|
+
"c.userActivity": "fluidgrids.self-hosted-workers"
|
|
42
|
+
};
|
|
43
|
+
var CODE_FEATURE_FLAGS = {
|
|
44
|
+
localActivity: "fluidgrids.durable-parity",
|
|
45
|
+
externalCancel: "fluidgrids.durable-parity",
|
|
46
|
+
childOptions: "fluidgrids.durable-parity",
|
|
47
|
+
canOptions: "fluidgrids.durable-parity",
|
|
48
|
+
autoUpgrade: "fluidgrids.durable-parity",
|
|
49
|
+
runRetry: "fluidgrids.durable-parity",
|
|
50
|
+
timeouts: "fluidgrids.durable-parity",
|
|
51
|
+
userActivity: "fluidgrids.self-hosted-workers",
|
|
52
|
+
updates: "fluidgrids.run-control",
|
|
53
|
+
queries: "fluidgrids.run-control",
|
|
54
|
+
dynamic: "fluidgrids.run-control",
|
|
55
|
+
interceptors: "fluidgrids.run-control",
|
|
56
|
+
searchAttributes: "fluidgrids.search-attributes"
|
|
57
|
+
};
|
|
58
|
+
var PHASE_C_CODE_FEATURES = [
|
|
59
|
+
"userActivity",
|
|
60
|
+
"updates",
|
|
61
|
+
"queries",
|
|
62
|
+
"searchAttributes",
|
|
63
|
+
"dynamic",
|
|
64
|
+
"interceptors"
|
|
65
|
+
];
|
|
32
66
|
var CORE_CHILD_OPTIONS = /* @__PURE__ */ new Set([
|
|
33
67
|
"parentClosePolicy",
|
|
34
68
|
"cancellationType",
|
|
@@ -41,7 +75,9 @@ var CORE_CHILD_OPTIONS = /* @__PURE__ */ new Set([
|
|
|
41
75
|
"startDelay",
|
|
42
76
|
"executionTimeout",
|
|
43
77
|
"runTimeout",
|
|
44
|
-
"workflowTaskTimeout"
|
|
78
|
+
"workflowTaskTimeout",
|
|
79
|
+
"fairnessKey",
|
|
80
|
+
"fairnessWeight"
|
|
45
81
|
]);
|
|
46
82
|
var CORE_CAN_OPTIONS = /* @__PURE__ */ new Set([
|
|
47
83
|
"taskQueue",
|
|
@@ -68,6 +104,9 @@ function hasOtherKeys(value, allowed) {
|
|
|
68
104
|
function commandFeatures(command) {
|
|
69
105
|
const needed = /* @__PURE__ */ new Set();
|
|
70
106
|
switch (command.type) {
|
|
107
|
+
case "SCHEDULE_ACTIVITY":
|
|
108
|
+
needed.add(command.kind === "user" ? "c.userActivity" : "core");
|
|
109
|
+
break;
|
|
71
110
|
case "START_CHILD_RUN":
|
|
72
111
|
needed.add("core");
|
|
73
112
|
if (hasOtherKeys(command.options, CORE_CHILD_OPTIONS)) needed.add("parity.childOptions");
|
|
@@ -110,18 +149,40 @@ function isCommandEnabled(type, enabled = "core") {
|
|
|
110
149
|
if (PHASE_B_CORE_COMMANDS.has(type)) return true;
|
|
111
150
|
return enabled === "parity" && PHASE_B_PARITY_COMMANDS.has(type);
|
|
112
151
|
}
|
|
152
|
+
function phaseCFeaturesOf(command) {
|
|
153
|
+
return commandFeatures(command).filter((feature) => feature.startsWith("c."));
|
|
154
|
+
}
|
|
113
155
|
function isWorkflowCommandEnabled(command, enabled = "core") {
|
|
114
156
|
if (typeof enabled === "string") {
|
|
157
|
+
if (phaseCFeaturesOf(command).length > 0) return false;
|
|
115
158
|
if (command.type === "REQUEST_CANCEL_EXTERNAL_RUN" && "childId" in command.target) return true;
|
|
116
159
|
return isCommandEnabled(command.type, enabled);
|
|
117
160
|
}
|
|
118
161
|
return commandFeatures(command).every((feature) => enabled.has(feature));
|
|
119
162
|
}
|
|
163
|
+
function codeFeaturesEnabledBy(enabled) {
|
|
164
|
+
if (typeof enabled === "string") return [];
|
|
165
|
+
const flags = /* @__PURE__ */ new Set(["fluidgrids.durable-functions"]);
|
|
166
|
+
for (const feature of enabled) {
|
|
167
|
+
if (PHASE_B_PARITY_FEATURES.has(feature) && !PHASE_B_CORE_FEATURES.has(feature))
|
|
168
|
+
flags.add("fluidgrids.durable-parity");
|
|
169
|
+
const flag = PHASE_C_FEATURE_FLAGS[feature];
|
|
170
|
+
if (flag !== void 0) flags.add(flag);
|
|
171
|
+
}
|
|
172
|
+
return Object.keys(CODE_FEATURE_FLAGS).filter((feature) => flags.has(CODE_FEATURE_FLAGS[feature] ?? "")).sort();
|
|
173
|
+
}
|
|
120
174
|
function unsupportedMessage(command, enabled = "core") {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
175
|
+
const missing = typeof enabled === "string" ? phaseCFeaturesOf(command) : commandFeatures(command).filter((feature) => !enabled.has(feature));
|
|
176
|
+
if (missing.length === 0) return `${command.type} is not supported in this release`;
|
|
177
|
+
const flags = /* @__PURE__ */ new Set();
|
|
178
|
+
if (missing.some((feature) => feature.startsWith("parity.")))
|
|
179
|
+
flags.add("fluidgrids.durable-parity");
|
|
180
|
+
for (const feature of missing) {
|
|
181
|
+
const flag2 = PHASE_C_FEATURE_FLAGS[feature];
|
|
182
|
+
if (flag2 !== void 0) flags.add(flag2);
|
|
183
|
+
}
|
|
184
|
+
const names = [...flags];
|
|
185
|
+
const flag = names.length === 0 ? "" : ` (needs the ${names.join(" and ")} flag${names.length === 1 ? "" : "s"})`;
|
|
125
186
|
return `${command.type} needs ${missing.join(", ")}, which this workspace does not enable${flag}`;
|
|
126
187
|
}
|
|
127
188
|
function isReliefCommand(command, lease) {
|
|
@@ -130,8 +191,9 @@ function isReliefCommand(command, lease) {
|
|
|
130
191
|
return lease.grantedLocalActivityIds.includes(command.localActivityId);
|
|
131
192
|
case "ACCEPT_UPDATE":
|
|
132
193
|
case "REJECT_UPDATE":
|
|
133
|
-
case "COMPLETE_UPDATE":
|
|
134
194
|
return lease.deliveredUpdateIds.includes(command.updateId);
|
|
195
|
+
case "COMPLETE_UPDATE":
|
|
196
|
+
return true;
|
|
135
197
|
default:
|
|
136
198
|
return false;
|
|
137
199
|
}
|
|
@@ -236,9 +298,19 @@ function initialRunState() {
|
|
|
236
298
|
sideEffects: {},
|
|
237
299
|
markers: {},
|
|
238
300
|
signalsReceived: 0,
|
|
239
|
-
context: {}
|
|
301
|
+
context: {},
|
|
302
|
+
updates: {},
|
|
303
|
+
searchAttributes: {}
|
|
240
304
|
};
|
|
241
305
|
}
|
|
306
|
+
function mergeSearchAttributes(current, entries) {
|
|
307
|
+
const out = { ...current };
|
|
308
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
309
|
+
if (value === null) delete out[key];
|
|
310
|
+
else out[key] = value;
|
|
311
|
+
}
|
|
312
|
+
return out;
|
|
313
|
+
}
|
|
242
314
|
function utf8Bytes(text) {
|
|
243
315
|
let bytes = 0;
|
|
244
316
|
for (let index = 0; index < text.length; index++) {
|
|
@@ -313,6 +385,8 @@ function applyEvent(state, event) {
|
|
|
313
385
|
state.input = p["input"] ?? null;
|
|
314
386
|
if (typeof p["context"] === "object" && p["context"] !== null && !Array.isArray(p["context"]))
|
|
315
387
|
state.context = { ...p["context"] };
|
|
388
|
+
if (typeof p["searchAttributes"] === "object" && p["searchAttributes"] !== null && !Array.isArray(p["searchAttributes"]))
|
|
389
|
+
state.searchAttributes = mergeSearchAttributes({}, p["searchAttributes"]);
|
|
316
390
|
break;
|
|
317
391
|
case "WORKFLOW_TASK_SCHEDULED":
|
|
318
392
|
state.task = { state: "SCHEDULED", taskId: str(p, "taskId"), attempt: state.task.attempt };
|
|
@@ -337,11 +411,14 @@ function applyEvent(state, event) {
|
|
|
337
411
|
const id = str(p, "activityId");
|
|
338
412
|
if (state.activities[id])
|
|
339
413
|
throw new HistoryStateError(`Activity "${id}" is scheduled twice`, event.seq);
|
|
414
|
+
const user = p["kind"] === "user";
|
|
340
415
|
state.activities[id] = {
|
|
341
416
|
status: "SCHEDULED",
|
|
342
417
|
attempt: 0,
|
|
418
|
+
kind: user ? "user" : "node",
|
|
343
419
|
nodeType: str(p, "nodeType"),
|
|
344
420
|
operation: str(p, "operation"),
|
|
421
|
+
...user ? { activityName: str(p, "activityName"), taskQueue: str(p, "taskQueue") } : {},
|
|
345
422
|
scheduledSeq: event.seq,
|
|
346
423
|
...typeof p["cancellationType"] === "string" ? { cancellationType: p["cancellationType"] } : {},
|
|
347
424
|
...typeof p["summary"] === "string" ? { summary: p["summary"] } : {}
|
|
@@ -490,6 +567,43 @@ function applyEvent(state, event) {
|
|
|
490
567
|
case "MARKER_RECORDED":
|
|
491
568
|
state.markers[str(p, "markerId")] = p["data"] ?? null;
|
|
492
569
|
break;
|
|
570
|
+
case "UPDATE_ADMITTED": {
|
|
571
|
+
const id = str(p, "updateId");
|
|
572
|
+
if (state.updates[id])
|
|
573
|
+
throw new HistoryStateError(`Update "${id}" is admitted twice`, event.seq);
|
|
574
|
+
state.updates[id] = { status: "ADMITTED", name: str(p, "name"), seq: event.seq };
|
|
575
|
+
break;
|
|
576
|
+
}
|
|
577
|
+
case "UPDATE_ACCEPTED": {
|
|
578
|
+
const id = str(p, "updateId");
|
|
579
|
+
const found = state.updates[id];
|
|
580
|
+
if (found && found.status !== "ADMITTED")
|
|
581
|
+
throw new HistoryStateError(`Update "${id}" is accepted twice`, event.seq);
|
|
582
|
+
state.updates[id] = {
|
|
583
|
+
status: "ACCEPTED",
|
|
584
|
+
name: found?.name ?? str(p, "name"),
|
|
585
|
+
seq: found?.seq ?? event.seq
|
|
586
|
+
};
|
|
587
|
+
break;
|
|
588
|
+
}
|
|
589
|
+
case "UPDATE_COMPLETED": {
|
|
590
|
+
const id = str(p, "updateId");
|
|
591
|
+
const found = state.updates[id];
|
|
592
|
+
if (!found || found.status !== "ACCEPTED")
|
|
593
|
+
throw new HistoryStateError(
|
|
594
|
+
`UPDATE_COMPLETED for update "${id}" that is not accepted`,
|
|
595
|
+
event.seq
|
|
596
|
+
);
|
|
597
|
+
found.status = "COMPLETED";
|
|
598
|
+
if (failureOf(p)) found.failed = true;
|
|
599
|
+
break;
|
|
600
|
+
}
|
|
601
|
+
case "SEARCH_ATTRIBUTES_UPSERTED": {
|
|
602
|
+
const attributes = p["attributes"];
|
|
603
|
+
if (typeof attributes === "object" && attributes !== null && !Array.isArray(attributes))
|
|
604
|
+
state.searchAttributes = mergeSearchAttributes(state.searchAttributes, attributes);
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
493
607
|
case "CONTEXT_UPSERTED": {
|
|
494
608
|
const entries = p["entries"];
|
|
495
609
|
if (typeof entries === "object" && entries !== null && !Array.isArray(entries))
|
|
@@ -545,6 +659,11 @@ function payloadOf(command) {
|
|
|
545
659
|
}
|
|
546
660
|
return out;
|
|
547
661
|
}
|
|
662
|
+
function completedPayload(command) {
|
|
663
|
+
if (command.failure !== void 0)
|
|
664
|
+
return { updateId: command.updateId, failure: command.failure };
|
|
665
|
+
return { updateId: command.updateId, result: command.result ?? null };
|
|
666
|
+
}
|
|
548
667
|
function eventsForCommands(state, commands, context) {
|
|
549
668
|
const issues = [];
|
|
550
669
|
const events = [];
|
|
@@ -563,6 +682,8 @@ function eventsForCommands(state, commands, context) {
|
|
|
563
682
|
const externals = new Set(Object.keys(state.externals));
|
|
564
683
|
const sideEffects = new Set(Object.keys(state.sideEffects));
|
|
565
684
|
const localActivities = new Set(Object.keys(state.localActivities));
|
|
685
|
+
const updates = new Map(Object.entries(state.updates).map(([id, u]) => [id, u.status]));
|
|
686
|
+
const answered = /* @__PURE__ */ new Set();
|
|
566
687
|
let unsupported = false;
|
|
567
688
|
commands.forEach((command, index) => {
|
|
568
689
|
if (!isWorkflowCommandEnabled(command, context.enabled) && !(context.relief !== void 0 && isReliefCommand(command, context.relief))) {
|
|
@@ -577,7 +698,7 @@ function eventsForCommands(state, commands, context) {
|
|
|
577
698
|
case "SCHEDULE_ACTIVITY":
|
|
578
699
|
if (activities.has(command.activityId))
|
|
579
700
|
reject(index, "activity.duplicate", `Activity "${command.activityId}" already exists`);
|
|
580
|
-
if (!isActivityNodeTypeAllowed(command.nodeType))
|
|
701
|
+
if (command.kind === "node" && !isActivityNodeTypeAllowed(command.nodeType))
|
|
581
702
|
reject(
|
|
582
703
|
index,
|
|
583
704
|
"durable.activityTypeNotAllowed",
|
|
@@ -674,6 +795,42 @@ function eventsForCommands(state, commands, context) {
|
|
|
674
795
|
case "CONTINUE_AS_NEW":
|
|
675
796
|
events.push({ ...base, type: "WORKFLOW_CONTINUED_AS_NEW", payload: payloadOf(command) });
|
|
676
797
|
break;
|
|
798
|
+
case "UPSERT_SEARCH_ATTRIBUTES":
|
|
799
|
+
events.push({ ...base, type: "SEARCH_ATTRIBUTES_UPSERTED", payload: payloadOf(command) });
|
|
800
|
+
break;
|
|
801
|
+
case "ACCEPT_UPDATE":
|
|
802
|
+
case "REJECT_UPDATE": {
|
|
803
|
+
const id = command.updateId;
|
|
804
|
+
const status = updates.get(id);
|
|
805
|
+
const delivered = context.updates?.[id];
|
|
806
|
+
if (answered.has(id) || status !== void 0 && status !== "ADMITTED") {
|
|
807
|
+
reject(index, "update.answered", `Update "${id}" is already answered`);
|
|
808
|
+
break;
|
|
809
|
+
}
|
|
810
|
+
if (status === void 0 && delivered === void 0) {
|
|
811
|
+
reject(index, "update.unknown", `Update "${id}" was not delivered to this task`);
|
|
812
|
+
break;
|
|
813
|
+
}
|
|
814
|
+
answered.add(id);
|
|
815
|
+
if (command.type === "REJECT_UPDATE") break;
|
|
816
|
+
updates.set(id, "ACCEPTED");
|
|
817
|
+
const admitted = state.updates[id];
|
|
818
|
+
const payload = { updateId: id, name: admitted?.name ?? delivered?.name ?? "" };
|
|
819
|
+
if (delivered?.args !== void 0) payload["args"] = delivered.args;
|
|
820
|
+
if (delivered?.headers !== void 0) payload["headers"] = { ...delivered.headers };
|
|
821
|
+
events.push({ ...base, type: "UPDATE_ACCEPTED", payload });
|
|
822
|
+
break;
|
|
823
|
+
}
|
|
824
|
+
case "COMPLETE_UPDATE": {
|
|
825
|
+
const id = command.updateId;
|
|
826
|
+
if (updates.get(id) !== "ACCEPTED") {
|
|
827
|
+
reject(index, "update.notAccepted", `Update "${id}" is not accepted`);
|
|
828
|
+
break;
|
|
829
|
+
}
|
|
830
|
+
updates.set(id, "COMPLETED");
|
|
831
|
+
events.push({ ...base, type: "UPDATE_COMPLETED", payload: completedPayload(command) });
|
|
832
|
+
break;
|
|
833
|
+
}
|
|
677
834
|
}
|
|
678
835
|
});
|
|
679
836
|
if (issues.length > 0)
|
|
@@ -717,4 +874,4 @@ function codeWorkflowParentClosePolicy(state) {
|
|
|
717
874
|
var CHILD_DEFAULT_PARENT_CLOSE_POLICY = Object.freeze({ child: "TERMINATE", startChild: "ABANDON" });
|
|
718
875
|
var CHILD_DEFAULT_CANCELLATION_TYPE = "WAIT_CANCELLATION_COMPLETED";
|
|
719
876
|
|
|
720
|
-
export { CHILD_DEFAULT_CANCELLATION_TYPE, CHILD_DEFAULT_PARENT_CLOSE_POLICY, COMMAND_FEATURES, CORE_CAN_OPTIONS, CORE_CHILD_OPTIONS, HistoryStateError, PHASE_B_CORE_FEATURES, PHASE_B_PARITY_FEATURES, applyEvent, codeWorkflowParentClosePolicy, commandFeatures, continueAsNewRetryShape, eventsForCommands, hasUnprocessedInput, initialRunState, isActivityOpen, isChildOpen, isCommandEnabled, isReliefCommand, isWorkflowCommandEnabled, pendingCounts, projectRunState, splitActivations, taskCompletedEvents, unseenInputs, unsupportedMessage, utf8Bytes };
|
|
877
|
+
export { CHILD_DEFAULT_CANCELLATION_TYPE, CHILD_DEFAULT_PARENT_CLOSE_POLICY, CODE_FEATURE_FLAGS, COMMAND_FEATURES, CORE_CAN_OPTIONS, CORE_CHILD_OPTIONS, HistoryStateError, PHASE_B_CORE_FEATURES, PHASE_B_PARITY_FEATURES, PHASE_C_CODE_FEATURES, PHASE_C_FEATURES, PHASE_C_FEATURE_FLAGS, applyEvent, codeFeaturesEnabledBy, codeWorkflowParentClosePolicy, commandFeatures, continueAsNewRetryShape, eventsForCommands, hasUnprocessedInput, initialRunState, isActivityOpen, isChildOpen, isCommandEnabled, isReliefCommand, isWorkflowCommandEnabled, mergeSearchAttributes, pendingCounts, projectRunState, splitActivations, taskCompletedEvents, unseenInputs, unsupportedMessage, utf8Bytes };
|