@bian-womp/spark-graph 0.1.11 → 0.1.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 CHANGED
@@ -480,18 +480,25 @@ class GraphRuntime {
480
480
  h(payload);
481
481
  }
482
482
  setInput(nodeId, handle, value) {
483
+ this.setInputs(nodeId, { [handle]: value });
484
+ }
485
+ setInputs(nodeId, inputs) {
483
486
  const node = this.nodes.get(nodeId);
484
487
  if (!node)
485
488
  throw new Error(`Node not found: ${nodeId}`);
486
- // If this input has an inbound edge, prefer propagated runtime value over manual input
487
- const hasInbound = this.edges.some((e) => e.target.nodeId === nodeId && e.target.handle === handle);
488
- if (hasInbound)
489
- return; // respect linked value
490
- node.inputs[handle] = value;
491
- // Emit value event for input updates
492
- this.emit("value", { nodeId, handle, value, io: "input" });
493
- if (!this.paused)
494
- this.scheduleInputsChanged(nodeId);
489
+ for (const [handle, value] of Object.entries(inputs)) {
490
+ const hasInbound = this.edges.some((e) => e.target.nodeId === nodeId && e.target.handle === handle);
491
+ if (hasInbound)
492
+ continue;
493
+ node.inputs[handle] = value;
494
+ // Emit value event for input updates
495
+ this.emit("value", { nodeId, handle, value, io: "input" });
496
+ }
497
+ if (!this.paused) {
498
+ // Only schedule if all inbound inputs are present (or there are none)
499
+ if (this.allInboundHaveValue(nodeId))
500
+ this.scheduleInputsChanged(nodeId);
501
+ }
495
502
  }
496
503
  getOutput(nodeId, output) {
497
504
  const node = this.nodes.get(nodeId);
@@ -637,6 +644,20 @@ class GraphRuntime {
637
644
  // switch or merge
638
645
  startRun(rid, { ...node.inputs });
639
646
  }
647
+ // Returns true if all inbound handles for the node currently have a value
648
+ allInboundHaveValue(nodeId) {
649
+ const node = this.nodes.get(nodeId);
650
+ if (!node)
651
+ return false;
652
+ const inbound = this.edges.filter((e) => e.target.nodeId === nodeId);
653
+ if (inbound.length === 0)
654
+ return true;
655
+ for (const e of inbound) {
656
+ if (!(e.target.handle in node.inputs))
657
+ return false;
658
+ }
659
+ return true;
660
+ }
640
661
  invalidateDownstream(nodeId) {
641
662
  // Notifies dependents; for now we propagate current outputs
642
663
  for (const e of this.edges.filter((e) => e.source.nodeId === nodeId)) {
@@ -672,7 +693,7 @@ class GraphRuntime {
672
693
  value: v,
673
694
  io: "input",
674
695
  });
675
- if (!this.paused)
696
+ if (!this.paused && this.allInboundHaveValue(e.target.nodeId))
676
697
  this.scheduleInputsChanged(e.target.nodeId);
677
698
  };
678
699
  if (e.convertAsync) {
@@ -1255,7 +1276,10 @@ class AbstractEngine {
1255
1276
  this.graphRuntime.launch();
1256
1277
  }
1257
1278
  setInput(nodeId, handle, value) {
1258
- this.graphRuntime.setInput(nodeId, handle, value);
1279
+ this.setInputs(nodeId, { [handle]: value });
1280
+ }
1281
+ setInputs(nodeId, inputs) {
1282
+ this.graphRuntime.setInputs(nodeId, inputs);
1259
1283
  }
1260
1284
  triggerExternal(nodeId, event) {
1261
1285
  this.graphRuntime.triggerExternal(nodeId, event);
@@ -1318,8 +1342,8 @@ class BatchedEngine extends AbstractEngine {
1318
1342
  this.timer = setInterval(() => this.flush(), this.opts.flushIntervalMs);
1319
1343
  }
1320
1344
  }
1321
- setInput(nodeId, handle, value) {
1322
- super.setInput(nodeId, handle, value);
1345
+ setInputs(nodeId, inputs) {
1346
+ super.setInputs(nodeId, inputs);
1323
1347
  this.dirtyNodes.add(nodeId);
1324
1348
  }
1325
1349
  triggerExternal(nodeId, event) {
@@ -1395,7 +1419,7 @@ class HybridEngine extends AbstractEngine {
1395
1419
  launch() {
1396
1420
  this.graphRuntime.resume();
1397
1421
  }
1398
- setInput(nodeId, handle, value) {
1422
+ setInputs(nodeId, inputs) {
1399
1423
  this.updateWindow();
1400
1424
  this.countInWindow += 1;
1401
1425
  const threshold = this.opts.batchThreshold ?? 5;
@@ -1418,7 +1442,7 @@ class HybridEngine extends AbstractEngine {
1418
1442
  this.flushTimer = undefined;
1419
1443
  }, windowMs);
1420
1444
  }
1421
- super.setInput(nodeId, handle, value);
1445
+ super.setInputs(nodeId, inputs);
1422
1446
  this.dirtyNodes.add(nodeId);
1423
1447
  if (!this.batching)
1424
1448
  this.graphRuntime.__unsafe_scheduleInputsChanged(nodeId);
@@ -1444,8 +1468,8 @@ class StepEngine extends AbstractEngine {
1444
1468
  this.graphRuntime.pause();
1445
1469
  }
1446
1470
  launch() { }
1447
- setInput(nodeId, handle, value) {
1448
- super.setInput(nodeId, handle, value);
1471
+ setInputs(nodeId, inputs) {
1472
+ super.setInputs(nodeId, inputs);
1449
1473
  this.dirtyNodes.add(nodeId);
1450
1474
  }
1451
1475
  triggerExternal(nodeId, event) {