@bian-womp/spark-graph 0.3.70 → 0.3.72

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.
Files changed (77) hide show
  1. package/lib/cjs/index.cjs +133 -234
  2. package/lib/cjs/index.cjs.map +1 -1
  3. package/lib/cjs/src/builder/GraphBuilder.d.ts.map +1 -1
  4. package/lib/cjs/src/builder/Registry.d.ts.map +1 -1
  5. package/lib/cjs/src/core/categories.d.ts.map +1 -1
  6. package/lib/cjs/src/core/order.d.ts.map +1 -1
  7. package/lib/cjs/src/core/type-utils.d.ts.map +1 -1
  8. package/lib/cjs/src/core/types.d.ts.map +1 -1
  9. package/lib/cjs/src/examples/arrays.d.ts.map +1 -1
  10. package/lib/cjs/src/examples/async.d.ts.map +1 -1
  11. package/lib/cjs/src/examples/progress.d.ts.map +1 -1
  12. package/lib/cjs/src/examples/runMode.d.ts.map +1 -1
  13. package/lib/cjs/src/examples/shared.d.ts.map +1 -1
  14. package/lib/cjs/src/examples/simple.d.ts.map +1 -1
  15. package/lib/cjs/src/examples/snapshot.d.ts.map +1 -1
  16. package/lib/cjs/src/index.d.ts +7 -7
  17. package/lib/cjs/src/index.d.ts.map +1 -1
  18. package/lib/cjs/src/misc/base.d.ts.map +1 -1
  19. package/lib/cjs/src/misc/utils/LevelLogger.d.ts.map +1 -1
  20. package/lib/cjs/src/misc/utils/json.d.ts.map +1 -1
  21. package/lib/cjs/src/misc/utils/merge.d.ts.map +1 -1
  22. package/lib/cjs/src/plugins/composite.d.ts.map +1 -1
  23. package/lib/cjs/src/runtime/Engine.d.ts.map +1 -1
  24. package/lib/cjs/src/runtime/GraphLifecycleApi.d.ts.map +1 -1
  25. package/lib/cjs/src/runtime/GraphRuntime.d.ts.map +1 -1
  26. package/lib/cjs/src/runtime/LocalEngine.d.ts.map +1 -1
  27. package/lib/cjs/src/runtime/components/EdgePropagator.d.ts.map +1 -1
  28. package/lib/cjs/src/runtime/components/EventEmitter.d.ts.map +1 -1
  29. package/lib/cjs/src/runtime/components/Graph.d.ts.map +1 -1
  30. package/lib/cjs/src/runtime/components/HandleResolver.d.ts.map +1 -1
  31. package/lib/cjs/src/runtime/components/NodeExecutor.d.ts.map +1 -1
  32. package/lib/cjs/src/runtime/components/RunContextManager.d.ts.map +1 -1
  33. package/lib/cjs/src/runtime/components/RuntimeValidatorManager.d.ts.map +1 -1
  34. package/lib/cjs/src/runtime/components/graph-utils.d.ts.map +1 -1
  35. package/lib/cjs/src/runtime/components/interfaces.d.ts.map +1 -1
  36. package/lib/cjs/src/runtime/components/types.d.ts.map +1 -1
  37. package/lib/cjs/src/runtime/utils.d.ts +9 -0
  38. package/lib/cjs/src/runtime/utils.d.ts.map +1 -1
  39. package/lib/esm/index.js +133 -234
  40. package/lib/esm/index.js.map +1 -1
  41. package/lib/esm/src/builder/GraphBuilder.d.ts.map +1 -1
  42. package/lib/esm/src/builder/Registry.d.ts.map +1 -1
  43. package/lib/esm/src/core/categories.d.ts.map +1 -1
  44. package/lib/esm/src/core/order.d.ts.map +1 -1
  45. package/lib/esm/src/core/type-utils.d.ts.map +1 -1
  46. package/lib/esm/src/core/types.d.ts.map +1 -1
  47. package/lib/esm/src/examples/arrays.d.ts.map +1 -1
  48. package/lib/esm/src/examples/async.d.ts.map +1 -1
  49. package/lib/esm/src/examples/progress.d.ts.map +1 -1
  50. package/lib/esm/src/examples/runMode.d.ts.map +1 -1
  51. package/lib/esm/src/examples/shared.d.ts.map +1 -1
  52. package/lib/esm/src/examples/simple.d.ts.map +1 -1
  53. package/lib/esm/src/examples/snapshot.d.ts.map +1 -1
  54. package/lib/esm/src/index.d.ts +7 -7
  55. package/lib/esm/src/index.d.ts.map +1 -1
  56. package/lib/esm/src/misc/base.d.ts.map +1 -1
  57. package/lib/esm/src/misc/utils/LevelLogger.d.ts.map +1 -1
  58. package/lib/esm/src/misc/utils/json.d.ts.map +1 -1
  59. package/lib/esm/src/misc/utils/merge.d.ts.map +1 -1
  60. package/lib/esm/src/plugins/composite.d.ts.map +1 -1
  61. package/lib/esm/src/runtime/Engine.d.ts.map +1 -1
  62. package/lib/esm/src/runtime/GraphLifecycleApi.d.ts.map +1 -1
  63. package/lib/esm/src/runtime/GraphRuntime.d.ts.map +1 -1
  64. package/lib/esm/src/runtime/LocalEngine.d.ts.map +1 -1
  65. package/lib/esm/src/runtime/components/EdgePropagator.d.ts.map +1 -1
  66. package/lib/esm/src/runtime/components/EventEmitter.d.ts.map +1 -1
  67. package/lib/esm/src/runtime/components/Graph.d.ts.map +1 -1
  68. package/lib/esm/src/runtime/components/HandleResolver.d.ts.map +1 -1
  69. package/lib/esm/src/runtime/components/NodeExecutor.d.ts.map +1 -1
  70. package/lib/esm/src/runtime/components/RunContextManager.d.ts.map +1 -1
  71. package/lib/esm/src/runtime/components/RuntimeValidatorManager.d.ts.map +1 -1
  72. package/lib/esm/src/runtime/components/graph-utils.d.ts.map +1 -1
  73. package/lib/esm/src/runtime/components/interfaces.d.ts.map +1 -1
  74. package/lib/esm/src/runtime/components/types.d.ts.map +1 -1
  75. package/lib/esm/src/runtime/utils.d.ts +9 -0
  76. package/lib/esm/src/runtime/utils.d.ts.map +1 -1
  77. package/package.json +4 -2
package/lib/cjs/index.cjs CHANGED
@@ -4,9 +4,7 @@ function typed(typeId, value) {
4
4
  return { __spark_type: typeId, __spark_value: value };
5
5
  }
6
6
  function isTyped(v) {
7
- return (!!v &&
8
- typeof v === "object" &&
9
- Object.prototype.hasOwnProperty.call(v, "__spark_type"));
7
+ return !!v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "__spark_type");
10
8
  }
