@cadenza.io/core 3.14.0 → 3.15.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
@@ -265,6 +265,7 @@ var SignalBroker = class _SignalBroker {
265
265
  this.debouncedEmitters = /* @__PURE__ */ new Map();
266
266
  // TODO: Signals should be a class with a the observers, registered flag and other data.
267
267
  this.signalObservers = /* @__PURE__ */ new Map();
268
+ this.emittedSignalsRegistry = /* @__PURE__ */ new Set();
268
269
  this.emitStacks = /* @__PURE__ */ new Map();
269
270
  this.addSignal("meta.signal_broker.added");
270
271
  }
@@ -371,6 +372,9 @@ var SignalBroker = class _SignalBroker {
371
372
  this.addSignal(signal);
372
373
  this.signalObservers.get(signal).tasks.add(routineOrTask);
373
374
  }
375
+ registerEmittedSignal(signal) {
376
+ this.emittedSignalsRegistry.add(signal);
377
+ }
374
378
  /**
375
379
  * Unsubscribes a routine/task from a signal.
376
380
  * @param signal The signal.
@@ -646,14 +650,18 @@ var SignalBroker = class _SignalBroker {
646
650
  listObservedSignals() {
647
651
  return Array.from(this.signalObservers.keys());
648
652
  }
653
+ listEmittedSignals() {
654
+ return Array.from(this.emittedSignalsRegistry);
655
+ }
649
656
  reset() {
650
657
  this.emitStacks.clear();
651
658
  this.signalObservers.clear();
659
+ this.emittedSignalsRegistry.clear();
652
660
  }
653
661
  };
654
662
 
655
663
  // src/engine/GraphRunner.ts
656
- import { v4 as uuid6 } from "uuid";
664
+ import { v4 as uuid5 } from "uuid";
657
665
 
658
666
  // src/engine/GraphRun.ts
659
667
  import { v4 as uuid2 } from "uuid";
@@ -2158,8 +2166,178 @@ var GraphRoutine = class extends SignalEmitter {
2158
2166
  }
2159
2167
  };
2160
2168
 
2169
+ // src/engine/GraphRunner.ts
2170
+ var GraphRunner = class extends SignalEmitter {
2171
+ /**
2172
+ * Constructs a runner.
2173
+ * @param isMeta Meta flag (default false).
2174
+ * @edge Creates 'Start run' meta-task chained to registry gets.
2175
+ */
2176
+ constructor(isMeta = false) {
2177
+ super(isMeta);
2178
+ this.debug = false;
2179
+ this.verbose = false;
2180
+ this.isRunning = false;
2181
+ this.isMeta = false;
2182
+ this.isMeta = isMeta;
2183
+ this.strategy = Cadenza.runStrategy.PARALLEL;
2184
+ this.currentRun = new GraphRun(this.strategy);
2185
+ }
2186
+ /**
2187
+ * Adds tasks or routines to the current execution pipeline. Supports both individual tasks,
2188
+ * routines, or arrays of tasks and routines. Handles metadata and execution context management.
2189
+ *
2190
+ * @param {Task|GraphRoutine|(Task|GraphRoutine)[]} tasks - The task(s) or routine(s) to be added.
2191
+ * It can be a single task, a single routine, or an array of tasks and routines.
2192
+ * @param {AnyObject} [context={}] - Optional context object to provide execution trace and metadata.
2193
+ * Used to propagate information across task or routine executions.
2194
+ * @return {void} - This method does not return a value.
2195
+ */
2196
+ addTasks(tasks, context = {}) {
2197
+ let _tasks = Array.isArray(tasks) ? tasks : [tasks];
2198
+ if (_tasks.length === 0) {
2199
+ console.warn("No tasks/routines to add.");
2200
+ return;
2201
+ }
2202
+ let routineName = _tasks.map((t) => t.name).join(" | ");
2203
+ let routineVersion = null;
2204
+ let isMeta = _tasks.every((t) => t.isMeta);
2205
+ const allTasks = _tasks.flatMap((t) => {
2206
+ if (t instanceof GraphRoutine) {
2207
+ routineName = t.name;
2208
+ routineVersion = t.version;
2209
+ isMeta = t.isMeta;
2210
+ const routineTasks = [];
2211
+ t.forEachTask((task) => routineTasks.push(task));
2212
+ return routineTasks;
2213
+ }
2214
+ return t;
2215
+ });
2216
+ const isSubMeta = allTasks.some((t) => t.isSubMeta) || !!context.__isSubMeta;
2217
+ context.__isSubMeta = isSubMeta;
2218
+ const isNewTrace = !context.__routineExecId && !context.__metadata?.__executionTraceId && !context.__executionTraceId;
2219
+ const executionTraceId = context.__metadata?.__executionTraceId ?? context.__executionTraceId ?? uuid5();
2220
+ context.__executionTraceId = executionTraceId;
2221
+ const routineExecId = context.__routineExecId ?? uuid5();
2222
+ context.__routineExecId = routineExecId;
2223
+ const ctx = new GraphContext(context || {});
2224
+ if (!isSubMeta) {
2225
+ const contextData = ctx.export();
2226
+ if (isNewTrace) {
2227
+ this.emitMetrics("meta.runner.new_trace", {
2228
+ data: {
2229
+ uuid: executionTraceId,
2230
+ issuer_type: "service",
2231
+ // TODO: Add issuer type
2232
+ issuer_id: context.__metadata?.__issuerId ?? context.__issuerId ?? null,
2233
+ issued_at: formatTimestamp(Date.now()),
2234
+ intent: context.__metadata?.__intent ?? context.__intent ?? null,
2235
+ context: contextData,
2236
+ is_meta: isMeta
2237
+ },
2238
+ __metadata: {
2239
+ __executionTraceId: executionTraceId
2240
+ }
2241
+ });
2242
+ }
2243
+ this.emitMetrics("meta.runner.added_tasks", {
2244
+ data: {
2245
+ uuid: routineExecId,
2246
+ name: routineName,
2247
+ routineVersion,
2248
+ isMeta,
2249
+ executionTraceId,
2250
+ context: isNewTrace ? contextData.id : contextData,
2251
+ previousRoutineExecution: context.__localRoutineExecId ?? context.__metadata?.__routineExecId ?? null,
2252
+ created: formatTimestamp(Date.now())
2253
+ },
2254
+ __metadata: {
2255
+ __executionTraceId: executionTraceId
2256
+ }
2257
+ });
2258
+ }
2259
+ allTasks.forEach(
2260
+ (task) => this.currentRun.addNode(
2261
+ new GraphNode(task, ctx, routineExecId, [], this.debug, this.verbose)
2262
+ )
2263
+ );
2264
+ }
2265
+ /**
2266
+ * Executes the provided tasks or routines. Maintains the execution state
2267
+ * and handles synchronous or asynchronous processing.
2268
+ *
2269
+ * @param {Task|GraphRoutine|(Task|GraphRoutine)[]} [tasks] - A single task, a single routine, or an array of tasks or routines to execute. Optional.
2270
+ * @param {AnyObject} [context] - An optional context object to be used during task execution.
2271
+ * @return {GraphRun|Promise<GraphRun>} - Returns a `GraphRun` instance if the execution is synchronous, or a `Promise` resolving to a `GraphRun` for asynchronous execution.
2272
+ */
2273
+ run(tasks, context) {
2274
+ if (tasks) {
2275
+ this.addTasks(tasks, context ?? {});
2276
+ }
2277
+ if (this.isRunning) {
2278
+ return this.currentRun;
2279
+ }
2280
+ if (this.currentRun) {
2281
+ this.isRunning = true;
2282
+ const runResult = this.currentRun.run();
2283
+ if (runResult instanceof Promise) {
2284
+ return this.runAsync(runResult);
2285
+ }
2286
+ }
2287
+ return this.reset();
2288
+ }
2289
+ /**
2290
+ * Executes the provided asynchronous operation and resets the state afterwards.
2291
+ *
2292
+ * @param {Promise<void>} run - A promise representing the asynchronous operation to execute.
2293
+ * @return {Promise<GraphRun>} A promise that resolves to the result of the reset operation after the asynchronous operation completes.
2294
+ */
2295
+ async runAsync(run) {
2296
+ await run;
2297
+ return this.reset();
2298
+ }
2299
+ /**
2300
+ * Resets the current state of the graph, creating a new GraphRun instance
2301
+ * and returning the previous run instance.
2302
+ * If the debug mode is not enabled, it will destroy the existing resources.
2303
+ *
2304
+ * @return {GraphRun} The last GraphRun instance before the reset.
2305
+ */
2306
+ reset() {
2307
+ this.isRunning = false;
2308
+ const lastRun = this.currentRun;
2309
+ if (!this.debug) {
2310
+ this.destroy();
2311
+ }
2312
+ this.currentRun = new GraphRun(this.strategy);
2313
+ return lastRun;
2314
+ }
2315
+ setDebug(value) {
2316
+ this.debug = value;
2317
+ }
2318
+ setVerbose(value) {
2319
+ this.verbose = value;
2320
+ }
2321
+ destroy() {
2322
+ this.currentRun.destroy();
2323
+ }
2324
+ /**
2325
+ * Sets the strategy to be used for running the graph and initializes
2326
+ * the current run with the provided strategy if no process is currently running.
2327
+ *
2328
+ * @param {GraphRunStrategy} strategy - The strategy to use for running the graph.
2329
+ * @return {void}
2330
+ */
2331
+ setStrategy(strategy) {
2332
+ this.strategy = strategy;
2333
+ if (!this.isRunning) {
2334
+ this.currentRun = new GraphRun(this.strategy);
2335
+ }
2336
+ }
2337
+ };
2338
+
2161
2339
  // src/graph/definition/Task.ts
