@cadenza.io/core 1.10.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -36,6 +36,41 @@ __export(index_exports, {
36
36
  });
37
37
  module.exports = __toCommonJS(index_exports);
38
38
 
39
+ // src/utils/tools.ts
40
+ function deepCloneFilter(input, filterOut = () => false) {
41
+ if (input === null || typeof input !== "object") {
42
+ return input;
43
+ }
44
+ const visited = /* @__PURE__ */ new WeakMap();
45
+ const stack = [];
46
+ const output = Array.isArray(input) ? [] : {};
47
+ stack.push({ source: input, target: output });
48
+ visited.set(input, output);
49
+ while (stack.length) {
50
+ const { source, target, key } = stack.pop();
51
+ const currentTarget = key !== void 0 ? target[key] : target;
52
+ for (const [k, value] of Object.entries(source)) {
53
+ if (filterOut(k)) continue;
54
+ if (value && typeof value === "object") {
55
+ if (visited.has(value)) {
56
+ currentTarget[k] = visited.get(value);
57
+ continue;
58
+ }
59
+ const clonedValue = Array.isArray(value) ? [] : {};
60
+ currentTarget[k] = clonedValue;
61
+ visited.set(value, clonedValue);
62
+ stack.push({ source: value, target: currentTarget, key: k });
63
+ } else {
64
+ currentTarget[k] = value;
65
+ }
66
+ }
67
+ }
68
+ return output;
69
+ }
70
+ function formatTimestamp(timestamp) {
71
+ return new Date(timestamp).toISOString();
72
+ }
73
+
39
74
  // src/engine/SignalBroker.ts