11
9
  function unwrapTypeId(v) {
12
10
  if (isTyped(v))
@@ -66,12 +64,8 @@ function mergeInputHandleDescriptors(staticDesc, dynamicDesc) {
66
64
  (typeof dynamicDesc === "string" || Array.isArray(dynamicDesc))) {
67
65
  return dynamicDesc;
68
66
  }
69
- const staticObj = typeof staticDesc === "string" || Array.isArray(staticDesc)
70
- ? { typeId: staticDesc }
71
- : staticDesc;
72
- const dynamicObj = typeof dynamicDesc === "string" || Array.isArray(dynamicDesc)
73
- ? { typeId: dynamicDesc }
74
- : dynamicDesc;
67
+ const staticObj = typeof staticDesc === "string" || Array.isArray(staticDesc) ? { typeId: staticDesc } : staticDesc;
68
+ const dynamicObj = typeof dynamicDesc === "string" || Array.isArray(dynamicDesc) ? { typeId: dynamicDesc } : dynamicDesc;
75
69
  // Merge: dynamic takes precedence, but merge metadata objects
76
70
  const merged = {
77
71
  typeId: dynamicObj.typeId ?? staticObj.typeId,
@@ -152,7 +146,7 @@ class Registry {
152
146
  };
153
147
  this.types.set(arrayId, arrayDesc);
154
148
  }
155
- this.registerCoercion(desc.id, arrayId, (value) => Array.isArray(value) ? value : [value]);
149
+ this.registerCoercion(desc.id, arrayId, (value) => (Array.isArray(value) ? value : [value]));
156
150
  this.registerCoercion(arrayId, desc.id, (value) => {
157
151
  if (!Array.isArray(value))
158
152
  return value;
@@ -178,8 +172,8 @@ class Registry {
178
172
  const arrayId = `${typeId}[]`;
179
173
  if (this.types.has(arrayId) && !this.serializers.has(arrayId)) {
180
174
  this.serializers.set(arrayId, {
181
- serialize: (value) => Array.isArray(value) ? value.map((el) => s.serialize(el)) : value,
182
- deserialize: (data) => Array.isArray(data) ? data.map((el) => s.deserialize(el)) : data,
175
+ serialize: (value) => (Array.isArray(value) ? value.map((el) => s.serialize(el)) : value),
176
+ deserialize: (data) => (Array.isArray(data) ? data.map((el) => s.deserialize(el)) : data),
183
177
  });
184
178
  }
185
179
  return this;
@@ -355,8 +349,7 @@ class Registry {
355
349
  let i = 0;
356
350
  while (i < queue.length) {
357
351
  const q = queue[i];
358
- if (e.cost.edges < q.cost.edges ||
359
- (e.cost.edges === q.cost.edges && e.cost.async < q.cost.async)) {
352
+ if (e.cost.edges < q.cost.edges || (e.cost.edges === q.cost.edges && e.cost.async < q.cost.async)) {
360
353
  break;
361
354
  }
362
355
  i++;
@@ -475,9 +468,7 @@ class Registry {
475
468
  const rec = this.enums.get(id);
476
469
  if (!rec)
477
470
  return value;
478
- return rec.valueToLabel.has(n)
479
- ? n
480
- : Array.from(rec.valueToLabel.keys())[0] ?? 0;
471
+ return rec.valueToLabel.has(n) ? n : (Array.from(rec.valueToLabel.keys())[0] ?? 0);
481
472
  });
482
473
  this.registerCoercion(id, labelType, (value) => {
483
474
  const n = Number(value);
@@ -924,8 +915,7 @@ class Graph {
924
915
  if (inbound.length === 0)
925
916
  return true;
926
917
  for (const e of inbound) {
927
- if (node.resolvedHandles?.inputs?.[e.target.handle] &&
928
- !node.inputs[e.target.handle]) {
918
+ if (node.resolvedHandles?.inputs?.[e.target.handle] && !node.inputs[e.target.handle]) {
929
919
  return false;
930
920
  }
931
921
  }
@@ -1003,9 +993,7 @@ function getValueAtPath(obj, pathSegments) {
1003
993
  let current = obj;
1004
994
  for (let i = 0; i < pathSegments.length - 1; i++) {
1005
995
  const segment = pathSegments[i];
1006
- if (current === null ||
1007
- current === undefined ||
1008
- typeof current !== "object") {
996
+ if (current === null || current === undefined || typeof current !== "object") {
1009
997
  return null;
1010
998
  }
1011
999
  if (typeof segment === "string") {
@@ -1054,9 +1042,7 @@ function getValueAtPath(obj, pathSegments) {
1054
1042
  return null;
1055
1043
  return { value: current[index], parent: current, key: index };
1056
1044
  }
1057
- else if (current !== null &&
1058
- current !== undefined &&
1059
- typeof current === "object") {
1045
+ else if (current !== null && current !== undefined && typeof current === "object") {
1060
1046
  return {
1061
1047
  value: current[lastSegment],
1062
1048
  parent: current,
@@ -1170,29 +1156,20 @@ function findMatchingPaths(obj, pathSegments, currentPath = []) {
1170
1156
  if (Array.isArray(obj)) {
1171
1157
  const index = parseInt(currentSegment, 10);
1172
1158
  if (!isNaN(index) && index >= 0 && index < obj.length) {
1173
- results.push(...findMatchingPaths(obj[index], remainingSegments, [
1174
- ...currentPath,
1175
- index,
1176
- ]));
1159
+ results.push(...findMatchingPaths(obj[index], remainingSegments, [...currentPath, index]));
1177
1160
  }
1178
1161
  }
1179
1162
  else if (obj !== null && obj !== undefined && typeof obj === "object") {
1180
1163
  const objRecord = obj;
1181
1164
  if (currentSegment in objRecord) {
1182
- results.push(...findMatchingPaths(objRecord[currentSegment], remainingSegments, [
1183
- ...currentPath,
1184
- currentSegment,
1185
- ]));
1165
+ results.push(...findMatchingPaths(objRecord[currentSegment], remainingSegments, [...currentPath, currentSegment]));
1186
1166
  }
1187
1167
  }
1188
1168
  }
1189
1169
  else if (typeof currentSegment === "number") {
1190
1170
  if (Array.isArray(obj)) {
1191
1171
  if (currentSegment >= 0 && currentSegment < obj.length) {
1192
- results.push(...findMatchingPaths(obj[currentSegment], remainingSegments, [
1193
- ...currentPath,
1194
- currentSegment,
1195
- ]));
1172
+ results.push(...findMatchingPaths(obj[currentSegment], remainingSegments, [...currentPath, currentSegment]));
1196
1173
  }
1197
1174
  }
1198
1175
  }
@@ -1206,10 +1183,7 @@ function findMatchingPaths(obj, pathSegments, currentPath = []) {
1206
1183
  const objRecord = obj;
1207
1184
  for (const key of Object.keys(objRecord)) {
1208
1185
  if (currentSegment.test(key)) {
1209
- results.push(...findMatchingPaths(objRecord[key], remainingSegments, [
1210
- ...currentPath,
1211
- key,
1212
- ]));
1186
+ results.push(...findMatchingPaths(objRecord[key], remainingSegments, [...currentPath, key]));
1213
1187
  }
1214
1188
  }
1215
1189
  }
@@ -1220,12 +1194,8 @@ function stringifyJson(obj, oneLiner) {
1220
1194
  // No formatting requested: behave exactly like native JSON.stringify.
1221
1195
  if (!oneLiner)
1222
1196
  return JSON.stringify(obj);
1223
- const indentSize = Number.isFinite(oneLiner.indent)
1224
- ? Math.max(0, Math.floor(oneLiner.indent))
1225
- : 2;
1226
- const maxDepth = typeof oneLiner.maxDepth === "number" && Number.isFinite(oneLiner.maxDepth)
1227
- ? oneLiner.maxDepth
1228
- : undefined;
1197
+ const indentSize = Number.isFinite(oneLiner.indent) ? Math.max(0, Math.floor(oneLiner.indent)) : 2;
1198
+ const maxDepth = typeof oneLiner.maxDepth === "number" && Number.isFinite(oneLiner.maxDepth) ? oneLiner.maxDepth : undefined;
1229
1199
  const patterns = (oneLiner.paths || []).filter(Boolean);
1230
1200
  // Preserve JSON.stringify semantics for things like toJSON(), dropping functions/undefined, etc.
1231
1201
  // Note: this still throws on circular structures (same as JSON.stringify).
@@ -1428,22 +1398,13 @@ function compilePathMatcher(pattern) {
1428
1398
  res = ti < pathTokens.length && go(pi + 1, ti + 1);
1429
1399
  }
1430
1400
  else if (p === "#") {
1431
- res =
1432
- ti < pathTokens.length &&
1433
- isNumericSegment(pathTokens[ti]) &&
1434
- go(pi + 1, ti + 1);
1401
+ res = ti < pathTokens.length && isNumericSegment(pathTokens[ti]) && go(pi + 1, ti + 1);
1435
1402
  }
1436
1403
  else if (p === "[*]") {
1437
- res =
1438
- ti < pathTokens.length &&
1439
- isIndex(pathTokens[ti]) &&
1440
- go(pi + 1, ti + 1);
1404
+ res = ti < pathTokens.length && isIndex(pathTokens[ti]) && go(pi + 1, ti + 1);
1441
1405
  }
1442
1406
  else {
1443
- res =
1444
- ti < pathTokens.length &&
1445
- eq(p.toLowerCase(), pathTokens[ti].toLowerCase()) &&
1446
- go(pi + 1, ti + 1);
1407
+ res = ti < pathTokens.length && eq(p.toLowerCase(), pathTokens[ti].toLowerCase()) && go(pi + 1, ti + 1);
1447
1408
  }
1448
1409
  }
1449
1410
  memo.set(key, res);
@@ -1469,10 +1430,7 @@ function stringifySceneAndOps(obj) {
1469
1430
  "**.perUserExt.*.#",
1470
1431
  "**.perUserExt.*.*.#",
1471
1432
  ],
1472
- criteria: ({ value, key }) => (typeof value === "object" &&
1473
- value &&
1474
- Object.keys(value).sort().join(",") === "x,y,z") ||
1475
- key === "value",
1433
+ criteria: ({ value, key }) => (typeof value === "object" && value && Object.keys(value).sort().join(",") === "x,y,z") || key === "value",
1476
1434
  });
1477
1435
  }
1478
1436
 
@@ -1542,8 +1500,7 @@ class LevelLogger {
1542
1500
  parseJsonStringIfFull(str) {
1543
1501
  const trimmed = str.trim();
1544
1502
  // Check if the string starts with { or [ and ends with } or ]
1545
- if ((trimmed.startsWith("{") && trimmed.endsWith("}")) ||
1546
- (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
1503
+ if ((trimmed.startsWith("{") && trimmed.endsWith("}")) || (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
1547
1504
  try {
1548
1505
  const parsed = JSON.parse(trimmed);
1549
1506
  return JSON.stringify(parsed, null, 2);
@@ -1562,8 +1519,7 @@ class LevelLogger {
1562
1519
  parseJsonStringToObject(str) {
1563
1520
  const trimmed = str.trim();
1564
1521
  // Check if the string starts with { or [ and ends with } or ]
1565
- if ((trimmed.startsWith("{") && trimmed.endsWith("}")) ||
1566
- (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
1522
+ if ((trimmed.startsWith("{") && trimmed.endsWith("}")) || (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
1567
1523
  try {
1568
1524
  return JSON.parse(trimmed);
1569
1525
  }
@@ -1664,10 +1620,7 @@ class LevelLogger {
1664
1620
  // (starts with { or [ and contains newlines indicating it was formatted),
1665
1621
  // output it directly without stringifySceneAndOps to preserve formatting
1666
1622
  // Wrap it with json`...` to distinguish it as formatted JSON
1667
- if (parseJsonString &&
1668
- typeof v === "string" &&
1669
- v.trim().match(/^[{\[]/) &&
1670
- v.includes("\n")) {
1623
+ if (parseJsonString && typeof v === "string" && v.trim().match(/^[{\[]/) && v.includes("\n")) {
1671
1624
  return `${k}=json\`${v}\``;
1672
1625
  }
1673
1626
  // If this key had a JSON string parsed and we're formatting JSON,
@@ -1682,9 +1635,7 @@ class LevelLogger {
1682
1635
  })
1683
1636
  .join(formatJson ? "\n" : " ")}`
1684
1637
  : "";
1685
- const prefixedMessage = this.prefix
1686
- ? `${this.prefix} ${message}${contextStr}`
1687
- : `${message}${contextStr}`;
1638
+ const prefixedMessage = this.prefix ? `${this.prefix} ${message}${contextStr}` : `${message}${contextStr}`;
1688
1639
  switch (requestedLevel) {
1689
1640
  case "debug":
1690
1641
  console.info(prefixedMessage);
@@ -1919,10 +1870,7 @@ class RunContextManager {
1919
1870
  });
1920
1871
  return;
1921
1872
  }
1922
- if (ctx.pendingNodes > 0 ||
1923
- ctx.pendingEdges > 0 ||
1924
- ctx.pendingResolvers > 0 ||
1925
- ctx.pendingQueued > 0) {
1873
+ if (ctx.pendingNodes > 0 || ctx.pendingEdges > 0 || ctx.pendingResolvers > 0 || ctx.pendingQueued > 0) {
1926
1874
  return; // Still has pending work
1927
1875
  }
1928
1876
  this.logger.info("finish-run-context", {
@@ -2041,6 +1989,19 @@ function valuesEqual(a, b) {
2041
1989
  }
2042
1990
  return false;
2043
1991
  }
1992
+ /**
1993
+ * Format a node reference as <typeId>.<nodeId> for logs.
1994
+ */
1995
+ function formatNodeRef(graph, nodeId) {
1996
+ const node = graph.getNode(nodeId);
1997
+ return `${node?.typeId ?? "unknown"}.${nodeId}`;
1998
+ }
1999
+ /**
2000
+ * Format a node handle reference as <typeId>.<nodeId>.<handle> for logs.
2001
+ */
2002
+ function formatNodeHandleRef(graph, nodeId, handle) {
2003
+ return `${formatNodeRef(graph, nodeId)}.${handle}`;
2004
+ }
2044
2005
 
2045
2006
  function tryHandleResolving(def, registry, environment) {
2046
2007
  const out = new Map();
@@ -2148,9 +2109,7 @@ function extractEdgeTypes(sourceNodeId, sourceHandle, targetNodeId, targetHandle
2148
2109
  const srcDeclared = srcResolved
2149
2110
  ? srcResolved.outputs[sourceHandle]
2150
2111
  : registry.nodes.get(graph.getNode(sourceNodeId)?.typeId || "")?.outputs[sourceHandle];
2151
- const dstDeclared = getInputDeclaredTypes(dstResolved
2152
- ? dstResolved.inputs
2153
- : registry.nodes.get(graph.getNode(targetNodeId)?.typeId || "")?.inputs, targetHandle);
2112
+ const dstDeclared = getInputDeclaredTypes(dstResolved ? dstResolved.inputs : registry.nodes.get(graph.getNode(targetNodeId)?.typeId || "")?.inputs, targetHandle);
2154
2113
  return {
2155
2114
  srcDeclared,
2156
2115
  dstDeclared,
@@ -2246,9 +2205,7 @@ function buildEdgeConverters(srcDeclared, dstDeclared, registry, edgeLabel) {
2246
2205
  const { typeId, payload } = extractPayload(v);
2247
2206
  const res = getCoercion(typeId);
2248
2207
  if (!res) {
2249
- const fallbackType = isDstUnion && typeId && dstTypes.includes(typeId)
2250
- ? typeId
2251
- : undefined;
2208
+ const fallbackType = isDstUnion && typeId && dstTypes.includes(typeId) ? typeId : undefined;
2252
2209
  return wrapIfDstUnion(fallbackType, payload);
2253
2210
  }
2254
2211
  if (res.kind === "async" && res.convertAsync) {
@@ -2269,9 +2226,7 @@ function buildEdgeConverters(srcDeclared, dstDeclared, registry, edgeLabel) {
2269
2226
  const { typeId, payload } = extractPayload(v);
2270
2227
  const res = getCoercion(typeId);
2271
2228
  if (!res) {
2272
- const fallbackType = isDstUnion && typeId && dstTypes.includes(typeId)
2273
- ? typeId
2274
- : undefined;
2229
+ const fallbackType = isDstUnion && typeId && dstTypes.includes(typeId) ? typeId : undefined;
2275
2230
  return wrapIfDstUnion(fallbackType, payload);
2276
2231
  }
2277
2232
  if (res.kind === "async") {
@@ -2445,15 +2400,11 @@ class HandleResolver {
2445
2400
  // Update edge properties via Graph
2446
2401
  this.graph.updateEdgeProperties(e.id, {
2447
2402
  dstDeclared,
2448
- srcUnionTypes: Array.isArray(srcDeclared)
2449
- ? [...srcDeclared]
2450
- : undefined,
2403
+ srcUnionTypes: Array.isArray(srcDeclared) ? [...srcDeclared] : undefined,
2451
2404
  convert: conv.convert,
2452
2405
  convertAsync: conv.convertAsync,
2453
2406
  });
2454
- if (e.target.nodeId === nodeId &&
2455
- oldDstDeclared === undefined &&
2456
- dstDeclared !== undefined) {
2407
+ if (e.target.nodeId === nodeId && oldDstDeclared === undefined && dstDeclared !== undefined) {
2457
2408
  const srcNode = this.graph.getNode(e.source.nodeId);
2458
2409
  if (srcNode) {
2459
2410
  const srcValue = srcNode.outputs[e.source.handle];
@@ -2489,7 +2440,7 @@ class HandleResolver {
2489
2440
  const nodeLogValue = LOG_LEVEL_VALUES[nodeLogLevel] ?? 1;
2490
2441
  const shouldLog = nodeLogValue <= LOG_LEVEL_VALUES.debug && nodeLogLevel !== "silent";
2491
2442
  if (shouldLog) {
2492
- console.info(`[node:${nodeId}:${node.typeId}] resolveHandles-start`);
2443
+ console.info(`[node:${formatNodeRef(this.graph, nodeId)}] resolveHandles-start`);
2493
2444
  }
2494
2445
  let resolved;
2495
2446
  try {
@@ -2504,13 +2455,13 @@ class HandleResolver {
2504
2455
  catch {
2505
2456
  // Log resolveHandles-done even on error
2506
2457
  if (shouldLog) {
2507
- console.info(`[node:${nodeId}:${node.typeId}] resolveHandles-done (error)`);
2458
+ console.info(`[node:${formatNodeRef(this.graph, nodeId)}] resolveHandles-done (error)`);
2508
2459
  }
2509
2460
  return;
2510
2461
  }
2511
2462
  // Log resolveHandles-done
2512
2463
  if (shouldLog) {
2513
- console.info(`[node:${nodeId}:${node.typeId}] resolveHandles-done`);
2464
+ console.info(`[node:${formatNodeRef(this.graph, nodeId)}] resolveHandles-done`);
2514
2465
  }
2515
2466
  // If a newer recompute was scheduled, drop this result
2516
2467
  if ((this.recomputeTokenByNode.get(nodeId) ?? 0) !== token)
@@ -2606,9 +2557,7 @@ class EdgePropagator {
2606
2557
  const effectiveRunContexts = runContextIds && runContextIds.size > 0
2607
2558
  ? this.filterEffectiveRunContexts(edge, srcNodeId, runContextIds)
2608
2559
  : undefined;
2609
- if (runContextIds &&
2610
- runContextIds.size > 0 &&
2611
- !(effectiveRunContexts && effectiveRunContexts.size > 0)) {
2560
+ if (runContextIds && runContextIds.size > 0 && !(effectiveRunContexts && effectiveRunContexts.size > 0)) {
2612
2561
  return; // No valid run-contexts for this edge
2613
2562
  }
2614
2563
  // Validate union types
@@ -2649,12 +2598,16 @@ class EdgePropagator {
2649
2598
  const isUnion = Array.isArray(edge.srcUnionTypes);
2650
2599
  const isTypedValue = isTyped(value);
2651
2600
  if (isUnion && !isTypedValue) {
2601
+ const sourceTypeId = this.graph.getNode(edge.source.nodeId)?.typeId;
2602
+ const targetTypeId = this.graph.getNode(edge.target.nodeId)?.typeId;
2652
2603
  const err = new Error(`Output ${srcNodeId}.${edge.source.handle} requires typed value for union output (allowed: ${edge.srcUnionTypes.join("|")})`);
2653
2604
  this.eventEmitter.emit("error", {
2654
2605
  kind: "edge-convert",
2655
2606
  edgeId: edge.id,
2656
2607
  source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
2657
2608
  target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
2609
+ sourceTypeId,
2610
+ targetTypeId,
2658
2611
  err,
2659
2612
  });
2660
2613
  return false;
@@ -2670,7 +2623,14 @@ class EdgePropagator {
2670
2623
  convertedValue = edge.convert(value);
2671
2624
  }
2672
2625
  else {
2673
- console.warn(`No convert function for edge ${edge.id} of type ${edge.source.nodeId}.${edge.source.handle} -> ${edge.target.nodeId}.${edge.target.handle}`);
2626
+ const fromType = (Array.isArray(edge.srcUnionTypes) && edge.srcUnionTypes.length > 0
2627
+ ? edge.srcUnionTypes.join("|")
2628
+ : undefined) ??
2629
+ unwrapTypeId(value) ??
2630
+ edge.typeId ??
2631
+ "unknown";
2632
+ const toType = Array.isArray(edge.dstDeclared) ? edge.dstDeclared.join("|") : (edge.dstDeclared ?? "unknown");
2633
+ console.warn(`No convert function for edge ${edge.id} [${formatNodeHandleRef(this.graph, edge.source.nodeId, edge.source.handle)} -> ${formatNodeHandleRef(this.graph, edge.target.nodeId, edge.target.handle)}] from:${fromType} to:${toType}`);
2674
2634
  }
2675
2635
  this.applyToTarget(edge, convertedValue, effectiveRunContexts);
2676
2636
  }
@@ -2681,20 +2641,22 @@ class EdgePropagator {
2681
2641
  if (!edge.convertAsync)
2682
2642
  return;
2683
2643
  // Track edge run-context IDs for pendingEdges tracking
2684
- const edgeRunContextIds = effectiveRunContexts
2685
- ? Array.from(effectiveRunContexts)
2686
- : undefined;
2644
+ const edgeRunContextIds = effectiveRunContexts ? Array.from(effectiveRunContexts) : undefined;
2687
2645
  if (edgeRunContextIds) {
2688
2646
  for (const id of edgeRunContextIds) {
2689
2647
  this.runContextManager.startEdgeConversion(id, edge.id);
2690
2648
  }
2691
2649
  }
2650
+ const sourceTypeId = this.graph.getNode(edge.source.nodeId)?.typeId;
2651
+ const targetTypeId = this.graph.getNode(edge.target.nodeId)?.typeId;
2692
2652
  this.eventEmitter.emit("stats", {
2693
2653
  kind: "edge-start",
2694
2654
  edgeId: edge.id,
2695
2655
  typeId: edge.typeId,
2696
2656
  source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
2697
2657
  target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
2658
+ sourceTypeId,
2659
+ targetTypeId,
2698
2660
  });
2699
2661
  const controller = new AbortController();
2700
2662
  const startAt = Date.now();
@@ -2772,7 +2734,7 @@ class EdgePropagator {
2772
2734
  if (!dstIsArray) {
2773
2735
  return value;
2774
2736
  }
2775
- const toArray = (x) => Array.isArray(x) ? x : x === undefined ? [] : [x];
2737
+ const toArray = (x) => (Array.isArray(x) ? x : x === undefined ? [] : [x]);
2776
2738
  let forNode = this.arrayInputBuckets.get(edge.target.nodeId);
2777
2739
  if (!forNode) {
2778
2740
  forNode = new Map();
@@ -2863,6 +2825,8 @@ class EdgePropagator {
2863
2825
  typeId: edge.typeId,
2864
2826
  source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
2865
2827
  target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
2828
+ sourceTypeId: this.graph.getNode(edge.source.nodeId)?.typeId,
2829
+ targetTypeId: this.graph.getNode(edge.target.nodeId)?.typeId,
2866
2830
  durationMs: duration,
2867
2831
  });
2868
2832
  }
@@ -2879,6 +2843,8 @@ class EdgePropagator {
2879
2843
  edgeId: edge.id,
2880
2844
  source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
2881
2845
  target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
2846
+ sourceTypeId: this.graph.getNode(edge.source.nodeId)?.typeId,
2847
+ targetTypeId: this.graph.getNode(edge.target.nodeId)?.typeId,
2882
2848
  err,
2883
2849
  });
2884
2850
  }
@@ -2923,9 +2889,7 @@ class EdgePropagator {
2923
2889
  return;
2924
2890
  // Get resolved handles to filter out invalid outputs
2925
2891
  const resolved = this.graph.getResolvedHandles(nodeId);
2926
- const validOutputHandles = resolved?.outputs
2927
- ? new Set(Object.keys(resolved.outputs))
2928
- : new Set();
2892
+ const validOutputHandles = resolved?.outputs ? new Set(Object.keys(resolved.outputs)) : new Set();
2929
2893
  // Use node's activeRunContexts to propagate to new nodes that were added
2930
2894
  const activeRunContextIds = this.graph.getNodeRunContextIds(nodeId);
2931
2895
  for (const [handle, value] of Object.entries(node.outputs)) {
@@ -2996,7 +2960,7 @@ class NodeExecutor {
2996
2960
  // Create log function that respects node's logLevel using LevelLogger
2997
2961
  const node = this.graph.getNode(nodeId);
2998
2962
  const nodeLogLevel = node?.logLevel ?? "info";
2999
- const logger = new LevelLogger(nodeLogLevel, `[node:${runId || nodeId}:${node?.typeId ?? ""}]`);
2963
+ const logger = new LevelLogger(nodeLogLevel, `[node:${formatNodeRef(this.graph, nodeId)}:${runId}]`);
3000
2964
  const log = (level, message, context) => {
3001
2965
  switch (level) {
3002
2966
  case "debug":
@@ -3024,11 +2988,8 @@ class NodeExecutor {
3024
2988
  execute: (opts) => {
3025
2989
  if (this.graph.allInboundHaveValue(nodeId)) {
3026
2990
  let runContextIdsToUse = this.runtime.getRunMode() === "auto" ? undefined : runContextIds;
3027
- if (this.runtime.getRunMode() === "manual" &&
3028
- (!runContextIds || runContextIds.size === 0)) {
3029
- runContextIdsToUse = new Set([
3030
- this.runContextManager.createRunContext(nodeId, opts),
3031
- ]);
2991
+ if (this.runtime.getRunMode() === "manual" && (!runContextIds || runContextIds.size === 0)) {
2992
+ runContextIdsToUse = new Set([this.runContextManager.createRunContext(nodeId, opts)]);
3032
2993
  }
3033
2994
  this.execute(nodeId, {
3034
2995
  runContextIds: runContextIdsToUse,
@@ -3064,24 +3025,22 @@ class NodeExecutor {
3064
3025
  return;
3065
3026
  const runMode = this.runtime.getRunMode();
3066
3027
  if (!runMode) {
3067
- console.trace(`NodeExecutor.execute[${nodeId}:${reason}]: no runMode, skipping execution`);
3028
+ console.trace(`NodeExecutor.execute[${formatNodeRef(this.graph, nodeId)}:${reason}]: no runMode, skipping execution`);
3068
3029
  return;
3069
3030
  }
3070
3031
  // In manual mode, require runContextIds unless autoRun policy is set
3071
3032
  if (runMode === "manual" && (!runContextIds || runContextIds.size === 0)) {
3072
3033
  // If autoRun is true, auto-generate a run context (similar to createExecutionContext pattern)
3073
3034
  if (node.policy?.autoRun === true) {
3074
- runContextIds = new Set([
3075
- this.runContextManager.createRunContext(nodeId, { propagate: false }),
3076
- ]);
3035
+ runContextIds = new Set([this.runContextManager.createRunContext(nodeId, { propagate: false })]);
3077
3036
  }
3078
3037
  else {
3079
- console.trace(`NodeExecutor.execute[${nodeId}:${reason}]: no runContextIds provided in manual mode, skipping execution`);
3038
+ console.trace(`NodeExecutor.execute[${formatNodeRef(this.graph, nodeId)}:${reason}]: no runContextIds provided in manual mode, skipping execution`);
3080
3039
  return;
3081
3040
  }
3082
3041
  }
3083
3042
  if (runMode === "auto" && runContextIds && runContextIds.size > 0) {
3084
- console.trace(`NodeExecutor.execute[${nodeId}:${reason}]: runContextIds provided in auto mode, ignoring`);
3043
+ console.trace(`NodeExecutor.execute[${formatNodeRef(this.graph, nodeId)}:${reason}]: runContextIds provided in auto mode, ignoring`);
3085
3044
  runContextIds = undefined;
3086
3045
  }
3087
3046
  // Early validation for auto-mode paused state
@@ -3096,6 +3055,7 @@ class NodeExecutor {
3096
3055
  code: runtimeValidationError.code || "RUNTIME_VALIDATION_BLOCKED",
3097
3056
  details: {
3098
3057
  nodeId,
3058
+ nodeTypeId: node?.typeId,
3099
3059
  ...runtimeValidationError.details,
3100
3060
  },
3101
3061
  });
@@ -3106,8 +3066,7 @@ class NodeExecutor {
3106
3066
  if (runContextIds) {
3107
3067
  this.graph.addNodeRunContextIds(nodeId, runContextIds);
3108
3068
  }
3109
- if (!canSkipHandleResolution &&
3110
- !this.handleResolver.getPendingResolution(nodeId)) {
3069
+ if (!canSkipHandleResolution && !this.handleResolver.getPendingResolution(nodeId)) {
3111
3070
  this.handleResolver.scheduleRecomputeHandles(nodeId);
3112
3071
  }
3113
3072
  // Check if handles are being resolved - wait for resolution before executing
@@ -3158,9 +3117,7 @@ class NodeExecutor {
3158
3117
  return false;
3159
3118
  const policy = node.policy ?? {};
3160
3119
  const lastScheduledAt = node.lastScheduledAt;
3161
- return !!(policy.debounceMs &&
3162
- lastScheduledAt &&
3163
- now - lastScheduledAt < policy.debounceMs);
3120
+ return !!(policy.debounceMs && lastScheduledAt && now - lastScheduledAt < policy.debounceMs);
3164
3121
  }
3165
3122
  /**
3166
3123
  * Handle debounced scheduling by replacing the latest queued item
@@ -3443,6 +3400,7 @@ class NodeExecutor {
3443
3400
  this.eventEmitter.emit("error", {
3444
3401
  kind: "node-run",
3445
3402
  nodeId,
3403
+ nodeTypeId: node.typeId,
3446
3404
  runId: plan.runId,
3447
3405
  err,
3448
3406
  });
@@ -3475,9 +3433,7 @@ class NodeExecutor {
3475
3433
  return;
3476
3434
  const controllers = this.graph.getNodeControllers(nodeId);
3477
3435
  const lastEndAt = Date.now();
3478
- const lastDurationMs = node.stats.lastStartAt && lastEndAt
3479
- ? lastEndAt - node.stats.lastStartAt
3480
- : undefined;
3436
+ const lastDurationMs = node.stats.lastStartAt && lastEndAt ? lastEndAt - node.stats.lastStartAt : undefined;
3481
3437
  this.graph.updateNodeStats(nodeId, {
3482
3438
  active: Math.max(0, controllers.size),
3483
3439
  lastEndAt,
@@ -3645,7 +3601,7 @@ class RuntimeValidatorManager {
3645
3601
  }
3646
3602
  catch (err) {
3647
3603
  // Don't let validator errors break execution - log and continue
3648
- console.error(`Runtime validator error for node ${nodeId}:`, err);
3604
+ console.error(`Runtime validator error for node ${formatNodeRef(this.graph, nodeId)}:`, err);
3649
3605
  }
3650
3606
  }
3651
3607
  return null;
@@ -3658,7 +3614,7 @@ class GraphRuntime {
3658
3614
  // State
3659
3615
  this.environment = {};
3660
3616
  this.customNodeData = {};
3661
- this.runMode = null;
3617
+ this.runMode = "manual";
3662
3618
  this.pauseRefCount = 0;
3663
3619
  this.persistentPauseToken = null;
3664
3620
  // Initialize components
@@ -3780,11 +3736,7 @@ class GraphRuntime {
3780
3736
  : desc
3781
3737
  ? getInputDeclaredTypes(desc.inputs, handle)
3782
3738
  : undefined;
3783
- const typeIds = Array.isArray(declaredTypes)
3784
- ? declaredTypes
3785
- : declaredTypes
3786
- ? [declaredTypes]
3787
- : [];
3739
+ const typeIds = Array.isArray(declaredTypes) ? declaredTypes : declaredTypes ? [declaredTypes] : [];
3788
3740
  if (typeIds.length > 0) {
3789
3741
  const isValidForAny = typeIds.some((tId) => {
3790
3742
  const typeDesc = registry.types.get(tId);
@@ -3795,10 +3747,11 @@ class GraphRuntime {
3795
3747
  });
3796
3748
  if (value !== undefined && !isValidForAny) {
3797
3749
  const typeLabel = typeIds.join("|");
3798
- const errorMessage = `Invalid value for input ${nodeId}.${handle} (type ${typeLabel}): ${JSON.stringify(value)}`;
3750
+ const errorMessage = `Invalid value for input ${formatNodeRef(this.graph, nodeId)}.${handle} (type ${typeLabel}): ${JSON.stringify(value)}`;
3799
3751
  this.eventEmitter.emit("error", {
3800
3752
  kind: "input-validation",
3801
3753
  nodeId,
3754
+ nodeTypeId: node.typeId,
3802
3755
  handle,
3803
3756
  typeId: typeLabel,
3804
3757
  value,
@@ -4055,9 +4008,7 @@ class GraphRuntime {
4055
4008
  const shouldAutoRun = this.runMode === "auto" || node?.policy?.autoRun === true;
4056
4009
  let runContextIdsToUse = undefined;
4057
4010
  if (this.runMode === "manual") {
4058
- runContextIdsToUse = new Set([
4059
- this.runContextManager.createRunContext(nodeId, { propagate: false }),
4060
- ]);
4011
+ runContextIdsToUse = new Set([this.runContextManager.createRunContext(nodeId, { propagate: false })]);
4061
4012
  }
4062
4013
  if (shouldAutoRun && this.graph.allInboundHaveValue(nodeId)) {
4063
4014
  this.execute(nodeId, {
@@ -4230,8 +4181,7 @@ class GraphRuntime {
4230
4181
  set.add(e.target.handle);
4231
4182
  beforeInbound.set(e.target.nodeId, set);
4232
4183
  // Build beforeOutTargets map
4233
- const tmap = beforeOutTargets.get(e.source.nodeId) ??
4234
- new Map();
4184
+ const tmap = beforeOutTargets.get(e.source.nodeId) ?? new Map();
4235
4185
  const tset = tmap.get(e.source.handle) ?? new Set();
4236
4186
  tset.add(`${e.target.nodeId}.${e.target.handle}`);
4237
4187
  tmap.set(e.source.handle, tset);
@@ -4251,8 +4201,7 @@ class GraphRuntime {
4251
4201
  const changedHandles = {};
4252
4202
  for (const [nodeId, newHandles] of result.resolved) {
4253
4203
  const oldHandles = this.graph.getResolvedHandles(nodeId);
4254
- if (!oldHandles ||
4255
- JSON.stringify(oldHandles) !== JSON.stringify(newHandles)) {
4204
+ if (!oldHandles || JSON.stringify(oldHandles) !== JSON.stringify(newHandles)) {
4256
4205
  changedHandles[nodeId] = newHandles;
4257
4206
  }
4258
4207
  }
@@ -4304,8 +4253,7 @@ class GraphRuntime {
4304
4253
  // Propagate changes on edges added
4305
4254
  const afterOutTargets = new Map();
4306
4255
  this.graph.forEachEdge((e) => {
4307
- const targetMap = afterOutTargets.get(e.source.nodeId) ??
4308
- new Map();
4256
+ const targetMap = afterOutTargets.get(e.source.nodeId) ?? new Map();
4309
4257
  const targetSet = targetMap.get(e.source.handle) ?? new Set();
4310
4258
  targetSet.add(`${e.target.nodeId}.${e.target.handle}`);
4311
4259
  targetMap.set(e.source.handle, targetSet);
@@ -4330,10 +4278,7 @@ class GraphRuntime {
4330
4278
  for (const nodeId of nodesToCheck) {
4331
4279
  const beforeMap = beforeOutTargets.get(nodeId) ?? new Map();
4332
4280
  const afterMap = afterOutTargets.get(nodeId) ?? new Map();
4333
- const handles = new Set([
4334
- ...Array.from(beforeMap.keys()),
4335
- ...Array.from(afterMap.keys()),
4336
- ]);
4281
+ const handles = new Set([...Array.from(beforeMap.keys()), ...Array.from(afterMap.keys())]);
4337
4282
  for (const handle of handles) {
4338
4283
  const beforeTargetSet = beforeMap.get(handle) ?? new Set();
4339
4284
  const afterTargetSet = afterMap.get(handle) ?? new Set();
@@ -4454,7 +4399,10 @@ class GraphBuilder {
4454
4399
  effByNodeId.set(n.nodeId, getEffectiveHandles(n));
4455
4400
  const nodeType = this.registry.nodes.get(n.typeId);
4456
4401
  if (!nodeType) {
4457
- pushIssue("error", "NODE_TYPE_MISSING", `Unknown node type ${n.typeId}`, { typeId: n.typeId, nodeId: n.nodeId });
4402
+ pushIssue("error", "NODE_TYPE_MISSING", `Unknown node type ${n.typeId}`, {
4403
+ typeId: n.typeId,
4404
+ nodeId: n.nodeId,
4405
+ });
4458
4406
  continue;
4459
4407
  }
4460
4408
  if (!this.registry.categories.has(nodeType.categoryId)) {
@@ -4474,9 +4422,7 @@ class GraphBuilder {
4474
4422
  typeof paramValue === "number" &&
4475
4423
  !enumTypes.some((et) => validateEnumValue(et, paramValue, n.nodeId))) {
4476
4424
  const enumDef = this.registry.enums.get(enumTypes[0]);
4477
- const validValues = enumDef
4478
- ? Array.from(enumDef.valueToLabel.keys()).join(", ")
4479
- : "unknown";
4425
+ const validValues = enumDef ? Array.from(enumDef.valueToLabel.keys()).join(", ") : "unknown";
4480
4426
  pushIssue("error", "ENUM_VALUE_INVALID", `Node ${n.nodeId} param ${paramKey} has invalid enum value ${paramValue}. Valid values: ${validValues}`, {
4481
4427
  nodeId: n.nodeId,
4482
4428
  input: paramKey,
@@ -4496,9 +4442,7 @@ class GraphBuilder {
4496
4442
  typeof defaultValue === "number" &&
4497
4443
  !enumTypes.some((et) => validateEnumValue(et, defaultValue, n.nodeId))) {
4498
4444
  const enumDef = this.registry.enums.get(enumTypes[0]);
4499
- const validValues = enumDef
4500
- ? Array.from(enumDef.valueToLabel.keys()).join(", ")
4501
- : "unknown";
4445
+ const validValues = enumDef ? Array.from(enumDef.valueToLabel.keys()).join(", ") : "unknown";
4502
4446
  pushIssue("warning", "ENUM_DEFAULT_INVALID", `Node ${n.nodeId} input default ${handle} has invalid enum value ${defaultValue}. Valid values: ${validValues}`, {
4503
4447
  nodeId: n.nodeId,
4504
4448
  input: handle,
@@ -4541,7 +4485,9 @@ class GraphBuilder {
4541
4485
  if (e.typeId) {
4542
4486
  const type = this.registry.types.get(e.typeId);
4543
4487
  if (!type) {
4544
- pushIssue("error", "TYPE_MISSING", `Edge ${e.id} explicit type ${e.typeId} is missing or unknown`, { edgeId: e.id });
4488
+ pushIssue("error", "TYPE_MISSING", `Edge ${e.id} explicit type ${e.typeId} is missing or unknown`, {
4489
+ edgeId: e.id,
4490
+ });
4545
4491
  }
4546
4492
  }
4547
4493
  if (srcNode) {
@@ -4630,19 +4576,13 @@ class GraphBuilder {
4630
4576
  const outputTypes = {};
4631
4577
  for (const [outerIn, map] of Object.entries(exposure.inputs)) {
4632
4578
  const innerNode = def.nodes.find((n) => n.nodeId === map.nodeId);
4633
- const innerDesc = innerNode
4634
- ? this.registry.nodes.get(innerNode.typeId)
4635
- : undefined;
4636
- const typeIds = innerDesc
4637
- ? getInputDeclaredTypes(innerDesc.inputs, map.handle)
4638
- : undefined;
4579
+ const innerDesc = innerNode ? this.registry.nodes.get(innerNode.typeId) : undefined;
4580
+ const typeIds = innerDesc ? getInputDeclaredTypes(innerDesc.inputs, map.handle) : undefined;
4639
4581
  inputTypes[outerIn] = typeIds ?? "unknown";
4640
4582
  }
4641
4583
  for (const [outerOut, map] of Object.entries(exposure.outputs)) {
4642
4584
  const innerNode = def.nodes.find((n) => n.nodeId === map.nodeId);
4643
- const innerDesc = innerNode
4644
- ? this.registry.nodes.get(innerNode.typeId)
4645
- : undefined;
4585
+ const innerDesc = innerNode ? this.registry.nodes.get(innerNode.typeId) : undefined;
4646
4586
  const typeId = innerDesc ? innerDesc.outputs[map.handle] : undefined;
4647
4587
  const single = Array.isArray(typeId) ? typeId[0] : typeId;
4648
4588
  outputTypes[outerOut] = single ?? "unknown";
@@ -4845,7 +4785,7 @@ const CompositeCategory = (registry) => ({
4845
4785
  });
4846
4786
 
4847
4787
  // Helpers
4848
- const asArray = (v) => Array.isArray(v) ? v : [Number(v)];
4788
+ const asArray = (v) => (Array.isArray(v) ? v : [Number(v)]);
4849
4789
  const broadcast = (a, b) => {
4850
4790
  const aa = asArray(a);
4851
4791
  const bb = asArray(b);
@@ -4858,7 +4798,7 @@ const broadcast = (a, b) => {
4858
4798
  const len = Math.max(aa.length, bb.length);
4859
4799
  return [new Array(len).fill(aa[0] ?? 0), new Array(len).fill(bb[0] ?? 0)];
4860
4800
  };
4861
- const asBoolArray = (v) => Array.isArray(v) ? v.map((x) => Boolean(x)) : [Boolean(v)];
4801
+ const asBoolArray = (v) => (Array.isArray(v) ? v.map((x) => Boolean(x)) : [Boolean(v)]);
4862
4802
  const broadcastBool = (a, b) => {
4863
4803
  const aa = asBoolArray(a);
4864
4804
  const bb = asBoolArray(b);
@@ -4869,10 +4809,7 @@ const broadcastBool = (a, b) => {
4869
4809
  if (bb.length === 1)
4870
4810
  return [aa, new Array(aa.length).fill(bb[0])];
4871
4811
  const len = Math.max(aa.length, bb.length);
4872
- return [
4873
- new Array(len).fill(aa[0] ?? false),
4874
- new Array(len).fill(bb[0] ?? false),
4875
- ];
4812
+ return [new Array(len).fill(aa[0] ?? false), new Array(len).fill(bb[0] ?? false)];
4876
4813
  };
4877
4814
  const clamp = (x, min, max) => Math.min(max, Math.max(min, x));
4878
4815
  const lerp = (a, b, t) => a + (b - a) * t;
@@ -4922,8 +4859,7 @@ function jsonPointerSet(obj, pointer, value) {
4922
4859
  if (next === undefined || next === null) {
4923
4860
  // create container heuristically
4924
4861
  const nextKey = parts[i + 1];
4925
- cur[key] =
4926
- typeof nextKey === "string" && /^[0-9]+$/.test(nextKey) ? [] : {};
4862
+ cur[key] = typeof nextKey === "string" && /^[0-9]+$/.test(nextKey) ? [] : {};
4927
4863
  }
4928
4864
  cur = cur[key];
4929
4865
  }
@@ -5057,9 +4993,7 @@ function setupBasicGraphRegistry(id) {
5057
4993
  }, { withArray: false });
5058
4994
  registry.registerType({
5059
4995
  id: "base.vec3",
5060
- validate: (v) => Array.isArray(v) &&
5061
- v.length === 3 &&
5062
- v.every((x) => typeof x === "number"),
4996
+ validate: (v) => Array.isArray(v) && v.length === 3 && v.every((x) => typeof x === "number"),
5063
4997
  bakeTarget: { nodeTypeId: "base.input.vec3", inputHandle: "Value" },
5064
4998
  }, { withArray: true, arrayPickFirstDefined: true });
5065
4999
  // float -> vec3 : map x to [x,0,0]
@@ -5104,9 +5038,7 @@ function setupBasicGraphRegistry(id) {
5104
5038
  });
5105
5039
  registry.registerCoercion("base.object", "base.vec3", (v) => {
5106
5040
  try {
5107
- if (Array.isArray(v) &&
5108
- v.length === 3 &&
5109
- v.every((x) => typeof x === "number")) {
5041
+ if (Array.isArray(v) && v.length === 3 && v.every((x) => typeof x === "number")) {
5110
5042
  return v;
5111
5043
  }
5112
5044
  return undefined;
@@ -5236,9 +5168,7 @@ function setupBasicGraphRegistry(id) {
5236
5168
  const [a, b] = broadcast(ins.ValueA, ins.ValueB);
5237
5169
  const t = Number(ins.Factor ?? 0);
5238
5170
  const len = Math.max(a.length, b.length);
5239
- const out = new Array(len)
5240
- .fill(0)
5241
- .map((_, i) => lerp(Number(a[i] ?? 0), Number(b[i] ?? 0), t));
5171
+ const out = new Array(len).fill(0).map((_, i) => lerp(Number(a[i] ?? 0), Number(b[i] ?? 0), t));
5242
5172
  return { Value: out };
5243
5173
  },
5244
5174
  });
@@ -5266,9 +5196,7 @@ function setupBasicGraphRegistry(id) {
5266
5196
  const out = vals.map((v) => {
5267
5197
  const t = (Number(v) - fromMin) / (fromMax - fromMin || 1);
5268
5198
  const r = toMin + t * (toMax - toMin);
5269
- return doClamp
5270
- ? clamp(r, Math.min(toMin, toMax), Math.max(toMin, toMax))
5271
- : r;
5199
+ return doClamp ? clamp(r, Math.min(toMin, toMax), Math.max(toMin, toMax)) : r;
5272
5200
  });
5273
5201
  return { Value: out };
5274
5202
  },
@@ -5312,8 +5240,8 @@ function setupBasicGraphRegistry(id) {
5312
5240
  const sum = arr.reduce((s, x) => s + Number(x || 0), 0);
5313
5241
  return arr.length ? sum / arr.length : 0;
5314
5242
  },
5315
- [BaseMathOperation.MinAll]: (arr) => arr.length ? Math.min(...arr.map((x) => Number(x))) : 0,
5316
- [BaseMathOperation.MaxAll]: (arr) => arr.length ? Math.max(...arr.map((x) => Number(x))) : 0,
5243
+ [BaseMathOperation.MinAll]: (arr) => (arr.length ? Math.min(...arr.map((x) => Number(x))) : 0),
5244
+ [BaseMathOperation.MaxAll]: (arr) => (arr.length ? Math.max(...arr.map((x) => Number(x))) : 0),
5317
5245
  };
5318
5246
  if (aggregateByOp[op] !== undefined)
5319
5247
  return { Result: [aggregateByOp[op](a)] };
@@ -5330,8 +5258,8 @@ function setupBasicGraphRegistry(id) {
5330
5258
  const fn = binaryByOp[op] || binaryByOp[BaseMathOperation.Add];
5331
5259
  const len = Math.max(a.length, b.length);
5332
5260
  const out = new Array(len).fill(0).map((_, i) => {
5333
- const ax = a.length === 1 && len > 1 ? a[0] : a[i] ?? 0;
5334
- const bx = b.length === 1 && len > 1 ? b[0] : b[i] ?? 0;
5261
+ const ax = a.length === 1 && len > 1 ? a[0] : (a[i] ?? 0);
5262
+ const bx = b.length === 1 && len > 1 ? b[0] : (b[i] ?? 0);
5335
5263
  return fn(Number(ax), Number(bx));
5336
5264
  });
5337
5265
  return { Result: out };
@@ -5472,9 +5400,7 @@ function setupBasicGraphRegistry(id) {
5472
5400
  impl: (ins) => {
5473
5401
  const arr = Array.isArray(ins.Items) ? ins.Items : [];
5474
5402
  const s = Math.trunc(Number(ins.Start ?? 0));
5475
- const e = Number.isFinite(Number(ins.End))
5476
- ? Math.trunc(Number(ins.End))
5477
- : undefined;
5403
+ const e = Number.isFinite(Number(ins.End)) ? Math.trunc(Number(ins.End)) : undefined;
5478
5404
  return { Result: arr.slice(s, e) };
5479
5405
  },
5480
5406
  });
@@ -5749,11 +5675,7 @@ function setupBasicGraphRegistry(id) {
5749
5675
  outputs: { Keys: "base.string[]" },
5750
5676
  impl: (ins) => {
5751
5677
  const obj = ins.Object;
5752
- const keys = isPlainObject(obj)
5753
- ? Object.keys(obj)
5754
- : Array.isArray(obj)
5755
- ? Object.keys(obj)
5756
- : [];
5678
+ const keys = isPlainObject(obj) ? Object.keys(obj) : Array.isArray(obj) ? Object.keys(obj) : [];
5757
5679
  return { Keys: keys };
5758
5680
  },
5759
5681
  });
@@ -5764,11 +5686,7 @@ function setupBasicGraphRegistry(id) {
5764
5686
  outputs: { Values: "base.object" },
5765
5687
  impl: (ins) => {
5766
5688
  const obj = ins.Object;
5767
- const vals = isPlainObject(obj)
5768
- ? Object.values(obj)
5769
- : Array.isArray(obj)
5770
- ? Object.values(obj)
5771
- : [];
5689
+ const vals = isPlainObject(obj) ? Object.values(obj) : Array.isArray(obj) ? Object.values(obj) : [];
5772
5690
  return { Values: vals };
5773
5691
  },
5774
5692
  });
@@ -5780,11 +5698,7 @@ function setupBasicGraphRegistry(id) {
5780
5698
  impl: (ins) => {
5781
5699
  const root = structuredClone(ins.Object);
5782
5700
  const opsRaw = ins.Ops;
5783
- const ops = Array.isArray(opsRaw)
5784
- ? opsRaw
5785
- : opsRaw
5786
- ? [opsRaw]
5787
- : [];
5701
+ const ops = Array.isArray(opsRaw) ? opsRaw : opsRaw ? [opsRaw] : [];
5788
5702
  let cur = root;
5789
5703
  for (const op of ops) {
5790
5704
  if (!op || typeof op !== "object")
@@ -5875,9 +5789,7 @@ function registerDelayNode(registry) {
5875
5789
  impl: async (ins, ctx) => {
5876
5790
  const ms = Number(ins.DelayMs ?? 200);
5877
5791
  const valueRaw = ins.Value;
5878
- if (valueRaw === undefined ||
5879
- valueRaw === null ||
5880
- Number.isNaN(Number(valueRaw))) {
5792
+ if (valueRaw === undefined || valueRaw === null || Number.isNaN(Number(valueRaw))) {
5881
5793
  return; // wait until x is present to avoid NaN emissions
5882
5794
  }
5883
5795
  await new Promise((resolve, reject) => {
@@ -5947,9 +5859,7 @@ function generateId(prefix, used = new Set()) {
5947
5859
  id = `${prefix}${Math.random().toString(36).slice(2, 8)}`;
5948
5860
  attempts++;
5949
5861
  if (attempts > 1000) {
5950
- id = `${prefix}${Date.now().toString(36)}${Math.random()
5951
- .toString(36)
5952
- .slice(2, 4)}`;
5862
+ id = `${prefix}${Date.now().toString(36)}${Math.random().toString(36).slice(2, 4)}`;
5953
5863
  }
5954
5864
  } while (used.has(id));
5955
5865
  return id;
@@ -5990,12 +5900,10 @@ function installLogging(engine) {
5990
5900
  console.warn(`[error] input-validation: ${e.nodeId}.${e.handle} (type ${e.typeId})`, e.message);
5991
5901
  }
5992
5902
  else if (e.kind === "registry") {
5993
- console.warn(`[error] registry:`, e.err?.message ?? e.err, e.attempt !== undefined
5994
- ? `(attempt ${e.attempt}/${e.maxAttempts ?? "?"})`
5995
- : "");
5903
+ console.warn(`[error] registry:`, e.err?.message ?? e.err, e.attempt !== undefined ? `(attempt ${e.attempt}/${e.maxAttempts ?? "?"})` : "");
5996
5904
  }
5997
5905
  else if (e.kind === "system") {
5998
- console.warn(`[error] system: ${e.message}`, e.code ? `(code: ${e.code})` : "", e.err ? e.err?.message ?? e.err : "", e.details ? JSON.stringify(e.details) : "");
5906
+ console.warn(`[error] system: ${e.message}`, e.code ? `(code: ${e.code})` : "", e.err ? (e.err?.message ?? e.err) : "", e.details ? JSON.stringify(e.details) : "");
5999
5907
  }
6000
5908
  else {
6001
5909
  // Log any other error kinds (shouldn't happen, but handle gracefully)
@@ -6320,11 +6228,7 @@ function buildTypeMaps(def) {
6320
6228
  }
6321
6229
  if (node.resolvedHandles?.outputs) {
6322
6230
  for (const [handleId, handleDesc] of Object.entries(node.resolvedHandles.outputs)) {
6323
- const typeId = typeof handleDesc === "string"
6324
- ? handleDesc
6325
- : Array.isArray(handleDesc)
6326
- ? handleDesc[0]
6327
- : undefined;
6231
+ const typeId = typeof handleDesc === "string" ? handleDesc : Array.isArray(handleDesc) ? handleDesc[0] : undefined;
6328
6232
  if (typeId)
6329
6233
  nodeOutputTypes.set(handleId, typeId);
6330
6234
  }
@@ -6375,8 +6279,7 @@ function applyConversion(items, values, converter, type) {
6375
6279
  });
6376
6280
  if (convertedValue === null) {
6377
6281
  delete values[item.nodeId]?.[item.handleId];
6378
- if (values[item.nodeId] &&
6379
- Object.keys(values[item.nodeId]).length === 0) {
6282
+ if (values[item.nodeId] && Object.keys(values[item.nodeId]).length === 0) {
6380
6283
  delete values[item.nodeId];
6381
6284
  }
6382
6285
  }
@@ -6422,7 +6325,7 @@ function convertSnapshot(snapshot, converter) {
6422
6325
  }
6423
6326
  const { converted: convertedInputs, toConvert: inputsToConvert } = collectValuesToConvert(snapshot.inputs ?? {}, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "input");
6424
6327
  const { converted: convertedOutputs, toConvert: outputsToConvert } = collectValuesToConvert(snapshot.outputs ?? {}, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "output");
6425
- const { converted: convertedInputDefaults, toConvert: inputDefaultsToConvert, } = collectValuesToConvert(inputDefaults, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "inputDefault");
6328
+ const { converted: convertedInputDefaults, toConvert: inputDefaultsToConvert } = collectValuesToConvert(inputDefaults, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "inputDefault");
6426
6329
  applyConversion(inputsToConvert, convertedInputs, converter, "input");
6427
6330
  applyConversion(outputsToConvert, convertedOutputs, converter, "output");
6428
6331
  applyConversion(inputDefaultsToConvert, convertedInputDefaults, converter, "inputDefault");
@@ -6612,7 +6515,7 @@ function matchesPattern(value, pattern) {
6612
6515
  */
6613
6516
  function buildValueConverter(config) {
6614
6517
  return (converterConfig) => {
6615
- const { nodeId, handleId, value, type, nodeTypeId, handleDataType, runtimeTypeId, } = converterConfig;
6518
+ const { nodeId, handleId, value, type, nodeTypeId, handleDataType, runtimeTypeId } = converterConfig;
6616
6519
  const isValueTyped = isTyped(value);
6617
6520
  for (const mapping of config.mappings) {
6618
6521
  if (mapping.type && mapping.type !== type)
@@ -6655,8 +6558,7 @@ function buildValueConverter(config) {
6655
6558
  }
6656
6559
  }
6657
6560
  else {
6658
- if (typeof matchValue === "string" ||
6659
- typeof matchValue === "number") {
6561
+ if (typeof matchValue === "string" || typeof matchValue === "number") {
6660
6562
  const key = String(matchValue);
6661
6563
  if (key in mapping.valueMap) {
6662
6564
  newValue = mapping.valueMap[key];
@@ -6690,8 +6592,7 @@ function buildValueConverter(config) {
6690
6592
  }
6691
6593
  }
6692
6594
  else {
6693
- if (typeof innerValue === "string" ||
6694
- typeof innerValue === "number") {
6595
+ if (typeof innerValue === "string" || typeof innerValue === "number") {
6695
6596
  const key = String(innerValue);
6696
6597
  if (key in mapping.valueMap) {
6697
6598
  newValue = mapping.valueMap[key];
@@ -6718,8 +6619,7 @@ function buildValueConverter(config) {
6718
6619
  : firstSegment instanceof RegExp
6719
6620
  ? null
6720
6621
  : String(firstSegment);
6721
- if (firstSegmentStr !== "__spark_value" &&
6722
- firstSegmentStr !== "__spark_type") {
6622
+ if (firstSegmentStr !== "__spark_value" && firstSegmentStr !== "__spark_type") {
6723
6623
  pathSegments = ["__spark_value", ...pathSegments];
6724
6624
  }
6725
6625
  }
@@ -6739,8 +6639,7 @@ function buildValueConverter(config) {
6739
6639
  }
6740
6640
  }
6741
6641
  else {
6742
- if (typeof matchValue === "string" ||
6743
- typeof matchValue === "number") {
6642
+ if (typeof matchValue === "string" || typeof matchValue === "number") {
6744
6643
  const key = String(matchValue);
6745
6644
  if (key in mapping.valueMap) {
6746
6645
  newValue = mapping.valueMap[key];