@bian-womp/spark-workbench 0.2.15 → 0.2.17

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
@@ -1535,17 +1535,23 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
1535
1535
  const snap = await runner.snapshotFull();
1536
1536
  const remoteDef = snap?.def;
1537
1537
  if (remoteDef && Array.isArray(remoteDef.nodes)) {
1538
+ // Mutate current def in-place to avoid emitting graphChanged and causing update loop
1538
1539
  const cur = wb.export();
1539
- const merged = {
1540
- ...cur,
1541
- nodes: cur.nodes.map((n) => {
1542
- const rn = (remoteDef.nodes || []).find((m) => m.nodeId === n.nodeId);
1543
- if (rn && rn.resolvedHandles)
1544
- return { ...n, resolvedHandles: rn.resolvedHandles };
1545
- return n;
1546
- }),
1547
- };
1548
- await wb.load(merged);
1540
+ const byId = new Map((remoteDef.nodes || []).map((n) => [n.nodeId, n]));
1541
+ let changed = false;
1542
+ for (const n of cur.nodes) {
1543
+ const rn = byId.get(n.nodeId);
1544
+ if (rn && rn.resolvedHandles) {
1545
+ const before = JSON.stringify(n.resolvedHandles || {});
1546
+ const after = JSON.stringify(rn.resolvedHandles || {});
1547
+ if (before !== after) {
1548
+ n.resolvedHandles = rn.resolvedHandles;
1549
+ changed = true;
1550
+ }
1551
+ }
1552
+ }
1553
+ if (changed)
1554
+ wb.refreshValidation();
1549
1555
  }
1550
1556
  }
1551
1557
  catch { }
@@ -1557,8 +1563,6 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
1557
1563
  ...s,
1558
1564
  [nodeId]: { ...s[nodeId], invalidated: true },
1559
1565
  }));
1560
- // On any input change, refresh resolved handles (covers context-driven dynamic ports)
1561
- refreshResolvedHandles();
1562
1566
  }
1563
1567
  return add("runner", "value")(e);
1564
1568
  });
@@ -1602,9 +1606,10 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
1602
1606
  return next;
1603
1607
  });
1604
1608
  }
1605
- // After build/update, pull resolved handles from remote snapshot and merge into local def for UI
1606
- if (e?.reason === "graph-updated" || e?.reason === "graph-built")
1609
+ // After build/update, pull resolved handles and merge in-place (no graphChanged)
1610
+ if (e?.reason === "graph-updated" || e?.reason === "graph-built") {
1607
1611
  refreshResolvedHandles();
1612
+ }
1608
1613
  return add("runner", "invalidate")(e);
1609
1614
  });
1610
1615
  const off3b = runner.on("stats", (s) => {