40
75
  var SignalBroker = class _SignalBroker {
41
76
  // execId -> emitted signals
@@ -102,8 +137,11 @@ var SignalBroker = class _SignalBroker {
102
137
  },
103
138
  "Executes queued signals and clears the stack",
104
139
  500,
105
- { maxWait: 1e4 }
106
- ).doOn("meta.process_signal_queue_requested");
140
+ {
141
+ maxWait: 1e4,
142
+ leading: true
143
+ }
144
+ ).doOn("meta.process_signal_queue_requested").emitsAfter("meta.signal_broker.queue_empty");
107
145
  this.getSignalsTask = Cadenza.createMetaTask("Get signals", (ctx) => {
108
146
  return {
109
147
  __signals: Array.from(this.signalObservers.keys()),
@@ -145,6 +183,7 @@ var SignalBroker = class _SignalBroker {
145
183
  */
146
184
  emit(signal, context = {}) {
147
185
  const execId = context.__routineExecId || "global";
186
+ delete context.__routineExecId;
148
187
  if (!this.emitStacks.has(execId)) this.emitStacks.set(execId, /* @__PURE__ */ new Map());
149
188
  const stack = this.emitStacks.get(execId);
150
189
  stack.set(signal, context);
@@ -157,29 +196,36 @@ var SignalBroker = class _SignalBroker {
157
196
  }
158
197
  }
159
198
  execute(signal, context) {
160
- const isMeta = signal.startsWith("meta");
161
- const emittedAt = Date.now();
162
- const data = {
163
- ...context,
164
- __signalEmission: {
199
+ const isMeta = signal.startsWith("meta.");
200
+ const isSubMeta = signal.startsWith("sub_meta.");
201
+ if (!isSubMeta && (!isMeta || this.debug)) {
202
+ const emittedAt = Date.now();
203
+ context.__signalEmission = {
165
204
  ...context.__signalEmission,
166
205
  signalName: signal,
167
- emittedAt,
206
+ emittedAt: formatTimestamp(emittedAt),
168
207
  isMeta
169
- }
170
- };
171
- let executed;
172
- executed = this.executeListener(signal, data);
173
- const parts = signal.slice(0, Math.max(signal.lastIndexOf(":"), signal.lastIndexOf("."))).split(".");
174
- for (let i = parts.length; i > 0; i--) {
175
- const parent = parts.slice(0, i).join(".");
176
- executed = executed || this.executeListener(parent + ".*", data);
208
+ };
209
+ } else if (isSubMeta) {
210
+ context.__isSubMeta = true;
211
+ delete context.__signalEmission;
212
+ } else {
213
+ delete context.__signalEmission;
177
214
  }
178
- if (this.debug) {
179
- console.log(
180
- `Emitted signal ${signal} with context ${JSON.stringify(data)}`,
181
- executed ? "\u2705" : "\u274C"
182
- );
215
+ let executed;
216
+ executed = this.executeListener(signal, context);
217
+ if (!isSubMeta) {
218
+ const parts = signal.slice(0, Math.max(signal.lastIndexOf(":"), signal.lastIndexOf("."))).split(".");
219
+ for (let i = parts.length; i > 0; i--) {
220
+ const parent = parts.slice(0, i).join(".");
221
+ executed = executed || this.executeListener(parent + ".*", context);
222
+ }
223
+ if (this.debug) {
224
+ console.log(
225
+ `Emitted signal ${signal} with context ${JSON.stringify(context)}`,
226
+ executed ? "\u2705" : "\u274C"
227
+ );
228
+ }
183
229
  }
184
230
  return executed;
185
231
  }
@@ -486,40 +532,6 @@ var import_uuid3 = require("uuid");
486
532
 
487
533
  // src/graph/context/GraphContext.ts
488
534
  var import_uuid2 = require("uuid");
489
-
490
- // src/utils/tools.ts
491
- function deepCloneFilter(input, filterOut = () => false) {
492
- if (input === null || typeof input !== "object") {
493
- return input;
494
- }
495
- const visited = /* @__PURE__ */ new WeakMap();
496
- const stack = [];
497
- const output = Array.isArray(input) ? [] : {};
498
- stack.push({ source: input, target: output });
499
- visited.set(input, output);
500
- while (stack.length) {
501
- const { source, target, key } = stack.pop();
502
- const currentTarget = key !== void 0 ? target[key] : target;
503
- for (const [k, value] of Object.entries(source)) {
504
- if (filterOut(k)) continue;
505
- if (value && typeof value === "object") {
506
- if (visited.has(value)) {
507
- currentTarget[k] = visited.get(value);
508
- continue;
509
- }
510
- const clonedValue = Array.isArray(value) ? [] : {};
511
- currentTarget[k] = clonedValue;
512
- visited.set(value, clonedValue);
513
- stack.push({ source: value, target: currentTarget, key: k });
514
- } else {
515
- currentTarget[k] = value;
516
- }
517
- }
518
- }
519
- return output;
520
- }
521
-
522
- // src/graph/context/GraphContext.ts
523
535
  var GraphContext = class _GraphContext {
524
536
  // __keys, frozen
525
537
  constructor(context) {
@@ -679,7 +691,10 @@ function sleep(ms) {
679
691
  // src/graph/execution/GraphNode.ts
680
692
  var GraphNode = class _GraphNode extends SignalEmitter {
681
693
  constructor(task, context, routineExecId, prevNodes = [], debug = false) {
682
- super(task.isMeta);
694
+ var _a;
695
+ super(
696
+ task.isMeta && !debug || task.isSubMeta || ((_a = context == null ? void 0 : context.getMetaData()) == null ? void 0 : _a.__isSubMeta)
697
+ );
683
698
  this.divided = false;
684
699
  this.splitGroupId = "";
685
700
  this.processing = false;
@@ -750,6 +765,7 @@ var GraphNode = class _GraphNode extends SignalEmitter {
750
765
  return this.task.getTag(this.context);
751
766
  }
752
767
  scheduleOn(layer) {
768
+ var _a;
753
769
  let shouldSchedule = true;
754
770
  const nodes = layer.getNodesByRoutineExecId(this.routineExecId);
755
771
  for (const node of nodes) {
@@ -766,23 +782,56 @@ var GraphNode = class _GraphNode extends SignalEmitter {
766
782
  if (shouldSchedule) {
767
783
  this.layer = layer;
768
784
  layer.add(this);
785
+ const context = this.context.getFullContext();
769
786
  const scheduledAt = Date.now();
770
787
  this.emitWithMetadata("meta.node.scheduled", {
771
- ...this.lightExport(),
772
- __scheduled: scheduledAt
788
+ data: {
789
+ uuid: this.id,
790
+ routineExecutionId: this.routineExecId,
791
+ contractId: context.__contractId,
792
+ context: this.context.export(),
793
+ taskId: this.task.id,
794
+ taskName: this.task.name,
795
+ isMeta: this.isMeta(),
796
+ isScheduled: true,
797
+ splitGroupId: this.splitGroupId,
798
+ created: formatTimestamp(scheduledAt)
799
+ }
773
800
  });
774
- const context = this.context.getFullContext();
775
- if (context.__signalEmission !== void 0 && (!this.isMeta() || this.debug)) {
801
+ this.previousNodes.forEach((node) => {
802
+ this.emitWithMetadata("meta.node.mapped", {
803
+ data: {
804
+ taskExecutionId: this.id,
805
+ previousTaskExecutionId: node.id,
806
+ executionCount: "increment"
807
+ },
808
+ filter: {
809
+ taskId: this.task.id,
810
+ previousTaskId: node.task.id
811
+ }
812
+ });
813
+ if (node.failed || node.errored) {
814
+ this.emitWithMetadata("meta.node.failed_mapped", {
815
+ data: {
816
+ executionCount: "increment"
817
+ },
818
+ filter: {
819
+ taskId: this.task.id,
820
+ failTaskId: node.task.id
821
+ }
822
+ });
823
+ }
824
+ });
825
+ if (((_a = context.__signalEmission) == null ? void 0 : _a.signalName) && (!this.isMeta() || this.debug)) {
776
826
  this.emitWithMetadata("meta.node.consumed_signal", {
777
- __signalConsumption: {
827
+ data: {
778
828
  signalName: context.__signalEmission.signalName,
779
829
  taskId: this.task.id,
780
830
  taskExecutionId: this.id,
781
- consumedAt: scheduledAt
831
+ consumedAt: formatTimestamp(scheduledAt)
782
832
  }
783
833
  });
784
834
  delete context.__signalEmission;
785
- this.migrate(context);
786
835
  }
787
836
  }
788
837
  }
@@ -790,14 +839,25 @@ var GraphNode = class _GraphNode extends SignalEmitter {
790
839
  if (this.executionStart === 0) {
791
840
  this.executionStart = Date.now();
792
841
  }
793
- const memento = this.lightExport();
794
842
  if (this.previousNodes.length === 0) {
795
- this.emitWithMetadata("meta.node.started_routine_execution", memento);
843
+ this.emitWithMetadata("meta.node.started_routine_execution", {
844
+ data: {
845
+ isRunning: true,
846
+ started: formatTimestamp(this.executionStart)
847
+ },
848
+ filter: { uuid: this.routineExecId }
849
+ });
796
850
  }
797
851
  if (this.debug) {
798
852
  this.log();
799
853
  }
800
- this.emitWithMetadata("meta.node.started", memento);
854
+ this.emitWithMetadata("meta.node.started", {
855
+ data: {
856
+ isRunning: true,
857
+ started: formatTimestamp(this.executionStart)
858
+ },
859
+ filter: { uuid: this.id }
860
+ });
801
861
  return this.executionStart;
802
862
  }
803
863
  end() {
@@ -807,15 +867,44 @@ var GraphNode = class _GraphNode extends SignalEmitter {
807
867
  this.processing = false;
808
868
  const end = Date.now();
809
869
  this.executionTime = end - this.executionStart;
810
- const memento = this.lightExport();
870
+ const context = this.context.getFullContext();
811
871
  if (this.errored || this.failed) {
812
- this.emitWithMetadata("meta.node.errored", memento);
872
+ this.emitWithMetadata("meta.node.errored", {
873
+ data: {
874
+ isRunning: false,
875
+ errored: this.errored,
876
+ failed: this.failed,
877
+ errorMessage: context.__error
878
+ },
879
+ filter: { uuid: this.id }
880
+ });
813
881
  }
814
- this.emitWithMetadata("meta.node.ended", memento);
882
+ this.emitWithMetadata("meta.node.ended", {
883
+ data: {
884
+ isRunning: false,
885
+ isComplete: true,
886
+ resultContext: this.context.export(),
887
+ errored: this.errored,
888
+ failed: this.failed,
889
+ errorMessage: context.__error,
890
+ progress: 1,
891
+ ended: formatTimestamp(end)
892
+ },
893
+ filter: { uuid: this.id }
894
+ });
815
895
  if (this.graphDone()) {
816
896
  this.emitWithMetadata(
817
897
  `meta.node.ended_routine_execution:${this.routineExecId}`,
818
- memento
898
+ {
899
+ data: {
900
+ isRunning: false,
901
+ isComplete: true,
902
+ resultContext: this.context.export(),
903
+ progress: 1,
904
+ ended: formatTimestamp(end)
905
+ },
906
+ filter: { uuid: this.routineExecId }
907
+ }
819
908
  );
820
909
  }
821
910
  return end;
@@ -877,23 +966,41 @@ var GraphNode = class _GraphNode extends SignalEmitter {
877
966
  }
878
967
  }
879
968
  emitWithMetadata(signal, ctx) {
880
- this.emit(signal, {
881
- ...ctx,
882
- __signalEmission: {
969
+ if (this.silent) return;
970
+ const data = { ...ctx };
971
+ if (!this.task.isHidden) {
972
+ data.__signalEmission = {
883
973
  taskId: this.task.id,
884
974
  taskExecutionId: this.id
885
- }
886
- });
975
+ };
976
+ data.__metadata = {
977
+ __routineExecId: this.routineExecId
978
+ };
979
+ }
980
+ this.emit(signal, data);
887
981
  }
888
982
  onProgress(progress) {
889
- var _a, _b, _c;
983
+ var _a, _b;
890
984
  progress = Math.min(Math.max(0, progress), 1);
891
- this.emitWithMetadata(`meta.node.progress:${this.routineExecId}`, {
892
- __nodeId: this.id,
893
- __routineExecId: this.routineExecId,
894
- __progress: progress,
895
- __weight: this.task.progressWeight / ((_c = (_b = (_a = this.layer) == null ? void 0 : _a.getNodesByRoutineExecId(this.routineExecId)) == null ? void 0 : _b.length) != null ? _c : 1)
985
+ this.emitWithMetadata("meta.node.progress", {
986
+ data: {
987
+ progress
988
+ },
989
+ filter: {
990
+ uuid: this.id
991
+ }
896
992
  });
993
+ this.emitWithMetadata(
994
+ `meta.node.routine_execution_progress:${this.routineExecId}`,
995
+ {
996
+ data: {
997
+ progress: progress * this.task.progressWeight / ((_b = (_a = this.layer) == null ? void 0 : _a.getIdenticalNodes(this).length) != null ? _b : 1)
998
+ },
999
+ filter: {
1000
+ uuid: this.routineExecId
1001
+ }
1002
+ }
1003
+ );
897
1004
  }
898
1005
  postProcess() {
899
1006
  if (typeof this.result === "string") {
@@ -910,11 +1017,11 @@ var GraphNode = class _GraphNode extends SignalEmitter {
910
1017
  }
911
1018
  if (this.errored || this.failed) {
912
1019
  this.task.mapOnFailSignals(
913
- (signal) => this.emitWithMetadata(signal, this.context)
1020
+ (signal) => this.emitWithMetadata(signal, this.context.getFullContext())
914
1021
  );
915
1022
  } else {
916
1023
  this.task.mapSignals(
917
- (signal) => this.emitWithMetadata(signal, this.context)
1024
+ (signal) => this.emitWithMetadata(signal, this.context.getFullContext())
918
1025
  );
919
1026
  }
920
1027
  this.end();
@@ -1303,8 +1410,24 @@ var GraphRoutine = class extends SignalParticipant {
1303
1410
  this.name = name;
1304
1411
  this.description = description;
1305
1412
  this.isMeta = isMeta;
1306
- tasks.forEach((t) => this.tasks.add(t));
1307
- this.emit("meta.routine.created", { __routine: this });
1413
+ this.emit("meta.routine.created", {
1414
+ data: {
1415
+ uuid: this.id,
1416
+ name: this.name,
1417
+ description: this.description,
1418
+ isMeta: this.isMeta
1419
+ },
1420
+ __routineInstance: this
1421
+ });
1422
+ tasks.forEach((t) => {
1423
+ this.tasks.add(t);
1424
+ this.emit("meta.routine.task_added", {
1425
+ data: {
1426
+ taskId: t.id,
1427
+ routineId: this.id
1428
+ }
1429
+ });
1430
+ });
1308
1431
  }
1309
1432
  /**
1310
1433
  * Applies callback to starting tasks.
@@ -1334,7 +1457,10 @@ var GraphRoutine = class extends SignalParticipant {
1334
1457
  */
1335
1458
  destroy() {
1336
1459
  this.tasks.clear();
1337
- this.emit("meta.routine.destroyed", { __id: this.id });
1460
+ this.emit("meta.routine.destroyed", {
1461
+ data: { deleted: true },
1462
+ filter: { uuid: this.id }
1463
+ });
1338
1464
  }
1339
1465
  };
1340
1466
 
@@ -1384,6 +1510,8 @@ var Task = class extends SignalParticipant {
1384
1510
  * @param register Register via signal (default true).
1385
1511
  * @param isUnique
1386
1512
  * @param isMeta
1513
+ * @param isSubMeta
1514
+ * @param isHidden
1387
1515
  * @param getTagCallback
1388
1516
  * @param inputSchema
1389
1517
  * @param validateInputContext
@@ -1395,14 +1523,17 @@ var Task = class extends SignalParticipant {
1395
1523
  * @param retryDelayFactor
1396
1524
  * @edge Emits 'meta.task.created' with { __task: this } for seed.
1397
1525
  */
1398
- constructor(name, task, description = "", concurrency = 0, timeout = 0, register = true, isUnique = false, isMeta = false, getTagCallback = void 0, inputSchema = void 0, validateInputContext = false, outputSchema = void 0, validateOutputContext = false, retryCount = 0, retryDelay = 0, retryDelayMax = 0, retryDelayFactor = 1) {
1526
+ 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) {
1399
1527
  super();
1400
1528
  this.isMeta = false;
1529
+ this.isSubMeta = false;
1530
+ this.isHidden = false;
1401
1531
  this.isUnique = false;
1402
1532
  this.throttled = false;
1403
1533
  this.isSignal = false;
1404
1534
  this.isDeputy = false;
1405
1535
  this.isEphemeral = false;
1536
+ this.isDebounce = false;
1406
1537
  this.inputContextSchema = void 0;
1407
1538
  this.validateInputContext = false;
1408
1539
  this.outputContextSchema = void 0;
@@ -1425,6 +1556,8 @@ var Task = class extends SignalParticipant {
1425
1556
  this.timeout = timeout;
1426
1557
  this.isUnique = isUnique;
1427
1558
  this.isMeta = isMeta;
1559
+ this.isSubMeta = isSubMeta;
1560
+ this.isHidden = isHidden;
1428
1561
  this.inputContextSchema = inputSchema;
1429
1562
  this.validateInputContext = validateInputContext;
1430
1563
  this.outputContextSchema = outputSchema;
@@ -1437,8 +1570,35 @@ var Task = class extends SignalParticipant {
1437
1570
  this.getTag = (context) => getTagCallback(context, this);
1438
1571
  this.throttled = true;
1439
1572
  }
1440
- if (register) {
1441
- this.emit("meta.task.created", { __task: this });
1573
+ if (register && !this.isHidden && !this.isSubMeta) {
1574
+ const { __functionString, __getTagCallback } = this.export();
1575
+ this.emit("meta.task.created", {
1576
+ __task: {
1577
+ uuid: this.id,
1578
+ name: this.name,
1579
+ description: this.description,
1580
+ functionString: __functionString,
1581
+ tagIdGetter: __getTagCallback,
1582
+ layerIndex: this.layerIndex,
1583
+ concurrency: this.concurrency,
1584
+ retryCount: this.retryCount,
1585
+ retryDelay: this.retryDelay,
1586
+ retryDelayMax: this.retryDelayMax,
1587
+ retryDelayFactor: this.retryDelayFactor,
1588
+ timeout: this.timeout,
1589
+ isUnique: this.isUnique,
1590
+ isSignal: this.isSignal,
1591
+ isThrottled: this.throttled,
1592
+ isDebounce: this.isDebounce,
1593
+ isEphemeral: this.isEphemeral,
1594
+ isMeta: this.isMeta,
1595
+ validateInputContext: this.validateInputContext,
1596
+ validateOutputContext: this.validateOutputContext,
1597
+ inputContextSchemaId: this.inputContextSchema,
1598
+ outputContextSchemaId: this.outputContextSchema
1599
+ },
1600
+ __taskInstance: this
1601
+ });
1442
1602
  }
1443
1603
  }
1444
1604
  getTag(context) {
@@ -1648,6 +1808,12 @@ var Task = class extends SignalParticipant {
1648
1808
  this.decouple(pred);
1649
1809
  throw new Error(`Cycle adding pred ${pred.name} to ${this.name}`);
1650
1810
  }
1811
+ this.emit("meta.task.relationship_added", {
1812
+ data: {
1813
+ taskId: this.id,
1814
+ predecessorTaskId: pred.id
1815
+ }
1816
+ });
1651
1817
  }
1652
1818
  this.updateProgressWeights();
1653
1819
  return this;
@@ -1662,6 +1828,12 @@ var Task = class extends SignalParticipant {
1662
1828
  this.decouple(next);
1663
1829
  throw new Error(`Cycle adding next ${next.name} to ${this.name}`);
1664
1830
  }
1831
+ this.emit("meta.task.relationship_added", {
1832
+ data: {
1833
+ taskId: next.id,
1834
+ predecessorTaskId: this.id
1835
+ }
1836
+ });
1665
1837
  }
1666
1838
  this.updateProgressWeights();
1667
1839
  return this;
@@ -1687,6 +1859,12 @@ var Task = class extends SignalParticipant {
1687
1859
  this.decouple(task);
1688
1860
  throw new Error(`Cycle adding onFail ${task.name} to ${this.name}`);
1689
1861
  }
1862
+ this.emit("meta.task.on_fail_relationship_added", {
1863
+ data: {
1864
+ taskId: this.id,
1865
+ onFailTaskId: task.id
1866
+ }
1867
+ });
1690
1868
  }
1691
1869
  return this;
1692
1870
  }
@@ -1718,11 +1896,20 @@ var Task = class extends SignalParticipant {
1718
1896
  return layers;
1719
1897
  }
1720
1898
  updateLayerFromPredecessors() {
1899
+ const prevLayerIndex = this.layerIndex;
1721
1900
  let maxPred = 0;
1722
1901
  this.predecessorTasks.forEach(
1723
1902
  (pred) => maxPred = Math.max(maxPred, pred.layerIndex)
1724
1903
  );
1725
1904
  this.layerIndex = maxPred + 1;
1905
+ if (prevLayerIndex !== this.layerIndex) {
1906
+ this.emit("meta.task.layer_index_changed", {
1907
+ data: {
1908
+ layerIndex: this.layerIndex
1909
+ },
1910
+ filter: { uuid: this.id }
1911
+ });
1912
+ }
1726
1913
  const queue = Array.from(this.nextTasks);
1727
1914
  while (queue.length) {
1728
1915
  const next = queue.shift();
@@ -1762,7 +1949,10 @@ var Task = class extends SignalParticipant {
1762
1949
  this.predecessorTasks.clear();
1763
1950
  this.onFailTasks.clear();
1764
1951
  this.destroyed = true;
1765
- this.emit("meta.task.destroyed", { __id: this.id });
1952
+ this.emit("meta.task.destroyed", {
1953
+ data: { deleted: true },
1954
+ filter: { uuid: this.id }
1955
+ });
1766
1956
  }
1767
1957
  export() {
1768
1958
  return {
@@ -1808,13 +1998,13 @@ var GraphRegistry = class _GraphRegistry {
1808
1998
  this.tasks = /* @__PURE__ */ new Map();
1809
1999
  this.routines = /* @__PURE__ */ new Map();
1810
2000
  this.registerTask = new Task(
1811
- "Registry Seed",
2001
+ "Register task",
1812
2002
  (context) => {
1813
- const { __task } = context;
1814
- if (__task && !this.tasks.has(__task.id)) {
1815
- console.log("Registering task:", __task.name);
1816
- this.tasks.set(__task.id, __task);
2003
+ const { __taskInstance } = context;
2004
+ if (__taskInstance && !this.tasks.has(__taskInstance.id)) {
2005
+ this.tasks.set(__taskInstance.id, __taskInstance);
1817
2006
  }
2007
+ delete context.__taskInstance;
1818
2008
  return true;
1819
2009
  },
1820
2010
  "Registers tasks. Seed for meta.taskCreated",
@@ -1919,10 +2109,11 @@ var GraphRegistry = class _GraphRegistry {
1919
2109
  this.registerRoutine = Cadenza.createMetaTask(
1920
2110
  "Register routine",
1921
2111
  (context) => {
1922
- const { __routine } = context;
1923
- if (__routine && !this.routines.has(__routine.id)) {
1924
- this.routines.set(__routine.id, __routine);
2112
+ const { __routineInstance } = context;
2113
+ if (__routineInstance && !this.routines.has(__routineInstance.id)) {
2114
+ this.routines.set(__routineInstance.id, __routineInstance);
1925
2115
  }
2116
+ delete context.__routineInstance;
1926
2117
  return true;
1927
2118
  },
1928
2119
  "Registers routine."
@@ -2059,28 +2250,18 @@ var GraphRunner = class extends SignalEmitter {
2059
2250
  const ctx = new GraphContext(context || {});
2060
2251
  const routineExecId = (_a = context.__routineExecId) != null ? _a : (0, import_uuid6.v4)();
2061
2252
  context.__routineExecId = routineExecId;
2062
- const data = {
2063
- __routineExecId: routineExecId,
2064
- __routineName: routineName,
2065
- __isMeta: isMeta,
2066
- __routineId: routineId,
2067
- __context: ctx.export(),
2068
- __previousRoutineExecution: (_c = (_b = context.__metaData) == null ? void 0 : _b.__routineExecId) != null ? _c : null,
2069
- __contractId: (_f = (_e = (_d = context.__metaData) == null ? void 0 : _d.__contractId) != null ? _e : context.__contractId) != null ? _f : null,
2070
- __task: {
2071
- __name: routineName
2072
- },
2073
- __scheduled: Date.now()
2074
- };
2075
- this.emit("meta.runner.added_tasks", data);
2076
- if (this.debug) {
2077
- console.log(
2078
- `${this.isMeta ? "Meta" : ""}Runner added tasks`,
2079
- allTasks.map((t) => t.name),
2080
- "with context",
2081
- ctx.getFullContext()
2082
- );
2083
- }
2253
+ this.emit("meta.runner.added_tasks", {
2254
+ data: {
2255
+ uuid: routineExecId,
2256
+ name: routineName,
2257
+ isMeta,
2258
+ contractId: (_d = (_c = (_b = context.__metaData) == null ? void 0 : _b.__contractId) != null ? _c : context.__contractId) != null ? _d : null,
2259
+ context: ctx.export(),
2260
+ previousRoutineExecution: (_f = (_e = context.__metaData) == null ? void 0 : _e.__routineExecId) != null ? _f : null,
2261
+ // TODO: There is a chance this is not added to the database yet...
2262
+ created: formatTimestamp(Date.now())
2263
+ }
2264
+ });
2084
2265
  allTasks.forEach(
2085
2266
  (task) => this.currentRun.addNode(
2086
2267
  new GraphNode(task, ctx, routineExecId, [], this.debug)
@@ -2151,7 +2332,7 @@ var GraphRunner = class extends SignalEmitter {
2151
2332
 
2152
2333
  // src/graph/definition/DebounceTask.ts
2153
2334
  var DebounceTask = class extends Task {
2154
- constructor(name, task, description = "", debounceTime = 1e3, leading = false, trailing = true, maxWait = 0, concurrency = 0, timeout = 0, register = true, isUnique = false, isMeta = false, inputSchema = void 0, validateInputSchema = false, outputSchema = void 0, validateOutputSchema = false) {
2335
+ 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) {
2155
2336
  super(
2156
2337
  name,
2157
2338
  task,
@@ -2161,6 +2342,8 @@ var DebounceTask = class extends Task {
2161
2342
  register,
2162
2343
  isUnique,
2163
2344
  isMeta,
2345
+ isSubMeta,
2346
+ isHidden,
2164
2347
  void 0,
2165
2348
  inputSchema,
2166
2349
  validateInputSchema,
@@ -2270,7 +2453,7 @@ var DebounceTask = class extends Task {
2270
2453
 
2271
2454
  // src/graph/definition/EphemeralTask.ts
2272
2455
  var EphemeralTask = class extends Task {
2273
- constructor(name, task, description = "", once = true, condition = () => true, concurrency = 0, timeout = 0, register = false, isUnique = false, isMeta = false, getTagCallback = void 0, inputSchema = void 0, validateInputContext = false, outputSchema = void 0, validateOutputContext = false, retryCount = 0, retryDelay = 0, retryDelayMax = 0, retryDelayFactor = 1) {
2456
+ constructor(name, task, description = "", once = true, condition = () => true, concurrency = 0, timeout = 0, register = false, 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) {
2274
2457
  super(
2275
2458
  name,
2276
2459
  task,
@@ -2280,6 +2463,8 @@ var EphemeralTask = class extends Task {
2280
2463
  register,
2281
2464
  isUnique,
2282
2465
  isMeta,
2466
+ isSubMeta,
2467
+ isHidden,
2283
2468
  getTagCallback,
2284
2469
  inputSchema,
2285
2470
  validateInputContext,
@@ -2296,7 +2481,7 @@ var EphemeralTask = class extends Task {
2296
2481
  }
2297
2482
  execute(context, emit, progressCallback) {
2298
2483
  const result = super.execute(context, emit, progressCallback);
2299
- if (this.once || !this.condition(result)) {
2484
+ if (this.once || this.condition(result)) {
2300
2485
  this.destroy();
2301
2486
  return result;
2302
2487
  }
@@ -2404,6 +2589,11 @@ var GraphLayer = class _GraphLayer extends ExecutionChain {
2404
2589
  getNodesByRoutineExecId(routineExecId) {
2405
2590
  return this.nodes.filter((node) => node.routineExecId === routineExecId);
2406
2591
  }
2592
+ getIdenticalNodes(node) {
2593
+ return this.nodes.filter(
2594
+ (n) => node.routineExecId === n.routineExecId && node.sharesTaskWith(n)
2595
+ );
2596
+ }
2407
2597
  isProcessed() {
2408
2598
  for (const node of this.nodes) {
2409
2599
  if (!node.isProcessed()) {
@@ -2877,6 +3067,8 @@ var Cadenza = class {
2877
3067
  register: true,
2878
3068
  isUnique: false,
2879
3069
  isMeta: false,
3070
+ isSubMeta: false,
3071
+ isHidden: false,
2880
3072
  getTagCallback: void 0,
2881
3073
  inputSchema: void 0,
2882
3074
  validateInputContext: false,
@@ -2898,6 +3090,8 @@ var Cadenza = class {
2898
3090
  options.register,
2899
3091
  options.isUnique,
2900
3092
  options.isMeta,
3093
+ options.isSubMeta,
3094
+ options.isHidden,
2901
3095
  options.getTagCallback,
2902
3096
  options.inputSchema,
2903
3097
  options.validateInputContext,
@@ -2925,6 +3119,8 @@ var Cadenza = class {
2925
3119
  register: true,
2926
3120
  isUnique: false,
2927
3121
  isMeta: true,
3122
+ isSubMeta: false,
3123
+ isHidden: false,
2928
3124
  getTagCallback: void 0,
2929
3125
  inputSchema: void 0,
2930
3126
  validateInputContext: false,
@@ -2954,6 +3150,8 @@ var Cadenza = class {
2954
3150
  register: true,
2955
3151
  isUnique: true,
2956
3152
  isMeta: false,
3153
+ isSubMeta: false,
3154
+ isHidden: false,
2957
3155
  getTagCallback: void 0,
2958
3156
  inputSchema: void 0,
2959
3157
  validateInputContext: false,
@@ -2981,6 +3179,8 @@ var Cadenza = class {
2981
3179
  register: true,
2982
3180
  isUnique: true,
2983
3181
  isMeta: true,
3182
+ isSubMeta: false,
3183
+ isHidden: false,
2984
3184
  getTagCallback: void 0,
2985
3185
  inputSchema: void 0,
2986
3186
  validateInputContext: false,
@@ -3010,6 +3210,8 @@ var Cadenza = class {
3010
3210
  register: true,
3011
3211
  isUnique: false,
3012
3212
  isMeta: false,
3213
+ isSubMeta: false,
3214
+ isHidden: false,
3013
3215
  inputSchema: void 0,
3014
3216
  validateInputContext: false,
3015
3217
  outputSchema: void 0,
@@ -3037,6 +3239,8 @@ var Cadenza = class {
3037
3239
  register: true,
3038
3240
  isUnique: false,
3039
3241
  isMeta: true,
3242
+ isSubMeta: false,
3243
+ isHidden: false,
3040
3244
  inputSchema: void 0,
3041
3245
  validateInputContext: false,
3042
3246
  outputSchema: void 0,
@@ -3074,6 +3278,8 @@ var Cadenza = class {
3074
3278
  maxWait: 0,
3075
3279
  isUnique: false,
3076
3280
  isMeta: false,
3281
+ isSubMeta: false,
3282
+ isHidden: false,
3077
3283
  inputSchema: void 0,
3078
3284
  validateInputContext: false,
3079
3285
  outputSchema: void 0,
@@ -3094,6 +3300,8 @@ var Cadenza = class {
3094
3300
  options.register,
3095
3301
  options.isUnique,
3096
3302
  options.isMeta,
3303
+ options.isSubMeta,
3304
+ options.isHidden,
3097
3305
  options.inputSchema,
3098
3306
  options.validateInputContext,
3099
3307
  options.outputSchema,
@@ -3118,6 +3326,8 @@ var Cadenza = class {
3118
3326
  maxWait: 0,
3119
3327
  isUnique: false,
3120
3328
  isMeta: false,
3329
+ isSubMeta: false,
3330
+ isHidden: false,
3121
3331
  inputSchema: void 0,
3122
3332
  validateInputContext: false,
3123
3333
  outputSchema: void 0,
@@ -3138,18 +3348,20 @@ var Cadenza = class {
3138
3348
  * @param name Identifier (may not be unique if not registered).
3139
3349
  * @param func Function.
3140
3350
  * @param description Optional.
3141
- * @param once Destroy after first exec (default true).
3142
- * @param destroyCondition Predicate for destruction (default always true).
3143
- * @param options Optional task options.
3351
+ * @param options Optional task options plus optional "once" (true) and "destroyCondition" (ctx => boolean).
3144
3352
  * @returns The created EphemeralTask.
3145
3353
  * @edge Destruction triggered post-exec via Node/Builder; emits meta-signal for cleanup.
3146
3354
  */
3147
- static createEphemeralTask(name, func, description, once = true, destroyCondition = () => true, options = {
3355
+ static createEphemeralTask(name, func, description, options = {
3148
3356
  concurrency: 0,
3149
3357
  timeout: 0,
3150
3358
  register: true,
3151
3359
  isUnique: false,
3152
3360
  isMeta: false,
3361
+ isSubMeta: false,
3362
+ isHidden: false,
3363
+ once: true,
3364
+ destroyCondition: () => true,
3153
3365
  getTagCallback: void 0,
3154
3366
  inputSchema: void 0,
3155
3367
  validateInputContext: false,
@@ -3166,13 +3378,15 @@ var Cadenza = class {
3166
3378
  name,
3167
3379
  func,
3168
3380
  description,
3169
- once,
3170
- destroyCondition,
3381
+ options.once,
3382
+ options.destroyCondition,
3171
3383
  options.concurrency,
3172
3384
  options.timeout,
3173
3385
  options.register,
3174
3386
  options.isUnique,
3175
3387
  options.isMeta,
3388
+ options.isSubMeta,
3389
+ options.isHidden,
3176
3390
  options.getTagCallback,
3177
3391
  options.inputSchema,
3178
3392
  options.validateInputContext,
@@ -3189,17 +3403,19 @@ var Cadenza = class {
3189
3403
  * @param name Identifier.
3190
3404
  * @param func Function.
3191
3405
  * @param description Optional.
3192
- * @param once Destroy after first (default true).
3193
- * @param destroyCondition Destruction predicate.
3194
- * @param options Optional task options.
3406
+ * @param options Optional task options plus optional "once" (true) and "destroyCondition" (ctx => boolean).
3195
3407
  * @returns The created EphemeralMetaTask.
3196
3408
  */
3197
- static createEphemeralMetaTask(name, func, description, once = true, destroyCondition = () => true, options = {
3409
+ static createEphemeralMetaTask(name, func, description, options = {
3198
3410
  concurrency: 0,
3199
3411
  timeout: 0,
3200
3412
  register: true,
3201
3413
  isUnique: false,
3202
3414
  isMeta: true,
3415
+ isSubMeta: false,
3416
+ isHidden: false,
3417
+ once: true,
3418
+ destroyCondition: () => true,
3203
3419
  getTagCallback: void 0,
3204
3420
  inputSchema: void 0,
3205
3421
  validateInputContext: false,
@@ -3211,14 +3427,7 @@ var Cadenza = class {
3211
3427
  retryDelayFactor: 1
3212
3428
  }) {
3213
3429
  options.isMeta = true;
3214
- return this.createEphemeralTask(
3215
- name,
3216
- func,
3217
- description,
3218
- once,
3219
- destroyCondition,
3220
- options
3221
- );
3430
+ return this.createEphemeralTask(name, func, description, options);
3222
3431
  }
3223
3432
  /**
3224
3433
  * Creates a GraphRoutine (named entry to starting tasks) and registers it.
@@ -3255,6 +3464,7 @@ var Cadenza = class {
3255
3464
  var _a, _b;
3256
3465
  (_a = this.broker) == null ? void 0 : _a.reset();
3257
3466
  (_b = this.registry) == null ? void 0 : _b.reset();
3467
+ this.isBootstrapped = false;
3258
3468
  }
3259
3469
  };
3260
3470
  Cadenza.isBootstrapped = false;