2162
- import { v4 as uuid5 } from "uuid";
2340
+ import { v4 as uuid6 } from "uuid";
2163
2341
 
2164
2342
  // src/graph/iterators/TaskIterator.ts
2165
2343
  var TaskIterator = class {
@@ -2308,7 +2486,7 @@ var Task = class _Task extends SignalEmitter {
2308
2486
  }
2309
2487
  clone(traverse = false, includeSignals = false) {
2310
2488
  const clonedTask = new _Task(
2311
- `${this.name} (clone ${uuid5().slice(0, 8)})`,
2489
+ `${this.name} (clone ${uuid6().slice(0, 8)})`,
2312
2490
  this.taskFunction,
2313
2491
  this.description,
2314
2492
  this.concurrency,
@@ -2793,6 +2971,14 @@ var Task = class _Task extends SignalEmitter {
2793
2971
  mapPrevious(callback) {
2794
2972
  return Array.from(this.predecessorTasks).map(callback);
2795
2973
  }
2974
+ makeRoutine(name, description) {
2975
+ if (this.isMeta) {
2976
+ Cadenza.createMetaRoutine(name, [this], description);
2977
+ } else {
2978
+ Cadenza.createRoutine(name, [this], description);
2979
+ }
2980
+ return this;
2981
+ }
2796
2982
  /**
2797
2983
  * Adds the specified signals to the current instance, making it observe them.
2798
2984
  * If the instance is already observing a signal, it will be skipped.
@@ -2849,29 +3035,33 @@ var Task = class _Task extends SignalEmitter {
2849
3035
  emitsOnFail(...signals) {
2850
3036
  signals.forEach((signal) => {
2851
3037
  this.signalsToEmitOnFail.add(signal);
2852
- this.attachSignal(signal, true);
3038
+ this.attachSignal(signal);
2853
3039
  });
2854
3040
  return this;
2855
3041
  }
2856
3042
  /**
2857
3043
  * Attaches a signal to the current context and emits metadata if the register flag is set.
2858
3044
  *
2859
- * @param {string} signal - The name of the signal to attach.
2860
- * @param {boolean} [isOnFail=false] - Indicates if the signal should be marked as "on fail".
3045
+ * @param {...string} signals - The names of the signals to attach.
2861
3046
  * @return {void} This method does not return a value.
2862
3047
  */
2863
- attachSignal(signal, isOnFail = false) {
2864
- this.emitsSignals.add(signal);
2865
- if (this.register) {
2866
- this.emitWithMetadata("meta.task.attached_signal", {
2867
- data: {
2868
- signalName: signal.split(":")[0],
2869
- taskName: this.name,
2870
- taskVersion: this.version,
2871
- isOnFail
2872
- }
2873
- });
2874
- }
3048
+ attachSignal(...signals) {
3049
+ signals.forEach((signal) => {
3050
+ this.emitsSignals.add(signal);
3051
+ Cadenza.broker.registerEmittedSignal(signal);
3052
+ if (this.register) {
3053
+ const isOnFail = this.signalsToEmitOnFail.has(signal);
3054
+ this.emitWithMetadata("meta.task.attached_signal", {
3055
+ data: {
3056
+ signalName: signal.split(":")[0],
3057
+ taskName: this.name,
3058
+ taskVersion: this.version,
3059
+ isOnFail
3060
+ }
3061
+ });
3062
+ }
3063
+ });
3064
+ return this;
2875
3065
  }
2876
3066
  /**
2877
3067
  * Unsubscribes the current instance from the specified signals.
@@ -3251,205 +3441,6 @@ var GraphRegistry = class _GraphRegistry {
3251
3441
  }
3252
3442
  };
3253
3443
 
3254
- // src/engine/GraphRunner.ts
3255
- var GraphRunner = class extends SignalEmitter {
3256
- /**
3257
- * Constructs a runner.
3258
- * @param isMeta Meta flag (default false).
3259
- * @edge Creates 'Start run' meta-task chained to registry gets.
3260
- */
3261
- constructor(isMeta = false) {
3262
- super(isMeta);
3263
- this.debug = false;
3264
- this.verbose = false;
3265
- this.isRunning = false;
3266
- this.isMeta = false;
3267
- this.isMeta = isMeta;
3268
- this.strategy = Cadenza.runStrategy.PARALLEL;
3269
- this.currentRun = new GraphRun(this.strategy);
3270
- }
3271
- init() {
3272
- if (this.isMeta) return;
3273
- Cadenza.createMetaTask(
3274
- "Start run",
3275
- this.startRun.bind(this),
3276
- "Starts a run"
3277
- ).doAfter(
3278
- GraphRegistry.instance.getTaskByName,
3279
- GraphRegistry.instance.getRoutineByName
3280
- );
3281
- }
3282
- /**
3283
- * Adds tasks or routines to the current execution pipeline. Supports both individual tasks,
3284
- * routines, or arrays of tasks and routines. Handles metadata and execution context management.
3285
- *
3286
- * @param {Task|GraphRoutine|(Task|GraphRoutine)[]} tasks - The task(s) or routine(s) to be added.
3287
- * It can be a single task, a single routine, or an array of tasks and routines.
3288
- * @param {AnyObject} [context={}] - Optional context object to provide execution trace and metadata.
3289
- * Used to propagate information across task or routine executions.
3290
- * @return {void} - This method does not return a value.
3291
- */
3292
- addTasks(tasks, context = {}) {
3293
- let _tasks = Array.isArray(tasks) ? tasks : [tasks];
3294
- if (_tasks.length === 0) {
3295
- console.warn("No tasks/routines to add.");
3296
- return;
3297
- }
3298
- let routineName = _tasks.map((t) => t.name).join(" | ");
3299
- let routineVersion = null;
3300
- let isMeta = _tasks.every((t) => t.isMeta);
3301
- const allTasks = _tasks.flatMap((t) => {
3302
- if (t instanceof GraphRoutine) {
3303
- routineName = t.name;
3304
- routineVersion = t.version;
3305
- isMeta = t.isMeta;
3306
- const routineTasks = [];
3307
- t.forEachTask((task) => routineTasks.push(task));
3308
- return routineTasks;
3309
- }
3310
- return t;
3311
- });
3312
- const isSubMeta = allTasks.some((t) => t.isSubMeta) || !!context.__isSubMeta;
3313
- context.__isSubMeta = isSubMeta;
3314
- const isNewTrace = !context.__routineExecId && !context.__metadata?.__executionTraceId && !context.__executionTraceId;
3315
- const executionTraceId = context.__metadata?.__executionTraceId ?? context.__executionTraceId ?? uuid6();
3316
- context.__executionTraceId = executionTraceId;
3317
- const routineExecId = context.__routineExecId ?? uuid6();
3318
- context.__routineExecId = routineExecId;
3319
- const ctx = new GraphContext(context || {});
3320
- if (!isSubMeta) {
3321
- const contextData = ctx.export();
3322
- if (isNewTrace) {
3323
- this.emitMetrics("meta.runner.new_trace", {
3324
- data: {
3325
- uuid: executionTraceId,
3326
- issuer_type: "service",
3327
- // TODO: Add issuer type
3328
- issuer_id: context.__metadata?.__issuerId ?? context.__issuerId ?? null,
3329
- issued_at: formatTimestamp(Date.now()),
3330
- intent: context.__metadata?.__intent ?? context.__intent ?? null,
3331
- context: contextData,
3332
- is_meta: isMeta
3333
- },
3334
- __metadata: {
3335
- __executionTraceId: executionTraceId
3336
- }
3337
- });
3338
- }
3339
- this.emitMetrics("meta.runner.added_tasks", {
3340
- data: {
3341
- uuid: routineExecId,
3342
- name: routineName,
3343
- routineVersion,
3344
- isMeta,
3345
- executionTraceId,
3346
- context: isNewTrace ? contextData.id : contextData,
3347
- previousRoutineExecution: context.__localRoutineExecId ?? context.__metadata?.__routineExecId ?? null,
3348
- // TODO: There is a chance this is not added to the database yet...
3349
- created: formatTimestamp(Date.now())
3350
- },
3351
- __metadata: {
3352
- __executionTraceId: executionTraceId
3353
- }
3354
- });
3355
- }
3356
- allTasks.forEach(
3357
- (task) => this.currentRun.addNode(
3358
- new GraphNode(task, ctx, routineExecId, [], this.debug, this.verbose)
3359
- )
3360
- );
3361
- }
3362
- /**
3363
- * Executes the provided tasks or routines. Maintains the execution state
3364
- * and handles synchronous or asynchronous processing.
3365
- *
3366
- * @param {Task|GraphRoutine|(Task|GraphRoutine)[]} [tasks] - A single task, a single routine, or an array of tasks or routines to execute. Optional.
3367
- * @param {AnyObject} [context] - An optional context object to be used during task execution.
3368
- * @return {GraphRun|Promise<GraphRun>} - Returns a `GraphRun` instance if the execution is synchronous, or a `Promise` resolving to a `GraphRun` for asynchronous execution.
3369
- */
3370
- run(tasks, context) {
3371
- if (tasks) {
3372
- this.addTasks(tasks, context ?? {});
3373
- }
3374
- if (this.isRunning) {
3375
- return this.currentRun;
3376
- }
3377
- if (this.currentRun) {
3378
- this.isRunning = true;
3379
- const runResult = this.currentRun.run();
3380
- if (runResult instanceof Promise) {
3381
- return this.runAsync(runResult);
3382
- }
3383
- }
3384
- return this.reset();
3385
- }
3386
- /**
3387
- * Executes the provided asynchronous operation and resets the state afterwards.
3388
- *
3389
- * @param {Promise<void>} run - A promise representing the asynchronous operation to execute.
3390
- * @return {Promise<GraphRun>} A promise that resolves to the result of the reset operation after the asynchronous operation completes.
3391
- */
3392
- async runAsync(run) {
3393
- await run;
3394
- return this.reset();
3395
- }
3396
- /**
3397
- * Resets the current state of the graph, creating a new GraphRun instance
3398
- * and returning the previous run instance.
3399
- * If the debug mode is not enabled, it will destroy the existing resources.
3400
- *
3401
- * @return {GraphRun} The last GraphRun instance before the reset.
3402
- */
3403
- reset() {
3404
- this.isRunning = false;
3405
- const lastRun = this.currentRun;
3406
- if (!this.debug) {
3407
- this.destroy();
3408
- }
3409
- this.currentRun = new GraphRun(this.strategy);
3410
- return lastRun;
3411
- }
3412
- setDebug(value) {
3413
- this.debug = value;
3414
- }
3415
- setVerbose(value) {
3416
- this.verbose = value;
3417
- }
3418
- destroy() {
3419
- this.currentRun.destroy();
3420
- }
3421
- /**
3422
- * Sets the strategy to be used for running the graph and initializes
3423
- * the current run with the provided strategy if no process is currently running.
3424
- *
3425
- * @param {GraphRunStrategy} strategy - The strategy to use for running the graph.
3426
- * @return {void}
3427
- */
3428
- setStrategy(strategy) {
3429
- this.strategy = strategy;
3430
- if (!this.isRunning) {
3431
- this.currentRun = new GraphRun(this.strategy);
3432
- }
3433
- }
3434
- // TODO This should not live here. This is deputy related.
3435
- startRun(context, emit) {
3436
- if (context.task || context.routine) {
3437
- const routine = context.task ?? context.routine;
3438
- delete context.task;
3439
- delete context.routine;
3440
- context.__routineExecId = context.__metadata?.__deputyExecId ?? null;
3441
- context.__isDeputy = true;
3442
- this.run(routine, context);
3443
- return true;
3444
- } else {
3445
- context.errored = true;
3446
- context.__error = "No routine or task defined.";
3447
- emit("meta.runner.failed", context);
3448
- return false;
3449
- }
3450
- }
3451
- };
3452
-
3453
3444
  // src/graph/definition/DebounceTask.ts
3454
3445
  var DebounceTask = class extends Task {
3455
3446
  constructor(name, task, description = "", debounceTime = 1e3, leading = false, trailing = true, maxWait = 0, concurrency = 0, timeout = 0, register = true, isUnique = false, isMeta = false, isSubMeta = false, isHidden = false, inputSchema = void 0, validateInputSchema = false, outputSchema = void 0, validateOutputSchema = false) {
@@ -4408,8 +4399,6 @@ var Cadenza = class {
4408
4399
  }
4409
4400
  this.registry = GraphRegistry.instance;
4410
4401
  this.broker.init();
4411
- this.runner.init();
4412
- this.metaRunner.init();
4413
4402
  }
4414
4403
  /**
4415
4404
  * Retrieves the available strategies for running graphs.