@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.mjs CHANGED
@@ -41,6 +41,7 @@ function formatTimestamp(timestamp) {
41
41
  }
42
42
 
43
43
  // src/engine/SignalBroker.ts
44
+ import { v4 as uuid } from "uuid";
44
45
  var SignalBroker = class _SignalBroker {
45
46
  // execId -> emitted signals
46
47
  constructor() {
@@ -51,10 +52,6 @@ var SignalBroker = class _SignalBroker {
51
52
  this.emitStacks = /* @__PURE__ */ new Map();
52
53
  this.addSignal("meta.signal_broker.added");
53
54
  }
54
- /**
55
- * Singleton instance for signal management.
56
- * @returns The broker instance.
57
- */
58
55
  static get instance() {
59
56
  if (!this.instance_) {
60
57
  this.instance_ = new _SignalBroker();
@@ -67,6 +64,15 @@ var SignalBroker = class _SignalBroker {
67
64
  setVerbose(value) {
68
65
  this.verbose = value;
69
66
  }
67
+ /**
68
+ * Validates the provided signal name string to ensure it adheres to specific formatting rules.
69
+ * Throws an error if any of the validation checks fail.
70
+ *
71
+ * @param {string} signalName - The signal name to be validated.
72
+ * @return {void} - Returns nothing if the signal name is valid.
73
+ * @throws {Error} - Throws an error if the signal name is longer than 100 characters, contains spaces,
74
+ * contains backslashes, or contains uppercase letters in restricted parts of the name.
75
+ */
70
76
  validateSignalName(signalName) {
71
77
  if (signalName.length > 100) {
72
78
  throw new Error(
@@ -96,6 +102,11 @@ var SignalBroker = class _SignalBroker {
96
102
  this.runner = runner;
97
103
  this.metaRunner = metaRunner;
98
104
  }
105
+ /**
106
+ * Initializes and sets up the various tasks for managing and processing signals.
107
+ *
108
+ * @return {void} This method does not return a value.
109
+ */
99
110
  init() {
100
111
  this.clearSignalsTask = Cadenza.createDebounceMetaTask(
101
112
  "Execute and clear queued signals",
@@ -160,11 +171,82 @@ var SignalBroker = class _SignalBroker {
160
171
  }
161
172
  }
162
173
  /**
163
- * Emits a signal and bubbles to matching wildcards/parents (e.g., 'a.b.action' triggers 'a.b.action', 'a.b.*', 'a.*').
164
- * @param signal The signal name.
165
- * @param context The payload.
166
- * @edge Fire-and-forget; guards against loops per execId (from context.__graphExecId).
167
- * @edge For distribution, SignalTask can prefix and proxy remote.
174
+ * Schedules a signal to be emitted after a specified delay or at an exact date and time.
175
+ *
176
+ * @param {string} signal - The name of the signal to be emitted.
177
+ * @param {AnyObject} context - The context to be passed along with the signal.
178
+ * @param {number} [timeoutMs=60000] - The delay in milliseconds before the signal is emitted. Defaults to 60,000 ms.
179
+ * @param {Date} [exactDateTime] - An exact date and time at which to emit the signal. If provided, this overrides the `timeoutMs`.
180
+ * @return {AbortController} An AbortController instance that can be used to cancel the scheduled signal emission.
181
+ */
182
+ schedule(signal, context, timeoutMs = 6e4, exactDateTime) {
183
+ let delay = timeoutMs;
184
+ if (exactDateTime != null) {
185
+ delay = exactDateTime.getTime() - Date.now();
186
+ }
187
+ delay = Math.max(0, timeoutMs);
188
+ const controller = new AbortController();
189
+ const { signal: signalController } = controller;
190
+ const tick = () => this.emit(signal, context);
191
+ const timerId = setTimeout(() => {
192
+ if (!signalController.aborted) tick();
193
+ }, delay);
194
+ signalController.addEventListener("abort", () => clearTimeout(timerId));
195
+ return controller;
196
+ }
197
+ /**
198
+ * Emits `signal` repeatedly with a fixed interval.
199
+ *
200
+ * @param signal
201
+ * @param context
202
+ * @param intervalMs
203
+ * @param leading If true, emits immediately (unless a startDateTime is given and we are before it).
204
+ * @param startDateTime Optional absolute Date when the *first* emission after `leading` should occur.
205
+ * @returns a handle with `clear()` to stop the loop.
206
+ */
207
+ throttle(signal, context, intervalMs = 6e4, leading = false, startDateTime) {
208
+ if (intervalMs <= 0) {
209
+ throw new Error("intervalMs must be a positive number");
210
+ }
211
+ const emit = () => this.emit(signal, context);
212
+ if (leading) {
213
+ const now = Date.now();
214
+ const start = startDateTime?.getTime();
215
+ if (!start || start <= now) {
216
+ emit();
217
+ }
218
+ }
219
+ let firstDelay = intervalMs;
220
+ if (startDateTime) {
221
+ let slot = startDateTime.getTime();
222
+ const now = Date.now();
223
+ while (slot < now) {
224
+ slot += intervalMs;
225
+ }
226
+ firstDelay = slot - now;
227
+ }
228
+ let timer = null;
229
+ let stopped = false;
230
+ const scheduleNext = () => {
231
+ if (stopped) return;
232
+ emit();
233
+ timer = setTimeout(scheduleNext, intervalMs);
234
+ };
235
+ timer = setTimeout(scheduleNext, firstDelay);
236
+ return {
237
+ clear() {
238
+ stopped = true;
239
+ if (timer !== null) clearTimeout(timer);
240
+ }
241
+ };
242
+ }
243
+ /**
244
+ * Emits a signal with the specified context, triggering any associated handlers for that signal.
245
+ *
246
+ * @param {string} signal - The name of the signal to emit.
247
+ * @param {AnyObject} [context={}] - An optional context object containing additional information or metadata
248
+ * associated with the signal. If the context includes a `__routineExecId`, it will be handled accordingly.
249
+ * @return {void} This method does not return a value.
168
250
  */
169
251
  emit(signal, context = {}) {
170
252
  const execId = context.__routineExecId || "global";
@@ -181,15 +263,56 @@ var SignalBroker = class _SignalBroker {
181
263
  if (stack.size === 0) this.emitStacks.delete(execId);
182
264
  }
183
265
  }
266
+ /**
267
+ * Executes a signal by emitting events, updating context, and invoking listeners.
268
+ * Creates a new execution trace if necessary and updates the context with relevant metadata.
269
+ * Handles specific, hierarchy-based, and wildcard signals.
270
+ *
271
+ * @param {string} signal - The signal name to be executed, potentially including namespaces or tags (e.g., "meta.*" or "signal:type").
272
+ * @param {AnyObject} context - An object containing relevant metadata and execution details used for handling the signal.
273
+ * @return {boolean} Returns true if any listeners were successfully executed, otherwise false.
274
+ */
184
275
  execute(signal, context) {
185
276
  const isMeta = signal.includes("meta.");
186
277
  const isSubMeta = signal.includes("sub_meta.") || context.__isSubMeta;
187
278
  const isMetric = context.__signalEmission?.isMetric;
188
279
  if (!isSubMeta && (!isMeta || this.debug)) {
280
+ const isNewTrace = !context.__signalEmission?.executionTraceId && !context.__metadata?.__executionTraceId && !context.__executionTraceId;
281
+ const executionTraceId = context.__metadata?.__executionTraceId ?? context.__executionTraceId ?? uuid();
282
+ if (isNewTrace) {
283
+ this.emit("sub_meta.signal_broker.new_trace", {
284
+ data: {
285
+ uuid: executionTraceId,
286
+ issuer_type: "service",
287
+ // TODO: Add issuer type
288
+ issuer_id: context.__metadata?.__issuerId ?? context.__issuerId ?? null,
289
+ issued_at: formatTimestamp(Date.now()),
290
+ intent: context.__metadata?.__intent ?? context.__intent ?? null,
291
+ context: {
292
+ id: uuid(),
293
+ context
294
+ },
295
+ is_meta: isMeta
296
+ },
297
+ metadata: {
298
+ __executionTraceId: executionTraceId
299
+ }
300
+ });
301
+ context.__metadata = {
302
+ ...context.__metadata,
303
+ __executionTraceId: executionTraceId
304
+ };
305
+ }
189
306
  const emittedAt = Date.now();
307
+ const signalParts = signal.split(":");
308
+ const signalName = signalParts[0];
309
+ const signalTag = signalParts.length > 1 ? signalParts[1] : null;
190
310
  context.__signalEmission = {
191
311
  ...context.__signalEmission ?? {},
192
- signalName: signal,
312
+ uuid: uuid(),
313
+ executionTraceId,
314
+ signalName,
315
+ signalTag,
193
316
  emittedAt: formatTimestamp(emittedAt),
194
317
  consumed: false,
195
318
  consumedBy: null,
@@ -217,6 +340,15 @@ var SignalBroker = class _SignalBroker {
217
340
  }
218
341
  return executed;
219
342
  }
343
+ /**
344
+ * Executes the tasks associated with a given signal and context.
345
+ * It processes both normal and meta tasks depending on the signal type
346
+ * and the availability of the appropriate runner.
347
+ *
348
+ * @param {string} signal - The signal identifier that determines which tasks to execute.
349
+ * @param {AnyObject} context - The context object passed to the task execution function.
350
+ * @return {boolean} - Returns true if tasks were executed; otherwise, false.
351
+ */
220
352
  executeListener(signal, context) {
221
353
  const obs = this.signalObservers.get(signal);
222
354
  if (!obs || obs.tasks.size === 0) {
@@ -242,6 +374,15 @@ var SignalBroker = class _SignalBroker {
242
374
  }
243
375
  return false;
244
376
  }
377
+ /**
378
+ * Adds a signal to the signalObservers for tracking and execution.
379
+ * Performs validation on the signal name and emits a meta signal event when added.
380
+ * If the signal contains a namespace (denoted by a colon ":"), its base signal is
381
+ * also added if it doesn't already exist.
382
+ *
383
+ * @param {string} signal - The name of the signal to be added.
384
+ * @return {void} This method does not return any value.
385
+ */
245
386
  addSignal(signal) {
246
387
  let _signal = signal;
247
388
  if (!this.signalObservers.has(_signal)) {
@@ -267,7 +408,6 @@ var SignalBroker = class _SignalBroker {
267
408
  this.emit("meta.signal_broker.added", { __signalName: _signal });
268
409
  }
269
410
  }
270
- // TODO schedule signals
271
411
  /**
272
412
  * Lists all observed signals.
273
413
  * @returns Array of signals.
@@ -282,10 +422,10 @@ var SignalBroker = class _SignalBroker {
282
422
  };
283
423
 
284
424
  // src/engine/GraphRunner.ts
285
- import { v4 as uuid4 } from "uuid";
425
+ import { v4 as uuid5 } from "uuid";
286
426
 
287
427
  // src/engine/GraphRun.ts
288
- import { v4 as uuid } from "uuid";
428
+ import { v4 as uuid2 } from "uuid";
289
429
 
290
430
  // src/utils/ColorRandomizer.ts
291
431
  var ColorRandomizer = class {
@@ -476,7 +616,7 @@ var VueFlowExporter = class {
476
616
  // src/engine/GraphRun.ts
477
617
  var GraphRun = class {
478
618
  constructor(strategy) {
479
- this.id = uuid();
619
+ this.id = uuid2();
480
620
  this.strategy = strategy;
481
621
  this.strategy.setRunInstance(this);
482
622
  this.exporter = new VueFlowExporter();
@@ -530,10 +670,10 @@ var GraphRun = class {
530
670
  };
531
671
 
532
672
  // src/graph/execution/GraphNode.ts
533
- import { v4 as uuid3 } from "uuid";
673
+ import { v4 as uuid4 } from "uuid";
534
674
 
535
675
  // src/graph/context/GraphContext.ts
536
- import { v4 as uuid2 } from "uuid";
676
+ import { v4 as uuid3 } from "uuid";
537
677
  var GraphContext = class _GraphContext {
538
678
  // __keys, frozen
539
679
  constructor(context) {
@@ -547,7 +687,7 @@ var GraphContext = class _GraphContext {
547
687
  this.metadata = Object.fromEntries(
548
688
  Object.entries(this.fullContext).filter(([key]) => key.startsWith("__"))
549
689
  );
550
- this.id = uuid2();
690
+ this.id = uuid3();
551
691
  }
552
692
  /**
553
693
  * Gets frozen user data (read-only, no clone).
@@ -556,6 +696,11 @@ var GraphContext = class _GraphContext {
556
696
  getContext() {
557
697
  return this.userData;
558
698
  }
699
+ /**
700
+ * Clones the current user context data and returns a deep-cloned copy of it.
701
+ *
702
+ * @return {AnyObject} A deep-cloned copy of the user context data.
703
+ */
559
704
  getClonedContext() {
560
705
  return deepCloneFilter(this.userData);
561
706
  }
@@ -566,6 +711,11 @@ var GraphContext = class _GraphContext {
566
711
  getFullContext() {
567
712
  return this.fullContext;
568
713
  }
714
+ /**
715
+ * Creates and returns a deep-cloned version of the fullContext object.
716
+ *
717
+ * @return {AnyObject} A deep copy of the fullContext instance, preserving all nested structures and data.
718
+ */
569
719
  getClonedFullContext() {
570
720
  return deepCloneFilter(this.fullContext);
571
721
  }
@@ -592,10 +742,11 @@ var GraphContext = class _GraphContext {
592
742
  return new _GraphContext(context);
593
743
  }
594
744
  /**
595
- * Combines with another for uniques (joins userData).
596
- * @param otherContext The other.
597
- * @returns New combined GraphContext.
598
- * @edge Appends other.userData to joinedContexts in userData.
745
+ * Combines the current GraphContext with another GraphContext, merging their user data
746
+ * and full context into a new GraphContext instance.
747
+ *
748
+ * @param {GraphContext} otherContext - The other GraphContext to combine with the current one.
749
+ * @return {GraphContext} A new GraphContext instance containing merged data from both contexts.
599
750
  */
600
751
  combine(otherContext) {
601
752
  const newUser = { ...this.userData };
@@ -713,7 +864,7 @@ var GraphNode = class _GraphNode extends SignalEmitter {
713
864
  this.destroyed = false;
714
865
  this.debug = false;
715
866
  this.verbose = false;
716
- this.id = uuid3();
867
+ this.id = uuid4();
717
868
  this.task = task;
718
869
  this.context = context;
719
870
  this.retryCount = task.retryCount;
@@ -723,6 +874,8 @@ var GraphNode = class _GraphNode extends SignalEmitter {
723
874
  this.splitGroupId = routineExecId;
724
875
  this.debug = debug;
725
876
  this.verbose = verbose;
877
+ const ctx = context.getMetadata();
878
+ this.executionTraceId = ctx.__executionTraceId ?? ctx.__metadata?.__executionTraceId;
726
879
  if (!this.task || !this.task.validateInput) {
727
880
  console.log("task not found", this.task, this.context);
728
881
  }
@@ -748,15 +901,40 @@ var GraphNode = class _GraphNode extends SignalEmitter {
748
901
  graphDone() {
749
902
  return this.graphComplete;
750
903
  }
904
+ /**
905
+ * Compares the current GraphNode instance with another GraphNode to determine if they are considered equal.
906
+ *
907
+ * @param {GraphNode} node - The GraphNode object to compare with the current instance.
908
+ * @return {boolean} Returns true if the nodes share the same task, context, and belong to the same graph; otherwise, false.
909
+ */
751
910
  isEqualTo(node) {
752
911
  return this.sharesTaskWith(node) && this.sharesContextWith(node) && this.isPartOfSameGraph(node);
753
912
  }
913
+ /**
914
+ * Determines if the given node is part of the same graph as the current node.
915
+ *
916
+ * @param {GraphNode} node - The node to compare with the current node.
917
+ * @return {boolean} Returns true if the provided node is part of the same graph
918
+ * (i.e., has the same routineExecId), otherwise false.
919
+ */
754
920
  isPartOfSameGraph(node) {
755
921
  return this.routineExecId === node.routineExecId;
756
922
  }
923
+ /**
924
+ * Determines whether the current instance shares a task with the provided node.
925
+ *
926
+ * @param {GraphNode} node - The graph node to compare with the current instance.
927
+ * @return {boolean} Returns true if the task names of both nodes match, otherwise false.
928
+ */
757
929
  sharesTaskWith(node) {
758
930
  return this.task.name === node.task.name;
759
931
  }
932
+ /**
933
+ * Determines whether the current node shares the same context as the specified node.
934
+ *
935
+ * @param {GraphNode} node - The graph node to compare with the current node's context.
936
+ * @return {boolean} True if both nodes share the same context; otherwise, false.
937
+ */
760
938
  sharesContextWith(node) {
761
939
  return this.context.id === node.context.id;
762
940
  }
@@ -766,9 +944,26 @@ var GraphNode = class _GraphNode extends SignalEmitter {
766
944
  getConcurrency() {
767
945
  return this.task.concurrency;
768
946
  }
947
+ /**
948
+ * Retrieves the tag associated with the current task and context.
949
+ *
950
+ * @return {string} The tag retrieved from the task within the given context.
951
+ */
769
952
  getTag() {
770
953
  return this.task.getTag(this.context);
771
954
  }
955
+ /**
956
+ * Schedules the current node/task on the specified graph layer if applicable.
957
+ *
958
+ * This method assesses whether the current node/task should be scheduled
959
+ * on the given graph layer. It ensures that tasks are only scheduled
960
+ * under certain conditions, such as checking if the task shares
961
+ * execution contexts or dependencies with other nodes, and handles
962
+ * various metadata emissions and context updates during the scheduling process.
963
+ *
964
+ * @param {GraphLayer} layer - The graph layer on which the current task should be scheduled.
965
+ * @returns {void} Does not return a value.
966
+ */
772
967
  scheduleOn(layer) {
773
968
  let shouldSchedule = true;
774
969
  const nodes = layer.getNodesByRoutineExecId(this.routineExecId);
@@ -792,7 +987,7 @@ var GraphNode = class _GraphNode extends SignalEmitter {
792
987
  data: {
793
988
  uuid: this.id,
794
989
  routineExecutionId: this.routineExecId,
795
- executionTraceId: context.__executionTraceId ?? context.__metadata?.__executionTraceId,
990
+ executionTraceId: this.executionTraceId,
796
991
  context: this.previousNodes.length === 0 ? this.context.id : this.context.export(),
797
992
  taskName: this.task.name,
798
993
  taskVersion: this.task.version,
@@ -836,10 +1031,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
836
1031
  if (context.__signalEmission?.consumed === false && (!this.isMeta() || this.debug)) {
837
1032
  this.emitMetricsWithMetadata("meta.node.consumed_signal", {
838
1033
  data: {
1034
+ signalEmissionId: context.__signalEmission.uuid,
839
1035
  signalName: context.__signalEmission.signalName,
1036
+ signalTag: context.__signalEmission.signalTag,
840
1037
  taskName: this.task.name,
841
1038
  taskVersion: this.task.version,
842
1039
  taskExecutionId: this.id,
1040
+ routineExecutionId: this.routineExecId,
1041
+ executionTraceId: this.executionTraceId,
843
1042
  consumedAt: formatTimestamp(scheduledAt)
844
1043
  }
845
1044
  });
@@ -848,6 +1047,18 @@ var GraphNode = class _GraphNode extends SignalEmitter {
848
1047
  }
849
1048
  }
850
1049
  }
1050
+ /**
1051
+ * Starts the execution process by initializing the execution start timestamp,
1052
+ * emitting relevant metadata, and logging debug information if applicable.
1053
+ *
1054
+ * The method performs the following actions:
1055
+ * 1. Sets the execution start timestamp if it's not already initialized.
1056
+ * 2. Emits metrics with metadata about the routine execution starting, including additional data if there are no previous nodes.
1057
+ * 3. Optionally logs debug or verbose information based on the current settings.
1058
+ * 4. Emits additional metrics to indicate that the execution has started.
1059
+ *
1060
+ * @return {number} The timestamp indicating when the execution started.
1061
+ */
851
1062
  start() {
852
1063
  if (this.executionStart === 0) {
853
1064
  this.executionStart = Date.now();
@@ -873,6 +1084,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
873
1084
  });
874
1085
  return this.executionStart;
875
1086
  }
1087
+ /**
1088
+ * Marks the end of an execution process, performs necessary cleanup, emits
1089
+ * metrics with associated metadata, and signals the completion of execution.
1090
+ * Also handles specific cases when the graph completes.
1091
+ *
1092
+ * @return {number} The timestamp corresponding to the end of execution. If execution
1093
+ * was not started, it returns 0.
1094
+ */
876
1095
  end() {
877
1096
  if (this.executionStart === 0) {
878
1097
  return 0;
@@ -925,6 +1144,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
925
1144
  }
926
1145
  return end;
927
1146
  }
1147
+ /**
1148
+ * Executes the main logic of the task, including input validation, processing, and post-processing.
1149
+ * Handles both synchronous and asynchronous workflows.
1150
+ *
1151
+ * @return {Array|Promise|undefined} Returns the next nodes to process if available.
1152
+ * If asynchronous processing is required, it returns a Promise that resolves to the next nodes.
1153
+ * Returns undefined in case of an error during input validation or preconditions that prevent processing.
1154
+ */
928
1155
  execute() {
929
1156
  if (!this.divided && !this.processing) {
930
1157
  this.processing = true;
@@ -948,6 +1175,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
948
1175
  }
949
1176
  return this.nextNodes;
950
1177
  }
1178
+ /**
1179
+ * Executes an asynchronous workflow that processes a result and retries on errors.
1180
+ * The method handles different result states, checks for error properties, and invokes
1181
+ * error handling when necessary.
1182
+ *
1183
+ * @return {Promise<void>} A promise that resolves when the operation completes successfully,
1184
+ * or rejects if an unhandled error occurs.
1185
+ */
951
1186
  async workAsync() {
952
1187
  try {
953
1188
  this.result = await this.result;
@@ -964,6 +1199,12 @@ var GraphNode = class _GraphNode extends SignalEmitter {
964
1199
  }
965
1200
  }
966
1201
  }
1202
+ /**
1203
+ * Executes an asynchronous operation, processes the result, and determines the next nodes to execute.
1204
+ * This method will manage asynchronous work, handle post-processing of results, and ensure proper handling of both synchronous and asynchronous next node configurations.
1205
+ *
1206
+ * @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.
1207
+ */
967
1208
  async executeAsync() {
968
1209
  await this.workAsync();
969
1210
  const nextNodes = this.postProcess();
@@ -973,6 +1214,16 @@ var GraphNode = class _GraphNode extends SignalEmitter {
973
1214
  this.nextNodes = nextNodes;
974
1215
  return this.nextNodes;
975
1216
  }
1217
+ /**
1218
+ * Executes the task associated with the current instance, using the given context,
1219
+ * progress callback, and metadata. If the task fails or an error occurs, it attempts
1220
+ * to retry the execution. If the retry is not successful, it propagates the error and
1221
+ * returns the result.
1222
+ *
1223
+ * @return {TaskResult | Promise<TaskResult>} The result of the task execution, or a
1224
+ * promise that resolves to the task result. This includes handling for retries on
1225
+ * failure and error propagation.
1226
+ */
976
1227
  work() {
977
1228
  try {
978
1229
  const result = this.task.execute(
@@ -996,39 +1247,67 @@ var GraphNode = class _GraphNode extends SignalEmitter {
996
1247
  });
997
1248
  }
998
1249
  }
1250
+ /**
1251
+ * Emits a signal along with its associated metadata. The metadata includes
1252
+ * task-specific information such as task name, version, execution ID, and
1253
+ * additional context metadata like routine execution ID and execution trace ID.
1254
+ * This method is designed to enrich emitted signals with relevant details
1255
+ * before broadcasting them.
1256
+ *
1257
+ * @param {string} signal - The name of the signal to be emitted.
1258
+ * @param {AnyObject} data - The data object to be sent along with the signal. Metadata
1259
+ * will be injected into this object before being emitted.
1260
+ * @return {void} No return value.
1261
+ */
999
1262
  emitWithMetadata(signal, data) {
1000
1263
  if (!this.task?.isHidden) {
1001
1264
  data.__signalEmission = {
1002
1265
  taskName: this.task.name,
1003
1266
  taskVersion: this.task.version,
1004
- taskExecutionId: this.id
1267
+ taskExecutionId: this.id,
1268
+ routineExecutionId: this.routineExecId,
1269
+ executionTraceId: this.executionTraceId,
1270
+ isMetric: false
1005
1271
  };
1006
- const context = this.context.getMetadata();
1007
1272
  data.__metadata = {
1008
1273
  ...data.__metadata,
1009
1274
  __routineExecId: this.routineExecId,
1010
- __executionTraceId: context.__metadata?.__executionTraceId ?? context.__executionTraceId
1275
+ __executionTraceId: this.executionTraceId
1011
1276
  };
1012
1277
  }
1013
1278
  this.emit(signal, data);
1014
1279
  }
1280
+ /**
1281
+ * Emits metrics with additional metadata describing the task execution and context.
1282
+ *
1283
+ * @param {string} signal - The signal name being emitted.
1284
+ * @param {AnyObject} data - The data associated with the signal emission, enriched with metadata.
1285
+ * @return {void} Emits the signal with enriched data and does not return a value.
1286
+ */
1015
1287
  emitMetricsWithMetadata(signal, data) {
1016
1288
  if (!this.task?.isHidden) {
1017
1289
  data.__signalEmission = {
1018
1290
  taskName: this.task.name,
1019
1291
  taskVersion: this.task.version,
1020
1292
  taskExecutionId: this.id,
1293
+ routineExecutionId: this.routineExecId,
1294
+ executionTraceId: this.executionTraceId,
1021
1295
  isMetric: true
1022
1296
  };
1023
- const context = this.context.getMetadata();
1024
1297
  data.__metadata = {
1025
1298
  ...data.__metadata,
1026
1299
  __routineExecId: this.routineExecId,
1027
- __executionTraceId: context.__metadata?.__executionTraceId ?? context.__executionTraceId
1300
+ __executionTraceId: this.executionTraceId
1028
1301
  };
1029
1302
  }
1030
1303
  this.emitMetrics(signal, data);
1031
1304
  }
1305
+ /**
1306
+ * Updates the progress of a task and emits metrics with associated metadata.
1307
+ *
1308
+ * @param {number} progress - A number representing the progress value, which will be clamped between 0 and 1.
1309
+ * @return {void} This method does not return a value.
1310
+ */
1032
1311
  onProgress(progress) {
1033
1312
  progress = Math.min(Math.max(0, progress), 1);
1034
1313
  this.emitMetricsWithMetadata("meta.node.progress", {
@@ -1051,6 +1330,18 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1051
1330
  }
1052
1331
  );
1053
1332
  }
1333
+ /**
1334
+ * Processes the result of the current operation, validates it, and determines the next set of nodes.
1335
+ *
1336
+ * This method ensures that results of certain types such as strings or arrays
1337
+ * are flagged as errors. It divides the current context into subsequent nodes
1338
+ * for further processing. If the division returns a promise, it delegates the
1339
+ * processing to `postProcessAsync`. For synchronous division, it sets the
1340
+ * `nextNodes` and finalizes the operation.
1341
+ *
1342
+ * @return {(Array|undefined)} Returns an array of next nodes for further processing,
1343
+ * or undefined if no further processing is required.
1344
+ */
1054
1345
  postProcess() {
1055
1346
  if (typeof this.result === "string") {
1056
1347
  this.onError(
@@ -1068,11 +1359,23 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1068
1359
  this.finalize();
1069
1360
  return this.nextNodes;
1070
1361
  }
1362
+ /**
1363
+ * Asynchronously processes and finalizes the provided graph nodes.
1364
+ *
1365
+ * @param {Promise<GraphNode[]>} nextNodes A promise that resolves to an array of graph nodes to be processed.
1366
+ * @return {Promise<GraphNode[]>} A promise that resolves to the processed array of graph nodes.
1367
+ */
1071
1368
  async postProcessAsync(nextNodes) {
1072
1369
  this.nextNodes = await nextNodes;
1073
1370
  this.finalize();
1074
1371
  return this.nextNodes;
1075
1372
  }
1373
+ /**
1374
+ * Finalizes the current task execution by determining if the task is complete, handles any errors or failures,
1375
+ * emits relevant signals based on the task outcomes, and ensures proper end of the task lifecycle.
1376
+ *
1377
+ * @return {void} Does not return a value.
1378
+ */
1076
1379
  finalize() {
1077
1380
  if (this.nextNodes.length === 0) {
1078
1381
  this.completeSubgraph();
@@ -1088,6 +1391,13 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1088
1391
  }
1089
1392
  this.end();
1090
1393
  }
1394
+ /**
1395
+ * Handles an error event, processes the error, and updates the state accordingly.
1396
+ *
1397
+ * @param {unknown} error - The error object or message that occurred.
1398
+ * @param {AnyObject} [errorData={}] - Additional error data to include in the result.
1399
+ * @return {void} This method does not return any value.
1400
+ */
1091
1401
  onError(error, errorData = {}) {
1092
1402
  this.result = {
1093
1403
  ...this.context.getFullContext(),
@@ -1101,6 +1411,12 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1101
1411
  this.migrate(this.result);
1102
1412
  this.errored = true;
1103
1413
  }
1414
+ /**
1415
+ * 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.
1416
+ *
1417
+ * @param {any} [prevResult] - The result from a previous attempt, if any, to return when no retries are performed.
1418
+ * @return {Promise<TaskResult>} - A promise that resolves with the result of the retried task or the previous result if no retries occur.
1419
+ */
1104
1420
  async retry(prevResult) {
1105
1421
  if (this.retryCount === 0) {
1106
1422
  return prevResult;
@@ -1108,6 +1424,13 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1108
1424
  await this.delayRetry();
1109
1425
  return this.work();
1110
1426
  }
1427
+ /**
1428
+ * Retries an asynchronous operation and returns its result.
1429
+ * If the retry count is zero, the method immediately returns the provided previous result.
1430
+ *
1431
+ * @param {any} [prevResult] - The optional result from a previous operation attempt, if applicable.
1432
+ * @return {Promise<TaskResult>} A promise that resolves to the result of the retried operation.
1433
+ */
1111
1434
  async retryAsync(prevResult) {
1112
1435
  if (this.retryCount === 0) {
1113
1436
  return prevResult;
@@ -1125,6 +1448,15 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1125
1448
  this.retryDelay = this.task.retryDelayMax;
1126
1449
  }
1127
1450
  }
1451
+ /**
1452
+ * Processes the result of a task by generating new nodes based on the task output.
1453
+ * The method handles synchronous and asynchronous generators, validates task output,
1454
+ * and creates new nodes accordingly. If errors occur, the method attempts to handle them
1455
+ * by generating alternative task nodes.
1456
+ *
1457
+ * @return {GraphNode[] | Promise<GraphNode[]>} Returns an array of generated GraphNode objects
1458
+ * (synchronously or wrapped in a Promise) based on the task result, or propagates errors if validation fails.
1459
+ */
1128
1460
  divide() {
1129
1461
  const newNodes = [];
1130
1462
  if (this.result?.next && typeof this.result.next === "function") {
@@ -1163,7 +1495,7 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1163
1495
  if (this.errored) {
1164
1496
  newNodes.push(
1165
1497
  ...this.task.mapNext(
1166
- (t) => this.clone().split(uuid3()).differentiate(t).migrate({ ...this.result }),
1498
+ (t) => this.clone().split(uuid4()).differentiate(t).migrate({ ...this.result }),
1167
1499
  true
1168
1500
  )
1169
1501
  );
@@ -1176,6 +1508,13 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1176
1508
  });
1177
1509
  return newNodes;
1178
1510
  }
1511
+ /**
1512
+ * Processes an asynchronous iterator result, validates its output, and generates new graph nodes accordingly.
1513
+ * Additionally, continues to process and validate results from an asynchronous generator.
1514
+ *
1515
+ * @param {Promise<IteratorResult<any>>} current - A promise resolving to the current step result from an asynchronous iterator.
1516
+ * @return {Promise<GraphNode[]>} A promise resolving to an array of generated GraphNode objects based on validated outputs.
1517
+ */
1179
1518
  async divideAsync(current) {
1180
1519
  const nextNodes = [];
1181
1520
  const _current = await current;
@@ -1198,8 +1537,14 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1198
1537
  this.divided = true;
1199
1538
  return nextNodes;
1200
1539
  }
1540
+ /**
1541
+ * Generates new nodes based on the provided result and task configuration.
1542
+ *
1543
+ * @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.
1544
+ * @return {GraphNode[]} An array of newly generated graph nodes configured based on the task and context.
1545
+ */
1201
1546
  generateNewNodes(result) {
1202
- const groupId = uuid3();
1547
+ const groupId = uuid4();
1203
1548
  const newNodes = [];
1204
1549
  if (typeof result !== "boolean") {
1205
1550
  const failed = result.failed !== void 0 && result.failed || result.error !== void 0;
@@ -1240,6 +1585,12 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1240
1585
  }
1241
1586
  return newNodes;
1242
1587
  }
1588
+ /**
1589
+ * Executes the differentiation process based on a given task and updates the instance properties accordingly.
1590
+ *
1591
+ * @param {Task} task - The task object containing information such as retry count, retry delay, and metadata status.
1592
+ * @return {GraphNode} The updated instance after processing the task.
1593
+ */
1243
1594
  differentiate(task) {
1244
1595
  this.task = task;
1245
1596
  this.retryCount = task.retryCount;
@@ -1247,14 +1598,32 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1247
1598
  this.silent = task.isMeta && !this.debug || task.isSubMeta || this.context?.getMetadata()?.__isSubMeta;
1248
1599
  return this;
1249
1600
  }
1601
+ /**
1602
+ * Migrates the current instance to a new context and returns the updated instance.
1603
+ *
1604
+ * @param {any} ctx - The context data to be used for migration.
1605
+ * @return {GraphNode} The updated instance after migration.
1606
+ */
1250
1607
  migrate(ctx) {
1251
1608
  this.context = new GraphContext(ctx);
1252
1609
  return this;
1253
1610
  }
1611
+ /**
1612
+ * Splits the current node into a new group identified by the provided ID.
1613
+ *
1614
+ * @param {string} id - The unique identifier for the new split group.
1615
+ * @return {GraphNode} The current instance of the GraphNode with the updated split group ID.
1616
+ */
1254
1617
  split(id) {
1255
1618
  this.splitGroupId = id;
1256
1619
  return this;
1257
1620
  }
1621
+ /**
1622
+ * Creates a new instance of the GraphNode with the current node's properties.
1623
+ * This method allows for duplicating the existing graph node.
1624
+ *
1625
+ * @return {GraphNode} A new instance of GraphNode that is a copy of the current node.
1626
+ */
1258
1627
  clone() {
1259
1628
  return new _GraphNode(
1260
1629
  this.task,
@@ -1265,6 +1634,13 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1265
1634
  this.verbose
1266
1635
  );
1267
1636
  }
1637
+ /**
1638
+ * Consumes the given graph node by combining contexts, merging previous nodes,
1639
+ * and performing associated operations on the provided node.
1640
+ *
1641
+ * @param {GraphNode} node - The graph node to be consumed.
1642
+ * @return {void} This method does not return a value.
1643
+ */
1268
1644
  consume(node) {
1269
1645
  this.context = this.context.combine(node.context);
1270
1646
  this.previousNodes = this.previousNodes.concat(node.previousNodes);
@@ -1272,9 +1648,22 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1272
1648
  node.changeIdentity(this.id);
1273
1649
  node.destroy();
1274
1650
  }
1651
+ /**
1652
+ * Changes the identity of the current instance by updating the `id` property.
1653
+ *
1654
+ * @param {string} id - The new identity value to be assigned.
1655
+ * @return {void} Does not return a value.
1656
+ */
1275
1657
  changeIdentity(id) {
1276
1658
  this.id = id;
1277
1659
  }
1660
+ /**
1661
+ * Completes the subgraph for the current node and recursively for its previous nodes
1662
+ * once all next nodes have their subgraphs marked as done. If there are no previous nodes,
1663
+ * it completes the entire graph.
1664
+ *
1665
+ * @return {void} Does not return a value.
1666
+ */
1278
1667
  completeSubgraph() {
1279
1668
  for (const node of this.nextNodes) {
1280
1669
  if (!node.subgraphDone()) {
@@ -1288,10 +1677,22 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1288
1677
  }
1289
1678
  this.previousNodes.forEach((n) => n.completeSubgraph());
1290
1679
  }
1680
+ /**
1681
+ * Completes the current graph by setting a flag indicating the graph has been completed
1682
+ * and recursively completes all subsequent nodes in the graph.
1683
+ *
1684
+ * @return {void} Does not return a value.
1685
+ */
1291
1686
  completeGraph() {
1292
1687
  this.graphComplete = true;
1293
1688
  this.nextNodes.forEach((n) => n.completeGraph());
1294
1689
  }
1690
+ /**
1691
+ * Destroys the current instance by releasing resources, breaking references,
1692
+ * and resetting properties to ensure proper cleanup.
1693
+ *
1694
+ * @return {void} No return value.
1695
+ */
1295
1696
  destroy() {
1296
1697
  this.context = null;
1297
1698
  this.task = null;
@@ -1304,15 +1705,40 @@ var GraphNode = class _GraphNode extends SignalEmitter {
1304
1705
  this.layer = void 0;
1305
1706
  this.destroyed = true;
1306
1707
  }
1708
+ /**
1709
+ * Retrieves an iterator for traversing through the graph nodes.
1710
+ *
1711
+ * @return {GraphNodeIterator} An iterator instance specific to this graph node.
1712
+ */
1307
1713
  getIterator() {
1308
1714
  return new GraphNodeIterator(this);
1309
1715
  }
1716
+ /**
1717
+ * Applies a callback function to each node in the `nextNodes` array and returns
1718
+ * the resulting array from the map operation.
1719
+ *
1720
+ * @param {function} callback - A function to execute on each `GraphNode` in the `nextNodes` array.
1721
+ * The function receives a `GraphNode` as its argument.
1722
+ * @return {Array} The resulting array after applying the callback function to each node in `nextNodes`.
1723
+ */
1310
1724
  mapNext(callback) {
1311
1725
  return this.nextNodes.map(callback);
1312
1726
  }
1727
+ /**
1728
+ * Accepts a visitor object and calls its visitNode method with the current instance.
1729
+ *
1730
+ * @param {GraphVisitor} visitor - The visitor instance implementing the GraphVisitor interface.
1731
+ * @return {void} This method does not return a value.
1732
+ */
1313
1733
  accept(visitor) {
1314
1734
  visitor.visitNode(this);
1315
1735
  }
1736
+ /**
1737
+ * Exports the current object's state and returns it in a serialized format.
1738
+ * The exported object contains metadata, task details, context information, execution times, node relationships, routine execution status, and other state information.
1739
+ *
1740
+ * @return {Object} An object representing the current state.
1741
+ */
1316
1742
  export() {
1317
1743
  return {
1318
1744
  __id: this.id,
@@ -1410,9 +1836,12 @@ var GraphRoutine = class extends SignalEmitter {
1410
1836
  });
1411
1837
  }
1412
1838
  /**
1413
- * Applies callback to starting tasks.
1414
- * @param callBack The callback.
1415
- * @returns Promise if async.
1839
+ * Iterates over each task in the `tasks` collection and applies the provided callback function.
1840
+ * If the callback returns a Promise, resolves all Promises concurrently.
1841
+ *
1842
+ * @param {function} callBack - A function to be executed on each task from the `tasks` collection.
1843
+ * The callback receives the current task as its argument.
1844
+ * @return {Promise<void>} A Promise that resolves once all callback executions, including asynchronous ones, are complete.
1416
1845
  */
1417
1846
  async forEachTask(callBack) {
1418
1847
  const promises = [];
@@ -1431,10 +1860,10 @@ var GraphRoutine = class extends SignalEmitter {
1431
1860
  this.emit("meta.routine.global_version_set", { version: this.version });
1432
1861
  }
1433
1862
  /**
1434
- * Subscribes to signals (chainable).
1435
- * @param signals The signal names.
1436
- * @returns This for chaining.
1437
- * @edge Duplicates ignored; assumes broker.observe binds this as handler.
1863
+ * Subscribes the current instance to the specified signals, enabling it to observe them.
1864
+ *
1865
+ * @param {...string} signals - The names of the signals to observe.
1866
+ * @return {this} Returns the instance to allow for method chaining.
1438
1867
  */
1439
1868
  doOn(...signals) {
1440
1869
  signals.forEach((signal) => {
@@ -1445,8 +1874,11 @@ var GraphRoutine = class extends SignalEmitter {
1445
1874
  return this;
1446
1875
  }
1447
1876
  /**
1448
- * Unsubscribes from all observed signals.
1449
- * @returns This for chaining.
1877
+ * Unsubscribes from all observed signals and clears the internal collection
1878
+ * of observed signals. This ensures that the instance is no longer listening
1879
+ * or reacting to any previously subscribed signals.
1880
+ *
1881
+ * @return {this} Returns the current instance for chaining purposes.
1450
1882
  */
1451
1883
  unsubscribeAll() {
1452
1884
  this.observedSignals.forEach(
@@ -1456,10 +1888,10 @@ var GraphRoutine = class extends SignalEmitter {
1456
1888
  return this;
1457
1889
  }
1458
1890
  /**
1459
- * Unsubscribes from specific signals.
1460
- * @param signals The signals.
1461
- * @returns This for chaining.
1462
- * @edge No-op if not subscribed.
1891
+ * Unsubscribes the current instance from the specified signals.
1892
+ *
1893
+ * @param {...string} signals - The signals to unsubscribe from.
1894
+ * @return {this} The current instance for method chaining.
1463
1895
  */
1464
1896
  unsubscribe(...signals) {
1465
1897
  signals.forEach((signal) => {
@@ -1471,7 +1903,12 @@ var GraphRoutine = class extends SignalEmitter {
1471
1903
  return this;
1472
1904
  }
1473
1905
  /**
1474
- * Destroys the routine.
1906
+ * Cleans up resources and emits an event indicating the destruction of the routine.
1907
+ *
1908
+ * This method unsubscribes from all events, clears the tasks list,
1909
+ * and emits a "meta.routine.destroyed" event with details of the destruction.
1910
+ *
1911
+ * @return {void}
1475
1912
  */
1476
1913
  destroy() {
1477
1914
  this.unsubscribeAll();
@@ -1517,27 +1954,27 @@ var TaskIterator = class {
1517
1954
  // src/graph/definition/Task.ts
1518
1955
  var Task = class extends SignalEmitter {
1519
1956
  /**
1520
- * Constructs a Task (static definition).
1521
- * @param name Name.
1522
- * @param task Function.
1523
- * @param description Description.
1524
- * @param concurrency Limit.
1525
- * @param timeout ms.
1526
- * @param register Register via signal (default true).
1527
- * @param isUnique
1528
- * @param isMeta
1529
- * @param isSubMeta
1530
- * @param isHidden
1531
- * @param getTagCallback
1532
- * @param inputSchema
1533
- * @param validateInputContext
1534
- * @param outputSchema
1535
- * @param validateOutputContext
1536
- * @param retryCount
1537
- * @param retryDelay
1538
- * @param retryDelayMax
1539
- * @param retryDelayFactor
1540
- * @edge Emits 'meta.task.created' with { __task: this } for seed.
1957
+ * Constructs an instance of the task with the specified properties and configuration options.
1958
+ *
1959
+ * @param {string} name - The name of the task.
1960
+ * @param {TaskFunction} task - The function that represents the task logic.
1961
+ * @param {string} [description=""] - A description of the task.
1962
+ * @param {number} [concurrency=0] - The number of concurrent executions allowed for the task.
1963
+ * @param {number} [timeout=0] - The maximum execution time for the task in milliseconds.
1964
+ * @param {boolean} [register=true] - Indicates if the task should be registered or not.
1965
+ * @param {boolean} [isUnique=false] - Specifies if the task should only allow one instance to exist at any time.
1966
+ * @param {boolean} [isMeta=false] - Indicates if the task is a meta-task.
1967
+ * @param {boolean} [isSubMeta=false] - Indicates if the task is a sub-meta-task.
1968
+ * @param {boolean} [isHidden=false] - Determines if the task is hidden and not exposed publicly.
1969
+ * @param {ThrottleTagGetter} [getTagCallback=undefined] - A callback to generate a throttle tag for the task.
1970
+ * @param {SchemaDefinition} [inputSchema=undefined] - The input schema for validating the task's input context.
1971
+ * @param {boolean} [validateInputContext=false] - Specifies if the input context should be validated against the input schema.
1972
+ * @param {SchemaDefinition} [outputSchema=undefined] - The output schema for validating the task's output context.
1973
+ * @param {boolean} [validateOutputContext=false] - Specifies if the output context should be validated against the output schema.
1974
+ * @param {number} [retryCount=0] - The number of retry attempts allowed for the task in case of failure.
1975
+ * @param {number} [retryDelay=0] - The initial delay (in milliseconds) between retry attempts.
1976
+ * @param {number} [retryDelayMax=0] - The maximum delay (in milliseconds) allowed between retries.
1977
+ * @param {number} [retryDelayFactor=1] - The factor by which the retry delay increases after each attempt.
1541
1978
  */
1542
1979
  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) {
1543
1980
  super(isSubMeta || isHidden);
@@ -1626,6 +2063,13 @@ var Task = class extends SignalEmitter {
1626
2063
  });
1627
2064
  }
1628
2065
  }
2066
+ /**
2067
+ * Retrieves the tag associated with the instance.
2068
+ * Can be overridden by subclasses.
2069
+ *
2070
+ * @param {AnyObject} [context] - Optional context parameter that can be provided.
2071
+ * @return {string} The tag value of the instance.
2072
+ */
1629
2073
  getTag(context) {
1630
2074
  return this.name;
1631
2075
  }
@@ -1656,16 +2100,35 @@ var Task = class extends SignalEmitter {
1656
2100
  setValidateOutputContext(value) {
1657
2101
  this.validateOutputContext = value;
1658
2102
  }
2103
+ /**
2104
+ * Emits a signal along with metadata if certain conditions are met.
2105
+ *
2106
+ * This method sends a signal with optional context data and adds metadata
2107
+ * to the emitted data if the instance is not hidden and not a subordinate metadata object.
2108
+ *
2109
+ * @param {string} signal - The name of the signal to emit.
2110
+ * @param {AnyObject} [ctx={}] - Additional context data to include with the emitted signal.
2111
+ * @return {void} Does not return a value.
2112
+ */
1659
2113
  emitWithMetadata(signal, ctx = {}) {
1660
2114
  const data = { ...ctx };
1661
2115
  if (!this.isHidden && !this.isSubMeta) {
1662
2116
  data.__signalEmission = {
1663
2117
  taskName: this.name,
1664
- taskVersion: this.version
2118
+ taskVersion: this.version,
2119
+ isMetric: false
1665
2120
  };
1666
2121
  }
1667
2122
  this.emit(signal, data);
1668
2123
  }
2124
+ /**
2125
+ * Emits metrics with additional metadata enhancement based on the context and the state of the instance.
2126
+ * This is used to prevent loops on the meta layer in debug mode.
2127
+ *
2128
+ * @param {string} signal - The signal identifier for the metric being emitted.
2129
+ * @param {AnyObject} [ctx={}] - Optional context object to provide additional information with the metric.
2130
+ * @return {void} This method does not return any value.
2131
+ */
1669
2132
  emitMetricsWithMetadata(signal, ctx = {}) {
1670
2133
  const data = { ...ctx };
1671
2134
  if (!this.isHidden && !this.isSubMeta) {
@@ -1678,12 +2141,13 @@ var Task = class extends SignalEmitter {
1678
2141
  this.emitMetrics(signal, data);
1679
2142
  }
1680
2143
  /**
1681
- * Validates a context deeply against a schema.
1682
- * @param data - The data to validate (input context or output result).
1683
- * @param schema - The schema definition.
1684
- * @param path - The current path for error reporting (default: 'root').
1685
- * @returns { { valid: boolean, errors: Record<string, string> } } - Validation result with detailed errors if invalid.
1686
- * @description Recursively checks types, required fields, and constraints; allows extra properties not in schema.
2144
+ * Validates a data object against a specified schema definition and returns validation results.
2145
+ *
2146
+ * @param {any} data - The target object to validate against the schema.
2147
+ * @param {SchemaDefinition | undefined} schema - The schema definition describing the expected structure and constraints of the data.
2148
+ * @param {string} [path="context"] - The base path or context for traversing the data, used in generating error messages.
2149
+ * @return {{ valid: boolean, errors: Record<string, string> }} - An object containing a validity flag (`valid`)
2150
+ * and a map (`errors`) of validation error messages keyed by property paths.
1687
2151
  */
1688
2152
  validateSchema(data, schema, path = "context") {
1689
2153
  const errors = {};
@@ -1786,6 +2250,12 @@ var Task = class extends SignalEmitter {
1786
2250
  }
1787
2251
  return { valid: true, errors: {} };
1788
2252
  }
2253
+ /**
2254
+ * Validates the input context against the predefined schema and emits metadata if validation fails.
2255
+ *
2256
+ * @param {AnyObject} context - The input context to validate.
2257
+ * @return {true | AnyObject} - Returns `true` if validation succeeds, otherwise returns an error object containing details of the validation failure.
2258
+ */
1789
2259
  validateInput(context) {
1790
2260
  if (this.validateInputContext) {
1791
2261
  const validationResult = this.validateSchema(
@@ -1808,6 +2278,13 @@ var Task = class extends SignalEmitter {
1808
2278
  }
1809
2279
  return true;
1810
2280
  }
2281
+ /**
2282
+ * Validates the output context using the provided schema and emits metadata if validation fails.
2283
+ *
2284
+ * @param {AnyObject} context - The output context to validate.
2285
+ * @return {true | AnyObject} Returns `true` if the output context is valid; otherwise, returns an object
2286
+ * containing error information when validation fails.
2287
+ */
1811
2288
  validateOutput(context) {
1812
2289
  if (this.validateOutputContext) {
1813
2290
  const validationResult = this.validateSchema(
@@ -1831,14 +2308,13 @@ var Task = class extends SignalEmitter {
1831
2308
  return true;
1832
2309
  }
1833
2310
  /**
1834
- * Executes the task function after optional input validation.
1835
- * @param context - The GraphContext to validate and execute.
1836
- * @param emit
1837
- * @param progressCallback - Callback for progress updates.
1838
- * @param nodeData
1839
- * @returns TaskResult from the taskFunction or error object on validation failure.
1840
- * @edge If validateInputContext is true, validates context; on failure, emits 'meta.task.validationFailed' with detailed errors.
1841
- * @edge If validateOutputContext is true, validates output; on failure, emits 'meta.task.outputValidationFailed' with detailed errors.
2311
+ * Executes a task within a given context, optionally emitting signals and reporting progress.
2312
+ *
2313
+ * @param {GraphContext} context The execution context which provides data and functions necessary for the task.
2314
+ * @param {function(string, AnyObject): void} emit A function to emit signals and communicate intermediate results or states.
2315
+ * @param {function(number): void} progressCallback A callback function used to report task progress as a percentage (0 to 100).
2316
+ * @param {{ nodeId: string; routineExecId: string }} nodeData An object containing identifiers related to the node and execution routine.
2317
+ * @return {TaskResult} The result of the executed task.
1842
2318
  */
1843
2319
  execute(context, emit, progressCallback, nodeData) {
1844
2320
  return this.taskFunction(
@@ -1847,6 +2323,15 @@ var Task = class extends SignalEmitter {
1847
2323
  progressCallback
1848
2324
  );
1849
2325
  }
2326
+ /**
2327
+ * Adds tasks as predecessors to the current task and establishes dependencies between them.
2328
+ * Ensures that adding predecessors does not create cyclic dependencies.
2329
+ * Updates task relationships, progress weights, and emits relevant metrics after operations.
2330
+ *
2331
+ * @param {Task[]} tasks - An array of tasks to be added as predecessors to the current task.
2332
+ * @return {this} The current task instance for method chaining.
2333
+ * @throws {Error} Throws an error if adding a predecessor creates a cycle in the task structure.
2334
+ */
1850
2335
  doAfter(...tasks) {
1851
2336
  for (const pred of tasks) {
1852
2337
  if (this.predecessorTasks.has(pred)) continue;
@@ -1869,6 +2354,14 @@ var Task = class extends SignalEmitter {
1869
2354
  this.updateProgressWeights();
1870
2355
  return this;
1871
2356
  }
2357
+ /**
2358
+ * Adds a sequence of tasks as successors to the current task, ensuring no cyclic dependencies are introduced.
2359
+ * Metrics are emitted when a relationship is successfully added.
2360
+ *
2361
+ * @param {...Task} tasks - The tasks to be added as successors to the current task.
2362
+ * @return {this} Returns the current task instance for method chaining.
2363
+ * @throws {Error} Throws an error if adding a task causes a cyclic dependency.
2364
+ */
1872
2365
  then(...tasks) {
1873
2366
  for (const next of tasks) {
1874
2367
  if (this.nextTasks.has(next)) continue;
@@ -1891,6 +2384,12 @@ var Task = class extends SignalEmitter {
1891
2384
  this.updateProgressWeights();
1892
2385
  return this;
1893
2386
  }
2387
+ /**
2388
+ * Decouples the current task from the provided task by removing mutual references.
2389
+ *
2390
+ * @param {Task} task - The task to decouple from the current task.
2391
+ * @return {void} This method does not return a value.
2392
+ */
1894
2393
  decouple(task) {
1895
2394
  if (task.nextTasks.has(this)) {
1896
2395
  task.nextTasks.delete(this);
@@ -1902,6 +2401,14 @@ var Task = class extends SignalEmitter {
1902
2401
  }
1903
2402
  this.updateLayerFromPredecessors();
1904
2403
  }
2404
+ /**
2405
+ * Updates the progress weights for tasks within each layer of the subgraph.
2406
+ * The progress weight for each task is calculated based on the inverse proportion
2407
+ * of the number of layers and the number of tasks in each layer. This ensures an
2408
+ * even distribution of progress weight across the tasks in the layers.
2409
+ *
2410
+ * @return {void} Does not return a value.
2411
+ */
1905
2412
  updateProgressWeights() {
1906
2413
  const layers = this.getSubgraphLayers();
1907
2414
  const numLayers = layers.size;
@@ -1915,6 +2422,12 @@ var Task = class extends SignalEmitter {
1915
2422
  );
1916
2423
  });
1917
2424
  }
2425
+ /**
2426
+ * Retrieves a mapping of layer indices to sets of tasks within each layer of a subgraph.
2427
+ * This method traverses the task dependencies and organizes tasks by their respective layer indices.
2428
+ *
2429
+ * @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.
2430
+ */
1918
2431
  getSubgraphLayers() {
1919
2432
  const layers = /* @__PURE__ */ new Map();
1920
2433
  const queue = [this];
@@ -1929,6 +2442,13 @@ var Task = class extends SignalEmitter {
1929
2442
  }
1930
2443
  return layers;
1931
2444
  }
2445
+ /**
2446
+ * Updates the `layerIndex` of the current task based on the maximum layer index of its predecessors
2447
+ * and propagates the update recursively to all subsequent tasks. If the `layerIndex` changes,
2448
+ * emits a metric event with metadata about the change.
2449
+ *
2450
+ * @return {void} This method does not return a value.
2451
+ */
1932
2452
  updateLayerFromPredecessors() {
1933
2453
  const prevLayerIndex = this.layerIndex;
1934
2454
  let maxPred = 0;
@@ -1951,6 +2471,12 @@ var Task = class extends SignalEmitter {
1951
2471
  next.nextTasks.forEach((n) => queue.push(n));
1952
2472
  }
1953
2473
  }
2474
+ /**
2475
+ * Determines whether there is a cycle in the tasks graph.
2476
+ * This method performs a depth-first search (DFS) to detect cycles.
2477
+ *
2478
+ * @return {boolean} - Returns true if a cycle is found in the graph, otherwise false.
2479
+ */
1954
2480
  hasCycle() {
1955
2481
  const visited = /* @__PURE__ */ new Set();
1956
2482
  const recStack = /* @__PURE__ */ new Set();
@@ -1967,18 +2493,33 @@ var Task = class extends SignalEmitter {
1967
2493
  };
1968
2494
  return dfs(this);
1969
2495
  }
2496
+ /**
2497
+ * Maps over the next set of tasks or failed tasks if specified, applying the provided callback function.
2498
+ *
2499
+ * @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.
2500
+ * @param {boolean} [failed=false] A boolean that determines whether to map over the failed tasks (true) or the next tasks (false).
2501
+ * @return {any[]} An array of transformed tasks resulting from applying the callback function.
2502
+ */
1970
2503
  mapNext(callback, failed = false) {
1971
2504
  const tasks = failed ? Array.from(this.onFailTasks) : Array.from(this.nextTasks);
1972
2505
  return tasks.map(callback);
1973
2506
  }
2507
+ /**
2508
+ * Maps through each task in the set of predecessor tasks and applies the provided callback function.
2509
+ *
2510
+ * @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.
2511
+ * @return {any[]} An array containing the results of applying the callback function to each predecessor task.
2512
+ */
1974
2513
  mapPrevious(callback) {
1975
2514
  return Array.from(this.predecessorTasks).map(callback);
1976
2515
  }
1977
2516
  /**
1978
- * Subscribes to signals (chainable).
1979
- * @param signals The signal names.
1980
- * @returns This for chaining.
1981
- * @edge Duplicates ignored; assumes broker.observe binds this as handler.
2517
+ * Adds the specified signals to the current instance, making it observe them.
2518
+ * If the instance is already observing a signal, it will be skipped.
2519
+ * The method also emits metadata information if the `register` property is set.
2520
+ *
2521
+ * @param {...string[]} signals - The array of signal names to observe.
2522
+ * @return {this} The current instance after adding the specified signals.
1982
2523
  */
1983
2524
  doOn(...signals) {
1984
2525
  signals.forEach((signal) => {
@@ -1998,9 +2539,10 @@ var Task = class extends SignalEmitter {
1998
2539
  return this;
1999
2540
  }
2000
2541
  /**
2001
- * Sets signals to emit post-execution (chainable).
2002
- * @param signals The signal names.
2003
- * @returns This for chaining.
2542
+ * Registers the specified signals to be emitted after the Task executes successfully and attaches them for further processing.
2543
+ *
2544
+ * @param {...string} signals - The list of signals to be registered for emission.
2545
+ * @return {this} The current instance for method chaining.
2004
2546
  */
2005
2547
  emits(...signals) {
2006
2548
  signals.forEach((signal) => {
@@ -2009,6 +2551,13 @@ var Task = class extends SignalEmitter {
2009
2551
  });
2010
2552
  return this;
2011
2553
  }
2554
+ /**
2555
+ * Configures the instance to emit specified signals when the task execution fails.
2556
+ * A failure is defined as anything that does not return a successful result.
2557
+ *
2558
+ * @param {...string} signals - The names of the signals to emit upon failure.
2559
+ * @return {this} Returns the current instance for chaining.
2560
+ */
2012
2561
  emitsOnFail(...signals) {
2013
2562
  signals.forEach((signal) => {
2014
2563
  this.signalsToEmitOnFail.add(signal);
@@ -2016,6 +2565,13 @@ var Task = class extends SignalEmitter {
2016
2565
  });
2017
2566
  return this;
2018
2567
  }
2568
+ /**
2569
+ * Attaches a signal to the current context and emits metadata if the register flag is set.
2570
+ *
2571
+ * @param {string} signal - The name of the signal to attach.
2572
+ * @param {boolean} [isOnFail=false] - Indicates if the signal should be marked as "on fail".
2573
+ * @return {void} This method does not return a value.
2574
+ */
2019
2575
  attachSignal(signal, isOnFail = false) {
2020
2576
  this.emitsSignals.add(signal);
2021
2577
  if (this.register) {
@@ -2030,10 +2586,12 @@ var Task = class extends SignalEmitter {
2030
2586
  }
2031
2587
  }
2032
2588
  /**
2033
- * Unsubscribes from specific signals.
2034
- * @param signals The signals.
2035
- * @returns This for chaining.
2036
- * @edge No-op if not subscribed.
2589
+ * Unsubscribes the current instance from the specified signals.
2590
+ * This method removes the signals from the observedSignals set, unsubscribes
2591
+ * from the underlying broker, and emits metadata for the unsubscription if applicable.
2592
+ *
2593
+ * @param {string[]} signals - The list of signal names to unsubscribe from.
2594
+ * @return {this} Returns the current instance for method chaining.
2037
2595
  */
2038
2596
  unsubscribe(...signals) {
2039
2597
  signals.forEach((signal) => {
@@ -2055,8 +2613,9 @@ var Task = class extends SignalEmitter {
2055
2613
  return this;
2056
2614
  }
2057
2615
  /**
2058
- * Unsubscribes from all observed signals.
2059
- * @returns This for chaining.
2616
+ * Unsubscribes from all currently observed signals and clears the list of observed signals.
2617
+ *
2618
+ * @return {this} The instance of the class to allow method chaining.
2060
2619
  */
2061
2620
  unsubscribeAll() {
2062
2621
  this.unsubscribe(...this.observedSignals);
@@ -2064,9 +2623,10 @@ var Task = class extends SignalEmitter {
2064
2623
  return this;
2065
2624
  }
2066
2625
  /**
2067
- * Detaches specific emitted signals.
2068
- * @param signals The signals.
2069
- * @returns This for chaining.
2626
+ * Detaches the specified signals from being emitted after execution and optionally emits metadata for each detached signal.
2627
+ *
2628
+ * @param {...string} signals - The list of signal names to be detached. Signals can be in the format "namespace:signalName".
2629
+ * @return {this} Returns the current instance of the object for method chaining.
2070
2630
  */
2071
2631
  detachSignals(...signals) {
2072
2632
  signals.forEach((signal) => {
@@ -2085,27 +2645,50 @@ var Task = class extends SignalEmitter {
2085
2645
  return this;
2086
2646
  }
2087
2647
  /**
2088
- * Detaches all emitted signals.
2089
- * @returns This for chaining.
2648
+ * Detaches all signals associated with the object by invoking the `detachSignals` method
2649
+ * and clearing the `signalsToEmitAfter` collection.
2650
+ *
2651
+ * @return {this} Returns the current instance to allow method chaining.
2090
2652
  */
2091
2653
  detachAllSignals() {
2092
2654
  this.detachSignals(...this.signalsToEmitAfter);
2093
2655
  this.signalsToEmitAfter.clear();
2094
2656
  return this;
2095
2657
  }
2658
+ /**
2659
+ * Maps over the signals in the `signalsToEmitAfter` set and applies a callback function to each signal.
2660
+ *
2661
+ * @param {function(string): void} callback - A function that is called with each signal
2662
+ * in the `signalsToEmitAfter` set, providing the signal as an argument.
2663
+ * @return {Array<any>} An array containing the results of applying the callback
2664
+ * function to each signal.
2665
+ */
2096
2666
  mapSignals(callback) {
2097
2667
  return Array.from(this.signalsToEmitAfter).map(callback);
2098
2668
  }
2669
+ /**
2670
+ * Maps over the signals in `signalsToEmitOnFail` and applies the provided callback to each signal.
2671
+ *
2672
+ * @param {function(string): void} callback - A function that receives each signal as a string and performs an operation or transformation on it.
2673
+ * @return {Array} The array resulting from applying the callback to each signal in `signalsToEmitOnFail`.
2674
+ */
2099
2675
  mapOnFailSignals(callback) {
2100
2676
  return Array.from(this.signalsToEmitOnFail).map(callback);
2101
2677
  }
2678
+ /**
2679
+ * Maps over the observed signals with the provided callback function.
2680
+ *
2681
+ * @param {function(string): void} callback - A function to execute on each signal in the observed signals array.
2682
+ * @return {Array} A new array containing the results of calling the callback function on each observed signal.
2683
+ */
2102
2684
  mapObservedSignals(callback) {
2103
2685
  return Array.from(this.observedSignals).map(callback);
2104
2686
  }
2105
2687
  /**
2106
- * Emits attached signals.
2107
- * @param context The context for emission.
2108
- * @edge If isMeta (from Task), suppresses further "meta.*" to prevent loops.
2688
+ * Emits a collection of signals stored in the `signalsToEmitAfter` array.
2689
+ *
2690
+ * @param {GraphContext} context - The context object containing data or state to be passed to the emitted signals.
2691
+ * @return {void} This method does not return a value.
2109
2692
  */
2110
2693
  emitSignals(context) {
2111
2694
  this.signalsToEmitAfter.forEach((signal) => {
@@ -2113,15 +2696,29 @@ var Task = class extends SignalEmitter {
2113
2696
  });
2114
2697
  }
2115
2698
  /**
2116
- * Emits attached fail signals.
2117
- * @param context The context for emission.
2118
- * @edge If isMeta (from Task), suppresses further "meta.*" to prevent loops.
2699
+ * Emits registered signals when an operation fails.
2700
+ *
2701
+ * @param {GraphContext} context - The context from which the full context is derived and passed to the signals being emitted.
2702
+ * @return {void} This method does not return any value.
2119
2703
  */
2120
2704
  emitOnFailSignals(context) {
2121
2705
  this.signalsToEmitOnFail.forEach((signal) => {
2122
2706
  this.emit(signal, context.getFullContext());
2123
2707
  });
2124
2708
  }
2709
+ /**
2710
+ * Cleans up and destroys the task instance, detaching it from other tasks and
2711
+ * performing necessary cleanup operations.
2712
+ *
2713
+ * This method:
2714
+ * - Unsubscribes from all signals and events.
2715
+ * - Detaches all associated signal handlers.
2716
+ * - Removes the task from successor and predecessor task mappings.
2717
+ * - Clears all task relationships and marks the task as destroyed.
2718
+ * - Emits destruction metrics, if applicable.
2719
+ *
2720
+ * @return {void} No value is returned because the function performs clean-up operations.
2721
+ */
2125
2722
  destroy() {
2126
2723
  this.unsubscribeAll();
2127
2724
  this.detachAllSignals();
@@ -2139,6 +2736,18 @@ var Task = class extends SignalEmitter {
2139
2736
  });
2140
2737
  }
2141
2738
  }
2739
+ /**
2740
+ * Exports the current state of the object as a structured plain object.
2741
+ *
2742
+ * @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:
2743
+ * - Name and description of the task.
2744
+ * - Layer index, uniqueness, meta, and signal-related flags.
2745
+ * - Event triggers and attached signals.
2746
+ * - Throttling, concurrency, timeout settings, and ephemeral flag.
2747
+ * - Task function as a string.
2748
+ * - Serialization of getter callbacks and schemas for input/output validation.
2749
+ * - Relationships such as next tasks, failure tasks, and predecessor tasks.
2750
+ */
2142
2751
  export() {
2143
2752
  return {
2144
2753
  __name: this.name,
@@ -2165,9 +2774,20 @@ var Task = class extends SignalEmitter {
2165
2774
  __previousTasks: Array.from(this.predecessorTasks).map((t) => t.name)
2166
2775
  };
2167
2776
  }
2777
+ /**
2778
+ * Returns an iterator for iterating over tasks associated with this instance.
2779
+ *
2780
+ * @return {TaskIterator} An iterator instance for tasks.
2781
+ */
2168
2782
  getIterator() {
2169
2783
  return new TaskIterator(this);
2170
2784
  }
2785
+ /**
2786
+ * Accepts a visitor object to perform operations on the current instance.
2787
+ *
2788
+ * @param {GraphVisitor} visitor - The visitor object implementing operations for this instance.
2789
+ * @return {void} This method does not return a value.
2790
+ */
2171
2791
  accept(visitor) {
2172
2792
  visitor.visitTask(this);
2173
2793
  }
@@ -2178,6 +2798,16 @@ var Task = class extends SignalEmitter {
2178
2798
 
2179
2799
  // src/registry/GraphRegistry.ts
2180
2800
  var GraphRegistry = class _GraphRegistry {
2801
+ /**
2802
+ * Constructs a new instance and sets up various meta tasks and routines.
2803
+ *
2804
+ * This constructor initializes several predefined tasks for managing operations
2805
+ * like registering tasks, updating schemas for tasks, fetching tasks or routines,
2806
+ * and performing actions on all tasks or routines. It also initializes routines
2807
+ * to handle similar operations and hardcodes the initial meta tasks and routines.
2808
+ *
2809
+ * It initializes the instance state by setting up tasks and routines.
2810
+ */
2181
2811
  constructor() {
2182
2812
  this.tasks = /* @__PURE__ */ new Map();
2183
2813
  this.routines = /* @__PURE__ */ new Map();
@@ -2362,12 +2992,14 @@ var GraphRunner = class extends SignalEmitter {
2362
2992
  );
2363
2993
  }
2364
2994
  /**
2365
- * Adds tasks/routines to current run.
2366
- * @param tasks Tasks/routines.
2367
- * @param context Context (defaults {}).
2368
- * @edge Flattens routines to tasks; generates routineExecId if not in context.
2369
- * @edge Emits 'meta.runner.added_tasks' with metadata.
2370
- * @edge Empty tasks warns no-op.
2995
+ * Adds tasks or routines to the current execution pipeline. Supports both individual tasks,
2996
+ * routines, or arrays of tasks and routines. Handles metadata and execution context management.
2997
+ *
2998
+ * @param {Task|GraphRoutine|(Task|GraphRoutine)[]} tasks - The task(s) or routine(s) to be added.
2999
+ * It can be a single task, a single routine, or an array of tasks and routines.
3000
+ * @param {AnyObject} [context={}] - Optional context object to provide execution trace and metadata.
3001
+ * Used to propagate information across task or routine executions.
3002
+ * @return {void} - This method does not return a value.
2371
3003
  */
2372
3004
  addTasks(tasks, context = {}) {
2373
3005
  let _tasks = Array.isArray(tasks) ? tasks : [tasks];
@@ -2392,9 +3024,9 @@ var GraphRunner = class extends SignalEmitter {
2392
3024
  const isSubMeta = allTasks.some((t) => t.isSubMeta) || !!context.__isSubMeta;
2393
3025
  context.__isSubMeta = isSubMeta;
2394
3026
  const isNewTrace = !context.__routineExecId && !context.__metadata?.__executionTraceId && !context.__executionTraceId;
2395
- const executionTraceId = context.__metadata?.__executionTraceId ?? context.__executionTraceId ?? uuid4();
3027
+ const executionTraceId = context.__metadata?.__executionTraceId ?? context.__executionTraceId ?? uuid5();
2396
3028
  context.__executionTraceId = executionTraceId;
2397
- const routineExecId = context.__routineExecId ?? uuid4();
3029
+ const routineExecId = context.__routineExecId ?? uuid5();
2398
3030
  context.__routineExecId = routineExecId;
2399
3031
  const ctx = new GraphContext(context || {});
2400
3032
  if (!isSubMeta) {
@@ -2440,11 +3072,12 @@ var GraphRunner = class extends SignalEmitter {
2440
3072
  );
2441
3073
  }
2442
3074
  /**
2443
- * Runs tasks/routines.
2444
- * @param tasks Optional tasks/routines.
2445
- * @param context Optional context.
2446
- * @returns Current/last run (Promise if async).
2447
- * @edge If running, returns current; else runs and resets.
3075
+ * Executes the provided tasks or routines. Maintains the execution state
3076
+ * and handles synchronous or asynchronous processing.
3077
+ *
3078
+ * @param {Task|GraphRoutine|(Task|GraphRoutine)[]} [tasks] - A single task, a single routine, or an array of tasks or routines to execute. Optional.
3079
+ * @param {AnyObject} [context] - An optional context object to be used during task execution.
3080
+ * @return {GraphRun|Promise<GraphRun>} - Returns a `GraphRun` instance if the execution is synchronous, or a `Promise` resolving to a `GraphRun` for asynchronous execution.
2448
3081
  */
2449
3082
  run(tasks, context) {
2450
3083
  if (tasks) {
@@ -2462,10 +3095,23 @@ var GraphRunner = class extends SignalEmitter {
2462
3095
  }
2463
3096
  return this.reset();
2464
3097
  }
3098
+ /**
3099
+ * Executes the provided asynchronous operation and resets the state afterwards.
3100
+ *
3101
+ * @param {Promise<void>} run - A promise representing the asynchronous operation to execute.
3102
+ * @return {Promise<GraphRun>} A promise that resolves to the result of the reset operation after the asynchronous operation completes.
3103
+ */
2465
3104
  async runAsync(run) {
2466
3105
  await run;
2467
3106
  return this.reset();
2468
3107
  }
3108
+ /**
3109
+ * Resets the current state of the graph, creating a new GraphRun instance
3110
+ * and returning the previous run instance.
3111
+ * If the debug mode is not enabled, it will destroy the existing resources.
3112
+ *
3113
+ * @return {GraphRun} The last GraphRun instance before the reset.
3114
+ */
2469
3115
  reset() {
2470
3116
  this.isRunning = false;
2471
3117
  const lastRun = this.currentRun;
@@ -2484,6 +3130,13 @@ var GraphRunner = class extends SignalEmitter {
2484
3130
  destroy() {
2485
3131
  this.currentRun.destroy();
2486
3132
  }
3133
+ /**
3134
+ * Sets the strategy to be used for running the graph and initializes
3135
+ * the current run with the provided strategy if no process is currently running.
3136
+ *
3137
+ * @param {GraphRunStrategy} strategy - The strategy to use for running the graph.
3138
+ * @return {void}
3139
+ */
2487
3140
  setStrategy(strategy) {
2488
3141
  this.strategy = strategy;
2489
3142
  if (!this.isRunning) {
@@ -2543,6 +3196,14 @@ var DebounceTask = class extends Task {
2543
3196
  this.trailing = trailing;
2544
3197
  this.maxWait = maxWait;
2545
3198
  }
3199
+ /**
3200
+ * Executes the taskFunction with the provided context, emit function, and progress callback.
3201
+ * It clears any existing timeout before execution.
3202
+ * Handles synchronous and asynchronous results from taskFunction.
3203
+ * If an error occurs during execution, it resolves with the error.
3204
+ *
3205
+ * @return {void} This method does not return any value.
3206
+ */
2546
3207
  executeFunction() {
2547
3208
  if (this.lastTimeout) {
2548
3209
  clearTimeout(this.lastTimeout);
@@ -2568,6 +3229,19 @@ var DebounceTask = class extends Task {
2568
3229
  }
2569
3230
  }
2570
3231
  }
3232
+ /**
3233
+ * Executes a debounced operation, ensuring controlled execution of functions
3234
+ * over a specified debounce time and maximum wait time. This method handles
3235
+ * both leading and trailing edge executions and invokes callbacks accordingly.
3236
+ *
3237
+ * @param {Function} resolve - The function to call when the operation is successfully resolved.
3238
+ * @param {Function} reject - The function to call with an error or reason if the operation fails.
3239
+ * @param {GraphContext} context - The execution context for the operation.
3240
+ * @param {NodeJS.Timeout} timeout - A timeout object for managing execution delays.
3241
+ * @param {Function} emit - A callback function to emit signals with a specific context.
3242
+ * @param {Function} progressCallback - A callback function to report progress during operation execution.
3243
+ * @return {void} Does not return a value but sets internal timers and invokes provided callbacks.
3244
+ */
2571
3245
  debouncedTrigger(resolve, reject, context, timeout, emit, progressCallback) {
2572
3246
  const callNow = this.leading && this.timer === null;
2573
3247
  const isNewBurst = this.timer === null;
@@ -2613,6 +3287,14 @@ var DebounceTask = class extends Task {
2613
3287
  }, this.maxWait);
2614
3288
  }
2615
3289
  }
3290
+ /**
3291
+ * Executes a task with a debounced trigger mechanism.
3292
+ *
3293
+ * @param {GraphContext} context - The context containing relevant graph data for the execution.
3294
+ * @param {function(string, any): void} emit - A function used to emit signals with associated context.
3295
+ * @param {function(number): void} progressCallback - A callback function to report the progress of the task as a number between 0 and 1.
3296
+ * @return {Promise<TaskResult>} A promise that resolves with the task result upon completion or rejects on failure.
3297
+ */
2616
3298
  execute(context, emit, progressCallback) {
2617
3299
  return new Promise((resolve, reject) => {
2618
3300
  const timeout = setTimeout(() => {
@@ -2658,6 +3340,15 @@ var EphemeralTask = class extends Task {
2658
3340
  this.once = once;
2659
3341
  this.condition = condition;
2660
3342
  }
3343
+ /**
3344
+ * Executes the process logic with the provided context, emit function, progress callback, and node data.
3345
+ *
3346
+ * @param {any} context - The execution context, carrying necessary parameters or states for the operation.
3347
+ * @param {function(string, AnyObject): void} emit - A function to emit signals with a string identifier and associated context.
3348
+ * @param {function(number): void} progressCallback - A callback function to report the progress of the execution as a numerical value.
3349
+ * @param {{ nodeId: string, routineExecId: string }} nodeData - An object containing details about the node ID and routine execution ID.
3350
+ * @return {any} The result of the execution, returned from the base implementation or processed internally.
3351
+ */
2661
3352
  execute(context, emit, progressCallback, nodeData) {
2662
3353
  const result = super.execute(context, emit, progressCallback, nodeData);
2663
3354
  if (this.once || this.condition(result)) {
@@ -2751,26 +3442,56 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2751
3442
  this.debug = false;
2752
3443
  this.index = index;
2753
3444
  }
3445
+ /**
3446
+ * Sets the debug mode for the current instance and all associated nodes.
3447
+ *
3448
+ * @param {boolean} value - A boolean value to enable (true) or disable (false) debug mode.
3449
+ * @return {void} No return value.
3450
+ */
2754
3451
  setDebug(value) {
2755
3452
  this.debug = value;
2756
3453
  for (const node of this.nodes) {
2757
3454
  node.setDebug(value);
2758
3455
  }
2759
3456
  }
3457
+ /**
3458
+ * Checks if the current layer has a preceding layer.
3459
+ *
3460
+ * @return {boolean} True if the current layer has a preceding layer that is an instance of GraphLayer; otherwise, false.
3461
+ */
2760
3462
  get hasPreceding() {
2761
3463
  return !!this.previous && this.previous instanceof _GraphLayer;
2762
3464
  }
2763
3465
  getNumberOfNodes() {
2764
3466
  return this.nodes.length;
2765
3467
  }
3468
+ /**
3469
+ * Retrieves a list of nodes that match the given routine execution ID.
3470
+ *
3471
+ * @param {string} routineExecId - The ID of the routine execution to filter nodes by.
3472
+ * @return {Array} An array of nodes that have the specified routine execution ID.
3473
+ */
2766
3474
  getNodesByRoutineExecId(routineExecId) {
2767
3475
  return this.nodes.filter((node) => node.routineExecId === routineExecId);
2768
3476
  }
3477
+ /**
3478
+ * Finds and returns all nodes in the graph that are identical to the given node.
3479
+ * Two nodes are considered identical if they share the same routine execution ID
3480
+ * and share a task with each other.
3481
+ *
3482
+ * @param {GraphNode} node - The reference node to compare against other nodes in the graph.
3483
+ * @return {GraphNode[]} An array of nodes that are identical to the given node.
3484
+ */
2769
3485
  getIdenticalNodes(node) {
2770
3486
  return this.nodes.filter(
2771
3487
  (n) => node.routineExecId === n.routineExecId && node.sharesTaskWith(n)
2772
3488
  );
2773
3489
  }
3490
+ /**
3491
+ * Checks whether all nodes in the collection have been processed.
3492
+ *
3493
+ * @return {boolean} Returns true if all nodes are processed, otherwise false.
3494
+ */
2774
3495
  isProcessed() {
2775
3496
  for (const node of this.nodes) {
2776
3497
  if (!node.isProcessed()) {
@@ -2779,6 +3500,11 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2779
3500
  }
2780
3501
  return true;
2781
3502
  }
3503
+ /**
3504
+ * Checks whether all layers in the graph have been processed.
3505
+ *
3506
+ * @return {boolean} Returns true if all graph layers are processed; otherwise, returns false.
3507
+ */
2782
3508
  graphDone() {
2783
3509
  let done = true;
2784
3510
  let layer = this;
@@ -2791,6 +3517,13 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2791
3517
  }
2792
3518
  return done;
2793
3519
  }
3520
+ /**
3521
+ * Sets the next GraphLayer in the sequence if it has a higher index than the current layer.
3522
+ * Updates the previous property if the given next layer has an existing previous layer.
3523
+ *
3524
+ * @param {GraphLayer} next - The next GraphLayer to be linked in the sequence.
3525
+ * @return {void} Does not return a value. Modifies the current layer's state.
3526
+ */
2794
3527
  setNext(next) {
2795
3528
  if (next.index <= this.index) {
2796
3529
  return;
@@ -2800,15 +3533,32 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2800
3533
  }
2801
3534
  super.setNext(next);
2802
3535
  }
3536
+ /**
3537
+ * Adds a node to the graph.
3538
+ *
3539
+ * @param {GraphNode} node - The node to be added to the graph.
3540
+ * @return {void}
3541
+ */
2803
3542
  add(node) {
2804
3543
  this.nodes.push(node);
2805
3544
  }
3545
+ /**
3546
+ * Starts the execution timer if it has not been started already.
3547
+ * Records the current timestamp as the start time.
3548
+ *
3549
+ * @return {number} The timestamp representing the start time in milliseconds.
3550
+ */
2806
3551
  start() {
2807
3552
  if (!this.executionStart) {
2808
3553
  this.executionStart = Date.now();
2809
3554
  }
2810
3555
  return this.executionStart;
2811
3556
  }
3557
+ /**
3558
+ * Marks the end of a process by capturing the current timestamp and calculating the execution time if a start time exists.
3559
+ *
3560
+ * @return {number} The timestamp at which the process ended, or 0 if the start time is not defined.
3561
+ */
2812
3562
  end() {
2813
3563
  if (!this.executionStart) {
2814
3564
  return 0;
@@ -2817,6 +3567,14 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2817
3567
  this.executionTime = end - this.executionStart;
2818
3568
  return end;
2819
3569
  }
3570
+ /**
3571
+ * Destroys the current graph layer and its associated resources.
3572
+ * This method recursively destroys all nodes in the current layer, clears the node list,
3573
+ * and ensures that any connected subsequent graph layers are also destroyed.
3574
+ * Additionally, it calls the decoupling logic to disconnect the current layer from its dependencies.
3575
+ *
3576
+ * @return {void} Does not return any value.
3577
+ */
2820
3578
  destroy() {
2821
3579
  for (const node of this.nodes) {
2822
3580
  node.destroy();
@@ -2828,9 +3586,20 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2828
3586
  }
2829
3587
  this.decouple();
2830
3588
  }
3589
+ /**
3590
+ * Returns an iterator for traversing through the graph layers.
3591
+ *
3592
+ * @return {GraphLayerIterator} An instance of GraphLayerIterator to traverse graph layers.
3593
+ */
2831
3594
  getIterator() {
2832
3595
  return new GraphLayerIterator(this);
2833
3596
  }
3597
+ /**
3598
+ * Accepts a visitor object to traverse or perform operations on the current graph layer and its nodes.
3599
+ *
3600
+ * @param {GraphVisitor} visitor - The visitor instance implementing the visitLayer and visitNode behavior.
3601
+ * @return {void} Returns nothing.
3602
+ */
2834
3603
  accept(visitor) {
2835
3604
  visitor.visitLayer(this);
2836
3605
  for (const node of this.nodes) {
@@ -2867,6 +3636,14 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2867
3636
 
2868
3637
  // src/graph/execution/SyncGraphLayer.ts
2869
3638
  var SyncGraphLayer = class extends GraphLayer {
3639
+ /**
3640
+ * Executes the processing logic of the current set of graph nodes. Iterates through all
3641
+ * nodes, skipping any that have already been processed, and executes their respective
3642
+ * logic to generate new nodes. Asynchronous functions are not supported and will
3643
+ * trigger an error log.
3644
+ *
3645
+ * @return {GraphNode[]} An array of newly generated graph nodes after executing the logic of each unprocessed node.
3646
+ */
2870
3647
  execute() {
2871
3648
  this.start();
2872
3649
  const result = [];
@@ -2899,20 +3676,49 @@ var GraphBuilder = class {
2899
3676
  getResult() {
2900
3677
  return this.graph;
2901
3678
  }
3679
+ /**
3680
+ * Composes a series of functions or operations.
3681
+ * This method should be implemented in the child class
3682
+ * to define custom composition logic.
3683
+ *
3684
+ * @return {any} The result of the composed operations or functions
3685
+ * when implemented in the child class.
3686
+ */
2902
3687
  compose() {
2903
3688
  throw "Implement this in child class...";
2904
3689
  }
3690
+ /**
3691
+ * Adds a node to the appropriate layer of the graph.
3692
+ *
3693
+ * @param {GraphNode} node - The node to be added to the graph. The node contains
3694
+ * layer information that determines which layer it belongs to.
3695
+ * @return {void} Does not return a value.
3696
+ */
2905
3697
  addNode(node) {
2906
3698
  const index = node.getLayerIndex();
2907
3699
  this.addLayer(index);
2908
3700
  const layer = this.getLayer(index);
2909
3701
  node.scheduleOn(layer);
2910
3702
  }
3703
+ /**
3704
+ * Adds multiple nodes to the graph.
3705
+ *
3706
+ * @param {GraphNode[]} nodes - An array of nodes to be added to the graph.
3707
+ * @return {void} This method does not return a value.
3708
+ */
2911
3709
  addNodes(nodes) {
2912
3710
  for (const node of nodes) {
2913
3711
  this.addNode(node);
2914
3712
  }
2915
3713
  }
3714
+ /**
3715
+ * Adds a new layer to the graph at the specified index. If the graph does not exist,
3716
+ * it creates the graph using the specified index. Updates the graph's top layer index
3717
+ * and maintains the order of layers.
3718
+ *
3719
+ * @param {number} index - The index at which the new layer should be added to the graph.
3720
+ * @return {void} This method does not return a value.
3721
+ */
2916
3722
  addLayer(index) {
2917
3723
  if (!this.graph) {
2918
3724
  const layer = this.createLayer(index);
@@ -2939,11 +3745,23 @@ var GraphBuilder = class {
2939
3745
  this.addLayer(index);
2940
3746
  }
2941
3747
  }
3748
+ /**
3749
+ * Creates a new layer for the graph at the specified index.
3750
+ *
3751
+ * @param {number} index - The index of the layer to be created.
3752
+ * @return {GraphLayer} A new instance of the graph layer corresponding to the provided index.
3753
+ */
2942
3754
  createLayer(index) {
2943
3755
  const layer = new SyncGraphLayer(index);
2944
3756
  layer.setDebug(this.debug);
2945
3757
  return layer;
2946
3758
  }
3759
+ /**
3760
+ * Retrieves a specific layer from the current set of layers.
3761
+ *
3762
+ * @param {number} layerIndex - The index of the layer to retrieve.
3763
+ * @return {*} The layer corresponding to the given index.
3764
+ */
2947
3765
  getLayer(layerIndex) {
2948
3766
  return this.layers[layerIndex - this.topLayerIndex];
2949
3767
  }
@@ -2956,6 +3774,12 @@ var GraphBuilder = class {
2956
3774
 
2957
3775
  // src/engine/builders/GraphBreadthFirstBuilder.ts
2958
3776
  var GraphBreadthFirstBuilder = class extends GraphBuilder {
3777
+ /**
3778
+ * Composes layers of a graph by iterating through them, executing their logic,
3779
+ * and adding the resulting nodes to the current graph.
3780
+ *
3781
+ * @return {void} This method does not return a value.
3782
+ */
2959
3783
  compose() {
2960
3784
  if (!this.graph) {
2961
3785
  return;
@@ -3011,6 +3835,15 @@ var ThrottleEngine = class _ThrottleEngine {
3011
3835
  setConcurrencyLimit(tag, limit) {
3012
3836
  this.maxConcurrencyPerTag[tag] = limit;
3013
3837
  }
3838
+ /**
3839
+ * Manages the execution of a function `fn` applied on a specified node `node` with controlled concurrency for a given tag.
3840
+ * The method ensures that processes are executed in a throttled manner, respecting the maximum concurrency for each tag.
3841
+ *
3842
+ * @param {ProcessFunction} fn - The function to be executed on the provided node.
3843
+ * @param {GraphNode} node - The graph node on which the function `fn` will be applied.
3844
+ * @param {string} [tag="default"] - The concurrency grouping tag used to control and group the throttling behavior.
3845
+ * @return {Promise<GraphNode[]>} A promise resolving to an array of GraphNode objects once the throttled function execution completes.
3846
+ */
3014
3847
  throttle(fn, node, tag = "default") {
3015
3848
  var _a, _b;
3016
3849
  const functionPromise = new Promise((resolve) => {
@@ -3022,6 +3855,12 @@ var ThrottleEngine = class _ThrottleEngine {
3022
3855
  this.processQueue(tag);
3023
3856
  return functionPromise;
3024
3857
  }
3858
+ /**
3859
+ * Processes the tasks in the queue for a given tag while respecting concurrency limits.
3860
+ *
3861
+ * @param {string} tag - The identifier for the queue to be processed, used to group tasks and manage concurrency controls.
3862
+ * @return {void} Does not return a value; it processes tasks asynchronously and manages state internally.
3863
+ */
3025
3864
  processQueue(tag) {
3026
3865
  const maxAllowed = this.maxConcurrencyPerTag[tag];
3027
3866
  while ((this.queues[tag]?.length ?? 0) > 0 && (this.runningCounts[tag] ?? 0) < maxAllowed) {
@@ -3037,6 +3876,14 @@ var ThrottleEngine = class _ThrottleEngine {
3037
3876
  delete this.runningCounts[tag];
3038
3877
  }
3039
3878
  }
3879
+ /**
3880
+ * Processes a given item consisting of a function and a graph node.
3881
+ *
3882
+ * @param {Array} item - An array where the first element is a processing function and the second element is a graph node.
3883
+ * @param {Function} item[0] - The function to process the graph node.
3884
+ * @param {GraphNode} item[1] - The graph node to be processed.
3885
+ * @return {Promise<void>} A promise that resolves when the processing and cleanup are complete.
3886
+ */
3040
3887
  async process(item) {
3041
3888
  const fn = item[0];
3042
3889
  const node = item[1];
@@ -3053,10 +3900,24 @@ var AsyncGraphLayer = class extends GraphLayer {
3053
3900
  this.waitingNodes = [];
3054
3901
  this.processingNodes = /* @__PURE__ */ new Set();
3055
3902
  }
3903
+ /**
3904
+ * Adds a node to the graph and tracks it as a waiting node.
3905
+ *
3906
+ * @param {GraphNode} node - The graph node to be added.
3907
+ * @return {void}
3908
+ */
3056
3909
  add(node) {
3057
3910
  this.nodes.push(node);
3058
3911
  this.waitingNodes.push(node);
3059
3912
  }
3913
+ /**
3914
+ * Executes the processing of nodes by iterating over the queued `waitingNodes`,
3915
+ * processing each node, and managing concurrency limits where applicable.
3916
+ * The method returns a mapping of routine execution IDs to arrays of processed nodes or promises.
3917
+ *
3918
+ * @return {Object} An object where the keys are routine execution IDs and the values
3919
+ * represent arrays of processed nodes or promises resolving to processed nodes.
3920
+ */
3060
3921
  execute() {
3061
3922
  var _a;
3062
3923
  if (this.waitingNodes.length === 0) {
@@ -3090,6 +3951,13 @@ var AsyncGraphLayer = class extends GraphLayer {
3090
3951
  }
3091
3952
  return result;
3092
3953
  }
3954
+ /**
3955
+ * Processes the given graph node, executes its logic, and handles synchronous or asynchronous outcomes.
3956
+ *
3957
+ * @param {GraphNode} node - The graph node to be processed.
3958
+ * @return {Promise<GraphNode[]> | GraphNode[]} A promise that resolves to an array of next graph nodes if asynchronous,
3959
+ * or an array of next graph nodes if synchronous.
3960
+ */
3093
3961
  processNode(node) {
3094
3962
  node.start();
3095
3963
  const nextNodes = node.execute();
@@ -3099,11 +3967,23 @@ var AsyncGraphLayer = class extends GraphLayer {
3099
3967
  this.processingNodes.delete(node);
3100
3968
  return nextNodes;
3101
3969
  }
3970
+ /**
3971
+ * Processes the given graph node asynchronously and removes it from the processing nodes set.
3972
+ *
3973
+ * @param {GraphNode} node - The current graph node being processed.
3974
+ * @param {Promise<GraphNode[]>} nextNodes - A promise that resolves to an array of the next graph nodes to process.
3975
+ * @return {Promise<GraphNode[]>} A promise that resolves to an array of the next graph nodes.
3976
+ */
3102
3977
  async processAsync(node, nextNodes) {
3103
3978
  const result = await nextNodes;
3104
3979
  this.processingNodes.delete(node);
3105
3980
  return result;
3106
3981
  }
3982
+ /**
3983
+ * Cleans up resources used by the instance by resetting relevant properties and invoking the parent class's destroy method.
3984
+ *
3985
+ * @return {void} No value is returned as the method performs cleanup operations.
3986
+ */
3107
3987
  destroy() {
3108
3988
  super.destroy();
3109
3989
  this.waitingNodes = [];
@@ -3113,6 +3993,14 @@ var AsyncGraphLayer = class extends GraphLayer {
3113
3993
 
3114
3994
  // src/engine/builders/GraphAsyncQueueBuilder.ts
3115
3995
  var GraphAsyncQueueBuilder = class extends GraphBuilder {
3996
+ /**
3997
+ * This method iterates over a graph structure and processes its layers sequentially.
3998
+ * It continues processing each layer until all layers in the graph are completed.
3999
+ * The asynchronous behavior ensures the operation provides breathing room for other
4000
+ * tasks/processes to execute during its operation.
4001
+ *
4002
+ * @return {Promise<void>} A promise that resolves when all layers of the graph are processed or rejects if an error occurs.
4003
+ */
3116
4004
  async compose() {
3117
4005
  if (!this.graph) {
3118
4006
  return;
@@ -3131,6 +4019,14 @@ var GraphAsyncQueueBuilder = class extends GraphBuilder {
3131
4019
  await sleep(0);
3132
4020
  }
3133
4021
  }
4022
+ /**
4023
+ * Processes a given asynchronous graph layer and executes its nodes.
4024
+ * Handles promises within the nodes and adds the resolved or processed
4025
+ * nodes to the graph.
4026
+ *
4027
+ * @param {AsyncGraphLayer} layer - The asynchronous graph layer to be processed.
4028
+ * @return {void} - This method does not return a value.
4029
+ */
3134
4030
  processLayer(layer) {
3135
4031
  const nextNodes = layer.execute();
3136
4032
  for (const routineExecId of Object.keys(nextNodes)) {
@@ -3144,6 +4040,13 @@ var GraphAsyncQueueBuilder = class extends GraphBuilder {
3144
4040
  }
3145
4041
  }
3146
4042
  }
4043
+ /**
4044
+ * Creates a new instance of AsyncGraphLayer, sets its debug configuration,
4045
+ * and returns the created layer.
4046
+ *
4047
+ * @param {number} index - The index to associate with the new AsyncGraphLayer.
4048
+ * @return {AsyncGraphLayer} A new instance of AsyncGraphLayer with the specified index and debug configuration.
4049
+ */
3147
4050
  createLayer(index) {
3148
4051
  const layer = new AsyncGraphLayer(index);
3149
4052
  layer.setDebug(this.debug);
@@ -3157,6 +4060,12 @@ var GraphAsyncRun = class extends GraphRunStrategy {
3157
4060
  super();
3158
4061
  this.graphBuilder = new GraphAsyncQueueBuilder();
3159
4062
  }
4063
+ /**
4064
+ * Executes the run operation, which involves composing the graph builder,
4065
+ * updating the run instance, and resetting the state.
4066
+ *
4067
+ * @return {Promise<void>} A promise that resolves when the operation completes.
4068
+ */
3160
4069
  async run() {
3161
4070
  await this.graphBuilder.compose();
3162
4071
  this.updateRunInstance();
@@ -3172,6 +4081,12 @@ var GraphAsyncRun = class extends GraphRunStrategy {
3172
4081
 
3173
4082
  // src/engine/strategy/GraphStandardRun.ts
3174
4083
  var GraphStandardRun = class extends GraphRunStrategy {
4084
+ /**
4085
+ * Executes the sequence of operations involving graph composition,
4086
+ * instance updating, and reset mechanisms.
4087
+ *
4088
+ * @return {void} Does not return a value.
4089
+ */
3175
4090
  run() {
3176
4091
  this.graphBuilder.compose();
3177
4092
  this.updateRunInstance();
@@ -3184,6 +4099,13 @@ var GraphStandardRun = class extends GraphRunStrategy {
3184
4099
 
3185
4100
  // src/Cadenza.ts
3186
4101
  var Cadenza = class {
4102
+ /**
4103
+ * Initializes the system by setting up the required components such as the
4104
+ * signal broker, runners, and graph registry. Ensures the initialization
4105
+ * happens only once. Configures debug settings if applicable.
4106
+ *
4107
+ * @return {void} No value is returned.
4108
+ */
3187
4109
  static bootstrap() {
3188
4110
  if (this.isBootstrapped) return;
3189
4111
  this.isBootstrapped = true;
@@ -3201,12 +4123,27 @@ var Cadenza = class {
3201
4123
  this.runner.init();
3202
4124
  this.metaRunner.init();
3203
4125
  }
4126
+ /**
4127
+ * Retrieves the available strategies for running graphs.
4128
+ *
4129
+ * @return {Object} An object containing the available run strategies, where:
4130
+ * - PARALLEL: Executes graph runs asynchronously.
4131
+ * - SEQUENTIAL: Executes graph runs in a sequential order.
4132
+ */
3204
4133
  static get runStrategy() {
3205
4134
  return {
3206
4135
  PARALLEL: new GraphAsyncRun(),
3207
4136
  SEQUENTIAL: new GraphStandardRun()
3208
4137
  };
3209
4138
  }
4139
+ /**
4140
+ * Sets the mode for the application and configures the broker and runner settings accordingly.
4141
+ *
4142
+ * @param {CadenzaMode} mode - The mode to set. It can be one of the following:
4143
+ * "debug", "dev", "verbose", or "production".
4144
+ * Each mode adjusts debug and verbosity settings.
4145
+ * @return {void} This method does not return a value.
4146
+ */
3210
4147
  static setMode(mode) {
3211
4148
  this.mode = mode;
3212
4149
  this.bootstrap();
@@ -3228,29 +4165,129 @@ var Cadenza = class {
3228
4165
  }
3229
4166
  }
3230
4167
  /**
3231
- * Validates a name for uniqueness and non-emptiness.
3232
- * @param name The name to validate.
3233
- * @throws Error if invalid.
4168
+ * Validates the given name to ensure it is a non-empty string.
4169
+ * Throws an error if the validation fails.
4170
+ *
4171
+ * @param {string} name - The name to validate.
4172
+ * @return {void} This method does not return anything.
4173
+ * @throws {Error} If the name is not a non-empty string.
3234
4174
  */
3235
4175
  static validateName(name) {
3236
4176
  if (!name || typeof name !== "string") {
3237
4177
  throw new Error("Task or Routine name must be a non-empty string.");
3238
4178
  }
3239
4179
  }
4180
+ /**
4181
+ * Executes the specified task or GraphRoutine with the given context using an internal runner.
4182
+ *
4183
+ * @param {Task | GraphRoutine} task - The task or GraphRoutine to be executed.
4184
+ * @param {AnyObject} context - The context in which the task or GraphRoutine should be executed.
4185
+ * @return {void}
4186
+ *
4187
+ * @example
4188
+ * ```ts
4189
+ * const task = Cadenza.createTask('My task', (ctx) => {
4190
+ * console.log('My task executed with context:', ctx);
4191
+ * });
4192
+ *
4193
+ * Cadenza.run(task, { foo: 'bar' });
4194
+ *
4195
+ * const routine = Cadenza.createRoutine('My routine', [task], 'My routine description');
4196
+ *
4197
+ * Cadenza.run(routine, { foo: 'bar' });
4198
+ * ```
4199
+ */
3240
4200
  static run(task, context) {
3241
4201
  this.runner?.run(task, context);
3242
4202
  }
4203
+ /**
4204
+ * Emits an event with the specified name and data payload to the broker.
4205
+ *
4206
+ * @param {string} event - The name of the event to emit.
4207
+ * @param {AnyObject} [data={}] - The data payload associated with the event.
4208
+ * @return {void} - No return value.
4209
+ *
4210
+ * @example
4211
+ * This is meant to be used as a global event emitter.
4212
+ * 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}.
4213
+ * ```ts
4214
+ * Cadenza.emit('main.my_event', { foo: 'bar' });
4215
+ * ```
4216
+ */
3243
4217
  static emit(event, data = {}) {
3244
4218
  this.broker?.emit(event, data);
3245
4219
  }
3246
4220
  /**
3247
- * Creates a standard Task and registers it in the GraphRegistry.
3248
- * @param name Unique identifier for the task.
3249
- * @param func The function or async generator to execute.
3250
- * @param description Optional human-readable description for introspection.
3251
- * @param options Optional task options.
3252
- * @returns The created Task instance.
3253
- * @throws Error if name is invalid or duplicate in registry.
4221
+ * Creates and registers a new task with the specified parameters and options.
4222
+ * Tasks are the basic building blocks of Cadenza graphs and are responsible for executing logic.
4223
+ * See {@link Task} for more information.
4224
+ *
4225
+ * @param {string} name - The unique name of the task.
4226
+ * @param {TaskFunction} func - The function to be executed by the task.
4227
+ * @param {string} [description] - An optional description for the task.
4228
+ * @param {TaskOptions} [options={}] - Configuration options for the task, such as concurrency, timeout, and retry settings.
4229
+ * @return {Task} The created task instance.
4230
+ *
4231
+ * @example
4232
+ * You can use arrow functions to create tasks.
4233
+ * ```ts
4234
+ * const task = Cadenza.createTask('My task', (ctx) => {
4235
+ * console.log('My task executed with context:', ctx);
4236
+ * }, 'My task description');
4237
+ * ```
4238
+ *
4239
+ * You can also use named functions to create tasks.
4240
+ * This is the preferred way to create tasks since it allows for code inspection in the CadenzaUI.
4241
+ * ```ts
4242
+ * function myTask(ctx) {
4243
+ * console.log('My task executed with context:', ctx);
4244
+ * }
4245
+ *
4246
+ * const task = Cadenza.createTask('My task', myTask);
4247
+ * ```
4248
+ *
4249
+ * ** Use the TaskOptions object to configure the task. **
4250
+ *
4251
+ * With concurrency limit, timeout limit and retry settings.
4252
+ * ```ts
4253
+ * Cadenza.createTask('My task', (ctx) => {
4254
+ * console.log('My task executed with context:', ctx);
4255
+ * }, 'My task description', {
4256
+ * concurrency: 10,
4257
+ * timeout: 10000,
4258
+ * retryCount: 3,
4259
+ * retryDelay: 1000,
4260
+ * retryDelayFactor: 1.5,
4261
+ * });
4262
+ * ```
4263
+ *
4264
+ * You can specify the input and output context schemas for the task.
4265
+ * ```ts
4266
+ * Cadenza.createTask('My task', (ctx) => {
4267
+ * return { bar: 'foo' + ctx.foo };
4268
+ * }, 'My task description', {
4269
+ * inputContextSchema: {
4270
+ * type: 'object',
4271
+ * properties: {
4272
+ * foo: {
4273
+ * type: 'string',
4274
+ * },
4275
+ * },
4276
+ * required: ['foo'],
4277
+ * },
4278
+ * validateInputContext: true, // default is false
4279
+ * outputContextSchema: {
4280
+ * type: 'object',
4281
+ * properties: {
4282
+ * bar: {
4283
+ * type: 'string',
4284
+ * },
4285
+ * },
4286
+ * required: ['bar'],
4287
+ * },
4288
+ * validateOutputContext: true, // default is false
4289
+ * });
4290
+ * ```
3254
4291
  */
3255
4292
  static createTask(name, func, description, options = {}) {
3256
4293
  this.bootstrap();
@@ -3297,40 +4334,82 @@ var Cadenza = class {
3297
4334
  );
3298
4335
  }
3299
4336
  /**
3300
- * Creates a MetaTask (for meta-layer graphs) and registers it.
3301
- * MetaTasks suppress further meta-signal emissions to prevent loops.
3302
- * @param name Unique identifier for the meta-task.
3303
- * @param func The function or async generator to execute.
3304
- * @param description Optional description.
3305
- * @param options Optional task options.
3306
- * @returns The created MetaTask instance.
3307
- * @throws Error if name invalid or duplicate.
4337
+ * Creates a meta task with the specified name, functionality, description, and options.
4338
+ * This is used for creating tasks that lives on the meta layer.
4339
+ * The meta layer is a special layer that is executed separately from the business logic layer and is used for extending Cadenzas core functionality.
4340
+ * See {@link Task} or {@link createTask} for more information.
4341
+ *
4342
+ * @param {string} name - The name of the meta task.
4343
+ * @param {TaskFunction} func - The function to be executed by the meta task.
4344
+ * @param {string} [description] - An optional description of the meta task.
4345
+ * @param {TaskOptions} [options={}] - Additional optional task configuration. Automatically sets `isMeta` to true.
4346
+ * @return {Task} A task instance configured as a meta task.
3308
4347
  */
3309
4348
  static createMetaTask(name, func, description, options = {}) {
3310
4349
  options.isMeta = true;
3311
4350
  return this.createTask(name, func, description, options);
3312
4351
  }
3313
4352
  /**
3314
- * Creates a UniqueTask (executes once per execution ID, merging parents) and registers it.
3315
- * Use for fan-in/joins after parallel branches.
3316
- * @param name Unique identifier.
3317
- * @param func Function receiving joinedContexts.
3318
- * @param description Optional description.
3319
- * @param options Optional task options.
3320
- * @returns The created UniqueTask.
3321
- * @throws Error if invalid.
4353
+ * Creates a unique task by wrapping the provided task function with a uniqueness constraint.
4354
+ * Unique tasks are designed to execute once per execution ID, merging parents. This is useful for
4355
+ * tasks that require fan-in/joins after parallel branches.
4356
+ * See {@link Task} for more information.
4357
+ *
4358
+ * @param {string} name - The name of the task to be created.
4359
+ * @param {TaskFunction} func - The function that contains the logic for the task. It receives joinedContexts as a list in the context (context.joinedContexts).
4360
+ * @param {string} [description] - An optional description of the task.
4361
+ * @param {TaskOptions} [options={}] - Optional configuration for the task, such as additional metadata or task options.
4362
+ * @return {Task} The task instance that was created with a uniqueness constraint.
4363
+ *
4364
+ * @example
4365
+ * ```ts
4366
+ * const splitTask = Cadenza.createTask('Split foos', function* (ctx) {
4367
+ * for (const foo of ctx.foos) {
4368
+ * yield { foo };
4369
+ * }
4370
+ * }, 'Splits a list of foos into multiple sub-branches');
4371
+ *
4372
+ * const processTask = Cadenza.createTask('Process foo', (ctx) => {
4373
+ * return { bar: 'foo' + ctx.foo };
4374
+ * }, 'Process a foo');
4375
+ *
4376
+ * const uniqueTask = Cadenza.createUniqueTask('Gather processed foos', (ctx) => {
4377
+ * // A unique task will always be provided with a list of contexts (ctx.joinedContexts) from its predecessors.
4378
+ * const processedFoos = ctx.joinedContexts.map((c) => c.bar);
4379
+ * return { foos: processedFoos };
4380
+ * }, 'Gathers together the processed foos.');
4381
+ *
4382
+ * splitTask.then(
4383
+ * processTask.then(
4384
+ * uniqueTask,
4385
+ * ),
4386
+ * );
4387
+ *
4388
+ * // Give the flow a name using a routine
4389
+ * Cadenza.createRoutine(
4390
+ * 'Process foos',
4391
+ * [splitTask],
4392
+ * 'Processes a list of foos'
4393
+ * ).doOn('main.received_foos'); // Subscribe to a signal
4394
+ *
4395
+ * // Trigger the flow from anywhere
4396
+ * Cadenza.emit('main.received_foos', { foos: ['foo1', 'foo2', 'foo3'] });
4397
+ * ```
4398
+ *
3322
4399
  */
3323
4400
  static createUniqueTask(name, func, description, options = {}) {
3324
4401
  options.isUnique = true;
3325
4402
  return this.createTask(name, func, description, options);
3326
4403
  }
3327
4404
  /**
3328
- * Creates a UniqueMetaTask for meta-layer joins.
3329
- * @param name Unique identifier.
3330
- * @param func Function.
3331
- * @param description Optional.
3332
- * @param options Optional task options.
3333
- * @returns The created UniqueMetaTask.
4405
+ * Creates a unique meta task with the specified name, function, description, and options.
4406
+ * See {@link createUniqueTask} and {@link createMetaTask} for more information.
4407
+ *
4408
+ * @param {string} name - The name of the task to create.
4409
+ * @param {TaskFunction} func - The function to execute when the task is run.
4410
+ * @param {string} [description] - An optional description of the task.
4411
+ * @param {TaskOptions} [options={}] - Optional settings for the task. Defaults to an empty object. Automatically sets `isMeta` and `isUnique` to true.
4412
+ * @return {Task} The created unique meta task.
3334
4413
  */
3335
4414
  static createUniqueMetaTask(name, func, description, options = {}) {
3336
4415
  options.isMeta = true;
@@ -3338,14 +4417,33 @@ var Cadenza = class {
3338
4417
  return this.createUniqueTask(name, func, description, options);
3339
4418
  }
3340
4419
  /**
3341
- * Creates a ThrottledTask (rate-limited by concurrency or custom groups) and registers it.
3342
- * @param name Unique identifier.
3343
- * @param func Function.
3344
- * @param throttledIdGetter Optional getter for dynamic grouping (e.g., per-user).
3345
- * @param description Optional.
3346
- * @param options Optional task options.
3347
- * @returns The created ThrottledTask.
3348
- * @edge If no getter, throttles per task ID; use for resource protection.
4420
+ * 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.
4421
+ * This is useful for ensuring execution order and preventing race conditions.
4422
+ * See {@link Task} for more information.
4423
+ *
4424
+ * @param {string} name - The name of the task.
4425
+ * @param {TaskFunction} func - The function to be executed when the task runs.
4426
+ * @param {ThrottleTagGetter} [throttledIdGetter=() => "default"] - A function that generates a throttle tag identifier to group tasks for throttling.
4427
+ * @param {string} [description] - An optional description of the task.
4428
+ * @param {TaskOptions} [options={}] - Additional options to customize the task behavior.
4429
+ * @return {Task} The created throttled task.
4430
+ *
4431
+ * @example
4432
+ * ```ts
4433
+ * const task = Cadenza.createThrottledTask(
4434
+ * 'My task',
4435
+ * async (ctx) => {
4436
+ * await new Promise((resolve) => setTimeout(resolve, 1000));
4437
+ * console.log('My task executed with context:', ctx);
4438
+ * },
4439
+ * // Will throttle by the value of ctx.foo to make sure tasks with the same value are executed sequentially
4440
+ * (ctx) => ctx.foo,
4441
+ * );
4442
+ *
4443
+ * Cadenza.run(task, { foo: 'bar' }); // (First execution)
4444
+ * Cadenza.run(task, { foo: 'bar' }); // This will be executed after the first execution is finished
4445
+ * Cadenza.run(task, { foo: 'baz' }); // This will be executed in parallel with the first execution
4446
+ * ```
3349
4447
  */
3350
4448
  static createThrottledTask(name, func, throttledIdGetter = () => "default", description, options = {}) {
3351
4449
  options.concurrency = 1;
@@ -3353,13 +4451,15 @@ var Cadenza = class {
3353
4451
  return this.createTask(name, func, description, options);
3354
4452
  }
3355
4453
  /**
3356
- * Creates a ThrottledMetaTask for meta-layer throttling.
3357
- * @param name Identifier.
3358
- * @param func Function.
3359
- * @param throttledIdGetter Optional getter.
3360
- * @param description Optional.
3361
- * @param options Optional task options.
3362
- * @returns The created ThrottledMetaTask.
4454
+ * Creates a throttled meta task with the specified configuration.
4455
+ * See {@link createThrottledTask} and {@link createMetaTask} for more information.
4456
+ *
4457
+ * @param {string} name - The name of the throttled meta task.
4458
+ * @param {TaskFunction} func - The task function to be executed.
4459
+ * @param {ThrottleTagGetter} throttledIdGetter - A function to retrieve the throttling identifier.
4460
+ * @param {string} [description] - An optional description of the task.
4461
+ * @param {TaskOptions} [options={}] - Additional options for configuring the task.
4462
+ * @return {Task} The created throttled meta task.
3363
4463
  */
3364
4464
  static createThrottledMetaTask(name, func, throttledIdGetter, description, options = {}) {
3365
4465
  options.isMeta = true;
@@ -3372,14 +4472,37 @@ var Cadenza = class {
3372
4472
  );
3373
4473
  }
3374
4474
  /**
3375
- * Creates a DebounceTask (delays exec until quiet period) and registers it.
3376
- * @param name Identifier.
3377
- * @param func Function.
3378
- * @param description Optional.
3379
- * @param debounceTime Delay in ms (default 1000).
3380
- * @param options Optional task options plus optional debounce config (e.g., leading/trailing).
3381
- * @returns The created DebounceTask.
3382
- * @edge Multiple triggers within time collapse to one exec.
4475
+ * Creates and returns a new debounced task with the specified parameters.
4476
+ * This is useful to prevent rapid execution of tasks that may be triggered by multiple events within a certain time frame.
4477
+ * See {@link DebounceTask} for more information.
4478
+ *
4479
+ * @param {string} name - The unique name of the task to be created.
4480
+ * @param {TaskFunction} func - The function to be executed by the task.
4481
+ * @param {string} [description] - An optional description of the task.
4482
+ * @param {number} [debounceTime=1000] - The debounce time in milliseconds to delay the execution of the task.
4483
+ * @param {TaskOptions & DebounceOptions} [options={}] - Additional configuration options for the task, including debounce behavior and other task properties.
4484
+ * @return {DebounceTask} A new instance of the DebounceTask with the specified configuration.
4485
+ *
4486
+ * @example
4487
+ * ```ts
4488
+ * const task = Cadenza.createDebounceTask(
4489
+ * 'My debounced task',
4490
+ * (ctx) => {
4491
+ * console.log('My task executed with context:', ctx);
4492
+ * },
4493
+ * 'My debounced task description',
4494
+ * 100, // Debounce time in milliseconds. Default is 1000
4495
+ * {
4496
+ * leading: false, // Should the first execution of a burst be executed immediately? Default is false
4497
+ * trailing: true, // Should the last execution of a burst be executed? Default is true
4498
+ * maxWait: 1000, // Maximum time in milliseconds to wait for the next execution. Default is 0
4499
+ * },
4500
+ * );
4501
+ *
4502
+ * Cadenza.run(task, { foo: 'bar' }); // This will not be executed
4503
+ * Cadenza.run(task, { foo: 'bar' }); // This will not be executed
4504
+ * Cadenza.run(task, { foo: 'baz' }); // This execution will be delayed by 100ms
4505
+ * ```
3383
4506
  */
3384
4507
  static createDebounceTask(name, func, description, debounceTime = 1e3, options = {}) {
3385
4508
  this.bootstrap();
@@ -3423,13 +4546,15 @@ var Cadenza = class {
3423
4546
  );
3424
4547
  }
3425
4548
  /**
3426
- * Creates a DebouncedMetaTask for meta-layer debouncing.
3427
- * @param name Identifier.
3428
- * @param func Function.
3429
- * @param description Optional.
3430
- * @param debounceTime Delay in ms.
3431
- * @param options Optional task options plus optional debounce config (e.g., leading/trailing).
3432
- * @returns The created DebouncedMetaTask.
4549
+ * Creates a debounced meta task with the specified parameters.
4550
+ * See {@link createDebounceTask} and {@link createMetaTask} for more information.
4551
+ *
4552
+ * @param {string} name - The name of the task.
4553
+ * @param {TaskFunction} func - The function to be executed by the task.
4554
+ * @param {string} [description] - Optional description of the task.
4555
+ * @param {number} [debounceTime=1000] - The debounce delay in milliseconds.
4556
+ * @param {TaskOptions & DebounceOptions} [options={}] - Additional configuration options for the task.
4557
+ * @return {DebounceTask} Returns an instance of the debounced meta task.
3433
4558
  */
3434
4559
  static createDebounceMetaTask(name, func, description, debounceTime = 1e3, options = {}) {
3435
4560
  options.isMeta = true;
@@ -3442,14 +4567,64 @@ var Cadenza = class {
3442
4567
  );
3443
4568
  }
3444
4569
  /**
3445
- * Creates an EphemeralTask (self-destructs after exec or condition) without default registration.
3446
- * Useful for transients; optionally register if needed.
3447
- * @param name Identifier (may not be unique if not registered).
3448
- * @param func Function.
3449
- * @param description Optional.
3450
- * @param options Optional task options plus optional "once" (true) and "destroyCondition" (ctx => boolean).
3451
- * @returns The created EphemeralTask.
3452
- * @edge Destruction triggered post-exec via Node/Builder; emits meta-signal for cleanup.
4570
+ * Creates an ephemeral task with the specified configuration.
4571
+ * Ephemeral tasks are designed to self-destruct after execution or a certain condition is met.
4572
+ * This is useful for transient tasks such as resolving promises or performing cleanup operations.
4573
+ * They are not registered by default.
4574
+ * See {@link EphemeralTask} for more information.
4575
+ *
4576
+ * @param {string} name - The name of the task to be created.
4577
+ * @param {TaskFunction} func - The function that defines the logic of the task.
4578
+ * @param {string} [description] - An optional description of the task.
4579
+ * @param {TaskOptions & EphemeralTaskOptions} [options={}] - The configuration options for the task, including concurrency, timeouts, and retry policies.
4580
+ * @return {EphemeralTask} The created ephemeral task instance.
4581
+ *
4582
+ * @example
4583
+ * By default, ephemeral tasks are executed once and destroyed after execution.
4584
+ * ```ts
4585
+ * const task = Cadenza.createEphemeralTask('My ephemeral task', (ctx) => {
4586
+ * console.log('My task executed with context:', ctx);
4587
+ * });
4588
+ *
4589
+ * Cadenza.run(task); // Executes the task once and destroys it after execution
4590
+ * Cadenza.run(task); // Does nothing, since the task is destroyed
4591
+ * ```
4592
+ *
4593
+ * Use destroy condition to conditionally destroy the task
4594
+ * ```ts
4595
+ * const task = Cadenza.createEphemeralTask(
4596
+ * 'My ephemeral task',
4597
+ * (ctx) => {
4598
+ * console.log('My task executed with context:', ctx);
4599
+ * },
4600
+ * 'My ephemeral task description',
4601
+ * {
4602
+ * once: false, // Should the task be executed only once? Default is true
4603
+ * destroyCondition: (ctx) => ctx.foo > 10, // Should the task be destroyed after execution? Default is undefined
4604
+ * },
4605
+ * );
4606
+ *
4607
+ * Cadenza.run(task, { foo: 5 }); // The task will not be destroyed and can still be executed
4608
+ * Cadenza.run(task, { foo: 10 }); // The task will not be destroyed and can still be executed
4609
+ * Cadenza.run(task, { foo: 20 }); // The task will be destroyed after execution and cannot be executed anymore
4610
+ * Cadenza.run(task, { foo: 30 }); // This will not be executed
4611
+ * ```
4612
+ *
4613
+ * A practical use case for ephemeral tasks is to resolve a promise upon some external event.
4614
+ * ```ts
4615
+ * const task = Cadenza.createTask('Confirm something', (ctx, emit) => {
4616
+ * return new Promise((resolve) => {
4617
+ * ctx.foo = uuid();
4618
+ *
4619
+ * Cadenza.createEphemeralTask(`Resolve promise of ${ctx.foo}`, (c) => {
4620
+ * console.log('My task executed with context:', ctx);
4621
+ * resolve(c);
4622
+ * }).doOn(`socket.confirmation_received:${ctx.foo}`);
4623
+ *
4624
+ * emit('this_domain.confirmation_requested', ctx);
4625
+ * });
4626
+ * });
4627
+ * ```
3453
4628
  */
3454
4629
  static createEphemeralTask(name, func, description, options = {}) {
3455
4630
  this.bootstrap();
@@ -3500,45 +4675,72 @@ var Cadenza = class {
3500
4675
  );
3501
4676
  }
3502
4677
  /**
3503
- * Creates an EphemeralMetaTask for meta-layer transients.
3504
- * @param name Identifier.
3505
- * @param func Function.
3506
- * @param description Optional.
3507
- * @param options Optional task options plus optional "once" (true) and "destroyCondition" (ctx => boolean).
3508
- * @returns The created EphemeralMetaTask.
4678
+ * Creates an ephemeral meta task with the specified name, function, description, and options.
4679
+ * See {@link createEphemeralTask} and {@link createMetaTask} for more details.
4680
+ *
4681
+ * @param {string} name - The name of the task to be created.
4682
+ * @param {TaskFunction} func - The function to be executed as part of the task.
4683
+ * @param {string} [description] - An optional description of the task.
4684
+ * @param {TaskOptions & EphemeralTaskOptions} [options={}] - Additional options for configuring the task.
4685
+ * @return {EphemeralTask} The created ephemeral meta task.
3509
4686
  */
3510
4687
  static createEphemeralMetaTask(name, func, description, options = {}) {
3511
4688
  options.isMeta = true;
3512
4689
  return this.createEphemeralTask(name, func, description, options);
3513
4690
  }
3514
4691
  /**
3515
- * Creates a GraphRoutine (named entry to starting tasks) and registers it.
3516
- * @param name Unique identifier.
3517
- * @param tasks Starting tasks (can be empty, but warns as no-op).
3518
- * @param description Optional.
3519
- * @returns The created GraphRoutine.
3520
- * @edge If tasks empty, routine is valid but inert.
4692
+ * Creates a new routine with the specified name, tasks, and an optional description.
4693
+ * Routines are named entry points to starting tasks and are registered in the GraphRegistry.
4694
+ * They are used to group tasks together and provide a high-level structure for organizing and managing the execution of a set of tasks.
4695
+ * See {@link GraphRoutine} for more information.
4696
+ *
4697
+ * @param {string} name - The name of the routine to create.
4698
+ * @param {Task[]} tasks - A list of tasks to include in the routine.
4699
+ * @param {string} [description=""] - An optional description for the routine.
4700
+ * @return {GraphRoutine} A new instance of the GraphRoutine containing the specified tasks and description.
4701
+ *
4702
+ * @example
4703
+ * ```ts
4704
+ * const task1 = Cadenza.createTask("Task 1", () => {});
4705
+ * const task2 = Cadenza.createTask("Task 2", () => {});
4706
+ *
4707
+ * task1.then(task2);
4708
+ *
4709
+ * const routine = Cadenza.createRoutine("Some routine", [task1]);
4710
+ *
4711
+ * Cadenza.run(routine);
4712
+ *
4713
+ * // Or, routines can be triggered by signals
4714
+ * routine.doOn("some.signal");
4715
+ *
4716
+ * Cadenza.emit("some.signal", {});
4717
+ * ```
3521
4718
  */
3522
4719
  static createRoutine(name, tasks, description = "") {
3523
4720
  this.bootstrap();
3524
4721
  this.validateName(name);
3525
4722
  if (tasks.length === 0) {
3526
- console.warn(`Routine '${name}' created with no starting tasks (no-op).`);
4723
+ throw new Error(`Routine '${name}' created with no starting tasks.`);
3527
4724
  }
3528
4725
  return new GraphRoutine(name, tasks, description);
3529
4726
  }
3530
4727
  /**
3531
- * Creates a MetaRoutine for meta-layer entry points.
3532
- * @param name Identifier.
3533
- * @param tasks Starting tasks.
3534
- * @param description Optional.
3535
- * @returns The created MetaRoutine.
4728
+ * Creates a meta routine with a given name, tasks, and optional description.
4729
+ * Routines are named entry points to starting tasks and are registered in the GraphRegistry.
4730
+ * They are used to group tasks together and provide a high-level structure for organizing and managing the execution of a set of tasks.
4731
+ * See {@link GraphRoutine} and {@link createRoutine} for more information.
4732
+ *
4733
+ * @param {string} name - The name of the routine to be created.
4734
+ * @param {Task[]} tasks - An array of tasks that the routine will consist of.
4735
+ * @param {string} [description=""] - An optional description for the routine.
4736
+ * @return {GraphRoutine} A new instance of the `GraphRoutine` representing the created routine.
4737
+ * @throws {Error} If no starting tasks are provided.
3536
4738
  */
3537
4739
  static createMetaRoutine(name, tasks, description = "") {
3538
4740
  this.bootstrap();
3539
4741
  this.validateName(name);
3540
4742
  if (tasks.length === 0) {
3541
- console.warn(`Routine '${name}' created with no starting tasks (no-op).`);
4743
+ throw new Error(`Routine '${name}' created with no starting tasks.`);
3542
4744
  }
3543
4745
  return new GraphRoutine(name, tasks, description, true);
3544
4746
  }