@workglow/task-graph 0.0.121 → 0.0.123

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.
Files changed (63) hide show
  1. package/dist/browser.js +103 -60
  2. package/dist/browser.js.map +25 -25
  3. package/dist/bun.js +103 -60
  4. package/dist/bun.js.map +25 -25
  5. package/dist/node.js +103 -60
  6. package/dist/node.js.map +25 -25
  7. package/dist/storage/TaskGraphRepository.d.ts.map +1 -1
  8. package/dist/storage/TaskGraphTabularRepository.d.ts +1 -1
  9. package/dist/storage/TaskGraphTabularRepository.d.ts.map +1 -1
  10. package/dist/storage/TaskOutputRepository.d.ts.map +1 -1
  11. package/dist/storage/TaskOutputTabularRepository.d.ts.map +1 -1
  12. package/dist/task/ConditionalTask.d.ts +1 -1
  13. package/dist/task/ConditionalTask.d.ts.map +1 -1
  14. package/dist/task/FallbackTask.d.ts +45 -45
  15. package/dist/task/FallbackTask.d.ts.map +1 -1
  16. package/dist/task/FallbackTaskRunner.d.ts +0 -8
  17. package/dist/task/FallbackTaskRunner.d.ts.map +1 -1
  18. package/dist/task/GraphAsTask.d.ts +1 -2
  19. package/dist/task/GraphAsTask.d.ts.map +1 -1
  20. package/dist/task/GraphAsTaskRunner.d.ts.map +1 -1
  21. package/dist/task/ITask.d.ts +2 -1
  22. package/dist/task/ITask.d.ts.map +1 -1
  23. package/dist/task/InputResolver.d.ts +2 -1
  24. package/dist/task/InputResolver.d.ts.map +1 -1
  25. package/dist/task/IteratorTask.d.ts +13 -13
  26. package/dist/task/IteratorTask.d.ts.map +1 -1
  27. package/dist/task/IteratorTaskRunner.d.ts +9 -1
  28. package/dist/task/IteratorTaskRunner.d.ts.map +1 -1
  29. package/dist/task/JobQueueTask.d.ts +10 -10
  30. package/dist/task/JobQueueTask.d.ts.map +1 -1
  31. package/dist/task/MapTask.d.ts +19 -19
  32. package/dist/task/MapTask.d.ts.map +1 -1
  33. package/dist/task/ReduceTask.d.ts +14 -14
  34. package/dist/task/ReduceTask.d.ts.map +1 -1
  35. package/dist/task/StreamTypes.d.ts +1 -1
  36. package/dist/task/StreamTypes.d.ts.map +1 -1
  37. package/dist/task/Task.d.ts +2 -1
  38. package/dist/task/Task.d.ts.map +1 -1
  39. package/dist/task/TaskError.d.ts.map +1 -1
  40. package/dist/task/TaskEvents.d.ts +16 -1
  41. package/dist/task/TaskEvents.d.ts.map +1 -1
  42. package/dist/task/TaskJSON.d.ts +4 -4
  43. package/dist/task/TaskJSON.d.ts.map +1 -1
  44. package/dist/task/TaskQueueRegistry.d.ts.map +1 -1
  45. package/dist/task/TaskRunner.d.ts.map +1 -1
  46. package/dist/task/TaskTypes.d.ts +1 -1
  47. package/dist/task/TaskTypes.d.ts.map +1 -1
  48. package/dist/task/WhileTask.d.ts +22 -22
  49. package/dist/task/WhileTask.d.ts.map +1 -1
  50. package/dist/task/WhileTaskRunner.d.ts.map +1 -1
  51. package/dist/task/index.d.ts +1 -1
  52. package/dist/task/iterationSchema.d.ts +1 -1
  53. package/dist/task/iterationSchema.d.ts.map +1 -1
  54. package/dist/task-graph/Dataflow.d.ts.map +1 -1
  55. package/dist/task-graph/GraphSchemaUtils.d.ts +1 -1
  56. package/dist/task-graph/GraphSchemaUtils.d.ts.map +1 -1
  57. package/dist/task-graph/TaskGraph.d.ts +2 -1
  58. package/dist/task-graph/TaskGraph.d.ts.map +1 -1
  59. package/dist/task-graph/TaskGraphRunner.d.ts +8 -2
  60. package/dist/task-graph/TaskGraphRunner.d.ts.map +1 -1
  61. package/dist/task-graph/TaskGraphScheduler.d.ts.map +1 -1
  62. package/dist/task-graph/Workflow.d.ts.map +1 -1
  63. package/package.json +14 -14
