@bian-womp/spark-graph 0.3.71 → 0.3.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/index.cjs +163 -268
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/builder/GraphBuilder.d.ts.map +1 -1
- package/lib/cjs/src/builder/Registry.d.ts.map +1 -1
- package/lib/cjs/src/core/categories.d.ts.map +1 -1
- package/lib/cjs/src/core/order.d.ts.map +1 -1
- package/lib/cjs/src/core/type-utils.d.ts.map +1 -1
- package/lib/cjs/src/core/types.d.ts.map +1 -1
- package/lib/cjs/src/examples/arrays.d.ts.map +1 -1
- package/lib/cjs/src/examples/async.d.ts.map +1 -1
- package/lib/cjs/src/examples/progress.d.ts.map +1 -1
- package/lib/cjs/src/examples/runMode.d.ts.map +1 -1
- package/lib/cjs/src/examples/shared.d.ts.map +1 -1
- package/lib/cjs/src/examples/simple.d.ts.map +1 -1
- package/lib/cjs/src/examples/snapshot.d.ts.map +1 -1
- package/lib/cjs/src/index.d.ts +7 -7
- package/lib/cjs/src/index.d.ts.map +1 -1
- package/lib/cjs/src/misc/base.d.ts.map +1 -1
- package/lib/cjs/src/misc/utils/LevelLogger.d.ts.map +1 -1
- package/lib/cjs/src/misc/utils/json.d.ts.map +1 -1
- package/lib/cjs/src/misc/utils/merge.d.ts.map +1 -1
- package/lib/cjs/src/plugins/composite.d.ts.map +1 -1
- package/lib/cjs/src/runtime/Engine.d.ts.map +1 -1
- package/lib/cjs/src/runtime/GraphLifecycleApi.d.ts.map +1 -1
- package/lib/cjs/src/runtime/GraphRuntime.d.ts +7 -6
- package/lib/cjs/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/lib/cjs/src/runtime/LocalEngine.d.ts.map +1 -1
- package/lib/cjs/src/runtime/components/EdgePropagator.d.ts +2 -7
- package/lib/cjs/src/runtime/components/EdgePropagator.d.ts.map +1 -1
- package/lib/cjs/src/runtime/components/EventEmitter.d.ts.map +1 -1
- package/lib/cjs/src/runtime/components/Graph.d.ts.map +1 -1
- package/lib/cjs/src/runtime/components/HandleResolver.d.ts.map +1 -1
- package/lib/cjs/src/runtime/components/NodeExecutor.d.ts.map +1 -1
- package/lib/cjs/src/runtime/components/RunContextManager.d.ts.map +1 -1
- package/lib/cjs/src/runtime/components/RuntimeValidatorManager.d.ts.map +1 -1
- package/lib/cjs/src/runtime/components/graph-utils.d.ts.map +1 -1
- package/lib/cjs/src/runtime/components/interfaces.d.ts +2 -1
- package/lib/cjs/src/runtime/components/interfaces.d.ts.map +1 -1
- package/lib/cjs/src/runtime/components/types.d.ts.map +1 -1
- package/lib/cjs/src/runtime/utils.d.ts +9 -0
- package/lib/cjs/src/runtime/utils.d.ts.map +1 -1
- package/lib/esm/index.js +163 -268
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/builder/GraphBuilder.d.ts.map +1 -1
- package/lib/esm/src/builder/Registry.d.ts.map +1 -1
- package/lib/esm/src/core/categories.d.ts.map +1 -1
- package/lib/esm/src/core/order.d.ts.map +1 -1
- package/lib/esm/src/core/type-utils.d.ts.map +1 -1
- package/lib/esm/src/core/types.d.ts.map +1 -1
- package/lib/esm/src/examples/arrays.d.ts.map +1 -1
- package/lib/esm/src/examples/async.d.ts.map +1 -1
- package/lib/esm/src/examples/progress.d.ts.map +1 -1
- package/lib/esm/src/examples/runMode.d.ts.map +1 -1
- package/lib/esm/src/examples/shared.d.ts.map +1 -1
- package/lib/esm/src/examples/simple.d.ts.map +1 -1
- package/lib/esm/src/examples/snapshot.d.ts.map +1 -1
- package/lib/esm/src/index.d.ts +7 -7
- package/lib/esm/src/index.d.ts.map +1 -1
- package/lib/esm/src/misc/base.d.ts.map +1 -1
- package/lib/esm/src/misc/utils/LevelLogger.d.ts.map +1 -1
- package/lib/esm/src/misc/utils/json.d.ts.map +1 -1
- package/lib/esm/src/misc/utils/merge.d.ts.map +1 -1
- package/lib/esm/src/plugins/composite.d.ts.map +1 -1
- package/lib/esm/src/runtime/Engine.d.ts.map +1 -1
- package/lib/esm/src/runtime/GraphLifecycleApi.d.ts.map +1 -1
- package/lib/esm/src/runtime/GraphRuntime.d.ts +7 -6
- package/lib/esm/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/lib/esm/src/runtime/LocalEngine.d.ts.map +1 -1
- package/lib/esm/src/runtime/components/EdgePropagator.d.ts +2 -7
- package/lib/esm/src/runtime/components/EdgePropagator.d.ts.map +1 -1
- package/lib/esm/src/runtime/components/EventEmitter.d.ts.map +1 -1
- package/lib/esm/src/runtime/components/Graph.d.ts.map +1 -1
- package/lib/esm/src/runtime/components/HandleResolver.d.ts.map +1 -1
- package/lib/esm/src/runtime/components/NodeExecutor.d.ts.map +1 -1
- package/lib/esm/src/runtime/components/RunContextManager.d.ts.map +1 -1
- package/lib/esm/src/runtime/components/RuntimeValidatorManager.d.ts.map +1 -1
- package/lib/esm/src/runtime/components/graph-utils.d.ts.map +1 -1
- package/lib/esm/src/runtime/components/interfaces.d.ts +2 -1
- package/lib/esm/src/runtime/components/interfaces.d.ts.map +1 -1
- package/lib/esm/src/runtime/components/types.d.ts.map +1 -1
- package/lib/esm/src/runtime/utils.d.ts +9 -0
- package/lib/esm/src/runtime/utils.d.ts.map +1 -1
- 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
|
|
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
|
-
|
|
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
|
-
|
|
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}
|
|
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}
|
|
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}
|
|
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)
|
|
@@ -2572,11 +2523,10 @@ class HandleResolver {
|
|
|
2572
2523
|
* EdgePropagator component - handles value propagation through edges
|
|
2573
2524
|
*/
|
|
2574
2525
|
class EdgePropagator {
|
|
2575
|
-
constructor(graph, eventEmitter, runContextManager,
|
|
2526
|
+
constructor(graph, eventEmitter, runContextManager, nodeExecutor, runtime) {
|
|
2576
2527
|
this.graph = graph;
|
|
2577
2528
|
this.eventEmitter = eventEmitter;
|
|
2578
2529
|
this.runContextManager = runContextManager;
|
|
2579
|
-
this.handleResolver = handleResolver;
|
|
2580
2530
|
this.nodeExecutor = nodeExecutor;
|
|
2581
2531
|
this.runtime = runtime;
|
|
2582
2532
|
this.arrayInputBuckets = new Map();
|
|
@@ -2606,9 +2556,7 @@ class EdgePropagator {
|
|
|
2606
2556
|
const effectiveRunContexts = runContextIds && runContextIds.size > 0
|
|
2607
2557
|
? this.filterEffectiveRunContexts(edge, srcNodeId, runContextIds)
|
|
2608
2558
|
: undefined;
|
|
2609
|
-
if (runContextIds &&
|
|
2610
|
-
runContextIds.size > 0 &&
|
|
2611
|
-
!(effectiveRunContexts && effectiveRunContexts.size > 0)) {
|
|
2559
|
+
if (runContextIds && runContextIds.size > 0 && !(effectiveRunContexts && effectiveRunContexts.size > 0)) {
|
|
2612
2560
|
return; // No valid run-contexts for this edge
|
|
2613
2561
|
}
|
|
2614
2562
|
// Validate union types
|
|
@@ -2649,12 +2597,16 @@ class EdgePropagator {
|
|
|
2649
2597
|
const isUnion = Array.isArray(edge.srcUnionTypes);
|
|
2650
2598
|
const isTypedValue = isTyped(value);
|
|
2651
2599
|
if (isUnion && !isTypedValue) {
|
|
2600
|
+
const sourceTypeId = this.graph.getNode(edge.source.nodeId)?.typeId;
|
|
2601
|
+
const targetTypeId = this.graph.getNode(edge.target.nodeId)?.typeId;
|
|
2652
2602
|
const err = new Error(`Output ${srcNodeId}.${edge.source.handle} requires typed value for union output (allowed: ${edge.srcUnionTypes.join("|")})`);
|
|
2653
2603
|
this.eventEmitter.emit("error", {
|
|
2654
2604
|
kind: "edge-convert",
|
|
2655
2605
|
edgeId: edge.id,
|
|
2656
2606
|
source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
|
|
2657
2607
|
target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
|
|
2608
|
+
sourceTypeId,
|
|
2609
|
+
targetTypeId,
|
|
2658
2610
|
err,
|
|
2659
2611
|
});
|
|
2660
2612
|
return false;
|
|
@@ -2670,7 +2622,14 @@ class EdgePropagator {
|
|
|
2670
2622
|
convertedValue = edge.convert(value);
|
|
2671
2623
|
}
|
|
2672
2624
|
else {
|
|
2673
|
-
|
|
2625
|
+
const fromType = (Array.isArray(edge.srcUnionTypes) && edge.srcUnionTypes.length > 0
|
|
2626
|
+
? edge.srcUnionTypes.join("|")
|
|
2627
|
+
: undefined) ??
|
|
2628
|
+
unwrapTypeId(value) ??
|
|
2629
|
+
edge.typeId ??
|
|
2630
|
+
"unknown";
|
|
2631
|
+
const toType = Array.isArray(edge.dstDeclared) ? edge.dstDeclared.join("|") : (edge.dstDeclared ?? "unknown");
|
|
2632
|
+
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
2633
|
}
|
|
2675
2634
|
this.applyToTarget(edge, convertedValue, effectiveRunContexts);
|
|
2676
2635
|
}
|
|
@@ -2681,20 +2640,22 @@ class EdgePropagator {
|
|
|
2681
2640
|
if (!edge.convertAsync)
|
|
2682
2641
|
return;
|
|
2683
2642
|
// Track edge run-context IDs for pendingEdges tracking
|
|
2684
|
-
const edgeRunContextIds = effectiveRunContexts
|
|
2685
|
-
? Array.from(effectiveRunContexts)
|
|
2686
|
-
: undefined;
|
|
2643
|
+
const edgeRunContextIds = effectiveRunContexts ? Array.from(effectiveRunContexts) : undefined;
|
|
2687
2644
|
if (edgeRunContextIds) {
|
|
2688
2645
|
for (const id of edgeRunContextIds) {
|
|
2689
2646
|
this.runContextManager.startEdgeConversion(id, edge.id);
|
|
2690
2647
|
}
|
|
2691
2648
|
}
|
|
2649
|
+
const sourceTypeId = this.graph.getNode(edge.source.nodeId)?.typeId;
|
|
2650
|
+
const targetTypeId = this.graph.getNode(edge.target.nodeId)?.typeId;
|
|
2692
2651
|
this.eventEmitter.emit("stats", {
|
|
2693
2652
|
kind: "edge-start",
|
|
2694
2653
|
edgeId: edge.id,
|
|
2695
2654
|
typeId: edge.typeId,
|
|
2696
2655
|
source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
|
|
2697
2656
|
target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
|
|
2657
|
+
sourceTypeId,
|
|
2658
|
+
targetTypeId,
|
|
2698
2659
|
});
|
|
2699
2660
|
const controller = new AbortController();
|
|
2700
2661
|
const startAt = Date.now();
|
|
@@ -2754,7 +2715,7 @@ class EdgePropagator {
|
|
|
2754
2715
|
// Set input value (respecting skipPropagateValues)
|
|
2755
2716
|
const shouldSetValue = this.shouldSetInputValue(effectiveRunContexts);
|
|
2756
2717
|
if (shouldSetValue && valueChanged) {
|
|
2757
|
-
this.setTargetInput(edge, processedValue);
|
|
2718
|
+
this.runtime.setTargetInput(edge, processedValue, "applyToTarget");
|
|
2758
2719
|
}
|
|
2759
2720
|
else if (shouldSetValue && !valueChanged) {
|
|
2760
2721
|
// Even if value didn't change, update timestamp if we're forcing execution
|
|
@@ -2772,7 +2733,7 @@ class EdgePropagator {
|
|
|
2772
2733
|
if (!dstIsArray) {
|
|
2773
2734
|
return value;
|
|
2774
2735
|
}
|
|
2775
|
-
const toArray = (x) => Array.isArray(x) ? x : x === undefined ? [] : [x];
|
|
2736
|
+
const toArray = (x) => (Array.isArray(x) ? x : x === undefined ? [] : [x]);
|
|
2776
2737
|
let forNode = this.arrayInputBuckets.get(edge.target.nodeId);
|
|
2777
2738
|
if (!forNode) {
|
|
2778
2739
|
forNode = new Map();
|
|
@@ -2810,13 +2771,6 @@ class EdgePropagator {
|
|
|
2810
2771
|
}
|
|
2811
2772
|
return true;
|
|
2812
2773
|
}
|
|
2813
|
-
/**
|
|
2814
|
-
* Set target input value and emit event
|
|
2815
|
-
*/
|
|
2816
|
-
setTargetInput(edge, value) {
|
|
2817
|
-
this.graph.updateNodeInput(edge.target.nodeId, edge.target.handle, value);
|
|
2818
|
-
this.handleResolver.scheduleRecomputeHandles(edge.target.nodeId);
|
|
2819
|
-
}
|
|
2820
2774
|
/**
|
|
2821
2775
|
* Execute downstream if conditions are met
|
|
2822
2776
|
*/
|
|
@@ -2863,6 +2817,8 @@ class EdgePropagator {
|
|
|
2863
2817
|
typeId: edge.typeId,
|
|
2864
2818
|
source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
|
|
2865
2819
|
target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
|
|
2820
|
+
sourceTypeId: this.graph.getNode(edge.source.nodeId)?.typeId,
|
|
2821
|
+
targetTypeId: this.graph.getNode(edge.target.nodeId)?.typeId,
|
|
2866
2822
|
durationMs: duration,
|
|
2867
2823
|
});
|
|
2868
2824
|
}
|
|
@@ -2879,6 +2835,8 @@ class EdgePropagator {
|
|
|
2879
2835
|
edgeId: edge.id,
|
|
2880
2836
|
source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
|
|
2881
2837
|
target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
|
|
2838
|
+
sourceTypeId: this.graph.getNode(edge.source.nodeId)?.typeId,
|
|
2839
|
+
targetTypeId: this.graph.getNode(edge.target.nodeId)?.typeId,
|
|
2882
2840
|
err,
|
|
2883
2841
|
});
|
|
2884
2842
|
}
|
|
@@ -2923,9 +2881,7 @@ class EdgePropagator {
|
|
|
2923
2881
|
return;
|
|
2924
2882
|
// Get resolved handles to filter out invalid outputs
|
|
2925
2883
|
const resolved = this.graph.getResolvedHandles(nodeId);
|
|
2926
|
-
const validOutputHandles = resolved?.outputs
|
|
2927
|
-
? new Set(Object.keys(resolved.outputs))
|
|
2928
|
-
: new Set();
|
|
2884
|
+
const validOutputHandles = resolved?.outputs ? new Set(Object.keys(resolved.outputs)) : new Set();
|
|
2929
2885
|
// Use node's activeRunContexts to propagate to new nodes that were added
|
|
2930
2886
|
const activeRunContextIds = this.graph.getNodeRunContextIds(nodeId);
|
|
2931
2887
|
for (const [handle, value] of Object.entries(node.outputs)) {
|
|
@@ -2996,7 +2952,7 @@ class NodeExecutor {
|
|
|
2996
2952
|
// Create log function that respects node's logLevel using LevelLogger
|
|
2997
2953
|
const node = this.graph.getNode(nodeId);
|
|
2998
2954
|
const nodeLogLevel = node?.logLevel ?? "info";
|
|
2999
|
-
const logger = new LevelLogger(nodeLogLevel, `[node:${
|
|
2955
|
+
const logger = new LevelLogger(nodeLogLevel, `[node:${formatNodeRef(this.graph, nodeId)}:${runId}]`);
|
|
3000
2956
|
const log = (level, message, context) => {
|
|
3001
2957
|
switch (level) {
|
|
3002
2958
|
case "debug":
|
|
@@ -3024,11 +2980,8 @@ class NodeExecutor {
|
|
|
3024
2980
|
execute: (opts) => {
|
|
3025
2981
|
if (this.graph.allInboundHaveValue(nodeId)) {
|
|
3026
2982
|
let runContextIdsToUse = this.runtime.getRunMode() === "auto" ? undefined : runContextIds;
|
|
3027
|
-
if (this.runtime.getRunMode() === "manual" &&
|
|
3028
|
-
|
|
3029
|
-
runContextIdsToUse = new Set([
|
|
3030
|
-
this.runContextManager.createRunContext(nodeId, opts),
|
|
3031
|
-
]);
|
|
2983
|
+
if (this.runtime.getRunMode() === "manual" && (!runContextIds || runContextIds.size === 0)) {
|
|
2984
|
+
runContextIdsToUse = new Set([this.runContextManager.createRunContext(nodeId, opts)]);
|
|
3032
2985
|
}
|
|
3033
2986
|
this.execute(nodeId, {
|
|
3034
2987
|
runContextIds: runContextIdsToUse,
|
|
@@ -3064,24 +3017,22 @@ class NodeExecutor {
|
|
|
3064
3017
|
return;
|
|
3065
3018
|
const runMode = this.runtime.getRunMode();
|
|
3066
3019
|
if (!runMode) {
|
|
3067
|
-
console.trace(`NodeExecutor.execute[${nodeId}:${reason}]: no runMode, skipping execution`);
|
|
3020
|
+
console.trace(`NodeExecutor.execute[${formatNodeRef(this.graph, nodeId)}:${reason}]: no runMode, skipping execution`);
|
|
3068
3021
|
return;
|
|
3069
3022
|
}
|
|
3070
3023
|
// In manual mode, require runContextIds unless autoRun policy is set
|
|
3071
3024
|
if (runMode === "manual" && (!runContextIds || runContextIds.size === 0)) {
|
|
3072
3025
|
// If autoRun is true, auto-generate a run context (similar to createExecutionContext pattern)
|
|
3073
3026
|
if (node.policy?.autoRun === true) {
|
|
3074
|
-
runContextIds = new Set([
|
|
3075
|
-
this.runContextManager.createRunContext(nodeId, { propagate: false }),
|
|
3076
|
-
]);
|
|
3027
|
+
runContextIds = new Set([this.runContextManager.createRunContext(nodeId, { propagate: false })]);
|
|
3077
3028
|
}
|
|
3078
3029
|
else {
|
|
3079
|
-
console.trace(`NodeExecutor.execute[${nodeId}:${reason}]: no runContextIds provided in manual mode, skipping execution`);
|
|
3030
|
+
console.trace(`NodeExecutor.execute[${formatNodeRef(this.graph, nodeId)}:${reason}]: no runContextIds provided in manual mode, skipping execution`);
|
|
3080
3031
|
return;
|
|
3081
3032
|
}
|
|
3082
3033
|
}
|
|
3083
3034
|
if (runMode === "auto" && runContextIds && runContextIds.size > 0) {
|
|
3084
|
-
console.trace(`NodeExecutor.execute[${nodeId}:${reason}]: runContextIds provided in auto mode, ignoring`);
|
|
3035
|
+
console.trace(`NodeExecutor.execute[${formatNodeRef(this.graph, nodeId)}:${reason}]: runContextIds provided in auto mode, ignoring`);
|
|
3085
3036
|
runContextIds = undefined;
|
|
3086
3037
|
}
|
|
3087
3038
|
// Early validation for auto-mode paused state
|
|
@@ -3096,6 +3047,7 @@ class NodeExecutor {
|
|
|
3096
3047
|
code: runtimeValidationError.code || "RUNTIME_VALIDATION_BLOCKED",
|
|
3097
3048
|
details: {
|
|
3098
3049
|
nodeId,
|
|
3050
|
+
nodeTypeId: node?.typeId,
|
|
3099
3051
|
...runtimeValidationError.details,
|
|
3100
3052
|
},
|
|
3101
3053
|
});
|
|
@@ -3106,8 +3058,7 @@ class NodeExecutor {
|
|
|
3106
3058
|
if (runContextIds) {
|
|
3107
3059
|
this.graph.addNodeRunContextIds(nodeId, runContextIds);
|
|
3108
3060
|
}
|
|
3109
|
-
if (!canSkipHandleResolution &&
|
|
3110
|
-
!this.handleResolver.getPendingResolution(nodeId)) {
|
|
3061
|
+
if (!canSkipHandleResolution && !this.handleResolver.getPendingResolution(nodeId)) {
|
|
3111
3062
|
this.handleResolver.scheduleRecomputeHandles(nodeId);
|
|
3112
3063
|
}
|
|
3113
3064
|
// Check if handles are being resolved - wait for resolution before executing
|
|
@@ -3158,9 +3109,7 @@ class NodeExecutor {
|
|
|
3158
3109
|
return false;
|
|
3159
3110
|
const policy = node.policy ?? {};
|
|
3160
3111
|
const lastScheduledAt = node.lastScheduledAt;
|
|
3161
|
-
return !!(policy.debounceMs &&
|
|
3162
|
-
lastScheduledAt &&
|
|
3163
|
-
now - lastScheduledAt < policy.debounceMs);
|
|
3112
|
+
return !!(policy.debounceMs && lastScheduledAt && now - lastScheduledAt < policy.debounceMs);
|
|
3164
3113
|
}
|
|
3165
3114
|
/**
|
|
3166
3115
|
* Handle debounced scheduling by replacing the latest queued item
|
|
@@ -3443,6 +3392,7 @@ class NodeExecutor {
|
|
|
3443
3392
|
this.eventEmitter.emit("error", {
|
|
3444
3393
|
kind: "node-run",
|
|
3445
3394
|
nodeId,
|
|
3395
|
+
nodeTypeId: node.typeId,
|
|
3446
3396
|
runId: plan.runId,
|
|
3447
3397
|
err,
|
|
3448
3398
|
});
|
|
@@ -3475,9 +3425,7 @@ class NodeExecutor {
|
|
|
3475
3425
|
return;
|
|
3476
3426
|
const controllers = this.graph.getNodeControllers(nodeId);
|
|
3477
3427
|
const lastEndAt = Date.now();
|
|
3478
|
-
const lastDurationMs = node.stats.lastStartAt && lastEndAt
|
|
3479
|
-
? lastEndAt - node.stats.lastStartAt
|
|
3480
|
-
: undefined;
|
|
3428
|
+
const lastDurationMs = node.stats.lastStartAt && lastEndAt ? lastEndAt - node.stats.lastStartAt : undefined;
|
|
3481
3429
|
this.graph.updateNodeStats(nodeId, {
|
|
3482
3430
|
active: Math.max(0, controllers.size),
|
|
3483
3431
|
lastEndAt,
|
|
@@ -3645,7 +3593,7 @@ class RuntimeValidatorManager {
|
|
|
3645
3593
|
}
|
|
3646
3594
|
catch (err) {
|
|
3647
3595
|
// Don't let validator errors break execution - log and continue
|
|
3648
|
-
console.error(`Runtime validator error for node ${nodeId}:`, err);
|
|
3596
|
+
console.error(`Runtime validator error for node ${formatNodeRef(this.graph, nodeId)}:`, err);
|
|
3649
3597
|
}
|
|
3650
3598
|
}
|
|
3651
3599
|
return null;
|
|
@@ -3666,7 +3614,7 @@ class GraphRuntime {
|
|
|
3666
3614
|
this.graph = new Graph(this.eventEmitter);
|
|
3667
3615
|
this.runContextManager = new RunContextManager(this.graph, "warn");
|
|
3668
3616
|
this.handleResolver = new HandleResolver(this.graph, this.eventEmitter, this.runContextManager, this);
|
|
3669
|
-
this.edgePropagator = new EdgePropagator(this.graph, this.eventEmitter, this.runContextManager, this
|
|
3617
|
+
this.edgePropagator = new EdgePropagator(this.graph, this.eventEmitter, this.runContextManager, this, this);
|
|
3670
3618
|
// Create NodeExecutor with EdgePropagator and HandleResolver
|
|
3671
3619
|
this.nodeExecutor = new NodeExecutor(this.graph, this.eventEmitter, this.runContextManager, this.handleResolver, this, this);
|
|
3672
3620
|
// Create RuntimeValidatorManager
|
|
@@ -3755,6 +3703,30 @@ class GraphRuntime {
|
|
|
3755
3703
|
on(event, handler) {
|
|
3756
3704
|
return this.eventEmitter.on(event, handler);
|
|
3757
3705
|
}
|
|
3706
|
+
/**
|
|
3707
|
+
* Check if an event is an invalidate event that should trigger re-execution
|
|
3708
|
+
*/
|
|
3709
|
+
isInvalidateEvent(event) {
|
|
3710
|
+
if (!event || typeof event !== "object")
|
|
3711
|
+
return false;
|
|
3712
|
+
// Check if event has action === "invalidate"
|
|
3713
|
+
const e = event;
|
|
3714
|
+
return e.action === "invalidate";
|
|
3715
|
+
}
|
|
3716
|
+
executeNodeAutoRun(nodeId, opts) {
|
|
3717
|
+
const node = this.graph.getNode(nodeId);
|
|
3718
|
+
const shouldAutoRun = this.runMode === "auto" || node?.policy?.autoRun === true;
|
|
3719
|
+
let runContextIdsToUse = undefined;
|
|
3720
|
+
if (this.runMode === "manual") {
|
|
3721
|
+
runContextIdsToUse = new Set([this.runContextManager.createRunContext(nodeId, { propagate: false })]);
|
|
3722
|
+
}
|
|
3723
|
+
if (shouldAutoRun && this.graph.allInboundHaveValue(nodeId)) {
|
|
3724
|
+
this.execute(nodeId, {
|
|
3725
|
+
runContextIds: runContextIdsToUse,
|
|
3726
|
+
reason: opts?.reason ?? "executeNodeAutoRun",
|
|
3727
|
+
});
|
|
3728
|
+
}
|
|
3729
|
+
}
|
|
3758
3730
|
setInputs(nodeId, inputs) {
|
|
3759
3731
|
const node = this.graph.getNode(nodeId);
|
|
3760
3732
|
if (!node)
|
|
@@ -3780,11 +3752,7 @@ class GraphRuntime {
|
|
|
3780
3752
|
: desc
|
|
3781
3753
|
? getInputDeclaredTypes(desc.inputs, handle)
|
|
3782
3754
|
: undefined;
|
|
3783
|
-
const typeIds = Array.isArray(declaredTypes)
|
|
3784
|
-
? declaredTypes
|
|
3785
|
-
: declaredTypes
|
|
3786
|
-
? [declaredTypes]
|
|
3787
|
-
: [];
|
|
3755
|
+
const typeIds = Array.isArray(declaredTypes) ? declaredTypes : declaredTypes ? [declaredTypes] : [];
|
|
3788
3756
|
if (typeIds.length > 0) {
|
|
3789
3757
|
const isValidForAny = typeIds.some((tId) => {
|
|
3790
3758
|
const typeDesc = registry.types.get(tId);
|
|
@@ -3795,10 +3763,11 @@ class GraphRuntime {
|
|
|
3795
3763
|
});
|
|
3796
3764
|
if (value !== undefined && !isValidForAny) {
|
|
3797
3765
|
const typeLabel = typeIds.join("|");
|
|
3798
|
-
const errorMessage = `Invalid value for input ${nodeId}.${handle} (type ${typeLabel}): ${JSON.stringify(value)}`;
|
|
3766
|
+
const errorMessage = `Invalid value for input ${formatNodeRef(this.graph, nodeId)}.${handle} (type ${typeLabel}): ${JSON.stringify(value)}`;
|
|
3799
3767
|
this.eventEmitter.emit("error", {
|
|
3800
3768
|
kind: "input-validation",
|
|
3801
3769
|
nodeId,
|
|
3770
|
+
nodeTypeId: node.typeId,
|
|
3802
3771
|
handle,
|
|
3803
3772
|
typeId: typeLabel,
|
|
3804
3773
|
value,
|
|
@@ -3813,8 +3782,6 @@ class GraphRuntime {
|
|
|
3813
3782
|
const same = valuesEqual(prev, value);
|
|
3814
3783
|
if (!same) {
|
|
3815
3784
|
this.graph.updateNodeInput(nodeId, handle, value);
|
|
3816
|
-
// Emit value event for input updates
|
|
3817
|
-
this.eventEmitter.emit("value", { nodeId, handle, value, io: "input" });
|
|
3818
3785
|
anyChanged = true;
|
|
3819
3786
|
}
|
|
3820
3787
|
}
|
|
@@ -3866,16 +3833,6 @@ class GraphRuntime {
|
|
|
3866
3833
|
// Forward event to node's onExternalEvent handler for custom actions
|
|
3867
3834
|
node.runtime.onExternalEvent?.(event, node.state);
|
|
3868
3835
|
}
|
|
3869
|
-
/**
|
|
3870
|
-
* Check if an event is an invalidate event that should trigger re-execution
|
|
3871
|
-
*/
|
|
3872
|
-
isInvalidateEvent(event) {
|
|
3873
|
-
if (!event || typeof event !== "object")
|
|
3874
|
-
return false;
|
|
3875
|
-
// Check if event has action === "invalidate"
|
|
3876
|
-
const e = event;
|
|
3877
|
-
return e.action === "invalidate";
|
|
3878
|
-
}
|
|
3879
3836
|
cancelNodeRuns(nodeIds) {
|
|
3880
3837
|
this.nodeExecutor.cancelNodeRuns(nodeIds);
|
|
3881
3838
|
}
|
|
@@ -3903,6 +3860,7 @@ class GraphRuntime {
|
|
|
3903
3860
|
this.nodeExecutor.setEnvironment(this.environment);
|
|
3904
3861
|
for (const nodeId of this.graph.getNodeIds()) {
|
|
3905
3862
|
this.handleResolver.scheduleRecomputeHandles(nodeId);
|
|
3863
|
+
this.executeNodeAutoRun(nodeId, { reason: "setEnvironment" });
|
|
3906
3864
|
}
|
|
3907
3865
|
}
|
|
3908
3866
|
setCustomNodeData(customNodeData) {
|
|
@@ -4050,21 +4008,10 @@ class GraphRuntime {
|
|
|
4050
4008
|
}
|
|
4051
4009
|
}
|
|
4052
4010
|
}
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
if (this.runMode === "manual") {
|
|
4058
|
-
runContextIdsToUse = new Set([
|
|
4059
|
-
this.runContextManager.createRunContext(nodeId, { propagate: false }),
|
|
4060
|
-
]);
|
|
4061
|
-
}
|
|
4062
|
-
if (shouldAutoRun && this.graph.allInboundHaveValue(nodeId)) {
|
|
4063
|
-
this.execute(nodeId, {
|
|
4064
|
-
runContextIds: runContextIdsToUse,
|
|
4065
|
-
reason: opts?.reason ?? "executeNodeAutoRun",
|
|
4066
|
-
});
|
|
4067
|
-
}
|
|
4011
|
+
setTargetInput(edge, value, reason) {
|
|
4012
|
+
this.graph.updateNodeInput(edge.target.nodeId, edge.target.handle, value);
|
|
4013
|
+
this.handleResolver.scheduleRecomputeHandles(edge.target.nodeId);
|
|
4014
|
+
this.executeNodeAutoRun(edge.target.nodeId, { reason });
|
|
4068
4015
|
}
|
|
4069
4016
|
copyOutputs(fromNodeId, toNodeId, options) {
|
|
4070
4017
|
const fromNode = this.getNodeData(fromNodeId);
|
|
@@ -4230,8 +4177,7 @@ class GraphRuntime {
|
|
|
4230
4177
|
set.add(e.target.handle);
|
|
4231
4178
|
beforeInbound.set(e.target.nodeId, set);
|
|
4232
4179
|
// Build beforeOutTargets map
|
|
4233
|
-
const tmap = beforeOutTargets.get(e.source.nodeId) ??
|
|
4234
|
-
new Map();
|
|
4180
|
+
const tmap = beforeOutTargets.get(e.source.nodeId) ?? new Map();
|
|
4235
4181
|
const tset = tmap.get(e.source.handle) ?? new Set();
|
|
4236
4182
|
tset.add(`${e.target.nodeId}.${e.target.handle}`);
|
|
4237
4183
|
tmap.set(e.source.handle, tset);
|
|
@@ -4251,8 +4197,7 @@ class GraphRuntime {
|
|
|
4251
4197
|
const changedHandles = {};
|
|
4252
4198
|
for (const [nodeId, newHandles] of result.resolved) {
|
|
4253
4199
|
const oldHandles = this.graph.getResolvedHandles(nodeId);
|
|
4254
|
-
if (!oldHandles ||
|
|
4255
|
-
JSON.stringify(oldHandles) !== JSON.stringify(newHandles)) {
|
|
4200
|
+
if (!oldHandles || JSON.stringify(oldHandles) !== JSON.stringify(newHandles)) {
|
|
4256
4201
|
changedHandles[nodeId] = newHandles;
|
|
4257
4202
|
}
|
|
4258
4203
|
}
|
|
@@ -4304,8 +4249,7 @@ class GraphRuntime {
|
|
|
4304
4249
|
// Propagate changes on edges added
|
|
4305
4250
|
const afterOutTargets = new Map();
|
|
4306
4251
|
this.graph.forEachEdge((e) => {
|
|
4307
|
-
const targetMap = afterOutTargets.get(e.source.nodeId) ??
|
|
4308
|
-
new Map();
|
|
4252
|
+
const targetMap = afterOutTargets.get(e.source.nodeId) ?? new Map();
|
|
4309
4253
|
const targetSet = targetMap.get(e.source.handle) ?? new Set();
|
|
4310
4254
|
targetSet.add(`${e.target.nodeId}.${e.target.handle}`);
|
|
4311
4255
|
targetMap.set(e.source.handle, targetSet);
|
|
@@ -4330,10 +4274,7 @@ class GraphRuntime {
|
|
|
4330
4274
|
for (const nodeId of nodesToCheck) {
|
|
4331
4275
|
const beforeMap = beforeOutTargets.get(nodeId) ?? new Map();
|
|
4332
4276
|
const afterMap = afterOutTargets.get(nodeId) ?? new Map();
|
|
4333
|
-
const handles = new Set([
|
|
4334
|
-
...Array.from(beforeMap.keys()),
|
|
4335
|
-
...Array.from(afterMap.keys()),
|
|
4336
|
-
]);
|
|
4277
|
+
const handles = new Set([...Array.from(beforeMap.keys()), ...Array.from(afterMap.keys())]);
|
|
4337
4278
|
for (const handle of handles) {
|
|
4338
4279
|
const beforeTargetSet = beforeMap.get(handle) ?? new Set();
|
|
4339
4280
|
const afterTargetSet = afterMap.get(handle) ?? new Set();
|
|
@@ -4454,7 +4395,10 @@ class GraphBuilder {
|
|
|
4454
4395
|
effByNodeId.set(n.nodeId, getEffectiveHandles(n));
|
|
4455
4396
|
const nodeType = this.registry.nodes.get(n.typeId);
|
|
4456
4397
|
if (!nodeType) {
|
|
4457
|
-
pushIssue("error", "NODE_TYPE_MISSING", `Unknown node type ${n.typeId}`, {
|
|
4398
|
+
pushIssue("error", "NODE_TYPE_MISSING", `Unknown node type ${n.typeId}`, {
|
|
4399
|
+
typeId: n.typeId,
|
|
4400
|
+
nodeId: n.nodeId,
|
|
4401
|
+
});
|
|
4458
4402
|
continue;
|
|
4459
4403
|
}
|
|
4460
4404
|
if (!this.registry.categories.has(nodeType.categoryId)) {
|
|
@@ -4474,9 +4418,7 @@ class GraphBuilder {
|
|
|
4474
4418
|
typeof paramValue === "number" &&
|
|
4475
4419
|
!enumTypes.some((et) => validateEnumValue(et, paramValue, n.nodeId))) {
|
|
4476
4420
|
const enumDef = this.registry.enums.get(enumTypes[0]);
|
|
4477
|
-
const validValues = enumDef
|
|
4478
|
-
? Array.from(enumDef.valueToLabel.keys()).join(", ")
|
|
4479
|
-
: "unknown";
|
|
4421
|
+
const validValues = enumDef ? Array.from(enumDef.valueToLabel.keys()).join(", ") : "unknown";
|
|
4480
4422
|
pushIssue("error", "ENUM_VALUE_INVALID", `Node ${n.nodeId} param ${paramKey} has invalid enum value ${paramValue}. Valid values: ${validValues}`, {
|
|
4481
4423
|
nodeId: n.nodeId,
|
|
4482
4424
|
input: paramKey,
|
|
@@ -4496,9 +4438,7 @@ class GraphBuilder {
|
|
|
4496
4438
|
typeof defaultValue === "number" &&
|
|
4497
4439
|
!enumTypes.some((et) => validateEnumValue(et, defaultValue, n.nodeId))) {
|
|
4498
4440
|
const enumDef = this.registry.enums.get(enumTypes[0]);
|
|
4499
|
-
const validValues = enumDef
|
|
4500
|
-
? Array.from(enumDef.valueToLabel.keys()).join(", ")
|
|
4501
|
-
: "unknown";
|
|
4441
|
+
const validValues = enumDef ? Array.from(enumDef.valueToLabel.keys()).join(", ") : "unknown";
|
|
4502
4442
|
pushIssue("warning", "ENUM_DEFAULT_INVALID", `Node ${n.nodeId} input default ${handle} has invalid enum value ${defaultValue}. Valid values: ${validValues}`, {
|
|
4503
4443
|
nodeId: n.nodeId,
|
|
4504
4444
|
input: handle,
|
|
@@ -4541,7 +4481,9 @@ class GraphBuilder {
|
|
|
4541
4481
|
if (e.typeId) {
|
|
4542
4482
|
const type = this.registry.types.get(e.typeId);
|
|
4543
4483
|
if (!type) {
|
|
4544
|
-
pushIssue("error", "TYPE_MISSING", `Edge ${e.id} explicit type ${e.typeId} is missing or unknown`, {
|
|
4484
|
+
pushIssue("error", "TYPE_MISSING", `Edge ${e.id} explicit type ${e.typeId} is missing or unknown`, {
|
|
4485
|
+
edgeId: e.id,
|
|
4486
|
+
});
|
|
4545
4487
|
}
|
|
4546
4488
|
}
|
|
4547
4489
|
if (srcNode) {
|
|
@@ -4630,19 +4572,13 @@ class GraphBuilder {
|
|
|
4630
4572
|
const outputTypes = {};
|
|
4631
4573
|
for (const [outerIn, map] of Object.entries(exposure.inputs)) {
|
|
4632
4574
|
const innerNode = def.nodes.find((n) => n.nodeId === map.nodeId);
|
|
4633
|
-
const innerDesc = innerNode
|
|
4634
|
-
|
|
4635
|
-
: undefined;
|
|
4636
|
-
const typeIds = innerDesc
|
|
4637
|
-
? getInputDeclaredTypes(innerDesc.inputs, map.handle)
|
|
4638
|
-
: undefined;
|
|
4575
|
+
const innerDesc = innerNode ? this.registry.nodes.get(innerNode.typeId) : undefined;
|
|
4576
|
+
const typeIds = innerDesc ? getInputDeclaredTypes(innerDesc.inputs, map.handle) : undefined;
|
|
4639
4577
|
inputTypes[outerIn] = typeIds ?? "unknown";
|
|
4640
4578
|
}
|
|
4641
4579
|
for (const [outerOut, map] of Object.entries(exposure.outputs)) {
|
|
4642
4580
|
const innerNode = def.nodes.find((n) => n.nodeId === map.nodeId);
|
|
4643
|
-
const innerDesc = innerNode
|
|
4644
|
-
? this.registry.nodes.get(innerNode.typeId)
|
|
4645
|
-
: undefined;
|
|
4581
|
+
const innerDesc = innerNode ? this.registry.nodes.get(innerNode.typeId) : undefined;
|
|
4646
4582
|
const typeId = innerDesc ? innerDesc.outputs[map.handle] : undefined;
|
|
4647
4583
|
const single = Array.isArray(typeId) ? typeId[0] : typeId;
|
|
4648
4584
|
outputTypes[outerOut] = single ?? "unknown";
|
|
@@ -4845,7 +4781,7 @@ const CompositeCategory = (registry) => ({
|
|
|
4845
4781
|
});
|
|
4846
4782
|
|
|
4847
4783
|
// Helpers
|
|
4848
|
-
const asArray = (v) => Array.isArray(v) ? v : [Number(v)];
|
|
4784
|
+
const asArray = (v) => (Array.isArray(v) ? v : [Number(v)]);
|
|
4849
4785
|
const broadcast = (a, b) => {
|
|
4850
4786
|
const aa = asArray(a);
|
|
4851
4787
|
const bb = asArray(b);
|
|
@@ -4858,7 +4794,7 @@ const broadcast = (a, b) => {
|
|
|
4858
4794
|
const len = Math.max(aa.length, bb.length);
|
|
4859
4795
|
return [new Array(len).fill(aa[0] ?? 0), new Array(len).fill(bb[0] ?? 0)];
|
|
4860
4796
|
};
|
|
4861
|
-
const asBoolArray = (v) => Array.isArray(v) ? v.map((x) => Boolean(x)) : [Boolean(v)];
|
|
4797
|
+
const asBoolArray = (v) => (Array.isArray(v) ? v.map((x) => Boolean(x)) : [Boolean(v)]);
|
|
4862
4798
|
const broadcastBool = (a, b) => {
|
|
4863
4799
|
const aa = asBoolArray(a);
|
|
4864
4800
|
const bb = asBoolArray(b);
|
|
@@ -4869,10 +4805,7 @@ const broadcastBool = (a, b) => {
|
|
|
4869
4805
|
if (bb.length === 1)
|
|
4870
4806
|
return [aa, new Array(aa.length).fill(bb[0])];
|
|
4871
4807
|
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
|
-
];
|
|
4808
|
+
return [new Array(len).fill(aa[0] ?? false), new Array(len).fill(bb[0] ?? false)];
|
|
4876
4809
|
};
|
|
4877
4810
|
const clamp = (x, min, max) => Math.min(max, Math.max(min, x));
|
|
4878
4811
|
const lerp = (a, b, t) => a + (b - a) * t;
|
|
@@ -4922,8 +4855,7 @@ function jsonPointerSet(obj, pointer, value) {
|
|
|
4922
4855
|
if (next === undefined || next === null) {
|
|
4923
4856
|
// create container heuristically
|
|
4924
4857
|
const nextKey = parts[i + 1];
|
|
4925
|
-
cur[key] =
|
|
4926
|
-
typeof nextKey === "string" && /^[0-9]+$/.test(nextKey) ? [] : {};
|
|
4858
|
+
cur[key] = typeof nextKey === "string" && /^[0-9]+$/.test(nextKey) ? [] : {};
|
|
4927
4859
|
}
|
|
4928
4860
|
cur = cur[key];
|
|
4929
4861
|
}
|
|
@@ -5057,9 +4989,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5057
4989
|
}, { withArray: false });
|
|
5058
4990
|
registry.registerType({
|
|
5059
4991
|
id: "base.vec3",
|
|
5060
|
-
validate: (v) => Array.isArray(v) &&
|
|
5061
|
-
v.length === 3 &&
|
|
5062
|
-
v.every((x) => typeof x === "number"),
|
|
4992
|
+
validate: (v) => Array.isArray(v) && v.length === 3 && v.every((x) => typeof x === "number"),
|
|
5063
4993
|
bakeTarget: { nodeTypeId: "base.input.vec3", inputHandle: "Value" },
|
|
5064
4994
|
}, { withArray: true, arrayPickFirstDefined: true });
|
|
5065
4995
|
// float -> vec3 : map x to [x,0,0]
|
|
@@ -5104,9 +5034,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5104
5034
|
});
|
|
5105
5035
|
registry.registerCoercion("base.object", "base.vec3", (v) => {
|
|
5106
5036
|
try {
|
|
5107
|
-
if (Array.isArray(v) &&
|
|
5108
|
-
v.length === 3 &&
|
|
5109
|
-
v.every((x) => typeof x === "number")) {
|
|
5037
|
+
if (Array.isArray(v) && v.length === 3 && v.every((x) => typeof x === "number")) {
|
|
5110
5038
|
return v;
|
|
5111
5039
|
}
|
|
5112
5040
|
return undefined;
|
|
@@ -5236,9 +5164,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5236
5164
|
const [a, b] = broadcast(ins.ValueA, ins.ValueB);
|
|
5237
5165
|
const t = Number(ins.Factor ?? 0);
|
|
5238
5166
|
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));
|
|
5167
|
+
const out = new Array(len).fill(0).map((_, i) => lerp(Number(a[i] ?? 0), Number(b[i] ?? 0), t));
|
|
5242
5168
|
return { Value: out };
|
|
5243
5169
|
},
|
|
5244
5170
|
});
|
|
@@ -5266,9 +5192,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5266
5192
|
const out = vals.map((v) => {
|
|
5267
5193
|
const t = (Number(v) - fromMin) / (fromMax - fromMin || 1);
|
|
5268
5194
|
const r = toMin + t * (toMax - toMin);
|
|
5269
|
-
return doClamp
|
|
5270
|
-
? clamp(r, Math.min(toMin, toMax), Math.max(toMin, toMax))
|
|
5271
|
-
: r;
|
|
5195
|
+
return doClamp ? clamp(r, Math.min(toMin, toMax), Math.max(toMin, toMax)) : r;
|
|
5272
5196
|
});
|
|
5273
5197
|
return { Value: out };
|
|
5274
5198
|
},
|
|
@@ -5312,8 +5236,8 @@ function setupBasicGraphRegistry(id) {
|
|
|
5312
5236
|
const sum = arr.reduce((s, x) => s + Number(x || 0), 0);
|
|
5313
5237
|
return arr.length ? sum / arr.length : 0;
|
|
5314
5238
|
},
|
|
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,
|
|
5239
|
+
[BaseMathOperation.MinAll]: (arr) => (arr.length ? Math.min(...arr.map((x) => Number(x))) : 0),
|
|
5240
|
+
[BaseMathOperation.MaxAll]: (arr) => (arr.length ? Math.max(...arr.map((x) => Number(x))) : 0),
|
|
5317
5241
|
};
|
|
5318
5242
|
if (aggregateByOp[op] !== undefined)
|
|
5319
5243
|
return { Result: [aggregateByOp[op](a)] };
|
|
@@ -5330,8 +5254,8 @@ function setupBasicGraphRegistry(id) {
|
|
|
5330
5254
|
const fn = binaryByOp[op] || binaryByOp[BaseMathOperation.Add];
|
|
5331
5255
|
const len = Math.max(a.length, b.length);
|
|
5332
5256
|
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;
|
|
5257
|
+
const ax = a.length === 1 && len > 1 ? a[0] : (a[i] ?? 0);
|
|
5258
|
+
const bx = b.length === 1 && len > 1 ? b[0] : (b[i] ?? 0);
|
|
5335
5259
|
return fn(Number(ax), Number(bx));
|
|
5336
5260
|
});
|
|
5337
5261
|
return { Result: out };
|
|
@@ -5472,9 +5396,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5472
5396
|
impl: (ins) => {
|
|
5473
5397
|
const arr = Array.isArray(ins.Items) ? ins.Items : [];
|
|
5474
5398
|
const s = Math.trunc(Number(ins.Start ?? 0));
|
|
5475
|
-
const e = Number.isFinite(Number(ins.End))
|
|
5476
|
-
? Math.trunc(Number(ins.End))
|
|
5477
|
-
: undefined;
|
|
5399
|
+
const e = Number.isFinite(Number(ins.End)) ? Math.trunc(Number(ins.End)) : undefined;
|
|
5478
5400
|
return { Result: arr.slice(s, e) };
|
|
5479
5401
|
},
|
|
5480
5402
|
});
|
|
@@ -5749,11 +5671,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5749
5671
|
outputs: { Keys: "base.string[]" },
|
|
5750
5672
|
impl: (ins) => {
|
|
5751
5673
|
const obj = ins.Object;
|
|
5752
|
-
const keys = isPlainObject(obj)
|
|
5753
|
-
? Object.keys(obj)
|
|
5754
|
-
: Array.isArray(obj)
|
|
5755
|
-
? Object.keys(obj)
|
|
5756
|
-
: [];
|
|
5674
|
+
const keys = isPlainObject(obj) ? Object.keys(obj) : Array.isArray(obj) ? Object.keys(obj) : [];
|
|
5757
5675
|
return { Keys: keys };
|
|
5758
5676
|
},
|
|
5759
5677
|
});
|
|
@@ -5764,11 +5682,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5764
5682
|
outputs: { Values: "base.object" },
|
|
5765
5683
|
impl: (ins) => {
|
|
5766
5684
|
const obj = ins.Object;
|
|
5767
|
-
const vals = isPlainObject(obj)
|
|
5768
|
-
? Object.values(obj)
|
|
5769
|
-
: Array.isArray(obj)
|
|
5770
|
-
? Object.values(obj)
|
|
5771
|
-
: [];
|
|
5685
|
+
const vals = isPlainObject(obj) ? Object.values(obj) : Array.isArray(obj) ? Object.values(obj) : [];
|
|
5772
5686
|
return { Values: vals };
|
|
5773
5687
|
},
|
|
5774
5688
|
});
|
|
@@ -5780,11 +5694,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5780
5694
|
impl: (ins) => {
|
|
5781
5695
|
const root = structuredClone(ins.Object);
|
|
5782
5696
|
const opsRaw = ins.Ops;
|
|
5783
|
-
const ops = Array.isArray(opsRaw)
|
|
5784
|
-
? opsRaw
|
|
5785
|
-
: opsRaw
|
|
5786
|
-
? [opsRaw]
|
|
5787
|
-
: [];
|
|
5697
|
+
const ops = Array.isArray(opsRaw) ? opsRaw : opsRaw ? [opsRaw] : [];
|
|
5788
5698
|
let cur = root;
|
|
5789
5699
|
for (const op of ops) {
|
|
5790
5700
|
if (!op || typeof op !== "object")
|
|
@@ -5875,9 +5785,7 @@ function registerDelayNode(registry) {
|
|
|
5875
5785
|
impl: async (ins, ctx) => {
|
|
5876
5786
|
const ms = Number(ins.DelayMs ?? 200);
|
|
5877
5787
|
const valueRaw = ins.Value;
|
|
5878
|
-
if (valueRaw === undefined ||
|
|
5879
|
-
valueRaw === null ||
|
|
5880
|
-
Number.isNaN(Number(valueRaw))) {
|
|
5788
|
+
if (valueRaw === undefined || valueRaw === null || Number.isNaN(Number(valueRaw))) {
|
|
5881
5789
|
return; // wait until x is present to avoid NaN emissions
|
|
5882
5790
|
}
|
|
5883
5791
|
await new Promise((resolve, reject) => {
|
|
@@ -5947,9 +5855,7 @@ function generateId(prefix, used = new Set()) {
|
|
|
5947
5855
|
id = `${prefix}${Math.random().toString(36).slice(2, 8)}`;
|
|
5948
5856
|
attempts++;
|
|
5949
5857
|
if (attempts > 1000) {
|
|
5950
|
-
id = `${prefix}${Date.now().toString(36)}${Math.random()
|
|
5951
|
-
.toString(36)
|
|
5952
|
-
.slice(2, 4)}`;
|
|
5858
|
+
id = `${prefix}${Date.now().toString(36)}${Math.random().toString(36).slice(2, 4)}`;
|
|
5953
5859
|
}
|
|
5954
5860
|
} while (used.has(id));
|
|
5955
5861
|
return id;
|
|
@@ -5990,12 +5896,10 @@ function installLogging(engine) {
|
|
|
5990
5896
|
console.warn(`[error] input-validation: ${e.nodeId}.${e.handle} (type ${e.typeId})`, e.message);
|
|
5991
5897
|
}
|
|
5992
5898
|
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
|
-
: "");
|
|
5899
|
+
console.warn(`[error] registry:`, e.err?.message ?? e.err, e.attempt !== undefined ? `(attempt ${e.attempt}/${e.maxAttempts ?? "?"})` : "");
|
|
5996
5900
|
}
|
|
5997
5901
|
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) : "");
|
|
5902
|
+
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
5903
|
}
|
|
6000
5904
|
else {
|
|
6001
5905
|
// Log any other error kinds (shouldn't happen, but handle gracefully)
|
|
@@ -6320,11 +6224,7 @@ function buildTypeMaps(def) {
|
|
|
6320
6224
|
}
|
|
6321
6225
|
if (node.resolvedHandles?.outputs) {
|
|
6322
6226
|
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;
|
|
6227
|
+
const typeId = typeof handleDesc === "string" ? handleDesc : Array.isArray(handleDesc) ? handleDesc[0] : undefined;
|
|
6328
6228
|
if (typeId)
|
|
6329
6229
|
nodeOutputTypes.set(handleId, typeId);
|
|
6330
6230
|
}
|
|
@@ -6375,8 +6275,7 @@ function applyConversion(items, values, converter, type) {
|
|
|
6375
6275
|
});
|
|
6376
6276
|
if (convertedValue === null) {
|
|
6377
6277
|
delete values[item.nodeId]?.[item.handleId];
|
|
6378
|
-
if (values[item.nodeId] &&
|
|
6379
|
-
Object.keys(values[item.nodeId]).length === 0) {
|
|
6278
|
+
if (values[item.nodeId] && Object.keys(values[item.nodeId]).length === 0) {
|
|
6380
6279
|
delete values[item.nodeId];
|
|
6381
6280
|
}
|
|
6382
6281
|
}
|
|
@@ -6422,7 +6321,7 @@ function convertSnapshot(snapshot, converter) {
|
|
|
6422
6321
|
}
|
|
6423
6322
|
const { converted: convertedInputs, toConvert: inputsToConvert } = collectValuesToConvert(snapshot.inputs ?? {}, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "input");
|
|
6424
6323
|
const { converted: convertedOutputs, toConvert: outputsToConvert } = collectValuesToConvert(snapshot.outputs ?? {}, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "output");
|
|
6425
|
-
const { converted: convertedInputDefaults, toConvert: inputDefaultsToConvert
|
|
6324
|
+
const { converted: convertedInputDefaults, toConvert: inputDefaultsToConvert } = collectValuesToConvert(inputDefaults, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "inputDefault");
|
|
6426
6325
|
applyConversion(inputsToConvert, convertedInputs, converter, "input");
|
|
6427
6326
|
applyConversion(outputsToConvert, convertedOutputs, converter, "output");
|
|
6428
6327
|
applyConversion(inputDefaultsToConvert, convertedInputDefaults, converter, "inputDefault");
|
|
@@ -6612,7 +6511,7 @@ function matchesPattern(value, pattern) {
|
|
|
6612
6511
|
*/
|
|
6613
6512
|
function buildValueConverter(config) {
|
|
6614
6513
|
return (converterConfig) => {
|
|
6615
|
-
const { nodeId, handleId, value, type, nodeTypeId, handleDataType, runtimeTypeId
|
|
6514
|
+
const { nodeId, handleId, value, type, nodeTypeId, handleDataType, runtimeTypeId } = converterConfig;
|
|
6616
6515
|
const isValueTyped = isTyped(value);
|
|
6617
6516
|
for (const mapping of config.mappings) {
|
|
6618
6517
|
if (mapping.type && mapping.type !== type)
|
|
@@ -6655,8 +6554,7 @@ function buildValueConverter(config) {
|
|
|
6655
6554
|
}
|
|
6656
6555
|
}
|
|
6657
6556
|
else {
|
|
6658
|
-
if (typeof matchValue === "string" ||
|
|
6659
|
-
typeof matchValue === "number") {
|
|
6557
|
+
if (typeof matchValue === "string" || typeof matchValue === "number") {
|
|
6660
6558
|
const key = String(matchValue);
|
|
6661
6559
|
if (key in mapping.valueMap) {
|
|
6662
6560
|
newValue = mapping.valueMap[key];
|
|
@@ -6690,8 +6588,7 @@ function buildValueConverter(config) {
|
|
|
6690
6588
|
}
|
|
6691
6589
|
}
|
|
6692
6590
|
else {
|
|
6693
|
-
if (typeof innerValue === "string" ||
|
|
6694
|
-
typeof innerValue === "number") {
|
|
6591
|
+
if (typeof innerValue === "string" || typeof innerValue === "number") {
|
|
6695
6592
|
const key = String(innerValue);
|
|
6696
6593
|
if (key in mapping.valueMap) {
|
|
6697
6594
|
newValue = mapping.valueMap[key];
|
|
@@ -6718,8 +6615,7 @@ function buildValueConverter(config) {
|
|
|
6718
6615
|
: firstSegment instanceof RegExp
|
|
6719
6616
|
? null
|
|
6720
6617
|
: String(firstSegment);
|
|
6721
|
-
if (firstSegmentStr !== "__spark_value" &&
|
|
6722
|
-
firstSegmentStr !== "__spark_type") {
|
|
6618
|
+
if (firstSegmentStr !== "__spark_value" && firstSegmentStr !== "__spark_type") {
|
|
6723
6619
|
pathSegments = ["__spark_value", ...pathSegments];
|
|
6724
6620
|
}
|
|
6725
6621
|
}
|
|
@@ -6739,8 +6635,7 @@ function buildValueConverter(config) {
|
|
|
6739
6635
|
}
|
|
6740
6636
|
}
|
|
6741
6637
|
else {
|
|
6742
|
-
if (typeof matchValue === "string" ||
|
|
6743
|
-
typeof matchValue === "number") {
|
|
6638
|
+
if (typeof matchValue === "string" || typeof matchValue === "number") {
|
|
6744
6639
|
const key = String(matchValue);
|
|
6745
6640
|
if (key in mapping.valueMap) {
|
|
6746
6641
|
newValue = mapping.valueMap[key];
|