@bian-womp/spark-graph 0.2.11 → 0.2.13
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 +63 -3
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/runtime/GraphRuntime.d.ts +1 -0
- package/lib/cjs/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/lib/esm/index.js +63 -3
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/runtime/GraphRuntime.d.ts +1 -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());
|
|
@@ -1124,6 +1149,8 @@ class GraphRuntime {
|
|
|
1124
1149
|
setState: (next) => Object.assign(node.state, next),
|
|
1125
1150
|
});
|
|
1126
1151
|
this.nodes.delete(nodeId);
|
|
1152
|
+
// Clear any array buckets for this node
|
|
1153
|
+
this.arrayInputBuckets.delete(nodeId);
|
|
1127
1154
|
}
|
|
1128
1155
|
}
|
|
1129
1156
|
// Add or update existing nodes
|
|
@@ -1301,6 +1328,16 @@ class GraphRuntime {
|
|
|
1301
1328
|
}
|
|
1302
1329
|
}
|
|
1303
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
|
+
}
|
|
1304
1341
|
this.scheduleInputsChanged(nodeId);
|
|
1305
1342
|
}
|
|
1306
1343
|
}
|
|
@@ -1348,6 +1385,29 @@ class GraphRuntime {
|
|
|
1348
1385
|
}
|
|
1349
1386
|
}
|
|
1350
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
|
+
}
|
|
1351
1411
|
}
|
|
1352
1412
|
}
|
|
1353
1413
|
|