@workglow/task-graph 0.2.13 → 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 +190 -31
- package/dist/browser.js.map +19 -18
- package/dist/bun.js +190 -31
- package/dist/bun.js.map +19 -18
- package/dist/node.js +190 -31
- 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 +6 -0
- package/dist/task-graph/TaskGraph.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/bun.js
CHANGED
|
@@ -637,7 +637,8 @@ function computeGraphInputSchema(graph, options) {
|
|
|
637
637
|
for (const [inputName, inputProp] of Object.entries(taskProperties)) {
|
|
638
638
|
if (!properties[inputName]) {
|
|
639
639
|
properties[inputName] = inputProp;
|
|
640
|
-
|
|
640
|
+
const isRequired = taskInputSchema.required?.includes(inputName) === true && !(task.defaults && task.defaults[inputName] !== undefined);
|
|
641
|
+
if (isRequired) {
|
|
641
642
|
required.push(inputName);
|
|
642
643
|
}
|
|
643
644
|
if (trackOrigins) {
|
|
@@ -950,6 +951,7 @@ import { DirectedAcyclicGraph } from "@workglow/util/graph";
|
|
|
950
951
|
|
|
951
952
|
// src/task/GraphAsTask.ts
|
|
952
953
|
import { getLogger as getLogger4 } from "@workglow/util";
|
|
954
|
+
import { CycleError } from "@workglow/util/graph";
|
|
953
955
|
import { compileSchema as compileSchema2 } from "@workglow/util/schema";
|
|
954
956
|
|
|
955
957
|
// src/task-graph/TaskGraphRunner.ts
|
|
@@ -2474,6 +2476,11 @@ function evaluatePolicy(policy, required) {
|
|
|
2474
2476
|
}
|
|
2475
2477
|
return results;
|
|
2476
2478
|
}
|
|
2479
|
+
function can(policy, id, resources) {
|
|
2480
|
+
const required = resources !== undefined ? { id, resources } : { id };
|
|
2481
|
+
const [result] = evaluatePolicy(policy, { entitlements: [required] });
|
|
2482
|
+
return result;
|
|
2483
|
+
}
|
|
2477
2484
|
|
|
2478
2485
|
// src/task/EntitlementResolver.ts
|
|
2479
2486
|
import { createServiceToken as createServiceToken2 } from "@workglow/util";
|
|
@@ -2490,6 +2497,16 @@ var DENY_ALL_RESOLVER = {
|
|
|
2490
2497
|
var ENTITLEMENT_RESOLVER = createServiceToken2("workglow.entitlementResolver");
|
|
2491
2498
|
|
|
2492
2499
|
// src/task/EntitlementEnforcer.ts
|
|
2500
|
+
function formatEntitlementDenial(denial) {
|
|
2501
|
+
switch (denial.reason) {
|
|
2502
|
+
case "policy-deny":
|
|
2503
|
+
return `${denial.entitlement.id} (denied by rule ${denial.matchedRule.id})`;
|
|
2504
|
+
case "user-deny":
|
|
2505
|
+
return `${denial.entitlement.id} (denied by user)`;
|
|
2506
|
+
case "default-deny":
|
|
2507
|
+
return `${denial.entitlement.id} (no matching grant)`;
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2493
2510
|
var PERMISSIVE_ENFORCER = {
|
|
2494
2511
|
checkAll: async () => [],
|
|
2495
2512
|
checkTask: async () => []
|
|
@@ -2500,24 +2517,27 @@ function createPolicyEnforcer(policy, resolver = PERMISSIVE_RESOLVER) {
|
|
|
2500
2517
|
const denied = [];
|
|
2501
2518
|
for (const result of results) {
|
|
2502
2519
|
if (result.verdict === "denied") {
|
|
2503
|
-
|
|
2520
|
+
if (result.matchedRule) {
|
|
2521
|
+
denied.push({ entitlement: result.entitlement, reason: "policy-deny", matchedRule: result.matchedRule });
|
|
2522
|
+
} else {
|
|
2523
|
+
denied.push({ entitlement: result.entitlement, reason: "default-deny" });
|
|
2524
|
+
}
|
|
2504
2525
|
} else if (result.verdict === "ask") {
|
|
2505
2526
|
const request = {
|
|
2506
2527
|
entitlement: result.entitlement,
|
|
2507
2528
|
taskType: taskType ?? "unknown",
|
|
2508
2529
|
taskId: taskId ?? "unknown"
|
|
2509
2530
|
};
|
|
2510
|
-
|
|
2511
|
-
if (
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
}
|
|
2515
|
-
continue;
|
|
2531
|
+
let answer = resolver.lookup(request);
|
|
2532
|
+
if (answer === undefined) {
|
|
2533
|
+
answer = await resolver.prompt(request);
|
|
2534
|
+
resolver.save(request, answer);
|
|
2516
2535
|
}
|
|
2517
|
-
const answer = await resolver.prompt(request);
|
|
2518
|
-
resolver.save(request, answer);
|
|
2519
2536
|
if (answer === "deny") {
|
|
2520
|
-
|
|
2537
|
+
if (!result.matchedRule) {
|
|
2538
|
+
throw new Error(`Invariant violation: ask verdict for "${result.entitlement.id}" is missing matchedRule`);
|
|
2539
|
+
}
|
|
2540
|
+
denied.push({ entitlement: result.entitlement, reason: "user-deny", matchedRule: result.matchedRule });
|
|
2521
2541
|
}
|
|
2522
2542
|
}
|
|
2523
2543
|
}
|
|
@@ -3025,7 +3045,7 @@ class TaskGraphRunner {
|
|
|
3025
3045
|
if (this.activeEnforcer && task.constructor.hasDynamicEntitlements) {
|
|
3026
3046
|
const denied = await this.activeEnforcer.checkTask(task);
|
|
3027
3047
|
if (denied.length > 0) {
|
|
3028
|
-
throw new TaskEntitlementError(`Task ${task.constructor.type} denied entitlements: ${denied.map(
|
|
3048
|
+
throw new TaskEntitlementError(`Task ${task.constructor.type} denied entitlements: ${denied.map(formatEntitlementDenial).join(", ")}`);
|
|
3029
3049
|
}
|
|
3030
3050
|
}
|
|
3031
3051
|
if (isStreamable) {
|
|
@@ -3248,7 +3268,7 @@ class TaskGraphRunner {
|
|
|
3248
3268
|
const enforcer = this.registry.get(ENTITLEMENT_ENFORCER);
|
|
3249
3269
|
const denied = await enforcer.checkAll(computeGraphEntitlements(this.graph));
|
|
3250
3270
|
if (denied.length > 0) {
|
|
3251
|
-
throw new TaskEntitlementError(`Denied entitlements: ${denied.map(
|
|
3271
|
+
throw new TaskEntitlementError(`Denied entitlements: ${denied.map(formatEntitlementDenial).join(", ")}`);
|
|
3252
3272
|
}
|
|
3253
3273
|
this.activeEnforcer = enforcer;
|
|
3254
3274
|
} else {
|
|
@@ -3592,6 +3612,18 @@ class GraphAsTask extends Task {
|
|
|
3592
3612
|
yield { type: "finish", data: input };
|
|
3593
3613
|
}
|
|
3594
3614
|
}
|
|
3615
|
+
validateAcyclic() {
|
|
3616
|
+
if (!this.hasChildren())
|
|
3617
|
+
return;
|
|
3618
|
+
if (!this.subGraph.isAcyclic()) {
|
|
3619
|
+
throw new CycleError(`${this.type} (${this.id}): subgraph contains a cycle \u2014 loop tasks must wrap an acyclic subgraph.`);
|
|
3620
|
+
}
|
|
3621
|
+
for (const child of this.subGraph.getTasks()) {
|
|
3622
|
+
if (child instanceof GraphAsTask) {
|
|
3623
|
+
child.validateAcyclic();
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3595
3627
|
regenerateGraph() {
|
|
3596
3628
|
this._inputSchemaNode = undefined;
|
|
3597
3629
|
this.events.emit("regenerate");
|
|
@@ -3742,7 +3774,7 @@ function convertPipeFunctionToTask(fn, config) {
|
|
|
3742
3774
|
properties: {
|
|
3743
3775
|
[DATAFLOW_ALL_PORTS]: {}
|
|
3744
3776
|
},
|
|
3745
|
-
additionalProperties:
|
|
3777
|
+
additionalProperties: true
|
|
3746
3778
|
};
|
|
3747
3779
|
};
|
|
3748
3780
|
static outputSchema = () => {
|
|
@@ -3751,7 +3783,7 @@ function convertPipeFunctionToTask(fn, config) {
|
|
|
3751
3783
|
properties: {
|
|
3752
3784
|
[DATAFLOW_ALL_PORTS]: {}
|
|
3753
3785
|
},
|
|
3754
|
-
additionalProperties:
|
|
3786
|
+
additionalProperties: true
|
|
3755
3787
|
};
|
|
3756
3788
|
};
|
|
3757
3789
|
static cacheable = false;
|
|
@@ -3860,6 +3892,9 @@ class TaskGraph {
|
|
|
3860
3892
|
topologicallySortedNodes() {
|
|
3861
3893
|
return this._dag.topologicallySortedNodes();
|
|
3862
3894
|
}
|
|
3895
|
+
isAcyclic() {
|
|
3896
|
+
return this._dag.isAcyclic();
|
|
3897
|
+
}
|
|
3863
3898
|
addTask(task, config) {
|
|
3864
3899
|
return this._dag.addNode(ensureTask(task, config));
|
|
3865
3900
|
}
|
|
@@ -4133,7 +4168,75 @@ function serialGraph(tasks, inputHandle, outputHandle) {
|
|
|
4133
4168
|
return graph;
|
|
4134
4169
|
}
|
|
4135
4170
|
// src/task-graph/Workflow.ts
|
|
4136
|
-
import { EventEmitter as EventEmitter5, getLogger as getLogger5, uuid4 as
|
|
4171
|
+
import { EventEmitter as EventEmitter5, getLogger as getLogger5, uuid4 as uuid46 } from "@workglow/util";
|
|
4172
|
+
|
|
4173
|
+
// src/task-graph/ConditionalBuilder.ts
|
|
4174
|
+
import { uuid4 as uuid45 } from "@workglow/util";
|
|
4175
|
+
class ConditionalBuilder {
|
|
4176
|
+
workflow;
|
|
4177
|
+
condition;
|
|
4178
|
+
thenSpec;
|
|
4179
|
+
elseSpec;
|
|
4180
|
+
constructor(workflow, condition) {
|
|
4181
|
+
this.workflow = workflow;
|
|
4182
|
+
this.condition = condition;
|
|
4183
|
+
}
|
|
4184
|
+
then(taskClass, input, config) {
|
|
4185
|
+
this.thenSpec = { taskClass, input, config };
|
|
4186
|
+
return this;
|
|
4187
|
+
}
|
|
4188
|
+
else(taskClass, input, config) {
|
|
4189
|
+
this.elseSpec = { taskClass, input, config };
|
|
4190
|
+
return this;
|
|
4191
|
+
}
|
|
4192
|
+
endIf() {
|
|
4193
|
+
if (!this.thenSpec) {
|
|
4194
|
+
throw new WorkflowError(".endIf() called without a prior .then(...) call");
|
|
4195
|
+
}
|
|
4196
|
+
const thenPort = "then";
|
|
4197
|
+
const elsePort = "else";
|
|
4198
|
+
const branches = [
|
|
4199
|
+
{
|
|
4200
|
+
id: thenPort,
|
|
4201
|
+
condition: this.condition,
|
|
4202
|
+
outputPort: thenPort
|
|
4203
|
+
}
|
|
4204
|
+
];
|
|
4205
|
+
if (this.elseSpec) {
|
|
4206
|
+
branches.push({
|
|
4207
|
+
id: elsePort,
|
|
4208
|
+
condition: (input) => !this.condition(input),
|
|
4209
|
+
outputPort: elsePort
|
|
4210
|
+
});
|
|
4211
|
+
}
|
|
4212
|
+
const conditionalTask = new ConditionalTask({
|
|
4213
|
+
id: uuid45(),
|
|
4214
|
+
branches,
|
|
4215
|
+
exclusive: true,
|
|
4216
|
+
defaultBranch: this.elseSpec ? elsePort : undefined
|
|
4217
|
+
});
|
|
4218
|
+
this.workflow.graph.addTask(conditionalTask);
|
|
4219
|
+
const thenTask = instantiate(this.thenSpec);
|
|
4220
|
+
this.workflow.graph.addTask(thenTask);
|
|
4221
|
+
this.workflow.graph.addDataflow(new Dataflow(conditionalTask.id, thenPort, thenTask.id, "*"));
|
|
4222
|
+
if (this.elseSpec) {
|
|
4223
|
+
const elseTask = instantiate(this.elseSpec);
|
|
4224
|
+
this.workflow.graph.addTask(elseTask);
|
|
4225
|
+
this.workflow.graph.addDataflow(new Dataflow(conditionalTask.id, elsePort, elseTask.id, "*"));
|
|
4226
|
+
}
|
|
4227
|
+
return this.workflow;
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
4230
|
+
function instantiate(spec) {
|
|
4231
|
+
const config = {
|
|
4232
|
+
id: uuid45(),
|
|
4233
|
+
...spec.config,
|
|
4234
|
+
defaults: spec.input
|
|
4235
|
+
};
|
|
4236
|
+
return new spec.taskClass(config);
|
|
4237
|
+
}
|
|
4238
|
+
|
|
4239
|
+
// src/task-graph/Workflow.ts
|
|
4137
4240
|
function getLastTask(workflow) {
|
|
4138
4241
|
const tasks = workflow.graph.getTasks();
|
|
4139
4242
|
return tasks.length > 0 ? tasks[tasks.length - 1] : undefined;
|
|
@@ -4276,7 +4379,7 @@ class Workflow {
|
|
|
4276
4379
|
this._error = "";
|
|
4277
4380
|
const parent = getLastTask(this);
|
|
4278
4381
|
const task = this.addTaskToGraph(taskClass, {
|
|
4279
|
-
id:
|
|
4382
|
+
id: uuid46(),
|
|
4280
4383
|
...config,
|
|
4281
4384
|
defaults: input
|
|
4282
4385
|
});
|
|
@@ -4557,7 +4660,7 @@ class Workflow {
|
|
|
4557
4660
|
addLoopTask(taskClass, config = {}) {
|
|
4558
4661
|
this._error = "";
|
|
4559
4662
|
const parent = getLastTask(this);
|
|
4560
|
-
const task = this.addTaskToGraph(taskClass, { id:
|
|
4663
|
+
const task = this.addTaskToGraph(taskClass, { id: uuid46(), ...config });
|
|
4561
4664
|
if (this._dataFlows.length > 0) {
|
|
4562
4665
|
this._dataFlows.forEach((dataflow) => {
|
|
4563
4666
|
const taskSchema = task.inputSchema();
|
|
@@ -4577,6 +4680,9 @@ class Workflow {
|
|
|
4577
4680
|
}
|
|
4578
4681
|
return loopBuilder;
|
|
4579
4682
|
}
|
|
4683
|
+
if(condition) {
|
|
4684
|
+
return new ConditionalBuilder(this, condition);
|
|
4685
|
+
}
|
|
4580
4686
|
autoConnectLoopTask(pending) {
|
|
4581
4687
|
if (!pending)
|
|
4582
4688
|
return;
|
|
@@ -4934,6 +5040,7 @@ class Workflow {
|
|
|
4934
5040
|
return;
|
|
4935
5041
|
}
|
|
4936
5042
|
this._iteratorTask.subGraph = this.graph;
|
|
5043
|
+
this._iteratorTask.validateAcyclic();
|
|
4937
5044
|
}
|
|
4938
5045
|
finalizeAndReturn() {
|
|
4939
5046
|
if (!this._parentWorkflow) {
|
|
@@ -4968,6 +5075,7 @@ function getMethodNameMap() {
|
|
|
4968
5075
|
}
|
|
4969
5076
|
var LOOP_TASK_TYPES = {
|
|
4970
5077
|
MapTask: { method: "map", endMethod: "endMap" },
|
|
5078
|
+
ForEachTask: { method: "forEach", endMethod: "endForEach" },
|
|
4971
5079
|
ReduceTask: { method: "reduce", endMethod: "endReduce" },
|
|
4972
5080
|
WhileTask: { method: "while", endMethod: "endWhile" },
|
|
4973
5081
|
GraphAsTask: { method: "group", endMethod: "endGroup" }
|
|
@@ -5150,7 +5258,8 @@ function extractLoopConfig(task) {
|
|
|
5150
5258
|
}
|
|
5151
5259
|
break;
|
|
5152
5260
|
}
|
|
5153
|
-
case "MapTask":
|
|
5261
|
+
case "MapTask":
|
|
5262
|
+
case "ForEachTask": {
|
|
5154
5263
|
if (rawConfig.preserveOrder !== undefined && rawConfig.preserveOrder !== true) {
|
|
5155
5264
|
config.preserveOrder = rawConfig.preserveOrder;
|
|
5156
5265
|
}
|
|
@@ -5163,16 +5272,22 @@ function extractLoopConfig(task) {
|
|
|
5163
5272
|
if (rawConfig.batchSize !== undefined) {
|
|
5164
5273
|
config.batchSize = rawConfig.batchSize;
|
|
5165
5274
|
}
|
|
5275
|
+
if (rawConfig.maxIterations !== undefined) {
|
|
5276
|
+
config.maxIterations = rawConfig.maxIterations;
|
|
5277
|
+
}
|
|
5166
5278
|
break;
|
|
5167
5279
|
}
|
|
5168
5280
|
case "ReduceTask": {
|
|
5169
5281
|
if (rawConfig.initialValue !== undefined) {
|
|
5170
5282
|
config.initialValue = rawConfig.initialValue;
|
|
5171
5283
|
}
|
|
5284
|
+
if (rawConfig.maxIterations !== undefined) {
|
|
5285
|
+
config.maxIterations = rawConfig.maxIterations;
|
|
5286
|
+
}
|
|
5172
5287
|
break;
|
|
5173
5288
|
}
|
|
5174
5289
|
case "WhileTask": {
|
|
5175
|
-
if (rawConfig.maxIterations !== undefined
|
|
5290
|
+
if (rawConfig.maxIterations !== undefined) {
|
|
5176
5291
|
config.maxIterations = rawConfig.maxIterations;
|
|
5177
5292
|
}
|
|
5178
5293
|
if (rawConfig.chainIterations !== undefined && rawConfig.chainIterations !== true) {
|
|
@@ -5610,15 +5725,15 @@ async function compactSchemaInputs(input, schema, config, visited = new Set) {
|
|
|
5610
5725
|
return compacted;
|
|
5611
5726
|
}
|
|
5612
5727
|
// src/task/IteratorTaskRunner.ts
|
|
5613
|
-
import { uuid4 as
|
|
5728
|
+
import { uuid4 as uuid47 } from "@workglow/util";
|
|
5614
5729
|
class IteratorTaskRunner extends GraphAsTaskRunner {
|
|
5615
5730
|
aggregatingParentMapProgress = false;
|
|
5616
5731
|
mapPartialProgress = [];
|
|
5617
5732
|
mapPartialIterationCount = 0;
|
|
5618
5733
|
async executeTask(input) {
|
|
5619
5734
|
let analysis = this.task.analyzeIterationInput(input);
|
|
5620
|
-
const maxIterations = this.task.config.maxIterations;
|
|
5621
|
-
if (
|
|
5735
|
+
const maxIterations = resolveIterationBound(this.task.config.maxIterations);
|
|
5736
|
+
if (analysis.iterationCount > maxIterations) {
|
|
5622
5737
|
analysis = { ...analysis, iterationCount: maxIterations };
|
|
5623
5738
|
}
|
|
5624
5739
|
if (analysis.iterationCount === 0) {
|
|
@@ -5724,7 +5839,7 @@ class IteratorTaskRunner extends GraphAsTaskRunner {
|
|
|
5724
5839
|
const idMap = new Map;
|
|
5725
5840
|
for (const task of graph.getTasks()) {
|
|
5726
5841
|
const ctor = task.constructor;
|
|
5727
|
-
const newId =
|
|
5842
|
+
const newId = uuid47();
|
|
5728
5843
|
idMap.set(task.config.id, newId);
|
|
5729
5844
|
const clonedConfig = { ...task.config, id: newId };
|
|
5730
5845
|
const newTask = new ctor({ ...clonedConfig, defaults: task.defaults }, task.runConfig);
|
|
@@ -5794,15 +5909,21 @@ var ITERATOR_CONTEXT_SCHEMA = {
|
|
|
5794
5909
|
}
|
|
5795
5910
|
}
|
|
5796
5911
|
};
|
|
5912
|
+
function resolveIterationBound(bound) {
|
|
5913
|
+
return bound === "unbounded" ? Number.POSITIVE_INFINITY : bound;
|
|
5914
|
+
}
|
|
5797
5915
|
var iteratorTaskConfigSchema = {
|
|
5798
5916
|
type: "object",
|
|
5799
5917
|
properties: {
|
|
5800
5918
|
...graphAsTaskConfigSchema["properties"],
|
|
5801
5919
|
concurrencyLimit: { type: "integer", minimum: 1 },
|
|
5802
5920
|
batchSize: { type: "integer", minimum: 1 },
|
|
5803
|
-
maxIterations: {
|
|
5921
|
+
maxIterations: {
|
|
5922
|
+
oneOf: [{ type: "integer", minimum: 1 }, { type: "string", const: "unbounded" }]
|
|
5923
|
+
},
|
|
5804
5924
|
iterationInputConfig: { type: "object", additionalProperties: true }
|
|
5805
5925
|
},
|
|
5926
|
+
required: ["maxIterations"],
|
|
5806
5927
|
additionalProperties: false
|
|
5807
5928
|
};
|
|
5808
5929
|
function isArrayVariant(schema) {
|
|
@@ -5917,6 +6038,12 @@ class IteratorTask extends GraphAsTask {
|
|
|
5917
6038
|
static configSchema() {
|
|
5918
6039
|
return iteratorTaskConfigSchema;
|
|
5919
6040
|
}
|
|
6041
|
+
constructor(config = {}, runConfig = {}) {
|
|
6042
|
+
if (config.maxIterations === undefined) {
|
|
6043
|
+
throw new TaskConfigurationError(`${new.target.type ?? "IteratorTask"}: maxIterations is required. ` + `Pass a positive integer to cap iteration, or "unbounded" to opt out explicitly.`);
|
|
6044
|
+
}
|
|
6045
|
+
super(config, runConfig);
|
|
6046
|
+
}
|
|
5920
6047
|
static getIterationContextSchema() {
|
|
5921
6048
|
return ITERATOR_CONTEXT_SCHEMA;
|
|
5922
6049
|
}
|
|
@@ -6306,13 +6433,16 @@ var whileTaskConfigSchema = {
|
|
|
6306
6433
|
properties: {
|
|
6307
6434
|
...graphAsTaskConfigSchema["properties"],
|
|
6308
6435
|
condition: {},
|
|
6309
|
-
maxIterations: {
|
|
6436
|
+
maxIterations: {
|
|
6437
|
+
oneOf: [{ type: "integer", minimum: 1 }, { type: "string", const: "unbounded" }]
|
|
6438
|
+
},
|
|
6310
6439
|
chainIterations: { type: "boolean" },
|
|
6311
6440
|
conditionField: { type: "string" },
|
|
6312
6441
|
conditionOperator: { type: "string" },
|
|
6313
6442
|
conditionValue: { type: "string" },
|
|
6314
6443
|
iterationInputConfig: { type: "object", additionalProperties: true }
|
|
6315
6444
|
},
|
|
6445
|
+
required: ["maxIterations"],
|
|
6316
6446
|
additionalProperties: false
|
|
6317
6447
|
};
|
|
6318
6448
|
|
|
@@ -6325,6 +6455,12 @@ class WhileTask extends GraphAsTask {
|
|
|
6325
6455
|
static configSchema() {
|
|
6326
6456
|
return whileTaskConfigSchema;
|
|
6327
6457
|
}
|
|
6458
|
+
constructor(config = {}, runConfig = {}) {
|
|
6459
|
+
if (config.maxIterations === undefined) {
|
|
6460
|
+
throw new TaskConfigurationError(`${new.target.type ?? "WhileTask"}: maxIterations is required. ` + `Pass a positive integer to cap iteration, or "unbounded" to opt out explicitly.`);
|
|
6461
|
+
}
|
|
6462
|
+
super(config, runConfig);
|
|
6463
|
+
}
|
|
6328
6464
|
static getIterationContextSchema() {
|
|
6329
6465
|
return WHILE_CONTEXT_SCHEMA;
|
|
6330
6466
|
}
|
|
@@ -6342,7 +6478,7 @@ class WhileTask extends GraphAsTask {
|
|
|
6342
6478
|
return this.config.condition;
|
|
6343
6479
|
}
|
|
6344
6480
|
get maxIterations() {
|
|
6345
|
-
return this.config.maxIterations
|
|
6481
|
+
return resolveIterationBound(this.config.maxIterations);
|
|
6346
6482
|
}
|
|
6347
6483
|
get chainIterations() {
|
|
6348
6484
|
return this.config.chainIterations ?? true;
|
|
@@ -6949,8 +7085,10 @@ var mapTaskConfigSchema = {
|
|
|
6949
7085
|
properties: {
|
|
6950
7086
|
...iteratorTaskConfigSchema["properties"],
|
|
6951
7087
|
preserveOrder: { type: "boolean" },
|
|
6952
|
-
flatten: { type: "boolean" }
|
|
7088
|
+
flatten: { type: "boolean" },
|
|
7089
|
+
discardResults: { type: "boolean" }
|
|
6953
7090
|
},
|
|
7091
|
+
required: iteratorTaskConfigSchema.required,
|
|
6954
7092
|
additionalProperties: false
|
|
6955
7093
|
};
|
|
6956
7094
|
|
|
@@ -6983,6 +7121,9 @@ class MapTask extends IteratorTask {
|
|
|
6983
7121
|
get flatten() {
|
|
6984
7122
|
return this.config.flatten ?? false;
|
|
6985
7123
|
}
|
|
7124
|
+
get discardResults() {
|
|
7125
|
+
return this.config.discardResults ?? false;
|
|
7126
|
+
}
|
|
6986
7127
|
preserveIterationOrder() {
|
|
6987
7128
|
return this.preserveOrder;
|
|
6988
7129
|
}
|
|
@@ -7004,6 +7145,9 @@ class MapTask extends IteratorTask {
|
|
|
7004
7145
|
return this.getWrappedOutputSchema();
|
|
7005
7146
|
}
|
|
7006
7147
|
collectResults(results) {
|
|
7148
|
+
if (this.discardResults) {
|
|
7149
|
+
return this.getEmptyResult();
|
|
7150
|
+
}
|
|
7007
7151
|
const collected = super.collectResults(results);
|
|
7008
7152
|
if (!this.flatten || typeof collected !== "object" || collected === null) {
|
|
7009
7153
|
return collected;
|
|
@@ -7019,8 +7163,19 @@ class MapTask extends IteratorTask {
|
|
|
7019
7163
|
return flattened;
|
|
7020
7164
|
}
|
|
7021
7165
|
}
|
|
7166
|
+
|
|
7167
|
+
class ForEachTask extends MapTask {
|
|
7168
|
+
static type = "ForEachTask";
|
|
7169
|
+
static title = "For Each";
|
|
7170
|
+
static description = "Runs a workflow per array item for side effects; discards collected results";
|
|
7171
|
+
constructor(config = {}, runConfig = {}) {
|
|
7172
|
+
super({ discardResults: true, ...config }, runConfig);
|
|
7173
|
+
}
|
|
7174
|
+
}
|
|
7022
7175
|
Workflow.prototype.map = CreateLoopWorkflow(MapTask);
|
|
7023
7176
|
Workflow.prototype.endMap = CreateEndLoopWorkflow("endMap");
|
|
7177
|
+
Workflow.prototype.forEach = CreateLoopWorkflow(ForEachTask);
|
|
7178
|
+
Workflow.prototype.endForEach = CreateEndLoopWorkflow("endForEach");
|
|
7024
7179
|
// src/task/ReduceTask.ts
|
|
7025
7180
|
var reduceTaskConfigSchema = {
|
|
7026
7181
|
type: "object",
|
|
@@ -7039,13 +7194,13 @@ class ReduceTask extends IteratorTask {
|
|
|
7039
7194
|
static configSchema() {
|
|
7040
7195
|
return reduceTaskConfigSchema;
|
|
7041
7196
|
}
|
|
7042
|
-
constructor(config = {}) {
|
|
7197
|
+
constructor(config = {}, runConfig = {}) {
|
|
7043
7198
|
const reduceConfig = {
|
|
7044
7199
|
...config,
|
|
7045
7200
|
concurrencyLimit: 1,
|
|
7046
7201
|
batchSize: 1
|
|
7047
7202
|
};
|
|
7048
|
-
super(reduceConfig);
|
|
7203
|
+
super(reduceConfig, runConfig);
|
|
7049
7204
|
}
|
|
7050
7205
|
get initialValue() {
|
|
7051
7206
|
return this.config.initialValue ?? {};
|
|
@@ -7489,6 +7644,7 @@ export {
|
|
|
7489
7644
|
scanGraphForCredentials,
|
|
7490
7645
|
resourcePatternMatches,
|
|
7491
7646
|
resolveSchemaInputs,
|
|
7647
|
+
resolveIterationBound,
|
|
7492
7648
|
resetMethodNameCache,
|
|
7493
7649
|
removeIterationProperties,
|
|
7494
7650
|
registerJobQueueFactory,
|
|
@@ -7531,6 +7687,7 @@ export {
|
|
|
7531
7687
|
getFormatPrefix,
|
|
7532
7688
|
getAppendPortId,
|
|
7533
7689
|
formatValue,
|
|
7690
|
+
formatEntitlementDenial,
|
|
7534
7691
|
findArrayPorts,
|
|
7535
7692
|
filterIterationProperties,
|
|
7536
7693
|
fallbackTaskConfigSchema,
|
|
@@ -7559,6 +7716,7 @@ export {
|
|
|
7559
7716
|
computeGraphInputSchema,
|
|
7560
7717
|
computeGraphEntitlements,
|
|
7561
7718
|
compactSchemaInputs,
|
|
7719
|
+
can,
|
|
7562
7720
|
calculateNodeDepths,
|
|
7563
7721
|
buildIterationInputSchema,
|
|
7564
7722
|
addIterationContextToSchema,
|
|
@@ -7611,6 +7769,7 @@ export {
|
|
|
7611
7769
|
GraphAsTaskRunner,
|
|
7612
7770
|
GraphAsTask,
|
|
7613
7771
|
GRAPH_RESULT_ARRAY,
|
|
7772
|
+
ForEachTask,
|
|
7614
7773
|
FallbackTaskRunner,
|
|
7615
7774
|
FallbackTask,
|
|
7616
7775
|
EventTaskGraphToDagMapping,
|
|
@@ -7634,4 +7793,4 @@ export {
|
|
|
7634
7793
|
BROWSER_GRANTS
|
|
7635
7794
|
};
|
|
7636
7795
|
|
|
7637
|
-
//# debugId=
|
|
7796
|
+
//# debugId=ACCBFB832EC2FB9F64756E2164756E21
|