@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/esm/index.js CHANGED
@@ -2,9 +2,7 @@ function typed(typeId, value) {
2
2
  return { __spark_type: typeId, __spark_value: value };
3
3
  }
4
4
  function isTyped(v) {
5
- return (!!v &&
6
- typeof v === "object" &&
7
- Object.prototype.hasOwnProperty.call(v, "__spark_type"));
5
+ return !!v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "__spark_type");
8
6
  }
9
7
  function unwrapTypeId(v) {
10
8
  if (isTyped(v))
@@ -64,12 +62,8 @@ function mergeInputHandleDescriptors(staticDesc, dynamicDesc) {
64
62
  (typeof dynamicDesc === "string" || Array.isArray(dynamicDesc))) {
65
63
  return dynamicDesc;
66
64
  }
67
- const staticObj = typeof staticDesc === "string" || Array.isArray(staticDesc)
68
- ? { typeId: staticDesc }
69
- : staticDesc;
70
- const dynamicObj = typeof dynamicDesc === "string" || Array.isArray(dynamicDesc)
71
- ? { typeId: dynamicDesc }
72
- : dynamicDesc;
65
+ const staticObj = typeof staticDesc === "string" || Array.isArray(staticDesc) ? { typeId: staticDesc } : staticDesc;
66
+ const dynamicObj = typeof dynamicDesc === "string" || Array.isArray(dynamicDesc) ? { typeId: dynamicDesc } : dynamicDesc;
73
67
  // Merge: dynamic takes precedence, but merge metadata objects
74
68
  const merged = {
75
69
  typeId: dynamicObj.typeId ?? staticObj.typeId,
@@ -150,7 +144,7 @@ class Registry {
150
144
  };
151
145
  this.types.set(arrayId, arrayDesc);
152
146
  }
153
- this.registerCoercion(desc.id, arrayId, (value) => Array.isArray(value) ? value : [value]);
147
+ this.registerCoercion(desc.id, arrayId, (value) => (Array.isArray(value) ? value : [value]));
154
148
  this.registerCoercion(arrayId, desc.id, (value) => {
155
149
  if (!Array.isArray(value))
156
150
  return value;
@@ -176,8 +170,8 @@ class Registry {
176
170
  const arrayId = `${typeId}[]`;
177
171
  if (this.types.has(arrayId) && !this.serializers.has(arrayId)) {
178
172
  this.serializers.set(arrayId, {
179
- serialize: (value) => Array.isArray(value) ? value.map((el) => s.serialize(el)) : value,
180
- deserialize: (data) => Array.isArray(data) ? data.map((el) => s.deserialize(el)) : data,
173
+ serialize: (value) => (Array.isArray(value) ? value.map((el) => s.serialize(el)) : value),
174
+ deserialize: (data) => (Array.isArray(data) ? data.map((el) => s.deserialize(el)) : data),
181
175
  });
182
176
  }
183
177
  return this;
@@ -353,8 +347,7 @@ class Registry {
353
347
  let i = 0;
354
348
  while (i < queue.length) {
355
349
  const q = queue[i];
356
- if (e.cost.edges < q.cost.edges ||
357
- (e.cost.edges === q.cost.edges && e.cost.async < q.cost.async)) {
350
+ if (e.cost.edges < q.cost.edges || (e.cost.edges === q.cost.edges && e.cost.async < q.cost.async)) {
358
351
  break;
359
352
  }
360
353
  i++;
@@ -473,9 +466,7 @@ class Registry {
473
466
  const rec = this.enums.get(id);
474
467
  if (!rec)
475
468
  return value;
476
- return rec.valueToLabel.has(n)
477
- ? n
478
- : Array.from(rec.valueToLabel.keys())[0] ?? 0;
469
+ return rec.valueToLabel.has(n) ? n : (Array.from(rec.valueToLabel.keys())[0] ?? 0);
479
470
  });
480
471
  this.registerCoercion(id, labelType, (value) => {
481
472
  const n = Number(value);
@@ -922,8 +913,7 @@ class Graph {
922
913
  if (inbound.length === 0)
923
914
  return true;
924
915
  for (const e of inbound) {
925
- if (node.resolvedHandles?.inputs?.[e.target.handle] &&
926
- !node.inputs[e.target.handle]) {
916
+ if (node.resolvedHandles?.inputs?.[e.target.handle] && !node.inputs[e.target.handle]) {
927
917
  return false;
928
918
  }
929
919
  }
@@ -1001,9 +991,7 @@ function getValueAtPath(obj, pathSegments) {
1001
991
  let current = obj;
1002
992
  for (let i = 0; i < pathSegments.length - 1; i++) {
1003
993
  const segment = pathSegments[i];
1004
- if (current === null ||
1005
- current === undefined ||
1006
- typeof current !== "object") {
994
+ if (current === null || current === undefined || typeof current !== "object") {
1007
995
  return null;
1008
996
  }
1009
997
  if (typeof segment === "string") {
@@ -1052,9 +1040,7 @@ function getValueAtPath(obj, pathSegments) {
1052
1040
  return null;
1053
1041
  return { value: current[index], parent: current, key: index };
1054
1042
  }
1055
- else if (current !== null &&
1056
- current !== undefined &&
1057
- typeof current === "object") {
1043
+ else if (current !== null && current !== undefined && typeof current === "object") {
1058
1044
  return {
1059
1045
  value: current[lastSegment],
1060
1046
  parent: current,
@@ -1168,29 +1154,20 @@ function findMatchingPaths(obj, pathSegments, currentPath = []) {
1168
1154
  if (Array.isArray(obj)) {
1169
1155
  const index = parseInt(currentSegment, 10);
1170
1156
  if (!isNaN(index) && index >= 0 && index < obj.length) {
1171
- results.push(...findMatchingPaths(obj[index], remainingSegments, [
1172
- ...currentPath,
1173
- index,
1174
- ]));
1157
+ results.push(...findMatchingPaths(obj[index], remainingSegments, [...currentPath, index]));
1175
1158
  }
1176
1159
  }
1177
1160
  else if (obj !== null && obj !== undefined && typeof obj === "object") {
1178
1161
  const objRecord = obj;
1179
1162
  if (currentSegment in objRecord) {
1180
- results.push(...findMatchingPaths(objRecord[currentSegment], remainingSegments, [
1181
- ...currentPath,
1182
- currentSegment,
1183
- ]));
1163
+ results.push(...findMatchingPaths(objRecord[currentSegment], remainingSegments, [...currentPath, currentSegment]));
1184
1164
  }
1185
1165
  }
1186
1166
  }
1187
1167
  else if (typeof currentSegment === "number") {
1188
1168
  if (Array.isArray(obj)) {
1189
1169
  if (currentSegment >= 0 && currentSegment < obj.length) {
1190
- results.push(...findMatchingPaths(obj[currentSegment], remainingSegments, [
1191
- ...currentPath,
1192
- currentSegment,
1193
- ]));
1170
+ results.push(...findMatchingPaths(obj[currentSegment], remainingSegments, [...currentPath, currentSegment]));
1194
1171
  }
1195
1172
  }
1196
1173
  }
@@ -1204,10 +1181,7 @@ function findMatchingPaths(obj, pathSegments, currentPath = []) {
1204
1181
  const objRecord = obj;
1205
1182
  for (const key of Object.keys(objRecord)) {
1206
1183
  if (currentSegment.test(key)) {
1207
- results.push(...findMatchingPaths(objRecord[key], remainingSegments, [
1208
- ...currentPath,
1209
- key,
1210
- ]));
1184
+ results.push(...findMatchingPaths(objRecord[key], remainingSegments, [...currentPath, key]));
1211
1185
  }
1212
1186
  }
1213
1187
  }
@@ -1218,12 +1192,8 @@ function stringifyJson(obj, oneLiner) {
1218
1192
  // No formatting requested: behave exactly like native JSON.stringify.
1219
1193
  if (!oneLiner)
1220
1194
  return JSON.stringify(obj);
1221
- const indentSize = Number.isFinite(oneLiner.indent)
1222
- ? Math.max(0, Math.floor(oneLiner.indent))
1223
- : 2;
1224
- const maxDepth = typeof oneLiner.maxDepth === "number" && Number.isFinite(oneLiner.maxDepth)
1225
- ? oneLiner.maxDepth
1226
- : undefined;
1195
+ const indentSize = Number.isFinite(oneLiner.indent) ? Math.max(0, Math.floor(oneLiner.indent)) : 2;
1196
+ const maxDepth = typeof oneLiner.maxDepth === "number" && Number.isFinite(oneLiner.maxDepth) ? oneLiner.maxDepth : undefined;
1227
1197
  const patterns = (oneLiner.paths || []).filter(Boolean);
1228
1198
  // Preserve JSON.stringify semantics for things like toJSON(), dropping functions/undefined, etc.
1229
1199
  // Note: this still throws on circular structures (same as JSON.stringify).
@@ -1426,22 +1396,13 @@ function compilePathMatcher(pattern) {
1426
1396
  res = ti < pathTokens.length && go(pi + 1, ti + 1);
1427
1397
  }
1428
1398
  else if (p === "#") {
1429
- res =
1430
- ti < pathTokens.length &&
1431
- isNumericSegment(pathTokens[ti]) &&
1432
- go(pi + 1, ti + 1);
1399
+ res = ti < pathTokens.length && isNumericSegment(pathTokens[ti]) && go(pi + 1, ti + 1);
1433
1400
  }
1434
1401
  else if (p === "[*]") {
1435
- res =
1436
- ti < pathTokens.length &&
1437
- isIndex(pathTokens[ti]) &&
1438
- go(pi + 1, ti + 1);
1402
+ res = ti < pathTokens.length && isIndex(pathTokens[ti]) && go(pi + 1, ti + 1);
1439
1403
  }
1440
1404
  else {
1441
- res =
1442
- ti < pathTokens.length &&
1443
- eq(p.toLowerCase(), pathTokens[ti].toLowerCase()) &&
1444
- go(pi + 1, ti + 1);
1405
+ res = ti < pathTokens.length && eq(p.toLowerCase(), pathTokens[ti].toLowerCase()) && go(pi + 1, ti + 1);
1445
1406
  }
1446
1407
  }
1447
1408
  memo.set(key, res);
@@ -1467,10 +1428,7 @@ function stringifySceneAndOps(obj) {
1467
1428
  "**.perUserExt.*.#",
1468
1429
  "**.perUserExt.*.*.#",
1469
1430
  ],
1470
- criteria: ({ value, key }) => (typeof value === "object" &&
1471
- value &&
1472
- Object.keys(value).sort().join(",") === "x,y,z") ||
1473
- key === "value",
1431
+ criteria: ({ value, key }) => (typeof value === "object" && value && Object.keys(value).sort().join(",") === "x,y,z") || key === "value",
1474
1432
  });
1475
1433
  }
1476
1434
 
@@ -1540,8 +1498,7 @@ class LevelLogger {
1540
1498
  parseJsonStringIfFull(str) {
1541
1499
  const trimmed = str.trim();
1542
1500
  // Check if the string starts with { or [ and ends with } or ]
1543
- if ((trimmed.startsWith("{") && trimmed.endsWith("}")) ||
1544
- (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
1501
+ if ((trimmed.startsWith("{") && trimmed.endsWith("}")) || (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
1545
1502
  try {
1546
1503
  const parsed = JSON.parse(trimmed);
1547
1504
  return JSON.stringify(parsed, null, 2);
@@ -1560,8 +1517,7 @@ class LevelLogger {
1560
1517
  parseJsonStringToObject(str) {
1561
1518
  const trimmed = str.trim();
1562
1519
  // Check if the string starts with { or [ and ends with } or ]
1563
- if ((trimmed.startsWith("{") && trimmed.endsWith("}")) ||
1564
- (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
1520
+ if ((trimmed.startsWith("{") && trimmed.endsWith("}")) || (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
1565
1521
  try {
1566
1522
  return JSON.parse(trimmed);
1567
1523
  }
@@ -1662,10 +1618,7 @@ class LevelLogger {
1662
1618
  // (starts with { or [ and contains newlines indicating it was formatted),
1663
1619
  // output it directly without stringifySceneAndOps to preserve formatting
1664
1620
  // Wrap it with json`...` to distinguish it as formatted JSON
1665
- if (parseJsonString &&
1666
- typeof v === "string" &&
1667
- v.trim().match(/^[{\[]/) &&
1668
- v.includes("\n")) {
1621
+ if (parseJsonString && typeof v === "string" && v.trim().match(/^[{\[]/) && v.includes("\n")) {
1669
1622
  return `${k}=json\`${v}\``;
1670
1623
  }
1671
1624
  // If this key had a JSON string parsed and we're formatting JSON,
@@ -1680,9 +1633,7 @@ class LevelLogger {
1680
1633
  })
1681
1634
  .join(formatJson ? "\n" : " ")}`
1682
1635
  : "";
1683
- const prefixedMessage = this.prefix
1684
- ? `${this.prefix} ${message}${contextStr}`
1685
- : `${message}${contextStr}`;
1636
+ const prefixedMessage = this.prefix ? `${this.prefix} ${message}${contextStr}` : `${message}${contextStr}`;
1686
1637
  switch (requestedLevel) {
1687
1638
  case "debug":
1688
1639
  console.info(prefixedMessage);
@@ -1917,10 +1868,7 @@ class RunContextManager {
1917
1868
  });
1918
1869
  return;
1919
1870
  }
1920
- if (ctx.pendingNodes > 0 ||
1921
- ctx.pendingEdges > 0 ||
1922
- ctx.pendingResolvers > 0 ||
1923
- ctx.pendingQueued > 0) {
1871
+ if (ctx.pendingNodes > 0 || ctx.pendingEdges > 0 || ctx.pendingResolvers > 0 || ctx.pendingQueued > 0) {
1924
1872
  return; // Still has pending work
1925
1873
  }
1926
1874
  this.logger.info("finish-run-context", {
@@ -2039,6 +1987,19 @@ function valuesEqual(a, b) {
2039
1987
  }
2040
1988
  return false;
2041
1989
  }
1990
+ /**
1991
+ * Format a node reference as <typeId>.<nodeId> for logs.
1992
+ */
1993
+ function formatNodeRef(graph, nodeId) {
1994
+ const node = graph.getNode(nodeId);
1995
+ return `${node?.typeId ?? "unknown"}.${nodeId}`;
1996
+ }
1997
+ /**
1998
+ * Format a node handle reference as <typeId>.<nodeId>.<handle> for logs.
1999
+ */
2000
+ function formatNodeHandleRef(graph, nodeId, handle) {
2001
+ return `${formatNodeRef(graph, nodeId)}.${handle}`;
2002
+ }
2042
2003
 
2043
2004
  function tryHandleResolving(def, registry, environment) {
2044
2005
  const out = new Map();
@@ -2146,9 +2107,7 @@ function extractEdgeTypes(sourceNodeId, sourceHandle, targetNodeId, targetHandle
2146
2107
  const srcDeclared = srcResolved
2147
2108
  ? srcResolved.outputs[sourceHandle]
2148
2109
  : registry.nodes.get(graph.getNode(sourceNodeId)?.typeId || "")?.outputs[sourceHandle];
2149
- const dstDeclared = getInputDeclaredTypes(dstResolved
2150
- ? dstResolved.inputs
2151
- : registry.nodes.get(graph.getNode(targetNodeId)?.typeId || "")?.inputs, targetHandle);
2110
+ const dstDeclared = getInputDeclaredTypes(dstResolved ? dstResolved.inputs : registry.nodes.get(graph.getNode(targetNodeId)?.typeId || "")?.inputs, targetHandle);
2152
2111
  return {
2153
2112
  srcDeclared,
2154
2113
  dstDeclared,
@@ -2244,9 +2203,7 @@ function buildEdgeConverters(srcDeclared, dstDeclared, registry, edgeLabel) {
2244
2203
  const { typeId, payload } = extractPayload(v);
2245
2204
  const res = getCoercion(typeId);
2246
2205
  if (!res) {
2247
- const fallbackType = isDstUnion && typeId && dstTypes.includes(typeId)
2248
- ? typeId
2249
- : undefined;
2206
+ const fallbackType = isDstUnion && typeId && dstTypes.includes(typeId) ? typeId : undefined;
2250
2207
  return wrapIfDstUnion(fallbackType, payload);
2251
2208
  }
2252
2209
  if (res.kind === "async" && res.convertAsync) {
@@ -2267,9 +2224,7 @@ function buildEdgeConverters(srcDeclared, dstDeclared, registry, edgeLabel) {
2267
2224
  const { typeId, payload } = extractPayload(v);
2268
2225
  const res = getCoercion(typeId);
2269
2226
  if (!res) {
2270
- const fallbackType = isDstUnion && typeId && dstTypes.includes(typeId)
2271
- ? typeId
2272
- : undefined;
2227
+ const fallbackType = isDstUnion && typeId && dstTypes.includes(typeId) ? typeId : undefined;
2273
2228
  return wrapIfDstUnion(fallbackType, payload);
2274
2229
  }
2275
2230
  if (res.kind === "async") {
@@ -2443,15 +2398,11 @@ class HandleResolver {
2443
2398
  // Update edge properties via Graph
2444
2399
  this.graph.updateEdgeProperties(e.id, {
2445
2400
  dstDeclared,
2446
- srcUnionTypes: Array.isArray(srcDeclared)
2447
- ? [...srcDeclared]
2448
- : undefined,
2401
+ srcUnionTypes: Array.isArray(srcDeclared) ? [...srcDeclared] : undefined,
2449
2402
  convert: conv.convert,
2450
2403
  convertAsync: conv.convertAsync,
2451
2404
  });
2452
- if (e.target.nodeId === nodeId &&
2453
- oldDstDeclared === undefined &&
2454
- dstDeclared !== undefined) {
2405
+ if (e.target.nodeId === nodeId && oldDstDeclared === undefined && dstDeclared !== undefined) {
2455
2406
  const srcNode = this.graph.getNode(e.source.nodeId);
2456
2407
  if (srcNode) {
2457
2408
  const srcValue = srcNode.outputs[e.source.handle];
@@ -2487,7 +2438,7 @@ class HandleResolver {
2487
2438
  const nodeLogValue = LOG_LEVEL_VALUES[nodeLogLevel] ?? 1;
2488
2439
  const shouldLog = nodeLogValue <= LOG_LEVEL_VALUES.debug && nodeLogLevel !== "silent";
2489
2440
  if (shouldLog) {
2490
- console.info(`[node:${nodeId}:${node.typeId}] resolveHandles-start`);
2441
+ console.info(`[node:${formatNodeRef(this.graph, nodeId)}] resolveHandles-start`);
2491
2442
  }
2492
2443
  let resolved;
2493
2444
  try {
@@ -2502,13 +2453,13 @@ class HandleResolver {
2502
2453
  catch {
2503
2454
  // Log resolveHandles-done even on error
2504
2455
  if (shouldLog) {
2505
- console.info(`[node:${nodeId}:${node.typeId}] resolveHandles-done (error)`);
2456
+ console.info(`[node:${formatNodeRef(this.graph, nodeId)}] resolveHandles-done (error)`);
2506
2457
  }
2507
2458
  return;
2508
2459
  }
2509
2460
  // Log resolveHandles-done
2510
2461
  if (shouldLog) {
2511
- console.info(`[node:${nodeId}:${node.typeId}] resolveHandles-done`);
2462
+ console.info(`[node:${formatNodeRef(this.graph, nodeId)}] resolveHandles-done`);
2512
2463
  }
2513
2464
  // If a newer recompute was scheduled, drop this result
2514
2465
  if ((this.recomputeTokenByNode.get(nodeId) ?? 0) !== token)
@@ -2604,9 +2555,7 @@ class EdgePropagator {
2604
2555
  const effectiveRunContexts = runContextIds && runContextIds.size > 0
2605
2556
  ? this.filterEffectiveRunContexts(edge, srcNodeId, runContextIds)
2606
2557
  : undefined;
2607
- if (runContextIds &&
2608
- runContextIds.size > 0 &&
2609
- !(effectiveRunContexts && effectiveRunContexts.size > 0)) {
2558
+ if (runContextIds && runContextIds.size > 0 && !(effectiveRunContexts && effectiveRunContexts.size > 0)) {
2610
2559
  return; // No valid run-contexts for this edge
2611
2560
  }
2612
2561
  // Validate union types
@@ -2647,12 +2596,16 @@ class EdgePropagator {
2647
2596
  const isUnion = Array.isArray(edge.srcUnionTypes);
2648
2597
  const isTypedValue = isTyped(value);
2649
2598
  if (isUnion && !isTypedValue) {
2599
+ const sourceTypeId = this.graph.getNode(edge.source.nodeId)?.typeId;
2600
+ const targetTypeId = this.graph.getNode(edge.target.nodeId)?.typeId;
2650
2601
  const err = new Error(`Output ${srcNodeId}.${edge.source.handle} requires typed value for union output (allowed: ${edge.srcUnionTypes.join("|")})`);
2651
2602
  this.eventEmitter.emit("error", {
2652
2603
  kind: "edge-convert",
2653
2604
  edgeId: edge.id,
2654
2605
  source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
2655
2606
  target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
2607
+ sourceTypeId,
2608
+ targetTypeId,
2656
2609
  err,
2657
2610
  });
2658
2611
  return false;
@@ -2668,7 +2621,14 @@ class EdgePropagator {
2668
2621
  convertedValue = edge.convert(value);
2669
2622
  }
2670
2623
  else {
2671
- console.warn(`No convert function for edge ${edge.id} of type ${edge.source.nodeId}.${edge.source.handle} -> ${edge.target.nodeId}.${edge.target.handle}`);
2624
+ const fromType = (Array.isArray(edge.srcUnionTypes) && edge.srcUnionTypes.length > 0
2625
+ ? edge.srcUnionTypes.join("|")
2626
+ : undefined) ??
2627
+ unwrapTypeId(value) ??
2628
+ edge.typeId ??
2629
+ "unknown";
2630
+ const toType = Array.isArray(edge.dstDeclared) ? edge.dstDeclared.join("|") : (edge.dstDeclared ?? "unknown");
2631
+ 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}`);
2672
2632
  }
2673
2633
  this.applyToTarget(edge, convertedValue, effectiveRunContexts);
2674
2634
  }
@@ -2679,20 +2639,22 @@ class EdgePropagator {
2679
2639
  if (!edge.convertAsync)
2680
2640
  return;
2681
2641
  // Track edge run-context IDs for pendingEdges tracking
2682
- const edgeRunContextIds = effectiveRunContexts
2683
- ? Array.from(effectiveRunContexts)
2684
- : undefined;
2642
+ const edgeRunContextIds = effectiveRunContexts ? Array.from(effectiveRunContexts) : undefined;
2685
2643
  if (edgeRunContextIds) {
2686
2644
  for (const id of edgeRunContextIds) {
2687
2645
  this.runContextManager.startEdgeConversion(id, edge.id);
2688
2646
  }
2689
2647
  }
2648
+ const sourceTypeId = this.graph.getNode(edge.source.nodeId)?.typeId;
2649
+ const targetTypeId = this.graph.getNode(edge.target.nodeId)?.typeId;
2690
2650
  this.eventEmitter.emit("stats", {
2691
2651
  kind: "edge-start",
2692
2652
  edgeId: edge.id,
2693
2653
  typeId: edge.typeId,
2694
2654
  source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
2695
2655
  target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
2656
+ sourceTypeId,
2657
+ targetTypeId,
2696
2658
  });
2697
2659
  const controller = new AbortController();
2698
2660
  const startAt = Date.now();
@@ -2770,7 +2732,7 @@ class EdgePropagator {
2770
2732
  if (!dstIsArray) {
2771
2733
  return value;
2772
2734
  }
2773
- const toArray = (x) => Array.isArray(x) ? x : x === undefined ? [] : [x];
2735
+ const toArray = (x) => (Array.isArray(x) ? x : x === undefined ? [] : [x]);
2774
2736
  let forNode = this.arrayInputBuckets.get(edge.target.nodeId);
2775
2737
  if (!forNode) {
2776
2738
  forNode = new Map();
@@ -2861,6 +2823,8 @@ class EdgePropagator {
2861
2823
  typeId: edge.typeId,
2862
2824
  source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
2863
2825
  target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
2826
+ sourceTypeId: this.graph.getNode(edge.source.nodeId)?.typeId,
2827
+ targetTypeId: this.graph.getNode(edge.target.nodeId)?.typeId,
2864
2828
  durationMs: duration,
2865
2829
  });
2866
2830
  }
@@ -2877,6 +2841,8 @@ class EdgePropagator {
2877
2841
  edgeId: edge.id,
2878
2842
  source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
2879
2843
  target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
2844
+ sourceTypeId: this.graph.getNode(edge.source.nodeId)?.typeId,
2845
+ targetTypeId: this.graph.getNode(edge.target.nodeId)?.typeId,
2880
2846
  err,
2881
2847
  });
2882
2848
  }
@@ -2921,9 +2887,7 @@ class EdgePropagator {
2921
2887
  return;
2922
2888
  // Get resolved handles to filter out invalid outputs
2923
2889
  const resolved = this.graph.getResolvedHandles(nodeId);
2924
- const validOutputHandles = resolved?.outputs
2925
- ? new Set(Object.keys(resolved.outputs))
2926
- : new Set();
2890
+ const validOutputHandles = resolved?.outputs ? new Set(Object.keys(resolved.outputs)) : new Set();
2927
2891
  // Use node's activeRunContexts to propagate to new nodes that were added
2928
2892
  const activeRunContextIds = this.graph.getNodeRunContextIds(nodeId);
2929
2893
  for (const [handle, value] of Object.entries(node.outputs)) {
@@ -2994,7 +2958,7 @@ class NodeExecutor {
2994
2958
  // Create log function that respects node's logLevel using LevelLogger
2995
2959
  const node = this.graph.getNode(nodeId);
2996
2960
  const nodeLogLevel = node?.logLevel ?? "info";
2997
- const logger = new LevelLogger(nodeLogLevel, `[node:${runId || nodeId}:${node?.typeId ?? ""}]`);
2961
+ const logger = new LevelLogger(nodeLogLevel, `[node:${formatNodeRef(this.graph, nodeId)}:${runId}]`);
2998
2962
  const log = (level, message, context) => {
2999
2963
  switch (level) {
3000
2964
  case "debug":
@@ -3022,11 +2986,8 @@ class NodeExecutor {
3022
2986
  execute: (opts) => {
3023
2987
  if (this.graph.allInboundHaveValue(nodeId)) {
3024
2988
  let runContextIdsToUse = this.runtime.getRunMode() === "auto" ? undefined : runContextIds;
3025
- if (this.runtime.getRunMode() === "manual" &&
3026
- (!runContextIds || runContextIds.size === 0)) {
3027
- runContextIdsToUse = new Set([
3028
- this.runContextManager.createRunContext(nodeId, opts),
3029
- ]);
2989
+ if (this.runtime.getRunMode() === "manual" && (!runContextIds || runContextIds.size === 0)) {
2990
+ runContextIdsToUse = new Set([this.runContextManager.createRunContext(nodeId, opts)]);
3030
2991
  }
3031
2992
  this.execute(nodeId, {
3032
2993
  runContextIds: runContextIdsToUse,
@@ -3062,24 +3023,22 @@ class NodeExecutor {
3062
3023
  return;
3063
3024
  const runMode = this.runtime.getRunMode();
3064
3025
  if (!runMode) {
3065
- console.trace(`NodeExecutor.execute[${nodeId}:${reason}]: no runMode, skipping execution`);
3026
+ console.trace(`NodeExecutor.execute[${formatNodeRef(this.graph, nodeId)}:${reason}]: no runMode, skipping execution`);
3066
3027
  return;
3067
3028
  }
3068
3029
  // In manual mode, require runContextIds unless autoRun policy is set
3069
3030
  if (runMode === "manual" && (!runContextIds || runContextIds.size === 0)) {
3070
3031
  // If autoRun is true, auto-generate a run context (similar to createExecutionContext pattern)
3071
3032
  if (node.policy?.autoRun === true) {
3072
- runContextIds = new Set([
3073
- this.runContextManager.createRunContext(nodeId, { propagate: false }),
3074
- ]);
3033
+ runContextIds = new Set([this.runContextManager.createRunContext(nodeId, { propagate: false })]);
3075
3034
  }
3076
3035
  else {
3077
- console.trace(`NodeExecutor.execute[${nodeId}:${reason}]: no runContextIds provided in manual mode, skipping execution`);
3036
+ console.trace(`NodeExecutor.execute[${formatNodeRef(this.graph, nodeId)}:${reason}]: no runContextIds provided in manual mode, skipping execution`);
3078
3037
  return;
3079
3038
  }
3080
3039
  }
3081
3040
  if (runMode === "auto" && runContextIds && runContextIds.size > 0) {
3082
- console.trace(`NodeExecutor.execute[${nodeId}:${reason}]: runContextIds provided in auto mode, ignoring`);
3041
+ console.trace(`NodeExecutor.execute[${formatNodeRef(this.graph, nodeId)}:${reason}]: runContextIds provided in auto mode, ignoring`);
3083
3042
  runContextIds = undefined;
3084
3043
  }
3085
3044
  // Early validation for auto-mode paused state
@@ -3094,6 +3053,7 @@ class NodeExecutor {
3094
3053
  code: runtimeValidationError.code || "RUNTIME_VALIDATION_BLOCKED",
3095
3054
  details: {
3096
3055
  nodeId,
3056
+ nodeTypeId: node?.typeId,
3097
3057
  ...runtimeValidationError.details,
3098
3058
  },
3099
3059
  });
@@ -3104,8 +3064,7 @@ class NodeExecutor {
3104
3064
  if (runContextIds) {
3105
3065
  this.graph.addNodeRunContextIds(nodeId, runContextIds);
3106
3066
  }
3107
- if (!canSkipHandleResolution &&
3108
- !this.handleResolver.getPendingResolution(nodeId)) {
3067
+ if (!canSkipHandleResolution && !this.handleResolver.getPendingResolution(nodeId)) {
3109
3068
  this.handleResolver.scheduleRecomputeHandles(nodeId);
3110
3069
  }
3111
3070
  // Check if handles are being resolved - wait for resolution before executing
@@ -3156,9 +3115,7 @@ class NodeExecutor {
3156
3115
  return false;
3157
3116
  const policy = node.policy ?? {};
3158
3117
  const lastScheduledAt = node.lastScheduledAt;
3159
- return !!(policy.debounceMs &&
3160
- lastScheduledAt &&
3161
- now - lastScheduledAt < policy.debounceMs);
3118
+ return !!(policy.debounceMs && lastScheduledAt && now - lastScheduledAt < policy.debounceMs);
3162
3119
  }
3163
3120
  /**
3164
3121
  * Handle debounced scheduling by replacing the latest queued item
@@ -3441,6 +3398,7 @@ class NodeExecutor {
3441
3398
  this.eventEmitter.emit("error", {
3442
3399
  kind: "node-run",
3443
3400
  nodeId,
3401
+ nodeTypeId: node.typeId,
3444
3402
  runId: plan.runId,
3445
3403
  err,
3446
3404
  });
@@ -3473,9 +3431,7 @@ class NodeExecutor {
3473
3431
  return;
3474
3432
  const controllers = this.graph.getNodeControllers(nodeId);
3475
3433
  const lastEndAt = Date.now();
3476
- const lastDurationMs = node.stats.lastStartAt && lastEndAt
3477
- ? lastEndAt - node.stats.lastStartAt
3478
- : undefined;
3434
+ const lastDurationMs = node.stats.lastStartAt && lastEndAt ? lastEndAt - node.stats.lastStartAt : undefined;
3479
3435
  this.graph.updateNodeStats(nodeId, {
3480
3436
  active: Math.max(0, controllers.size),
3481
3437
  lastEndAt,
@@ -3643,7 +3599,7 @@ class RuntimeValidatorManager {
3643
3599
  }
3644
3600
  catch (err) {
3645
3601
  // Don't let validator errors break execution - log and continue
3646
- console.error(`Runtime validator error for node ${nodeId}:`, err);
3602
+ console.error(`Runtime validator error for node ${formatNodeRef(this.graph, nodeId)}:`, err);
3647
3603
  }
3648
3604
  }
3649
3605
  return null;
@@ -3656,7 +3612,7 @@ class GraphRuntime {
3656
3612
  // State
3657
3613
  this.environment = {};
3658
3614
  this.customNodeData = {};
3659
- this.runMode = null;
3615
+ this.runMode = "manual";
3660
3616
  this.pauseRefCount = 0;
3661
3617
  this.persistentPauseToken = null;
3662
3618
  // Initialize components
@@ -3778,11 +3734,7 @@ class GraphRuntime {
3778
3734
  : desc
3779
3735
  ? getInputDeclaredTypes(desc.inputs, handle)
3780
3736
  : undefined;
3781
- const typeIds = Array.isArray(declaredTypes)
3782
- ? declaredTypes
3783
- : declaredTypes
3784
- ? [declaredTypes]
3785
- : [];
3737
+ const typeIds = Array.isArray(declaredTypes) ? declaredTypes : declaredTypes ? [declaredTypes] : [];
3786
3738
  if (typeIds.length > 0) {
3787
3739
  const isValidForAny = typeIds.some((tId) => {
3788
3740
  const typeDesc = registry.types.get(tId);
@@ -3793,10 +3745,11 @@ class GraphRuntime {
3793
3745
  });
3794
3746
  if (value !== undefined && !isValidForAny) {
3795
3747
  const typeLabel = typeIds.join("|");
3796
- const errorMessage = `Invalid value for input ${nodeId}.${handle} (type ${typeLabel}): ${JSON.stringify(value)}`;
3748
+ const errorMessage = `Invalid value for input ${formatNodeRef(this.graph, nodeId)}.${handle} (type ${typeLabel}): ${JSON.stringify(value)}`;
3797
3749
  this.eventEmitter.emit("error", {
3798
3750
  kind: "input-validation",
3799
3751
  nodeId,
3752
+ nodeTypeId: node.typeId,
3800
3753
  handle,
3801
3754
  typeId: typeLabel,
3802
3755
  value,
@@ -4053,9 +4006,7 @@ class GraphRuntime {
4053
4006
  const shouldAutoRun = this.runMode === "auto" || node?.policy?.autoRun === true;
4054
4007
  let runContextIdsToUse = undefined;
4055
4008
  if (this.runMode === "manual") {
4056
- runContextIdsToUse = new Set([
4057
- this.runContextManager.createRunContext(nodeId, { propagate: false }),
4058
- ]);
4009
+ runContextIdsToUse = new Set([this.runContextManager.createRunContext(nodeId, { propagate: false })]);
4059
4010
  }
4060
4011
  if (shouldAutoRun && this.graph.allInboundHaveValue(nodeId)) {
4061
4012
  this.execute(nodeId, {
@@ -4228,8 +4179,7 @@ class GraphRuntime {
4228
4179
  set.add(e.target.handle);
4229
4180
  beforeInbound.set(e.target.nodeId, set);
4230
4181
  // Build beforeOutTargets map
4231
- const tmap = beforeOutTargets.get(e.source.nodeId) ??
4232
- new Map();
4182
+ const tmap = beforeOutTargets.get(e.source.nodeId) ?? new Map();
4233
4183
  const tset = tmap.get(e.source.handle) ?? new Set();
4234
4184
  tset.add(`${e.target.nodeId}.${e.target.handle}`);
4235
4185
  tmap.set(e.source.handle, tset);
@@ -4249,8 +4199,7 @@ class GraphRuntime {
4249
4199
  const changedHandles = {};
4250
4200
  for (const [nodeId, newHandles] of result.resolved) {
4251
4201
  const oldHandles = this.graph.getResolvedHandles(nodeId);
4252
- if (!oldHandles ||
4253
- JSON.stringify(oldHandles) !== JSON.stringify(newHandles)) {
4202
+ if (!oldHandles || JSON.stringify(oldHandles) !== JSON.stringify(newHandles)) {
4254
4203
  changedHandles[nodeId] = newHandles;
4255
4204
  }
4256
4205
  }
@@ -4302,8 +4251,7 @@ class GraphRuntime {
4302
4251
  // Propagate changes on edges added
4303
4252
  const afterOutTargets = new Map();
4304
4253
  this.graph.forEachEdge((e) => {
4305
- const targetMap = afterOutTargets.get(e.source.nodeId) ??
4306
- new Map();
4254
+ const targetMap = afterOutTargets.get(e.source.nodeId) ?? new Map();
4307
4255
  const targetSet = targetMap.get(e.source.handle) ?? new Set();
4308
4256
  targetSet.add(`${e.target.nodeId}.${e.target.handle}`);
4309
4257
  targetMap.set(e.source.handle, targetSet);
@@ -4328,10 +4276,7 @@ class GraphRuntime {
4328
4276
  for (const nodeId of nodesToCheck) {
4329
4277
  const beforeMap = beforeOutTargets.get(nodeId) ?? new Map();
4330
4278
  const afterMap = afterOutTargets.get(nodeId) ?? new Map();
4331
- const handles = new Set([
4332
- ...Array.from(beforeMap.keys()),
4333
- ...Array.from(afterMap.keys()),
4334
- ]);
4279
+ const handles = new Set([...Array.from(beforeMap.keys()), ...Array.from(afterMap.keys())]);
4335
4280
  for (const handle of handles) {
4336
4281
  const beforeTargetSet = beforeMap.get(handle) ?? new Set();
4337
4282
  const afterTargetSet = afterMap.get(handle) ?? new Set();
@@ -4452,7 +4397,10 @@ class GraphBuilder {
4452
4397
  effByNodeId.set(n.nodeId, getEffectiveHandles(n));
4453
4398
  const nodeType = this.registry.nodes.get(n.typeId);
4454
4399
  if (!nodeType) {
4455
- pushIssue("error", "NODE_TYPE_MISSING", `Unknown node type ${n.typeId}`, { typeId: n.typeId, nodeId: n.nodeId });
4400
+ pushIssue("error", "NODE_TYPE_MISSING", `Unknown node type ${n.typeId}`, {
4401
+ typeId: n.typeId,
4402
+ nodeId: n.nodeId,
4403
+ });
4456
4404
  continue;
4457
4405
  }
4458
4406
  if (!this.registry.categories.has(nodeType.categoryId)) {
@@ -4472,9 +4420,7 @@ class GraphBuilder {
4472
4420
  typeof paramValue === "number" &&
4473
4421
  !enumTypes.some((et) => validateEnumValue(et, paramValue, n.nodeId))) {
4474
4422
  const enumDef = this.registry.enums.get(enumTypes[0]);
4475
- const validValues = enumDef
4476
- ? Array.from(enumDef.valueToLabel.keys()).join(", ")
4477
- : "unknown";
4423
+ const validValues = enumDef ? Array.from(enumDef.valueToLabel.keys()).join(", ") : "unknown";
4478
4424
  pushIssue("error", "ENUM_VALUE_INVALID", `Node ${n.nodeId} param ${paramKey} has invalid enum value ${paramValue}. Valid values: ${validValues}`, {
4479
4425
  nodeId: n.nodeId,
4480
4426
  input: paramKey,
@@ -4494,9 +4440,7 @@ class GraphBuilder {
4494
4440
  typeof defaultValue === "number" &&
4495
4441
  !enumTypes.some((et) => validateEnumValue(et, defaultValue, n.nodeId))) {
4496
4442
  const enumDef = this.registry.enums.get(enumTypes[0]);
4497
- const validValues = enumDef
4498
- ? Array.from(enumDef.valueToLabel.keys()).join(", ")
4499
- : "unknown";
4443
+ const validValues = enumDef ? Array.from(enumDef.valueToLabel.keys()).join(", ") : "unknown";
4500
4444
  pushIssue("warning", "ENUM_DEFAULT_INVALID", `Node ${n.nodeId} input default ${handle} has invalid enum value ${defaultValue}. Valid values: ${validValues}`, {
4501
4445
  nodeId: n.nodeId,
4502
4446
  input: handle,
@@ -4539,7 +4483,9 @@ class GraphBuilder {
4539
4483
  if (e.typeId) {
4540
4484
  const type = this.registry.types.get(e.typeId);
4541
4485
  if (!type) {
4542
- pushIssue("error", "TYPE_MISSING", `Edge ${e.id} explicit type ${e.typeId} is missing or unknown`, { edgeId: e.id });
4486
+ pushIssue("error", "TYPE_MISSING", `Edge ${e.id} explicit type ${e.typeId} is missing or unknown`, {
4487
+ edgeId: e.id,
4488
+ });
4543
4489
  }
4544
4490
  }
4545
4491
  if (srcNode) {
@@ -4628,19 +4574,13 @@ class GraphBuilder {
4628
4574
  const outputTypes = {};
4629
4575
  for (const [outerIn, map] of Object.entries(exposure.inputs)) {
4630
4576
  const innerNode = def.nodes.find((n) => n.nodeId === map.nodeId);
4631
- const innerDesc = innerNode
4632
- ? this.registry.nodes.get(innerNode.typeId)
4633
- : undefined;
4634
- const typeIds = innerDesc
4635
- ? getInputDeclaredTypes(innerDesc.inputs, map.handle)
4636
- : undefined;
4577
+ const innerDesc = innerNode ? this.registry.nodes.get(innerNode.typeId) : undefined;
4578
+ const typeIds = innerDesc ? getInputDeclaredTypes(innerDesc.inputs, map.handle) : undefined;
4637
4579
  inputTypes[outerIn] = typeIds ?? "unknown";
4638
4580
  }
4639
4581
  for (const [outerOut, map] of Object.entries(exposure.outputs)) {
4640
4582
  const innerNode = def.nodes.find((n) => n.nodeId === map.nodeId);
4641
- const innerDesc = innerNode
4642
- ? this.registry.nodes.get(innerNode.typeId)
4643
- : undefined;
4583
+ const innerDesc = innerNode ? this.registry.nodes.get(innerNode.typeId) : undefined;
4644
4584
  const typeId = innerDesc ? innerDesc.outputs[map.handle] : undefined;
4645
4585
  const single = Array.isArray(typeId) ? typeId[0] : typeId;
4646
4586
  outputTypes[outerOut] = single ?? "unknown";
@@ -4843,7 +4783,7 @@ const CompositeCategory = (registry) => ({
4843
4783
  });
4844
4784
 
4845
4785
  // Helpers
4846
- const asArray = (v) => Array.isArray(v) ? v : [Number(v)];
4786
+ const asArray = (v) => (Array.isArray(v) ? v : [Number(v)]);
4847
4787
  const broadcast = (a, b) => {
4848
4788
  const aa = asArray(a);
4849
4789
  const bb = asArray(b);
@@ -4856,7 +4796,7 @@ const broadcast = (a, b) => {
4856
4796
  const len = Math.max(aa.length, bb.length);
4857
4797
  return [new Array(len).fill(aa[0] ?? 0), new Array(len).fill(bb[0] ?? 0)];
4858
4798
  };
4859
- const asBoolArray = (v) => Array.isArray(v) ? v.map((x) => Boolean(x)) : [Boolean(v)];
4799
+ const asBoolArray = (v) => (Array.isArray(v) ? v.map((x) => Boolean(x)) : [Boolean(v)]);
4860
4800
  const broadcastBool = (a, b) => {
4861
4801
  const aa = asBoolArray(a);
4862
4802
  const bb = asBoolArray(b);
@@ -4867,10 +4807,7 @@ const broadcastBool = (a, b) => {
4867
4807
  if (bb.length === 1)
4868
4808
  return [aa, new Array(aa.length).fill(bb[0])];
4869
4809
  const len = Math.max(aa.length, bb.length);
4870
- return [
4871
- new Array(len).fill(aa[0] ?? false),
4872
- new Array(len).fill(bb[0] ?? false),
4873
- ];
4810
+ return [new Array(len).fill(aa[0] ?? false), new Array(len).fill(bb[0] ?? false)];
4874
4811
  };
4875
4812
  const clamp = (x, min, max) => Math.min(max, Math.max(min, x));
4876
4813
  const lerp = (a, b, t) => a + (b - a) * t;
@@ -4920,8 +4857,7 @@ function jsonPointerSet(obj, pointer, value) {
4920
4857
  if (next === undefined || next === null) {
4921
4858
  // create container heuristically
4922
4859
  const nextKey = parts[i + 1];
4923
- cur[key] =
4924
- typeof nextKey === "string" && /^[0-9]+$/.test(nextKey) ? [] : {};
4860
+ cur[key] = typeof nextKey === "string" && /^[0-9]+$/.test(nextKey) ? [] : {};
4925
4861
  }
4926
4862
  cur = cur[key];
4927
4863
  }
@@ -5055,9 +4991,7 @@ function setupBasicGraphRegistry(id) {
5055
4991
  }, { withArray: false });
5056
4992
  registry.registerType({
5057
4993
  id: "base.vec3",
5058
- validate: (v) => Array.isArray(v) &&
5059
- v.length === 3 &&
5060
- v.every((x) => typeof x === "number"),
4994
+ validate: (v) => Array.isArray(v) && v.length === 3 && v.every((x) => typeof x === "number"),
5061
4995
  bakeTarget: { nodeTypeId: "base.input.vec3", inputHandle: "Value" },
5062
4996
  }, { withArray: true, arrayPickFirstDefined: true });
5063
4997
  // float -> vec3 : map x to [x,0,0]
@@ -5102,9 +5036,7 @@ function setupBasicGraphRegistry(id) {
5102
5036
  });
5103
5037
  registry.registerCoercion("base.object", "base.vec3", (v) => {
5104
5038
  try {
5105
- if (Array.isArray(v) &&
5106
- v.length === 3 &&
5107
- v.every((x) => typeof x === "number")) {
5039
+ if (Array.isArray(v) && v.length === 3 && v.every((x) => typeof x === "number")) {
5108
5040
  return v;
5109
5041
  }
5110
5042
  return undefined;
@@ -5234,9 +5166,7 @@ function setupBasicGraphRegistry(id) {
5234
5166
  const [a, b] = broadcast(ins.ValueA, ins.ValueB);
5235
5167
  const t = Number(ins.Factor ?? 0);
5236
5168
  const len = Math.max(a.length, b.length);
5237
- const out = new Array(len)
5238
- .fill(0)
5239
- .map((_, i) => lerp(Number(a[i] ?? 0), Number(b[i] ?? 0), t));
5169
+ const out = new Array(len).fill(0).map((_, i) => lerp(Number(a[i] ?? 0), Number(b[i] ?? 0), t));
5240
5170
  return { Value: out };
5241
5171
  },
5242
5172
  });
@@ -5264,9 +5194,7 @@ function setupBasicGraphRegistry(id) {
5264
5194
  const out = vals.map((v) => {
5265
5195
  const t = (Number(v) - fromMin) / (fromMax - fromMin || 1);
5266
5196
  const r = toMin + t * (toMax - toMin);
5267
- return doClamp
5268
- ? clamp(r, Math.min(toMin, toMax), Math.max(toMin, toMax))
5269
- : r;
5197
+ return doClamp ? clamp(r, Math.min(toMin, toMax), Math.max(toMin, toMax)) : r;
5270
5198
  });
5271
5199
  return { Value: out };
5272
5200
  },
@@ -5310,8 +5238,8 @@ function setupBasicGraphRegistry(id) {
5310
5238
  const sum = arr.reduce((s, x) => s + Number(x || 0), 0);
5311
5239
  return arr.length ? sum / arr.length : 0;
5312
5240
  },
5313
- [BaseMathOperation.MinAll]: (arr) => arr.length ? Math.min(...arr.map((x) => Number(x))) : 0,
5314
- [BaseMathOperation.MaxAll]: (arr) => arr.length ? Math.max(...arr.map((x) => Number(x))) : 0,
5241
+ [BaseMathOperation.MinAll]: (arr) => (arr.length ? Math.min(...arr.map((x) => Number(x))) : 0),
5242
+ [BaseMathOperation.MaxAll]: (arr) => (arr.length ? Math.max(...arr.map((x) => Number(x))) : 0),
5315
5243
  };
5316
5244
  if (aggregateByOp[op] !== undefined)
5317
5245
  return { Result: [aggregateByOp[op](a)] };
@@ -5328,8 +5256,8 @@ function setupBasicGraphRegistry(id) {
5328
5256
  const fn = binaryByOp[op] || binaryByOp[BaseMathOperation.Add];
5329
5257
  const len = Math.max(a.length, b.length);
5330
5258
  const out = new Array(len).fill(0).map((_, i) => {
5331
- const ax = a.length === 1 && len > 1 ? a[0] : a[i] ?? 0;
5332
- const bx = b.length === 1 && len > 1 ? b[0] : b[i] ?? 0;
5259
+ const ax = a.length === 1 && len > 1 ? a[0] : (a[i] ?? 0);
5260
+ const bx = b.length === 1 && len > 1 ? b[0] : (b[i] ?? 0);
5333
5261
  return fn(Number(ax), Number(bx));
5334
5262
  });
5335
5263
  return { Result: out };
@@ -5470,9 +5398,7 @@ function setupBasicGraphRegistry(id) {
5470
5398
  impl: (ins) => {
5471
5399
  const arr = Array.isArray(ins.Items) ? ins.Items : [];
5472
5400
  const s = Math.trunc(Number(ins.Start ?? 0));
5473
- const e = Number.isFinite(Number(ins.End))
5474
- ? Math.trunc(Number(ins.End))
5475
- : undefined;
5401
+ const e = Number.isFinite(Number(ins.End)) ? Math.trunc(Number(ins.End)) : undefined;
5476
5402
  return { Result: arr.slice(s, e) };
5477
5403
  },
5478
5404
  });
@@ -5747,11 +5673,7 @@ function setupBasicGraphRegistry(id) {
5747
5673
  outputs: { Keys: "base.string[]" },
5748
5674
  impl: (ins) => {
5749
5675
  const obj = ins.Object;
5750
- const keys = isPlainObject(obj)
5751
- ? Object.keys(obj)
5752
- : Array.isArray(obj)
5753
- ? Object.keys(obj)
5754
- : [];
5676
+ const keys = isPlainObject(obj) ? Object.keys(obj) : Array.isArray(obj) ? Object.keys(obj) : [];
5755
5677
  return { Keys: keys };
5756
5678
  },
5757
5679
  });
@@ -5762,11 +5684,7 @@ function setupBasicGraphRegistry(id) {
5762
5684
  outputs: { Values: "base.object" },
5763
5685
  impl: (ins) => {
5764
5686
  const obj = ins.Object;
5765
- const vals = isPlainObject(obj)
5766
- ? Object.values(obj)
5767
- : Array.isArray(obj)
5768
- ? Object.values(obj)
5769
- : [];
5687
+ const vals = isPlainObject(obj) ? Object.values(obj) : Array.isArray(obj) ? Object.values(obj) : [];
5770
5688
  return { Values: vals };
5771
5689
  },
5772
5690
  });
@@ -5778,11 +5696,7 @@ function setupBasicGraphRegistry(id) {
5778
5696
  impl: (ins) => {
5779
5697
  const root = structuredClone(ins.Object);
5780
5698
  const opsRaw = ins.Ops;
5781
- const ops = Array.isArray(opsRaw)
5782
- ? opsRaw
5783
- : opsRaw
5784
- ? [opsRaw]
5785
- : [];
5699
+ const ops = Array.isArray(opsRaw) ? opsRaw : opsRaw ? [opsRaw] : [];
5786
5700
  let cur = root;
5787
5701
  for (const op of ops) {
5788
5702
  if (!op || typeof op !== "object")
@@ -5873,9 +5787,7 @@ function registerDelayNode(registry) {
5873
5787
  impl: async (ins, ctx) => {
5874
5788
  const ms = Number(ins.DelayMs ?? 200);
5875
5789
  const valueRaw = ins.Value;
5876
- if (valueRaw === undefined ||
5877
- valueRaw === null ||
5878
- Number.isNaN(Number(valueRaw))) {
5790
+ if (valueRaw === undefined || valueRaw === null || Number.isNaN(Number(valueRaw))) {
5879
5791
  return; // wait until x is present to avoid NaN emissions
5880
5792
  }
5881
5793
  await new Promise((resolve, reject) => {
@@ -5945,9 +5857,7 @@ function generateId(prefix, used = new Set()) {
5945
5857
  id = `${prefix}${Math.random().toString(36).slice(2, 8)}`;
5946
5858
  attempts++;
5947
5859
  if (attempts > 1000) {
5948
- id = `${prefix}${Date.now().toString(36)}${Math.random()
5949
- .toString(36)
5950
- .slice(2, 4)}`;
5860
+ id = `${prefix}${Date.now().toString(36)}${Math.random().toString(36).slice(2, 4)}`;
5951
5861
  }
5952
5862
  } while (used.has(id));
5953
5863
  return id;
@@ -5988,12 +5898,10 @@ function installLogging(engine) {
5988
5898
  console.warn(`[error] input-validation: ${e.nodeId}.${e.handle} (type ${e.typeId})`, e.message);
5989
5899
  }
5990
5900
  else if (e.kind === "registry") {
5991
- console.warn(`[error] registry:`, e.err?.message ?? e.err, e.attempt !== undefined
5992
- ? `(attempt ${e.attempt}/${e.maxAttempts ?? "?"})`
5993
- : "");
5901
+ console.warn(`[error] registry:`, e.err?.message ?? e.err, e.attempt !== undefined ? `(attempt ${e.attempt}/${e.maxAttempts ?? "?"})` : "");
5994
5902
  }
5995
5903
  else if (e.kind === "system") {
5996
- console.warn(`[error] system: ${e.message}`, e.code ? `(code: ${e.code})` : "", e.err ? e.err?.message ?? e.err : "", e.details ? JSON.stringify(e.details) : "");
5904
+ console.warn(`[error] system: ${e.message}`, e.code ? `(code: ${e.code})` : "", e.err ? (e.err?.message ?? e.err) : "", e.details ? JSON.stringify(e.details) : "");
5997
5905
  }
5998
5906
  else {
5999
5907
  // Log any other error kinds (shouldn't happen, but handle gracefully)
@@ -6318,11 +6226,7 @@ function buildTypeMaps(def) {
6318
6226
  }
6319
6227
  if (node.resolvedHandles?.outputs) {
6320
6228
  for (const [handleId, handleDesc] of Object.entries(node.resolvedHandles.outputs)) {
6321
- const typeId = typeof handleDesc === "string"
6322
- ? handleDesc
6323
- : Array.isArray(handleDesc)
6324
- ? handleDesc[0]
6325
- : undefined;
6229
+ const typeId = typeof handleDesc === "string" ? handleDesc : Array.isArray(handleDesc) ? handleDesc[0] : undefined;
6326
6230
  if (typeId)
6327
6231
  nodeOutputTypes.set(handleId, typeId);
6328
6232
  }
@@ -6373,8 +6277,7 @@ function applyConversion(items, values, converter, type) {
6373
6277
  });
6374
6278
  if (convertedValue === null) {
6375
6279
  delete values[item.nodeId]?.[item.handleId];
6376
- if (values[item.nodeId] &&
6377
- Object.keys(values[item.nodeId]).length === 0) {
6280
+ if (values[item.nodeId] && Object.keys(values[item.nodeId]).length === 0) {
6378
6281
  delete values[item.nodeId];
6379
6282
  }
6380
6283
  }
@@ -6420,7 +6323,7 @@ function convertSnapshot(snapshot, converter) {
6420
6323
  }
6421
6324
  const { converted: convertedInputs, toConvert: inputsToConvert } = collectValuesToConvert(snapshot.inputs ?? {}, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "input");
6422
6325
  const { converted: convertedOutputs, toConvert: outputsToConvert } = collectValuesToConvert(snapshot.outputs ?? {}, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "output");
6423
- const { converted: convertedInputDefaults, toConvert: inputDefaultsToConvert, } = collectValuesToConvert(inputDefaults, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "inputDefault");
6326
+ const { converted: convertedInputDefaults, toConvert: inputDefaultsToConvert } = collectValuesToConvert(inputDefaults, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "inputDefault");
6424
6327
  applyConversion(inputsToConvert, convertedInputs, converter, "input");
6425
6328
  applyConversion(outputsToConvert, convertedOutputs, converter, "output");
6426
6329
  applyConversion(inputDefaultsToConvert, convertedInputDefaults, converter, "inputDefault");
@@ -6610,7 +6513,7 @@ function matchesPattern(value, pattern) {
6610
6513
  */
6611
6514
  function buildValueConverter(config) {
6612
6515
  return (converterConfig) => {
6613
- const { nodeId, handleId, value, type, nodeTypeId, handleDataType, runtimeTypeId, } = converterConfig;
6516
+ const { nodeId, handleId, value, type, nodeTypeId, handleDataType, runtimeTypeId } = converterConfig;
6614
6517
  const isValueTyped = isTyped(value);
6615
6518
  for (const mapping of config.mappings) {
6616
6519
  if (mapping.type && mapping.type !== type)
@@ -6653,8 +6556,7 @@ function buildValueConverter(config) {
6653
6556
  }
6654
6557
  }
6655
6558
  else {
6656
- if (typeof matchValue === "string" ||
6657
- typeof matchValue === "number") {
6559
+ if (typeof matchValue === "string" || typeof matchValue === "number") {
6658
6560
  const key = String(matchValue);
6659
6561
  if (key in mapping.valueMap) {
6660
6562
  newValue = mapping.valueMap[key];
@@ -6688,8 +6590,7 @@ function buildValueConverter(config) {
6688
6590
  }
6689
6591
  }
6690
6592
  else {
6691
- if (typeof innerValue === "string" ||
6692
- typeof innerValue === "number") {
6593
+ if (typeof innerValue === "string" || typeof innerValue === "number") {
6693
6594
  const key = String(innerValue);
6694
6595
  if (key in mapping.valueMap) {
6695
6596
  newValue = mapping.valueMap[key];
@@ -6716,8 +6617,7 @@ function buildValueConverter(config) {
6716
6617
  : firstSegment instanceof RegExp
6717
6618
  ? null
6718
6619
  : String(firstSegment);
6719
- if (firstSegmentStr !== "__spark_value" &&
6720
- firstSegmentStr !== "__spark_type") {
6620
+ if (firstSegmentStr !== "__spark_value" && firstSegmentStr !== "__spark_type") {
6721
6621
  pathSegments = ["__spark_value", ...pathSegments];
6722
6622
  }
6723
6623
  }
@@ -6737,8 +6637,7 @@ function buildValueConverter(config) {
6737
6637
  }
6738
6638
  }
6739
6639
  else {
6740
- if (typeof matchValue === "string" ||
6741
- typeof matchValue === "number") {
6640
+ if (typeof matchValue === "string" || typeof matchValue === "number") {
6742
6641
  const key = String(matchValue);
6743
6642
  if (key in mapping.valueMap) {
6744
6643
  newValue = mapping.valueMap[key];