@cadenza.io/core 3.10.0 → 3.12.0

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/index.mjs CHANGED
@@ -41,6 +41,7 @@ function formatTimestamp(timestamp) {
41
41
  }
42
42
 
43
43
  // src/engine/SignalBroker.ts
44
+ import { v4 as uuid } from "uuid";
44
45
  var SignalBroker = class _SignalBroker {
45
46
  // execId -> emitted signals
46
47
  constructor() {
@@ -51,10 +52,6 @@ var SignalBroker = class _SignalBroker {
51
52
  this.emitStacks = /* @__PURE__ */ new Map();
52
53
  this.addSignal("meta.signal_broker.added");
53
54
  }
54
- /**
55
- * Singleton instance for signal management.
56
- * @returns The broker instance.
57
- */
58
55
  static get instance() {
59
56
  if (!this.instance_) {
60
57
  this.instance_ = new _SignalBroker();
@@ -67,6 +64,15 @@ var SignalBroker = class _SignalBroker {
67
64
  setVerbose(value) {
68
65
  this.verbose = value;
69
66
  }
67
+ /**
68
+ * Validates the provided signal name string to ensure it adheres to specific formatting rules.
69
+ * Throws an error if any of the validation checks fail.
70
+ *
71
+ * @param {string} signalName - The signal name to be validated.
72
+ * @return {void} - Returns nothing if the signal name is valid.
73
+ * @throws {Error} - Throws an error if the signal name is longer than 100 characters, contains spaces,
74
+ * contains backslashes, or contains uppercase letters in restricted parts of the name.
75
+ */
70
76
  validateSignalName(signalName) {
71
77
  if (signalName.length > 100) {
72
78
  throw new Error(
@@ -96,6 +102,11 @@ var SignalBroker = class _SignalBroker {
96
102
  this.runner = runner;
97
103
  this.metaRunner = metaRunner;
98
104
  }
105
+ /**
106
+ * Initializes and sets up the various tasks for managing and processing signals.
107
+ *
108
+ * @return {void} This method does not return a value.
109
+ */
99
110
  init() {
100
111
  this.clearSignalsTask = Cadenza.createDebounceMetaTask(
101
112
  "Execute and clear queued signals",
@@ -159,6 +170,15 @@ var SignalBroker = class _SignalBroker {
159
170
  }
160
171
  }
161
172
  }
173
+ /**
174
+ * Schedules a signal to be emitted after a specified delay or at an exact date and time.
175
+ *
176
+ * @param {string} signal - The name of the signal to be emitted.
177
+ * @param {AnyObject} context - The context to be passed along with the signal.
178
+ * @param {number} [timeoutMs=60000] - The delay in milliseconds before the signal is emitted. Defaults to 60,000 ms.
179
+ * @param {Date} [exactDateTime] - An exact date and time at which to emit the signal. If provided, this overrides the `timeoutMs`.
180
+ * @return {AbortController} An AbortController instance that can be used to cancel the scheduled signal emission.
181
+ */
162
182
  schedule(signal, context, timeoutMs = 6e4, exactDateTime) {
163
183
  let delay = timeoutMs;
164
184
  if (exactDateTime != null) {
@@ -221,11 +241,12 @@ var SignalBroker = class _SignalBroker {
221
241
  };
222
242
  }
223
243
  /**
224
- * Emits a signal and bubbles to matching wildcards/parents (e.g., 'a.b.action' triggers 'a.b.action', 'a.b.*', 'a.*').
225
- * @param signal The signal name.
226
- * @param context The payload.
227
- * @edge Fire-and-forget; guards against loops per execId (from context.__graphExecId).
228
- * @edge For distribution, SignalTask can prefix and proxy remote.
244
+ * Emits a signal with the specified context, triggering any associated handlers for that signal.
245
+ *
246
+ * @param {string} signal - The name of the signal to emit.
247
+ * @param {AnyObject} [context={}] - An optional context object containing additional information or metadata
248
+ * associated with the signal. If the context includes a `__routineExecId`, it will be handled accordingly.
249
+ * @return {void} This method does not return a value.
229
250
  */
230
251
  emit(signal, context = {}) {
231
252
  const execId = context.__routineExecId || "global";
@@ -242,20 +263,62 @@ var SignalBroker = class _SignalBroker {
242
263
  if (stack.size === 0) this.emitStacks.delete(execId);
243
264
  }
244
265
  }
266
+ /**
267
+ * Executes a signal by emitting events, updating context, and invoking listeners.
268
+ * Creates a new execution trace if necessary and updates the context with relevant metadata.
269
+ * Handles specific, hierarchy-based, and wildcard signals.
270
+ *
271
+ * @param {string} signal - The signal name to be executed, potentially including namespaces or tags (e.g., "meta.*" or "signal:type").
272
+ * @param {AnyObject} context - An object containing relevant metadata and execution details used for handling the signal.
273
+ * @return {boolean} Returns true if any listeners were successfully executed, otherwise false.
274
+ */
245
275
  execute(signal, context) {
246
276
  const isMeta = signal.includes("meta.");
247
277
  const isSubMeta = signal.includes("sub_meta.") || context.__isSubMeta;
248
278
  const isMetric = context.__signalEmission?.isMetric;
249
279
  if (!isSubMeta && (!isMeta || this.debug)) {
280
+ const isNewTrace = !context.__signalEmission?.executionTraceId && !context.__metadata?.__executionTraceId && !context.__executionTraceId;
281
+ const executionTraceId = context.__metadata?.__executionTraceId ?? context.__executionTraceId ?? uuid();
282
+ if (isNewTrace) {
283
+ this.emit("sub_meta.signal_broker.new_trace", {
284
+ data: {
285
+ uuid: executionTraceId,
286
+ issuer_type: "service",
287
+ // TODO: Add issuer type
288
+ issuer_id: context.__metadata?.__issuerId ?? context.__issuerId ?? null,
289
+ issued_at: formatTimestamp(Date.now()),
290
+ intent: context.__metadata?.__intent ?? context.__intent ?? null,
291
+ context: {
292
+ id: uuid(),
293
+ context
294
+ },
295
+ is_meta: isMeta
296
+ },
297
+ metadata: {
298
+ __executionTraceId: executionTraceId
299
+ }
300
+ });
301
+ context.__metadata = {
302
+ ...context.__metadata,
303
+ __executionTraceId: executionTraceId
304
+ };
305
+ }
250
306
  const emittedAt = Date.now();
307
+ const signalParts = signal.split(":");
308
+ const signalName = signalParts[0];
309
+ const signalTag = signalParts.length > 1 ? signalParts[1] : null;
251
310
  context.__signalEmission = {
252
311
  ...context.__signalEmission ?? {},
253
- signalName: signal,
312
+ uuid: uuid(),
313
+ executionTraceId,
314
+ signalName,
315
+ signalTag,
254
316
  emittedAt: formatTimestamp(emittedAt),
255
317
  consumed: false,
256
318
  consumedBy: null,
257
319
  isMeta
258
320
  };
321
+ this.emit("sub_meta.signal_broker.emitting_signal", context);
259
322
  } else if (isSubMeta) {
260
323
  context.__isSubMeta = true;
261
324
  delete context.__signalEmission;
@@ -278,6 +341,15 @@ var SignalBroker = class _SignalBroker {
278
341
  }
279
342
  return executed;
280
343
  }
344
+ /**
345
+ * Executes the tasks associated with a given signal and context.
346
+ * It processes both normal and meta tasks depending on the signal type
347
+ * and the availability of the appropriate runner.
348
+ *
349
+ * @param {string} signal - The signal identifier that determines which tasks to execute.
350
+ * @param {AnyObject} context - The context object passed to the task execution function.
351
+ * @return {boolean} - Returns true if tasks were executed; otherwise, false.
352
+ */
281
353
  executeListener(signal, context) {
282
354
  const obs = this.signalObservers.get(signal);
283
355
  if (!obs || obs.tasks.size === 0) {
@@ -303,6 +375,15 @@ var SignalBroker = class _SignalBroker {
303
375
  }
304
376
  return false;
305
377
  }
378
+ /**
379
+ * Adds a signal to the signalObservers for tracking and execution.
380
+ * Performs validation on the signal name and emits a meta signal event when added.
381
+ * If the signal contains a namespace (denoted by a colon ":"), its base signal is
382
+ * also added if it doesn't already exist.
383
+ *
384
+ * @param {string} signal - The name of the signal to be added.
385
+ * @return {void} This method does not return any value.
386
+ */
306
387
  addSignal(signal) {
307
388
  let _signal = signal;
308
389
  if (!this.signalObservers.has(_signal)) {
@@ -328,7 +409,6 @@ var SignalBroker = class _SignalBroker {
328
409
  this.emit("meta.signal_broker.added", { __signalName: _signal });
329
410
  }
330
411
  }
331
- // TODO schedule signals
332
412
  /**
333
413
  * Lists all observed signals.
334
414
  * @returns Array of signals.
@@ -343,10 +423,10 @@ var SignalBroker = class _SignalBroker {
343
423
  };
344
424
 
345
425
  // src/engine/GraphRunner.ts
346
- import { v4 as uuid4 } from "uuid";
426
+ import { v4 as uuid5 } from "uuid";
347
427
 
348
428
  // src/engine/GraphRun.ts
349
- import { v4 as uuid } from "uuid";
429
+ import { v4 as uuid2 } from "uuid";
350
430
 
351
431
  // src/utils/ColorRandomizer.ts
352
432
  var ColorRandomizer = class {
@@ -537,7 +617,7 @@ var VueFlowExporter = class {
537
617
  // src/engine/GraphRun.ts
538
618
  var GraphRun = class {
539
619
  constructor(strategy) {
540
- this.id = uuid();
620
+ this.id = uuid2();
541
621
  this.strategy = strategy;
542
622
  this.strategy.setRunInstance(this);
543
623
  this.exporter = new VueFlowExporter();
@@ -591,10 +671,10 @@ var GraphRun = class {
591
671
  };
592
672
 
593
673
  // src/graph/execution/GraphNode.ts
594
- import { v4 as uuid3 } from "uuid";
674
+ import { v4 as uuid4 } from "uuid";
595
675
 
596
676
  // src/graph/context/GraphContext.ts
597
- import { v4 as uuid2 } from "uuid";
677
+ import { v4 as uuid3 } from "uuid";
598
678
  var GraphContext = class _GraphContext {
599
679
  // __keys, frozen
600
680
  constructor(context) {
@@ -608,7 +688,7 @@ var GraphContext = class _GraphContext {
608
688
  this.metadata = Object.fromEntries(
609
689
  Object.entries(this.fullContext).filter(([key]) => key.startsWith("__"))
610
690
  );
611
- this.id = uuid2();
691
+ this.id = uuid3();
612
692
  }
613
693
  /**
614
694
  * Gets frozen user data (read-only, no clone).
@@ -617,6 +697,11 @@ var GraphContext = class _GraphContext {
617
697
  getContext() {
618
698
  return this.userData;
619
699
  }
700
+ /**
701
+ * Clones the current user context data and returns a deep-cloned copy of it.
702
+ *
703
+ * @return {AnyObject} A deep-cloned copy of the user context data.
704
+ */
620
705
  getClonedContext() {
621
706
  return deepCloneFilter(this.userData);
622
707
  }
@@ -627,6 +712,11 @@ var GraphContext = class _GraphContext {
627
712
  getFullContext() {
628
713
  return this.fullContext;
629
714
  }
715
+ /**
716
+ * Creates and returns a deep-cloned version of the fullContext object.
717
+ *
718
+ * @return {AnyObject} A deep copy of the fullContext instance, preserving all nested structures and data.
719
+ */
630
720
  getClonedFullContext() {
631
721
  return deepCloneFilter(this.fullContext);
632
722
  }
@@ -653,10 +743,11 @@ var GraphContext = class _GraphContext {
653
743
  return new _GraphContext(context);
654
744
  }
655
745
  /**
656
- * Combines with another for uniques (joins userData).
657
- * @param otherContext The other.
658
- * @returns New combined GraphContext.
659
- * @edge Appends other.userData to joinedContexts in userData.
746
+ * Combines the current GraphContext with another GraphContext, merging their user data
747
+ * and full context into a new GraphContext instance.
748
+ *
749
+ * @param {GraphContext} otherContext - The other GraphContext to combine with the current one.
750
+ * @return {GraphContext} A new GraphContext instance containing merged data from both contexts.
660
751
  */
661
752
  combine(otherContext) {
662
753
  const newUser = { ...this.userData };
@@ -774,7 +865,7 @@ var GraphNode = class _GraphNode extends SignalEmitter {
774
865
  this.destroyed = false;
775
866
  this.debug = false;
776
867
  this.verbose = false;
777
- this.id = uuid3();
868
+ this.id = uuid4();
778
869
  this.task = task;
779
870
  this.context = context;
780
871
  this.retryCount = task.retryCount;
@@ -784,6 +875,8 @@ var GraphNode = class _GraphNode extends SignalEmitter {
784
875
  this.splitGroupId = routineExecId;
785
876
  this.debug = debug;
786
877
  this.verbose = verbose;
878
+ const ctx = context.getMetadata();
879
+ this.executionTraceId = ctx.__executionTraceId ?? ctx.__metadata?.__executionTraceId;
787
880
  if (!this.task || !this.task.validateInput) {
788
881
  console.log("task not found", this.task, this.context);
789
882
  }
@@ -809,15 +902,40 @@ var GraphNode = class _GraphNode extends SignalEmitter {
809
902
  graphDone() {
810
903
  return this.graphComplete;
811
904
  }
905
+ /**
906
+ * Compares the current GraphNode instance with another GraphNode to determine if they are considered equal.
907
+ *
908
+ * @param {GraphNode} node - The GraphNode object to compare with the current instance.
909
+ * @return {boolean} Returns true if the nodes share the same task, context, and belong to the same graph; otherwise, false.
910
+ */
812
911
  isEqualTo(node) {
813
912
  return this.sharesTaskWith(node) && this.sharesContextWith(node) && this.isPartOfSameGraph(node);
814
913
  }
914
+ /**
915
+ * Determines if the given node is part of the same graph as the current node.
916
+ *
917
+ * @param {GraphNode} node - The node to compare with the current node.
918
+ * @return {boolean} Returns true if the provided node is part of the same graph
919
+ * (i.e., has the same routineExecId), otherwise false.
920
+ */
815
921
  isPartOfSameGraph(node) {
816
922
  return this.routineExecId === node.routineExecId;
817
923
  }
924
+ /**
925
+ * Determines whether the current instance shares a task with the provided node.
926
+ *
927
+ * @param {GraphNode} node - The graph node to compare with the current instance.
928
+ * @return {boolean} Returns true if the task names of both nodes match, otherwise false.
929
+ */
818
930
  sharesTaskWith(node) {
819
931
  return this.task.name === node.task.name;
820
932
  }
933
+ /**
934
+ * Determines whether the current node shares the same context as the specified node.
935
+ *
936
+ * @param {GraphNode} node - The graph node to compare with the current node's context.
937
+ * @return {boolean} True if both nodes share the same context; otherwise, false.
938
+ */
821
939
  sharesContextWith(node) {
822
940
  return this.context.id === node.context.id;
823
941
  }
@@ -827,9 +945,26 @@ var GraphNode = class _GraphNode extends SignalEmitter {
827
945
  getConcurrency() {
828
946
  return this.task.concurrency;
829
947
  }
948
+ /**
949
+ * Retrieves the tag associated with the current task and context.
950
+ *
951
+ * @return {string} The tag retrieved from the task within the given context.
952
+ */
830
953
  getTag() {
831
954
  return this.task.getTag(this.context);
832
955
  }
956
+ /**
957
+ * Schedules the current node/task on the specified graph layer if applicable.
958
+ *
959
+ * This method assesses whether the current node/task should be scheduled
960
+ * on the given graph layer. It ensures that tasks are only scheduled
961
+ * under certain conditions, such as checking if the task shares
962
+ * execution contexts or dependencies with other nodes, and handles
963
+ * various metadata emissions and context updates during the scheduling process.
964
+ *
965
+ * @param {GraphLayer} layer - The graph layer on which the current task should be scheduled.
966
+ * @returns {void} Does not return a value.
967
+ */
833
968
  scheduleOn(layer) {
834
969
  let shouldSchedule = true;
835
970
  const nodes = layer.getNodesByRoutineExecId(this.routineExecId);
@@ -853,7 +988,7 @@ var GraphNode = class _GraphNode extends SignalEmitter {
853
988
  data: {
854
989
  uuid: this.id,
855
990
  routineExecutionId: this.routineExecId,
856
- executionTraceId: context.__executionTraceId ?? context.__metadata?.__executionTraceId,
991
+ executionTraceId: this.executionTraceId,
857
992
  context: this.previousNodes.length === 0 ? this.context.id : this.context.export(),
858
993
  taskName: this.task.name,
859
994
  taskVersion: this.task.version,
@@ -897,10 +1032,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
897
1032
  if (context.__signalEmission?.consumed === false && (!this.isMeta() || this.debug)) {
898
1033
  this.emitMetricsWithMetadata("meta.node.consumed_signal", {
899
1034
  data: {
1035
+ signalEmissionId: context.__signalEmission.uuid,
900
1036
  signalName: context.__signalEmission.signalName,
1037
+ signalTag: context.__signalEmission.signalTag,
901
1038
  taskName: this.task.name,
902
1039
  taskVersion: this.task.version,
903
1040
  taskExecutionId: this.id,
1041
+ routineExecutionId: this.routineExecId,
1042
+ executionTraceId: this.executionTraceId,
904
1043
  consumedAt: formatTimestamp(scheduledAt)
905
1044
  }
906
1045
  });
@@ -909,6 +1048,18 @@ var GraphNode = class _GraphNode extends SignalEmitter {
909
1048
  }
910
1049
  }
911
1050
  }
1051
+ /**
1052
+ * Starts the execution process by initializing the execution start timestamp,
1053
+ * emitting relevant metadata, and logging debug information if applicable.
1054
+ *
1055
+ * The method performs the following actions:
1056
+ * 1. Sets the execution start timestamp if it's not already initialized.
1057
+ * 2. Emits metrics with metadata about the routine execution starting, including additional data if there are no previous nodes.
1058
+ * 3. Optionally logs debug or verbose information based on the current settings.
1059
+ * 4. Emits additional metrics to indicate that the execution has started.
1060
+ *
1061
+ * @return {number} The timestamp indicating when the execution started.
1062
+ */
912
1063
  start() {
913
1064
  if (this.executionStart === 0) {
914
1065
  this.executionStart = Date.now();
@@ -934,6 +1085,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
934
1085
  });
935
1086
  return this.executionStart;
936
1087
  }
1088
+ /**
1089
+ * Marks the end of an execution process, performs necessary cleanup, emits
1090
+ * metrics with associated metadata, and signals the completion of execution.
1091
+ * Also handles specific cases when the graph completes.
1092
+ *
1093
+ * @return {number} The timestamp corresponding to the end of execution. If execution
1094
+ * was not started, it returns 0.
1095
+ */
937
1096
  end() {
938
1097
  if (this.executionStart === 0) {
939
1098
  return 0;
@@ -986,6 +1145,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
986
1145
  }
987
1146
  return end;
988
1147
  }
1148
+ /**
1149
+ * Executes the main logic of the task, including input validation, processing, and post-processing.
1150
+ * Handles both synchronous and asynchronous workflows.
1151
+ *
1152
+ * @return {Array|Promise|undefined} Returns the next nodes to process if available.
1153
+ * If asynchronous processing is required, it returns a Promise that resolves to the next nodes.
1154
+ * Returns undefined in case of an error during input validation or preconditions that prevent processing.
1155
+ */
989
1156
  execute() {
990
1157
  if (!this.divided && !this.processing) {
991
1158
  this.processing = true;
@@ -1009,6 +1176,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1009
1176
  }
1010
1177
  return this.nextNodes;
1011
1178
  }
1179
+ /**
1180
+ * Executes an asynchronous workflow that processes a result and retries on errors.
1181
+ * The method handles different result states, checks for error properties, and invokes
1182
+ * error handling when necessary.
1183
+ *
1184
+ * @return {Promise<void>} A promise that resolves when the operation completes successfully,
1185
+ * or rejects if an unhandled error occurs.
1186
+ */
1012
1187
  async workAsync() {
1013
1188
  try {
1014
1189
  this.result = await this.result;
@@ -1025,6 +1200,12 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1025
1200
  }
1026
1201
  }
1027
1202
  }
1203
+ /**
1204
+ * Executes an asynchronous operation, processes the result, and determines the next nodes to execute.
1205
+ * This method will manage asynchronous work, handle post-processing of results, and ensure proper handling of both synchronous and asynchronous next node configurations.
1206
+ *
1207
+ * @return {Promise<any>} A promise resolving to the next nodes to be executed. Can be the result of post-processing or a directly resolved next nodes object.
1208
+ */
1028
1209
  async executeAsync() {
1029
1210
  await this.workAsync();
1030
1211
  const nextNodes = this.postProcess();
@@ -1034,6 +1215,16 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1034
1215
  this.nextNodes = nextNodes;
1035
1216
  return this.nextNodes;
1036
1217
  }
1218
+ /**
1219
+ * Executes the task associated with the current instance, using the given context,
1220
+ * progress callback, and metadata. If the task fails or an error occurs, it attempts
1221
+ * to retry the execution. If the retry is not successful, it propagates the error and
1222
+ * returns the result.
1223
+ *
1224
+ * @return {TaskResult | Promise<TaskResult>} The result of the task execution, or a
1225
+ * promise that resolves to the task result. This includes handling for retries on
1226
+ * failure and error propagation.
1227
+ */
1037
1228
  work() {
1038
1229
  try {
1039
1230
  const result = this.task.execute(
@@ -1057,39 +1248,67 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1057
1248
  });
1058
1249
  }
1059
1250
  }
1251
+ /**
1252
+ * Emits a signal along with its associated metadata. The metadata includes
1253
+ * task-specific information such as task name, version, execution ID, and
1254
+ * additional context metadata like routine execution ID and execution trace ID.
1255
+ * This method is designed to enrich emitted signals with relevant details
1256
+ * before broadcasting them.
1257
+ *
1258
+ * @param {string} signal - The name of the signal to be emitted.
1259
+ * @param {AnyObject} data - The data object to be sent along with the signal. Metadata
1260
+ * will be injected into this object before being emitted.
1261
+ * @return {void} No return value.
1262
+ */
1060
1263
  emitWithMetadata(signal, data) {
1061
1264
  if (!this.task?.isHidden) {
1062
1265
  data.__signalEmission = {
1063
1266
  taskName: this.task.name,
1064
1267
  taskVersion: this.task.version,
1065
- taskExecutionId: this.id
1268
+ taskExecutionId: this.id,
1269
+ routineExecutionId: this.routineExecId,
1270
+ executionTraceId: this.executionTraceId,
1271
+ isMetric: false
1066
1272
  };
1067
- const context = this.context.getMetadata();
1068
1273
  data.__metadata = {
1069
1274
  ...data.__metadata,
1070
1275
  __routineExecId: this.routineExecId,
1071
- __executionTraceId: context.__metadata?.__executionTraceId ?? context.__executionTraceId
1276
+ __executionTraceId: this.executionTraceId
1072
1277
  };
1073
1278
  }
1074
1279
  this.emit(signal, data);
1075
1280
  }
1281
+ /**
1282
+ * Emits metrics with additional metadata describing the task execution and context.
1283
+ *
1284
+ * @param {string} signal - The signal name being emitted.
1285
+ * @param {AnyObject} data - The data associated with the signal emission, enriched with metadata.
1286
+ * @return {void} Emits the signal with enriched data and does not return a value.
1287
+ */
1076
1288
  emitMetricsWithMetadata(signal, data) {
1077
1289
  if (!this.task?.isHidden) {
1078
1290
  data.__signalEmission = {
1079
1291
  taskName: this.task.name,
1080
1292
  taskVersion: this.task.version,
1081
1293
  taskExecutionId: this.id,
1294
+ routineExecutionId: this.routineExecId,
1295
+ executionTraceId: this.executionTraceId,
1082
1296
  isMetric: true
1083
1297
  };
1084
- const context = this.context.getMetadata();
1085
1298
  data.__metadata = {
1086
1299
  ...data.__metadata,
1087
1300
  __routineExecId: this.routineExecId,
1088
- __executionTraceId: context.__metadata?.__executionTraceId ?? context.__executionTraceId
1301
+ __executionTraceId: this.executionTraceId
1089
1302
  };
1090
1303
  }
1091
1304
  this.emitMetrics(signal, data);
1092
1305
  }
1306
+ /**
1307
+ * Updates the progress of a task and emits metrics with associated metadata.
1308
+ *
1309
+ * @param {number} progress - A number representing the progress value, which will be clamped between 0 and 1.
1310
+ * @return {void} This method does not return a value.
1311
+ */
1093
1312
  onProgress(progress) {
1094
1313
  progress = Math.min(Math.max(0, progress), 1);
1095
1314
  this.emitMetricsWithMetadata("meta.node.progress", {
@@ -1112,6 +1331,18 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1112
1331
  }
1113
1332
  );
1114
1333
  }
1334
+ /**
1335
+ * Processes the result of the current operation, validates it, and determines the next set of nodes.
1336
+ *
1337
+ * This method ensures that results of certain types such as strings or arrays
1338
+ * are flagged as errors. It divides the current context into subsequent nodes
1339
+ * for further processing. If the division returns a promise, it delegates the
1340
+ * processing to `postProcessAsync`. For synchronous division, it sets the
1341
+ * `nextNodes` and finalizes the operation.
1342
+ *
1343
+ * @return {(Array|undefined)} Returns an array of next nodes for further processing,
1344
+ * or undefined if no further processing is required.
1345
+ */
1115
1346
  postProcess() {
1116
1347
  if (typeof this.result === "string") {
1117
1348
  this.onError(
@@ -1129,11 +1360,23 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1129
1360
  this.finalize();
1130
1361
  return this.nextNodes;
1131
1362
  }
1363
+ /**
1364
+ * Asynchronously processes and finalizes the provided graph nodes.
1365
+ *
1366
+ * @param {Promise<GraphNode[]>} nextNodes A promise that resolves to an array of graph nodes to be processed.
1367
+ * @return {Promise<GraphNode[]>} A promise that resolves to the processed array of graph nodes.
1368
+ */
1132
1369
  async postProcessAsync(nextNodes) {
1133
1370
  this.nextNodes = await nextNodes;
1134
1371
  this.finalize();
1135
1372
  return this.nextNodes;
1136
1373
  }
1374
+ /**
1375
+ * Finalizes the current task execution by determining if the task is complete, handles any errors or failures,
1376
+ * emits relevant signals based on the task outcomes, and ensures proper end of the task lifecycle.
1377
+ *
1378
+ * @return {void} Does not return a value.
1379
+ */
1137
1380
  finalize() {
1138
1381
  if (this.nextNodes.length === 0) {
1139
1382
  this.completeSubgraph();
@@ -1149,6 +1392,13 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1149
1392
  }
1150
1393
  this.end();
1151
1394
  }
1395
+ /**
1396
+ * Handles an error event, processes the error, and updates the state accordingly.
1397
+ *
1398
+ * @param {unknown} error - The error object or message that occurred.
1399
+ * @param {AnyObject} [errorData={}] - Additional error data to include in the result.
1400
+ * @return {void} This method does not return any value.
1401
+ */
1152
1402
  onError(error, errorData = {}) {
1153
1403
  this.result = {
1154
1404
  ...this.context.getFullContext(),
@@ -1162,6 +1412,12 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1162
1412
  this.migrate(this.result);
1163
1413
  this.errored = true;
1164
1414
  }
1415
+ /**
1416
+ * Retries a task based on the defined retry count and delay time. If the retry count is 0, it immediately resolves with the provided previous result.
1417
+ *
1418
+ * @param {any} [prevResult] - The result from a previous attempt, if any, to return when no retries are performed.
1419
+ * @return {Promise<TaskResult>} - A promise that resolves with the result of the retried task or the previous result if no retries occur.
1420
+ */
1165
1421
  async retry(prevResult) {
1166
1422
  if (this.retryCount === 0) {
1167
1423
  return prevResult;
@@ -1169,6 +1425,13 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1169
1425
  await this.delayRetry();
1170
1426
  return this.work();
1171
1427
  }
1428
+ /**
1429
+ * Retries an asynchronous operation and returns its result.
1430
+ * If the retry count is zero, the method immediately returns the provided previous result.
1431
+ *
1432
+ * @param {any} [prevResult] - The optional result from a previous operation attempt, if applicable.
1433
+ * @return {Promise<TaskResult>} A promise that resolves to the result of the retried operation.
1434
+ */
1172
1435
  async retryAsync(prevResult) {
1173
1436
  if (this.retryCount === 0) {
1174
1437
  return prevResult;
@@ -1186,6 +1449,15 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1186
1449
  this.retryDelay = this.task.retryDelayMax;
1187
1450
  }
1188
1451
  }
1452
+ /**
1453
+ * Processes the result of a task by generating new nodes based on the task output.
1454
+ * The method handles synchronous and asynchronous generators, validates task output,
1455
+ * and creates new nodes accordingly. If errors occur, the method attempts to handle them
1456
+ * by generating alternative task nodes.
1457
+ *
1458
+ * @return {GraphNode[] | Promise<GraphNode[]>} Returns an array of generated GraphNode objects
1459
+ * (synchronously or wrapped in a Promise) based on the task result, or propagates errors if validation fails.
1460
+ */
1189
1461
  divide() {
1190
1462
  const newNodes = [];
1191
1463
  if (this.result?.next && typeof this.result.next === "function") {
@@ -1224,7 +1496,7 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1224
1496
  if (this.errored) {
1225
1497
  newNodes.push(
1226
1498
  ...this.task.mapNext(
1227
- (t) => this.clone().split(uuid3()).differentiate(t).migrate({ ...this.result }),
1499
+ (t) => this.clone().split(uuid4()).differentiate(t).migrate({ ...this.result }),
1228
1500
  true
1229
1501
  )
1230
1502
  );
@@ -1237,6 +1509,13 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1237
1509
  });
1238
1510
  return newNodes;
1239
1511
  }
1512
+ /**
1513
+ * Processes an asynchronous iterator result, validates its output, and generates new graph nodes accordingly.
1514
+ * Additionally, continues to process and validate results from an asynchronous generator.
1515
+ *
1516
+ * @param {Promise<IteratorResult<any>>} current - A promise resolving to the current step result from an asynchronous iterator.
1517
+ * @return {Promise<GraphNode[]>} A promise resolving to an array of generated GraphNode objects based on validated outputs.
1518
+ */
1240
1519
  async divideAsync(current) {
1241
1520
  const nextNodes = [];
1242
1521
  const _current = await current;
@@ -1259,8 +1538,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1259
1538
  this.divided = true;
1260
1539
  return nextNodes;
1261
1540
  }
1541
+ /**
1542
+ * Generates new nodes based on the provided result and task configuration.
1543
+ *
1544
+ * @param {any} result - The result of the previous operation, which determines the configuration and context for new nodes. It can be a boolean or an object containing details like failure, errors, or metadata.
1545
+ * @return {GraphNode[]} An array of newly generated graph nodes configured based on the task and context.
1546
+ */
1262
1547
  generateNewNodes(result) {
1263
- const groupId = uuid3();
1548
+ const groupId = uuid4();
1264
1549
  const newNodes = [];
1265
1550
  if (typeof result !== "boolean") {
1266
1551
  const failed = result.failed !== void 0 && result.failed || result.error !== void 0;
@@ -1301,6 +1586,12 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1301
1586
  }
1302
1587
  return newNodes;
1303
1588
  }
1589
+ /**
1590
+ * Executes the differentiation process based on a given task and updates the instance properties accordingly.
1591
+ *
1592
+ * @param {Task} task - The task object containing information such as retry count, retry delay, and metadata status.
1593
+ * @return {GraphNode} The updated instance after processing the task.
1594
+ */
1304
1595
  differentiate(task) {
1305
1596
  this.task = task;
1306
1597
  this.retryCount = task.retryCount;
@@ -1308,14 +1599,32 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1308
1599
  this.silent = task.isMeta && !this.debug || task.isSubMeta || this.context?.getMetadata()?.__isSubMeta;
1309
1600
  return this;
1310
1601
  }
1602
+ /**
1603
+ * Migrates the current instance to a new context and returns the updated instance.
1604
+ *
1605
+ * @param {any} ctx - The context data to be used for migration.
1606
+ * @return {GraphNode} The updated instance after migration.
1607
+ */
1311
1608
  migrate(ctx) {
1312
1609
  this.context = new GraphContext(ctx);
1313
1610
  return this;
1314
1611
  }
1612
+ /**
1613
+ * Splits the current node into a new group identified by the provided ID.
1614
+ *
1615
+ * @param {string} id - The unique identifier for the new split group.
1616
+ * @return {GraphNode} The current instance of the GraphNode with the updated split group ID.
1617
+ */
1315
1618
  split(id) {
1316
1619
  this.splitGroupId = id;
1317
1620
  return this;
1318
1621
  }
1622
+ /**
1623
+ * Creates a new instance of the GraphNode with the current node's properties.
1624
+ * This method allows for duplicating the existing graph node.
1625
+ *
1626
+ * @return {GraphNode} A new instance of GraphNode that is a copy of the current node.
1627
+ */
1319
1628
  clone() {
1320
1629
  return new _GraphNode(
1321
1630
  this.task,
@@ -1326,6 +1635,13 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1326
1635
  this.verbose
1327
1636
  );
1328
1637
  }
1638
+ /**
1639
+ * Consumes the given graph node by combining contexts, merging previous nodes,
1640
+ * and performing associated operations on the provided node.
1641
+ *
1642
+ * @param {GraphNode} node - The graph node to be consumed.
1643
+ * @return {void} This method does not return a value.
1644
+ */
1329
1645
  consume(node) {
1330
1646
  this.context = this.context.combine(node.context);
1331
1647
  this.previousNodes = this.previousNodes.concat(node.previousNodes);
@@ -1333,9 +1649,22 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1333
1649
  node.changeIdentity(this.id);
1334
1650
  node.destroy();
1335
1651
  }
1652
+ /**
1653
+ * Changes the identity of the current instance by updating the `id` property.
1654
+ *
1655
+ * @param {string} id - The new identity value to be assigned.
1656
+ * @return {void} Does not return a value.
1657
+ */
1336
1658
  changeIdentity(id) {
1337
1659
  this.id = id;
1338
1660
  }
1661
+ /**
1662
+ * Completes the subgraph for the current node and recursively for its previous nodes
1663
+ * once all next nodes have their subgraphs marked as done. If there are no previous nodes,
1664
+ * it completes the entire graph.
1665
+ *
1666
+ * @return {void} Does not return a value.
1667
+ */
1339
1668
  completeSubgraph() {
1340
1669
  for (const node of this.nextNodes) {
1341
1670
  if (!node.subgraphDone()) {
@@ -1349,10 +1678,22 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1349
1678
  }
1350
1679
  this.previousNodes.forEach((n) => n.completeSubgraph());
1351
1680
  }
1681
+ /**
1682
+ * Completes the current graph by setting a flag indicating the graph has been completed
1683
+ * and recursively completes all subsequent nodes in the graph.
1684
+ *
1685
+ * @return {void} Does not return a value.
1686
+ */
1352
1687
  completeGraph() {
1353
1688
  this.graphComplete = true;
1354
1689
  this.nextNodes.forEach((n) => n.completeGraph());
1355
1690
  }
1691
+ /**
1692
+ * Destroys the current instance by releasing resources, breaking references,
1693
+ * and resetting properties to ensure proper cleanup.
1694
+ *
1695
+ * @return {void} No return value.
1696
+ */
1356
1697
  destroy() {
1357
1698
  this.context = null;
1358
1699
  this.task = null;
@@ -1365,15 +1706,40 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1365
1706
  this.layer = void 0;
1366
1707
  this.destroyed = true;
1367
1708
  }
1709
+ /**
1710
+ * Retrieves an iterator for traversing through the graph nodes.
1711
+ *
1712
+ * @return {GraphNodeIterator} An iterator instance specific to this graph node.
1713
+ */
1368
1714
  getIterator() {
1369
1715
  return new GraphNodeIterator(this);
1370
1716
  }
1717
+ /**
1718
+ * Applies a callback function to each node in the `nextNodes` array and returns
1719
+ * the resulting array from the map operation.
1720
+ *
1721
+ * @param {function} callback - A function to execute on each `GraphNode` in the `nextNodes` array.
1722
+ * The function receives a `GraphNode` as its argument.
1723
+ * @return {Array} The resulting array after applying the callback function to each node in `nextNodes`.
1724
+ */
1371
1725
  mapNext(callback) {
1372
1726
  return this.nextNodes.map(callback);
1373
1727
  }
1728
+ /**
1729
+ * Accepts a visitor object and calls its visitNode method with the current instance.
1730
+ *
1731
+ * @param {GraphVisitor} visitor - The visitor instance implementing the GraphVisitor interface.
1732
+ * @return {void} This method does not return a value.
1733
+ */
1374
1734
  accept(visitor) {
1375
1735
  visitor.visitNode(this);
1376
1736
  }
1737
+ /**
1738
+ * Exports the current object's state and returns it in a serialized format.
1739
+ * The exported object contains metadata, task details, context information, execution times, node relationships, routine execution status, and other state information.
1740
+ *
1741
+ * @return {Object} An object representing the current state.
1742
+ */
1377
1743
  export() {
1378
1744
  return {
1379
1745
  __id: this.id,
@@ -1471,9 +1837,12 @@ var GraphRoutine = class extends SignalEmitter {
1471
1837
  });
1472
1838
  }
1473
1839
  /**
1474
- * Applies callback to starting tasks.
1475
- * @param callBack The callback.
1476
- * @returns Promise if async.
1840
+ * Iterates over each task in the `tasks` collection and applies the provided callback function.
1841
+ * If the callback returns a Promise, resolves all Promises concurrently.
1842
+ *
1843
+ * @param {function} callBack - A function to be executed on each task from the `tasks` collection.
1844
+ * The callback receives the current task as its argument.
1845
+ * @return {Promise<void>} A Promise that resolves once all callback executions, including asynchronous ones, are complete.
1477
1846
  */
1478
1847
  async forEachTask(callBack) {
1479
1848
  const promises = [];
@@ -1492,10 +1861,10 @@ var GraphRoutine = class extends SignalEmitter {
1492
1861
  this.emit("meta.routine.global_version_set", { version: this.version });
1493
1862
  }
1494
1863
  /**
1495
- * Subscribes to signals (chainable).
1496
- * @param signals The signal names.
1497
- * @returns This for chaining.
1498
- * @edge Duplicates ignored; assumes broker.observe binds this as handler.
1864
+ * Subscribes the current instance to the specified signals, enabling it to observe them.
1865
+ *
1866
+ * @param {...string} signals - The names of the signals to observe.
1867
+ * @return {this} Returns the instance to allow for method chaining.
1499
1868
  */
1500
1869
  doOn(...signals) {
1501
1870
  signals.forEach((signal) => {
@@ -1506,8 +1875,11 @@ var GraphRoutine = class extends SignalEmitter {
1506
1875
  return this;
1507
1876
  }
1508
1877
  /**
1509
- * Unsubscribes from all observed signals.
1510
- * @returns This for chaining.
1878
+ * Unsubscribes from all observed signals and clears the internal collection
1879
+ * of observed signals. This ensures that the instance is no longer listening
1880
+ * or reacting to any previously subscribed signals.
1881
+ *
1882
+ * @return {this} Returns the current instance for chaining purposes.
1511
1883
  */
1512
1884
  unsubscribeAll() {
1513
1885
  this.observedSignals.forEach(
@@ -1517,10 +1889,10 @@ var GraphRoutine = class extends SignalEmitter {
1517
1889
  return this;
1518
1890
  }
1519
1891
  /**
1520
- * Unsubscribes from specific signals.
1521
- * @param signals The signals.
1522
- * @returns This for chaining.
1523
- * @edge No-op if not subscribed.
1892
+ * Unsubscribes the current instance from the specified signals.
1893
+ *
1894
+ * @param {...string} signals - The signals to unsubscribe from.
1895
+ * @return {this} The current instance for method chaining.
1524
1896
  */
1525
1897
  unsubscribe(...signals) {
1526
1898
  signals.forEach((signal) => {
@@ -1532,7 +1904,12 @@ var GraphRoutine = class extends SignalEmitter {
1532
1904
  return this;
1533
1905
  }
1534
1906
  /**
1535
- * Destroys the routine.
1907
+ * Cleans up resources and emits an event indicating the destruction of the routine.
1908
+ *
1909
+ * This method unsubscribes from all events, clears the tasks list,
1910
+ * and emits a "meta.routine.destroyed" event with details of the destruction.
1911
+ *
1912
+ * @return {void}
1536
1913
  */
1537
1914
  destroy() {
1538
1915
  this.unsubscribeAll();
@@ -1578,27 +1955,27 @@ var TaskIterator = class {
1578
1955
  // src/graph/definition/Task.ts
1579
1956
  var Task = class extends SignalEmitter {
1580
1957
  /**
1581
- * Constructs a Task (static definition).
1582
- * @param name Name.
1583
- * @param task Function.
1584
- * @param description Description.
1585
- * @param concurrency Limit.
1586
- * @param timeout ms.
1587
- * @param register Register via signal (default true).
1588
- * @param isUnique
1589
- * @param isMeta
1590
- * @param isSubMeta
1591
- * @param isHidden
1592
- * @param getTagCallback
1593
- * @param inputSchema
1594
- * @param validateInputContext
1595
- * @param outputSchema
1596
- * @param validateOutputContext
1597
- * @param retryCount
1598
- * @param retryDelay
1599
- * @param retryDelayMax
1600
- * @param retryDelayFactor
1601
- * @edge Emits 'meta.task.created' with { __task: this } for seed.
1958
+ * Constructs an instance of the task with the specified properties and configuration options.
1959
+ *
1960
+ * @param {string} name - The name of the task.
1961
+ * @param {TaskFunction} task - The function that represents the task logic.
1962
+ * @param {string} [description=""] - A description of the task.
1963
+ * @param {number} [concurrency=0] - The number of concurrent executions allowed for the task.
1964
+ * @param {number} [timeout=0] - The maximum execution time for the task in milliseconds.
1965
+ * @param {boolean} [register=true] - Indicates if the task should be registered or not.
1966
+ * @param {boolean} [isUnique=false] - Specifies if the task should only allow one instance to exist at any time.
1967
+ * @param {boolean} [isMeta=false] - Indicates if the task is a meta-task.
1968
+ * @param {boolean} [isSubMeta=false] - Indicates if the task is a sub-meta-task.
1969
+ * @param {boolean} [isHidden=false] - Determines if the task is hidden and not exposed publicly.
1970
+ * @param {ThrottleTagGetter} [getTagCallback=undefined] - A callback to generate a throttle tag for the task.
1971
+ * @param {SchemaDefinition} [inputSchema=undefined] - The input schema for validating the task's input context.
1972
+ * @param {boolean} [validateInputContext=false] - Specifies if the input context should be validated against the input schema.
1973
+ * @param {SchemaDefinition} [outputSchema=undefined] - The output schema for validating the task's output context.
1974
+ * @param {boolean} [validateOutputContext=false] - Specifies if the output context should be validated against the output schema.
1975
+ * @param {number} [retryCount=0] - The number of retry attempts allowed for the task in case of failure.
1976
+ * @param {number} [retryDelay=0] - The initial delay (in milliseconds) between retry attempts.
1977
+ * @param {number} [retryDelayMax=0] - The maximum delay (in milliseconds) allowed between retries.
1978
+ * @param {number} [retryDelayFactor=1] - The factor by which the retry delay increases after each attempt.
1602
1979
  */
1603
1980
  constructor(name, task, description = "", concurrency = 0, timeout = 0, register = true, isUnique = false, isMeta = false, isSubMeta = false, isHidden = false, getTagCallback = void 0, inputSchema = void 0, validateInputContext = false, outputSchema = void 0, validateOutputContext = false, retryCount = 0, retryDelay = 0, retryDelayMax = 0, retryDelayFactor = 1) {
1604
1981
  super(isSubMeta || isHidden);
@@ -1687,6 +2064,13 @@ var Task = class extends SignalEmitter {
1687
2064
  });
1688
2065
  }
1689
2066
  }
2067
+ /**
2068
+ * Retrieves the tag associated with the instance.
2069
+ * Can be overridden by subclasses.
2070
+ *
2071
+ * @param {AnyObject} [context] - Optional context parameter that can be provided.
2072
+ * @return {string} The tag value of the instance.
2073
+ */
1690
2074
  getTag(context) {
1691
2075
  return this.name;
1692
2076
  }
@@ -1717,16 +2101,35 @@ var Task = class extends SignalEmitter {
1717
2101
  setValidateOutputContext(value) {
1718
2102
  this.validateOutputContext = value;
1719
2103
  }
2104
+ /**
2105
+ * Emits a signal along with metadata if certain conditions are met.
2106
+ *
2107
+ * This method sends a signal with optional context data and adds metadata
2108
+ * to the emitted data if the instance is not hidden and not a subordinate metadata object.
2109
+ *
2110
+ * @param {string} signal - The name of the signal to emit.
2111
+ * @param {AnyObject} [ctx={}] - Additional context data to include with the emitted signal.
2112
+ * @return {void} Does not return a value.
2113
+ */
1720
2114
  emitWithMetadata(signal, ctx = {}) {
1721
2115
  const data = { ...ctx };
1722
2116
  if (!this.isHidden && !this.isSubMeta) {
1723
2117
  data.__signalEmission = {
1724
2118
  taskName: this.name,
1725
- taskVersion: this.version
2119
+ taskVersion: this.version,
2120
+ isMetric: false
1726
2121
  };
1727
2122
  }
1728
2123
  this.emit(signal, data);
1729
2124
  }
2125
+ /**
2126
+ * Emits metrics with additional metadata enhancement based on the context and the state of the instance.
2127
+ * This is used to prevent loops on the meta layer in debug mode.
2128
+ *
2129
+ * @param {string} signal - The signal identifier for the metric being emitted.
2130
+ * @param {AnyObject} [ctx={}] - Optional context object to provide additional information with the metric.
2131
+ * @return {void} This method does not return any value.
2132
+ */
1730
2133
  emitMetricsWithMetadata(signal, ctx = {}) {
1731
2134
  const data = { ...ctx };
1732
2135
  if (!this.isHidden && !this.isSubMeta) {
@@ -1739,12 +2142,13 @@ var Task = class extends SignalEmitter {
1739
2142
  this.emitMetrics(signal, data);
1740
2143
  }
1741
2144
  /**
1742
- * Validates a context deeply against a schema.
1743
- * @param data - The data to validate (input context or output result).
1744
- * @param schema - The schema definition.
1745
- * @param path - The current path for error reporting (default: 'root').
1746
- * @returns { { valid: boolean, errors: Record<string, string> } } - Validation result with detailed errors if invalid.
1747
- * @description Recursively checks types, required fields, and constraints; allows extra properties not in schema.
2145
+ * Validates a data object against a specified schema definition and returns validation results.
2146
+ *
2147
+ * @param {any} data - The target object to validate against the schema.
2148
+ * @param {SchemaDefinition | undefined} schema - The schema definition describing the expected structure and constraints of the data.
2149
+ * @param {string} [path="context"] - The base path or context for traversing the data, used in generating error messages.
2150
+ * @return {{ valid: boolean, errors: Record<string, string> }} - An object containing a validity flag (`valid`)
2151
+ * and a map (`errors`) of validation error messages keyed by property paths.
1748
2152
  */
1749
2153
  validateSchema(data, schema, path = "context") {
1750
2154
  const errors = {};
@@ -1847,6 +2251,12 @@ var Task = class extends SignalEmitter {
1847
2251
  }
1848
2252
  return { valid: true, errors: {} };
1849
2253
  }
2254
+ /**
2255
+ * Validates the input context against the predefined schema and emits metadata if validation fails.
2256
+ *
2257
+ * @param {AnyObject} context - The input context to validate.
2258
+ * @return {true | AnyObject} - Returns `true` if validation succeeds, otherwise returns an error object containing details of the validation failure.
2259
+ */
1850
2260
  validateInput(context) {
1851
2261
  if (this.validateInputContext) {
1852
2262
  const validationResult = this.validateSchema(
@@ -1869,6 +2279,13 @@ var Task = class extends SignalEmitter {
1869
2279
  }
1870
2280
  return true;
1871
2281
  }
2282
+ /**
2283
+ * Validates the output context using the provided schema and emits metadata if validation fails.
2284
+ *
2285
+ * @param {AnyObject} context - The output context to validate.
2286
+ * @return {true | AnyObject} Returns `true` if the output context is valid; otherwise, returns an object
2287
+ * containing error information when validation fails.
2288
+ */
1872
2289
  validateOutput(context) {
1873
2290
  if (this.validateOutputContext) {
1874
2291
  const validationResult = this.validateSchema(
@@ -1892,14 +2309,13 @@ var Task = class extends SignalEmitter {
1892
2309
  return true;
1893
2310
  }
1894
2311
  /**
1895
- * Executes the task function after optional input validation.
1896
- * @param context - The GraphContext to validate and execute.
1897
- * @param emit
1898
- * @param progressCallback - Callback for progress updates.
1899
- * @param nodeData
1900
- * @returns TaskResult from the taskFunction or error object on validation failure.
1901
- * @edge If validateInputContext is true, validates context; on failure, emits 'meta.task.validationFailed' with detailed errors.
1902
- * @edge If validateOutputContext is true, validates output; on failure, emits 'meta.task.outputValidationFailed' with detailed errors.
2312
+ * Executes a task within a given context, optionally emitting signals and reporting progress.
2313
+ *
2314
+ * @param {GraphContext} context The execution context which provides data and functions necessary for the task.
2315
+ * @param {function(string, AnyObject): void} emit A function to emit signals and communicate intermediate results or states.
2316
+ * @param {function(number): void} progressCallback A callback function used to report task progress as a percentage (0 to 100).
2317
+ * @param {{ nodeId: string; routineExecId: string }} nodeData An object containing identifiers related to the node and execution routine.
2318
+ * @return {TaskResult} The result of the executed task.
1903
2319
  */
1904
2320
  execute(context, emit, progressCallback, nodeData) {
1905
2321
  return this.taskFunction(
@@ -1908,6 +2324,15 @@ var Task = class extends SignalEmitter {
1908
2324
  progressCallback
1909
2325
  );
1910
2326
  }
2327
+ /**
2328
+ * Adds tasks as predecessors to the current task and establishes dependencies between them.
2329
+ * Ensures that adding predecessors does not create cyclic dependencies.
2330
+ * Updates task relationships, progress weights, and emits relevant metrics after operations.
2331
+ *
2332
+ * @param {Task[]} tasks - An array of tasks to be added as predecessors to the current task.
2333
+ * @return {this} The current task instance for method chaining.
2334
+ * @throws {Error} Throws an error if adding a predecessor creates a cycle in the task structure.
2335
+ */
1911
2336
  doAfter(...tasks) {
1912
2337
  for (const pred of tasks) {
1913
2338
  if (this.predecessorTasks.has(pred)) continue;
@@ -1930,6 +2355,14 @@ var Task = class extends SignalEmitter {
1930
2355
  this.updateProgressWeights();
1931
2356
  return this;
1932
2357
  }
2358
+ /**
2359
+ * Adds a sequence of tasks as successors to the current task, ensuring no cyclic dependencies are introduced.
2360
+ * Metrics are emitted when a relationship is successfully added.
2361
+ *
2362
+ * @param {...Task} tasks - The tasks to be added as successors to the current task.
2363
+ * @return {this} Returns the current task instance for method chaining.
2364
+ * @throws {Error} Throws an error if adding a task causes a cyclic dependency.
2365
+ */
1933
2366
  then(...tasks) {
1934
2367
  for (const next of tasks) {
1935
2368
  if (this.nextTasks.has(next)) continue;
@@ -1952,6 +2385,12 @@ var Task = class extends SignalEmitter {
1952
2385
  this.updateProgressWeights();
1953
2386
  return this;
1954
2387
  }
2388
+ /**
2389
+ * Decouples the current task from the provided task by removing mutual references.
2390
+ *
2391
+ * @param {Task} task - The task to decouple from the current task.
2392
+ * @return {void} This method does not return a value.
2393
+ */
1955
2394
  decouple(task) {
1956
2395
  if (task.nextTasks.has(this)) {
1957
2396
  task.nextTasks.delete(this);
@@ -1963,6 +2402,14 @@ var Task = class extends SignalEmitter {
1963
2402
  }
1964
2403
  this.updateLayerFromPredecessors();
1965
2404
  }
2405
+ /**
2406
+ * Updates the progress weights for tasks within each layer of the subgraph.
2407
+ * The progress weight for each task is calculated based on the inverse proportion
2408
+ * of the number of layers and the number of tasks in each layer. This ensures an
2409
+ * even distribution of progress weight across the tasks in the layers.
2410
+ *
2411
+ * @return {void} Does not return a value.
2412
+ */
1966
2413
  updateProgressWeights() {
1967
2414
  const layers = this.getSubgraphLayers();
1968
2415
  const numLayers = layers.size;
@@ -1976,6 +2423,12 @@ var Task = class extends SignalEmitter {
1976
2423
  );
1977
2424
  });
1978
2425
  }
2426
+ /**
2427
+ * Retrieves a mapping of layer indices to sets of tasks within each layer of a subgraph.
2428
+ * This method traverses the task dependencies and organizes tasks by their respective layer indices.
2429
+ *
2430
+ * @return {Map<number, Set<Task>>} A map where the key is the layer index (number) and the value is a set of tasks (Set<Task>) belonging to that layer.
2431
+ */
1979
2432
  getSubgraphLayers() {
1980
2433
  const layers = /* @__PURE__ */ new Map();
1981
2434
  const queue = [this];
@@ -1990,6 +2443,13 @@ var Task = class extends SignalEmitter {
1990
2443
  }
1991
2444
  return layers;
1992
2445
  }
2446
+ /**
2447
+ * Updates the `layerIndex` of the current task based on the maximum layer index of its predecessors
2448
+ * and propagates the update recursively to all subsequent tasks. If the `layerIndex` changes,
2449
+ * emits a metric event with metadata about the change.
2450
+ *
2451
+ * @return {void} This method does not return a value.
2452
+ */
1993
2453
  updateLayerFromPredecessors() {
1994
2454
  const prevLayerIndex = this.layerIndex;
1995
2455
  let maxPred = 0;
@@ -2012,6 +2472,12 @@ var Task = class extends SignalEmitter {
2012
2472
  next.nextTasks.forEach((n) => queue.push(n));
2013
2473
  }
2014
2474
  }
2475
+ /**
2476
+ * Determines whether there is a cycle in the tasks graph.
2477
+ * This method performs a depth-first search (DFS) to detect cycles.
2478
+ *
2479
+ * @return {boolean} - Returns true if a cycle is found in the graph, otherwise false.
2480
+ */
2015
2481
  hasCycle() {
2016
2482
  const visited = /* @__PURE__ */ new Set();
2017
2483
  const recStack = /* @__PURE__ */ new Set();
@@ -2028,18 +2494,33 @@ var Task = class extends SignalEmitter {
2028
2494
  };
2029
2495
  return dfs(this);
2030
2496
  }
2497
+ /**
2498
+ * Maps over the next set of tasks or failed tasks if specified, applying the provided callback function.
2499
+ *
2500
+ * @param {Function} callback A function that will be called with each task, transforming the task as needed. It receives a single parameter of type Task.
2501
+ * @param {boolean} [failed=false] A boolean that determines whether to map over the failed tasks (true) or the next tasks (false).
2502
+ * @return {any[]} An array of transformed tasks resulting from applying the callback function.
2503
+ */
2031
2504
  mapNext(callback, failed = false) {
2032
2505
  const tasks = failed ? Array.from(this.onFailTasks) : Array.from(this.nextTasks);
2033
2506
  return tasks.map(callback);
2034
2507
  }
2508
+ /**
2509
+ * Maps through each task in the set of predecessor tasks and applies the provided callback function.
2510
+ *
2511
+ * @param {function} callback - A function to execute on each task in the predecessor tasks. The function receives a `Task` object as its argument and returns any value.
2512
+ * @return {any[]} An array containing the results of applying the callback function to each predecessor task.
2513
+ */
2035
2514
  mapPrevious(callback) {
2036
2515
  return Array.from(this.predecessorTasks).map(callback);
2037
2516
  }
2038
2517
  /**
2039
- * Subscribes to signals (chainable).
2040
- * @param signals The signal names.
2041
- * @returns This for chaining.
2042
- * @edge Duplicates ignored; assumes broker.observe binds this as handler.
2518
+ * Adds the specified signals to the current instance, making it observe them.
2519
+ * If the instance is already observing a signal, it will be skipped.
2520
+ * The method also emits metadata information if the `register` property is set.
2521
+ *
2522
+ * @param {...string[]} signals - The array of signal names to observe.
2523
+ * @return {this} The current instance after adding the specified signals.
2043
2524
  */
2044
2525
  doOn(...signals) {
2045
2526
  signals.forEach((signal) => {
@@ -2059,9 +2540,10 @@ var Task = class extends SignalEmitter {
2059
2540
  return this;
2060
2541
  }
2061
2542
  /**
2062
- * Sets signals to emit post-execution (chainable).
2063
- * @param signals The signal names.
2064
- * @returns This for chaining.
2543
+ * Registers the specified signals to be emitted after the Task executes successfully and attaches them for further processing.
2544
+ *
2545
+ * @param {...string} signals - The list of signals to be registered for emission.
2546
+ * @return {this} The current instance for method chaining.
2065
2547
  */
2066
2548
  emits(...signals) {
2067
2549
  signals.forEach((signal) => {
@@ -2070,6 +2552,13 @@ var Task = class extends SignalEmitter {
2070
2552
  });
2071
2553
  return this;
2072
2554
  }
2555
+ /**
2556
+ * Configures the instance to emit specified signals when the task execution fails.
2557
+ * A failure is defined as anything that does not return a successful result.
2558
+ *
2559
+ * @param {...string} signals - The names of the signals to emit upon failure.
2560
+ * @return {this} Returns the current instance for chaining.
2561
+ */
2073
2562
  emitsOnFail(...signals) {
2074
2563
  signals.forEach((signal) => {
2075
2564
  this.signalsToEmitOnFail.add(signal);
@@ -2077,6 +2566,13 @@ var Task = class extends SignalEmitter {
2077
2566
  });
2078
2567
  return this;
2079
2568
  }
2569
+ /**
2570
+ * Attaches a signal to the current context and emits metadata if the register flag is set.
2571
+ *
2572
+ * @param {string} signal - The name of the signal to attach.
2573
+ * @param {boolean} [isOnFail=false] - Indicates if the signal should be marked as "on fail".
2574
+ * @return {void} This method does not return a value.
2575
+ */
2080
2576
  attachSignal(signal, isOnFail = false) {
2081
2577
  this.emitsSignals.add(signal);
2082
2578
  if (this.register) {
@@ -2091,10 +2587,12 @@ var Task = class extends SignalEmitter {
2091
2587
  }
2092
2588
  }
2093
2589
  /**
2094
- * Unsubscribes from specific signals.
2095
- * @param signals The signals.
2096
- * @returns This for chaining.
2097
- * @edge No-op if not subscribed.
2590
+ * Unsubscribes the current instance from the specified signals.
2591
+ * This method removes the signals from the observedSignals set, unsubscribes
2592
+ * from the underlying broker, and emits metadata for the unsubscription if applicable.
2593
+ *
2594
+ * @param {string[]} signals - The list of signal names to unsubscribe from.
2595
+ * @return {this} Returns the current instance for method chaining.
2098
2596
  */
2099
2597
  unsubscribe(...signals) {
2100
2598
  signals.forEach((signal) => {
@@ -2116,8 +2614,9 @@ var Task = class extends SignalEmitter {
2116
2614
  return this;
2117
2615
  }
2118
2616
  /**
2119
- * Unsubscribes from all observed signals.
2120
- * @returns This for chaining.
2617
+ * Unsubscribes from all currently observed signals and clears the list of observed signals.
2618
+ *
2619
+ * @return {this} The instance of the class to allow method chaining.
2121
2620
  */
2122
2621
  unsubscribeAll() {
2123
2622
  this.unsubscribe(...this.observedSignals);
@@ -2125,9 +2624,10 @@ var Task = class extends SignalEmitter {
2125
2624
  return this;
2126
2625
  }
2127
2626
  /**
2128
- * Detaches specific emitted signals.
2129
- * @param signals The signals.
2130
- * @returns This for chaining.
2627
+ * Detaches the specified signals from being emitted after execution and optionally emits metadata for each detached signal.
2628
+ *
2629
+ * @param {...string} signals - The list of signal names to be detached. Signals can be in the format "namespace:signalName".
2630
+ * @return {this} Returns the current instance of the object for method chaining.
2131
2631
  */
2132
2632
  detachSignals(...signals) {
2133
2633
  signals.forEach((signal) => {
@@ -2146,27 +2646,50 @@ var Task = class extends SignalEmitter {
2146
2646
  return this;
2147
2647
  }
2148
2648
  /**
2149
- * Detaches all emitted signals.
2150
- * @returns This for chaining.
2649
+ * Detaches all signals associated with the object by invoking the `detachSignals` method
2650
+ * and clearing the `signalsToEmitAfter` collection.
2651
+ *
2652
+ * @return {this} Returns the current instance to allow method chaining.
2151
2653
  */
2152
2654
  detachAllSignals() {
2153
2655
  this.detachSignals(...this.signalsToEmitAfter);
2154
2656
  this.signalsToEmitAfter.clear();
2155
2657
  return this;
2156
2658
  }
2659
+ /**
2660
+ * Maps over the signals in the `signalsToEmitAfter` set and applies a callback function to each signal.
2661
+ *
2662
+ * @param {function(string): void} callback - A function that is called with each signal
2663
+ * in the `signalsToEmitAfter` set, providing the signal as an argument.
2664
+ * @return {Array<any>} An array containing the results of applying the callback
2665
+ * function to each signal.
2666
+ */
2157
2667
  mapSignals(callback) {
2158
2668
  return Array.from(this.signalsToEmitAfter).map(callback);
2159
2669
  }
2670
+ /**
2671
+ * Maps over the signals in `signalsToEmitOnFail` and applies the provided callback to each signal.
2672
+ *
2673
+ * @param {function(string): void} callback - A function that receives each signal as a string and performs an operation or transformation on it.
2674
+ * @return {Array} The array resulting from applying the callback to each signal in `signalsToEmitOnFail`.
2675
+ */
2160
2676
  mapOnFailSignals(callback) {
2161
2677
  return Array.from(this.signalsToEmitOnFail).map(callback);
2162
2678
  }
2679
+ /**
2680
+ * Maps over the observed signals with the provided callback function.
2681
+ *
2682
+ * @param {function(string): void} callback - A function to execute on each signal in the observed signals array.
2683
+ * @return {Array} A new array containing the results of calling the callback function on each observed signal.
2684
+ */
2163
2685
  mapObservedSignals(callback) {
2164
2686
  return Array.from(this.observedSignals).map(callback);
2165
2687
  }
2166
2688
  /**
2167
- * Emits attached signals.
2168
- * @param context The context for emission.
2169
- * @edge If isMeta (from Task), suppresses further "meta.*" to prevent loops.
2689
+ * Emits a collection of signals stored in the `signalsToEmitAfter` array.
2690
+ *
2691
+ * @param {GraphContext} context - The context object containing data or state to be passed to the emitted signals.
2692
+ * @return {void} This method does not return a value.
2170
2693
  */
2171
2694
  emitSignals(context) {
2172
2695
  this.signalsToEmitAfter.forEach((signal) => {
@@ -2174,15 +2697,29 @@ var Task = class extends SignalEmitter {
2174
2697
  });
2175
2698
  }
2176
2699
  /**
2177
- * Emits attached fail signals.
2178
- * @param context The context for emission.
2179
- * @edge If isMeta (from Task), suppresses further "meta.*" to prevent loops.
2700
+ * Emits registered signals when an operation fails.
2701
+ *
2702
+ * @param {GraphContext} context - The context from which the full context is derived and passed to the signals being emitted.
2703
+ * @return {void} This method does not return any value.
2180
2704
  */
2181
2705
  emitOnFailSignals(context) {
2182
2706
  this.signalsToEmitOnFail.forEach((signal) => {
2183
2707
  this.emit(signal, context.getFullContext());
2184
2708
  });
2185
2709
  }
2710
+ /**
2711
+ * Cleans up and destroys the task instance, detaching it from other tasks and
2712
+ * performing necessary cleanup operations.
2713
+ *
2714
+ * This method:
2715
+ * - Unsubscribes from all signals and events.
2716
+ * - Detaches all associated signal handlers.
2717
+ * - Removes the task from successor and predecessor task mappings.
2718
+ * - Clears all task relationships and marks the task as destroyed.
2719
+ * - Emits destruction metrics, if applicable.
2720
+ *
2721
+ * @return {void} No value is returned because the function performs clean-up operations.
2722
+ */
2186
2723
  destroy() {
2187
2724
  this.unsubscribeAll();
2188
2725
  this.detachAllSignals();
@@ -2200,6 +2737,18 @@ var Task = class extends SignalEmitter {
2200
2737
  });
2201
2738
  }
2202
2739
  }
2740
+ /**
2741
+ * Exports the current state of the object as a structured plain object.
2742
+ *
2743
+ * @return {AnyObject} An object containing the serialized properties of the current instance. The exported object includes various metadata, schema information, task attributes, and related tasks, such as:
2744
+ * - Name and description of the task.
2745
+ * - Layer index, uniqueness, meta, and signal-related flags.
2746
+ * - Event triggers and attached signals.
2747
+ * - Throttling, concurrency, timeout settings, and ephemeral flag.
2748
+ * - Task function as a string.
2749
+ * - Serialization of getter callbacks and schemas for input/output validation.
2750
+ * - Relationships such as next tasks, failure tasks, and predecessor tasks.
2751
+ */
2203
2752
  export() {
2204
2753
  return {
2205
2754
  __name: this.name,
@@ -2226,9 +2775,20 @@ var Task = class extends SignalEmitter {
2226
2775
  __previousTasks: Array.from(this.predecessorTasks).map((t) => t.name)
2227
2776
  };
2228
2777
  }
2778
+ /**
2779
+ * Returns an iterator for iterating over tasks associated with this instance.
2780
+ *
2781
+ * @return {TaskIterator} An iterator instance for tasks.
2782
+ */
2229
2783
  getIterator() {
2230
2784
  return new TaskIterator(this);
2231
2785
  }
2786
+ /**
2787
+ * Accepts a visitor object to perform operations on the current instance.
2788
+ *
2789
+ * @param {GraphVisitor} visitor - The visitor object implementing operations for this instance.
2790
+ * @return {void} This method does not return a value.
2791
+ */
2232
2792
  accept(visitor) {
2233
2793
  visitor.visitTask(this);
2234
2794
  }
@@ -2239,6 +2799,16 @@ var Task = class extends SignalEmitter {
2239
2799
 
2240
2800
  // src/registry/GraphRegistry.ts
2241
2801
  var GraphRegistry = class _GraphRegistry {
2802
+ /**
2803
+ * Constructs a new instance and sets up various meta tasks and routines.
2804
+ *
2805
+ * This constructor initializes several predefined tasks for managing operations
2806
+ * like registering tasks, updating schemas for tasks, fetching tasks or routines,
2807
+ * and performing actions on all tasks or routines. It also initializes routines
2808
+ * to handle similar operations and hardcodes the initial meta tasks and routines.
2809
+ *
2810
+ * It initializes the instance state by setting up tasks and routines.
2811
+ */
2242
2812
  constructor() {
2243
2813
  this.tasks = /* @__PURE__ */ new Map();
2244
2814
  this.routines = /* @__PURE__ */ new Map();
@@ -2423,12 +2993,14 @@ var GraphRunner = class extends SignalEmitter {
2423
2993
  );
2424
2994
  }
2425
2995
  /**
2426
- * Adds tasks/routines to current run.
2427
- * @param tasks Tasks/routines.
2428
- * @param context Context (defaults {}).
2429
- * @edge Flattens routines to tasks; generates routineExecId if not in context.
2430
- * @edge Emits 'meta.runner.added_tasks' with metadata.
2431
- * @edge Empty tasks warns no-op.
2996
+ * Adds tasks or routines to the current execution pipeline. Supports both individual tasks,
2997
+ * routines, or arrays of tasks and routines. Handles metadata and execution context management.
2998
+ *
2999
+ * @param {Task|GraphRoutine|(Task|GraphRoutine)[]} tasks - The task(s) or routine(s) to be added.
3000
+ * It can be a single task, a single routine, or an array of tasks and routines.
3001
+ * @param {AnyObject} [context={}] - Optional context object to provide execution trace and metadata.
3002
+ * Used to propagate information across task or routine executions.
3003
+ * @return {void} - This method does not return a value.
2432
3004
  */
2433
3005
  addTasks(tasks, context = {}) {
2434
3006
  let _tasks = Array.isArray(tasks) ? tasks : [tasks];
@@ -2453,9 +3025,9 @@ var GraphRunner = class extends SignalEmitter {
2453
3025
  const isSubMeta = allTasks.some((t) => t.isSubMeta) || !!context.__isSubMeta;
2454
3026
  context.__isSubMeta = isSubMeta;
2455
3027
  const isNewTrace = !context.__routineExecId && !context.__metadata?.__executionTraceId && !context.__executionTraceId;
2456
- const executionTraceId = context.__metadata?.__executionTraceId ?? context.__executionTraceId ?? uuid4();
3028
+ const executionTraceId = context.__metadata?.__executionTraceId ?? context.__executionTraceId ?? uuid5();
2457
3029
  context.__executionTraceId = executionTraceId;
2458
- const routineExecId = context.__routineExecId ?? uuid4();
3030
+ const routineExecId = context.__routineExecId ?? uuid5();
2459
3031
  context.__routineExecId = routineExecId;
2460
3032
  const ctx = new GraphContext(context || {});
2461
3033
  if (!isSubMeta) {
@@ -2501,11 +3073,12 @@ var GraphRunner = class extends SignalEmitter {
2501
3073
  );
2502
3074
  }
2503
3075
  /**
2504
- * Runs tasks/routines.
2505
- * @param tasks Optional tasks/routines.
2506
- * @param context Optional context.
2507
- * @returns Current/last run (Promise if async).
2508
- * @edge If running, returns current; else runs and resets.
3076
+ * Executes the provided tasks or routines. Maintains the execution state
3077
+ * and handles synchronous or asynchronous processing.
3078
+ *
3079
+ * @param {Task|GraphRoutine|(Task|GraphRoutine)[]} [tasks] - A single task, a single routine, or an array of tasks or routines to execute. Optional.
3080
+ * @param {AnyObject} [context] - An optional context object to be used during task execution.
3081
+ * @return {GraphRun|Promise<GraphRun>} - Returns a `GraphRun` instance if the execution is synchronous, or a `Promise` resolving to a `GraphRun` for asynchronous execution.
2509
3082
  */
2510
3083
  run(tasks, context) {
2511
3084
  if (tasks) {
@@ -2523,10 +3096,23 @@ var GraphRunner = class extends SignalEmitter {
2523
3096
  }
2524
3097
  return this.reset();
2525
3098
  }
3099
+ /**
3100
+ * Executes the provided asynchronous operation and resets the state afterwards.
3101
+ *
3102
+ * @param {Promise<void>} run - A promise representing the asynchronous operation to execute.
3103
+ * @return {Promise<GraphRun>} A promise that resolves to the result of the reset operation after the asynchronous operation completes.
3104
+ */
2526
3105
  async runAsync(run) {
2527
3106
  await run;
2528
3107
  return this.reset();
2529
3108
  }
3109
+ /**
3110
+ * Resets the current state of the graph, creating a new GraphRun instance
3111
+ * and returning the previous run instance.
3112
+ * If the debug mode is not enabled, it will destroy the existing resources.
3113
+ *
3114
+ * @return {GraphRun} The last GraphRun instance before the reset.
3115
+ */
2530
3116
  reset() {
2531
3117
  this.isRunning = false;
2532
3118
  const lastRun = this.currentRun;
@@ -2545,6 +3131,13 @@ var GraphRunner = class extends SignalEmitter {
2545
3131
  destroy() {
2546
3132
  this.currentRun.destroy();
2547
3133
  }
3134
+ /**
3135
+ * Sets the strategy to be used for running the graph and initializes
3136
+ * the current run with the provided strategy if no process is currently running.
3137
+ *
3138
+ * @param {GraphRunStrategy} strategy - The strategy to use for running the graph.
3139
+ * @return {void}
3140
+ */
2548
3141
  setStrategy(strategy) {
2549
3142
  this.strategy = strategy;
2550
3143
  if (!this.isRunning) {
@@ -2604,6 +3197,14 @@ var DebounceTask = class extends Task {
2604
3197
  this.trailing = trailing;
2605
3198
  this.maxWait = maxWait;
2606
3199
  }
3200
+ /**
3201
+ * Executes the taskFunction with the provided context, emit function, and progress callback.
3202
+ * It clears any existing timeout before execution.
3203
+ * Handles synchronous and asynchronous results from taskFunction.
3204
+ * If an error occurs during execution, it resolves with the error.
3205
+ *
3206
+ * @return {void} This method does not return any value.
3207
+ */
2607
3208
  executeFunction() {
2608
3209
  if (this.lastTimeout) {
2609
3210
  clearTimeout(this.lastTimeout);
@@ -2629,6 +3230,19 @@ var DebounceTask = class extends Task {
2629
3230
  }
2630
3231
  }
2631
3232
  }
3233
+ /**
3234
+ * Executes a debounced operation, ensuring controlled execution of functions
3235
+ * over a specified debounce time and maximum wait time. This method handles
3236
+ * both leading and trailing edge executions and invokes callbacks accordingly.
3237
+ *
3238
+ * @param {Function} resolve - The function to call when the operation is successfully resolved.
3239
+ * @param {Function} reject - The function to call with an error or reason if the operation fails.
3240
+ * @param {GraphContext} context - The execution context for the operation.
3241
+ * @param {NodeJS.Timeout} timeout - A timeout object for managing execution delays.
3242
+ * @param {Function} emit - A callback function to emit signals with a specific context.
3243
+ * @param {Function} progressCallback - A callback function to report progress during operation execution.
3244
+ * @return {void} Does not return a value but sets internal timers and invokes provided callbacks.
3245
+ */
2632
3246
  debouncedTrigger(resolve, reject, context, timeout, emit, progressCallback) {
2633
3247
  const callNow = this.leading && this.timer === null;
2634
3248
  const isNewBurst = this.timer === null;
@@ -2674,6 +3288,14 @@ var DebounceTask = class extends Task {
2674
3288
  }, this.maxWait);
2675
3289
  }
2676
3290
  }
3291
+ /**
3292
+ * Executes a task with a debounced trigger mechanism.
3293
+ *
3294
+ * @param {GraphContext} context - The context containing relevant graph data for the execution.
3295
+ * @param {function(string, any): void} emit - A function used to emit signals with associated context.
3296
+ * @param {function(number): void} progressCallback - A callback function to report the progress of the task as a number between 0 and 1.
3297
+ * @return {Promise<TaskResult>} A promise that resolves with the task result upon completion or rejects on failure.
3298
+ */
2677
3299
  execute(context, emit, progressCallback) {
2678
3300
  return new Promise((resolve, reject) => {
2679
3301
  const timeout = setTimeout(() => {
@@ -2719,6 +3341,15 @@ var EphemeralTask = class extends Task {
2719
3341
  this.once = once;
2720
3342
  this.condition = condition;
2721
3343
  }
3344
+ /**
3345
+ * Executes the process logic with the provided context, emit function, progress callback, and node data.
3346
+ *
3347
+ * @param {any} context - The execution context, carrying necessary parameters or states for the operation.
3348
+ * @param {function(string, AnyObject): void} emit - A function to emit signals with a string identifier and associated context.
3349
+ * @param {function(number): void} progressCallback - A callback function to report the progress of the execution as a numerical value.
3350
+ * @param {{ nodeId: string, routineExecId: string }} nodeData - An object containing details about the node ID and routine execution ID.
3351
+ * @return {any} The result of the execution, returned from the base implementation or processed internally.
3352
+ */
2722
3353
  execute(context, emit, progressCallback, nodeData) {
2723
3354
  const result = super.execute(context, emit, progressCallback, nodeData);
2724
3355
  if (this.once || this.condition(result)) {
@@ -2812,26 +3443,56 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2812
3443
  this.debug = false;
2813
3444
  this.index = index;
2814
3445
  }
3446
+ /**
3447
+ * Sets the debug mode for the current instance and all associated nodes.
3448
+ *
3449
+ * @param {boolean} value - A boolean value to enable (true) or disable (false) debug mode.
3450
+ * @return {void} No return value.
3451
+ */
2815
3452
  setDebug(value) {
2816
3453
  this.debug = value;
2817
3454
  for (const node of this.nodes) {
2818
3455
  node.setDebug(value);
2819
3456
  }
2820
3457
  }
3458
+ /**
3459
+ * Checks if the current layer has a preceding layer.
3460
+ *
3461
+ * @return {boolean} True if the current layer has a preceding layer that is an instance of GraphLayer; otherwise, false.
3462
+ */
2821
3463
  get hasPreceding() {
2822
3464
  return !!this.previous && this.previous instanceof _GraphLayer;
2823
3465
  }
2824
3466
  getNumberOfNodes() {
2825
3467
  return this.nodes.length;
2826
3468
  }
3469
+ /**
3470
+ * Retrieves a list of nodes that match the given routine execution ID.
3471
+ *
3472
+ * @param {string} routineExecId - The ID of the routine execution to filter nodes by.
3473
+ * @return {Array} An array of nodes that have the specified routine execution ID.
3474
+ */
2827
3475
  getNodesByRoutineExecId(routineExecId) {
2828
3476
  return this.nodes.filter((node) => node.routineExecId === routineExecId);
2829
3477
  }
3478
+ /**
3479
+ * Finds and returns all nodes in the graph that are identical to the given node.
3480
+ * Two nodes are considered identical if they share the same routine execution ID
3481
+ * and share a task with each other.
3482
+ *
3483
+ * @param {GraphNode} node - The reference node to compare against other nodes in the graph.
3484
+ * @return {GraphNode[]} An array of nodes that are identical to the given node.
3485
+ */
2830
3486
  getIdenticalNodes(node) {
2831
3487
  return this.nodes.filter(
2832
3488
  (n) => node.routineExecId === n.routineExecId && node.sharesTaskWith(n)
2833
3489
  );
2834
3490
  }
3491
+ /**
3492
+ * Checks whether all nodes in the collection have been processed.
3493
+ *
3494
+ * @return {boolean} Returns true if all nodes are processed, otherwise false.
3495
+ */
2835
3496
  isProcessed() {
2836
3497
  for (const node of this.nodes) {
2837
3498
  if (!node.isProcessed()) {
@@ -2840,6 +3501,11 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2840
3501
  }
2841
3502
  return true;
2842
3503
  }
3504
+ /**
3505
+ * Checks whether all layers in the graph have been processed.
3506
+ *
3507
+ * @return {boolean} Returns true if all graph layers are processed; otherwise, returns false.
3508
+ */
2843
3509
  graphDone() {
2844
3510
  let done = true;
2845
3511
  let layer = this;
@@ -2852,6 +3518,13 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2852
3518
  }
2853
3519
  return done;
2854
3520
  }
3521
+ /**
3522
+ * Sets the next GraphLayer in the sequence if it has a higher index than the current layer.
3523
+ * Updates the previous property if the given next layer has an existing previous layer.
3524
+ *
3525
+ * @param {GraphLayer} next - The next GraphLayer to be linked in the sequence.
3526
+ * @return {void} Does not return a value. Modifies the current layer's state.
3527
+ */
2855
3528
  setNext(next) {
2856
3529
  if (next.index <= this.index) {
2857
3530
  return;
@@ -2861,15 +3534,32 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2861
3534
  }
2862
3535
  super.setNext(next);
2863
3536
  }
3537
+ /**
3538
+ * Adds a node to the graph.
3539
+ *
3540
+ * @param {GraphNode} node - The node to be added to the graph.
3541
+ * @return {void}
3542
+ */
2864
3543
  add(node) {
2865
3544
  this.nodes.push(node);
2866
3545
  }
3546
+ /**
3547
+ * Starts the execution timer if it has not been started already.
3548
+ * Records the current timestamp as the start time.
3549
+ *
3550
+ * @return {number} The timestamp representing the start time in milliseconds.
3551
+ */
2867
3552
  start() {
2868
3553
  if (!this.executionStart) {
2869
3554
  this.executionStart = Date.now();
2870
3555
  }
2871
3556
  return this.executionStart;
2872
3557
  }
3558
+ /**
3559
+ * Marks the end of a process by capturing the current timestamp and calculating the execution time if a start time exists.
3560
+ *
3561
+ * @return {number} The timestamp at which the process ended, or 0 if the start time is not defined.
3562
+ */
2873
3563
  end() {
2874
3564
  if (!this.executionStart) {
2875
3565
  return 0;
@@ -2878,6 +3568,14 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2878
3568
  this.executionTime = end - this.executionStart;
2879
3569
  return end;
2880
3570
  }
3571
+ /**
3572
+ * Destroys the current graph layer and its associated resources.
3573
+ * This method recursively destroys all nodes in the current layer, clears the node list,
3574
+ * and ensures that any connected subsequent graph layers are also destroyed.
3575
+ * Additionally, it calls the decoupling logic to disconnect the current layer from its dependencies.
3576
+ *
3577
+ * @return {void} Does not return any value.
3578
+ */
2881
3579
  destroy() {
2882
3580
  for (const node of this.nodes) {
2883
3581
  node.destroy();
@@ -2889,9 +3587,20 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2889
3587
  }
2890
3588
  this.decouple();
2891
3589
  }
3590
+ /**
3591
+ * Returns an iterator for traversing through the graph layers.
3592
+ *
3593
+ * @return {GraphLayerIterator} An instance of GraphLayerIterator to traverse graph layers.
3594
+ */
2892
3595
  getIterator() {
2893
3596
  return new GraphLayerIterator(this);
2894
3597
  }
3598
+ /**
3599
+ * Accepts a visitor object to traverse or perform operations on the current graph layer and its nodes.
3600
+ *
3601
+ * @param {GraphVisitor} visitor - The visitor instance implementing the visitLayer and visitNode behavior.
3602
+ * @return {void} Returns nothing.
3603
+ */
2895
3604
  accept(visitor) {
2896
3605
  visitor.visitLayer(this);
2897
3606
  for (const node of this.nodes) {
@@ -2928,6 +3637,14 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2928
3637
 
2929
3638
  // src/graph/execution/SyncGraphLayer.ts
2930
3639
  var SyncGraphLayer = class extends GraphLayer {
3640
+ /**
3641
+ * Executes the processing logic of the current set of graph nodes. Iterates through all
3642
+ * nodes, skipping any that have already been processed, and executes their respective
3643
+ * logic to generate new nodes. Asynchronous functions are not supported and will
3644
+ * trigger an error log.
3645
+ *
3646
+ * @return {GraphNode[]} An array of newly generated graph nodes after executing the logic of each unprocessed node.
3647
+ */
2931
3648
  execute() {
2932
3649
  this.start();
2933
3650
  const result = [];
@@ -2960,20 +3677,49 @@ var GraphBuilder = class {
2960
3677
  getResult() {
2961
3678
  return this.graph;
2962
3679
  }
3680
+ /**
3681
+ * Composes a series of functions or operations.
3682
+ * This method should be implemented in the child class
3683
+ * to define custom composition logic.
3684
+ *
3685
+ * @return {any} The result of the composed operations or functions
3686
+ * when implemented in the child class.
3687
+ */
2963
3688
  compose() {
2964
3689
  throw "Implement this in child class...";
2965
3690
  }
3691
+ /**
3692
+ * Adds a node to the appropriate layer of the graph.
3693
+ *
3694
+ * @param {GraphNode} node - The node to be added to the graph. The node contains
3695
+ * layer information that determines which layer it belongs to.
3696
+ * @return {void} Does not return a value.
3697
+ */
2966
3698
  addNode(node) {
2967
3699
  const index = node.getLayerIndex();
2968
3700
  this.addLayer(index);
2969
3701
  const layer = this.getLayer(index);
2970
3702
  node.scheduleOn(layer);
2971
3703
  }
3704
+ /**
3705
+ * Adds multiple nodes to the graph.
3706
+ *
3707
+ * @param {GraphNode[]} nodes - An array of nodes to be added to the graph.
3708
+ * @return {void} This method does not return a value.
3709
+ */
2972
3710
  addNodes(nodes) {
2973
3711
  for (const node of nodes) {
2974
3712
  this.addNode(node);
2975
3713
  }
2976
3714
  }
3715
+ /**
3716
+ * Adds a new layer to the graph at the specified index. If the graph does not exist,
3717
+ * it creates the graph using the specified index. Updates the graph's top layer index
3718
+ * and maintains the order of layers.
3719
+ *
3720
+ * @param {number} index - The index at which the new layer should be added to the graph.
3721
+ * @return {void} This method does not return a value.
3722
+ */
2977
3723
  addLayer(index) {
2978
3724
  if (!this.graph) {
2979
3725
  const layer = this.createLayer(index);
@@ -3000,11 +3746,23 @@ var GraphBuilder = class {
3000
3746
  this.addLayer(index);
3001
3747
  }
3002
3748
  }
3749
+ /**
3750
+ * Creates a new layer for the graph at the specified index.
3751
+ *
3752
+ * @param {number} index - The index of the layer to be created.
3753
+ * @return {GraphLayer} A new instance of the graph layer corresponding to the provided index.
3754
+ */
3003
3755
  createLayer(index) {
3004
3756
  const layer = new SyncGraphLayer(index);
3005
3757
  layer.setDebug(this.debug);
3006
3758
  return layer;
3007
3759
  }
3760
+ /**
3761
+ * Retrieves a specific layer from the current set of layers.
3762
+ *
3763
+ * @param {number} layerIndex - The index of the layer to retrieve.
3764
+ * @return {*} The layer corresponding to the given index.
3765
+ */
3008
3766
  getLayer(layerIndex) {
3009
3767
  return this.layers[layerIndex - this.topLayerIndex];
3010
3768
  }
@@ -3017,6 +3775,12 @@ var GraphBuilder = class {
3017
3775
 
3018
3776
  // src/engine/builders/GraphBreadthFirstBuilder.ts
3019
3777
  var GraphBreadthFirstBuilder = class extends GraphBuilder {
3778
+ /**
3779
+ * Composes layers of a graph by iterating through them, executing their logic,
3780
+ * and adding the resulting nodes to the current graph.
3781
+ *
3782
+ * @return {void} This method does not return a value.
3783
+ */
3020
3784
  compose() {
3021
3785
  if (!this.graph) {
3022
3786
  return;
@@ -3072,6 +3836,15 @@ var ThrottleEngine = class _ThrottleEngine {
3072
3836
  setConcurrencyLimit(tag, limit) {
3073
3837
  this.maxConcurrencyPerTag[tag] = limit;
3074
3838
  }
3839
+ /**
3840
+ * Manages the execution of a function `fn` applied on a specified node `node` with controlled concurrency for a given tag.
3841
+ * The method ensures that processes are executed in a throttled manner, respecting the maximum concurrency for each tag.
3842
+ *
3843
+ * @param {ProcessFunction} fn - The function to be executed on the provided node.
3844
+ * @param {GraphNode} node - The graph node on which the function `fn` will be applied.
3845
+ * @param {string} [tag="default"] - The concurrency grouping tag used to control and group the throttling behavior.
3846
+ * @return {Promise<GraphNode[]>} A promise resolving to an array of GraphNode objects once the throttled function execution completes.
3847
+ */
3075
3848
  throttle(fn, node, tag = "default") {
3076
3849
  var _a, _b;
3077
3850
  const functionPromise = new Promise((resolve) => {
@@ -3083,6 +3856,12 @@ var ThrottleEngine = class _ThrottleEngine {
3083
3856
  this.processQueue(tag);
3084
3857
  return functionPromise;
3085
3858
  }
3859
+ /**
3860
+ * Processes the tasks in the queue for a given tag while respecting concurrency limits.
3861
+ *
3862
+ * @param {string} tag - The identifier for the queue to be processed, used to group tasks and manage concurrency controls.
3863
+ * @return {void} Does not return a value; it processes tasks asynchronously and manages state internally.
3864
+ */
3086
3865
  processQueue(tag) {
3087
3866
  const maxAllowed = this.maxConcurrencyPerTag[tag];
3088
3867
  while ((this.queues[tag]?.length ?? 0) > 0 && (this.runningCounts[tag] ?? 0) < maxAllowed) {
@@ -3098,6 +3877,14 @@ var ThrottleEngine = class _ThrottleEngine {
3098
3877
  delete this.runningCounts[tag];
3099
3878
  }
3100
3879
  }
3880
+ /**
3881
+ * Processes a given item consisting of a function and a graph node.
3882
+ *
3883
+ * @param {Array} item - An array where the first element is a processing function and the second element is a graph node.
3884
+ * @param {Function} item[0] - The function to process the graph node.
3885
+ * @param {GraphNode} item[1] - The graph node to be processed.
3886
+ * @return {Promise<void>} A promise that resolves when the processing and cleanup are complete.
3887
+ */
3101
3888
  async process(item) {
3102
3889
  const fn = item[0];
3103
3890
  const node = item[1];
@@ -3114,10 +3901,24 @@ var AsyncGraphLayer = class extends GraphLayer {
3114
3901
  this.waitingNodes = [];
3115
3902
  this.processingNodes = /* @__PURE__ */ new Set();
3116
3903
  }
3904
+ /**
3905
+ * Adds a node to the graph and tracks it as a waiting node.
3906
+ *
3907
+ * @param {GraphNode} node - The graph node to be added.
3908
+ * @return {void}
3909
+ */
3117
3910
  add(node) {
3118
3911
  this.nodes.push(node);
3119
3912
  this.waitingNodes.push(node);
3120
3913
  }
3914
+ /**
3915
+ * Executes the processing of nodes by iterating over the queued `waitingNodes`,
3916
+ * processing each node, and managing concurrency limits where applicable.
3917
+ * The method returns a mapping of routine execution IDs to arrays of processed nodes or promises.
3918
+ *
3919
+ * @return {Object} An object where the keys are routine execution IDs and the values
3920
+ * represent arrays of processed nodes or promises resolving to processed nodes.
3921
+ */
3121
3922
  execute() {
3122
3923
  var _a;
3123
3924
  if (this.waitingNodes.length === 0) {
@@ -3151,6 +3952,13 @@ var AsyncGraphLayer = class extends GraphLayer {
3151
3952
  }
3152
3953
  return result;
3153
3954
  }
3955
+ /**
3956
+ * Processes the given graph node, executes its logic, and handles synchronous or asynchronous outcomes.
3957
+ *
3958
+ * @param {GraphNode} node - The graph node to be processed.
3959
+ * @return {Promise<GraphNode[]> | GraphNode[]} A promise that resolves to an array of next graph nodes if asynchronous,
3960
+ * or an array of next graph nodes if synchronous.
3961
+ */
3154
3962
  processNode(node) {
3155
3963
  node.start();
3156
3964
  const nextNodes = node.execute();
@@ -3160,11 +3968,23 @@ var AsyncGraphLayer = class extends GraphLayer {
3160
3968
  this.processingNodes.delete(node);
3161
3969
  return nextNodes;
3162
3970
  }
3971
+ /**
3972
+ * Processes the given graph node asynchronously and removes it from the processing nodes set.
3973
+ *
3974
+ * @param {GraphNode} node - The current graph node being processed.
3975
+ * @param {Promise<GraphNode[]>} nextNodes - A promise that resolves to an array of the next graph nodes to process.
3976
+ * @return {Promise<GraphNode[]>} A promise that resolves to an array of the next graph nodes.
3977
+ */
3163
3978
  async processAsync(node, nextNodes) {
3164
3979
  const result = await nextNodes;
3165
3980
  this.processingNodes.delete(node);
3166
3981
  return result;
3167
3982
  }
3983
+ /**
3984
+ * Cleans up resources used by the instance by resetting relevant properties and invoking the parent class's destroy method.
3985
+ *
3986
+ * @return {void} No value is returned as the method performs cleanup operations.
3987
+ */
3168
3988
  destroy() {
3169
3989
  super.destroy();
3170
3990
  this.waitingNodes = [];
@@ -3174,6 +3994,14 @@ var AsyncGraphLayer = class extends GraphLayer {
3174
3994
 
3175
3995
  // src/engine/builders/GraphAsyncQueueBuilder.ts
3176
3996
  var GraphAsyncQueueBuilder = class extends GraphBuilder {
3997
+ /**
3998
+ * This method iterates over a graph structure and processes its layers sequentially.
3999
+ * It continues processing each layer until all layers in the graph are completed.
4000
+ * The asynchronous behavior ensures the operation provides breathing room for other
4001
+ * tasks/processes to execute during its operation.
4002
+ *
4003
+ * @return {Promise<void>} A promise that resolves when all layers of the graph are processed or rejects if an error occurs.
4004
+ */
3177
4005
  async compose() {
3178
4006
  if (!this.graph) {
3179
4007
  return;
@@ -3192,6 +4020,14 @@ var GraphAsyncQueueBuilder = class extends GraphBuilder {
3192
4020
  await sleep(0);
3193
4021
  }
3194
4022
  }
4023
+ /**
4024
+ * Processes a given asynchronous graph layer and executes its nodes.
4025
+ * Handles promises within the nodes and adds the resolved or processed
4026
+ * nodes to the graph.
4027
+ *
4028
+ * @param {AsyncGraphLayer} layer - The asynchronous graph layer to be processed.
4029
+ * @return {void} - This method does not return a value.
4030
+ */
3195
4031
  processLayer(layer) {
3196
4032
  const nextNodes = layer.execute();
3197
4033
  for (const routineExecId of Object.keys(nextNodes)) {
@@ -3205,6 +4041,13 @@ var GraphAsyncQueueBuilder = class extends GraphBuilder {
3205
4041
  }
3206
4042
  }
3207
4043
  }
4044
+ /**
4045
+ * Creates a new instance of AsyncGraphLayer, sets its debug configuration,
4046
+ * and returns the created layer.
4047
+ *
4048
+ * @param {number} index - The index to associate with the new AsyncGraphLayer.
4049
+ * @return {AsyncGraphLayer} A new instance of AsyncGraphLayer with the specified index and debug configuration.
4050
+ */
3208
4051
  createLayer(index) {
3209
4052
  const layer = new AsyncGraphLayer(index);
3210
4053
  layer.setDebug(this.debug);
@@ -3218,6 +4061,12 @@ var GraphAsyncRun = class extends GraphRunStrategy {
3218
4061
  super();
3219
4062
  this.graphBuilder = new GraphAsyncQueueBuilder();
3220
4063
  }
4064
+ /**
4065
+ * Executes the run operation, which involves composing the graph builder,
4066
+ * updating the run instance, and resetting the state.
4067
+ *
4068
+ * @return {Promise<void>} A promise that resolves when the operation completes.
4069
+ */
3221
4070
  async run() {
3222
4071
  await this.graphBuilder.compose();
3223
4072
  this.updateRunInstance();
@@ -3233,6 +4082,12 @@ var GraphAsyncRun = class extends GraphRunStrategy {
3233
4082
 
3234
4083
  // src/engine/strategy/GraphStandardRun.ts
3235
4084
  var GraphStandardRun = class extends GraphRunStrategy {
4085
+ /**
4086
+ * Executes the sequence of operations involving graph composition,
4087
+ * instance updating, and reset mechanisms.
4088
+ *
4089
+ * @return {void} Does not return a value.
4090
+ */
3236
4091
  run() {
3237
4092
  this.graphBuilder.compose();
3238
4093
  this.updateRunInstance();
@@ -3245,6 +4100,13 @@ var GraphStandardRun = class extends GraphRunStrategy {
3245
4100
 
3246
4101
  // src/Cadenza.ts
3247
4102
  var Cadenza = class {
4103
+ /**
4104
+ * Initializes the system by setting up the required components such as the
4105
+ * signal broker, runners, and graph registry. Ensures the initialization
4106
+ * happens only once. Configures debug settings if applicable.
4107
+ *
4108
+ * @return {void} No value is returned.
4109
+ */
3248
4110
  static bootstrap() {
3249
4111
  if (this.isBootstrapped) return;
3250
4112
  this.isBootstrapped = true;
@@ -3262,12 +4124,27 @@ var Cadenza = class {
3262
4124
  this.runner.init();
3263
4125
  this.metaRunner.init();
3264
4126
  }
4127
+ /**
4128
+ * Retrieves the available strategies for running graphs.
4129
+ *
4130
+ * @return {Object} An object containing the available run strategies, where:
4131
+ * - PARALLEL: Executes graph runs asynchronously.
4132
+ * - SEQUENTIAL: Executes graph runs in a sequential order.
4133
+ */
3265
4134
  static get runStrategy() {
3266
4135
  return {
3267
4136
  PARALLEL: new GraphAsyncRun(),
3268
4137
  SEQUENTIAL: new GraphStandardRun()
3269
4138
  };
3270
4139
  }
4140
+ /**
4141
+ * Sets the mode for the application and configures the broker and runner settings accordingly.
4142
+ *
4143
+ * @param {CadenzaMode} mode - The mode to set. It can be one of the following:
4144
+ * "debug", "dev", "verbose", or "production".
4145
+ * Each mode adjusts debug and verbosity settings.
4146
+ * @return {void} This method does not return a value.
4147
+ */
3271
4148
  static setMode(mode) {
3272
4149
  this.mode = mode;
3273
4150
  this.bootstrap();
@@ -3289,29 +4166,129 @@ var Cadenza = class {
3289
4166
  }
3290
4167
  }
3291
4168
  /**
3292
- * Validates a name for uniqueness and non-emptiness.
3293
- * @param name The name to validate.
3294
- * @throws Error if invalid.
4169
+ * Validates the given name to ensure it is a non-empty string.
4170
+ * Throws an error if the validation fails.
4171
+ *
4172
+ * @param {string} name - The name to validate.
4173
+ * @return {void} This method does not return anything.
4174
+ * @throws {Error} If the name is not a non-empty string.
3295
4175
  */
3296
4176
  static validateName(name) {
3297
4177
  if (!name || typeof name !== "string") {
3298
4178
  throw new Error("Task or Routine name must be a non-empty string.");
3299
4179
  }
3300
4180
  }
4181
+ /**
4182
+ * Executes the specified task or GraphRoutine with the given context using an internal runner.
4183
+ *
4184
+ * @param {Task | GraphRoutine} task - The task or GraphRoutine to be executed.
4185
+ * @param {AnyObject} context - The context in which the task or GraphRoutine should be executed.
4186
+ * @return {void}
4187
+ *
4188
+ * @example
4189
+ * ```ts
4190
+ * const task = Cadenza.createTask('My task', (ctx) => {
4191
+ * console.log('My task executed with context:', ctx);
4192
+ * });
4193
+ *
4194
+ * Cadenza.run(task, { foo: 'bar' });
4195
+ *
4196
+ * const routine = Cadenza.createRoutine('My routine', [task], 'My routine description');
4197
+ *
4198
+ * Cadenza.run(routine, { foo: 'bar' });
4199
+ * ```
4200
+ */
3301
4201
  static run(task, context) {
3302
4202
  this.runner?.run(task, context);
3303
4203
  }
4204
+ /**
4205
+ * Emits an event with the specified name and data payload to the broker.
4206
+ *
4207
+ * @param {string} event - The name of the event to emit.
4208
+ * @param {AnyObject} [data={}] - The data payload associated with the event.
4209
+ * @return {void} - No return value.
4210
+ *
4211
+ * @example
4212
+ * This is meant to be used as a global event emitter.
4213
+ * If you want to emit an event from within a task, you can use the `emit` method provided to the task function. See {@link TaskFunction}.
4214
+ * ```ts
4215
+ * Cadenza.emit('main.my_event', { foo: 'bar' });
4216
+ * ```
4217
+ */
3304
4218
  static emit(event, data = {}) {
3305
4219
  this.broker?.emit(event, data);
3306
4220
  }
3307
4221
  /**
3308
- * Creates a standard Task and registers it in the GraphRegistry.
3309
- * @param name Unique identifier for the task.
3310
- * @param func The function or async generator to execute.
3311
- * @param description Optional human-readable description for introspection.
3312
- * @param options Optional task options.
3313
- * @returns The created Task instance.
3314
- * @throws Error if name is invalid or duplicate in registry.
4222
+ * Creates and registers a new task with the specified parameters and options.
4223
+ * Tasks are the basic building blocks of Cadenza graphs and are responsible for executing logic.
4224
+ * See {@link Task} for more information.
4225
+ *
4226
+ * @param {string} name - The unique name of the task.
4227
+ * @param {TaskFunction} func - The function to be executed by the task.
4228
+ * @param {string} [description] - An optional description for the task.
4229
+ * @param {TaskOptions} [options={}] - Configuration options for the task, such as concurrency, timeout, and retry settings.
4230
+ * @return {Task} The created task instance.
4231
+ *
4232
+ * @example
4233
+ * You can use arrow functions to create tasks.
4234
+ * ```ts
4235
+ * const task = Cadenza.createTask('My task', (ctx) => {
4236
+ * console.log('My task executed with context:', ctx);
4237
+ * }, 'My task description');
4238
+ * ```
4239
+ *
4240
+ * You can also use named functions to create tasks.
4241
+ * This is the preferred way to create tasks since it allows for code inspection in the CadenzaUI.
4242
+ * ```ts
4243
+ * function myTask(ctx) {
4244
+ * console.log('My task executed with context:', ctx);
4245
+ * }
4246
+ *
4247
+ * const task = Cadenza.createTask('My task', myTask);
4248
+ * ```
4249
+ *
4250
+ * ** Use the TaskOptions object to configure the task. **
4251
+ *
4252
+ * With concurrency limit, timeout limit and retry settings.
4253
+ * ```ts
4254
+ * Cadenza.createTask('My task', (ctx) => {
4255
+ * console.log('My task executed with context:', ctx);
4256
+ * }, 'My task description', {
4257
+ * concurrency: 10,
4258
+ * timeout: 10000,
4259
+ * retryCount: 3,
4260
+ * retryDelay: 1000,
4261
+ * retryDelayFactor: 1.5,
4262
+ * });
4263
+ * ```
4264
+ *
4265
+ * You can specify the input and output context schemas for the task.
4266
+ * ```ts
4267
+ * Cadenza.createTask('My task', (ctx) => {
4268
+ * return { bar: 'foo' + ctx.foo };
4269
+ * }, 'My task description', {
4270
+ * inputContextSchema: {
4271
+ * type: 'object',
4272
+ * properties: {
4273
+ * foo: {
4274
+ * type: 'string',
4275
+ * },
4276
+ * },
4277
+ * required: ['foo'],
4278
+ * },
4279
+ * validateInputContext: true, // default is false
4280
+ * outputContextSchema: {
4281
+ * type: 'object',
4282
+ * properties: {
4283
+ * bar: {
4284
+ * type: 'string',
4285
+ * },
4286
+ * },
4287
+ * required: ['bar'],
4288
+ * },
4289
+ * validateOutputContext: true, // default is false
4290
+ * });
4291
+ * ```
3315
4292
  */
3316
4293
  static createTask(name, func, description, options = {}) {
3317
4294
  this.bootstrap();
@@ -3358,40 +4335,82 @@ var Cadenza = class {
3358
4335
  );
3359
4336
  }
3360
4337
  /**
3361
- * Creates a MetaTask (for meta-layer graphs) and registers it.
3362
- * MetaTasks suppress further meta-signal emissions to prevent loops.
3363
- * @param name Unique identifier for the meta-task.
3364
- * @param func The function or async generator to execute.
3365
- * @param description Optional description.
3366
- * @param options Optional task options.
3367
- * @returns The created MetaTask instance.
3368
- * @throws Error if name invalid or duplicate.
4338
+ * Creates a meta task with the specified name, functionality, description, and options.
4339
+ * This is used for creating tasks that lives on the meta layer.
4340
+ * The meta layer is a special layer that is executed separately from the business logic layer and is used for extending Cadenzas core functionality.
4341
+ * See {@link Task} or {@link createTask} for more information.
4342
+ *
4343
+ * @param {string} name - The name of the meta task.
4344
+ * @param {TaskFunction} func - The function to be executed by the meta task.
4345
+ * @param {string} [description] - An optional description of the meta task.
4346
+ * @param {TaskOptions} [options={}] - Additional optional task configuration. Automatically sets `isMeta` to true.
4347
+ * @return {Task} A task instance configured as a meta task.
3369
4348
  */
3370
4349
  static createMetaTask(name, func, description, options = {}) {
3371
4350
  options.isMeta = true;
3372
4351
  return this.createTask(name, func, description, options);
3373
4352
  }
3374
4353
  /**
3375
- * Creates a UniqueTask (executes once per execution ID, merging parents) and registers it.
3376
- * Use for fan-in/joins after parallel branches.
3377
- * @param name Unique identifier.
3378
- * @param func Function receiving joinedContexts.
3379
- * @param description Optional description.
3380
- * @param options Optional task options.
3381
- * @returns The created UniqueTask.
3382
- * @throws Error if invalid.
4354
+ * Creates a unique task by wrapping the provided task function with a uniqueness constraint.
4355
+ * Unique tasks are designed to execute once per execution ID, merging parents. This is useful for
4356
+ * tasks that require fan-in/joins after parallel branches.
4357
+ * See {@link Task} for more information.
4358
+ *
4359
+ * @param {string} name - The name of the task to be created.
4360
+ * @param {TaskFunction} func - The function that contains the logic for the task. It receives joinedContexts as a list in the context (context.joinedContexts).
4361
+ * @param {string} [description] - An optional description of the task.
4362
+ * @param {TaskOptions} [options={}] - Optional configuration for the task, such as additional metadata or task options.
4363
+ * @return {Task} The task instance that was created with a uniqueness constraint.
4364
+ *
4365
+ * @example
4366
+ * ```ts
4367
+ * const splitTask = Cadenza.createTask('Split foos', function* (ctx) {
4368
+ * for (const foo of ctx.foos) {
4369
+ * yield { foo };
4370
+ * }
4371
+ * }, 'Splits a list of foos into multiple sub-branches');
4372
+ *
4373
+ * const processTask = Cadenza.createTask('Process foo', (ctx) => {
4374
+ * return { bar: 'foo' + ctx.foo };
4375
+ * }, 'Process a foo');
4376
+ *
4377
+ * const uniqueTask = Cadenza.createUniqueTask('Gather processed foos', (ctx) => {
4378
+ * // A unique task will always be provided with a list of contexts (ctx.joinedContexts) from its predecessors.
4379
+ * const processedFoos = ctx.joinedContexts.map((c) => c.bar);
4380
+ * return { foos: processedFoos };
4381
+ * }, 'Gathers together the processed foos.');
4382
+ *
4383
+ * splitTask.then(
4384
+ * processTask.then(
4385
+ * uniqueTask,
4386
+ * ),
4387
+ * );
4388
+ *
4389
+ * // Give the flow a name using a routine
4390
+ * Cadenza.createRoutine(
4391
+ * 'Process foos',
4392
+ * [splitTask],
4393
+ * 'Processes a list of foos'
4394
+ * ).doOn('main.received_foos'); // Subscribe to a signal
4395
+ *
4396
+ * // Trigger the flow from anywhere
4397
+ * Cadenza.emit('main.received_foos', { foos: ['foo1', 'foo2', 'foo3'] });
4398
+ * ```
4399
+ *
3383
4400
  */
3384
4401
  static createUniqueTask(name, func, description, options = {}) {
3385
4402
  options.isUnique = true;
3386
4403
  return this.createTask(name, func, description, options);
3387
4404
  }
3388
4405
  /**
3389
- * Creates a UniqueMetaTask for meta-layer joins.
3390
- * @param name Unique identifier.
3391
- * @param func Function.
3392
- * @param description Optional.
3393
- * @param options Optional task options.
3394
- * @returns The created UniqueMetaTask.
4406
+ * Creates a unique meta task with the specified name, function, description, and options.
4407
+ * See {@link createUniqueTask} and {@link createMetaTask} for more information.
4408
+ *
4409
+ * @param {string} name - The name of the task to create.
4410
+ * @param {TaskFunction} func - The function to execute when the task is run.
4411
+ * @param {string} [description] - An optional description of the task.
4412
+ * @param {TaskOptions} [options={}] - Optional settings for the task. Defaults to an empty object. Automatically sets `isMeta` and `isUnique` to true.
4413
+ * @return {Task} The created unique meta task.
3395
4414
  */
3396
4415
  static createUniqueMetaTask(name, func, description, options = {}) {
3397
4416
  options.isMeta = true;
@@ -3399,14 +4418,33 @@ var Cadenza = class {
3399
4418
  return this.createUniqueTask(name, func, description, options);
3400
4419
  }
3401
4420
  /**
3402
- * Creates a ThrottledTask (rate-limited by concurrency or custom groups) and registers it.
3403
- * @param name Unique identifier.
3404
- * @param func Function.
3405
- * @param throttledIdGetter Optional getter for dynamic grouping (e.g., per-user).
3406
- * @param description Optional.
3407
- * @param options Optional task options.
3408
- * @returns The created ThrottledTask.
3409
- * @edge If no getter, throttles per task ID; use for resource protection.
4421
+ * Creates a throttled task with a concurrency limit of 1, ensuring that only one instance of the task can run at a time for a specific throttle tag.
4422
+ * This is useful for ensuring execution order and preventing race conditions.
4423
+ * See {@link Task} for more information.
4424
+ *
4425
+ * @param {string} name - The name of the task.
4426
+ * @param {TaskFunction} func - The function to be executed when the task runs.
4427
+ * @param {ThrottleTagGetter} [throttledIdGetter=() => "default"] - A function that generates a throttle tag identifier to group tasks for throttling.
4428
+ * @param {string} [description] - An optional description of the task.
4429
+ * @param {TaskOptions} [options={}] - Additional options to customize the task behavior.
4430
+ * @return {Task} The created throttled task.
4431
+ *
4432
+ * @example
4433
+ * ```ts
4434
+ * const task = Cadenza.createThrottledTask(
4435
+ * 'My task',
4436
+ * async (ctx) => {
4437
+ * await new Promise((resolve) => setTimeout(resolve, 1000));
4438
+ * console.log('My task executed with context:', ctx);
4439
+ * },
4440
+ * // Will throttle by the value of ctx.foo to make sure tasks with the same value are executed sequentially
4441
+ * (ctx) => ctx.foo,
4442
+ * );
4443
+ *
4444
+ * Cadenza.run(task, { foo: 'bar' }); // (First execution)
4445
+ * Cadenza.run(task, { foo: 'bar' }); // This will be executed after the first execution is finished
4446
+ * Cadenza.run(task, { foo: 'baz' }); // This will be executed in parallel with the first execution
4447
+ * ```
3410
4448
  */
3411
4449
  static createThrottledTask(name, func, throttledIdGetter = () => "default", description, options = {}) {
3412
4450
  options.concurrency = 1;
@@ -3414,13 +4452,15 @@ var Cadenza = class {
3414
4452
  return this.createTask(name, func, description, options);
3415
4453
  }
3416
4454
  /**
3417
- * Creates a ThrottledMetaTask for meta-layer throttling.
3418
- * @param name Identifier.
3419
- * @param func Function.
3420
- * @param throttledIdGetter Optional getter.
3421
- * @param description Optional.
3422
- * @param options Optional task options.
3423
- * @returns The created ThrottledMetaTask.
4455
+ * Creates a throttled meta task with the specified configuration.
4456
+ * See {@link createThrottledTask} and {@link createMetaTask} for more information.
4457
+ *
4458
+ * @param {string} name - The name of the throttled meta task.
4459
+ * @param {TaskFunction} func - The task function to be executed.
4460
+ * @param {ThrottleTagGetter} throttledIdGetter - A function to retrieve the throttling identifier.
4461
+ * @param {string} [description] - An optional description of the task.
4462
+ * @param {TaskOptions} [options={}] - Additional options for configuring the task.
4463
+ * @return {Task} The created throttled meta task.
3424
4464
  */
3425
4465
  static createThrottledMetaTask(name, func, throttledIdGetter, description, options = {}) {
3426
4466
  options.isMeta = true;
@@ -3433,14 +4473,37 @@ var Cadenza = class {
3433
4473
  );
3434
4474
  }
3435
4475
  /**
3436
- * Creates a DebounceTask (delays exec until quiet period) and registers it.
3437
- * @param name Identifier.
3438
- * @param func Function.
3439
- * @param description Optional.
3440
- * @param debounceTime Delay in ms (default 1000).
3441
- * @param options Optional task options plus optional debounce config (e.g., leading/trailing).
3442
- * @returns The created DebounceTask.
3443
- * @edge Multiple triggers within time collapse to one exec.
4476
+ * Creates and returns a new debounced task with the specified parameters.
4477
+ * This is useful to prevent rapid execution of tasks that may be triggered by multiple events within a certain time frame.
4478
+ * See {@link DebounceTask} for more information.
4479
+ *
4480
+ * @param {string} name - The unique name of the task to be created.
4481
+ * @param {TaskFunction} func - The function to be executed by the task.
4482
+ * @param {string} [description] - An optional description of the task.
4483
+ * @param {number} [debounceTime=1000] - The debounce time in milliseconds to delay the execution of the task.
4484
+ * @param {TaskOptions & DebounceOptions} [options={}] - Additional configuration options for the task, including debounce behavior and other task properties.
4485
+ * @return {DebounceTask} A new instance of the DebounceTask with the specified configuration.
4486
+ *
4487
+ * @example
4488
+ * ```ts
4489
+ * const task = Cadenza.createDebounceTask(
4490
+ * 'My debounced task',
4491
+ * (ctx) => {
4492
+ * console.log('My task executed with context:', ctx);
4493
+ * },
4494
+ * 'My debounced task description',
4495
+ * 100, // Debounce time in milliseconds. Default is 1000
4496
+ * {
4497
+ * leading: false, // Should the first execution of a burst be executed immediately? Default is false
4498
+ * trailing: true, // Should the last execution of a burst be executed? Default is true
4499
+ * maxWait: 1000, // Maximum time in milliseconds to wait for the next execution. Default is 0
4500
+ * },
4501
+ * );
4502
+ *
4503
+ * Cadenza.run(task, { foo: 'bar' }); // This will not be executed
4504
+ * Cadenza.run(task, { foo: 'bar' }); // This will not be executed
4505
+ * Cadenza.run(task, { foo: 'baz' }); // This execution will be delayed by 100ms
4506
+ * ```
3444
4507
  */
3445
4508
  static createDebounceTask(name, func, description, debounceTime = 1e3, options = {}) {
3446
4509
  this.bootstrap();
@@ -3484,13 +4547,15 @@ var Cadenza = class {
3484
4547
  );
3485
4548
  }
3486
4549
  /**
3487
- * Creates a DebouncedMetaTask for meta-layer debouncing.
3488
- * @param name Identifier.
3489
- * @param func Function.
3490
- * @param description Optional.
3491
- * @param debounceTime Delay in ms.
3492
- * @param options Optional task options plus optional debounce config (e.g., leading/trailing).
3493
- * @returns The created DebouncedMetaTask.
4550
+ * Creates a debounced meta task with the specified parameters.
4551
+ * See {@link createDebounceTask} and {@link createMetaTask} for more information.
4552
+ *
4553
+ * @param {string} name - The name of the task.
4554
+ * @param {TaskFunction} func - The function to be executed by the task.
4555
+ * @param {string} [description] - Optional description of the task.
4556
+ * @param {number} [debounceTime=1000] - The debounce delay in milliseconds.
4557
+ * @param {TaskOptions & DebounceOptions} [options={}] - Additional configuration options for the task.
4558
+ * @return {DebounceTask} Returns an instance of the debounced meta task.
3494
4559
  */
3495
4560
  static createDebounceMetaTask(name, func, description, debounceTime = 1e3, options = {}) {
3496
4561
  options.isMeta = true;
@@ -3503,14 +4568,64 @@ var Cadenza = class {
3503
4568
  );
3504
4569
  }
3505
4570
  /**
3506
- * Creates an EphemeralTask (self-destructs after exec or condition) without default registration.
3507
- * Useful for transients; optionally register if needed.
3508
- * @param name Identifier (may not be unique if not registered).
3509
- * @param func Function.
3510
- * @param description Optional.
3511
- * @param options Optional task options plus optional "once" (true) and "destroyCondition" (ctx => boolean).
3512
- * @returns The created EphemeralTask.
3513
- * @edge Destruction triggered post-exec via Node/Builder; emits meta-signal for cleanup.
4571
+ * Creates an ephemeral task with the specified configuration.
4572
+ * Ephemeral tasks are designed to self-destruct after execution or a certain condition is met.
4573
+ * This is useful for transient tasks such as resolving promises or performing cleanup operations.
4574
+ * They are not registered by default.
4575
+ * See {@link EphemeralTask} for more information.
4576
+ *
4577
+ * @param {string} name - The name of the task to be created.
4578
+ * @param {TaskFunction} func - The function that defines the logic of the task.
4579
+ * @param {string} [description] - An optional description of the task.
4580
+ * @param {TaskOptions & EphemeralTaskOptions} [options={}] - The configuration options for the task, including concurrency, timeouts, and retry policies.
4581
+ * @return {EphemeralTask} The created ephemeral task instance.
4582
+ *
4583
+ * @example
4584
+ * By default, ephemeral tasks are executed once and destroyed after execution.
4585
+ * ```ts
4586
+ * const task = Cadenza.createEphemeralTask('My ephemeral task', (ctx) => {
4587
+ * console.log('My task executed with context:', ctx);
4588
+ * });
4589
+ *
4590
+ * Cadenza.run(task); // Executes the task once and destroys it after execution
4591
+ * Cadenza.run(task); // Does nothing, since the task is destroyed
4592
+ * ```
4593
+ *
4594
+ * Use destroy condition to conditionally destroy the task
4595
+ * ```ts
4596
+ * const task = Cadenza.createEphemeralTask(
4597
+ * 'My ephemeral task',
4598
+ * (ctx) => {
4599
+ * console.log('My task executed with context:', ctx);
4600
+ * },
4601
+ * 'My ephemeral task description',
4602
+ * {
4603
+ * once: false, // Should the task be executed only once? Default is true
4604
+ * destroyCondition: (ctx) => ctx.foo > 10, // Should the task be destroyed after execution? Default is undefined
4605
+ * },
4606
+ * );
4607
+ *
4608
+ * Cadenza.run(task, { foo: 5 }); // The task will not be destroyed and can still be executed
4609
+ * Cadenza.run(task, { foo: 10 }); // The task will not be destroyed and can still be executed
4610
+ * Cadenza.run(task, { foo: 20 }); // The task will be destroyed after execution and cannot be executed anymore
4611
+ * Cadenza.run(task, { foo: 30 }); // This will not be executed
4612
+ * ```
4613
+ *
4614
+ * A practical use case for ephemeral tasks is to resolve a promise upon some external event.
4615
+ * ```ts
4616
+ * const task = Cadenza.createTask('Confirm something', (ctx, emit) => {
4617
+ * return new Promise((resolve) => {
4618
+ * ctx.foo = uuid();
4619
+ *
4620
+ * Cadenza.createEphemeralTask(`Resolve promise of ${ctx.foo}`, (c) => {
4621
+ * console.log('My task executed with context:', ctx);
4622
+ * resolve(c);
4623
+ * }).doOn(`socket.confirmation_received:${ctx.foo}`);
4624
+ *
4625
+ * emit('this_domain.confirmation_requested', ctx);
4626
+ * });
4627
+ * });
4628
+ * ```
3514
4629
  */
3515
4630
  static createEphemeralTask(name, func, description, options = {}) {
3516
4631
  this.bootstrap();
@@ -3561,45 +4676,72 @@ var Cadenza = class {
3561
4676
  );
3562
4677
  }
3563
4678
  /**
3564
- * Creates an EphemeralMetaTask for meta-layer transients.
3565
- * @param name Identifier.
3566
- * @param func Function.
3567
- * @param description Optional.
3568
- * @param options Optional task options plus optional "once" (true) and "destroyCondition" (ctx => boolean).
3569
- * @returns The created EphemeralMetaTask.
4679
+ * Creates an ephemeral meta task with the specified name, function, description, and options.
4680
+ * See {@link createEphemeralTask} and {@link createMetaTask} for more details.
4681
+ *
4682
+ * @param {string} name - The name of the task to be created.
4683
+ * @param {TaskFunction} func - The function to be executed as part of the task.
4684
+ * @param {string} [description] - An optional description of the task.
4685
+ * @param {TaskOptions & EphemeralTaskOptions} [options={}] - Additional options for configuring the task.
4686
+ * @return {EphemeralTask} The created ephemeral meta task.
3570
4687
  */
3571
4688
  static createEphemeralMetaTask(name, func, description, options = {}) {
3572
4689
  options.isMeta = true;
3573
4690
  return this.createEphemeralTask(name, func, description, options);
3574
4691
  }
3575
4692
  /**
3576
- * Creates a GraphRoutine (named entry to starting tasks) and registers it.
3577
- * @param name Unique identifier.
3578
- * @param tasks Starting tasks (can be empty, but warns as no-op).
3579
- * @param description Optional.
3580
- * @returns The created GraphRoutine.
3581
- * @edge If tasks empty, routine is valid but inert.
4693
+ * Creates a new routine with the specified name, tasks, and an optional description.
4694
+ * Routines are named entry points to starting tasks and are registered in the GraphRegistry.
4695
+ * They are used to group tasks together and provide a high-level structure for organizing and managing the execution of a set of tasks.
4696
+ * See {@link GraphRoutine} for more information.
4697
+ *
4698
+ * @param {string} name - The name of the routine to create.
4699
+ * @param {Task[]} tasks - A list of tasks to include in the routine.
4700
+ * @param {string} [description=""] - An optional description for the routine.
4701
+ * @return {GraphRoutine} A new instance of the GraphRoutine containing the specified tasks and description.
4702
+ *
4703
+ * @example
4704
+ * ```ts
4705
+ * const task1 = Cadenza.createTask("Task 1", () => {});
4706
+ * const task2 = Cadenza.createTask("Task 2", () => {});
4707
+ *
4708
+ * task1.then(task2);
4709
+ *
4710
+ * const routine = Cadenza.createRoutine("Some routine", [task1]);
4711
+ *
4712
+ * Cadenza.run(routine);
4713
+ *
4714
+ * // Or, routines can be triggered by signals
4715
+ * routine.doOn("some.signal");
4716
+ *
4717
+ * Cadenza.emit("some.signal", {});
4718
+ * ```
3582
4719
  */
3583
4720
  static createRoutine(name, tasks, description = "") {
3584
4721
  this.bootstrap();
3585
4722
  this.validateName(name);
3586
4723
  if (tasks.length === 0) {
3587
- console.warn(`Routine '${name}' created with no starting tasks (no-op).`);
4724
+ throw new Error(`Routine '${name}' created with no starting tasks.`);
3588
4725
  }
3589
4726
  return new GraphRoutine(name, tasks, description);
3590
4727
  }
3591
4728
  /**
3592
- * Creates a MetaRoutine for meta-layer entry points.
3593
- * @param name Identifier.
3594
- * @param tasks Starting tasks.
3595
- * @param description Optional.
3596
- * @returns The created MetaRoutine.
4729
+ * Creates a meta routine with a given name, tasks, and optional description.
4730
+ * Routines are named entry points to starting tasks and are registered in the GraphRegistry.
4731
+ * They are used to group tasks together and provide a high-level structure for organizing and managing the execution of a set of tasks.
4732
+ * See {@link GraphRoutine} and {@link createRoutine} for more information.
4733
+ *
4734
+ * @param {string} name - The name of the routine to be created.
4735
+ * @param {Task[]} tasks - An array of tasks that the routine will consist of.
4736
+ * @param {string} [description=""] - An optional description for the routine.
4737
+ * @return {GraphRoutine} A new instance of the `GraphRoutine` representing the created routine.
4738
+ * @throws {Error} If no starting tasks are provided.
3597
4739
  */
3598
4740
  static createMetaRoutine(name, tasks, description = "") {
3599
4741
  this.bootstrap();
3600
4742
  this.validateName(name);
3601
4743
  if (tasks.length === 0) {
3602
- console.warn(`Routine '${name}' created with no starting tasks (no-op).`);
4744
+ throw new Error(`Routine '${name}' created with no starting tasks.`);
3603
4745
  }
3604
4746
  return new GraphRoutine(name, tasks, description, true);
3605
4747
  }