@bian-womp/spark-graph 0.2.10 → 0.2.12
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 +117 -3
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/builder/Registry.d.ts +1 -1
- package/lib/cjs/src/builder/Registry.d.ts.map +1 -1
- package/lib/cjs/src/core/types.d.ts +1 -1
- package/lib/cjs/src/core/types.d.ts.map +1 -1
- package/lib/cjs/src/examples/run.d.ts.map +1 -1
- package/lib/cjs/src/examples/snapshot.d.ts +4 -0
- package/lib/cjs/src/examples/snapshot.d.ts.map +1 -0
- package/lib/cjs/src/runtime/GraphRuntime.d.ts +7 -0
- package/lib/cjs/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/lib/esm/index.js +117 -3
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/builder/Registry.d.ts +1 -1
- package/lib/esm/src/builder/Registry.d.ts.map +1 -1
- package/lib/esm/src/core/types.d.ts +1 -1
- package/lib/esm/src/core/types.d.ts.map +1 -1
- package/lib/esm/src/examples/run.d.ts.map +1 -1
- package/lib/esm/src/examples/snapshot.d.ts +4 -0
- package/lib/esm/src/examples/snapshot.d.ts.map +1 -0
- package/lib/esm/src/runtime/GraphRuntime.d.ts +7 -0
- package/lib/esm/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/package.json +2 -2
package/lib/cjs/index.cjs
CHANGED
|
@@ -409,6 +409,10 @@ class GraphRuntime {
|
|
|
409
409
|
this.listeners = new Map();
|
|
410
410
|
this.environment = {};
|
|
411
411
|
this.paused = false;
|
|
412
|
+
// For array-typed target inputs, keep per-edge contributions so successive runs
|
|
413
|
+
// from the same source replace their slice instead of accumulating forever.
|
|
414
|
+
// Structure: nodeId -> handle -> edgeId -> values[]
|
|
415
|
+
this.arrayInputBuckets = new Map();
|
|
412
416
|
}
|
|
413
417
|
// Shallow/deep-ish equality to avoid unnecessary runs on identical values
|
|
414
418
|
valuesEqual(a, b) {
|
|
@@ -842,11 +846,31 @@ class GraphRuntime {
|
|
|
842
846
|
return;
|
|
843
847
|
const dstIsArray = typeof e.dstDeclared === "string" && e.dstDeclared.endsWith("[]");
|
|
844
848
|
let next = v;
|
|
845
|
-
// If target input is an array type,
|
|
849
|
+
// If target input is an array type, merge per-edge contributions deterministically
|
|
846
850
|
if (dstIsArray) {
|
|
847
851
|
const toArray = (x) => Array.isArray(x) ? x : x === undefined ? [] : [x];
|
|
848
|
-
|
|
849
|
-
|
|
852
|
+
// Update this edge's contribution
|
|
853
|
+
let forNode = this.arrayInputBuckets.get(e.target.nodeId);
|
|
854
|
+
if (!forNode) {
|
|
855
|
+
forNode = new Map();
|
|
856
|
+
this.arrayInputBuckets.set(e.target.nodeId, forNode);
|
|
857
|
+
}
|
|
858
|
+
let forHandle = forNode.get(e.target.handle);
|
|
859
|
+
if (!forHandle) {
|
|
860
|
+
forHandle = new Map();
|
|
861
|
+
forNode.set(e.target.handle, forHandle);
|
|
862
|
+
}
|
|
863
|
+
forHandle.set(e.id, toArray(v));
|
|
864
|
+
// Compute merged array in the order of current edges list
|
|
865
|
+
const merged = [];
|
|
866
|
+
for (const ed of this.edges) {
|
|
867
|
+
if (ed.target.nodeId === e.target.nodeId &&
|
|
868
|
+
ed.target.handle === e.target.handle) {
|
|
869
|
+
const part = forHandle.get(ed.id);
|
|
870
|
+
if (part && part.length)
|
|
871
|
+
merged.push(...part);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
850
874
|
next = merged;
|
|
851
875
|
}
|
|
852
876
|
const prev = dstNode.inputs[e.target.handle];
|
|
@@ -997,6 +1021,7 @@ class GraphRuntime {
|
|
|
997
1021
|
this.nodes.clear();
|
|
998
1022
|
this.edges = [];
|
|
999
1023
|
this.listeners.clear();
|
|
1024
|
+
this.arrayInputBuckets.clear();
|
|
1000
1025
|
}
|
|
1001
1026
|
getNodeIds() {
|
|
1002
1027
|
return Array.from(this.nodes.keys());
|
|
@@ -1054,6 +1079,60 @@ class GraphRuntime {
|
|
|
1054
1079
|
__unsafe_scheduleInputsChanged(nodeId) {
|
|
1055
1080
|
this.scheduleInputsChanged(nodeId);
|
|
1056
1081
|
}
|
|
1082
|
+
// Hydrate inputs/outputs without triggering computation; optionally re-emit outputs downstream
|
|
1083
|
+
hydrate(payload, opts) {
|
|
1084
|
+
const prevPaused = this.paused;
|
|
1085
|
+
this.paused = true;
|
|
1086
|
+
try {
|
|
1087
|
+
const ins = payload?.inputs || {};
|
|
1088
|
+
for (const [nodeId, map] of Object.entries(ins)) {
|
|
1089
|
+
const node = this.nodes.get(nodeId);
|
|
1090
|
+
if (!node)
|
|
1091
|
+
continue;
|
|
1092
|
+
for (const [h, v] of Object.entries(map || {})) {
|
|
1093
|
+
node.inputs[h] =
|
|
1094
|
+
typeof structuredClone === "function"
|
|
1095
|
+
? structuredClone(v)
|
|
1096
|
+
: JSON.parse(JSON.stringify(v));
|
|
1097
|
+
// emit input value event
|
|
1098
|
+
this.emit("value", {
|
|
1099
|
+
nodeId,
|
|
1100
|
+
handle: h,
|
|
1101
|
+
value: node.inputs[h],
|
|
1102
|
+
io: "input",
|
|
1103
|
+
runtimeTypeId: getTypedOutputTypeId(node.inputs[h]),
|
|
1104
|
+
});
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
const outs = payload?.outputs || {};
|
|
1108
|
+
for (const [nodeId, map] of Object.entries(outs)) {
|
|
1109
|
+
const node = this.nodes.get(nodeId);
|
|
1110
|
+
if (!node)
|
|
1111
|
+
continue;
|
|
1112
|
+
for (const [h, v] of Object.entries(map || {})) {
|
|
1113
|
+
node.outputs[h] =
|
|
1114
|
+
typeof structuredClone === "function"
|
|
1115
|
+
? structuredClone(v)
|
|
1116
|
+
: JSON.parse(JSON.stringify(v));
|
|
1117
|
+
// emit output value event
|
|
1118
|
+
this.emit("value", {
|
|
1119
|
+
nodeId,
|
|
1120
|
+
handle: h,
|
|
1121
|
+
value: node.outputs[h],
|
|
1122
|
+
io: "output",
|
|
1123
|
+
runtimeTypeId: getTypedOutputTypeId(node.outputs[h]),
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
if (opts?.reemit) {
|
|
1128
|
+
for (const nodeId of this.nodes.keys())
|
|
1129
|
+
this.reemitNodeOutputs(nodeId);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
finally {
|
|
1133
|
+
this.paused = prevPaused;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1057
1136
|
// Incrementally update nodes/edges to match new definition without full rebuild
|
|
1058
1137
|
update(def, registry) {
|
|
1059
1138
|
// Handle node additions and removals
|
|
@@ -1070,6 +1149,8 @@ class GraphRuntime {
|
|
|
1070
1149
|
setState: (next) => Object.assign(node.state, next),
|
|
1071
1150
|
});
|
|
1072
1151
|
this.nodes.delete(nodeId);
|
|
1152
|
+
// Clear any array buckets for this node
|
|
1153
|
+
this.arrayInputBuckets.delete(nodeId);
|
|
1073
1154
|
}
|
|
1074
1155
|
}
|
|
1075
1156
|
// Add or update existing nodes
|
|
@@ -1247,6 +1328,16 @@ class GraphRuntime {
|
|
|
1247
1328
|
}
|
|
1248
1329
|
}
|
|
1249
1330
|
}
|
|
1331
|
+
// Clear buckets for handles that lost inbound
|
|
1332
|
+
const bucketsForNode = this.arrayInputBuckets.get(nodeId);
|
|
1333
|
+
if (bucketsForNode) {
|
|
1334
|
+
for (const handle of Array.from(prevSet)) {
|
|
1335
|
+
if (!currSet.has(handle))
|
|
1336
|
+
bucketsForNode.delete(handle);
|
|
1337
|
+
}
|
|
1338
|
+
if (bucketsForNode.size === 0)
|
|
1339
|
+
this.arrayInputBuckets.delete(nodeId);
|
|
1340
|
+
}
|
|
1250
1341
|
this.scheduleInputsChanged(nodeId);
|
|
1251
1342
|
}
|
|
1252
1343
|
}
|
|
@@ -1294,6 +1385,29 @@ class GraphRuntime {
|
|
|
1294
1385
|
}
|
|
1295
1386
|
}
|
|
1296
1387
|
}
|
|
1388
|
+
// Prune array bucket contributions for edges that no longer exist
|
|
1389
|
+
const validPerTarget = new Map();
|
|
1390
|
+
for (const ed of this.edges) {
|
|
1391
|
+
const m = validPerTarget.get(ed.target.nodeId) ?? new Map();
|
|
1392
|
+
const s = m.get(ed.target.handle) ?? new Set();
|
|
1393
|
+
s.add(ed.id);
|
|
1394
|
+
m.set(ed.target.handle, s);
|
|
1395
|
+
validPerTarget.set(ed.target.nodeId, m);
|
|
1396
|
+
}
|
|
1397
|
+
for (const [nodeId, byHandle] of Array.from(this.arrayInputBuckets)) {
|
|
1398
|
+
const validHandles = validPerTarget.get(nodeId) ?? new Map();
|
|
1399
|
+
for (const [handle, perEdge] of Array.from(byHandle)) {
|
|
1400
|
+
const validEdgeIds = validHandles.get(handle) ?? new Set();
|
|
1401
|
+
for (const edgeId of Array.from(perEdge.keys())) {
|
|
1402
|
+
if (!validEdgeIds.has(edgeId))
|
|
1403
|
+
perEdge.delete(edgeId);
|
|
1404
|
+
}
|
|
1405
|
+
if (perEdge.size === 0)
|
|
1406
|
+
byHandle.delete(handle);
|
|
1407
|
+
}
|
|
1408
|
+
if (byHandle.size === 0)
|
|
1409
|
+
this.arrayInputBuckets.delete(nodeId);
|
|
1410
|
+
}
|
|
1297
1411
|
}
|
|
1298
1412
|
}
|
|
1299
1413
|
|