@workglow/task-graph 0.0.93 → 0.0.94
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 +248 -41
- package/dist/browser.js.map +9 -9
- package/dist/bun.js +248 -41
- package/dist/bun.js.map +9 -9
- package/dist/node.js +248 -41
- package/dist/node.js.map +9 -9
- package/dist/task/GraphAsTask.d.ts +9 -0
- package/dist/task/GraphAsTask.d.ts.map +1 -1
- package/dist/task/ITask.d.ts +7 -0
- package/dist/task/ITask.d.ts.map +1 -1
- package/dist/task/IteratorTask.d.ts +9 -0
- package/dist/task/IteratorTask.d.ts.map +1 -1
- package/dist/task/StreamTypes.d.ts +36 -5
- package/dist/task/StreamTypes.d.ts.map +1 -1
- package/dist/task/TaskJSON.d.ts +2 -3
- package/dist/task/TaskJSON.d.ts.map +1 -1
- package/dist/task/TaskRunner.d.ts +10 -3
- package/dist/task/TaskRunner.d.ts.map +1 -1
- package/dist/task/WhileTask.d.ts +8 -0
- package/dist/task/WhileTask.d.ts.map +1 -1
- package/dist/task-graph/Dataflow.d.ts +7 -6
- package/dist/task-graph/Dataflow.d.ts.map +1 -1
- package/dist/task-graph/TaskGraphRunner.d.ts +14 -2
- package/dist/task-graph/TaskGraphRunner.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/browser.js
CHANGED
|
@@ -47,19 +47,26 @@ class Dataflow {
|
|
|
47
47
|
if (!this.stream)
|
|
48
48
|
return;
|
|
49
49
|
const reader = this.stream.getReader();
|
|
50
|
-
|
|
50
|
+
const accumulatedPorts = new Map;
|
|
51
51
|
let lastSnapshotData = undefined;
|
|
52
52
|
let finishData = undefined;
|
|
53
53
|
let hasTextDelta = false;
|
|
54
|
+
let streamError;
|
|
54
55
|
try {
|
|
55
56
|
while (true) {
|
|
56
57
|
const { done, value: event } = await reader.read();
|
|
57
58
|
if (done)
|
|
58
59
|
break;
|
|
59
60
|
switch (event.type) {
|
|
60
|
-
case "text-delta":
|
|
61
|
+
case "text-delta": {
|
|
62
|
+
if (this.sourceTaskPortId !== DATAFLOW_ALL_PORTS && event.port !== this.sourceTaskPortId) {
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
61
65
|
hasTextDelta = true;
|
|
62
|
-
|
|
66
|
+
accumulatedPorts.set(event.port, (accumulatedPorts.get(event.port) ?? "") + event.textDelta);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
case "object-delta":
|
|
63
70
|
break;
|
|
64
71
|
case "snapshot":
|
|
65
72
|
lastSnapshotData = event.data;
|
|
@@ -68,6 +75,7 @@ class Dataflow {
|
|
|
68
75
|
finishData = event.data;
|
|
69
76
|
break;
|
|
70
77
|
case "error":
|
|
78
|
+
streamError = event.error;
|
|
71
79
|
break;
|
|
72
80
|
}
|
|
73
81
|
}
|
|
@@ -75,15 +83,25 @@ class Dataflow {
|
|
|
75
83
|
reader.releaseLock();
|
|
76
84
|
this.stream = undefined;
|
|
77
85
|
}
|
|
86
|
+
if (streamError) {
|
|
87
|
+
this.error = streamError;
|
|
88
|
+
this.setStatus(TaskStatus.FAILED);
|
|
89
|
+
throw streamError;
|
|
90
|
+
}
|
|
78
91
|
if (lastSnapshotData !== undefined) {
|
|
79
92
|
this.setPortData(lastSnapshotData);
|
|
80
93
|
} else if (finishData && Object.keys(finishData).length > 0) {
|
|
81
94
|
this.setPortData(finishData);
|
|
82
95
|
} else if (hasTextDelta) {
|
|
83
96
|
if (this.sourceTaskPortId === DATAFLOW_ALL_PORTS) {
|
|
84
|
-
|
|
97
|
+
const obj = {};
|
|
98
|
+
for (const [port, text] of accumulatedPorts) {
|
|
99
|
+
obj[port] = text;
|
|
100
|
+
}
|
|
101
|
+
this.value = obj;
|
|
85
102
|
} else {
|
|
86
|
-
|
|
103
|
+
const text = accumulatedPorts.values().next().value ?? "";
|
|
104
|
+
this.value = text;
|
|
87
105
|
}
|
|
88
106
|
}
|
|
89
107
|
}
|
|
@@ -465,29 +483,54 @@ function getPortStreamMode(schema, portId) {
|
|
|
465
483
|
return xStream;
|
|
466
484
|
return "none";
|
|
467
485
|
}
|
|
468
|
-
function
|
|
469
|
-
if (typeof
|
|
470
|
-
return
|
|
471
|
-
const props =
|
|
486
|
+
function getStreamingPorts(schema) {
|
|
487
|
+
if (typeof schema === "boolean")
|
|
488
|
+
return [];
|
|
489
|
+
const props = schema.properties;
|
|
472
490
|
if (!props)
|
|
473
|
-
return
|
|
474
|
-
|
|
475
|
-
for (const prop of Object.
|
|
491
|
+
return [];
|
|
492
|
+
const result = [];
|
|
493
|
+
for (const [name, prop] of Object.entries(props)) {
|
|
476
494
|
if (!prop || typeof prop === "boolean")
|
|
477
495
|
continue;
|
|
478
496
|
const xStream = prop["x-stream"];
|
|
479
|
-
if (xStream === "append")
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
found = "replace";
|
|
497
|
+
if (xStream === "append" || xStream === "replace") {
|
|
498
|
+
result.push({ port: name, mode: xStream });
|
|
499
|
+
}
|
|
483
500
|
}
|
|
484
|
-
return
|
|
501
|
+
return result;
|
|
502
|
+
}
|
|
503
|
+
function getOutputStreamMode(outputSchema) {
|
|
504
|
+
const ports = getStreamingPorts(outputSchema);
|
|
505
|
+
if (ports.length === 0)
|
|
506
|
+
return "none";
|
|
507
|
+
const mode = ports[0].mode;
|
|
508
|
+
for (let i = 1;i < ports.length; i++) {
|
|
509
|
+
if (ports[i].mode !== mode) {
|
|
510
|
+
throw new Error(`Mixed stream modes on a single task are not supported: ` + `port "${ports[0].port}" is "${mode}" but port "${ports[i].port}" is "${ports[i].mode}"`);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return mode;
|
|
485
514
|
}
|
|
486
515
|
function isTaskStreamable(task) {
|
|
487
516
|
if (typeof task.executeStream !== "function")
|
|
488
517
|
return false;
|
|
489
518
|
return getOutputStreamMode(task.outputSchema()) !== "none";
|
|
490
519
|
}
|
|
520
|
+
function getAppendPortId(schema) {
|
|
521
|
+
if (typeof schema === "boolean")
|
|
522
|
+
return;
|
|
523
|
+
const props = schema.properties;
|
|
524
|
+
if (!props)
|
|
525
|
+
return;
|
|
526
|
+
for (const [name, prop] of Object.entries(props)) {
|
|
527
|
+
if (!prop || typeof prop === "boolean")
|
|
528
|
+
continue;
|
|
529
|
+
if (prop["x-stream"] === "append")
|
|
530
|
+
return name;
|
|
531
|
+
}
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
491
534
|
function edgeNeedsAccumulation(sourceSchema, sourcePort, targetSchema, targetPort) {
|
|
492
535
|
const sourceMode = getPortStreamMode(sourceSchema, sourcePort);
|
|
493
536
|
if (sourceMode === "none")
|
|
@@ -504,6 +547,7 @@ class TaskRunner {
|
|
|
504
547
|
abortController;
|
|
505
548
|
outputCache;
|
|
506
549
|
registry = globalServiceRegistry;
|
|
550
|
+
inputStreams;
|
|
507
551
|
constructor(task) {
|
|
508
552
|
this.task = task;
|
|
509
553
|
this.own = this.own.bind(this);
|
|
@@ -606,7 +650,13 @@ class TaskRunner {
|
|
|
606
650
|
}
|
|
607
651
|
async executeStreamingTask(input) {
|
|
608
652
|
const streamMode = getOutputStreamMode(this.task.outputSchema());
|
|
609
|
-
|
|
653
|
+
if (streamMode === "append") {
|
|
654
|
+
const ports = getStreamingPorts(this.task.outputSchema());
|
|
655
|
+
if (ports.length === 0) {
|
|
656
|
+
throw new TaskError(`Task ${this.task.type} declares append streaming but no output port has x-stream: "append"`);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
const accumulated = new Map;
|
|
610
660
|
let chunkCount = 0;
|
|
611
661
|
let finalOutput;
|
|
612
662
|
this.task.emit("stream_start");
|
|
@@ -614,7 +664,8 @@ class TaskRunner {
|
|
|
614
664
|
signal: this.abortController.signal,
|
|
615
665
|
updateProgress: this.handleProgress.bind(this),
|
|
616
666
|
own: this.own,
|
|
617
|
-
registry: this.registry
|
|
667
|
+
registry: this.registry,
|
|
668
|
+
inputStreams: this.inputStreams
|
|
618
669
|
});
|
|
619
670
|
for await (const event of stream) {
|
|
620
671
|
chunkCount++;
|
|
@@ -628,20 +679,28 @@ class TaskRunner {
|
|
|
628
679
|
this.task.emit("stream_chunk", event);
|
|
629
680
|
switch (event.type) {
|
|
630
681
|
case "text-delta": {
|
|
631
|
-
accumulated
|
|
632
|
-
const progress = Math.min(99, Math.round(100 * (1 - Math.exp(-0.
|
|
682
|
+
accumulated.set(event.port, (accumulated.get(event.port) ?? "") + event.textDelta);
|
|
683
|
+
const progress = Math.min(99, Math.round(100 * (1 - Math.exp(-0.05 * chunkCount))));
|
|
684
|
+
await this.handleProgress(progress);
|
|
685
|
+
break;
|
|
686
|
+
}
|
|
687
|
+
case "object-delta": {
|
|
688
|
+
const progress = Math.min(99, Math.round(100 * (1 - Math.exp(-0.05 * chunkCount))));
|
|
633
689
|
await this.handleProgress(progress);
|
|
634
690
|
break;
|
|
635
691
|
}
|
|
636
692
|
case "snapshot": {
|
|
637
|
-
const progress = Math.min(99, Math.round(100 * (1 - Math.exp(-0.
|
|
693
|
+
const progress = Math.min(99, Math.round(100 * (1 - Math.exp(-0.05 * chunkCount))));
|
|
638
694
|
await this.handleProgress(progress);
|
|
639
695
|
break;
|
|
640
696
|
}
|
|
641
697
|
case "finish": {
|
|
642
698
|
if (streamMode === "append") {
|
|
643
|
-
const
|
|
644
|
-
|
|
699
|
+
const merged = { ...event.data || {} };
|
|
700
|
+
for (const [port, text] of accumulated) {
|
|
701
|
+
merged[port] = text.length > 0 ? text : event.data?.[port] ?? "";
|
|
702
|
+
}
|
|
703
|
+
finalOutput = merged;
|
|
645
704
|
} else if (streamMode === "replace") {
|
|
646
705
|
finalOutput = event.data;
|
|
647
706
|
}
|
|
@@ -1714,6 +1773,20 @@ class TaskGraphRunner {
|
|
|
1714
1773
|
}
|
|
1715
1774
|
async runTask(task, input) {
|
|
1716
1775
|
const isStreamable = isTaskStreamable(task);
|
|
1776
|
+
if (isStreamable) {
|
|
1777
|
+
const dataflows = this.graph.getSourceDataflows(task.config.id);
|
|
1778
|
+
const streamingEdges = dataflows.filter((df) => df.stream !== undefined);
|
|
1779
|
+
if (streamingEdges.length > 0) {
|
|
1780
|
+
const inputStreams = new Map;
|
|
1781
|
+
for (const df of streamingEdges) {
|
|
1782
|
+
const stream = df.stream;
|
|
1783
|
+
const [forwardCopy, materializeCopy] = stream.tee();
|
|
1784
|
+
inputStreams.set(df.targetTaskPortId, forwardCopy);
|
|
1785
|
+
df.setStream(materializeCopy);
|
|
1786
|
+
}
|
|
1787
|
+
task.runner.inputStreams = inputStreams;
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1717
1790
|
await this.awaitStreamInputs(task);
|
|
1718
1791
|
this.copyInputFromEdgesToNode(task);
|
|
1719
1792
|
if (isStreamable) {
|
|
@@ -1781,14 +1854,17 @@ class TaskGraphRunner {
|
|
|
1781
1854
|
task.off("stream_end", onStreamEnd);
|
|
1782
1855
|
}
|
|
1783
1856
|
}
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1857
|
+
static isPortDelta(event) {
|
|
1858
|
+
return event.type === "text-delta" || event.type === "object-delta";
|
|
1859
|
+
}
|
|
1860
|
+
createStreamFromTaskEvents(task, portId) {
|
|
1861
|
+
return new ReadableStream({
|
|
1789
1862
|
start: (controller) => {
|
|
1790
1863
|
const onChunk = (event) => {
|
|
1791
1864
|
try {
|
|
1865
|
+
if (portId !== undefined && TaskGraphRunner.isPortDelta(event) && event.port !== portId) {
|
|
1866
|
+
return;
|
|
1867
|
+
}
|
|
1792
1868
|
controller.enqueue(event);
|
|
1793
1869
|
} catch {}
|
|
1794
1870
|
};
|
|
@@ -1803,17 +1879,36 @@ class TaskGraphRunner {
|
|
|
1803
1879
|
task.on("stream_end", onEnd);
|
|
1804
1880
|
}
|
|
1805
1881
|
});
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1882
|
+
}
|
|
1883
|
+
pushStreamToEdges(task, streamMode) {
|
|
1884
|
+
const targetDataflows = this.graph.getTargetDataflows(task.config.id);
|
|
1885
|
+
if (targetDataflows.length === 0)
|
|
1886
|
+
return;
|
|
1887
|
+
const groups = new Map;
|
|
1888
|
+
for (const df of targetDataflows) {
|
|
1889
|
+
const key = df.sourceTaskPortId;
|
|
1890
|
+
let group = groups.get(key);
|
|
1891
|
+
if (!group) {
|
|
1892
|
+
group = [];
|
|
1893
|
+
groups.set(key, group);
|
|
1894
|
+
}
|
|
1895
|
+
group.push(df);
|
|
1896
|
+
}
|
|
1897
|
+
for (const [portKey, edges] of groups) {
|
|
1898
|
+
const filterPort = portKey === DATAFLOW_ALL_PORTS ? undefined : portKey;
|
|
1899
|
+
const stream = this.createStreamFromTaskEvents(task, filterPort);
|
|
1900
|
+
if (edges.length === 1) {
|
|
1901
|
+
edges[0].setStream(stream);
|
|
1902
|
+
} else {
|
|
1903
|
+
let currentStream = stream;
|
|
1904
|
+
for (let i = 0;i < edges.length; i++) {
|
|
1905
|
+
if (i === edges.length - 1) {
|
|
1906
|
+
edges[i].setStream(currentStream);
|
|
1907
|
+
} else {
|
|
1908
|
+
const [s1, s2] = currentStream.tee();
|
|
1909
|
+
edges[i].setStream(s1);
|
|
1910
|
+
currentStream = s2;
|
|
1911
|
+
}
|
|
1817
1912
|
}
|
|
1818
1913
|
}
|
|
1819
1914
|
}
|
|
@@ -2144,6 +2239,69 @@ class GraphAsTask extends Task {
|
|
|
2144
2239
|
});
|
|
2145
2240
|
}
|
|
2146
2241
|
}
|
|
2242
|
+
async* executeStream(input, context) {
|
|
2243
|
+
if (context.inputStreams) {
|
|
2244
|
+
for (const [, stream] of context.inputStreams) {
|
|
2245
|
+
const reader = stream.getReader();
|
|
2246
|
+
try {
|
|
2247
|
+
while (true) {
|
|
2248
|
+
const { done, value } = await reader.read();
|
|
2249
|
+
if (done)
|
|
2250
|
+
break;
|
|
2251
|
+
if (value.type === "finish")
|
|
2252
|
+
continue;
|
|
2253
|
+
yield value;
|
|
2254
|
+
}
|
|
2255
|
+
} finally {
|
|
2256
|
+
reader.releaseLock();
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
if (this.hasChildren()) {
|
|
2261
|
+
const endingNodeIds = new Set;
|
|
2262
|
+
const tasks = this.subGraph.getTasks();
|
|
2263
|
+
for (const task of tasks) {
|
|
2264
|
+
if (this.subGraph.getTargetDataflows(task.config.id).length === 0) {
|
|
2265
|
+
endingNodeIds.add(task.config.id);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
const eventQueue = [];
|
|
2269
|
+
let resolveWaiting;
|
|
2270
|
+
let subgraphDone = false;
|
|
2271
|
+
const unsub = this.subGraph.subscribeToTaskStreaming({
|
|
2272
|
+
onStreamChunk: (taskId, event) => {
|
|
2273
|
+
if (endingNodeIds.has(taskId) && event.type !== "finish") {
|
|
2274
|
+
eventQueue.push(event);
|
|
2275
|
+
resolveWaiting?.();
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
});
|
|
2279
|
+
const runPromise = this.subGraph.run(input, { parentSignal: context.signal }).then((results2) => {
|
|
2280
|
+
subgraphDone = true;
|
|
2281
|
+
resolveWaiting?.();
|
|
2282
|
+
return results2;
|
|
2283
|
+
});
|
|
2284
|
+
while (!subgraphDone) {
|
|
2285
|
+
if (eventQueue.length === 0) {
|
|
2286
|
+
await new Promise((resolve) => {
|
|
2287
|
+
resolveWaiting = resolve;
|
|
2288
|
+
});
|
|
2289
|
+
}
|
|
2290
|
+
while (eventQueue.length > 0) {
|
|
2291
|
+
yield eventQueue.shift();
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
while (eventQueue.length > 0) {
|
|
2295
|
+
yield eventQueue.shift();
|
|
2296
|
+
}
|
|
2297
|
+
unsub();
|
|
2298
|
+
const results = await runPromise;
|
|
2299
|
+
const mergedOutput = this.subGraph.mergeExecuteOutputsToRunOutput(results, this.compoundMerge);
|
|
2300
|
+
yield { type: "finish", data: mergedOutput };
|
|
2301
|
+
} else {
|
|
2302
|
+
yield { type: "finish", data: input };
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2147
2305
|
regenerateGraph() {
|
|
2148
2306
|
this._inputSchemaNode = undefined;
|
|
2149
2307
|
this.events.emit("regenerate");
|
|
@@ -3436,6 +3594,9 @@ class IteratorTask extends GraphAsTask {
|
|
|
3436
3594
|
}
|
|
3437
3595
|
return this._runner;
|
|
3438
3596
|
}
|
|
3597
|
+
async* executeStream(input, _context) {
|
|
3598
|
+
yield { type: "finish", data: input };
|
|
3599
|
+
}
|
|
3439
3600
|
set subGraph(subGraph) {
|
|
3440
3601
|
super.subGraph = subGraph;
|
|
3441
3602
|
this.invalidateIterationInputSchema();
|
|
@@ -3931,6 +4092,50 @@ class WhileTask extends GraphAsTask {
|
|
|
3931
4092
|
}
|
|
3932
4093
|
return currentOutput;
|
|
3933
4094
|
}
|
|
4095
|
+
async* executeStream(input, context) {
|
|
4096
|
+
if (!this.hasChildren()) {
|
|
4097
|
+
throw new TaskConfigurationError(`${this.type}: No subgraph set for while loop`);
|
|
4098
|
+
}
|
|
4099
|
+
const condition = this.condition ?? this.buildConditionFromExtras();
|
|
4100
|
+
if (!condition) {
|
|
4101
|
+
throw new TaskConfigurationError(`${this.type}: No condition function provided`);
|
|
4102
|
+
}
|
|
4103
|
+
const arrayAnalysis = this.analyzeArrayInputs(input);
|
|
4104
|
+
this._currentIteration = 0;
|
|
4105
|
+
let currentInput = { ...input };
|
|
4106
|
+
let currentOutput = {};
|
|
4107
|
+
const effectiveMax = arrayAnalysis ? Math.min(this.maxIterations, arrayAnalysis.iterationCount) : this.maxIterations;
|
|
4108
|
+
while (this._currentIteration < effectiveMax) {
|
|
4109
|
+
if (context.signal?.aborted)
|
|
4110
|
+
break;
|
|
4111
|
+
let iterationInput;
|
|
4112
|
+
if (arrayAnalysis) {
|
|
4113
|
+
iterationInput = {
|
|
4114
|
+
...this.buildIterationInput(currentInput, arrayAnalysis, this._currentIteration),
|
|
4115
|
+
_iterationIndex: this._currentIteration
|
|
4116
|
+
};
|
|
4117
|
+
} else {
|
|
4118
|
+
iterationInput = {
|
|
4119
|
+
...currentInput,
|
|
4120
|
+
_iterationIndex: this._currentIteration
|
|
4121
|
+
};
|
|
4122
|
+
}
|
|
4123
|
+
const results = await this.subGraph.run(iterationInput, {
|
|
4124
|
+
parentSignal: context.signal
|
|
4125
|
+
});
|
|
4126
|
+
currentOutput = this.subGraph.mergeExecuteOutputsToRunOutput(results, this.compoundMerge);
|
|
4127
|
+
if (!condition(currentOutput, this._currentIteration)) {
|
|
4128
|
+
break;
|
|
4129
|
+
}
|
|
4130
|
+
if (this.chainIterations) {
|
|
4131
|
+
currentInput = { ...currentInput, ...currentOutput };
|
|
4132
|
+
}
|
|
4133
|
+
this._currentIteration++;
|
|
4134
|
+
const progress = Math.min(this._currentIteration / effectiveMax * 100, 99);
|
|
4135
|
+
await context.updateProgress(progress, `Iteration ${this._currentIteration}`);
|
|
4136
|
+
}
|
|
4137
|
+
yield { type: "finish", data: currentOutput };
|
|
4138
|
+
}
|
|
3934
4139
|
getIterationContextSchema() {
|
|
3935
4140
|
return this.constructor.getIterationContextSchema();
|
|
3936
4141
|
}
|
|
@@ -4904,6 +5109,7 @@ export {
|
|
|
4904
5109
|
hasVectorOutput,
|
|
4905
5110
|
hasVectorLikeInput,
|
|
4906
5111
|
getTaskQueueRegistry,
|
|
5112
|
+
getStreamingPorts,
|
|
4907
5113
|
getPortStreamMode,
|
|
4908
5114
|
getOutputStreamMode,
|
|
4909
5115
|
getNestedValue,
|
|
@@ -4911,6 +5117,7 @@ export {
|
|
|
4911
5117
|
getJobQueueFactory,
|
|
4912
5118
|
getIterationContextSchemaForType,
|
|
4913
5119
|
getInputModeFromSchema,
|
|
5120
|
+
getAppendPortId,
|
|
4914
5121
|
findArrayPorts,
|
|
4915
5122
|
filterIterationProperties,
|
|
4916
5123
|
extractIterationProperties,
|
|
@@ -4980,4 +5187,4 @@ export {
|
|
|
4980
5187
|
ConditionalTask
|
|
4981
5188
|
};
|
|
4982
5189
|
|
|
4983
|
-
//# debugId=
|
|
5190
|
+
//# debugId=47367645DC674EAF64756E2164756E21
|