@workglow/task-graph 0.2.12 → 0.2.14
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/dist/browser.js +191 -32
- package/dist/browser.js.map +19 -18
- package/dist/bun.js +191 -32
- package/dist/bun.js.map +19 -18
- package/dist/node.js +191 -32
- package/dist/node.js.map +19 -18
- package/dist/task/EntitlementEnforcer.d.ts +37 -4
- package/dist/task/EntitlementEnforcer.d.ts.map +1 -1
- package/dist/task/EntitlementPolicy.d.ts +10 -0
- package/dist/task/EntitlementPolicy.d.ts.map +1 -1
- package/dist/task/FallbackTask.d.ts +2 -1
- package/dist/task/FallbackTask.d.ts.map +1 -1
- package/dist/task/GraphAsTask.d.ts +8 -0
- package/dist/task/GraphAsTask.d.ts.map +1 -1
- package/dist/task/IteratorTask.d.ts +25 -6
- package/dist/task/IteratorTask.d.ts.map +1 -1
- package/dist/task/IteratorTaskRunner.d.ts +1 -1
- package/dist/task/IteratorTaskRunner.d.ts.map +1 -1
- package/dist/task/MapTask.d.ts +47 -3
- package/dist/task/MapTask.d.ts.map +1 -1
- package/dist/task/ReduceTask.d.ts +9 -3
- package/dist/task/ReduceTask.d.ts.map +1 -1
- package/dist/task/TaskJSON.d.ts +8 -1
- package/dist/task/TaskJSON.d.ts.map +1 -1
- package/dist/task/WhileTask.d.ts +20 -7
- package/dist/task/WhileTask.d.ts.map +1 -1
- package/dist/task-graph/ConditionalBuilder.d.ts +49 -0
- package/dist/task-graph/ConditionalBuilder.d.ts.map +1 -0
- package/dist/task-graph/Conversions.d.ts.map +1 -1
- package/dist/task-graph/GraphSchemaUtils.d.ts +2 -2
- package/dist/task-graph/GraphSchemaUtils.d.ts.map +1 -1
- package/dist/task-graph/GraphToWorkflowCode.d.ts.map +1 -1
- package/dist/task-graph/TaskGraph.d.ts +9 -1
- package/dist/task-graph/TaskGraph.d.ts.map +1 -1
- package/dist/task-graph/TaskGraphRunner.d.ts.map +1 -1
- package/dist/task-graph/Workflow.d.ts +18 -1
- package/dist/task-graph/Workflow.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/EXECUTION_MODEL.md +6 -0
package/dist/browser.js
CHANGED
|
@@ -636,7 +636,8 @@ function computeGraphInputSchema(graph, options) {
|
|
|
636
636
|
for (const [inputName, inputProp] of Object.entries(taskProperties)) {
|
|
637
637
|
if (!properties[inputName]) {
|
|
638
638
|
properties[inputName] = inputProp;
|
|
639
|
-
|
|
639
|
+
const isRequired = taskInputSchema.required?.includes(inputName) === true && !(task.defaults && task.defaults[inputName] !== undefined);
|
|
640
|
+
if (isRequired) {
|
|
640
641
|
required.push(inputName);
|
|
641
642
|
}
|
|
642
643
|
if (trackOrigins) {
|
|
@@ -949,6 +950,7 @@ import { DirectedAcyclicGraph } from "@workglow/util/graph";
|
|
|
949
950
|
|
|
950
951
|
// src/task/GraphAsTask.ts
|
|
951
952
|
import { getLogger as getLogger4 } from "@workglow/util";
|
|
953
|
+
import { CycleError } from "@workglow/util/graph";
|
|
952
954
|
import { compileSchema as compileSchema2 } from "@workglow/util/schema";
|
|
953
955
|
|
|
954
956
|
// src/task-graph/TaskGraphRunner.ts
|
|
@@ -2473,6 +2475,11 @@ function evaluatePolicy(policy, required) {
|
|
|
2473
2475
|
}
|
|
2474
2476
|
return results;
|
|
2475
2477
|
}
|
|
2478
|
+
function can(policy, id, resources) {
|
|
2479
|
+
const required = resources !== undefined ? { id, resources } : { id };
|
|
2480
|
+
const [result] = evaluatePolicy(policy, { entitlements: [required] });
|
|
2481
|
+
return result;
|
|
2482
|
+
}
|
|
2476
2483
|
|
|
2477
2484
|
// src/task/EntitlementResolver.ts
|
|
2478
2485
|
import { createServiceToken as createServiceToken2 } from "@workglow/util";
|
|
@@ -2489,6 +2496,16 @@ var DENY_ALL_RESOLVER = {
|
|
|
2489
2496
|
var ENTITLEMENT_RESOLVER = createServiceToken2("workglow.entitlementResolver");
|
|
2490
2497
|
|
|
2491
2498
|
// src/task/EntitlementEnforcer.ts
|
|
2499
|
+
function formatEntitlementDenial(denial) {
|
|
2500
|
+
switch (denial.reason) {
|
|
2501
|
+
case "policy-deny":
|
|
2502
|
+
return `${denial.entitlement.id} (denied by rule ${denial.matchedRule.id})`;
|
|
2503
|
+
case "user-deny":
|
|
2504
|
+
return `${denial.entitlement.id} (denied by user)`;
|
|
2505
|
+
case "default-deny":
|
|
2506
|
+
return `${denial.entitlement.id} (no matching grant)`;
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2492
2509
|
var PERMISSIVE_ENFORCER = {
|
|
2493
2510
|
checkAll: async () => [],
|
|
2494
2511
|
checkTask: async () => []
|
|
@@ -2499,24 +2516,27 @@ function createPolicyEnforcer(policy, resolver = PERMISSIVE_RESOLVER) {
|
|
|
2499
2516
|
const denied = [];
|
|
2500
2517
|
for (const result of results) {
|
|
2501
2518
|
if (result.verdict === "denied") {
|
|
2502
|
-
|
|
2519
|
+
if (result.matchedRule) {
|
|
2520
|
+
denied.push({ entitlement: result.entitlement, reason: "policy-deny", matchedRule: result.matchedRule });
|
|
2521
|
+
} else {
|
|
2522
|
+
denied.push({ entitlement: result.entitlement, reason: "default-deny" });
|
|
2523
|
+
}
|
|
2503
2524
|
} else if (result.verdict === "ask") {
|
|
2504
2525
|
const request = {
|
|
2505
2526
|
entitlement: result.entitlement,
|
|
2506
2527
|
taskType: taskType ?? "unknown",
|
|
2507
2528
|
taskId: taskId ?? "unknown"
|
|
2508
2529
|
};
|
|
2509
|
-
|
|
2510
|
-
if (
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
}
|
|
2514
|
-
continue;
|
|
2530
|
+
let answer = resolver.lookup(request);
|
|
2531
|
+
if (answer === undefined) {
|
|
2532
|
+
answer = await resolver.prompt(request);
|
|
2533
|
+
resolver.save(request, answer);
|
|
2515
2534
|
}
|
|
2516
|
-
const answer = await resolver.prompt(request);
|
|
2517
|
-
resolver.save(request, answer);
|
|
2518
2535
|
if (answer === "deny") {
|
|
2519
|
-
|
|
2536
|
+
if (!result.matchedRule) {
|
|
2537
|
+
throw new Error(`Invariant violation: ask verdict for "${result.entitlement.id}" is missing matchedRule`);
|
|
2538
|
+
}
|
|
2539
|
+
denied.push({ entitlement: result.entitlement, reason: "user-deny", matchedRule: result.matchedRule });
|
|
2520
2540
|
}
|
|
2521
2541
|
}
|
|
2522
2542
|
}
|
|
@@ -2736,7 +2756,7 @@ class TaskGraphRunner {
|
|
|
2736
2756
|
const runAsync = async () => {
|
|
2737
2757
|
let errorRouted = false;
|
|
2738
2758
|
try {
|
|
2739
|
-
const taskInput = isRootTask ? input : this.filterInputForTask(task, input);
|
|
2759
|
+
const taskInput = isRootTask ? input : config?.matchAllEmptyInputs ? this.filterInputForTask(task, input) : {};
|
|
2740
2760
|
const taskPromise = this.runTask(task, taskInput);
|
|
2741
2761
|
this.inProgressTasks.set(task.id, taskPromise);
|
|
2742
2762
|
const taskResult = await taskPromise;
|
|
@@ -3024,7 +3044,7 @@ class TaskGraphRunner {
|
|
|
3024
3044
|
if (this.activeEnforcer && task.constructor.hasDynamicEntitlements) {
|
|
3025
3045
|
const denied = await this.activeEnforcer.checkTask(task);
|
|
3026
3046
|
if (denied.length > 0) {
|
|
3027
|
-
throw new TaskEntitlementError(`Task ${task.constructor.type} denied entitlements: ${denied.map(
|
|
3047
|
+
throw new TaskEntitlementError(`Task ${task.constructor.type} denied entitlements: ${denied.map(formatEntitlementDenial).join(", ")}`);
|
|
3028
3048
|
}
|
|
3029
3049
|
}
|
|
3030
3050
|
if (isStreamable) {
|
|
@@ -3247,7 +3267,7 @@ class TaskGraphRunner {
|
|
|
3247
3267
|
const enforcer = this.registry.get(ENTITLEMENT_ENFORCER);
|
|
3248
3268
|
const denied = await enforcer.checkAll(computeGraphEntitlements(this.graph));
|
|
3249
3269
|
if (denied.length > 0) {
|
|
3250
|
-
throw new TaskEntitlementError(`Denied entitlements: ${denied.map(
|
|
3270
|
+
throw new TaskEntitlementError(`Denied entitlements: ${denied.map(formatEntitlementDenial).join(", ")}`);
|
|
3251
3271
|
}
|
|
3252
3272
|
this.activeEnforcer = enforcer;
|
|
3253
3273
|
} else {
|
|
@@ -3591,6 +3611,18 @@ class GraphAsTask extends Task {
|
|
|
3591
3611
|
yield { type: "finish", data: input };
|
|
3592
3612
|
}
|
|
3593
3613
|
}
|
|
3614
|
+
validateAcyclic() {
|
|
3615
|
+
if (!this.hasChildren())
|
|
3616
|
+
return;
|
|
3617
|
+
if (!this.subGraph.isAcyclic()) {
|
|
3618
|
+
throw new CycleError(`${this.type} (${this.id}): subgraph contains a cycle — loop tasks must wrap an acyclic subgraph.`);
|
|
3619
|
+
}
|
|
3620
|
+
for (const child of this.subGraph.getTasks()) {
|
|
3621
|
+
if (child instanceof GraphAsTask) {
|
|
3622
|
+
child.validateAcyclic();
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3594
3626
|
regenerateGraph() {
|
|
3595
3627
|
this._inputSchemaNode = undefined;
|
|
3596
3628
|
this.events.emit("regenerate");
|
|
@@ -3741,7 +3773,7 @@ function convertPipeFunctionToTask(fn, config) {
|
|
|
3741
3773
|
properties: {
|
|
3742
3774
|
[DATAFLOW_ALL_PORTS]: {}
|
|
3743
3775
|
},
|
|
3744
|
-
additionalProperties:
|
|
3776
|
+
additionalProperties: true
|
|
3745
3777
|
};
|
|
3746
3778
|
};
|
|
3747
3779
|
static outputSchema = () => {
|
|
@@ -3750,7 +3782,7 @@ function convertPipeFunctionToTask(fn, config) {
|
|
|
3750
3782
|
properties: {
|
|
3751
3783
|
[DATAFLOW_ALL_PORTS]: {}
|
|
3752
3784
|
},
|
|
3753
|
-
additionalProperties:
|
|
3785
|
+
additionalProperties: true
|
|
3754
3786
|
};
|
|
3755
3787
|
};
|
|
3756
3788
|
static cacheable = false;
|
|
@@ -3859,6 +3891,9 @@ class TaskGraph {
|
|
|
3859
3891
|
topologicallySortedNodes() {
|
|
3860
3892
|
return this._dag.topologicallySortedNodes();
|
|
3861
3893
|
}
|
|
3894
|
+
isAcyclic() {
|
|
3895
|
+
return this._dag.isAcyclic();
|
|
3896
|
+
}
|
|
3862
3897
|
addTask(task, config) {
|
|
3863
3898
|
return this._dag.addNode(ensureTask(task, config));
|
|
3864
3899
|
}
|
|
@@ -4132,7 +4167,75 @@ function serialGraph(tasks, inputHandle, outputHandle) {
|
|
|
4132
4167
|
return graph;
|
|
4133
4168
|
}
|
|
4134
4169
|
// src/task-graph/Workflow.ts
|
|
4135
|
-
import { EventEmitter as EventEmitter5, getLogger as getLogger5, uuid4 as
|
|
4170
|
+
import { EventEmitter as EventEmitter5, getLogger as getLogger5, uuid4 as uuid46 } from "@workglow/util";
|
|
4171
|
+
|
|
4172
|
+
// src/task-graph/ConditionalBuilder.ts
|
|
4173
|
+
import { uuid4 as uuid45 } from "@workglow/util";
|
|
4174
|
+
class ConditionalBuilder {
|
|
4175
|
+
workflow;
|
|
4176
|
+
condition;
|
|
4177
|
+
thenSpec;
|
|
4178
|
+
elseSpec;
|
|
4179
|
+
constructor(workflow, condition) {
|
|
4180
|
+
this.workflow = workflow;
|
|
4181
|
+
this.condition = condition;
|
|
4182
|
+
}
|
|
4183
|
+
then(taskClass, input, config) {
|
|
4184
|
+
this.thenSpec = { taskClass, input, config };
|
|
4185
|
+
return this;
|
|
4186
|
+
}
|
|
4187
|
+
else(taskClass, input, config) {
|
|
4188
|
+
this.elseSpec = { taskClass, input, config };
|
|
4189
|
+
return this;
|
|
4190
|
+
}
|
|
4191
|
+
endIf() {
|
|
4192
|
+
if (!this.thenSpec) {
|
|
4193
|
+
throw new WorkflowError(".endIf() called without a prior .then(...) call");
|
|
4194
|
+
}
|
|
4195
|
+
const thenPort = "then";
|
|
4196
|
+
const elsePort = "else";
|
|
4197
|
+
const branches = [
|
|
4198
|
+
{
|
|
4199
|
+
id: thenPort,
|
|
4200
|
+
condition: this.condition,
|
|
4201
|
+
outputPort: thenPort
|
|
4202
|
+
}
|
|
4203
|
+
];
|
|
4204
|
+
if (this.elseSpec) {
|
|
4205
|
+
branches.push({
|
|
4206
|
+
id: elsePort,
|
|
4207
|
+
condition: (input) => !this.condition(input),
|
|
4208
|
+
outputPort: elsePort
|
|
4209
|
+
});
|
|
4210
|
+
}
|
|
4211
|
+
const conditionalTask = new ConditionalTask({
|
|
4212
|
+
id: uuid45(),
|
|
4213
|
+
branches,
|
|
4214
|
+
exclusive: true,
|
|
4215
|
+
defaultBranch: this.elseSpec ? elsePort : undefined
|
|
4216
|
+
});
|
|
4217
|
+
this.workflow.graph.addTask(conditionalTask);
|
|
4218
|
+
const thenTask = instantiate(this.thenSpec);
|
|
4219
|
+
this.workflow.graph.addTask(thenTask);
|
|
4220
|
+
this.workflow.graph.addDataflow(new Dataflow(conditionalTask.id, thenPort, thenTask.id, "*"));
|
|
4221
|
+
if (this.elseSpec) {
|
|
4222
|
+
const elseTask = instantiate(this.elseSpec);
|
|
4223
|
+
this.workflow.graph.addTask(elseTask);
|
|
4224
|
+
this.workflow.graph.addDataflow(new Dataflow(conditionalTask.id, elsePort, elseTask.id, "*"));
|
|
4225
|
+
}
|
|
4226
|
+
return this.workflow;
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
function instantiate(spec) {
|
|
4230
|
+
const config = {
|
|
4231
|
+
id: uuid45(),
|
|
4232
|
+
...spec.config,
|
|
4233
|
+
defaults: spec.input
|
|
4234
|
+
};
|
|
4235
|
+
return new spec.taskClass(config);
|
|
4236
|
+
}
|
|
4237
|
+
|
|
4238
|
+
// src/task-graph/Workflow.ts
|
|
4136
4239
|
function getLastTask(workflow) {
|
|
4137
4240
|
const tasks = workflow.graph.getTasks();
|
|
4138
4241
|
return tasks.length > 0 ? tasks[tasks.length - 1] : undefined;
|
|
@@ -4275,7 +4378,7 @@ class Workflow {
|
|
|
4275
4378
|
this._error = "";
|
|
4276
4379
|
const parent = getLastTask(this);
|
|
4277
4380
|
const task = this.addTaskToGraph(taskClass, {
|
|
4278
|
-
id:
|
|
4381
|
+
id: uuid46(),
|
|
4279
4382
|
...config,
|
|
4280
4383
|
defaults: input
|
|
4281
4384
|
});
|
|
@@ -4556,7 +4659,7 @@ class Workflow {
|
|
|
4556
4659
|
addLoopTask(taskClass, config = {}) {
|
|
4557
4660
|
this._error = "";
|
|
4558
4661
|
const parent = getLastTask(this);
|
|
4559
|
-
const task = this.addTaskToGraph(taskClass, { id:
|
|
4662
|
+
const task = this.addTaskToGraph(taskClass, { id: uuid46(), ...config });
|
|
4560
4663
|
if (this._dataFlows.length > 0) {
|
|
4561
4664
|
this._dataFlows.forEach((dataflow) => {
|
|
4562
4665
|
const taskSchema = task.inputSchema();
|
|
@@ -4576,6 +4679,9 @@ class Workflow {
|
|
|
4576
4679
|
}
|
|
4577
4680
|
return loopBuilder;
|
|
4578
4681
|
}
|
|
4682
|
+
if(condition) {
|
|
4683
|
+
return new ConditionalBuilder(this, condition);
|
|
4684
|
+
}
|
|
4579
4685
|
autoConnectLoopTask(pending) {
|
|
4580
4686
|
if (!pending)
|
|
4581
4687
|
return;
|
|
@@ -4933,6 +5039,7 @@ class Workflow {
|
|
|
4933
5039
|
return;
|
|
4934
5040
|
}
|
|
4935
5041
|
this._iteratorTask.subGraph = this.graph;
|
|
5042
|
+
this._iteratorTask.validateAcyclic();
|
|
4936
5043
|
}
|
|
4937
5044
|
finalizeAndReturn() {
|
|
4938
5045
|
if (!this._parentWorkflow) {
|
|
@@ -4967,6 +5074,7 @@ function getMethodNameMap() {
|
|
|
4967
5074
|
}
|
|
4968
5075
|
var LOOP_TASK_TYPES = {
|
|
4969
5076
|
MapTask: { method: "map", endMethod: "endMap" },
|
|
5077
|
+
ForEachTask: { method: "forEach", endMethod: "endForEach" },
|
|
4970
5078
|
ReduceTask: { method: "reduce", endMethod: "endReduce" },
|
|
4971
5079
|
WhileTask: { method: "while", endMethod: "endWhile" },
|
|
4972
5080
|
GraphAsTask: { method: "group", endMethod: "endGroup" }
|
|
@@ -5149,7 +5257,8 @@ function extractLoopConfig(task) {
|
|
|
5149
5257
|
}
|
|
5150
5258
|
break;
|
|
5151
5259
|
}
|
|
5152
|
-
case "MapTask":
|
|
5260
|
+
case "MapTask":
|
|
5261
|
+
case "ForEachTask": {
|
|
5153
5262
|
if (rawConfig.preserveOrder !== undefined && rawConfig.preserveOrder !== true) {
|
|
5154
5263
|
config.preserveOrder = rawConfig.preserveOrder;
|
|
5155
5264
|
}
|
|
@@ -5162,16 +5271,22 @@ function extractLoopConfig(task) {
|
|
|
5162
5271
|
if (rawConfig.batchSize !== undefined) {
|
|
5163
5272
|
config.batchSize = rawConfig.batchSize;
|
|
5164
5273
|
}
|
|
5274
|
+
if (rawConfig.maxIterations !== undefined) {
|
|
5275
|
+
config.maxIterations = rawConfig.maxIterations;
|
|
5276
|
+
}
|
|
5165
5277
|
break;
|
|
5166
5278
|
}
|
|
5167
5279
|
case "ReduceTask": {
|
|
5168
5280
|
if (rawConfig.initialValue !== undefined) {
|
|
5169
5281
|
config.initialValue = rawConfig.initialValue;
|
|
5170
5282
|
}
|
|
5283
|
+
if (rawConfig.maxIterations !== undefined) {
|
|
5284
|
+
config.maxIterations = rawConfig.maxIterations;
|
|
5285
|
+
}
|
|
5171
5286
|
break;
|
|
5172
5287
|
}
|
|
5173
5288
|
case "WhileTask": {
|
|
5174
|
-
if (rawConfig.maxIterations !== undefined
|
|
5289
|
+
if (rawConfig.maxIterations !== undefined) {
|
|
5175
5290
|
config.maxIterations = rawConfig.maxIterations;
|
|
5176
5291
|
}
|
|
5177
5292
|
if (rawConfig.chainIterations !== undefined && rawConfig.chainIterations !== true) {
|
|
@@ -5609,15 +5724,15 @@ async function compactSchemaInputs(input, schema, config, visited = new Set) {
|
|
|
5609
5724
|
return compacted;
|
|
5610
5725
|
}
|
|
5611
5726
|
// src/task/IteratorTaskRunner.ts
|
|
5612
|
-
import { uuid4 as
|
|
5727
|
+
import { uuid4 as uuid47 } from "@workglow/util";
|
|
5613
5728
|
class IteratorTaskRunner extends GraphAsTaskRunner {
|
|
5614
5729
|
aggregatingParentMapProgress = false;
|
|
5615
5730
|
mapPartialProgress = [];
|
|
5616
5731
|
mapPartialIterationCount = 0;
|
|
5617
5732
|
async executeTask(input) {
|
|
5618
5733
|
let analysis = this.task.analyzeIterationInput(input);
|
|
5619
|
-
const maxIterations = this.task.config.maxIterations;
|
|
5620
|
-
if (
|
|
5734
|
+
const maxIterations = resolveIterationBound(this.task.config.maxIterations);
|
|
5735
|
+
if (analysis.iterationCount > maxIterations) {
|
|
5621
5736
|
analysis = { ...analysis, iterationCount: maxIterations };
|
|
5622
5737
|
}
|
|
5623
5738
|
if (analysis.iterationCount === 0) {
|
|
@@ -5723,7 +5838,7 @@ class IteratorTaskRunner extends GraphAsTaskRunner {
|
|
|
5723
5838
|
const idMap = new Map;
|
|
5724
5839
|
for (const task of graph.getTasks()) {
|
|
5725
5840
|
const ctor = task.constructor;
|
|
5726
|
-
const newId =
|
|
5841
|
+
const newId = uuid47();
|
|
5727
5842
|
idMap.set(task.config.id, newId);
|
|
5728
5843
|
const clonedConfig = { ...task.config, id: newId };
|
|
5729
5844
|
const newTask = new ctor({ ...clonedConfig, defaults: task.defaults }, task.runConfig);
|
|
@@ -5793,15 +5908,21 @@ var ITERATOR_CONTEXT_SCHEMA = {
|
|
|
5793
5908
|
}
|
|
5794
5909
|
}
|
|
5795
5910
|
};
|
|
5911
|
+
function resolveIterationBound(bound) {
|
|
5912
|
+
return bound === "unbounded" ? Number.POSITIVE_INFINITY : bound;
|
|
5913
|
+
}
|
|
5796
5914
|
var iteratorTaskConfigSchema = {
|
|
5797
5915
|
type: "object",
|
|
5798
5916
|
properties: {
|
|
5799
5917
|
...graphAsTaskConfigSchema["properties"],
|
|
5800
5918
|
concurrencyLimit: { type: "integer", minimum: 1 },
|
|
5801
5919
|
batchSize: { type: "integer", minimum: 1 },
|
|
5802
|
-
maxIterations: {
|
|
5920
|
+
maxIterations: {
|
|
5921
|
+
oneOf: [{ type: "integer", minimum: 1 }, { type: "string", const: "unbounded" }]
|
|
5922
|
+
},
|
|
5803
5923
|
iterationInputConfig: { type: "object", additionalProperties: true }
|
|
5804
5924
|
},
|
|
5925
|
+
required: ["maxIterations"],
|
|
5805
5926
|
additionalProperties: false
|
|
5806
5927
|
};
|
|
5807
5928
|
function isArrayVariant(schema) {
|
|
@@ -5916,6 +6037,12 @@ class IteratorTask extends GraphAsTask {
|
|
|
5916
6037
|
static configSchema() {
|
|
5917
6038
|
return iteratorTaskConfigSchema;
|
|
5918
6039
|
}
|
|
6040
|
+
constructor(config = {}, runConfig = {}) {
|
|
6041
|
+
if (config.maxIterations === undefined) {
|
|
6042
|
+
throw new TaskConfigurationError(`${new.target.type ?? "IteratorTask"}: maxIterations is required. ` + `Pass a positive integer to cap iteration, or "unbounded" to opt out explicitly.`);
|
|
6043
|
+
}
|
|
6044
|
+
super(config, runConfig);
|
|
6045
|
+
}
|
|
5919
6046
|
static getIterationContextSchema() {
|
|
5920
6047
|
return ITERATOR_CONTEXT_SCHEMA;
|
|
5921
6048
|
}
|
|
@@ -6305,13 +6432,16 @@ var whileTaskConfigSchema = {
|
|
|
6305
6432
|
properties: {
|
|
6306
6433
|
...graphAsTaskConfigSchema["properties"],
|
|
6307
6434
|
condition: {},
|
|
6308
|
-
maxIterations: {
|
|
6435
|
+
maxIterations: {
|
|
6436
|
+
oneOf: [{ type: "integer", minimum: 1 }, { type: "string", const: "unbounded" }]
|
|
6437
|
+
},
|
|
6309
6438
|
chainIterations: { type: "boolean" },
|
|
6310
6439
|
conditionField: { type: "string" },
|
|
6311
6440
|
conditionOperator: { type: "string" },
|
|
6312
6441
|
conditionValue: { type: "string" },
|
|
6313
6442
|
iterationInputConfig: { type: "object", additionalProperties: true }
|
|
6314
6443
|
},
|
|
6444
|
+
required: ["maxIterations"],
|
|
6315
6445
|
additionalProperties: false
|
|
6316
6446
|
};
|
|
6317
6447
|
|
|
@@ -6324,6 +6454,12 @@ class WhileTask extends GraphAsTask {
|
|
|
6324
6454
|
static configSchema() {
|
|
6325
6455
|
return whileTaskConfigSchema;
|
|
6326
6456
|
}
|
|
6457
|
+
constructor(config = {}, runConfig = {}) {
|
|
6458
|
+
if (config.maxIterations === undefined) {
|
|
6459
|
+
throw new TaskConfigurationError(`${new.target.type ?? "WhileTask"}: maxIterations is required. ` + `Pass a positive integer to cap iteration, or "unbounded" to opt out explicitly.`);
|
|
6460
|
+
}
|
|
6461
|
+
super(config, runConfig);
|
|
6462
|
+
}
|
|
6327
6463
|
static getIterationContextSchema() {
|
|
6328
6464
|
return WHILE_CONTEXT_SCHEMA;
|
|
6329
6465
|
}
|
|
@@ -6341,7 +6477,7 @@ class WhileTask extends GraphAsTask {
|
|
|
6341
6477
|
return this.config.condition;
|
|
6342
6478
|
}
|
|
6343
6479
|
get maxIterations() {
|
|
6344
|
-
return this.config.maxIterations
|
|
6480
|
+
return resolveIterationBound(this.config.maxIterations);
|
|
6345
6481
|
}
|
|
6346
6482
|
get chainIterations() {
|
|
6347
6483
|
return this.config.chainIterations ?? true;
|
|
@@ -6948,8 +7084,10 @@ var mapTaskConfigSchema = {
|
|
|
6948
7084
|
properties: {
|
|
6949
7085
|
...iteratorTaskConfigSchema["properties"],
|
|
6950
7086
|
preserveOrder: { type: "boolean" },
|
|
6951
|
-
flatten: { type: "boolean" }
|
|
7087
|
+
flatten: { type: "boolean" },
|
|
7088
|
+
discardResults: { type: "boolean" }
|
|
6952
7089
|
},
|
|
7090
|
+
required: iteratorTaskConfigSchema.required,
|
|
6953
7091
|
additionalProperties: false
|
|
6954
7092
|
};
|
|
6955
7093
|
|
|
@@ -6982,6 +7120,9 @@ class MapTask extends IteratorTask {
|
|
|
6982
7120
|
get flatten() {
|
|
6983
7121
|
return this.config.flatten ?? false;
|
|
6984
7122
|
}
|
|
7123
|
+
get discardResults() {
|
|
7124
|
+
return this.config.discardResults ?? false;
|
|
7125
|
+
}
|
|
6985
7126
|
preserveIterationOrder() {
|
|
6986
7127
|
return this.preserveOrder;
|
|
6987
7128
|
}
|
|
@@ -7003,6 +7144,9 @@ class MapTask extends IteratorTask {
|
|
|
7003
7144
|
return this.getWrappedOutputSchema();
|
|
7004
7145
|
}
|
|
7005
7146
|
collectResults(results) {
|
|
7147
|
+
if (this.discardResults) {
|
|
7148
|
+
return this.getEmptyResult();
|
|
7149
|
+
}
|
|
7006
7150
|
const collected = super.collectResults(results);
|
|
7007
7151
|
if (!this.flatten || typeof collected !== "object" || collected === null) {
|
|
7008
7152
|
return collected;
|
|
@@ -7018,8 +7162,19 @@ class MapTask extends IteratorTask {
|
|
|
7018
7162
|
return flattened;
|
|
7019
7163
|
}
|
|
7020
7164
|
}
|
|
7165
|
+
|
|
7166
|
+
class ForEachTask extends MapTask {
|
|
7167
|
+
static type = "ForEachTask";
|
|
7168
|
+
static title = "For Each";
|
|
7169
|
+
static description = "Runs a workflow per array item for side effects; discards collected results";
|
|
7170
|
+
constructor(config = {}, runConfig = {}) {
|
|
7171
|
+
super({ discardResults: true, ...config }, runConfig);
|
|
7172
|
+
}
|
|
7173
|
+
}
|
|
7021
7174
|
Workflow.prototype.map = CreateLoopWorkflow(MapTask);
|
|
7022
7175
|
Workflow.prototype.endMap = CreateEndLoopWorkflow("endMap");
|
|
7176
|
+
Workflow.prototype.forEach = CreateLoopWorkflow(ForEachTask);
|
|
7177
|
+
Workflow.prototype.endForEach = CreateEndLoopWorkflow("endForEach");
|
|
7023
7178
|
// src/task/ReduceTask.ts
|
|
7024
7179
|
var reduceTaskConfigSchema = {
|
|
7025
7180
|
type: "object",
|
|
@@ -7038,13 +7193,13 @@ class ReduceTask extends IteratorTask {
|
|
|
7038
7193
|
static configSchema() {
|
|
7039
7194
|
return reduceTaskConfigSchema;
|
|
7040
7195
|
}
|
|
7041
|
-
constructor(config = {}) {
|
|
7196
|
+
constructor(config = {}, runConfig = {}) {
|
|
7042
7197
|
const reduceConfig = {
|
|
7043
7198
|
...config,
|
|
7044
7199
|
concurrencyLimit: 1,
|
|
7045
7200
|
batchSize: 1
|
|
7046
7201
|
};
|
|
7047
|
-
super(reduceConfig);
|
|
7202
|
+
super(reduceConfig, runConfig);
|
|
7048
7203
|
}
|
|
7049
7204
|
get initialValue() {
|
|
7050
7205
|
return this.config.initialValue ?? {};
|
|
@@ -8123,6 +8278,7 @@ export {
|
|
|
8123
8278
|
scanGraphForCredentials,
|
|
8124
8279
|
resourcePatternMatches,
|
|
8125
8280
|
resolveSchemaInputs,
|
|
8281
|
+
resolveIterationBound,
|
|
8126
8282
|
resetMethodNameCache,
|
|
8127
8283
|
removeIterationProperties,
|
|
8128
8284
|
registerJobQueueFactory,
|
|
@@ -8167,6 +8323,7 @@ export {
|
|
|
8167
8323
|
getFormatPrefix,
|
|
8168
8324
|
getAppendPortId,
|
|
8169
8325
|
formatValue,
|
|
8326
|
+
formatEntitlementDenial,
|
|
8170
8327
|
findArrayPorts,
|
|
8171
8328
|
filterIterationProperties,
|
|
8172
8329
|
fallbackTaskConfigSchema,
|
|
@@ -8195,6 +8352,7 @@ export {
|
|
|
8195
8352
|
computeGraphInputSchema,
|
|
8196
8353
|
computeGraphEntitlements,
|
|
8197
8354
|
compactSchemaInputs,
|
|
8355
|
+
can,
|
|
8198
8356
|
calculateNodeDepths,
|
|
8199
8357
|
buildIterationInputSchema,
|
|
8200
8358
|
addIterationContextToSchema,
|
|
@@ -8247,6 +8405,7 @@ export {
|
|
|
8247
8405
|
GraphAsTaskRunner,
|
|
8248
8406
|
GraphAsTask,
|
|
8249
8407
|
GRAPH_RESULT_ARRAY,
|
|
8408
|
+
ForEachTask,
|
|
8250
8409
|
FallbackTaskRunner,
|
|
8251
8410
|
FallbackTask,
|
|
8252
8411
|
EventTaskGraphToDagMapping,
|
|
@@ -8270,4 +8429,4 @@ export {
|
|
|
8270
8429
|
BROWSER_GRANTS
|
|
8271
8430
|
};
|
|
8272
8431
|
|
|
8273
|
-
//# debugId=
|
|
8432
|
+
//# debugId=8CB4AA21F9A0895064756E2164756E21
|