@cadenza.io/core 3.9.2 → 3.11.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.js CHANGED
@@ -78,6 +78,7 @@ function formatTimestamp(timestamp) {
78
78
  }
79
79
 
80
80
  // src/engine/SignalBroker.ts
81
+ var import_uuid = require("uuid");
81
82
  var SignalBroker = class _SignalBroker {
82
83
  // execId -> emitted signals
83
84
  constructor() {
@@ -88,10 +89,6 @@ var SignalBroker = class _SignalBroker {
88
89
  this.emitStacks = /* @__PURE__ */ new Map();
89
90
  this.addSignal("meta.signal_broker.added");
90
91
  }
91
- /**
92
- * Singleton instance for signal management.
93
- * @returns The broker instance.
94
- */
95
92
  static get instance() {
96
93
  if (!this.instance_) {
97
94
  this.instance_ = new _SignalBroker();
@@ -104,6 +101,15 @@ var SignalBroker = class _SignalBroker {
104
101
  setVerbose(value) {
105
102
  this.verbose = value;
106
103
  }
104
+ /**
105
+ * Validates the provided signal name string to ensure it adheres to specific formatting rules.
106
+ * Throws an error if any of the validation checks fail.
107
+ *
108
+ * @param {string} signalName - The signal name to be validated.
109
+ * @return {void} - Returns nothing if the signal name is valid.
110
+ * @throws {Error} - Throws an error if the signal name is longer than 100 characters, contains spaces,
111
+ * contains backslashes, or contains uppercase letters in restricted parts of the name.
112
+ */
107
113
  validateSignalName(signalName) {
108
114
  if (signalName.length > 100) {
109
115
  throw new Error(
@@ -133,6 +139,11 @@ var SignalBroker = class _SignalBroker {
133
139
  this.runner = runner;
134
140
  this.metaRunner = metaRunner;
135
141
  }
142
+ /**
143
+ * Initializes and sets up the various tasks for managing and processing signals.
144
+ *
145
+ * @return {void} This method does not return a value.
146
+ */
136
147
  init() {
137
148
  this.clearSignalsTask = Cadenza.createDebounceMetaTask(
138
149
  "Execute and clear queued signals",
@@ -197,11 +208,82 @@ var SignalBroker = class _SignalBroker {
197
208
  }
198
209
  }
199
210
  /**
200
- * Emits a signal and bubbles to matching wildcards/parents (e.g., 'a.b.action' triggers 'a.b.action', 'a.b.*', 'a.*').
201
- * @param signal The signal name.
202
- * @param context The payload.
203
- * @edge Fire-and-forget; guards against loops per execId (from context.__graphExecId).
204
- * @edge For distribution, SignalTask can prefix and proxy remote.
211
+ * Schedules a signal to be emitted after a specified delay or at an exact date and time.
212
+ *
213
+ * @param {string} signal - The name of the signal to be emitted.
214
+ * @param {AnyObject} context - The context to be passed along with the signal.
215
+ * @param {number} [timeoutMs=60000] - The delay in milliseconds before the signal is emitted. Defaults to 60,000 ms.
216
+ * @param {Date} [exactDateTime] - An exact date and time at which to emit the signal. If provided, this overrides the `timeoutMs`.
217
+ * @return {AbortController} An AbortController instance that can be used to cancel the scheduled signal emission.
218
+ */
219
+ schedule(signal, context, timeoutMs = 6e4, exactDateTime) {
220
+ let delay = timeoutMs;
221
+ if (exactDateTime != null) {
222
+ delay = exactDateTime.getTime() - Date.now();
223
+ }
224
+ delay = Math.max(0, timeoutMs);
225
+ const controller = new AbortController();
226
+ const { signal: signalController } = controller;
227
+ const tick = () => this.emit(signal, context);
228
+ const timerId = setTimeout(() => {
229
+ if (!signalController.aborted) tick();
230
+ }, delay);
231
+ signalController.addEventListener("abort", () => clearTimeout(timerId));
232
+ return controller;
233
+ }
234
+ /**
235
+ * Emits `signal` repeatedly with a fixed interval.
236
+ *
237
+ * @param signal
238
+ * @param context
239
+ * @param intervalMs
240
+ * @param leading If true, emits immediately (unless a startDateTime is given and we are before it).
241
+ * @param startDateTime Optional absolute Date when the *first* emission after `leading` should occur.
242
+ * @returns a handle with `clear()` to stop the loop.
243
+ */
244
+ throttle(signal, context, intervalMs = 6e4, leading = false, startDateTime) {
245
+ if (intervalMs <= 0) {
246
+ throw new Error("intervalMs must be a positive number");
247
+ }
248
+ const emit = () => this.emit(signal, context);
249
+ if (leading) {
250
+ const now = Date.now();
251
+ const start = startDateTime?.getTime();
252
+ if (!start || start <= now) {
253
+ emit();
254
+ }
255
+ }
256
+ let firstDelay = intervalMs;
257
+ if (startDateTime) {
258
+ let slot = startDateTime.getTime();
259
+ const now = Date.now();
260
+ while (slot < now) {
261
+ slot += intervalMs;
262
+ }
263
+ firstDelay = slot - now;
264
+ }
265
+ let timer = null;
266
+ let stopped = false;
267
+ const scheduleNext = () => {
268
+ if (stopped) return;
269
+ emit();
270
+ timer = setTimeout(scheduleNext, intervalMs);
271
+ };
272
+ timer = setTimeout(scheduleNext, firstDelay);
273
+ return {
274
+ clear() {
275
+ stopped = true;
276
+ if (timer !== null) clearTimeout(timer);
277
+ }
278
+ };
279
+ }
280
+ /**
281
+ * Emits a signal with the specified context, triggering any associated handlers for that signal.
282
+ *
283
+ * @param {string} signal - The name of the signal to emit.
284
+ * @param {AnyObject} [context={}] - An optional context object containing additional information or metadata
285
+ * associated with the signal. If the context includes a `__routineExecId`, it will be handled accordingly.
286
+ * @return {void} This method does not return a value.
205
287
  */
206
288
  emit(signal, context = {}) {
207
289
  const execId = context.__routineExecId || "global";
@@ -218,15 +300,56 @@ var SignalBroker = class _SignalBroker {
218
300
  if (stack.size === 0) this.emitStacks.delete(execId);
219
301
  }
220
302
  }
303
+ /**
304
+ * Executes a signal by emitting events, updating context, and invoking listeners.
305
+ * Creates a new execution trace if necessary and updates the context with relevant metadata.
306
+ * Handles specific, hierarchy-based, and wildcard signals.
307
+ *
308
+ * @param {string} signal - The signal name to be executed, potentially including namespaces or tags (e.g., "meta.*" or "signal:type").
309
+ * @param {AnyObject} context - An object containing relevant metadata and execution details used for handling the signal.
310
+ * @return {boolean} Returns true if any listeners were successfully executed, otherwise false.
311
+ */
221
312
  execute(signal, context) {
222
313
  const isMeta = signal.includes("meta.");
223
314
  const isSubMeta = signal.includes("sub_meta.") || context.__isSubMeta;
224
315
  const isMetric = context.__signalEmission?.isMetric;
225
316
  if (!isSubMeta && (!isMeta || this.debug)) {
317
+ const isNewTrace = !context.__signalEmission?.executionTraceId && !context.__metadata?.__executionTraceId && !context.__executionTraceId;
318
+ const executionTraceId = context.__metadata?.__executionTraceId ?? context.__executionTraceId ?? (0, import_uuid.v4)();
319
+ if (isNewTrace) {
320
+ this.emit("sub_meta.signal_broker.new_trace", {
321
+ data: {
322
+ uuid: executionTraceId,
323
+ issuer_type: "service",
324
+ // TODO: Add issuer type
325
+ issuer_id: context.__metadata?.__issuerId ?? context.__issuerId ?? null,
326
+ issued_at: formatTimestamp(Date.now()),
327
+ intent: context.__metadata?.__intent ?? context.__intent ?? null,
328
+ context: {
329
+ id: (0, import_uuid.v4)(),
330
+ context
331
+ },
332
+ is_meta: isMeta
333
+ },
334
+ metadata: {
335
+ __executionTraceId: executionTraceId
336
+ }
337
+ });
338
+ context.__metadata = {
339
+ ...context.__metadata,
340
+ __executionTraceId: executionTraceId
341
+ };
342
+ }
226
343
  const emittedAt = Date.now();
344
+ const signalParts = signal.split(":");
345
+ const signalName = signalParts[0];
346
+ const signalTag = signalParts.length > 1 ? signalParts[1] : null;
227
347
  context.__signalEmission = {
228
348
  ...context.__signalEmission ?? {},
229
- signalName: signal,
349
+ uuid: (0, import_uuid.v4)(),
350
+ executionTraceId,
351
+ signalName,
352
+ signalTag,
230
353
  emittedAt: formatTimestamp(emittedAt),
231
354
  consumed: false,
232
355
  consumedBy: null,
@@ -254,6 +377,15 @@ var SignalBroker = class _SignalBroker {
254
377
  }
255
378
  return executed;
256
379
  }
380
+ /**
381
+ * Executes the tasks associated with a given signal and context.
382
+ * It processes both normal and meta tasks depending on the signal type
383
+ * and the availability of the appropriate runner.
384
+ *
385
+ * @param {string} signal - The signal identifier that determines which tasks to execute.
386
+ * @param {AnyObject} context - The context object passed to the task execution function.
387
+ * @return {boolean} - Returns true if tasks were executed; otherwise, false.
388
+ */
257
389
  executeListener(signal, context) {
258
390
  const obs = this.signalObservers.get(signal);
259
391
  if (!obs || obs.tasks.size === 0) {
@@ -279,6 +411,15 @@ var SignalBroker = class _SignalBroker {
279
411
  }
280
412
  return false;
281
413
  }
414
+ /**
415
+ * Adds a signal to the signalObservers for tracking and execution.
416
+ * Performs validation on the signal name and emits a meta signal event when added.
417
+ * If the signal contains a namespace (denoted by a colon ":"), its base signal is
418
+ * also added if it doesn't already exist.
419
+ *
420
+ * @param {string} signal - The name of the signal to be added.
421
+ * @return {void} This method does not return any value.
422
+ */
282
423
  addSignal(signal) {
283
424
  let _signal = signal;
284
425
  if (!this.signalObservers.has(_signal)) {
@@ -304,7 +445,6 @@ var SignalBroker = class _SignalBroker {
304
445
  this.emit("meta.signal_broker.added", { __signalName: _signal });
305
446
  }
306
447
  }
307
- // TODO schedule signals
308
448
  /**
309
449
  * Lists all observed signals.
310
450
  * @returns Array of signals.
@@ -319,10 +459,10 @@ var SignalBroker = class _SignalBroker {
319
459
  };
320
460
 
321
461
  // src/engine/GraphRunner.ts
322
- var import_uuid4 = require("uuid");
462
+ var import_uuid5 = require("uuid");
323
463
 
324
464
  // src/engine/GraphRun.ts
325
- var import_uuid = require("uuid");
465
+ var import_uuid2 = require("uuid");
326
466
 
327
467
  // src/utils/ColorRandomizer.ts
328
468
  var ColorRandomizer = class {
@@ -513,7 +653,7 @@ var VueFlowExporter = class {
513
653
  // src/engine/GraphRun.ts
514
654
  var GraphRun = class {
515
655
  constructor(strategy) {
516
- this.id = (0, import_uuid.v4)();
656
+ this.id = (0, import_uuid2.v4)();
517
657
  this.strategy = strategy;
518
658
  this.strategy.setRunInstance(this);
519
659
  this.exporter = new VueFlowExporter();
@@ -567,10 +707,10 @@ var GraphRun = class {
567
707
  };
568
708
 
569
709
  // src/graph/execution/GraphNode.ts
570
- var import_uuid3 = require("uuid");
710
+ var import_uuid4 = require("uuid");
571
711
 
572
712
  // src/graph/context/GraphContext.ts
573
- var import_uuid2 = require("uuid");
713
+ var import_uuid3 = require("uuid");
574
714
  var GraphContext = class _GraphContext {
575
715
  // __keys, frozen
576
716
  constructor(context) {
@@ -584,7 +724,7 @@ var GraphContext = class _GraphContext {
584
724
  this.metadata = Object.fromEntries(
585
725
  Object.entries(this.fullContext).filter(([key]) => key.startsWith("__"))
586
726
  );
587
- this.id = (0, import_uuid2.v4)();
727
+ this.id = (0, import_uuid3.v4)();
588
728
  }
589
729
  /**
590
730
  * Gets frozen user data (read-only, no clone).
@@ -593,6 +733,11 @@ var GraphContext = class _GraphContext {
593
733
  getContext() {
594
734
  return this.userData;
595
735
  }
736
+ /**
737
+ * Clones the current user context data and returns a deep-cloned copy of it.
738
+ *
739
+ * @return {AnyObject} A deep-cloned copy of the user context data.
740
+ */
596
741
  getClonedContext() {
597
742
  return deepCloneFilter(this.userData);
598
743
  }
@@ -603,6 +748,11 @@ var GraphContext = class _GraphContext {
603
748
  getFullContext() {
604
749
  return this.fullContext;
605
750
  }
751
+ /**
752
+ * Creates and returns a deep-cloned version of the fullContext object.
753
+ *
754
+ * @return {AnyObject} A deep copy of the fullContext instance, preserving all nested structures and data.
755
+ */
606
756
  getClonedFullContext() {
607
757
  return deepCloneFilter(this.fullContext);
608
758
  }
@@ -629,10 +779,11 @@ var GraphContext = class _GraphContext {
629
779
  return new _GraphContext(context);
630
780
  }
631
781
  /**
632
- * Combines with another for uniques (joins userData).
633
- * @param otherContext The other.
634
- * @returns New combined GraphContext.
635
- * @edge Appends other.userData to joinedContexts in userData.
782
+ * Combines the current GraphContext with another GraphContext, merging their user data
783
+ * and full context into a new GraphContext instance.
784
+ *
785
+ * @param {GraphContext} otherContext - The other GraphContext to combine with the current one.
786
+ * @return {GraphContext} A new GraphContext instance containing merged data from both contexts.
636
787
  */
637
788
  combine(otherContext) {
638
789
  const newUser = { ...this.userData };
@@ -750,7 +901,7 @@ var GraphNode = class _GraphNode extends SignalEmitter {
750
901
  this.destroyed = false;
751
902
  this.debug = false;
752
903
  this.verbose = false;
753
- this.id = (0, import_uuid3.v4)();
904
+ this.id = (0, import_uuid4.v4)();
754
905
  this.task = task;
755
906
  this.context = context;
756
907
  this.retryCount = task.retryCount;
@@ -760,6 +911,8 @@ var GraphNode = class _GraphNode extends SignalEmitter {
760
911
  this.splitGroupId = routineExecId;
761
912
  this.debug = debug;
762
913
  this.verbose = verbose;
914
+ const ctx = context.getMetadata();
915
+ this.executionTraceId = ctx.__executionTraceId ?? ctx.__metadata?.__executionTraceId;
763
916
  if (!this.task || !this.task.validateInput) {
764
917
  console.log("task not found", this.task, this.context);
765
918
  }
@@ -785,15 +938,40 @@ var GraphNode = class _GraphNode extends SignalEmitter {
785
938
  graphDone() {
786
939
  return this.graphComplete;
787
940
  }
941
+ /**
942
+ * Compares the current GraphNode instance with another GraphNode to determine if they are considered equal.
943
+ *
944
+ * @param {GraphNode} node - The GraphNode object to compare with the current instance.
945
+ * @return {boolean} Returns true if the nodes share the same task, context, and belong to the same graph; otherwise, false.
946
+ */
788
947
  isEqualTo(node) {
789
948
  return this.sharesTaskWith(node) && this.sharesContextWith(node) && this.isPartOfSameGraph(node);
790
949
  }
950
+ /**
951
+ * Determines if the given node is part of the same graph as the current node.
952
+ *
953
+ * @param {GraphNode} node - The node to compare with the current node.
954
+ * @return {boolean} Returns true if the provided node is part of the same graph
955
+ * (i.e., has the same routineExecId), otherwise false.
956
+ */
791
957
  isPartOfSameGraph(node) {
792
958
  return this.routineExecId === node.routineExecId;
793
959
  }
960
+ /**
961
+ * Determines whether the current instance shares a task with the provided node.
962
+ *
963
+ * @param {GraphNode} node - The graph node to compare with the current instance.
964
+ * @return {boolean} Returns true if the task names of both nodes match, otherwise false.
965
+ */
794
966
  sharesTaskWith(node) {
795
967
  return this.task.name === node.task.name;
796
968
  }
969
+ /**
970
+ * Determines whether the current node shares the same context as the specified node.
971
+ *
972
+ * @param {GraphNode} node - The graph node to compare with the current node's context.
973
+ * @return {boolean} True if both nodes share the same context; otherwise, false.
974
+ */
797
975
  sharesContextWith(node) {
798
976
  return this.context.id === node.context.id;
799
977
  }
@@ -803,9 +981,26 @@ var GraphNode = class _GraphNode extends SignalEmitter {
803
981
  getConcurrency() {
804
982
  return this.task.concurrency;
805
983
  }
984
+ /**
985
+ * Retrieves the tag associated with the current task and context.
986
+ *
987
+ * @return {string} The tag retrieved from the task within the given context.
988
+ */
806
989
  getTag() {
807
990
  return this.task.getTag(this.context);
808
991
  }
992
+ /**
993
+ * Schedules the current node/task on the specified graph layer if applicable.
994
+ *
995
+ * This method assesses whether the current node/task should be scheduled
996
+ * on the given graph layer. It ensures that tasks are only scheduled
997
+ * under certain conditions, such as checking if the task shares
998
+ * execution contexts or dependencies with other nodes, and handles
999
+ * various metadata emissions and context updates during the scheduling process.
1000
+ *
1001
+ * @param {GraphLayer} layer - The graph layer on which the current task should be scheduled.
1002
+ * @returns {void} Does not return a value.
1003
+ */
809
1004
  scheduleOn(layer) {
810
1005
  let shouldSchedule = true;
811
1006
  const nodes = layer.getNodesByRoutineExecId(this.routineExecId);
@@ -829,7 +1024,7 @@ var GraphNode = class _GraphNode extends SignalEmitter {
829
1024
  data: {
830
1025
  uuid: this.id,
831
1026
  routineExecutionId: this.routineExecId,
832
- executionTraceId: context.__executionTraceId ?? context.__metadata?.__executionTraceId,
1027
+ executionTraceId: this.executionTraceId,
833
1028
  context: this.previousNodes.length === 0 ? this.context.id : this.context.export(),
834
1029
  taskName: this.task.name,
835
1030
  taskVersion: this.task.version,
@@ -873,10 +1068,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
873
1068
  if (context.__signalEmission?.consumed === false && (!this.isMeta() || this.debug)) {
874
1069
  this.emitMetricsWithMetadata("meta.node.consumed_signal", {
875
1070
  data: {
1071
+ signalEmissionId: context.__signalEmission.uuid,
876
1072
  signalName: context.__signalEmission.signalName,
1073
+ signalTag: context.__signalEmission.signalTag,
877
1074
  taskName: this.task.name,
878
1075
  taskVersion: this.task.version,
879
1076
  taskExecutionId: this.id,
1077
+ routineExecutionId: this.routineExecId,
1078
+ executionTraceId: this.executionTraceId,
880
1079
  consumedAt: formatTimestamp(scheduledAt)
881
1080
  }
882
1081
  });
@@ -885,6 +1084,18 @@ var GraphNode = class _GraphNode extends SignalEmitter {
885
1084
  }
886
1085
  }
887
1086
  }
1087
+ /**
1088
+ * Starts the execution process by initializing the execution start timestamp,
1089
+ * emitting relevant metadata, and logging debug information if applicable.
1090
+ *
1091
+ * The method performs the following actions:
1092
+ * 1. Sets the execution start timestamp if it's not already initialized.
1093
+ * 2. Emits metrics with metadata about the routine execution starting, including additional data if there are no previous nodes.
1094
+ * 3. Optionally logs debug or verbose information based on the current settings.
1095
+ * 4. Emits additional metrics to indicate that the execution has started.
1096
+ *
1097
+ * @return {number} The timestamp indicating when the execution started.
1098
+ */
888
1099
  start() {
889
1100
  if (this.executionStart === 0) {
890
1101
  this.executionStart = Date.now();
@@ -910,6 +1121,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
910
1121
  });
911
1122
  return this.executionStart;
912
1123
  }
1124
+ /**
1125
+ * Marks the end of an execution process, performs necessary cleanup, emits
1126
+ * metrics with associated metadata, and signals the completion of execution.
1127
+ * Also handles specific cases when the graph completes.
1128
+ *
1129
+ * @return {number} The timestamp corresponding to the end of execution. If execution
1130
+ * was not started, it returns 0.
1131
+ */
913
1132
  end() {
914
1133
  if (this.executionStart === 0) {
915
1134
  return 0;
@@ -962,6 +1181,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
962
1181
  }
963
1182
  return end;
964
1183
  }
1184
+ /**
1185
+ * Executes the main logic of the task, including input validation, processing, and post-processing.
1186
+ * Handles both synchronous and asynchronous workflows.
1187
+ *
1188
+ * @return {Array|Promise|undefined} Returns the next nodes to process if available.
1189
+ * If asynchronous processing is required, it returns a Promise that resolves to the next nodes.
1190
+ * Returns undefined in case of an error during input validation or preconditions that prevent processing.
1191
+ */
965
1192
  execute() {
966
1193
  if (!this.divided && !this.processing) {
967
1194
  this.processing = true;
@@ -985,6 +1212,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
985
1212
  }
986
1213
  return this.nextNodes;
987
1214
  }
1215
+ /**
1216
+ * Executes an asynchronous workflow that processes a result and retries on errors.
1217
+ * The method handles different result states, checks for error properties, and invokes
1218
+ * error handling when necessary.
1219
+ *
1220
+ * @return {Promise<void>} A promise that resolves when the operation completes successfully,
1221
+ * or rejects if an unhandled error occurs.
1222
+ */
988
1223
  async workAsync() {
989
1224
  try {
990
1225
  this.result = await this.result;
@@ -1001,6 +1236,12 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1001
1236
  }
1002
1237
  }
1003
1238
  }
1239
+ /**
1240
+ * Executes an asynchronous operation, processes the result, and determines the next nodes to execute.
1241
+ * This method will manage asynchronous work, handle post-processing of results, and ensure proper handling of both synchronous and asynchronous next node configurations.
1242
+ *
1243
+ * @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.
1244
+ */
1004
1245
  async executeAsync() {
1005
1246
  await this.workAsync();
1006
1247
  const nextNodes = this.postProcess();
@@ -1010,6 +1251,16 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1010
1251
  this.nextNodes = nextNodes;
1011
1252
  return this.nextNodes;
1012
1253
  }
1254
+ /**
1255
+ * Executes the task associated with the current instance, using the given context,
1256
+ * progress callback, and metadata. If the task fails or an error occurs, it attempts
1257
+ * to retry the execution. If the retry is not successful, it propagates the error and
1258
+ * returns the result.
1259
+ *
1260
+ * @return {TaskResult | Promise<TaskResult>} The result of the task execution, or a
1261
+ * promise that resolves to the task result. This includes handling for retries on
1262
+ * failure and error propagation.
1263
+ */
1013
1264
  work() {
1014
1265
  try {
1015
1266
  const result = this.task.execute(
@@ -1033,39 +1284,67 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1033
1284
  });
1034
1285
  }
1035
1286
  }
1287
+ /**
1288
+ * Emits a signal along with its associated metadata. The metadata includes
1289
+ * task-specific information such as task name, version, execution ID, and
1290
+ * additional context metadata like routine execution ID and execution trace ID.
1291
+ * This method is designed to enrich emitted signals with relevant details
1292
+ * before broadcasting them.
1293
+ *
1294
+ * @param {string} signal - The name of the signal to be emitted.
1295
+ * @param {AnyObject} data - The data object to be sent along with the signal. Metadata
1296
+ * will be injected into this object before being emitted.
1297
+ * @return {void} No return value.
1298
+ */
1036
1299
  emitWithMetadata(signal, data) {
1037
1300
  if (!this.task?.isHidden) {
1038
1301
  data.__signalEmission = {
1039
1302
  taskName: this.task.name,
1040
1303
  taskVersion: this.task.version,
1041
- taskExecutionId: this.id
1304
+ taskExecutionId: this.id,
1305
+ routineExecutionId: this.routineExecId,
1306
+ executionTraceId: this.executionTraceId,
1307
+ isMetric: false
1042
1308
  };
1043
- const context = this.context.getMetadata();
1044
1309
  data.__metadata = {
1045
1310
  ...data.__metadata,
1046
1311
  __routineExecId: this.routineExecId,
1047
- __executionTraceId: context.__metadata?.__executionTraceId ?? context.__executionTraceId
1312
+ __executionTraceId: this.executionTraceId
1048
1313
  };
1049
1314
  }
1050
1315
  this.emit(signal, data);
1051
1316
  }
1317
+ /**
1318
+ * Emits metrics with additional metadata describing the task execution and context.
1319
+ *
1320
+ * @param {string} signal - The signal name being emitted.
1321
+ * @param {AnyObject} data - The data associated with the signal emission, enriched with metadata.
1322
+ * @return {void} Emits the signal with enriched data and does not return a value.
1323
+ */
1052
1324
  emitMetricsWithMetadata(signal, data) {
1053
1325
  if (!this.task?.isHidden) {
1054
1326
  data.__signalEmission = {
1055
1327
  taskName: this.task.name,
1056
1328
  taskVersion: this.task.version,
1057
1329
  taskExecutionId: this.id,
1330
+ routineExecutionId: this.routineExecId,
1331
+ executionTraceId: this.executionTraceId,
1058
1332
  isMetric: true
1059
1333
  };
1060
- const context = this.context.getMetadata();
1061
1334
  data.__metadata = {
1062
1335
  ...data.__metadata,
1063
1336
  __routineExecId: this.routineExecId,
1064
- __executionTraceId: context.__metadata?.__executionTraceId ?? context.__executionTraceId
1337
+ __executionTraceId: this.executionTraceId
1065
1338
  };
1066
1339
  }
1067
1340
  this.emitMetrics(signal, data);
1068
1341
  }
1342
+ /**
1343
+ * Updates the progress of a task and emits metrics with associated metadata.
1344
+ *
1345
+ * @param {number} progress - A number representing the progress value, which will be clamped between 0 and 1.
1346
+ * @return {void} This method does not return a value.
1347
+ */
1069
1348
  onProgress(progress) {
1070
1349
  progress = Math.min(Math.max(0, progress), 1);
1071
1350
  this.emitMetricsWithMetadata("meta.node.progress", {
@@ -1088,6 +1367,18 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1088
1367
  }
1089
1368
  );
1090
1369
  }
1370
+ /**
1371
+ * Processes the result of the current operation, validates it, and determines the next set of nodes.
1372
+ *
1373
+ * This method ensures that results of certain types such as strings or arrays
1374
+ * are flagged as errors. It divides the current context into subsequent nodes
1375
+ * for further processing. If the division returns a promise, it delegates the
1376
+ * processing to `postProcessAsync`. For synchronous division, it sets the
1377
+ * `nextNodes` and finalizes the operation.
1378
+ *
1379
+ * @return {(Array|undefined)} Returns an array of next nodes for further processing,
1380
+ * or undefined if no further processing is required.
1381
+ */
1091
1382
  postProcess() {
1092
1383
  if (typeof this.result === "string") {
1093
1384
  this.onError(
@@ -1105,11 +1396,23 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1105
1396
  this.finalize();
1106
1397
  return this.nextNodes;
1107
1398
  }
1399
+ /**
1400
+ * Asynchronously processes and finalizes the provided graph nodes.
1401
+ *
1402
+ * @param {Promise<GraphNode[]>} nextNodes A promise that resolves to an array of graph nodes to be processed.
1403
+ * @return {Promise<GraphNode[]>} A promise that resolves to the processed array of graph nodes.
1404
+ */
1108
1405
  async postProcessAsync(nextNodes) {
1109
1406
  this.nextNodes = await nextNodes;
1110
1407
  this.finalize();
1111
1408
  return this.nextNodes;
1112
1409
  }
1410
+ /**
1411
+ * Finalizes the current task execution by determining if the task is complete, handles any errors or failures,
1412
+ * emits relevant signals based on the task outcomes, and ensures proper end of the task lifecycle.
1413
+ *
1414
+ * @return {void} Does not return a value.
1415
+ */
1113
1416
  finalize() {
1114
1417
  if (this.nextNodes.length === 0) {
1115
1418
  this.completeSubgraph();
@@ -1125,6 +1428,13 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1125
1428
  }
1126
1429
  this.end();
1127
1430
  }
1431
+ /**
1432
+ * Handles an error event, processes the error, and updates the state accordingly.
1433
+ *
1434
+ * @param {unknown} error - The error object or message that occurred.
1435
+ * @param {AnyObject} [errorData={}] - Additional error data to include in the result.
1436
+ * @return {void} This method does not return any value.
1437
+ */
1128
1438
  onError(error, errorData = {}) {
1129
1439
  this.result = {
1130
1440
  ...this.context.getFullContext(),
@@ -1138,6 +1448,12 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1138
1448
  this.migrate(this.result);
1139
1449
  this.errored = true;
1140
1450
  }
1451
+ /**
1452
+ * 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.
1453
+ *
1454
+ * @param {any} [prevResult] - The result from a previous attempt, if any, to return when no retries are performed.
1455
+ * @return {Promise<TaskResult>} - A promise that resolves with the result of the retried task or the previous result if no retries occur.
1456
+ */
1141
1457
  async retry(prevResult) {
1142
1458
  if (this.retryCount === 0) {
1143
1459
  return prevResult;
@@ -1145,6 +1461,13 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1145
1461
  await this.delayRetry();
1146
1462
  return this.work();
1147
1463
  }
1464
+ /**
1465
+ * Retries an asynchronous operation and returns its result.
1466
+ * If the retry count is zero, the method immediately returns the provided previous result.
1467
+ *
1468
+ * @param {any} [prevResult] - The optional result from a previous operation attempt, if applicable.
1469
+ * @return {Promise<TaskResult>} A promise that resolves to the result of the retried operation.
1470
+ */
1148
1471
  async retryAsync(prevResult) {
1149
1472
  if (this.retryCount === 0) {
1150
1473
  return prevResult;
@@ -1162,6 +1485,15 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1162
1485
  this.retryDelay = this.task.retryDelayMax;
1163
1486
  }
1164
1487
  }
1488
+ /**
1489
+ * Processes the result of a task by generating new nodes based on the task output.
1490
+ * The method handles synchronous and asynchronous generators, validates task output,
1491
+ * and creates new nodes accordingly. If errors occur, the method attempts to handle them
1492
+ * by generating alternative task nodes.
1493
+ *
1494
+ * @return {GraphNode[] | Promise<GraphNode[]>} Returns an array of generated GraphNode objects
1495
+ * (synchronously or wrapped in a Promise) based on the task result, or propagates errors if validation fails.
1496
+ */
1165
1497
  divide() {
1166
1498
  const newNodes = [];
1167
1499
  if (this.result?.next && typeof this.result.next === "function") {
@@ -1200,7 +1532,7 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1200
1532
  if (this.errored) {
1201
1533
  newNodes.push(
1202
1534
  ...this.task.mapNext(
1203
- (t) => this.clone().split((0, import_uuid3.v4)()).differentiate(t).migrate({ ...this.result }),
1535
+ (t) => this.clone().split((0, import_uuid4.v4)()).differentiate(t).migrate({ ...this.result }),
1204
1536
  true
1205
1537
  )
1206
1538
  );
@@ -1213,6 +1545,13 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1213
1545
  });
1214
1546
  return newNodes;
1215
1547
  }
1548
+ /**
1549
+ * Processes an asynchronous iterator result, validates its output, and generates new graph nodes accordingly.
1550
+ * Additionally, continues to process and validate results from an asynchronous generator.
1551
+ *
1552
+ * @param {Promise<IteratorResult<any>>} current - A promise resolving to the current step result from an asynchronous iterator.
1553
+ * @return {Promise<GraphNode[]>} A promise resolving to an array of generated GraphNode objects based on validated outputs.
1554
+ */
1216
1555
  async divideAsync(current) {
1217
1556
  const nextNodes = [];
1218
1557
  const _current = await current;
@@ -1235,8 +1574,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1235
1574
  this.divided = true;
1236
1575
  return nextNodes;
1237
1576
  }
1577
+ /**
1578
+ * Generates new nodes based on the provided result and task configuration.
1579
+ *
1580
+ * @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.
1581
+ * @return {GraphNode[]} An array of newly generated graph nodes configured based on the task and context.
1582
+ */
1238
1583
  generateNewNodes(result) {
1239
- const groupId = (0, import_uuid3.v4)();
1584
+ const groupId = (0, import_uuid4.v4)();
1240
1585
  const newNodes = [];
1241
1586
  if (typeof result !== "boolean") {
1242
1587
  const failed = result.failed !== void 0 && result.failed || result.error !== void 0;
@@ -1277,6 +1622,12 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1277
1622
  }
1278
1623
  return newNodes;
1279
1624
  }
1625
+ /**
1626
+ * Executes the differentiation process based on a given task and updates the instance properties accordingly.
1627
+ *
1628
+ * @param {Task} task - The task object containing information such as retry count, retry delay, and metadata status.
1629
+ * @return {GraphNode} The updated instance after processing the task.
1630
+ */
1280
1631
  differentiate(task) {
1281
1632
  this.task = task;
1282
1633
  this.retryCount = task.retryCount;
@@ -1284,14 +1635,32 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1284
1635
  this.silent = task.isMeta && !this.debug || task.isSubMeta || this.context?.getMetadata()?.__isSubMeta;
1285
1636
  return this;
1286
1637
  }
1638
+ /**
1639
+ * Migrates the current instance to a new context and returns the updated instance.
1640
+ *
1641
+ * @param {any} ctx - The context data to be used for migration.
1642
+ * @return {GraphNode} The updated instance after migration.
1643
+ */
1287
1644
  migrate(ctx) {
1288
1645
  this.context = new GraphContext(ctx);
1289
1646
  return this;
1290
1647
  }
1648
+ /**
1649
+ * Splits the current node into a new group identified by the provided ID.
1650
+ *
1651
+ * @param {string} id - The unique identifier for the new split group.
1652
+ * @return {GraphNode} The current instance of the GraphNode with the updated split group ID.
1653
+ */
1291
1654
  split(id) {
1292
1655
  this.splitGroupId = id;
1293
1656
  return this;
1294
1657
  }
1658
+ /**
1659
+ * Creates a new instance of the GraphNode with the current node's properties.
1660
+ * This method allows for duplicating the existing graph node.
1661
+ *
1662
+ * @return {GraphNode} A new instance of GraphNode that is a copy of the current node.
1663
+ */
1295
1664
  clone() {
1296
1665
  return new _GraphNode(
1297
1666
  this.task,
@@ -1302,6 +1671,13 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1302
1671
  this.verbose
1303
1672
  );
1304
1673
  }
1674
+ /**
1675
+ * Consumes the given graph node by combining contexts, merging previous nodes,
1676
+ * and performing associated operations on the provided node.
1677
+ *
1678
+ * @param {GraphNode} node - The graph node to be consumed.
1679
+ * @return {void} This method does not return a value.
1680
+ */
1305
1681
  consume(node) {
1306
1682
  this.context = this.context.combine(node.context);
1307
1683
  this.previousNodes = this.previousNodes.concat(node.previousNodes);
@@ -1309,9 +1685,22 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1309
1685
  node.changeIdentity(this.id);
1310
1686
  node.destroy();
1311
1687
  }
1688
+ /**
1689
+ * Changes the identity of the current instance by updating the `id` property.
1690
+ *
1691
+ * @param {string} id - The new identity value to be assigned.
1692
+ * @return {void} Does not return a value.
1693
+ */
1312
1694
  changeIdentity(id) {
1313
1695
  this.id = id;
1314
1696
  }
1697
+ /**
1698
+ * Completes the subgraph for the current node and recursively for its previous nodes
1699
+ * once all next nodes have their subgraphs marked as done. If there are no previous nodes,
1700
+ * it completes the entire graph.
1701
+ *
1702
+ * @return {void} Does not return a value.
1703
+ */
1315
1704
  completeSubgraph() {
1316
1705
  for (const node of this.nextNodes) {
1317
1706
  if (!node.subgraphDone()) {
@@ -1325,10 +1714,22 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1325
1714
  }
1326
1715
  this.previousNodes.forEach((n) => n.completeSubgraph());
1327
1716
  }
1717
+ /**
1718
+ * Completes the current graph by setting a flag indicating the graph has been completed
1719
+ * and recursively completes all subsequent nodes in the graph.
1720
+ *
1721
+ * @return {void} Does not return a value.
1722
+ */
1328
1723
  completeGraph() {
1329
1724
  this.graphComplete = true;
1330
1725
  this.nextNodes.forEach((n) => n.completeGraph());
1331
1726
  }
1727
+ /**
1728
+ * Destroys the current instance by releasing resources, breaking references,
1729
+ * and resetting properties to ensure proper cleanup.
1730
+ *
1731
+ * @return {void} No return value.
1732
+ */
1332
1733
  destroy() {
1333
1734
  this.context = null;
1334
1735
  this.task = null;
@@ -1341,15 +1742,40 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1341
1742
  this.layer = void 0;
1342
1743
  this.destroyed = true;
1343
1744
  }
1745
+ /**
1746
+ * Retrieves an iterator for traversing through the graph nodes.
1747
+ *
1748
+ * @return {GraphNodeIterator} An iterator instance specific to this graph node.
1749
+ */
1344
1750
  getIterator() {
1345
1751
  return new GraphNodeIterator(this);
1346
1752
  }
1753
+ /**
1754
+ * Applies a callback function to each node in the `nextNodes` array and returns
1755
+ * the resulting array from the map operation.
1756
+ *
1757
+ * @param {function} callback - A function to execute on each `GraphNode` in the `nextNodes` array.
1758
+ * The function receives a `GraphNode` as its argument.
1759
+ * @return {Array} The resulting array after applying the callback function to each node in `nextNodes`.
1760
+ */
1347
1761
  mapNext(callback) {
1348
1762
  return this.nextNodes.map(callback);
1349
1763
  }
1764
+ /**
1765
+ * Accepts a visitor object and calls its visitNode method with the current instance.
1766
+ *
1767
+ * @param {GraphVisitor} visitor - The visitor instance implementing the GraphVisitor interface.
1768
+ * @return {void} This method does not return a value.
1769
+ */
1350
1770
  accept(visitor) {
1351
1771
  visitor.visitNode(this);
1352
1772
  }
1773
+ /**
1774
+ * Exports the current object's state and returns it in a serialized format.
1775
+ * The exported object contains metadata, task details, context information, execution times, node relationships, routine execution status, and other state information.
1776
+ *
1777
+ * @return {Object} An object representing the current state.
1778
+ */
1353
1779
  export() {
1354
1780
  return {
1355
1781
  __id: this.id,
@@ -1447,9 +1873,12 @@ var GraphRoutine = class extends SignalEmitter {
1447
1873
  });
1448
1874
  }
1449
1875
  /**
1450
- * Applies callback to starting tasks.
1451
- * @param callBack The callback.
1452
- * @returns Promise if async.
1876
+ * Iterates over each task in the `tasks` collection and applies the provided callback function.
1877
+ * If the callback returns a Promise, resolves all Promises concurrently.
1878
+ *
1879
+ * @param {function} callBack - A function to be executed on each task from the `tasks` collection.
1880
+ * The callback receives the current task as its argument.
1881
+ * @return {Promise<void>} A Promise that resolves once all callback executions, including asynchronous ones, are complete.
1453
1882
  */
1454
1883
  async forEachTask(callBack) {
1455
1884
  const promises = [];
@@ -1468,10 +1897,10 @@ var GraphRoutine = class extends SignalEmitter {
1468
1897
  this.emit("meta.routine.global_version_set", { version: this.version });
1469
1898
  }
1470
1899
  /**
1471
- * Subscribes to signals (chainable).
1472
- * @param signals The signal names.
1473
- * @returns This for chaining.
1474
- * @edge Duplicates ignored; assumes broker.observe binds this as handler.
1900
+ * Subscribes the current instance to the specified signals, enabling it to observe them.
1901
+ *
1902
+ * @param {...string} signals - The names of the signals to observe.
1903
+ * @return {this} Returns the instance to allow for method chaining.
1475
1904
  */
1476
1905
  doOn(...signals) {
1477
1906
  signals.forEach((signal) => {
@@ -1482,8 +1911,11 @@ var GraphRoutine = class extends SignalEmitter {
1482
1911
  return this;
1483
1912
  }
1484
1913
  /**
1485
- * Unsubscribes from all observed signals.
1486
- * @returns This for chaining.
1914
+ * Unsubscribes from all observed signals and clears the internal collection
1915
+ * of observed signals. This ensures that the instance is no longer listening
1916
+ * or reacting to any previously subscribed signals.
1917
+ *
1918
+ * @return {this} Returns the current instance for chaining purposes.
1487
1919
  */
1488
1920
  unsubscribeAll() {
1489
1921
  this.observedSignals.forEach(
@@ -1493,10 +1925,10 @@ var GraphRoutine = class extends SignalEmitter {
1493
1925
  return this;
1494
1926
  }
1495
1927
  /**
1496
- * Unsubscribes from specific signals.
1497
- * @param signals The signals.
1498
- * @returns This for chaining.
1499
- * @edge No-op if not subscribed.
1928
+ * Unsubscribes the current instance from the specified signals.
1929
+ *
1930
+ * @param {...string} signals - The signals to unsubscribe from.
1931
+ * @return {this} The current instance for method chaining.
1500
1932
  */
1501
1933
  unsubscribe(...signals) {
1502
1934
  signals.forEach((signal) => {
@@ -1508,7 +1940,12 @@ var GraphRoutine = class extends SignalEmitter {
1508
1940
  return this;
1509
1941
  }
1510
1942
  /**
1511
- * Destroys the routine.
1943
+ * Cleans up resources and emits an event indicating the destruction of the routine.
1944
+ *
1945
+ * This method unsubscribes from all events, clears the tasks list,
1946
+ * and emits a "meta.routine.destroyed" event with details of the destruction.
1947
+ *
1948
+ * @return {void}
1512
1949
  */
1513
1950
  destroy() {
1514
1951
  this.unsubscribeAll();
@@ -1554,27 +1991,27 @@ var TaskIterator = class {
1554
1991
  // src/graph/definition/Task.ts
1555
1992
  var Task = class extends SignalEmitter {
1556
1993
  /**
1557
- * Constructs a Task (static definition).
1558
- * @param name Name.
1559
- * @param task Function.
1560
- * @param description Description.
1561
- * @param concurrency Limit.
1562
- * @param timeout ms.
1563
- * @param register Register via signal (default true).
1564
- * @param isUnique
1565
- * @param isMeta
1566
- * @param isSubMeta
1567
- * @param isHidden
1568
- * @param getTagCallback
1569
- * @param inputSchema
1570
- * @param validateInputContext
1571
- * @param outputSchema
1572
- * @param validateOutputContext
1573
- * @param retryCount
1574
- * @param retryDelay
1575
- * @param retryDelayMax
1576
- * @param retryDelayFactor
1577
- * @edge Emits 'meta.task.created' with { __task: this } for seed.
1994
+ * Constructs an instance of the task with the specified properties and configuration options.
1995
+ *
1996
+ * @param {string} name - The name of the task.
1997
+ * @param {TaskFunction} task - The function that represents the task logic.
1998
+ * @param {string} [description=""] - A description of the task.
1999
+ * @param {number} [concurrency=0] - The number of concurrent executions allowed for the task.
2000
+ * @param {number} [timeout=0] - The maximum execution time for the task in milliseconds.
2001
+ * @param {boolean} [register=true] - Indicates if the task should be registered or not.
2002
+ * @param {boolean} [isUnique=false] - Specifies if the task should only allow one instance to exist at any time.
2003
+ * @param {boolean} [isMeta=false] - Indicates if the task is a meta-task.
2004
+ * @param {boolean} [isSubMeta=false] - Indicates if the task is a sub-meta-task.
2005
+ * @param {boolean} [isHidden=false] - Determines if the task is hidden and not exposed publicly.
2006
+ * @param {ThrottleTagGetter} [getTagCallback=undefined] - A callback to generate a throttle tag for the task.
2007
+ * @param {SchemaDefinition} [inputSchema=undefined] - The input schema for validating the task's input context.
2008
+ * @param {boolean} [validateInputContext=false] - Specifies if the input context should be validated against the input schema.
2009
+ * @param {SchemaDefinition} [outputSchema=undefined] - The output schema for validating the task's output context.
2010
+ * @param {boolean} [validateOutputContext=false] - Specifies if the output context should be validated against the output schema.
2011
+ * @param {number} [retryCount=0] - The number of retry attempts allowed for the task in case of failure.
2012
+ * @param {number} [retryDelay=0] - The initial delay (in milliseconds) between retry attempts.
2013
+ * @param {number} [retryDelayMax=0] - The maximum delay (in milliseconds) allowed between retries.
2014
+ * @param {number} [retryDelayFactor=1] - The factor by which the retry delay increases after each attempt.
1578
2015
  */
1579
2016
  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) {
1580
2017
  super(isSubMeta || isHidden);
@@ -1663,6 +2100,13 @@ var Task = class extends SignalEmitter {
1663
2100
  });
1664
2101
  }
1665
2102
  }
2103
+ /**
2104
+ * Retrieves the tag associated with the instance.
2105
+ * Can be overridden by subclasses.
2106
+ *
2107
+ * @param {AnyObject} [context] - Optional context parameter that can be provided.
2108
+ * @return {string} The tag value of the instance.
2109
+ */
1666
2110
  getTag(context) {
1667
2111
  return this.name;
1668
2112
  }
@@ -1693,16 +2137,35 @@ var Task = class extends SignalEmitter {
1693
2137
  setValidateOutputContext(value) {
1694
2138
  this.validateOutputContext = value;
1695
2139
  }
2140
+ /**
2141
+ * Emits a signal along with metadata if certain conditions are met.
2142
+ *
2143
+ * This method sends a signal with optional context data and adds metadata
2144
+ * to the emitted data if the instance is not hidden and not a subordinate metadata object.
2145
+ *
2146
+ * @param {string} signal - The name of the signal to emit.
2147
+ * @param {AnyObject} [ctx={}] - Additional context data to include with the emitted signal.
2148
+ * @return {void} Does not return a value.
2149
+ */
1696
2150
  emitWithMetadata(signal, ctx = {}) {
1697
2151
  const data = { ...ctx };
1698
2152
  if (!this.isHidden && !this.isSubMeta) {
1699
2153
  data.__signalEmission = {
1700
2154
  taskName: this.name,
1701
- taskVersion: this.version
2155
+ taskVersion: this.version,
2156
+ isMetric: false
1702
2157
  };
1703
2158
  }
1704
2159
  this.emit(signal, data);
1705
2160
  }
2161
+ /**
2162
+ * Emits metrics with additional metadata enhancement based on the context and the state of the instance.
2163
+ * This is used to prevent loops on the meta layer in debug mode.
2164
+ *
2165
+ * @param {string} signal - The signal identifier for the metric being emitted.
2166
+ * @param {AnyObject} [ctx={}] - Optional context object to provide additional information with the metric.
2167
+ * @return {void} This method does not return any value.
2168
+ */
1706
2169
  emitMetricsWithMetadata(signal, ctx = {}) {
1707
2170
  const data = { ...ctx };
1708
2171
  if (!this.isHidden && !this.isSubMeta) {
@@ -1715,12 +2178,13 @@ var Task = class extends SignalEmitter {
1715
2178
  this.emitMetrics(signal, data);
1716
2179
  }
1717
2180
  /**
1718
- * Validates a context deeply against a schema.
1719
- * @param data - The data to validate (input context or output result).
1720
- * @param schema - The schema definition.
1721
- * @param path - The current path for error reporting (default: 'root').
1722
- * @returns { { valid: boolean, errors: Record<string, string> } } - Validation result with detailed errors if invalid.
1723
- * @description Recursively checks types, required fields, and constraints; allows extra properties not in schema.
2181
+ * Validates a data object against a specified schema definition and returns validation results.
2182
+ *
2183
+ * @param {any} data - The target object to validate against the schema.
2184
+ * @param {SchemaDefinition | undefined} schema - The schema definition describing the expected structure and constraints of the data.
2185
+ * @param {string} [path="context"] - The base path or context for traversing the data, used in generating error messages.
2186
+ * @return {{ valid: boolean, errors: Record<string, string> }} - An object containing a validity flag (`valid`)
2187
+ * and a map (`errors`) of validation error messages keyed by property paths.
1724
2188
  */
1725
2189
  validateSchema(data, schema, path = "context") {
1726
2190
  const errors = {};
@@ -1823,6 +2287,12 @@ var Task = class extends SignalEmitter {
1823
2287
  }
1824
2288
  return { valid: true, errors: {} };
1825
2289
  }
2290
+ /**
2291
+ * Validates the input context against the predefined schema and emits metadata if validation fails.
2292
+ *
2293
+ * @param {AnyObject} context - The input context to validate.
2294
+ * @return {true | AnyObject} - Returns `true` if validation succeeds, otherwise returns an error object containing details of the validation failure.
2295
+ */
1826
2296
  validateInput(context) {
1827
2297
  if (this.validateInputContext) {
1828
2298
  const validationResult = this.validateSchema(
@@ -1845,6 +2315,13 @@ var Task = class extends SignalEmitter {
1845
2315
  }
1846
2316
  return true;
1847
2317
  }
2318
+ /**
2319
+ * Validates the output context using the provided schema and emits metadata if validation fails.
2320
+ *
2321
+ * @param {AnyObject} context - The output context to validate.
2322
+ * @return {true | AnyObject} Returns `true` if the output context is valid; otherwise, returns an object
2323
+ * containing error information when validation fails.
2324
+ */
1848
2325
  validateOutput(context) {
1849
2326
  if (this.validateOutputContext) {
1850
2327
  const validationResult = this.validateSchema(
@@ -1868,14 +2345,13 @@ var Task = class extends SignalEmitter {
1868
2345
  return true;
1869
2346
  }
1870
2347
  /**
1871
- * Executes the task function after optional input validation.
1872
- * @param context - The GraphContext to validate and execute.
1873
- * @param emit
1874
- * @param progressCallback - Callback for progress updates.
1875
- * @param nodeData
1876
- * @returns TaskResult from the taskFunction or error object on validation failure.
1877
- * @edge If validateInputContext is true, validates context; on failure, emits 'meta.task.validationFailed' with detailed errors.
1878
- * @edge If validateOutputContext is true, validates output; on failure, emits 'meta.task.outputValidationFailed' with detailed errors.
2348
+ * Executes a task within a given context, optionally emitting signals and reporting progress.
2349
+ *
2350
+ * @param {GraphContext} context The execution context which provides data and functions necessary for the task.
2351
+ * @param {function(string, AnyObject): void} emit A function to emit signals and communicate intermediate results or states.
2352
+ * @param {function(number): void} progressCallback A callback function used to report task progress as a percentage (0 to 100).
2353
+ * @param {{ nodeId: string; routineExecId: string }} nodeData An object containing identifiers related to the node and execution routine.
2354
+ * @return {TaskResult} The result of the executed task.
1879
2355
  */
1880
2356
  execute(context, emit, progressCallback, nodeData) {
1881
2357
  return this.taskFunction(
@@ -1884,6 +2360,15 @@ var Task = class extends SignalEmitter {
1884
2360
  progressCallback
1885
2361
  );
1886
2362
  }
2363
+ /**
2364
+ * Adds tasks as predecessors to the current task and establishes dependencies between them.
2365
+ * Ensures that adding predecessors does not create cyclic dependencies.
2366
+ * Updates task relationships, progress weights, and emits relevant metrics after operations.
2367
+ *
2368
+ * @param {Task[]} tasks - An array of tasks to be added as predecessors to the current task.
2369
+ * @return {this} The current task instance for method chaining.
2370
+ * @throws {Error} Throws an error if adding a predecessor creates a cycle in the task structure.
2371
+ */
1887
2372
  doAfter(...tasks) {
1888
2373
  for (const pred of tasks) {
1889
2374
  if (this.predecessorTasks.has(pred)) continue;
@@ -1906,6 +2391,14 @@ var Task = class extends SignalEmitter {
1906
2391
  this.updateProgressWeights();
1907
2392
  return this;
1908
2393
  }
2394
+ /**
2395
+ * Adds a sequence of tasks as successors to the current task, ensuring no cyclic dependencies are introduced.
2396
+ * Metrics are emitted when a relationship is successfully added.
2397
+ *
2398
+ * @param {...Task} tasks - The tasks to be added as successors to the current task.
2399
+ * @return {this} Returns the current task instance for method chaining.
2400
+ * @throws {Error} Throws an error if adding a task causes a cyclic dependency.
2401
+ */
1909
2402
  then(...tasks) {
1910
2403
  for (const next of tasks) {
1911
2404
  if (this.nextTasks.has(next)) continue;
@@ -1928,6 +2421,12 @@ var Task = class extends SignalEmitter {
1928
2421
  this.updateProgressWeights();
1929
2422
  return this;
1930
2423
  }
2424
+ /**
2425
+ * Decouples the current task from the provided task by removing mutual references.
2426
+ *
2427
+ * @param {Task} task - The task to decouple from the current task.
2428
+ * @return {void} This method does not return a value.
2429
+ */
1931
2430
  decouple(task) {
1932
2431
  if (task.nextTasks.has(this)) {
1933
2432
  task.nextTasks.delete(this);
@@ -1939,6 +2438,14 @@ var Task = class extends SignalEmitter {
1939
2438
  }
1940
2439
  this.updateLayerFromPredecessors();
1941
2440
  }
2441
+ /**
2442
+ * Updates the progress weights for tasks within each layer of the subgraph.
2443
+ * The progress weight for each task is calculated based on the inverse proportion
2444
+ * of the number of layers and the number of tasks in each layer. This ensures an
2445
+ * even distribution of progress weight across the tasks in the layers.
2446
+ *
2447
+ * @return {void} Does not return a value.
2448
+ */
1942
2449
  updateProgressWeights() {
1943
2450
  const layers = this.getSubgraphLayers();
1944
2451
  const numLayers = layers.size;
@@ -1952,6 +2459,12 @@ var Task = class extends SignalEmitter {
1952
2459
  );
1953
2460
  });
1954
2461
  }
2462
+ /**
2463
+ * Retrieves a mapping of layer indices to sets of tasks within each layer of a subgraph.
2464
+ * This method traverses the task dependencies and organizes tasks by their respective layer indices.
2465
+ *
2466
+ * @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.
2467
+ */
1955
2468
  getSubgraphLayers() {
1956
2469
  const layers = /* @__PURE__ */ new Map();
1957
2470
  const queue = [this];
@@ -1966,6 +2479,13 @@ var Task = class extends SignalEmitter {
1966
2479
  }
1967
2480
  return layers;
1968
2481
  }
2482
+ /**
2483
+ * Updates the `layerIndex` of the current task based on the maximum layer index of its predecessors
2484
+ * and propagates the update recursively to all subsequent tasks. If the `layerIndex` changes,
2485
+ * emits a metric event with metadata about the change.
2486
+ *
2487
+ * @return {void} This method does not return a value.
2488
+ */
1969
2489
  updateLayerFromPredecessors() {
1970
2490
  const prevLayerIndex = this.layerIndex;
1971
2491
  let maxPred = 0;
@@ -1988,6 +2508,12 @@ var Task = class extends SignalEmitter {
1988
2508
  next.nextTasks.forEach((n) => queue.push(n));
1989
2509
  }
1990
2510
  }
2511
+ /**
2512
+ * Determines whether there is a cycle in the tasks graph.
2513
+ * This method performs a depth-first search (DFS) to detect cycles.
2514
+ *
2515
+ * @return {boolean} - Returns true if a cycle is found in the graph, otherwise false.
2516
+ */
1991
2517
  hasCycle() {
1992
2518
  const visited = /* @__PURE__ */ new Set();
1993
2519
  const recStack = /* @__PURE__ */ new Set();
@@ -2004,18 +2530,33 @@ var Task = class extends SignalEmitter {
2004
2530
  };
2005
2531
  return dfs(this);
2006
2532
  }
2533
+ /**
2534
+ * Maps over the next set of tasks or failed tasks if specified, applying the provided callback function.
2535
+ *
2536
+ * @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.
2537
+ * @param {boolean} [failed=false] A boolean that determines whether to map over the failed tasks (true) or the next tasks (false).
2538
+ * @return {any[]} An array of transformed tasks resulting from applying the callback function.
2539
+ */
2007
2540
  mapNext(callback, failed = false) {
2008
2541
  const tasks = failed ? Array.from(this.onFailTasks) : Array.from(this.nextTasks);
2009
2542
  return tasks.map(callback);
2010
2543
  }
2544
+ /**
2545
+ * Maps through each task in the set of predecessor tasks and applies the provided callback function.
2546
+ *
2547
+ * @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.
2548
+ * @return {any[]} An array containing the results of applying the callback function to each predecessor task.
2549
+ */
2011
2550
  mapPrevious(callback) {
2012
2551
  return Array.from(this.predecessorTasks).map(callback);
2013
2552
  }
2014
2553
  /**
2015
- * Subscribes to signals (chainable).
2016
- * @param signals The signal names.
2017
- * @returns This for chaining.
2018
- * @edge Duplicates ignored; assumes broker.observe binds this as handler.
2554
+ * Adds the specified signals to the current instance, making it observe them.
2555
+ * If the instance is already observing a signal, it will be skipped.
2556
+ * The method also emits metadata information if the `register` property is set.
2557
+ *
2558
+ * @param {...string[]} signals - The array of signal names to observe.
2559
+ * @return {this} The current instance after adding the specified signals.
2019
2560
  */
2020
2561
  doOn(...signals) {
2021
2562
  signals.forEach((signal) => {
@@ -2035,9 +2576,10 @@ var Task = class extends SignalEmitter {
2035
2576
  return this;
2036
2577
  }
2037
2578
  /**
2038
- * Sets signals to emit post-execution (chainable).
2039
- * @param signals The signal names.
2040
- * @returns This for chaining.
2579
+ * Registers the specified signals to be emitted after the Task executes successfully and attaches them for further processing.
2580
+ *
2581
+ * @param {...string} signals - The list of signals to be registered for emission.
2582
+ * @return {this} The current instance for method chaining.
2041
2583
  */
2042
2584
  emits(...signals) {
2043
2585
  signals.forEach((signal) => {
@@ -2046,6 +2588,13 @@ var Task = class extends SignalEmitter {
2046
2588
  });
2047
2589
  return this;
2048
2590
  }
2591
+ /**
2592
+ * Configures the instance to emit specified signals when the task execution fails.
2593
+ * A failure is defined as anything that does not return a successful result.
2594
+ *
2595
+ * @param {...string} signals - The names of the signals to emit upon failure.
2596
+ * @return {this} Returns the current instance for chaining.
2597
+ */
2049
2598
  emitsOnFail(...signals) {
2050
2599
  signals.forEach((signal) => {
2051
2600
  this.signalsToEmitOnFail.add(signal);
@@ -2053,6 +2602,13 @@ var Task = class extends SignalEmitter {
2053
2602
  });
2054
2603
  return this;
2055
2604
  }
2605
+ /**
2606
+ * Attaches a signal to the current context and emits metadata if the register flag is set.
2607
+ *
2608
+ * @param {string} signal - The name of the signal to attach.
2609
+ * @param {boolean} [isOnFail=false] - Indicates if the signal should be marked as "on fail".
2610
+ * @return {void} This method does not return a value.
2611
+ */
2056
2612
  attachSignal(signal, isOnFail = false) {
2057
2613
  this.emitsSignals.add(signal);
2058
2614
  if (this.register) {
@@ -2067,10 +2623,12 @@ var Task = class extends SignalEmitter {
2067
2623
  }
2068
2624
  }
2069
2625
  /**
2070
- * Unsubscribes from specific signals.
2071
- * @param signals The signals.
2072
- * @returns This for chaining.
2073
- * @edge No-op if not subscribed.
2626
+ * Unsubscribes the current instance from the specified signals.
2627
+ * This method removes the signals from the observedSignals set, unsubscribes
2628
+ * from the underlying broker, and emits metadata for the unsubscription if applicable.
2629
+ *
2630
+ * @param {string[]} signals - The list of signal names to unsubscribe from.
2631
+ * @return {this} Returns the current instance for method chaining.
2074
2632
  */
2075
2633
  unsubscribe(...signals) {
2076
2634
  signals.forEach((signal) => {
@@ -2092,8 +2650,9 @@ var Task = class extends SignalEmitter {
2092
2650
  return this;
2093
2651
  }
2094
2652
  /**
2095
- * Unsubscribes from all observed signals.
2096
- * @returns This for chaining.
2653
+ * Unsubscribes from all currently observed signals and clears the list of observed signals.
2654
+ *
2655
+ * @return {this} The instance of the class to allow method chaining.
2097
2656
  */
2098
2657
  unsubscribeAll() {
2099
2658
  this.unsubscribe(...this.observedSignals);
@@ -2101,9 +2660,10 @@ var Task = class extends SignalEmitter {
2101
2660
  return this;
2102
2661
  }
2103
2662
  /**
2104
- * Detaches specific emitted signals.
2105
- * @param signals The signals.
2106
- * @returns This for chaining.
2663
+ * Detaches the specified signals from being emitted after execution and optionally emits metadata for each detached signal.
2664
+ *
2665
+ * @param {...string} signals - The list of signal names to be detached. Signals can be in the format "namespace:signalName".
2666
+ * @return {this} Returns the current instance of the object for method chaining.
2107
2667
  */
2108
2668
  detachSignals(...signals) {
2109
2669
  signals.forEach((signal) => {
@@ -2122,27 +2682,50 @@ var Task = class extends SignalEmitter {
2122
2682
  return this;
2123
2683
  }
2124
2684
  /**
2125
- * Detaches all emitted signals.
2126
- * @returns This for chaining.
2685
+ * Detaches all signals associated with the object by invoking the `detachSignals` method
2686
+ * and clearing the `signalsToEmitAfter` collection.
2687
+ *
2688
+ * @return {this} Returns the current instance to allow method chaining.
2127
2689
  */
2128
2690
  detachAllSignals() {
2129
2691
  this.detachSignals(...this.signalsToEmitAfter);
2130
2692
  this.signalsToEmitAfter.clear();
2131
2693
  return this;
2132
2694
  }
2695
+ /**
2696
+ * Maps over the signals in the `signalsToEmitAfter` set and applies a callback function to each signal.
2697
+ *
2698
+ * @param {function(string): void} callback - A function that is called with each signal
2699
+ * in the `signalsToEmitAfter` set, providing the signal as an argument.
2700
+ * @return {Array<any>} An array containing the results of applying the callback
2701
+ * function to each signal.
2702
+ */
2133
2703
  mapSignals(callback) {
2134
2704
  return Array.from(this.signalsToEmitAfter).map(callback);
2135
2705
  }
2706
+ /**
2707
+ * Maps over the signals in `signalsToEmitOnFail` and applies the provided callback to each signal.
2708
+ *
2709
+ * @param {function(string): void} callback - A function that receives each signal as a string and performs an operation or transformation on it.
2710
+ * @return {Array} The array resulting from applying the callback to each signal in `signalsToEmitOnFail`.
2711
+ */
2136
2712
  mapOnFailSignals(callback) {
2137
2713
  return Array.from(this.signalsToEmitOnFail).map(callback);
2138
2714
  }
2715
+ /**
2716
+ * Maps over the observed signals with the provided callback function.
2717
+ *
2718
+ * @param {function(string): void} callback - A function to execute on each signal in the observed signals array.
2719
+ * @return {Array} A new array containing the results of calling the callback function on each observed signal.
2720
+ */
2139
2721
  mapObservedSignals(callback) {
2140
2722
  return Array.from(this.observedSignals).map(callback);
2141
2723
  }
2142
2724
  /**
2143
- * Emits attached signals.
2144
- * @param context The context for emission.
2145
- * @edge If isMeta (from Task), suppresses further "meta.*" to prevent loops.
2725
+ * Emits a collection of signals stored in the `signalsToEmitAfter` array.
2726
+ *
2727
+ * @param {GraphContext} context - The context object containing data or state to be passed to the emitted signals.
2728
+ * @return {void} This method does not return a value.
2146
2729
  */
2147
2730
  emitSignals(context) {
2148
2731
  this.signalsToEmitAfter.forEach((signal) => {
@@ -2150,15 +2733,29 @@ var Task = class extends SignalEmitter {
2150
2733
  });
2151
2734
  }
2152
2735
  /**
2153
- * Emits attached fail signals.
2154
- * @param context The context for emission.
2155
- * @edge If isMeta (from Task), suppresses further "meta.*" to prevent loops.
2736
+ * Emits registered signals when an operation fails.
2737
+ *
2738
+ * @param {GraphContext} context - The context from which the full context is derived and passed to the signals being emitted.
2739
+ * @return {void} This method does not return any value.
2156
2740
  */
2157
2741
  emitOnFailSignals(context) {
2158
2742
  this.signalsToEmitOnFail.forEach((signal) => {
2159
2743
  this.emit(signal, context.getFullContext());
2160
2744
  });
2161
2745
  }
2746
+ /**
2747
+ * Cleans up and destroys the task instance, detaching it from other tasks and
2748
+ * performing necessary cleanup operations.
2749
+ *
2750
+ * This method:
2751
+ * - Unsubscribes from all signals and events.
2752
+ * - Detaches all associated signal handlers.
2753
+ * - Removes the task from successor and predecessor task mappings.
2754
+ * - Clears all task relationships and marks the task as destroyed.
2755
+ * - Emits destruction metrics, if applicable.
2756
+ *
2757
+ * @return {void} No value is returned because the function performs clean-up operations.
2758
+ */
2162
2759
  destroy() {
2163
2760
  this.unsubscribeAll();
2164
2761
  this.detachAllSignals();
@@ -2176,6 +2773,18 @@ var Task = class extends SignalEmitter {
2176
2773
  });
2177
2774
  }
2178
2775
  }
2776
+ /**
2777
+ * Exports the current state of the object as a structured plain object.
2778
+ *
2779
+ * @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:
2780
+ * - Name and description of the task.
2781
+ * - Layer index, uniqueness, meta, and signal-related flags.
2782
+ * - Event triggers and attached signals.
2783
+ * - Throttling, concurrency, timeout settings, and ephemeral flag.
2784
+ * - Task function as a string.
2785
+ * - Serialization of getter callbacks and schemas for input/output validation.
2786
+ * - Relationships such as next tasks, failure tasks, and predecessor tasks.
2787
+ */
2179
2788
  export() {
2180
2789
  return {
2181
2790
  __name: this.name,
@@ -2202,9 +2811,20 @@ var Task = class extends SignalEmitter {
2202
2811
  __previousTasks: Array.from(this.predecessorTasks).map((t) => t.name)
2203
2812
  };
2204
2813
  }
2814
+ /**
2815
+ * Returns an iterator for iterating over tasks associated with this instance.
2816
+ *
2817
+ * @return {TaskIterator} An iterator instance for tasks.
2818
+ */
2205
2819
  getIterator() {
2206
2820
  return new TaskIterator(this);
2207
2821
  }
2822
+ /**
2823
+ * Accepts a visitor object to perform operations on the current instance.
2824
+ *
2825
+ * @param {GraphVisitor} visitor - The visitor object implementing operations for this instance.
2826
+ * @return {void} This method does not return a value.
2827
+ */
2208
2828
  accept(visitor) {
2209
2829
  visitor.visitTask(this);
2210
2830
  }
@@ -2215,6 +2835,16 @@ var Task = class extends SignalEmitter {
2215
2835
 
2216
2836
  // src/registry/GraphRegistry.ts
2217
2837
  var GraphRegistry = class _GraphRegistry {
2838
+ /**
2839
+ * Constructs a new instance and sets up various meta tasks and routines.
2840
+ *
2841
+ * This constructor initializes several predefined tasks for managing operations
2842
+ * like registering tasks, updating schemas for tasks, fetching tasks or routines,
2843
+ * and performing actions on all tasks or routines. It also initializes routines
2844
+ * to handle similar operations and hardcodes the initial meta tasks and routines.
2845
+ *
2846
+ * It initializes the instance state by setting up tasks and routines.
2847
+ */
2218
2848
  constructor() {
2219
2849
  this.tasks = /* @__PURE__ */ new Map();
2220
2850
  this.routines = /* @__PURE__ */ new Map();
@@ -2399,12 +3029,14 @@ var GraphRunner = class extends SignalEmitter {
2399
3029
  );
2400
3030
  }
2401
3031
  /**
2402
- * Adds tasks/routines to current run.
2403
- * @param tasks Tasks/routines.
2404
- * @param context Context (defaults {}).
2405
- * @edge Flattens routines to tasks; generates routineExecId if not in context.
2406
- * @edge Emits 'meta.runner.added_tasks' with metadata.
2407
- * @edge Empty tasks warns no-op.
3032
+ * Adds tasks or routines to the current execution pipeline. Supports both individual tasks,
3033
+ * routines, or arrays of tasks and routines. Handles metadata and execution context management.
3034
+ *
3035
+ * @param {Task|GraphRoutine|(Task|GraphRoutine)[]} tasks - The task(s) or routine(s) to be added.
3036
+ * It can be a single task, a single routine, or an array of tasks and routines.
3037
+ * @param {AnyObject} [context={}] - Optional context object to provide execution trace and metadata.
3038
+ * Used to propagate information across task or routine executions.
3039
+ * @return {void} - This method does not return a value.
2408
3040
  */
2409
3041
  addTasks(tasks, context = {}) {
2410
3042
  let _tasks = Array.isArray(tasks) ? tasks : [tasks];
@@ -2429,9 +3061,9 @@ var GraphRunner = class extends SignalEmitter {
2429
3061
  const isSubMeta = allTasks.some((t) => t.isSubMeta) || !!context.__isSubMeta;
2430
3062
  context.__isSubMeta = isSubMeta;
2431
3063
  const isNewTrace = !context.__routineExecId && !context.__metadata?.__executionTraceId && !context.__executionTraceId;
2432
- const executionTraceId = context.__metadata?.__executionTraceId ?? context.__executionTraceId ?? (0, import_uuid4.v4)();
3064
+ const executionTraceId = context.__metadata?.__executionTraceId ?? context.__executionTraceId ?? (0, import_uuid5.v4)();
2433
3065
  context.__executionTraceId = executionTraceId;
2434
- const routineExecId = context.__routineExecId ?? (0, import_uuid4.v4)();
3066
+ const routineExecId = context.__routineExecId ?? (0, import_uuid5.v4)();
2435
3067
  context.__routineExecId = routineExecId;
2436
3068
  const ctx = new GraphContext(context || {});
2437
3069
  if (!isSubMeta) {
@@ -2477,11 +3109,12 @@ var GraphRunner = class extends SignalEmitter {
2477
3109
  );
2478
3110
  }
2479
3111
  /**
2480
- * Runs tasks/routines.
2481
- * @param tasks Optional tasks/routines.
2482
- * @param context Optional context.
2483
- * @returns Current/last run (Promise if async).
2484
- * @edge If running, returns current; else runs and resets.
3112
+ * Executes the provided tasks or routines. Maintains the execution state
3113
+ * and handles synchronous or asynchronous processing.
3114
+ *
3115
+ * @param {Task|GraphRoutine|(Task|GraphRoutine)[]} [tasks] - A single task, a single routine, or an array of tasks or routines to execute. Optional.
3116
+ * @param {AnyObject} [context] - An optional context object to be used during task execution.
3117
+ * @return {GraphRun|Promise<GraphRun>} - Returns a `GraphRun` instance if the execution is synchronous, or a `Promise` resolving to a `GraphRun` for asynchronous execution.
2485
3118
  */
2486
3119
  run(tasks, context) {
2487
3120
  if (tasks) {
@@ -2499,10 +3132,23 @@ var GraphRunner = class extends SignalEmitter {
2499
3132
  }
2500
3133
  return this.reset();
2501
3134
  }
3135
+ /**
3136
+ * Executes the provided asynchronous operation and resets the state afterwards.
3137
+ *
3138
+ * @param {Promise<void>} run - A promise representing the asynchronous operation to execute.
3139
+ * @return {Promise<GraphRun>} A promise that resolves to the result of the reset operation after the asynchronous operation completes.
3140
+ */
2502
3141
  async runAsync(run) {
2503
3142
  await run;
2504
3143
  return this.reset();
2505
3144
  }
3145
+ /**
3146
+ * Resets the current state of the graph, creating a new GraphRun instance
3147
+ * and returning the previous run instance.
3148
+ * If the debug mode is not enabled, it will destroy the existing resources.
3149
+ *
3150
+ * @return {GraphRun} The last GraphRun instance before the reset.
3151
+ */
2506
3152
  reset() {
2507
3153
  this.isRunning = false;
2508
3154
  const lastRun = this.currentRun;
@@ -2521,6 +3167,13 @@ var GraphRunner = class extends SignalEmitter {
2521
3167
  destroy() {
2522
3168
  this.currentRun.destroy();
2523
3169
  }
3170
+ /**
3171
+ * Sets the strategy to be used for running the graph and initializes
3172
+ * the current run with the provided strategy if no process is currently running.
3173
+ *
3174
+ * @param {GraphRunStrategy} strategy - The strategy to use for running the graph.
3175
+ * @return {void}
3176
+ */
2524
3177
  setStrategy(strategy) {
2525
3178
  this.strategy = strategy;
2526
3179
  if (!this.isRunning) {
@@ -2580,6 +3233,14 @@ var DebounceTask = class extends Task {
2580
3233
  this.trailing = trailing;
2581
3234
  this.maxWait = maxWait;
2582
3235
  }
3236
+ /**
3237
+ * Executes the taskFunction with the provided context, emit function, and progress callback.
3238
+ * It clears any existing timeout before execution.
3239
+ * Handles synchronous and asynchronous results from taskFunction.
3240
+ * If an error occurs during execution, it resolves with the error.
3241
+ *
3242
+ * @return {void} This method does not return any value.
3243
+ */
2583
3244
  executeFunction() {
2584
3245
  if (this.lastTimeout) {
2585
3246
  clearTimeout(this.lastTimeout);
@@ -2605,6 +3266,19 @@ var DebounceTask = class extends Task {
2605
3266
  }
2606
3267
  }
2607
3268
  }
3269
+ /**
3270
+ * Executes a debounced operation, ensuring controlled execution of functions
3271
+ * over a specified debounce time and maximum wait time. This method handles
3272
+ * both leading and trailing edge executions and invokes callbacks accordingly.
3273
+ *
3274
+ * @param {Function} resolve - The function to call when the operation is successfully resolved.
3275
+ * @param {Function} reject - The function to call with an error or reason if the operation fails.
3276
+ * @param {GraphContext} context - The execution context for the operation.
3277
+ * @param {NodeJS.Timeout} timeout - A timeout object for managing execution delays.
3278
+ * @param {Function} emit - A callback function to emit signals with a specific context.
3279
+ * @param {Function} progressCallback - A callback function to report progress during operation execution.
3280
+ * @return {void} Does not return a value but sets internal timers and invokes provided callbacks.
3281
+ */
2608
3282
  debouncedTrigger(resolve, reject, context, timeout, emit, progressCallback) {
2609
3283
  const callNow = this.leading && this.timer === null;
2610
3284
  const isNewBurst = this.timer === null;
@@ -2650,6 +3324,14 @@ var DebounceTask = class extends Task {
2650
3324
  }, this.maxWait);
2651
3325
  }
2652
3326
  }
3327
+ /**
3328
+ * Executes a task with a debounced trigger mechanism.
3329
+ *
3330
+ * @param {GraphContext} context - The context containing relevant graph data for the execution.
3331
+ * @param {function(string, any): void} emit - A function used to emit signals with associated context.
3332
+ * @param {function(number): void} progressCallback - A callback function to report the progress of the task as a number between 0 and 1.
3333
+ * @return {Promise<TaskResult>} A promise that resolves with the task result upon completion or rejects on failure.
3334
+ */
2653
3335
  execute(context, emit, progressCallback) {
2654
3336
  return new Promise((resolve, reject) => {
2655
3337
  const timeout = setTimeout(() => {
@@ -2695,6 +3377,15 @@ var EphemeralTask = class extends Task {
2695
3377
  this.once = once;
2696
3378
  this.condition = condition;
2697
3379
  }
3380
+ /**
3381
+ * Executes the process logic with the provided context, emit function, progress callback, and node data.
3382
+ *
3383
+ * @param {any} context - The execution context, carrying necessary parameters or states for the operation.
3384
+ * @param {function(string, AnyObject): void} emit - A function to emit signals with a string identifier and associated context.
3385
+ * @param {function(number): void} progressCallback - A callback function to report the progress of the execution as a numerical value.
3386
+ * @param {{ nodeId: string, routineExecId: string }} nodeData - An object containing details about the node ID and routine execution ID.
3387
+ * @return {any} The result of the execution, returned from the base implementation or processed internally.
3388
+ */
2698
3389
  execute(context, emit, progressCallback, nodeData) {
2699
3390
  const result = super.execute(context, emit, progressCallback, nodeData);
2700
3391
  if (this.once || this.condition(result)) {
@@ -2788,26 +3479,56 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2788
3479
  this.debug = false;
2789
3480
  this.index = index;
2790
3481
  }
3482
+ /**
3483
+ * Sets the debug mode for the current instance and all associated nodes.
3484
+ *
3485
+ * @param {boolean} value - A boolean value to enable (true) or disable (false) debug mode.
3486
+ * @return {void} No return value.
3487
+ */
2791
3488
  setDebug(value) {
2792
3489
  this.debug = value;
2793
3490
  for (const node of this.nodes) {
2794
3491
  node.setDebug(value);
2795
3492
  }
2796
3493
  }
3494
+ /**
3495
+ * Checks if the current layer has a preceding layer.
3496
+ *
3497
+ * @return {boolean} True if the current layer has a preceding layer that is an instance of GraphLayer; otherwise, false.
3498
+ */
2797
3499
  get hasPreceding() {
2798
3500
  return !!this.previous && this.previous instanceof _GraphLayer;
2799
3501
  }
2800
3502
  getNumberOfNodes() {
2801
3503
  return this.nodes.length;
2802
3504
  }
3505
+ /**
3506
+ * Retrieves a list of nodes that match the given routine execution ID.
3507
+ *
3508
+ * @param {string} routineExecId - The ID of the routine execution to filter nodes by.
3509
+ * @return {Array} An array of nodes that have the specified routine execution ID.
3510
+ */
2803
3511
  getNodesByRoutineExecId(routineExecId) {
2804
3512
  return this.nodes.filter((node) => node.routineExecId === routineExecId);
2805
3513
  }
3514
+ /**
3515
+ * Finds and returns all nodes in the graph that are identical to the given node.
3516
+ * Two nodes are considered identical if they share the same routine execution ID
3517
+ * and share a task with each other.
3518
+ *
3519
+ * @param {GraphNode} node - The reference node to compare against other nodes in the graph.
3520
+ * @return {GraphNode[]} An array of nodes that are identical to the given node.
3521
+ */
2806
3522
  getIdenticalNodes(node) {
2807
3523
  return this.nodes.filter(
2808
3524
  (n) => node.routineExecId === n.routineExecId && node.sharesTaskWith(n)
2809
3525
  );
2810
3526
  }
3527
+ /**
3528
+ * Checks whether all nodes in the collection have been processed.
3529
+ *
3530
+ * @return {boolean} Returns true if all nodes are processed, otherwise false.
3531
+ */
2811
3532
  isProcessed() {
2812
3533
  for (const node of this.nodes) {
2813
3534
  if (!node.isProcessed()) {
@@ -2816,6 +3537,11 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2816
3537
  }
2817
3538
  return true;
2818
3539
  }
3540
+ /**
3541
+ * Checks whether all layers in the graph have been processed.
3542
+ *
3543
+ * @return {boolean} Returns true if all graph layers are processed; otherwise, returns false.
3544
+ */
2819
3545
  graphDone() {
2820
3546
  let done = true;
2821
3547
  let layer = this;
@@ -2828,6 +3554,13 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2828
3554
  }
2829
3555
  return done;
2830
3556
  }
3557
+ /**
3558
+ * Sets the next GraphLayer in the sequence if it has a higher index than the current layer.
3559
+ * Updates the previous property if the given next layer has an existing previous layer.
3560
+ *
3561
+ * @param {GraphLayer} next - The next GraphLayer to be linked in the sequence.
3562
+ * @return {void} Does not return a value. Modifies the current layer's state.
3563
+ */
2831
3564
  setNext(next) {
2832
3565
  if (next.index <= this.index) {
2833
3566
  return;
@@ -2837,15 +3570,32 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2837
3570
  }
2838
3571
  super.setNext(next);
2839
3572
  }
3573
+ /**
3574
+ * Adds a node to the graph.
3575
+ *
3576
+ * @param {GraphNode} node - The node to be added to the graph.
3577
+ * @return {void}
3578
+ */
2840
3579
  add(node) {
2841
3580
  this.nodes.push(node);
2842
3581
  }
3582
+ /**
3583
+ * Starts the execution timer if it has not been started already.
3584
+ * Records the current timestamp as the start time.
3585
+ *
3586
+ * @return {number} The timestamp representing the start time in milliseconds.
3587
+ */
2843
3588
  start() {
2844
3589
  if (!this.executionStart) {
2845
3590
  this.executionStart = Date.now();
2846
3591
  }
2847
3592
  return this.executionStart;
2848
3593
  }
3594
+ /**
3595
+ * Marks the end of a process by capturing the current timestamp and calculating the execution time if a start time exists.
3596
+ *
3597
+ * @return {number} The timestamp at which the process ended, or 0 if the start time is not defined.
3598
+ */
2849
3599
  end() {
2850
3600
  if (!this.executionStart) {
2851
3601
  return 0;
@@ -2854,6 +3604,14 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2854
3604
  this.executionTime = end - this.executionStart;
2855
3605
  return end;
2856
3606
  }
3607
+ /**
3608
+ * Destroys the current graph layer and its associated resources.
3609
+ * This method recursively destroys all nodes in the current layer, clears the node list,
3610
+ * and ensures that any connected subsequent graph layers are also destroyed.
3611
+ * Additionally, it calls the decoupling logic to disconnect the current layer from its dependencies.
3612
+ *
3613
+ * @return {void} Does not return any value.
3614
+ */
2857
3615
  destroy() {
2858
3616
  for (const node of this.nodes) {
2859
3617
  node.destroy();
@@ -2865,9 +3623,20 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2865
3623
  }
2866
3624
  this.decouple();
2867
3625
  }
3626
+ /**
3627
+ * Returns an iterator for traversing through the graph layers.
3628
+ *
3629
+ * @return {GraphLayerIterator} An instance of GraphLayerIterator to traverse graph layers.
3630
+ */
2868
3631
  getIterator() {
2869
3632
  return new GraphLayerIterator(this);
2870
3633
  }
3634
+ /**
3635
+ * Accepts a visitor object to traverse or perform operations on the current graph layer and its nodes.
3636
+ *
3637
+ * @param {GraphVisitor} visitor - The visitor instance implementing the visitLayer and visitNode behavior.
3638
+ * @return {void} Returns nothing.
3639
+ */
2871
3640
  accept(visitor) {
2872
3641
  visitor.visitLayer(this);
2873
3642
  for (const node of this.nodes) {
@@ -2904,6 +3673,14 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2904
3673
 
2905
3674
  // src/graph/execution/SyncGraphLayer.ts
2906
3675
  var SyncGraphLayer = class extends GraphLayer {
3676
+ /**
3677
+ * Executes the processing logic of the current set of graph nodes. Iterates through all
3678
+ * nodes, skipping any that have already been processed, and executes their respective
3679
+ * logic to generate new nodes. Asynchronous functions are not supported and will
3680
+ * trigger an error log.
3681
+ *
3682
+ * @return {GraphNode[]} An array of newly generated graph nodes after executing the logic of each unprocessed node.
3683
+ */
2907
3684
  execute() {
2908
3685
  this.start();
2909
3686
  const result = [];
@@ -2936,20 +3713,49 @@ var GraphBuilder = class {
2936
3713
  getResult() {
2937
3714
  return this.graph;
2938
3715
  }
3716
+ /**
3717
+ * Composes a series of functions or operations.
3718
+ * This method should be implemented in the child class
3719
+ * to define custom composition logic.
3720
+ *
3721
+ * @return {any} The result of the composed operations or functions
3722
+ * when implemented in the child class.
3723
+ */
2939
3724
  compose() {
2940
3725
  throw "Implement this in child class...";
2941
3726
  }
3727
+ /**
3728
+ * Adds a node to the appropriate layer of the graph.
3729
+ *
3730
+ * @param {GraphNode} node - The node to be added to the graph. The node contains
3731
+ * layer information that determines which layer it belongs to.
3732
+ * @return {void} Does not return a value.
3733
+ */
2942
3734
  addNode(node) {
2943
3735
  const index = node.getLayerIndex();
2944
3736
  this.addLayer(index);
2945
3737
  const layer = this.getLayer(index);
2946
3738
  node.scheduleOn(layer);
2947
3739
  }
3740
+ /**
3741
+ * Adds multiple nodes to the graph.
3742
+ *
3743
+ * @param {GraphNode[]} nodes - An array of nodes to be added to the graph.
3744
+ * @return {void} This method does not return a value.
3745
+ */
2948
3746
  addNodes(nodes) {
2949
3747
  for (const node of nodes) {
2950
3748
  this.addNode(node);
2951
3749
  }
2952
3750
  }
3751
+ /**
3752
+ * Adds a new layer to the graph at the specified index. If the graph does not exist,
3753
+ * it creates the graph using the specified index. Updates the graph's top layer index
3754
+ * and maintains the order of layers.
3755
+ *
3756
+ * @param {number} index - The index at which the new layer should be added to the graph.
3757
+ * @return {void} This method does not return a value.
3758
+ */
2953
3759
  addLayer(index) {
2954
3760
  if (!this.graph) {
2955
3761
  const layer = this.createLayer(index);
@@ -2976,11 +3782,23 @@ var GraphBuilder = class {
2976
3782
  this.addLayer(index);
2977
3783
  }
2978
3784
  }
3785
+ /**
3786
+ * Creates a new layer for the graph at the specified index.
3787
+ *
3788
+ * @param {number} index - The index of the layer to be created.
3789
+ * @return {GraphLayer} A new instance of the graph layer corresponding to the provided index.
3790
+ */
2979
3791
  createLayer(index) {
2980
3792
  const layer = new SyncGraphLayer(index);
2981
3793
  layer.setDebug(this.debug);
2982
3794
  return layer;
2983
3795
  }
3796
+ /**
3797
+ * Retrieves a specific layer from the current set of layers.
3798
+ *
3799
+ * @param {number} layerIndex - The index of the layer to retrieve.
3800
+ * @return {*} The layer corresponding to the given index.
3801
+ */
2984
3802
  getLayer(layerIndex) {
2985
3803
  return this.layers[layerIndex - this.topLayerIndex];
2986
3804
  }
@@ -2993,6 +3811,12 @@ var GraphBuilder = class {
2993
3811
 
2994
3812
  // src/engine/builders/GraphBreadthFirstBuilder.ts
2995
3813
  var GraphBreadthFirstBuilder = class extends GraphBuilder {
3814
+ /**
3815
+ * Composes layers of a graph by iterating through them, executing their logic,
3816
+ * and adding the resulting nodes to the current graph.
3817
+ *
3818
+ * @return {void} This method does not return a value.
3819
+ */
2996
3820
  compose() {
2997
3821
  if (!this.graph) {
2998
3822
  return;
@@ -3048,6 +3872,15 @@ var ThrottleEngine = class _ThrottleEngine {
3048
3872
  setConcurrencyLimit(tag, limit) {
3049
3873
  this.maxConcurrencyPerTag[tag] = limit;
3050
3874
  }
3875
+ /**
3876
+ * Manages the execution of a function `fn` applied on a specified node `node` with controlled concurrency for a given tag.
3877
+ * The method ensures that processes are executed in a throttled manner, respecting the maximum concurrency for each tag.
3878
+ *
3879
+ * @param {ProcessFunction} fn - The function to be executed on the provided node.
3880
+ * @param {GraphNode} node - The graph node on which the function `fn` will be applied.
3881
+ * @param {string} [tag="default"] - The concurrency grouping tag used to control and group the throttling behavior.
3882
+ * @return {Promise<GraphNode[]>} A promise resolving to an array of GraphNode objects once the throttled function execution completes.
3883
+ */
3051
3884
  throttle(fn, node, tag = "default") {
3052
3885
  var _a, _b;
3053
3886
  const functionPromise = new Promise((resolve) => {
@@ -3059,6 +3892,12 @@ var ThrottleEngine = class _ThrottleEngine {
3059
3892
  this.processQueue(tag);
3060
3893
  return functionPromise;
3061
3894
  }
3895
+ /**
3896
+ * Processes the tasks in the queue for a given tag while respecting concurrency limits.
3897
+ *
3898
+ * @param {string} tag - The identifier for the queue to be processed, used to group tasks and manage concurrency controls.
3899
+ * @return {void} Does not return a value; it processes tasks asynchronously and manages state internally.
3900
+ */
3062
3901
  processQueue(tag) {
3063
3902
  const maxAllowed = this.maxConcurrencyPerTag[tag];
3064
3903
  while ((this.queues[tag]?.length ?? 0) > 0 && (this.runningCounts[tag] ?? 0) < maxAllowed) {
@@ -3074,6 +3913,14 @@ var ThrottleEngine = class _ThrottleEngine {
3074
3913
  delete this.runningCounts[tag];
3075
3914
  }
3076
3915
  }
3916
+ /**
3917
+ * Processes a given item consisting of a function and a graph node.
3918
+ *
3919
+ * @param {Array} item - An array where the first element is a processing function and the second element is a graph node.
3920
+ * @param {Function} item[0] - The function to process the graph node.
3921
+ * @param {GraphNode} item[1] - The graph node to be processed.
3922
+ * @return {Promise<void>} A promise that resolves when the processing and cleanup are complete.
3923
+ */
3077
3924
  async process(item) {
3078
3925
  const fn = item[0];
3079
3926
  const node = item[1];
@@ -3090,10 +3937,24 @@ var AsyncGraphLayer = class extends GraphLayer {
3090
3937
  this.waitingNodes = [];
3091
3938
  this.processingNodes = /* @__PURE__ */ new Set();
3092
3939
  }
3940
+ /**
3941
+ * Adds a node to the graph and tracks it as a waiting node.
3942
+ *
3943
+ * @param {GraphNode} node - The graph node to be added.
3944
+ * @return {void}
3945
+ */
3093
3946
  add(node) {
3094
3947
  this.nodes.push(node);
3095
3948
  this.waitingNodes.push(node);
3096
3949
  }
3950
+ /**
3951
+ * Executes the processing of nodes by iterating over the queued `waitingNodes`,
3952
+ * processing each node, and managing concurrency limits where applicable.
3953
+ * The method returns a mapping of routine execution IDs to arrays of processed nodes or promises.
3954
+ *
3955
+ * @return {Object} An object where the keys are routine execution IDs and the values
3956
+ * represent arrays of processed nodes or promises resolving to processed nodes.
3957
+ */
3097
3958
  execute() {
3098
3959
  var _a;
3099
3960
  if (this.waitingNodes.length === 0) {
@@ -3127,6 +3988,13 @@ var AsyncGraphLayer = class extends GraphLayer {
3127
3988
  }
3128
3989
  return result;
3129
3990
  }
3991
+ /**
3992
+ * Processes the given graph node, executes its logic, and handles synchronous or asynchronous outcomes.
3993
+ *
3994
+ * @param {GraphNode} node - The graph node to be processed.
3995
+ * @return {Promise<GraphNode[]> | GraphNode[]} A promise that resolves to an array of next graph nodes if asynchronous,
3996
+ * or an array of next graph nodes if synchronous.
3997
+ */
3130
3998
  processNode(node) {
3131
3999
  node.start();
3132
4000
  const nextNodes = node.execute();
@@ -3136,11 +4004,23 @@ var AsyncGraphLayer = class extends GraphLayer {
3136
4004
  this.processingNodes.delete(node);
3137
4005
  return nextNodes;
3138
4006
  }
4007
+ /**
4008
+ * Processes the given graph node asynchronously and removes it from the processing nodes set.
4009
+ *
4010
+ * @param {GraphNode} node - The current graph node being processed.
4011
+ * @param {Promise<GraphNode[]>} nextNodes - A promise that resolves to an array of the next graph nodes to process.
4012
+ * @return {Promise<GraphNode[]>} A promise that resolves to an array of the next graph nodes.
4013
+ */
3139
4014
  async processAsync(node, nextNodes) {
3140
4015
  const result = await nextNodes;
3141
4016
  this.processingNodes.delete(node);
3142
4017
  return result;
3143
4018
  }
4019
+ /**
4020
+ * Cleans up resources used by the instance by resetting relevant properties and invoking the parent class's destroy method.
4021
+ *
4022
+ * @return {void} No value is returned as the method performs cleanup operations.
4023
+ */
3144
4024
  destroy() {
3145
4025
  super.destroy();
3146
4026
  this.waitingNodes = [];
@@ -3150,6 +4030,14 @@ var AsyncGraphLayer = class extends GraphLayer {
3150
4030
 
3151
4031
  // src/engine/builders/GraphAsyncQueueBuilder.ts
3152
4032
  var GraphAsyncQueueBuilder = class extends GraphBuilder {
4033
+ /**
4034
+ * This method iterates over a graph structure and processes its layers sequentially.
4035
+ * It continues processing each layer until all layers in the graph are completed.
4036
+ * The asynchronous behavior ensures the operation provides breathing room for other
4037
+ * tasks/processes to execute during its operation.
4038
+ *
4039
+ * @return {Promise<void>} A promise that resolves when all layers of the graph are processed or rejects if an error occurs.
4040
+ */
3153
4041
  async compose() {
3154
4042
  if (!this.graph) {
3155
4043
  return;
@@ -3168,6 +4056,14 @@ var GraphAsyncQueueBuilder = class extends GraphBuilder {
3168
4056
  await sleep(0);
3169
4057
  }
3170
4058
  }
4059
+ /**
4060
+ * Processes a given asynchronous graph layer and executes its nodes.
4061
+ * Handles promises within the nodes and adds the resolved or processed
4062
+ * nodes to the graph.
4063
+ *
4064
+ * @param {AsyncGraphLayer} layer - The asynchronous graph layer to be processed.
4065
+ * @return {void} - This method does not return a value.
4066
+ */
3171
4067
  processLayer(layer) {
3172
4068
  const nextNodes = layer.execute();
3173
4069
  for (const routineExecId of Object.keys(nextNodes)) {
@@ -3181,6 +4077,13 @@ var GraphAsyncQueueBuilder = class extends GraphBuilder {
3181
4077
  }
3182
4078
  }
3183
4079
  }
4080
+ /**
4081
+ * Creates a new instance of AsyncGraphLayer, sets its debug configuration,
4082
+ * and returns the created layer.
4083
+ *
4084
+ * @param {number} index - The index to associate with the new AsyncGraphLayer.
4085
+ * @return {AsyncGraphLayer} A new instance of AsyncGraphLayer with the specified index and debug configuration.
4086
+ */
3184
4087
  createLayer(index) {
3185
4088
  const layer = new AsyncGraphLayer(index);
3186
4089
  layer.setDebug(this.debug);
@@ -3194,6 +4097,12 @@ var GraphAsyncRun = class extends GraphRunStrategy {
3194
4097
  super();
3195
4098
  this.graphBuilder = new GraphAsyncQueueBuilder();
3196
4099
  }
4100
+ /**
4101
+ * Executes the run operation, which involves composing the graph builder,
4102
+ * updating the run instance, and resetting the state.
4103
+ *
4104
+ * @return {Promise<void>} A promise that resolves when the operation completes.
4105
+ */
3197
4106
  async run() {
3198
4107
  await this.graphBuilder.compose();
3199
4108
  this.updateRunInstance();
@@ -3209,6 +4118,12 @@ var GraphAsyncRun = class extends GraphRunStrategy {
3209
4118
 
3210
4119
  // src/engine/strategy/GraphStandardRun.ts
3211
4120
  var GraphStandardRun = class extends GraphRunStrategy {
4121
+ /**
4122
+ * Executes the sequence of operations involving graph composition,
4123
+ * instance updating, and reset mechanisms.
4124
+ *
4125
+ * @return {void} Does not return a value.
4126
+ */
3212
4127
  run() {
3213
4128
  this.graphBuilder.compose();
3214
4129
  this.updateRunInstance();
@@ -3221,6 +4136,13 @@ var GraphStandardRun = class extends GraphRunStrategy {
3221
4136
 
3222
4137
  // src/Cadenza.ts
3223
4138
  var Cadenza = class {
4139
+ /**
4140
+ * Initializes the system by setting up the required components such as the
4141
+ * signal broker, runners, and graph registry. Ensures the initialization
4142
+ * happens only once. Configures debug settings if applicable.
4143
+ *
4144
+ * @return {void} No value is returned.
4145
+ */
3224
4146
  static bootstrap() {
3225
4147
  if (this.isBootstrapped) return;
3226
4148
  this.isBootstrapped = true;
@@ -3238,12 +4160,27 @@ var Cadenza = class {
3238
4160
  this.runner.init();
3239
4161
  this.metaRunner.init();
3240
4162
  }
4163
+ /**
4164
+ * Retrieves the available strategies for running graphs.
4165
+ *
4166
+ * @return {Object} An object containing the available run strategies, where:
4167
+ * - PARALLEL: Executes graph runs asynchronously.
4168
+ * - SEQUENTIAL: Executes graph runs in a sequential order.
4169
+ */
3241
4170
  static get runStrategy() {
3242
4171
  return {
3243
4172
  PARALLEL: new GraphAsyncRun(),
3244
4173
  SEQUENTIAL: new GraphStandardRun()
3245
4174
  };
3246
4175
  }
4176
+ /**
4177
+ * Sets the mode for the application and configures the broker and runner settings accordingly.
4178
+ *
4179
+ * @param {CadenzaMode} mode - The mode to set. It can be one of the following:
4180
+ * "debug", "dev", "verbose", or "production".
4181
+ * Each mode adjusts debug and verbosity settings.
4182
+ * @return {void} This method does not return a value.
4183
+ */
3247
4184
  static setMode(mode) {
3248
4185
  this.mode = mode;
3249
4186
  this.bootstrap();
@@ -3265,29 +4202,129 @@ var Cadenza = class {
3265
4202
  }
3266
4203
  }
3267
4204
  /**
3268
- * Validates a name for uniqueness and non-emptiness.
3269
- * @param name The name to validate.
3270
- * @throws Error if invalid.
4205
+ * Validates the given name to ensure it is a non-empty string.
4206
+ * Throws an error if the validation fails.
4207
+ *
4208
+ * @param {string} name - The name to validate.
4209
+ * @return {void} This method does not return anything.
4210
+ * @throws {Error} If the name is not a non-empty string.
3271
4211
  */
3272
4212
  static validateName(name) {
3273
4213
  if (!name || typeof name !== "string") {
3274
4214
  throw new Error("Task or Routine name must be a non-empty string.");
3275
4215
  }
3276
4216
  }
4217
+ /**
4218
+ * Executes the specified task or GraphRoutine with the given context using an internal runner.
4219
+ *
4220
+ * @param {Task | GraphRoutine} task - The task or GraphRoutine to be executed.
4221
+ * @param {AnyObject} context - The context in which the task or GraphRoutine should be executed.
4222
+ * @return {void}
4223
+ *
4224
+ * @example
4225
+ * ```ts
4226
+ * const task = Cadenza.createTask('My task', (ctx) => {
4227
+ * console.log('My task executed with context:', ctx);
4228
+ * });
4229
+ *
4230
+ * Cadenza.run(task, { foo: 'bar' });
4231
+ *
4232
+ * const routine = Cadenza.createRoutine('My routine', [task], 'My routine description');
4233
+ *
4234
+ * Cadenza.run(routine, { foo: 'bar' });
4235
+ * ```
4236
+ */
3277
4237
  static run(task, context) {
3278
4238
  this.runner?.run(task, context);
3279
4239
  }
4240
+ /**
4241
+ * Emits an event with the specified name and data payload to the broker.
4242
+ *
4243
+ * @param {string} event - The name of the event to emit.
4244
+ * @param {AnyObject} [data={}] - The data payload associated with the event.
4245
+ * @return {void} - No return value.
4246
+ *
4247
+ * @example
4248
+ * This is meant to be used as a global event emitter.
4249
+ * 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}.
4250
+ * ```ts
4251
+ * Cadenza.emit('main.my_event', { foo: 'bar' });
4252
+ * ```
4253
+ */
3280
4254
  static emit(event, data = {}) {
3281
4255
  this.broker?.emit(event, data);
3282
4256
  }
3283
4257
  /**
3284
- * Creates a standard Task and registers it in the GraphRegistry.
3285
- * @param name Unique identifier for the task.
3286
- * @param func The function or async generator to execute.
3287
- * @param description Optional human-readable description for introspection.
3288
- * @param options Optional task options.
3289
- * @returns The created Task instance.
3290
- * @throws Error if name is invalid or duplicate in registry.
4258
+ * Creates and registers a new task with the specified parameters and options.
4259
+ * Tasks are the basic building blocks of Cadenza graphs and are responsible for executing logic.
4260
+ * See {@link Task} for more information.
4261
+ *
4262
+ * @param {string} name - The unique name of the task.
4263
+ * @param {TaskFunction} func - The function to be executed by the task.
4264
+ * @param {string} [description] - An optional description for the task.
4265
+ * @param {TaskOptions} [options={}] - Configuration options for the task, such as concurrency, timeout, and retry settings.
4266
+ * @return {Task} The created task instance.
4267
+ *
4268
+ * @example
4269
+ * You can use arrow functions to create tasks.
4270
+ * ```ts
4271
+ * const task = Cadenza.createTask('My task', (ctx) => {
4272
+ * console.log('My task executed with context:', ctx);
4273
+ * }, 'My task description');
4274
+ * ```
4275
+ *
4276
+ * You can also use named functions to create tasks.
4277
+ * This is the preferred way to create tasks since it allows for code inspection in the CadenzaUI.
4278
+ * ```ts
4279
+ * function myTask(ctx) {
4280
+ * console.log('My task executed with context:', ctx);
4281
+ * }
4282
+ *
4283
+ * const task = Cadenza.createTask('My task', myTask);
4284
+ * ```
4285
+ *
4286
+ * ** Use the TaskOptions object to configure the task. **
4287
+ *
4288
+ * With concurrency limit, timeout limit and retry settings.
4289
+ * ```ts
4290
+ * Cadenza.createTask('My task', (ctx) => {
4291
+ * console.log('My task executed with context:', ctx);
4292
+ * }, 'My task description', {
4293
+ * concurrency: 10,
4294
+ * timeout: 10000,
4295
+ * retryCount: 3,
4296
+ * retryDelay: 1000,
4297
+ * retryDelayFactor: 1.5,
4298
+ * });
4299
+ * ```
4300
+ *
4301
+ * You can specify the input and output context schemas for the task.
4302
+ * ```ts
4303
+ * Cadenza.createTask('My task', (ctx) => {
4304
+ * return { bar: 'foo' + ctx.foo };
4305
+ * }, 'My task description', {
4306
+ * inputContextSchema: {
4307
+ * type: 'object',
4308
+ * properties: {
4309
+ * foo: {
4310
+ * type: 'string',
4311
+ * },
4312
+ * },
4313
+ * required: ['foo'],
4314
+ * },
4315
+ * validateInputContext: true, // default is false
4316
+ * outputContextSchema: {
4317
+ * type: 'object',
4318
+ * properties: {
4319
+ * bar: {
4320
+ * type: 'string',
4321
+ * },
4322
+ * },
4323
+ * required: ['bar'],
4324
+ * },
4325
+ * validateOutputContext: true, // default is false
4326
+ * });
4327
+ * ```
3291
4328
  */
3292
4329
  static createTask(name, func, description, options = {}) {
3293
4330
  this.bootstrap();
@@ -3334,40 +4371,82 @@ var Cadenza = class {
3334
4371
  );
3335
4372
  }
3336
4373
  /**
3337
- * Creates a MetaTask (for meta-layer graphs) and registers it.
3338
- * MetaTasks suppress further meta-signal emissions to prevent loops.
3339
- * @param name Unique identifier for the meta-task.
3340
- * @param func The function or async generator to execute.
3341
- * @param description Optional description.
3342
- * @param options Optional task options.
3343
- * @returns The created MetaTask instance.
3344
- * @throws Error if name invalid or duplicate.
4374
+ * Creates a meta task with the specified name, functionality, description, and options.
4375
+ * This is used for creating tasks that lives on the meta layer.
4376
+ * The meta layer is a special layer that is executed separately from the business logic layer and is used for extending Cadenzas core functionality.
4377
+ * See {@link Task} or {@link createTask} for more information.
4378
+ *
4379
+ * @param {string} name - The name of the meta task.
4380
+ * @param {TaskFunction} func - The function to be executed by the meta task.
4381
+ * @param {string} [description] - An optional description of the meta task.
4382
+ * @param {TaskOptions} [options={}] - Additional optional task configuration. Automatically sets `isMeta` to true.
4383
+ * @return {Task} A task instance configured as a meta task.
3345
4384
  */
3346
4385
  static createMetaTask(name, func, description, options = {}) {
3347
4386
  options.isMeta = true;
3348
4387
  return this.createTask(name, func, description, options);
3349
4388
  }
3350
4389
  /**
3351
- * Creates a UniqueTask (executes once per execution ID, merging parents) and registers it.
3352
- * Use for fan-in/joins after parallel branches.
3353
- * @param name Unique identifier.
3354
- * @param func Function receiving joinedContexts.
3355
- * @param description Optional description.
3356
- * @param options Optional task options.
3357
- * @returns The created UniqueTask.
3358
- * @throws Error if invalid.
4390
+ * Creates a unique task by wrapping the provided task function with a uniqueness constraint.
4391
+ * Unique tasks are designed to execute once per execution ID, merging parents. This is useful for
4392
+ * tasks that require fan-in/joins after parallel branches.
4393
+ * See {@link Task} for more information.
4394
+ *
4395
+ * @param {string} name - The name of the task to be created.
4396
+ * @param {TaskFunction} func - The function that contains the logic for the task. It receives joinedContexts as a list in the context (context.joinedContexts).
4397
+ * @param {string} [description] - An optional description of the task.
4398
+ * @param {TaskOptions} [options={}] - Optional configuration for the task, such as additional metadata or task options.
4399
+ * @return {Task} The task instance that was created with a uniqueness constraint.
4400
+ *
4401
+ * @example
4402
+ * ```ts
4403
+ * const splitTask = Cadenza.createTask('Split foos', function* (ctx) {
4404
+ * for (const foo of ctx.foos) {
4405
+ * yield { foo };
4406
+ * }
4407
+ * }, 'Splits a list of foos into multiple sub-branches');
4408
+ *
4409
+ * const processTask = Cadenza.createTask('Process foo', (ctx) => {
4410
+ * return { bar: 'foo' + ctx.foo };
4411
+ * }, 'Process a foo');
4412
+ *
4413
+ * const uniqueTask = Cadenza.createUniqueTask('Gather processed foos', (ctx) => {
4414
+ * // A unique task will always be provided with a list of contexts (ctx.joinedContexts) from its predecessors.
4415
+ * const processedFoos = ctx.joinedContexts.map((c) => c.bar);
4416
+ * return { foos: processedFoos };
4417
+ * }, 'Gathers together the processed foos.');
4418
+ *
4419
+ * splitTask.then(
4420
+ * processTask.then(
4421
+ * uniqueTask,
4422
+ * ),
4423
+ * );
4424
+ *
4425
+ * // Give the flow a name using a routine
4426
+ * Cadenza.createRoutine(
4427
+ * 'Process foos',
4428
+ * [splitTask],
4429
+ * 'Processes a list of foos'
4430
+ * ).doOn('main.received_foos'); // Subscribe to a signal
4431
+ *
4432
+ * // Trigger the flow from anywhere
4433
+ * Cadenza.emit('main.received_foos', { foos: ['foo1', 'foo2', 'foo3'] });
4434
+ * ```
4435
+ *
3359
4436
  */
3360
4437
  static createUniqueTask(name, func, description, options = {}) {
3361
4438
  options.isUnique = true;
3362
4439
  return this.createTask(name, func, description, options);
3363
4440
  }
3364
4441
  /**
3365
- * Creates a UniqueMetaTask for meta-layer joins.
3366
- * @param name Unique identifier.
3367
- * @param func Function.
3368
- * @param description Optional.
3369
- * @param options Optional task options.
3370
- * @returns The created UniqueMetaTask.
4442
+ * Creates a unique meta task with the specified name, function, description, and options.
4443
+ * See {@link createUniqueTask} and {@link createMetaTask} for more information.
4444
+ *
4445
+ * @param {string} name - The name of the task to create.
4446
+ * @param {TaskFunction} func - The function to execute when the task is run.
4447
+ * @param {string} [description] - An optional description of the task.
4448
+ * @param {TaskOptions} [options={}] - Optional settings for the task. Defaults to an empty object. Automatically sets `isMeta` and `isUnique` to true.
4449
+ * @return {Task} The created unique meta task.
3371
4450
  */
3372
4451
  static createUniqueMetaTask(name, func, description, options = {}) {
3373
4452
  options.isMeta = true;
@@ -3375,14 +4454,33 @@ var Cadenza = class {
3375
4454
  return this.createUniqueTask(name, func, description, options);
3376
4455
  }
3377
4456
  /**
3378
- * Creates a ThrottledTask (rate-limited by concurrency or custom groups) and registers it.
3379
- * @param name Unique identifier.
3380
- * @param func Function.
3381
- * @param throttledIdGetter Optional getter for dynamic grouping (e.g., per-user).
3382
- * @param description Optional.
3383
- * @param options Optional task options.
3384
- * @returns The created ThrottledTask.
3385
- * @edge If no getter, throttles per task ID; use for resource protection.
4457
+ * 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.
4458
+ * This is useful for ensuring execution order and preventing race conditions.
4459
+ * See {@link Task} for more information.
4460
+ *
4461
+ * @param {string} name - The name of the task.
4462
+ * @param {TaskFunction} func - The function to be executed when the task runs.
4463
+ * @param {ThrottleTagGetter} [throttledIdGetter=() => "default"] - A function that generates a throttle tag identifier to group tasks for throttling.
4464
+ * @param {string} [description] - An optional description of the task.
4465
+ * @param {TaskOptions} [options={}] - Additional options to customize the task behavior.
4466
+ * @return {Task} The created throttled task.
4467
+ *
4468
+ * @example
4469
+ * ```ts
4470
+ * const task = Cadenza.createThrottledTask(
4471
+ * 'My task',
4472
+ * async (ctx) => {
4473
+ * await new Promise((resolve) => setTimeout(resolve, 1000));
4474
+ * console.log('My task executed with context:', ctx);
4475
+ * },
4476
+ * // Will throttle by the value of ctx.foo to make sure tasks with the same value are executed sequentially
4477
+ * (ctx) => ctx.foo,
4478
+ * );
4479
+ *
4480
+ * Cadenza.run(task, { foo: 'bar' }); // (First execution)
4481
+ * Cadenza.run(task, { foo: 'bar' }); // This will be executed after the first execution is finished
4482
+ * Cadenza.run(task, { foo: 'baz' }); // This will be executed in parallel with the first execution
4483
+ * ```
3386
4484
  */
3387
4485
  static createThrottledTask(name, func, throttledIdGetter = () => "default", description, options = {}) {
3388
4486
  options.concurrency = 1;
@@ -3390,13 +4488,15 @@ var Cadenza = class {
3390
4488
  return this.createTask(name, func, description, options);
3391
4489
  }
3392
4490
  /**
3393
- * Creates a ThrottledMetaTask for meta-layer throttling.
3394
- * @param name Identifier.
3395
- * @param func Function.
3396
- * @param throttledIdGetter Optional getter.
3397
- * @param description Optional.
3398
- * @param options Optional task options.
3399
- * @returns The created ThrottledMetaTask.
4491
+ * Creates a throttled meta task with the specified configuration.
4492
+ * See {@link createThrottledTask} and {@link createMetaTask} for more information.
4493
+ *
4494
+ * @param {string} name - The name of the throttled meta task.
4495
+ * @param {TaskFunction} func - The task function to be executed.
4496
+ * @param {ThrottleTagGetter} throttledIdGetter - A function to retrieve the throttling identifier.
4497
+ * @param {string} [description] - An optional description of the task.
4498
+ * @param {TaskOptions} [options={}] - Additional options for configuring the task.
4499
+ * @return {Task} The created throttled meta task.
3400
4500
  */
3401
4501
  static createThrottledMetaTask(name, func, throttledIdGetter, description, options = {}) {
3402
4502
  options.isMeta = true;
@@ -3409,14 +4509,37 @@ var Cadenza = class {
3409
4509
  );
3410
4510
  }
3411
4511
  /**
3412
- * Creates a DebounceTask (delays exec until quiet period) and registers it.
3413
- * @param name Identifier.
3414
- * @param func Function.
3415
- * @param description Optional.
3416
- * @param debounceTime Delay in ms (default 1000).
3417
- * @param options Optional task options plus optional debounce config (e.g., leading/trailing).
3418
- * @returns The created DebounceTask.
3419
- * @edge Multiple triggers within time collapse to one exec.
4512
+ * Creates and returns a new debounced task with the specified parameters.
4513
+ * This is useful to prevent rapid execution of tasks that may be triggered by multiple events within a certain time frame.
4514
+ * See {@link DebounceTask} for more information.
4515
+ *
4516
+ * @param {string} name - The unique name of the task to be created.
4517
+ * @param {TaskFunction} func - The function to be executed by the task.
4518
+ * @param {string} [description] - An optional description of the task.
4519
+ * @param {number} [debounceTime=1000] - The debounce time in milliseconds to delay the execution of the task.
4520
+ * @param {TaskOptions & DebounceOptions} [options={}] - Additional configuration options for the task, including debounce behavior and other task properties.
4521
+ * @return {DebounceTask} A new instance of the DebounceTask with the specified configuration.
4522
+ *
4523
+ * @example
4524
+ * ```ts
4525
+ * const task = Cadenza.createDebounceTask(
4526
+ * 'My debounced task',
4527
+ * (ctx) => {
4528
+ * console.log('My task executed with context:', ctx);
4529
+ * },
4530
+ * 'My debounced task description',
4531
+ * 100, // Debounce time in milliseconds. Default is 1000
4532
+ * {
4533
+ * leading: false, // Should the first execution of a burst be executed immediately? Default is false
4534
+ * trailing: true, // Should the last execution of a burst be executed? Default is true
4535
+ * maxWait: 1000, // Maximum time in milliseconds to wait for the next execution. Default is 0
4536
+ * },
4537
+ * );
4538
+ *
4539
+ * Cadenza.run(task, { foo: 'bar' }); // This will not be executed
4540
+ * Cadenza.run(task, { foo: 'bar' }); // This will not be executed
4541
+ * Cadenza.run(task, { foo: 'baz' }); // This execution will be delayed by 100ms
4542
+ * ```
3420
4543
  */
3421
4544
  static createDebounceTask(name, func, description, debounceTime = 1e3, options = {}) {
3422
4545
  this.bootstrap();
@@ -3460,13 +4583,15 @@ var Cadenza = class {
3460
4583
  );
3461
4584
  }
3462
4585
  /**
3463
- * Creates a DebouncedMetaTask for meta-layer debouncing.
3464
- * @param name Identifier.
3465
- * @param func Function.
3466
- * @param description Optional.
3467
- * @param debounceTime Delay in ms.
3468
- * @param options Optional task options plus optional debounce config (e.g., leading/trailing).
3469
- * @returns The created DebouncedMetaTask.
4586
+ * Creates a debounced meta task with the specified parameters.
4587
+ * See {@link createDebounceTask} and {@link createMetaTask} for more information.
4588
+ *
4589
+ * @param {string} name - The name of the task.
4590
+ * @param {TaskFunction} func - The function to be executed by the task.
4591
+ * @param {string} [description] - Optional description of the task.
4592
+ * @param {number} [debounceTime=1000] - The debounce delay in milliseconds.
4593
+ * @param {TaskOptions & DebounceOptions} [options={}] - Additional configuration options for the task.
4594
+ * @return {DebounceTask} Returns an instance of the debounced meta task.
3470
4595
  */
3471
4596
  static createDebounceMetaTask(name, func, description, debounceTime = 1e3, options = {}) {
3472
4597
  options.isMeta = true;
@@ -3479,14 +4604,64 @@ var Cadenza = class {
3479
4604
  );
3480
4605
  }
3481
4606
  /**
3482
- * Creates an EphemeralTask (self-destructs after exec or condition) without default registration.
3483
- * Useful for transients; optionally register if needed.
3484
- * @param name Identifier (may not be unique if not registered).
3485
- * @param func Function.
3486
- * @param description Optional.
3487
- * @param options Optional task options plus optional "once" (true) and "destroyCondition" (ctx => boolean).
3488
- * @returns The created EphemeralTask.
3489
- * @edge Destruction triggered post-exec via Node/Builder; emits meta-signal for cleanup.
4607
+ * Creates an ephemeral task with the specified configuration.
4608
+ * Ephemeral tasks are designed to self-destruct after execution or a certain condition is met.
4609
+ * This is useful for transient tasks such as resolving promises or performing cleanup operations.
4610
+ * They are not registered by default.
4611
+ * See {@link EphemeralTask} for more information.
4612
+ *
4613
+ * @param {string} name - The name of the task to be created.
4614
+ * @param {TaskFunction} func - The function that defines the logic of the task.
4615
+ * @param {string} [description] - An optional description of the task.
4616
+ * @param {TaskOptions & EphemeralTaskOptions} [options={}] - The configuration options for the task, including concurrency, timeouts, and retry policies.
4617
+ * @return {EphemeralTask} The created ephemeral task instance.
4618
+ *
4619
+ * @example
4620
+ * By default, ephemeral tasks are executed once and destroyed after execution.
4621
+ * ```ts
4622
+ * const task = Cadenza.createEphemeralTask('My ephemeral task', (ctx) => {
4623
+ * console.log('My task executed with context:', ctx);
4624
+ * });
4625
+ *
4626
+ * Cadenza.run(task); // Executes the task once and destroys it after execution
4627
+ * Cadenza.run(task); // Does nothing, since the task is destroyed
4628
+ * ```
4629
+ *
4630
+ * Use destroy condition to conditionally destroy the task
4631
+ * ```ts
4632
+ * const task = Cadenza.createEphemeralTask(
4633
+ * 'My ephemeral task',
4634
+ * (ctx) => {
4635
+ * console.log('My task executed with context:', ctx);
4636
+ * },
4637
+ * 'My ephemeral task description',
4638
+ * {
4639
+ * once: false, // Should the task be executed only once? Default is true
4640
+ * destroyCondition: (ctx) => ctx.foo > 10, // Should the task be destroyed after execution? Default is undefined
4641
+ * },
4642
+ * );
4643
+ *
4644
+ * Cadenza.run(task, { foo: 5 }); // The task will not be destroyed and can still be executed
4645
+ * Cadenza.run(task, { foo: 10 }); // The task will not be destroyed and can still be executed
4646
+ * Cadenza.run(task, { foo: 20 }); // The task will be destroyed after execution and cannot be executed anymore
4647
+ * Cadenza.run(task, { foo: 30 }); // This will not be executed
4648
+ * ```
4649
+ *
4650
+ * A practical use case for ephemeral tasks is to resolve a promise upon some external event.
4651
+ * ```ts
4652
+ * const task = Cadenza.createTask('Confirm something', (ctx, emit) => {
4653
+ * return new Promise((resolve) => {
4654
+ * ctx.foo = uuid();
4655
+ *
4656
+ * Cadenza.createEphemeralTask(`Resolve promise of ${ctx.foo}`, (c) => {
4657
+ * console.log('My task executed with context:', ctx);
4658
+ * resolve(c);
4659
+ * }).doOn(`socket.confirmation_received:${ctx.foo}`);
4660
+ *
4661
+ * emit('this_domain.confirmation_requested', ctx);
4662
+ * });
4663
+ * });
4664
+ * ```
3490
4665
  */
3491
4666
  static createEphemeralTask(name, func, description, options = {}) {
3492
4667
  this.bootstrap();
@@ -3537,45 +4712,72 @@ var Cadenza = class {
3537
4712
  );
3538
4713
  }
3539
4714
  /**
3540
- * Creates an EphemeralMetaTask for meta-layer transients.
3541
- * @param name Identifier.
3542
- * @param func Function.
3543
- * @param description Optional.
3544
- * @param options Optional task options plus optional "once" (true) and "destroyCondition" (ctx => boolean).
3545
- * @returns The created EphemeralMetaTask.
4715
+ * Creates an ephemeral meta task with the specified name, function, description, and options.
4716
+ * See {@link createEphemeralTask} and {@link createMetaTask} for more details.
4717
+ *
4718
+ * @param {string} name - The name of the task to be created.
4719
+ * @param {TaskFunction} func - The function to be executed as part of the task.
4720
+ * @param {string} [description] - An optional description of the task.
4721
+ * @param {TaskOptions & EphemeralTaskOptions} [options={}] - Additional options for configuring the task.
4722
+ * @return {EphemeralTask} The created ephemeral meta task.
3546
4723
  */
3547
4724
  static createEphemeralMetaTask(name, func, description, options = {}) {
3548
4725
  options.isMeta = true;
3549
4726
  return this.createEphemeralTask(name, func, description, options);
3550
4727
  }
3551
4728
  /**
3552
- * Creates a GraphRoutine (named entry to starting tasks) and registers it.
3553
- * @param name Unique identifier.
3554
- * @param tasks Starting tasks (can be empty, but warns as no-op).
3555
- * @param description Optional.
3556
- * @returns The created GraphRoutine.
3557
- * @edge If tasks empty, routine is valid but inert.
4729
+ * Creates a new routine with the specified name, tasks, and an 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} for more information.
4733
+ *
4734
+ * @param {string} name - The name of the routine to create.
4735
+ * @param {Task[]} tasks - A list of tasks to include in the routine.
4736
+ * @param {string} [description=""] - An optional description for the routine.
4737
+ * @return {GraphRoutine} A new instance of the GraphRoutine containing the specified tasks and description.
4738
+ *
4739
+ * @example
4740
+ * ```ts
4741
+ * const task1 = Cadenza.createTask("Task 1", () => {});
4742
+ * const task2 = Cadenza.createTask("Task 2", () => {});
4743
+ *
4744
+ * task1.then(task2);
4745
+ *
4746
+ * const routine = Cadenza.createRoutine("Some routine", [task1]);
4747
+ *
4748
+ * Cadenza.run(routine);
4749
+ *
4750
+ * // Or, routines can be triggered by signals
4751
+ * routine.doOn("some.signal");
4752
+ *
4753
+ * Cadenza.emit("some.signal", {});
4754
+ * ```
3558
4755
  */
3559
4756
  static createRoutine(name, tasks, description = "") {
3560
4757
  this.bootstrap();
3561
4758
  this.validateName(name);
3562
4759
  if (tasks.length === 0) {
3563
- console.warn(`Routine '${name}' created with no starting tasks (no-op).`);
4760
+ throw new Error(`Routine '${name}' created with no starting tasks.`);
3564
4761
  }
3565
4762
  return new GraphRoutine(name, tasks, description);
3566
4763
  }
3567
4764
  /**
3568
- * Creates a MetaRoutine for meta-layer entry points.
3569
- * @param name Identifier.
3570
- * @param tasks Starting tasks.
3571
- * @param description Optional.
3572
- * @returns The created MetaRoutine.
4765
+ * Creates a meta routine with a given name, tasks, and optional description.
4766
+ * Routines are named entry points to starting tasks and are registered in the GraphRegistry.
4767
+ * They are used to group tasks together and provide a high-level structure for organizing and managing the execution of a set of tasks.
4768
+ * See {@link GraphRoutine} and {@link createRoutine} for more information.
4769
+ *
4770
+ * @param {string} name - The name of the routine to be created.
4771
+ * @param {Task[]} tasks - An array of tasks that the routine will consist of.
4772
+ * @param {string} [description=""] - An optional description for the routine.
4773
+ * @return {GraphRoutine} A new instance of the `GraphRoutine` representing the created routine.
4774
+ * @throws {Error} If no starting tasks are provided.
3573
4775
  */
3574
4776
  static createMetaRoutine(name, tasks, description = "") {
3575
4777
  this.bootstrap();
3576
4778
  this.validateName(name);
3577
4779
  if (tasks.length === 0) {
3578
- console.warn(`Routine '${name}' created with no starting tasks (no-op).`);
4780
+ throw new Error(`Routine '${name}' created with no starting tasks.`);
3579
4781
  }
3580
4782
  return new GraphRoutine(name, tasks, description, true);
3581
4783
  }