package/dist/bun.js CHANGED
@@ -83,7 +83,8 @@ var init_TaskTypes = __esm(() => {
83
83
  });
84
84
 
85
85
  // src/task-graph/Dataflow.ts
86
- import { areSemanticallyCompatible, EventEmitter } from "@workglow/util";
86
+ import { areSemanticallyCompatible } from "@workglow/util/schema";
87
+ import { EventEmitter } from "@workglow/util";
87
88
 
88
89
  class Dataflow {
89
90
  sourceTaskId;
@@ -914,7 +915,6 @@ function getStructuredOutputSchemas(schema) {
914
915
  function hasStructuredOutput(schema) {
915
916
  return getStructuredOutputSchemas(schema).size > 0;
916
917
  }
917
- var init_StreamTypes = () => {};
918
918
 
919
919
  // src/task/TaskRunner.ts
920
920
  import {
@@ -1293,22 +1293,21 @@ class TaskRunner {
1293
1293
  }
1294
1294
  async handleProgress(progress, message, ...args) {
1295
1295
  this.task.progress = progress;
1296
- await this.updateProgress(this.task, progress, message, ...args);
1297
1296
  this.task.emit("progress", progress, message, ...args);
1297
+ await this.updateProgress(this.task, progress, message, ...args);
1298
1298
  }
1299
1299
  }
1300
1300
  var init_TaskRunner = __esm(() => {
1301
1301
  init_TaskOutputRepository();
1302
1302
  init_Conversions();
1303
1303
  init_InputResolver();
1304
- init_StreamTypes();
1305
1304
  init_TaskError();
1306
1305
  init_TaskTypes();
1307
1306
  });
1308
1307
 
1309
1308
  // src/task/Task.ts
1309
+ import { compileSchema } from "@workglow/util/schema";
1310
1310
  import {
1311
- compileSchema,
1312
1311
  deepEqual,
1313
1312
  EventEmitter as EventEmitter3,
1314
1313
  uuid4 as uuid42
@@ -1601,7 +1600,7 @@ class Task {
1601
1600
  return this.events.waitOn(name);
1602
1601
  }
1603
1602
  emit(name, ...args) {
1604
- this._events?.emit(name, ...args);
1603
+ this.events.emit(name, ...args);
1605
1604
  }
1606
1605
  emitSchemaChange(inputSchema, outputSchema) {
1607
1606
  const finalInputSchema = inputSchema ?? this.inputSchema();
@@ -1743,13 +1742,15 @@ class Task {
1743
1742
  const extras = config.extras;
1744
1743
  if (!extras || Object.keys(extras).length === 0)
1745
1744
  delete config.extras;
1746
- const json = this.stripSymbols({
1745
+ const base = {
1747
1746
  id: this.id,
1748
1747
  type: this.type,
1749
- defaults: this.defaults,
1750
- config
1751
- });
1752
- return json;
1748
+ defaults: this.defaults
1749
+ };
1750
+ if (Object.keys(config).length > 0) {
1751
+ base.config = config;
1752
+ }
1753
+ return this.stripSymbols(base);
1753
1754
  }
1754
1755
  toDependencyJSON(options) {
1755
1756
  const json = this.toJSON(options);
@@ -1862,13 +1863,11 @@ function getNestedValue(obj, path) {
1862
1863
  }
1863
1864
  return current;
1864
1865
  }
1865
- var init_ConditionUtils = () => {};
1866
1866
 
1867
1867
  // src/task/ConditionalTask.ts
1868
1868
  import { getLogger } from "@workglow/util";
1869
1869
  var conditionalTaskConfigSchema, ConditionalTask;
1870
1870
  var init_ConditionalTask = __esm(() => {
1871
- init_ConditionUtils();
1872
1871
  init_Task();
1873
1872
  init_TaskTypes();
1874
1873
  conditionalTaskConfigSchema = {
@@ -2222,7 +2221,6 @@ class DependencyBasedScheduler {
2222
2221
  }
2223
2222
  }
2224
2223
  var init_TaskGraphScheduler = __esm(() => {
2225
- init_StreamTypes();
2226
2224
  init_TaskTypes();
2227
2225
  });
2228
2226
 
@@ -2236,6 +2234,10 @@ import {
2236
2234
  SpanStatusCode as SpanStatusCode2,
2237
2235
  uuid4 as uuid43
2238
2236
  } from "@workglow/util";
2237
+ function taskPrototypeHasOwnExecute(task) {
2238
+ const Ctor = task.constructor;
2239
+ return Object.hasOwn(Ctor.prototype, "execute");
2240
+ }
2239
2241
 
2240
2242
  class TaskGraphRunner {
2241
2243
  processScheduler;
@@ -2822,23 +2824,25 @@ class TaskGraphRunner {
2822
2824
  this.graph.emit("disabled");
2823
2825
  }
2824
2826
  async handleProgress(task, progress, message, ...args) {
2825
- const total = this.graph.getTasks().length;
2826
- if (total > 1) {
2827
- const completed = this.graph.getTasks().reduce((acc, t) => acc + t.progress, 0);
2828
- progress = Math.round(completed / total);
2827
+ const contributors = this.graph.getTasks().filter(taskPrototypeHasOwnExecute);
2828
+ if (contributors.length > 1) {
2829
+ const sum = contributors.reduce((acc, t) => acc + t.progress, 0);
2830
+ progress = Math.round(sum / contributors.length);
2831
+ } else if (contributors.length === 1) {
2832
+ const [only] = contributors;
2833
+ progress = only.progress;
2829
2834
  }
2830
2835
  this.pushStatusFromNodeToEdges(this.graph, task);
2836
+ this.graph.emit("graph_progress", progress, message, args);
2831
2837
  if (task.runOutputData && Object.keys(task.runOutputData).length > 0) {
2832
2838
  await this.pushOutputFromNodeToEdges(task, task.runOutputData);
2833
2839
  }
2834
- this.graph.emit("graph_progress", progress, message, args);
2835
2840
  }
2836
2841
  }
2837
2842
  var PROPERTY_ARRAY = "PROPERTY_ARRAY", GRAPH_RESULT_ARRAY = "GRAPH_RESULT_ARRAY";
2838
2843
  var init_TaskGraphRunner = __esm(() => {
2839
2844
  init_TaskOutputRepository();
2840
2845
  init_ConditionalTask();
2841
- init_StreamTypes();
2842
2846
  init_TaskError();
2843
2847
  init_TaskTypes();
2844
2848
  init_Dataflow();
@@ -2902,7 +2906,7 @@ __export(exports_GraphAsTask, {
2902
2906
  graphAsTaskConfigSchema: () => graphAsTaskConfigSchema,
2903
2907
  GraphAsTask: () => GraphAsTask
2904
2908
  });
2905
- import { compileSchema as compileSchema2 } from "@workglow/util";
2909
+ import { compileSchema as compileSchema2 } from "@workglow/util/schema";
2906
2910
  var graphAsTaskConfigSchema, GraphAsTask;
2907
2911
  var init_GraphAsTask = __esm(() => {
2908
2912
  init_GraphSchemaUtils();
@@ -3203,7 +3207,8 @@ var init_TaskGraphEvents = __esm(() => {
3203
3207
  });
3204
3208
 
3205
3209
  // src/task-graph/TaskGraph.ts
3206
- import { DirectedAcyclicGraph, EventEmitter as EventEmitter4, uuid4 as uuid44 } from "@workglow/util";
3210
+ import { DirectedAcyclicGraph } from "@workglow/util/graph";
3211
+ import { EventEmitter as EventEmitter4, uuid4 as uuid44 } from "@workglow/util";
3207
3212
 
3208
3213
  class TaskGraph {
3209
3214
  outputCache;
@@ -3516,7 +3521,6 @@ init_Dataflow();
3516
3521
 
3517
3522
  // src/task-graph/Workflow.ts
3518
3523
  init_GraphAsTask();
3519
- init_StreamTypes();
3520
3524
  init_TaskError();
3521
3525
  init_Conversions();
3522
3526
  init_Dataflow();
@@ -4615,7 +4619,6 @@ function resetMethodNameCache() {
4615
4619
  }
4616
4620
  // src/task/index.ts
4617
4621
  init_ConditionalTask();
4618
- init_ConditionUtils();
4619
4622
 
4620
4623
  // src/task/FallbackTask.ts
4621
4624
  init_GraphAsTask();
@@ -4839,6 +4842,9 @@ init_GraphAsTaskRunner();
4839
4842
  import { uuid4 as uuid46 } from "@workglow/util";
4840
4843
 
4841
4844
  class IteratorTaskRunner extends GraphAsTaskRunner {
4845
+ aggregatingParentMapProgress = false;
4846
+ mapPartialProgress = [];
4847
+ mapPartialIterationCount = 0;
4842
4848
  async executeTask(input) {
4843
4849
  const analysis = this.task.analyzeIterationInput(input);
4844
4850
  if (analysis.iterationCount === 0) {
@@ -4860,30 +4866,43 @@ class IteratorTaskRunner extends GraphAsTaskRunner {
4860
4866
  const concurrency = Math.max(1, Math.min(requestedConcurrency, iterationCount));
4861
4867
  const orderedResults = preserveOrder ? new Array(iterationCount) : [];
4862
4868
  const completionOrderResults = [];
4863
- let completedCount = 0;
4864
- for (let batchStart = 0;batchStart < iterationCount; batchStart += batchSize) {
4865
- if (this.abortController?.signal.aborted) {
4866
- break;
4867
- }
4868
- const batchEnd = Math.min(batchStart + batchSize, iterationCount);
4869
- const batchIndices = Array.from({ length: batchEnd - batchStart }, (_, i) => batchStart + i);
4870
- const batchResults = await this.executeBatch(batchIndices, analysis, iterationCount, concurrency, async () => {
4871
- completedCount++;
4872
- const progress = Math.round(completedCount / iterationCount * 100);
4873
- await this.handleProgress(progress, `Completed ${completedCount}/${iterationCount} iterations`);
4874
- });
4875
- for (const { index, result } of batchResults) {
4876
- if (result === undefined)
4877
- continue;
4878
- if (preserveOrder) {
4879
- orderedResults[index] = result;
4880
- } else {
4881
- completionOrderResults.push(result);
4869
+ this.aggregatingParentMapProgress = true;
4870
+ this.mapPartialIterationCount = iterationCount;
4871
+ this.mapPartialProgress = new Array(iterationCount).fill(0);
4872
+ try {
4873
+ for (let batchStart = 0;batchStart < iterationCount; batchStart += batchSize) {
4874
+ if (this.abortController?.signal.aborted) {
4875
+ break;
4876
+ }
4877
+ const batchEnd = Math.min(batchStart + batchSize, iterationCount);
4878
+ const batchIndices = Array.from({ length: batchEnd - batchStart }, (_, i) => batchStart + i);
4879
+ const batchResults = await this.executeBatch(batchIndices, analysis, iterationCount, concurrency, undefined);
4880
+ for (const { index, result } of batchResults) {
4881
+ if (result === undefined)
4882
+ continue;
4883
+ if (preserveOrder) {
4884
+ orderedResults[index] = result;
4885
+ } else {
4886
+ completionOrderResults.push(result);
4887
+ }
4882
4888
  }
4883
4889
  }
4890
+ const collected = preserveOrder ? orderedResults.filter((result) => result !== undefined) : completionOrderResults;
4891
+ return this.task.collectResults(collected);
4892
+ } finally {
4893
+ this.aggregatingParentMapProgress = false;
4884
4894
  }
4885
- const collected = preserveOrder ? orderedResults.filter((result) => result !== undefined) : completionOrderResults;
4886
- return this.task.collectResults(collected);
4895
+ }
4896
+ emitMapParentProgressFromPartials(childMessage) {
4897
+ const n = this.mapPartialIterationCount;
4898
+ if (n <= 0)
4899
+ return;
4900
+ const sum = this.mapPartialProgress.reduce((a, b) => a + b, 0);
4901
+ const overall = Math.round(sum / n);
4902
+ const done = this.mapPartialProgress.filter((v) => v >= 100).length;
4903
+ const base = `Map ${done}/${n}`;
4904
+ const msg = childMessage ? `${base} \u2014 ${childMessage}` : `${base} iterations`;
4905
+ this.handleProgress(overall, msg);
4887
4906
  }
4888
4907
  async executeReduceIterations(analysis) {
4889
4908
  const iterationCount = analysis.iterationCount;
@@ -4895,7 +4914,7 @@ class IteratorTaskRunner extends GraphAsTaskRunner {
4895
4914
  const iterationInput = this.task.buildIterationRunInput(analysis, index, iterationCount, {
4896
4915
  accumulator
4897
4916
  });
4898
- const iterationResult = await this.executeSubgraphIteration(iterationInput);
4917
+ const iterationResult = await this.executeSubgraphIteration(iterationInput, index, iterationCount);
4899
4918
  accumulator = this.task.mergeIterationIntoAccumulator(accumulator, iterationResult, index);
4900
4919
  const progress = Math.round((index + 1) / iterationCount * 100);
4901
4920
  await this.handleProgress(progress, `Completed ${index + 1}/${iterationCount} iterations`);
@@ -4918,7 +4937,7 @@ class IteratorTaskRunner extends GraphAsTaskRunner {
4918
4937
  }
4919
4938
  const index = indices[position];
4920
4939
  const iterationInput = this.task.buildIterationRunInput(analysis, index, iterationCount);
4921
- const result = await this.executeSubgraphIteration(iterationInput);
4940
+ const result = await this.executeSubgraphIteration(iterationInput, index, iterationCount);
4922
4941
  results.push({ index, result });
4923
4942
  await onItemComplete?.();
4924
4943
  }
@@ -4945,20 +4964,44 @@ class IteratorTaskRunner extends GraphAsTaskRunner {
4945
4964
  }
4946
4965
  return clone;
4947
4966
  }
4948
- async executeSubgraphIteration(input) {
4967
+ async executeSubgraphIteration(input, index, iterationCount) {
4949
4968
  if (this.abortController?.signal.aborted) {
4950
4969
  return;
4951
4970
  }
4952
4971
  const graphClone = this.cloneGraph(this.task.subGraph);
4953
- const results = await graphClone.run(input, {
4954
- parentSignal: this.abortController?.signal,
4955
- outputCache: this.outputCache,
4956
- registry: this.registry
4957
- });
4958
- if (results.length === 0) {
4959
- return;
4972
+ this.task.emit("iteration_start", index, iterationCount);
4973
+ const taskProgressUnsubs = [];
4974
+ for (const t of graphClone.getTasks()) {
4975
+ const fn = (p, message) => {
4976
+ this.task.emit("iteration_progress", index, iterationCount, p, message);
4977
+ if (this.aggregatingParentMapProgress && this.mapPartialIterationCount > 0) {
4978
+ this.mapPartialProgress[index] = Math.max(this.mapPartialProgress[index] ?? 0, p);
4979
+ this.emitMapParentProgressFromPartials(message);
4980
+ }
4981
+ };
4982
+ t.events.on("progress", fn);
4983
+ taskProgressUnsubs.push({ task: t, fn });
4984
+ }
4985
+ try {
4986
+ const results = await graphClone.run(input, {
4987
+ parentSignal: this.abortController?.signal,
4988
+ outputCache: this.outputCache,
4989
+ registry: this.registry
4990
+ });
4991
+ if (results.length === 0) {
4992
+ return;
4993
+ }
4994
+ return graphClone.mergeExecuteOutputsToRunOutput(results, this.task.compoundMerge);
4995
+ } finally {
4996
+ for (const { task, fn } of taskProgressUnsubs) {
4997
+ task.events.off("progress", fn);
4998
+ }
4999
+ if (this.aggregatingParentMapProgress && this.mapPartialIterationCount > 0) {
5000
+ this.mapPartialProgress[index] = 100;
5001
+ this.emitMapParentProgressFromPartials();
5002
+ }
5003
+ this.task.emit("iteration_complete", index, iterationCount);
4960
5004
  }
4961
- return graphClone.mergeExecuteOutputsToRunOutput(results, this.task.compoundMerge);
4962
5005
  }
4963
5006
  }
4964
5007
 
@@ -5456,7 +5499,6 @@ class IteratorTask extends GraphAsTask {
5456
5499
  }
5457
5500
 
5458
5501
  // src/task/WhileTask.ts
5459
- init_ConditionUtils();
5460
5502
  init_GraphAsTask();
5461
5503
  init_TaskError();
5462
5504
 
@@ -6464,7 +6506,6 @@ queueMicrotask(() => {
6464
6506
  });
6465
6507
 
6466
6508
  // src/task/index.ts
6467
- init_StreamTypes();
6468
6509
  init_Task();
6469
6510
  init_TaskError();
6470
6511
 
@@ -6669,7 +6710,8 @@ init_TaskOutputRepository();
6669
6710
 
6670
6711
  // src/storage/TaskOutputTabularRepository.ts
6671
6712
  init_TaskOutputRepository();
6672
- import { compress, decompress, makeFingerprint } from "@workglow/util";
6713
+ import { compress, decompress } from "@workglow/util/compress";
6714
+ import { makeFingerprint } from "@workglow/util";
6673
6715
  var TaskOutputSchema = {
6674
6716
  type: "object",
6675
6717
  properties: {
@@ -6753,6 +6795,7 @@ class TaskOutputTabularRepository extends TaskOutputRepository {
6753
6795
  export {
6754
6796
  wrapSchemaInArray,
6755
6797
  whileTaskConfigSchema,
6798
+ taskPrototypeHasOwnExecute,
6756
6799
  setTaskQueueRegistry,
6757
6800
  setGlobalTaskConstructors,
6758
6801
  serialGraph,
@@ -6874,4 +6917,4 @@ export {
6874
6917
  ConditionalTask
6875
6918
  };
6876
6919
 
6877
- //# debugId=9EEB6F11C7BDA7A964756E2164756E21
6920
+ //# debugId=9A71E9C04775D82864756E2164756E21