@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/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
|
|
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
|
-
|
|
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
|
-
|
|
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}
|
|
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}
|
|
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}
|
|
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)
|
|
@@ -2570,11 +2521,10 @@ class HandleResolver {
|
|
|
2570
2521
|
* EdgePropagator component - handles value propagation through edges
|
|
2571
2522
|
*/
|
|
2572
2523
|
class EdgePropagator {
|
|
2573
|
-
constructor(graph, eventEmitter, runContextManager,
|
|
2524
|
+
constructor(graph, eventEmitter, runContextManager, nodeExecutor, runtime) {
|
|
2574
2525
|
this.graph = graph;
|
|
2575
2526
|
this.eventEmitter = eventEmitter;
|
|
2576
2527
|
this.runContextManager = runContextManager;
|
|
2577
|
-
this.handleResolver = handleResolver;
|
|
2578
2528
|
this.nodeExecutor = nodeExecutor;
|
|
2579
2529
|
this.runtime = runtime;
|
|
2580
2530
|
this.arrayInputBuckets = new Map();
|
|
@@ -2604,9 +2554,7 @@ class EdgePropagator {
|
|
|
2604
2554
|
const effectiveRunContexts = runContextIds && runContextIds.size > 0
|
|
2605
2555
|
? this.filterEffectiveRunContexts(edge, srcNodeId, runContextIds)
|
|
2606
2556
|
: undefined;
|
|
2607
|
-
if (runContextIds &&
|
|
2608
|
-
runContextIds.size > 0 &&
|
|
2609
|
-
!(effectiveRunContexts && effectiveRunContexts.size > 0)) {
|
|
2557
|
+
if (runContextIds && runContextIds.size > 0 && !(effectiveRunContexts && effectiveRunContexts.size > 0)) {
|
|
2610
2558
|
return; // No valid run-contexts for this edge
|
|
2611
2559
|
}
|
|
2612
2560
|
// Validate union types
|
|
@@ -2647,12 +2595,16 @@ class EdgePropagator {
|
|
|
2647
2595
|
const isUnion = Array.isArray(edge.srcUnionTypes);
|
|
2648
2596
|
const isTypedValue = isTyped(value);
|
|
2649
2597
|
if (isUnion && !isTypedValue) {
|
|
2598
|
+
const sourceTypeId = this.graph.getNode(edge.source.nodeId)?.typeId;
|
|
2599
|
+
const targetTypeId = this.graph.getNode(edge.target.nodeId)?.typeId;
|
|
2650
2600
|
const err = new Error(`Output ${srcNodeId}.${edge.source.handle} requires typed value for union output (allowed: ${edge.srcUnionTypes.join("|")})`);
|
|
2651
2601
|
this.eventEmitter.emit("error", {
|
|
2652
2602
|
kind: "edge-convert",
|
|
2653
2603
|
edgeId: edge.id,
|
|
2654
2604
|
source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
|
|
2655
2605
|
target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
|
|
2606
|
+
sourceTypeId,
|
|
2607
|
+
targetTypeId,
|
|
2656
2608
|
err,
|
|
2657
2609
|
});
|
|
2658
2610
|
return false;
|
|
@@ -2668,7 +2620,14 @@ class EdgePropagator {
|
|
|
2668
2620
|
convertedValue = edge.convert(value);
|
|
2669
2621
|
}
|
|
2670
2622
|
else {
|
|
2671
|
-
|
|
2623
|
+
const fromType = (Array.isArray(edge.srcUnionTypes) && edge.srcUnionTypes.length > 0
|
|
2624
|
+
? edge.srcUnionTypes.join("|")
|
|
2625
|
+
: undefined) ??
|
|
2626
|
+
unwrapTypeId(value) ??
|
|
2627
|
+
edge.typeId ??
|
|
2628
|
+
"unknown";
|
|
2629
|
+
const toType = Array.isArray(edge.dstDeclared) ? edge.dstDeclared.join("|") : (edge.dstDeclared ?? "unknown");
|
|
2630
|
+
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
2631
|
}
|
|
2673
2632
|
this.applyToTarget(edge, convertedValue, effectiveRunContexts);
|
|
2674
2633
|
}
|
|
@@ -2679,20 +2638,22 @@ class EdgePropagator {
|
|
|
2679
2638
|
if (!edge.convertAsync)
|
|
2680
2639
|
return;
|
|
2681
2640
|
// Track edge run-context IDs for pendingEdges tracking
|
|
2682
|
-
const edgeRunContextIds = effectiveRunContexts
|
|
2683
|
-
? Array.from(effectiveRunContexts)
|
|
2684
|
-
: undefined;
|
|
2641
|
+
const edgeRunContextIds = effectiveRunContexts ? Array.from(effectiveRunContexts) : undefined;
|
|
2685
2642
|
if (edgeRunContextIds) {
|
|
2686
2643
|
for (const id of edgeRunContextIds) {
|
|
2687
2644
|
this.runContextManager.startEdgeConversion(id, edge.id);
|
|
2688
2645
|
}
|
|
2689
2646
|
}
|
|
2647
|
+
const sourceTypeId = this.graph.getNode(edge.source.nodeId)?.typeId;
|
|
2648
|
+
const targetTypeId = this.graph.getNode(edge.target.nodeId)?.typeId;
|
|
2690
2649
|
this.eventEmitter.emit("stats", {
|
|
2691
2650
|
kind: "edge-start",
|
|
2692
2651
|
edgeId: edge.id,
|
|
2693
2652
|
typeId: edge.typeId,
|
|
2694
2653
|
source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
|
|
2695
2654
|
target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
|
|
2655
|
+
sourceTypeId,
|
|
2656
|
+
targetTypeId,
|
|
2696
2657
|
});
|
|
2697
2658
|
const controller = new AbortController();
|
|
2698
2659
|
const startAt = Date.now();
|
|
@@ -2752,7 +2713,7 @@ class EdgePropagator {
|
|
|
2752
2713
|
// Set input value (respecting skipPropagateValues)
|
|
2753
2714
|
const shouldSetValue = this.shouldSetInputValue(effectiveRunContexts);
|
|
2754
2715
|
if (shouldSetValue && valueChanged) {
|
|
2755
|
-
this.setTargetInput(edge, processedValue);
|
|
2716
|
+
this.runtime.setTargetInput(edge, processedValue, "applyToTarget");
|
|
2756
2717
|
}
|
|
2757
2718
|
else if (shouldSetValue && !valueChanged) {
|
|
2758
2719
|
// Even if value didn't change, update timestamp if we're forcing execution
|
|
@@ -2770,7 +2731,7 @@ class EdgePropagator {
|
|
|
2770
2731
|
if (!dstIsArray) {
|
|
2771
2732
|
return value;
|
|
2772
2733
|
}
|
|
2773
|
-
const toArray = (x) => Array.isArray(x) ? x : x === undefined ? [] : [x];
|
|
2734
|
+
const toArray = (x) => (Array.isArray(x) ? x : x === undefined ? [] : [x]);
|
|
2774
2735
|
let forNode = this.arrayInputBuckets.get(edge.target.nodeId);
|
|
2775
2736
|
if (!forNode) {
|
|
2776
2737
|
forNode = new Map();
|
|
@@ -2808,13 +2769,6 @@ class EdgePropagator {
|
|
|
2808
2769
|
}
|
|
2809
2770
|
return true;
|
|
2810
2771
|
}
|
|
2811
|
-
/**
|
|
2812
|
-
* Set target input value and emit event
|
|
2813
|
-
*/
|
|
2814
|
-
setTargetInput(edge, value) {
|
|
2815
|
-
this.graph.updateNodeInput(edge.target.nodeId, edge.target.handle, value);
|
|
2816
|
-
this.handleResolver.scheduleRecomputeHandles(edge.target.nodeId);
|
|
2817
|
-
}
|
|
2818
2772
|
/**
|
|
2819
2773
|
* Execute downstream if conditions are met
|
|
2820
2774
|
*/
|
|
@@ -2861,6 +2815,8 @@ class EdgePropagator {
|
|
|
2861
2815
|
typeId: edge.typeId,
|
|
2862
2816
|
source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
|
|
2863
2817
|
target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
|
|
2818
|
+
sourceTypeId: this.graph.getNode(edge.source.nodeId)?.typeId,
|
|
2819
|
+
targetTypeId: this.graph.getNode(edge.target.nodeId)?.typeId,
|
|
2864
2820
|
durationMs: duration,
|
|
2865
2821
|
});
|
|
2866
2822
|
}
|
|
@@ -2877,6 +2833,8 @@ class EdgePropagator {
|
|
|
2877
2833
|
edgeId: edge.id,
|
|
2878
2834
|
source: { nodeId: edge.source.nodeId, handle: edge.source.handle },
|
|
2879
2835
|
target: { nodeId: edge.target.nodeId, handle: edge.target.handle },
|
|
2836
|
+
sourceTypeId: this.graph.getNode(edge.source.nodeId)?.typeId,
|
|
2837
|
+
targetTypeId: this.graph.getNode(edge.target.nodeId)?.typeId,
|
|
2880
2838
|
err,
|
|
2881
2839
|
});
|
|
2882
2840
|
}
|
|
@@ -2921,9 +2879,7 @@ class EdgePropagator {
|
|
|
2921
2879
|
return;
|
|
2922
2880
|
// Get resolved handles to filter out invalid outputs
|
|
2923
2881
|
const resolved = this.graph.getResolvedHandles(nodeId);
|
|
2924
|
-
const validOutputHandles = resolved?.outputs
|
|
2925
|
-
? new Set(Object.keys(resolved.outputs))
|
|
2926
|
-
: new Set();
|
|
2882
|
+
const validOutputHandles = resolved?.outputs ? new Set(Object.keys(resolved.outputs)) : new Set();
|
|
2927
2883
|
// Use node's activeRunContexts to propagate to new nodes that were added
|
|
2928
2884
|
const activeRunContextIds = this.graph.getNodeRunContextIds(nodeId);
|
|
2929
2885
|
for (const [handle, value] of Object.entries(node.outputs)) {
|
|
@@ -2994,7 +2950,7 @@ class NodeExecutor {
|
|
|
2994
2950
|
// Create log function that respects node's logLevel using LevelLogger
|
|
2995
2951
|
const node = this.graph.getNode(nodeId);
|
|
2996
2952
|
const nodeLogLevel = node?.logLevel ?? "info";
|
|
2997
|
-
const logger = new LevelLogger(nodeLogLevel, `[node:${
|
|
2953
|
+
const logger = new LevelLogger(nodeLogLevel, `[node:${formatNodeRef(this.graph, nodeId)}:${runId}]`);
|
|
2998
2954
|
const log = (level, message, context) => {
|
|
2999
2955
|
switch (level) {
|
|
3000
2956
|
case "debug":
|
|
@@ -3022,11 +2978,8 @@ class NodeExecutor {
|
|
|
3022
2978
|
execute: (opts) => {
|
|
3023
2979
|
if (this.graph.allInboundHaveValue(nodeId)) {
|
|
3024
2980
|
let runContextIdsToUse = this.runtime.getRunMode() === "auto" ? undefined : runContextIds;
|
|
3025
|
-
if (this.runtime.getRunMode() === "manual" &&
|
|
3026
|
-
|
|
3027
|
-
runContextIdsToUse = new Set([
|
|
3028
|
-
this.runContextManager.createRunContext(nodeId, opts),
|
|
3029
|
-
]);
|
|
2981
|
+
if (this.runtime.getRunMode() === "manual" && (!runContextIds || runContextIds.size === 0)) {
|
|
2982
|
+
runContextIdsToUse = new Set([this.runContextManager.createRunContext(nodeId, opts)]);
|
|
3030
2983
|
}
|
|
3031
2984
|
this.execute(nodeId, {
|
|
3032
2985
|
runContextIds: runContextIdsToUse,
|
|
@@ -3062,24 +3015,22 @@ class NodeExecutor {
|
|
|
3062
3015
|
return;
|
|
3063
3016
|
const runMode = this.runtime.getRunMode();
|
|
3064
3017
|
if (!runMode) {
|
|
3065
|
-
console.trace(`NodeExecutor.execute[${nodeId}:${reason}]: no runMode, skipping execution`);
|
|
3018
|
+
console.trace(`NodeExecutor.execute[${formatNodeRef(this.graph, nodeId)}:${reason}]: no runMode, skipping execution`);
|
|
3066
3019
|
return;
|
|
3067
3020
|
}
|
|
3068
3021
|
// In manual mode, require runContextIds unless autoRun policy is set
|
|
3069
3022
|
if (runMode === "manual" && (!runContextIds || runContextIds.size === 0)) {
|
|
3070
3023
|
// If autoRun is true, auto-generate a run context (similar to createExecutionContext pattern)
|
|
3071
3024
|
if (node.policy?.autoRun === true) {
|
|
3072
|
-
runContextIds = new Set([
|
|
3073
|
-
this.runContextManager.createRunContext(nodeId, { propagate: false }),
|
|
3074
|
-
]);
|
|
3025
|
+
runContextIds = new Set([this.runContextManager.createRunContext(nodeId, { propagate: false })]);
|
|
3075
3026
|
}
|
|
3076
3027
|
else {
|
|
3077
|
-
console.trace(`NodeExecutor.execute[${nodeId}:${reason}]: no runContextIds provided in manual mode, skipping execution`);
|
|
3028
|
+
console.trace(`NodeExecutor.execute[${formatNodeRef(this.graph, nodeId)}:${reason}]: no runContextIds provided in manual mode, skipping execution`);
|
|
3078
3029
|
return;
|
|
3079
3030
|
}
|
|
3080
3031
|
}
|
|
3081
3032
|
if (runMode === "auto" && runContextIds && runContextIds.size > 0) {
|
|
3082
|
-
console.trace(`NodeExecutor.execute[${nodeId}:${reason}]: runContextIds provided in auto mode, ignoring`);
|
|
3033
|
+
console.trace(`NodeExecutor.execute[${formatNodeRef(this.graph, nodeId)}:${reason}]: runContextIds provided in auto mode, ignoring`);
|
|
3083
3034
|
runContextIds = undefined;
|
|
3084
3035
|
}
|
|
3085
3036
|
// Early validation for auto-mode paused state
|
|
@@ -3094,6 +3045,7 @@ class NodeExecutor {
|
|
|
3094
3045
|
code: runtimeValidationError.code || "RUNTIME_VALIDATION_BLOCKED",
|
|
3095
3046
|
details: {
|
|
3096
3047
|
nodeId,
|
|
3048
|
+
nodeTypeId: node?.typeId,
|
|
3097
3049
|
...runtimeValidationError.details,
|
|
3098
3050
|
},
|
|
3099
3051
|
});
|
|
@@ -3104,8 +3056,7 @@ class NodeExecutor {
|
|
|
3104
3056
|
if (runContextIds) {
|
|
3105
3057
|
this.graph.addNodeRunContextIds(nodeId, runContextIds);
|
|
3106
3058
|
}
|
|
3107
|
-
if (!canSkipHandleResolution &&
|
|
3108
|
-
!this.handleResolver.getPendingResolution(nodeId)) {
|
|
3059
|
+
if (!canSkipHandleResolution && !this.handleResolver.getPendingResolution(nodeId)) {
|
|
3109
3060
|
this.handleResolver.scheduleRecomputeHandles(nodeId);
|
|
3110
3061
|
}
|
|
3111
3062
|
// Check if handles are being resolved - wait for resolution before executing
|
|
@@ -3156,9 +3107,7 @@ class NodeExecutor {
|
|
|
3156
3107
|
return false;
|
|
3157
3108
|
const policy = node.policy ?? {};
|
|
3158
3109
|
const lastScheduledAt = node.lastScheduledAt;
|
|
3159
|
-
return !!(policy.debounceMs &&
|
|
3160
|
-
lastScheduledAt &&
|
|
3161
|
-
now - lastScheduledAt < policy.debounceMs);
|
|
3110
|
+
return !!(policy.debounceMs && lastScheduledAt && now - lastScheduledAt < policy.debounceMs);
|
|
3162
3111
|
}
|
|
3163
3112
|
/**
|
|
3164
3113
|
* Handle debounced scheduling by replacing the latest queued item
|
|
@@ -3441,6 +3390,7 @@ class NodeExecutor {
|
|
|
3441
3390
|
this.eventEmitter.emit("error", {
|
|
3442
3391
|
kind: "node-run",
|
|
3443
3392
|
nodeId,
|
|
3393
|
+
nodeTypeId: node.typeId,
|
|
3444
3394
|
runId: plan.runId,
|
|
3445
3395
|
err,
|
|
3446
3396
|
});
|
|
@@ -3473,9 +3423,7 @@ class NodeExecutor {
|
|
|
3473
3423
|
return;
|
|
3474
3424
|
const controllers = this.graph.getNodeControllers(nodeId);
|
|
3475
3425
|
const lastEndAt = Date.now();
|
|
3476
|
-
const lastDurationMs = node.stats.lastStartAt && lastEndAt
|
|
3477
|
-
? lastEndAt - node.stats.lastStartAt
|
|
3478
|
-
: undefined;
|
|
3426
|
+
const lastDurationMs = node.stats.lastStartAt && lastEndAt ? lastEndAt - node.stats.lastStartAt : undefined;
|
|
3479
3427
|
this.graph.updateNodeStats(nodeId, {
|
|
3480
3428
|
active: Math.max(0, controllers.size),
|
|
3481
3429
|
lastEndAt,
|
|
@@ -3643,7 +3591,7 @@ class RuntimeValidatorManager {
|
|
|
3643
3591
|
}
|
|
3644
3592
|
catch (err) {
|
|
3645
3593
|
// Don't let validator errors break execution - log and continue
|
|
3646
|
-
console.error(`Runtime validator error for node ${nodeId}:`, err);
|
|
3594
|
+
console.error(`Runtime validator error for node ${formatNodeRef(this.graph, nodeId)}:`, err);
|
|
3647
3595
|
}
|
|
3648
3596
|
}
|
|
3649
3597
|
return null;
|
|
@@ -3664,7 +3612,7 @@ class GraphRuntime {
|
|
|
3664
3612
|
this.graph = new Graph(this.eventEmitter);
|
|
3665
3613
|
this.runContextManager = new RunContextManager(this.graph, "warn");
|
|
3666
3614
|
this.handleResolver = new HandleResolver(this.graph, this.eventEmitter, this.runContextManager, this);
|
|
3667
|
-
this.edgePropagator = new EdgePropagator(this.graph, this.eventEmitter, this.runContextManager, this
|
|
3615
|
+
this.edgePropagator = new EdgePropagator(this.graph, this.eventEmitter, this.runContextManager, this, this);
|
|
3668
3616
|
// Create NodeExecutor with EdgePropagator and HandleResolver
|
|
3669
3617
|
this.nodeExecutor = new NodeExecutor(this.graph, this.eventEmitter, this.runContextManager, this.handleResolver, this, this);
|
|
3670
3618
|
// Create RuntimeValidatorManager
|
|
@@ -3753,6 +3701,30 @@ class GraphRuntime {
|
|
|
3753
3701
|
on(event, handler) {
|
|
3754
3702
|
return this.eventEmitter.on(event, handler);
|
|
3755
3703
|
}
|
|
3704
|
+
/**
|
|
3705
|
+
* Check if an event is an invalidate event that should trigger re-execution
|
|
3706
|
+
*/
|
|
3707
|
+
isInvalidateEvent(event) {
|
|
3708
|
+
if (!event || typeof event !== "object")
|
|
3709
|
+
return false;
|
|
3710
|
+
// Check if event has action === "invalidate"
|
|
3711
|
+
const e = event;
|
|
3712
|
+
return e.action === "invalidate";
|
|
3713
|
+
}
|
|
3714
|
+
executeNodeAutoRun(nodeId, opts) {
|
|
3715
|
+
const node = this.graph.getNode(nodeId);
|
|
3716
|
+
const shouldAutoRun = this.runMode === "auto" || node?.policy?.autoRun === true;
|
|
3717
|
+
let runContextIdsToUse = undefined;
|
|
3718
|
+
if (this.runMode === "manual") {
|
|
3719
|
+
runContextIdsToUse = new Set([this.runContextManager.createRunContext(nodeId, { propagate: false })]);
|
|
3720
|
+
}
|
|
3721
|
+
if (shouldAutoRun && this.graph.allInboundHaveValue(nodeId)) {
|
|
3722
|
+
this.execute(nodeId, {
|
|
3723
|
+
runContextIds: runContextIdsToUse,
|
|
3724
|
+
reason: opts?.reason ?? "executeNodeAutoRun",
|
|
3725
|
+
});
|
|
3726
|
+
}
|
|
3727
|
+
}
|
|
3756
3728
|
setInputs(nodeId, inputs) {
|
|
3757
3729
|
const node = this.graph.getNode(nodeId);
|
|
3758
3730
|
if (!node)
|
|
@@ -3778,11 +3750,7 @@ class GraphRuntime {
|
|
|
3778
3750
|
: desc
|
|
3779
3751
|
? getInputDeclaredTypes(desc.inputs, handle)
|
|
3780
3752
|
: undefined;
|
|
3781
|
-
const typeIds = Array.isArray(declaredTypes)
|
|
3782
|
-
? declaredTypes
|
|
3783
|
-
: declaredTypes
|
|
3784
|
-
? [declaredTypes]
|
|
3785
|
-
: [];
|
|
3753
|
+
const typeIds = Array.isArray(declaredTypes) ? declaredTypes : declaredTypes ? [declaredTypes] : [];
|
|
3786
3754
|
if (typeIds.length > 0) {
|
|
3787
3755
|
const isValidForAny = typeIds.some((tId) => {
|
|
3788
3756
|
const typeDesc = registry.types.get(tId);
|
|
@@ -3793,10 +3761,11 @@ class GraphRuntime {
|
|
|
3793
3761
|
});
|
|
3794
3762
|
if (value !== undefined && !isValidForAny) {
|
|
3795
3763
|
const typeLabel = typeIds.join("|");
|
|
3796
|
-
const errorMessage = `Invalid value for input ${nodeId}.${handle} (type ${typeLabel}): ${JSON.stringify(value)}`;
|
|
3764
|
+
const errorMessage = `Invalid value for input ${formatNodeRef(this.graph, nodeId)}.${handle} (type ${typeLabel}): ${JSON.stringify(value)}`;
|
|
3797
3765
|
this.eventEmitter.emit("error", {
|
|
3798
3766
|
kind: "input-validation",
|
|
3799
3767
|
nodeId,
|
|
3768
|
+
nodeTypeId: node.typeId,
|
|
3800
3769
|
handle,
|
|
3801
3770
|
typeId: typeLabel,
|
|
3802
3771
|
value,
|
|
@@ -3811,8 +3780,6 @@ class GraphRuntime {
|
|
|
3811
3780
|
const same = valuesEqual(prev, value);
|
|
3812
3781
|
if (!same) {
|
|
3813
3782
|
this.graph.updateNodeInput(nodeId, handle, value);
|
|
3814
|
-
// Emit value event for input updates
|
|
3815
|
-
this.eventEmitter.emit("value", { nodeId, handle, value, io: "input" });
|
|
3816
3783
|
anyChanged = true;
|
|
3817
3784
|
}
|
|
3818
3785
|
}
|
|
@@ -3864,16 +3831,6 @@ class GraphRuntime {
|
|
|
3864
3831
|
// Forward event to node's onExternalEvent handler for custom actions
|
|
3865
3832
|
node.runtime.onExternalEvent?.(event, node.state);
|
|
3866
3833
|
}
|
|
3867
|
-
/**
|
|
3868
|
-
* Check if an event is an invalidate event that should trigger re-execution
|
|
3869
|
-
*/
|
|
3870
|
-
isInvalidateEvent(event) {
|
|
3871
|
-
if (!event || typeof event !== "object")
|
|
3872
|
-
return false;
|
|
3873
|
-
// Check if event has action === "invalidate"
|
|
3874
|
-
const e = event;
|
|
3875
|
-
return e.action === "invalidate";
|
|
3876
|
-
}
|
|
3877
3834
|
cancelNodeRuns(nodeIds) {
|
|
3878
3835
|
this.nodeExecutor.cancelNodeRuns(nodeIds);
|
|
3879
3836
|
}
|
|
@@ -3901,6 +3858,7 @@ class GraphRuntime {
|
|
|
3901
3858
|
this.nodeExecutor.setEnvironment(this.environment);
|
|
3902
3859
|
for (const nodeId of this.graph.getNodeIds()) {
|
|
3903
3860
|
this.handleResolver.scheduleRecomputeHandles(nodeId);
|
|
3861
|
+
this.executeNodeAutoRun(nodeId, { reason: "setEnvironment" });
|
|
3904
3862
|
}
|
|
3905
3863
|
}
|
|
3906
3864
|
setCustomNodeData(customNodeData) {
|
|
@@ -4048,21 +4006,10 @@ class GraphRuntime {
|
|
|
4048
4006
|
}
|
|
4049
4007
|
}
|
|
4050
4008
|
}
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
if (this.runMode === "manual") {
|
|
4056
|
-
runContextIdsToUse = new Set([
|
|
4057
|
-
this.runContextManager.createRunContext(nodeId, { propagate: false }),
|
|
4058
|
-
]);
|
|
4059
|
-
}
|
|
4060
|
-
if (shouldAutoRun && this.graph.allInboundHaveValue(nodeId)) {
|
|
4061
|
-
this.execute(nodeId, {
|
|
4062
|
-
runContextIds: runContextIdsToUse,
|
|
4063
|
-
reason: opts?.reason ?? "executeNodeAutoRun",
|
|
4064
|
-
});
|
|
4065
|
-
}
|
|
4009
|
+
setTargetInput(edge, value, reason) {
|
|
4010
|
+
this.graph.updateNodeInput(edge.target.nodeId, edge.target.handle, value);
|
|
4011
|
+
this.handleResolver.scheduleRecomputeHandles(edge.target.nodeId);
|
|
4012
|
+
this.executeNodeAutoRun(edge.target.nodeId, { reason });
|
|
4066
4013
|
}
|
|
4067
4014
|
copyOutputs(fromNodeId, toNodeId, options) {
|
|
4068
4015
|
const fromNode = this.getNodeData(fromNodeId);
|
|
@@ -4228,8 +4175,7 @@ class GraphRuntime {
|
|
|
4228
4175
|
set.add(e.target.handle);
|
|
4229
4176
|
beforeInbound.set(e.target.nodeId, set);
|
|
4230
4177
|
// Build beforeOutTargets map
|
|
4231
|
-
const tmap = beforeOutTargets.get(e.source.nodeId) ??
|
|
4232
|
-
new Map();
|
|
4178
|
+
const tmap = beforeOutTargets.get(e.source.nodeId) ?? new Map();
|
|
4233
4179
|
const tset = tmap.get(e.source.handle) ?? new Set();
|
|
4234
4180
|
tset.add(`${e.target.nodeId}.${e.target.handle}`);
|
|
4235
4181
|
tmap.set(e.source.handle, tset);
|
|
@@ -4249,8 +4195,7 @@ class GraphRuntime {
|
|
|
4249
4195
|
const changedHandles = {};
|
|
4250
4196
|
for (const [nodeId, newHandles] of result.resolved) {
|
|
4251
4197
|
const oldHandles = this.graph.getResolvedHandles(nodeId);
|
|
4252
|
-
if (!oldHandles ||
|
|
4253
|
-
JSON.stringify(oldHandles) !== JSON.stringify(newHandles)) {
|
|
4198
|
+
if (!oldHandles || JSON.stringify(oldHandles) !== JSON.stringify(newHandles)) {
|
|
4254
4199
|
changedHandles[nodeId] = newHandles;
|
|
4255
4200
|
}
|
|
4256
4201
|
}
|
|
@@ -4302,8 +4247,7 @@ class GraphRuntime {
|
|
|
4302
4247
|
// Propagate changes on edges added
|
|
4303
4248
|
const afterOutTargets = new Map();
|
|
4304
4249
|
this.graph.forEachEdge((e) => {
|
|
4305
|
-
const targetMap = afterOutTargets.get(e.source.nodeId) ??
|
|
4306
|
-
new Map();
|
|
4250
|
+
const targetMap = afterOutTargets.get(e.source.nodeId) ?? new Map();
|
|
4307
4251
|
const targetSet = targetMap.get(e.source.handle) ?? new Set();
|
|
4308
4252
|
targetSet.add(`${e.target.nodeId}.${e.target.handle}`);
|
|
4309
4253
|
targetMap.set(e.source.handle, targetSet);
|
|
@@ -4328,10 +4272,7 @@ class GraphRuntime {
|
|
|
4328
4272
|
for (const nodeId of nodesToCheck) {
|
|
4329
4273
|
const beforeMap = beforeOutTargets.get(nodeId) ?? new Map();
|
|
4330
4274
|
const afterMap = afterOutTargets.get(nodeId) ?? new Map();
|
|
4331
|
-
const handles = new Set([
|
|
4332
|
-
...Array.from(beforeMap.keys()),
|
|
4333
|
-
...Array.from(afterMap.keys()),
|
|
4334
|
-
]);
|
|
4275
|
+
const handles = new Set([...Array.from(beforeMap.keys()), ...Array.from(afterMap.keys())]);
|
|
4335
4276
|
for (const handle of handles) {
|
|
4336
4277
|
const beforeTargetSet = beforeMap.get(handle) ?? new Set();
|
|
4337
4278
|
const afterTargetSet = afterMap.get(handle) ?? new Set();
|
|
@@ -4452,7 +4393,10 @@ class GraphBuilder {
|
|
|
4452
4393
|
effByNodeId.set(n.nodeId, getEffectiveHandles(n));
|
|
4453
4394
|
const nodeType = this.registry.nodes.get(n.typeId);
|
|
4454
4395
|
if (!nodeType) {
|
|
4455
|
-
pushIssue("error", "NODE_TYPE_MISSING", `Unknown node type ${n.typeId}`, {
|
|
4396
|
+
pushIssue("error", "NODE_TYPE_MISSING", `Unknown node type ${n.typeId}`, {
|
|
4397
|
+
typeId: n.typeId,
|
|
4398
|
+
nodeId: n.nodeId,
|
|
4399
|
+
});
|
|
4456
4400
|
continue;
|
|
4457
4401
|
}
|
|
4458
4402
|
if (!this.registry.categories.has(nodeType.categoryId)) {
|
|
@@ -4472,9 +4416,7 @@ class GraphBuilder {
|
|
|
4472
4416
|
typeof paramValue === "number" &&
|
|
4473
4417
|
!enumTypes.some((et) => validateEnumValue(et, paramValue, n.nodeId))) {
|
|
4474
4418
|
const enumDef = this.registry.enums.get(enumTypes[0]);
|
|
4475
|
-
const validValues = enumDef
|
|
4476
|
-
? Array.from(enumDef.valueToLabel.keys()).join(", ")
|
|
4477
|
-
: "unknown";
|
|
4419
|
+
const validValues = enumDef ? Array.from(enumDef.valueToLabel.keys()).join(", ") : "unknown";
|
|
4478
4420
|
pushIssue("error", "ENUM_VALUE_INVALID", `Node ${n.nodeId} param ${paramKey} has invalid enum value ${paramValue}. Valid values: ${validValues}`, {
|
|
4479
4421
|
nodeId: n.nodeId,
|
|
4480
4422
|
input: paramKey,
|
|
@@ -4494,9 +4436,7 @@ class GraphBuilder {
|
|
|
4494
4436
|
typeof defaultValue === "number" &&
|
|
4495
4437
|
!enumTypes.some((et) => validateEnumValue(et, defaultValue, n.nodeId))) {
|
|
4496
4438
|
const enumDef = this.registry.enums.get(enumTypes[0]);
|
|
4497
|
-
const validValues = enumDef
|
|
4498
|
-
? Array.from(enumDef.valueToLabel.keys()).join(", ")
|
|
4499
|
-
: "unknown";
|
|
4439
|
+
const validValues = enumDef ? Array.from(enumDef.valueToLabel.keys()).join(", ") : "unknown";
|
|
4500
4440
|
pushIssue("warning", "ENUM_DEFAULT_INVALID", `Node ${n.nodeId} input default ${handle} has invalid enum value ${defaultValue}. Valid values: ${validValues}`, {
|
|
4501
4441
|
nodeId: n.nodeId,
|
|
4502
4442
|
input: handle,
|
|
@@ -4539,7 +4479,9 @@ class GraphBuilder {
|
|
|
4539
4479
|
if (e.typeId) {
|
|
4540
4480
|
const type = this.registry.types.get(e.typeId);
|
|
4541
4481
|
if (!type) {
|
|
4542
|
-
pushIssue("error", "TYPE_MISSING", `Edge ${e.id} explicit type ${e.typeId} is missing or unknown`, {
|
|
4482
|
+
pushIssue("error", "TYPE_MISSING", `Edge ${e.id} explicit type ${e.typeId} is missing or unknown`, {
|
|
4483
|
+
edgeId: e.id,
|
|
4484
|
+
});
|
|
4543
4485
|
}
|
|
4544
4486
|
}
|
|
4545
4487
|
if (srcNode) {
|
|
@@ -4628,19 +4570,13 @@ class GraphBuilder {
|
|
|
4628
4570
|
const outputTypes = {};
|
|
4629
4571
|
for (const [outerIn, map] of Object.entries(exposure.inputs)) {
|
|
4630
4572
|
const innerNode = def.nodes.find((n) => n.nodeId === map.nodeId);
|
|
4631
|
-
const innerDesc = innerNode
|
|
4632
|
-
|
|
4633
|
-
: undefined;
|
|
4634
|
-
const typeIds = innerDesc
|
|
4635
|
-
? getInputDeclaredTypes(innerDesc.inputs, map.handle)
|
|
4636
|
-
: undefined;
|
|
4573
|
+
const innerDesc = innerNode ? this.registry.nodes.get(innerNode.typeId) : undefined;
|
|
4574
|
+
const typeIds = innerDesc ? getInputDeclaredTypes(innerDesc.inputs, map.handle) : undefined;
|
|
4637
4575
|
inputTypes[outerIn] = typeIds ?? "unknown";
|
|
4638
4576
|
}
|
|
4639
4577
|
for (const [outerOut, map] of Object.entries(exposure.outputs)) {
|
|
4640
4578
|
const innerNode = def.nodes.find((n) => n.nodeId === map.nodeId);
|
|
4641
|
-
const innerDesc = innerNode
|
|
4642
|
-
? this.registry.nodes.get(innerNode.typeId)
|
|
4643
|
-
: undefined;
|
|
4579
|
+
const innerDesc = innerNode ? this.registry.nodes.get(innerNode.typeId) : undefined;
|
|
4644
4580
|
const typeId = innerDesc ? innerDesc.outputs[map.handle] : undefined;
|
|
4645
4581
|
const single = Array.isArray(typeId) ? typeId[0] : typeId;
|
|
4646
4582
|
outputTypes[outerOut] = single ?? "unknown";
|
|
@@ -4843,7 +4779,7 @@ const CompositeCategory = (registry) => ({
|
|
|
4843
4779
|
});
|
|
4844
4780
|
|
|
4845
4781
|
// Helpers
|
|
4846
|
-
const asArray = (v) => Array.isArray(v) ? v : [Number(v)];
|
|
4782
|
+
const asArray = (v) => (Array.isArray(v) ? v : [Number(v)]);
|
|
4847
4783
|
const broadcast = (a, b) => {
|
|
4848
4784
|
const aa = asArray(a);
|
|
4849
4785
|
const bb = asArray(b);
|
|
@@ -4856,7 +4792,7 @@ const broadcast = (a, b) => {
|
|
|
4856
4792
|
const len = Math.max(aa.length, bb.length);
|
|
4857
4793
|
return [new Array(len).fill(aa[0] ?? 0), new Array(len).fill(bb[0] ?? 0)];
|
|
4858
4794
|
};
|
|
4859
|
-
const asBoolArray = (v) => Array.isArray(v) ? v.map((x) => Boolean(x)) : [Boolean(v)];
|
|
4795
|
+
const asBoolArray = (v) => (Array.isArray(v) ? v.map((x) => Boolean(x)) : [Boolean(v)]);
|
|
4860
4796
|
const broadcastBool = (a, b) => {
|
|
4861
4797
|
const aa = asBoolArray(a);
|
|
4862
4798
|
const bb = asBoolArray(b);
|
|
@@ -4867,10 +4803,7 @@ const broadcastBool = (a, b) => {
|
|
|
4867
4803
|
if (bb.length === 1)
|
|
4868
4804
|
return [aa, new Array(aa.length).fill(bb[0])];
|
|
4869
4805
|
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
|
-
];
|
|
4806
|
+
return [new Array(len).fill(aa[0] ?? false), new Array(len).fill(bb[0] ?? false)];
|
|
4874
4807
|
};
|
|
4875
4808
|
const clamp = (x, min, max) => Math.min(max, Math.max(min, x));
|
|
4876
4809
|
const lerp = (a, b, t) => a + (b - a) * t;
|
|
@@ -4920,8 +4853,7 @@ function jsonPointerSet(obj, pointer, value) {
|
|
|
4920
4853
|
if (next === undefined || next === null) {
|
|
4921
4854
|
// create container heuristically
|
|
4922
4855
|
const nextKey = parts[i + 1];
|
|
4923
|
-
cur[key] =
|
|
4924
|
-
typeof nextKey === "string" && /^[0-9]+$/.test(nextKey) ? [] : {};
|
|
4856
|
+
cur[key] = typeof nextKey === "string" && /^[0-9]+$/.test(nextKey) ? [] : {};
|
|
4925
4857
|
}
|
|
4926
4858
|
cur = cur[key];
|
|
4927
4859
|
}
|
|
@@ -5055,9 +4987,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5055
4987
|
}, { withArray: false });
|
|
5056
4988
|
registry.registerType({
|
|
5057
4989
|
id: "base.vec3",
|
|
5058
|
-
validate: (v) => Array.isArray(v) &&
|
|
5059
|
-
v.length === 3 &&
|
|
5060
|
-
v.every((x) => typeof x === "number"),
|
|
4990
|
+
validate: (v) => Array.isArray(v) && v.length === 3 && v.every((x) => typeof x === "number"),
|
|
5061
4991
|
bakeTarget: { nodeTypeId: "base.input.vec3", inputHandle: "Value" },
|
|
5062
4992
|
}, { withArray: true, arrayPickFirstDefined: true });
|
|
5063
4993
|
// float -> vec3 : map x to [x,0,0]
|
|
@@ -5102,9 +5032,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5102
5032
|
});
|
|
5103
5033
|
registry.registerCoercion("base.object", "base.vec3", (v) => {
|
|
5104
5034
|
try {
|
|
5105
|
-
if (Array.isArray(v) &&
|
|
5106
|
-
v.length === 3 &&
|
|
5107
|
-
v.every((x) => typeof x === "number")) {
|
|
5035
|
+
if (Array.isArray(v) && v.length === 3 && v.every((x) => typeof x === "number")) {
|
|
5108
5036
|
return v;
|
|
5109
5037
|
}
|
|
5110
5038
|
return undefined;
|
|
@@ -5234,9 +5162,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5234
5162
|
const [a, b] = broadcast(ins.ValueA, ins.ValueB);
|
|
5235
5163
|
const t = Number(ins.Factor ?? 0);
|
|
5236
5164
|
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));
|
|
5165
|
+
const out = new Array(len).fill(0).map((_, i) => lerp(Number(a[i] ?? 0), Number(b[i] ?? 0), t));
|
|
5240
5166
|
return { Value: out };
|
|
5241
5167
|
},
|
|
5242
5168
|
});
|
|
@@ -5264,9 +5190,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5264
5190
|
const out = vals.map((v) => {
|
|
5265
5191
|
const t = (Number(v) - fromMin) / (fromMax - fromMin || 1);
|
|
5266
5192
|
const r = toMin + t * (toMax - toMin);
|
|
5267
|
-
return doClamp
|
|
5268
|
-
? clamp(r, Math.min(toMin, toMax), Math.max(toMin, toMax))
|
|
5269
|
-
: r;
|
|
5193
|
+
return doClamp ? clamp(r, Math.min(toMin, toMax), Math.max(toMin, toMax)) : r;
|
|
5270
5194
|
});
|
|
5271
5195
|
return { Value: out };
|
|
5272
5196
|
},
|
|
@@ -5310,8 +5234,8 @@ function setupBasicGraphRegistry(id) {
|
|
|
5310
5234
|
const sum = arr.reduce((s, x) => s + Number(x || 0), 0);
|
|
5311
5235
|
return arr.length ? sum / arr.length : 0;
|
|
5312
5236
|
},
|
|
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,
|
|
5237
|
+
[BaseMathOperation.MinAll]: (arr) => (arr.length ? Math.min(...arr.map((x) => Number(x))) : 0),
|
|
5238
|
+
[BaseMathOperation.MaxAll]: (arr) => (arr.length ? Math.max(...arr.map((x) => Number(x))) : 0),
|
|
5315
5239
|
};
|
|
5316
5240
|
if (aggregateByOp[op] !== undefined)
|
|
5317
5241
|
return { Result: [aggregateByOp[op](a)] };
|
|
@@ -5328,8 +5252,8 @@ function setupBasicGraphRegistry(id) {
|
|
|
5328
5252
|
const fn = binaryByOp[op] || binaryByOp[BaseMathOperation.Add];
|
|
5329
5253
|
const len = Math.max(a.length, b.length);
|
|
5330
5254
|
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;
|
|
5255
|
+
const ax = a.length === 1 && len > 1 ? a[0] : (a[i] ?? 0);
|
|
5256
|
+
const bx = b.length === 1 && len > 1 ? b[0] : (b[i] ?? 0);
|
|
5333
5257
|
return fn(Number(ax), Number(bx));
|
|
5334
5258
|
});
|
|
5335
5259
|
return { Result: out };
|
|
@@ -5470,9 +5394,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5470
5394
|
impl: (ins) => {
|
|
5471
5395
|
const arr = Array.isArray(ins.Items) ? ins.Items : [];
|
|
5472
5396
|
const s = Math.trunc(Number(ins.Start ?? 0));
|
|
5473
|
-
const e = Number.isFinite(Number(ins.End))
|
|
5474
|
-
? Math.trunc(Number(ins.End))
|
|
5475
|
-
: undefined;
|
|
5397
|
+
const e = Number.isFinite(Number(ins.End)) ? Math.trunc(Number(ins.End)) : undefined;
|
|
5476
5398
|
return { Result: arr.slice(s, e) };
|
|
5477
5399
|
},
|
|
5478
5400
|
});
|
|
@@ -5747,11 +5669,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5747
5669
|
outputs: { Keys: "base.string[]" },
|
|
5748
5670
|
impl: (ins) => {
|
|
5749
5671
|
const obj = ins.Object;
|
|
5750
|
-
const keys = isPlainObject(obj)
|
|
5751
|
-
? Object.keys(obj)
|
|
5752
|
-
: Array.isArray(obj)
|
|
5753
|
-
? Object.keys(obj)
|
|
5754
|
-
: [];
|
|
5672
|
+
const keys = isPlainObject(obj) ? Object.keys(obj) : Array.isArray(obj) ? Object.keys(obj) : [];
|
|
5755
5673
|
return { Keys: keys };
|
|
5756
5674
|
},
|
|
5757
5675
|
});
|
|
@@ -5762,11 +5680,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5762
5680
|
outputs: { Values: "base.object" },
|
|
5763
5681
|
impl: (ins) => {
|
|
5764
5682
|
const obj = ins.Object;
|
|
5765
|
-
const vals = isPlainObject(obj)
|
|
5766
|
-
? Object.values(obj)
|
|
5767
|
-
: Array.isArray(obj)
|
|
5768
|
-
? Object.values(obj)
|
|
5769
|
-
: [];
|
|
5683
|
+
const vals = isPlainObject(obj) ? Object.values(obj) : Array.isArray(obj) ? Object.values(obj) : [];
|
|
5770
5684
|
return { Values: vals };
|
|
5771
5685
|
},
|
|
5772
5686
|
});
|
|
@@ -5778,11 +5692,7 @@ function setupBasicGraphRegistry(id) {
|
|
|
5778
5692
|
impl: (ins) => {
|
|
5779
5693
|
const root = structuredClone(ins.Object);
|
|
5780
5694
|
const opsRaw = ins.Ops;
|
|
5781
|
-
const ops = Array.isArray(opsRaw)
|
|
5782
|
-
? opsRaw
|
|
5783
|
-
: opsRaw
|
|
5784
|
-
? [opsRaw]
|
|
5785
|
-
: [];
|
|
5695
|
+
const ops = Array.isArray(opsRaw) ? opsRaw : opsRaw ? [opsRaw] : [];
|
|
5786
5696
|
let cur = root;
|
|
5787
5697
|
for (const op of ops) {
|
|
5788
5698
|
if (!op || typeof op !== "object")
|
|
@@ -5873,9 +5783,7 @@ function registerDelayNode(registry) {
|
|
|
5873
5783
|
impl: async (ins, ctx) => {
|
|
5874
5784
|
const ms = Number(ins.DelayMs ?? 200);
|
|
5875
5785
|
const valueRaw = ins.Value;
|
|
5876
|
-
if (valueRaw === undefined ||
|
|
5877
|
-
valueRaw === null ||
|
|
5878
|
-
Number.isNaN(Number(valueRaw))) {
|
|
5786
|
+
if (valueRaw === undefined || valueRaw === null || Number.isNaN(Number(valueRaw))) {
|
|
5879
5787
|
return; // wait until x is present to avoid NaN emissions
|
|
5880
5788
|
}
|
|
5881
5789
|
await new Promise((resolve, reject) => {
|
|
@@ -5945,9 +5853,7 @@ function generateId(prefix, used = new Set()) {
|
|
|
5945
5853
|
id = `${prefix}${Math.random().toString(36).slice(2, 8)}`;
|
|
5946
5854
|
attempts++;
|
|
5947
5855
|
if (attempts > 1000) {
|
|
5948
|
-
id = `${prefix}${Date.now().toString(36)}${Math.random()
|
|
5949
|
-
.toString(36)
|
|
5950
|
-
.slice(2, 4)}`;
|
|
5856
|
+
id = `${prefix}${Date.now().toString(36)}${Math.random().toString(36).slice(2, 4)}`;
|
|
5951
5857
|
}
|
|
5952
5858
|
} while (used.has(id));
|
|
5953
5859
|
return id;
|
|
@@ -5988,12 +5894,10 @@ function installLogging(engine) {
|
|
|
5988
5894
|
console.warn(`[error] input-validation: ${e.nodeId}.${e.handle} (type ${e.typeId})`, e.message);
|
|
5989
5895
|
}
|
|
5990
5896
|
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
|
-
: "");
|
|
5897
|
+
console.warn(`[error] registry:`, e.err?.message ?? e.err, e.attempt !== undefined ? `(attempt ${e.attempt}/${e.maxAttempts ?? "?"})` : "");
|
|
5994
5898
|
}
|
|
5995
5899
|
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) : "");
|
|
5900
|
+
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
5901
|
}
|
|
5998
5902
|
else {
|
|
5999
5903
|
// Log any other error kinds (shouldn't happen, but handle gracefully)
|
|
@@ -6318,11 +6222,7 @@ function buildTypeMaps(def) {
|
|
|
6318
6222
|
}
|
|
6319
6223
|
if (node.resolvedHandles?.outputs) {
|
|
6320
6224
|
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;
|
|
6225
|
+
const typeId = typeof handleDesc === "string" ? handleDesc : Array.isArray(handleDesc) ? handleDesc[0] : undefined;
|
|
6326
6226
|
if (typeId)
|
|
6327
6227
|
nodeOutputTypes.set(handleId, typeId);
|
|
6328
6228
|
}
|
|
@@ -6373,8 +6273,7 @@ function applyConversion(items, values, converter, type) {
|
|
|
6373
6273
|
});
|
|
6374
6274
|
if (convertedValue === null) {
|
|
6375
6275
|
delete values[item.nodeId]?.[item.handleId];
|
|
6376
|
-
if (values[item.nodeId] &&
|
|
6377
|
-
Object.keys(values[item.nodeId]).length === 0) {
|
|
6276
|
+
if (values[item.nodeId] && Object.keys(values[item.nodeId]).length === 0) {
|
|
6378
6277
|
delete values[item.nodeId];
|
|
6379
6278
|
}
|
|
6380
6279
|
}
|
|
@@ -6420,7 +6319,7 @@ function convertSnapshot(snapshot, converter) {
|
|
|
6420
6319
|
}
|
|
6421
6320
|
const { converted: convertedInputs, toConvert: inputsToConvert } = collectValuesToConvert(snapshot.inputs ?? {}, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "input");
|
|
6422
6321
|
const { converted: convertedOutputs, toConvert: outputsToConvert } = collectValuesToConvert(snapshot.outputs ?? {}, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "output");
|
|
6423
|
-
const { converted: convertedInputDefaults, toConvert: inputDefaultsToConvert
|
|
6322
|
+
const { converted: convertedInputDefaults, toConvert: inputDefaultsToConvert } = collectValuesToConvert(inputDefaults, nodeTypeMap, inputHandleTypeMap, outputHandleTypeMap, "inputDefault");
|
|
6424
6323
|
applyConversion(inputsToConvert, convertedInputs, converter, "input");
|
|
6425
6324
|
applyConversion(outputsToConvert, convertedOutputs, converter, "output");
|
|
6426
6325
|
applyConversion(inputDefaultsToConvert, convertedInputDefaults, converter, "inputDefault");
|
|
@@ -6610,7 +6509,7 @@ function matchesPattern(value, pattern) {
|
|
|
6610
6509
|
*/
|
|
6611
6510
|
function buildValueConverter(config) {
|
|
6612
6511
|
return (converterConfig) => {
|
|
6613
|
-
const { nodeId, handleId, value, type, nodeTypeId, handleDataType, runtimeTypeId
|
|
6512
|
+
const { nodeId, handleId, value, type, nodeTypeId, handleDataType, runtimeTypeId } = converterConfig;
|
|
6614
6513
|
const isValueTyped = isTyped(value);
|
|
6615
6514
|
for (const mapping of config.mappings) {
|
|
6616
6515
|
if (mapping.type && mapping.type !== type)
|
|
@@ -6653,8 +6552,7 @@ function buildValueConverter(config) {
|
|
|
6653
6552
|
}
|
|
6654
6553
|
}
|
|
6655
6554
|
else {
|
|
6656
|
-
if (typeof matchValue === "string" ||
|
|
6657
|
-
typeof matchValue === "number") {
|
|
6555
|
+
if (typeof matchValue === "string" || typeof matchValue === "number") {
|
|
6658
6556
|
const key = String(matchValue);
|
|
6659
6557
|
if (key in mapping.valueMap) {
|
|
6660
6558
|
newValue = mapping.valueMap[key];
|
|
@@ -6688,8 +6586,7 @@ function buildValueConverter(config) {
|
|
|
6688
6586
|
}
|
|
6689
6587
|
}
|
|
6690
6588
|
else {
|
|
6691
|
-
if (typeof innerValue === "string" ||
|
|
6692
|
-
typeof innerValue === "number") {
|
|
6589
|
+
if (typeof innerValue === "string" || typeof innerValue === "number") {
|
|
6693
6590
|
const key = String(innerValue);
|
|
6694
6591
|
if (key in mapping.valueMap) {
|
|
6695
6592
|
newValue = mapping.valueMap[key];
|
|
@@ -6716,8 +6613,7 @@ function buildValueConverter(config) {
|
|
|
6716
6613
|
: firstSegment instanceof RegExp
|
|
6717
6614
|
? null
|
|
6718
6615
|
: String(firstSegment);
|
|
6719
|
-
if (firstSegmentStr !== "__spark_value" &&
|
|
6720
|
-
firstSegmentStr !== "__spark_type") {
|
|
6616
|
+
if (firstSegmentStr !== "__spark_value" && firstSegmentStr !== "__spark_type") {
|
|
6721
6617
|
pathSegments = ["__spark_value", ...pathSegments];
|
|
6722
6618
|
}
|
|
6723
6619
|
}
|
|
@@ -6737,8 +6633,7 @@ function buildValueConverter(config) {
|
|
|
6737
6633
|
}
|
|
6738
6634
|
}
|
|
6739
6635
|
else {
|
|
6740
|
-
if (typeof matchValue === "string" ||
|
|
6741
|
-
typeof matchValue === "number") {
|
|
6636
|
+
if (typeof matchValue === "string" || typeof matchValue === "number") {
|
|
6742
6637
|
const key = String(matchValue);
|
|
6743
6638
|
if (key in mapping.valueMap) {
|
|
6744
6639
|
newValue = mapping.valueMap[key];
|