@bian-womp/spark-workbench 0.2.34 → 0.2.35
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 +214 -98
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/misc/DefaultNode.d.ts.map +1 -1
- package/lib/cjs/src/misc/Inspector.d.ts.map +1 -1
- package/lib/cjs/src/misc/WorkbenchCanvas.d.ts.map +1 -1
- package/lib/cjs/src/misc/context/WorkbenchContext.d.ts +1 -0
- package/lib/cjs/src/misc/context/WorkbenchContext.d.ts.map +1 -1
- package/lib/cjs/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/lib/cjs/src/misc/mapping.d.ts +2 -0
- package/lib/cjs/src/misc/mapping.d.ts.map +1 -1
- package/lib/cjs/src/runtime/AbstractGraphRunner.d.ts +4 -2
- package/lib/cjs/src/runtime/AbstractGraphRunner.d.ts.map +1 -1
- package/lib/cjs/src/runtime/IGraphRunner.d.ts +3 -2
- package/lib/cjs/src/runtime/IGraphRunner.d.ts.map +1 -1
- package/lib/cjs/src/runtime/LocalGraphRunner.d.ts +3 -2
- package/lib/cjs/src/runtime/LocalGraphRunner.d.ts.map +1 -1
- package/lib/cjs/src/runtime/RemoteGraphRunner.d.ts +3 -3
- package/lib/cjs/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
- package/lib/esm/index.js +214 -98
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/misc/DefaultNode.d.ts.map +1 -1
- package/lib/esm/src/misc/Inspector.d.ts.map +1 -1
- package/lib/esm/src/misc/WorkbenchCanvas.d.ts.map +1 -1
- package/lib/esm/src/misc/context/WorkbenchContext.d.ts +1 -0
- package/lib/esm/src/misc/context/WorkbenchContext.d.ts.map +1 -1
- package/lib/esm/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/lib/esm/src/misc/mapping.d.ts +2 -0
- package/lib/esm/src/misc/mapping.d.ts.map +1 -1
- package/lib/esm/src/runtime/AbstractGraphRunner.d.ts +4 -2
- package/lib/esm/src/runtime/AbstractGraphRunner.d.ts.map +1 -1
- package/lib/esm/src/runtime/IGraphRunner.d.ts +3 -2
- package/lib/esm/src/runtime/IGraphRunner.d.ts.map +1 -1
- package/lib/esm/src/runtime/LocalGraphRunner.d.ts +3 -2
- package/lib/esm/src/runtime/LocalGraphRunner.d.ts.map +1 -1
- package/lib/esm/src/runtime/RemoteGraphRunner.d.ts +3 -3
- package/lib/esm/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -339,6 +339,7 @@ class AbstractGraphRunner {
|
|
|
339
339
|
if (this.engine) {
|
|
340
340
|
throw new Error("Engine already running. Stop the current engine first.");
|
|
341
341
|
}
|
|
342
|
+
this.currentDef = def;
|
|
342
343
|
}
|
|
343
344
|
setInput(nodeId, handle, value) {
|
|
344
345
|
if (!this.stagedInputs[nodeId])
|
|
@@ -395,6 +396,7 @@ class AbstractGraphRunner {
|
|
|
395
396
|
this.engine = undefined;
|
|
396
397
|
this.runtime?.dispose();
|
|
397
398
|
this.runtime = undefined;
|
|
399
|
+
this.currentDef = undefined;
|
|
398
400
|
if (this.runningKind) {
|
|
399
401
|
this.runningKind = undefined;
|
|
400
402
|
this.emit("status", { running: false, engine: undefined });
|
|
@@ -429,12 +431,14 @@ class LocalGraphRunner extends AbstractGraphRunner {
|
|
|
429
431
|
this.emit("transport", { state: "local" });
|
|
430
432
|
}
|
|
431
433
|
build(def) {
|
|
434
|
+
this.currentDef = def;
|
|
432
435
|
const builder = new sparkGraph.GraphBuilder(this.registry);
|
|
433
436
|
this.runtime = builder.build(def);
|
|
434
437
|
// Signal UI that freshly built graph should be considered invalidated
|
|
435
438
|
this.emit("invalidate", { reason: "graph-built" });
|
|
436
439
|
}
|
|
437
440
|
update(def) {
|
|
441
|
+
this.currentDef = def;
|
|
438
442
|
if (!this.runtime)
|
|
439
443
|
return;
|
|
440
444
|
// Prevent mid-run churn while wiring changes are applied
|
|
@@ -499,11 +503,11 @@ class LocalGraphRunner extends AbstractGraphRunner {
|
|
|
499
503
|
if (eng instanceof sparkGraph.BatchedEngine)
|
|
500
504
|
eng.flush();
|
|
501
505
|
}
|
|
502
|
-
getOutputs(
|
|
506
|
+
getOutputs() {
|
|
503
507
|
const out = {};
|
|
504
|
-
if (!this.runtime)
|
|
508
|
+
if (!this.runtime || !this.currentDef)
|
|
505
509
|
return out;
|
|
506
|
-
for (const n of
|
|
510
|
+
for (const n of this.currentDef.nodes) {
|
|
507
511
|
const desc = this.registry.nodes.get(n.typeId);
|
|
508
512
|
const handles = Object.keys(desc?.outputs ?? {});
|
|
509
513
|
for (const h of handles) {
|
|
@@ -517,15 +521,17 @@ class LocalGraphRunner extends AbstractGraphRunner {
|
|
|
517
521
|
}
|
|
518
522
|
return out;
|
|
519
523
|
}
|
|
520
|
-
getInputs(
|
|
524
|
+
getInputs() {
|
|
521
525
|
const out = {};
|
|
522
|
-
|
|
526
|
+
if (!this.currentDef)
|
|
527
|
+
return out;
|
|
528
|
+
for (const n of this.currentDef.nodes) {
|
|
523
529
|
const staged = this.stagedInputs[n.nodeId] ?? {};
|
|
524
530
|
const runtimeInputs = this.runtime
|
|
525
531
|
? this.runtime.getNodeData?.(n.nodeId)?.inputs ?? {}
|
|
526
532
|
: {};
|
|
527
533
|
// Build inbound handle set for this node from current def
|
|
528
|
-
const inbound = new Set(
|
|
534
|
+
const inbound = new Set(this.currentDef.edges
|
|
529
535
|
.filter((e) => e.target.nodeId === n.nodeId)
|
|
530
536
|
.map((e) => e.target.handle));
|
|
531
537
|
// Merge staged only for non-inbound handles so UI reflects runtime values for wired inputs
|
|
@@ -539,26 +545,22 @@ class LocalGraphRunner extends AbstractGraphRunner {
|
|
|
539
545
|
}
|
|
540
546
|
return out;
|
|
541
547
|
}
|
|
548
|
+
getInputDefaults() {
|
|
549
|
+
const out = {};
|
|
550
|
+
if (!this.currentDef)
|
|
551
|
+
return out;
|
|
552
|
+
for (const n of this.currentDef.nodes) {
|
|
553
|
+
const dynDefaults = n.resolvedHandles?.inputDefaults ?? {};
|
|
554
|
+
if (Object.keys(dynDefaults).length > 0) {
|
|
555
|
+
out[n.nodeId] = dynDefaults;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
return out;
|
|
559
|
+
}
|
|
542
560
|
async snapshotFull() {
|
|
543
561
|
const def = undefined; // UI will supply def/positions on download for local
|
|
544
|
-
const inputs = this.getInputs(
|
|
545
|
-
|
|
546
|
-
nodes: Array.from(this.runtime.getNodeIds()).map((id) => ({
|
|
547
|
-
nodeId: id,
|
|
548
|
-
typeId: "",
|
|
549
|
-
})),
|
|
550
|
-
edges: [],
|
|
551
|
-
}
|
|
552
|
-
: { nodes: [], edges: [] });
|
|
553
|
-
const outputs = this.getOutputs(this.runtime
|
|
554
|
-
? {
|
|
555
|
-
nodes: Array.from(this.runtime.getNodeIds()).map((id) => ({
|
|
556
|
-
nodeId: id,
|
|
557
|
-
typeId: "",
|
|
558
|
-
})),
|
|
559
|
-
edges: [],
|
|
560
|
-
}
|
|
561
|
-
: { nodes: [], edges: [] });
|
|
562
|
+
const inputs = this.getInputs();
|
|
563
|
+
const outputs = this.getOutputs();
|
|
562
564
|
const environment = this.getEnvironment() || {};
|
|
563
565
|
return { def, environment, inputs, outputs };
|
|
564
566
|
}
|
|
@@ -635,8 +637,8 @@ class RemoteGraphRunner extends AbstractGraphRunner {
|
|
|
635
637
|
this.emit("registry", this.registry);
|
|
636
638
|
// Trigger update so validation/UI refreshes using last known graph
|
|
637
639
|
try {
|
|
638
|
-
if (this.
|
|
639
|
-
this.update(this.
|
|
640
|
+
if (this.currentDef)
|
|
641
|
+
this.update(this.currentDef);
|
|
640
642
|
}
|
|
641
643
|
catch {
|
|
642
644
|
console.error("Failed to update graph definition after registry changed");
|
|
@@ -654,12 +656,12 @@ class RemoteGraphRunner extends AbstractGraphRunner {
|
|
|
654
656
|
console.warn("Unsupported operation for remote runner");
|
|
655
657
|
}
|
|
656
658
|
update(def) {
|
|
659
|
+
this.currentDef = def;
|
|
657
660
|
// Remote: forward update; ignore errors (fire-and-forget)
|
|
658
661
|
this.ensureRemoteRunner().then(async (runner) => {
|
|
659
662
|
try {
|
|
660
663
|
await runner.update(def);
|
|
661
664
|
this.emit("invalidate", { reason: "graph-updated" });
|
|
662
|
-
this.lastDef = def;
|
|
663
665
|
}
|
|
664
666
|
catch { }
|
|
665
667
|
});
|
|
@@ -671,7 +673,6 @@ class RemoteGraphRunner extends AbstractGraphRunner {
|
|
|
671
673
|
await runner.build(def);
|
|
672
674
|
// Signal UI after remote build as well
|
|
673
675
|
this.emit("invalidate", { reason: "graph-built" });
|
|
674
|
-
this.lastDef = def;
|
|
675
676
|
// Hydrate current remote inputs/outputs (including defaults) into cache
|
|
676
677
|
try {
|
|
677
678
|
const snap = await runner.snapshot();
|
|
@@ -807,12 +808,12 @@ class RemoteGraphRunner extends AbstractGraphRunner {
|
|
|
807
808
|
// For now, we expose an async helper on RemoteRunner. Keep sync signature per interface.
|
|
808
809
|
return undefined;
|
|
809
810
|
}
|
|
810
|
-
getOutputs(
|
|
811
|
+
getOutputs() {
|
|
811
812
|
const out = {};
|
|
812
813
|
const cache = this.valueCache;
|
|
813
|
-
if (!cache)
|
|
814
|
+
if (!cache || !this.currentDef)
|
|
814
815
|
return out;
|
|
815
|
-
for (const n of
|
|
816
|
+
for (const n of this.currentDef.nodes) {
|
|
816
817
|
const resolved = n.resolvedHandles?.outputs;
|
|
817
818
|
const desc = this.registry.nodes.get(n.typeId);
|
|
818
819
|
const handles = Object.keys(resolved ?? desc?.outputs ?? {});
|
|
@@ -828,17 +829,19 @@ class RemoteGraphRunner extends AbstractGraphRunner {
|
|
|
828
829
|
}
|
|
829
830
|
return out;
|
|
830
831
|
}
|
|
831
|
-
getInputs(
|
|
832
|
+
getInputs() {
|
|
832
833
|
const out = {};
|
|
833
834
|
const cache = this.valueCache;
|
|
834
|
-
|
|
835
|
+
if (!this.currentDef)
|
|
836
|
+
return out;
|
|
837
|
+
for (const n of this.currentDef.nodes) {
|
|
835
838
|
const staged = this.stagedInputs[n.nodeId] ?? {};
|
|
836
839
|
const resolved = n.resolvedHandles?.inputs;
|
|
837
840
|
const desc = this.registry.nodes.get(n.typeId);
|
|
838
841
|
const handles = Object.keys(resolved ?? desc?.inputs ?? {});
|
|
839
842
|
const cur = {};
|
|
840
843
|
// Build inbound handle set for this node to honor wiring precedence
|
|
841
|
-
const inbound = new Set(
|
|
844
|
+
const inbound = new Set(this.currentDef.edges
|
|
842
845
|
.filter((e) => e.target.nodeId === n.nodeId)
|
|
843
846
|
.map((e) => e.target.handle));
|
|
844
847
|
for (const h of handles) {
|
|
@@ -857,6 +860,18 @@ class RemoteGraphRunner extends AbstractGraphRunner {
|
|
|
857
860
|
}
|
|
858
861
|
return out;
|
|
859
862
|
}
|
|
863
|
+
getInputDefaults() {
|
|
864
|
+
const out = {};
|
|
865
|
+
if (!this.currentDef)
|
|
866
|
+
return out;
|
|
867
|
+
for (const n of this.currentDef.nodes) {
|
|
868
|
+
const dynDefaults = n.resolvedHandles?.inputDefaults ?? {};
|
|
869
|
+
if (Object.keys(dynDefaults).length > 0) {
|
|
870
|
+
out[n.nodeId] = dynDefaults;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
return out;
|
|
874
|
+
}
|
|
860
875
|
dispose() {
|
|
861
876
|
super.dispose();
|
|
862
877
|
this.runner = undefined;
|
|
@@ -1608,6 +1623,7 @@ function toReactFlow(def, positions, registry, opts) {
|
|
|
1608
1623
|
renderWidth: initialWidth,
|
|
1609
1624
|
renderHeight: initialHeight,
|
|
1610
1625
|
inputValues: opts.inputs?.[n.nodeId],
|
|
1626
|
+
inputDefaults: opts.inputDefaults?.[n.nodeId],
|
|
1611
1627
|
outputValues: opts.outputs?.[n.nodeId],
|
|
1612
1628
|
status: opts.nodeStatus?.[n.nodeId],
|
|
1613
1629
|
validation: {
|
|
@@ -1773,8 +1789,9 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
1773
1789
|
const valuesTick = versionTick + graphTick + graphUiTick;
|
|
1774
1790
|
// Def and IO values
|
|
1775
1791
|
const def = wb.export();
|
|
1776
|
-
const inputsMap = React.useMemo(() => runner.getInputs(
|
|
1777
|
-
const
|
|
1792
|
+
const inputsMap = React.useMemo(() => runner.getInputs(), [runner, valuesTick]);
|
|
1793
|
+
const inputDefaultsMap = React.useMemo(() => runner.getInputDefaults(), [runner, valuesTick]);
|
|
1794
|
+
const outputsMap = React.useMemo(() => runner.getOutputs(), [runner, valuesTick]);
|
|
1778
1795
|
const outputTypesMap = React.useMemo(() => {
|
|
1779
1796
|
const out = {};
|
|
1780
1797
|
// Local: runtimeTypeId is not stored; derive from typed wrapper in outputsMap
|
|
@@ -1937,7 +1954,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
1937
1954
|
}
|
|
1938
1955
|
catch { }
|
|
1939
1956
|
};
|
|
1940
|
-
const
|
|
1957
|
+
const offRunnerValue = runner.on("value", (e) => {
|
|
1941
1958
|
if (e?.io === "input") {
|
|
1942
1959
|
const nodeId = e?.nodeId;
|
|
1943
1960
|
setNodeStatus((s) => ({
|
|
@@ -1947,7 +1964,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
1947
1964
|
}
|
|
1948
1965
|
return add("runner", "value")(e);
|
|
1949
1966
|
});
|
|
1950
|
-
const
|
|
1967
|
+
const offRunnerError = runner.on("error", (e) => {
|
|
1951
1968
|
const edgeError = e;
|
|
1952
1969
|
const nodeError = e;
|
|
1953
1970
|
const registryError = e;
|
|
@@ -2000,14 +2017,14 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2000
2017
|
}
|
|
2001
2018
|
return add("runner", "error")(e);
|
|
2002
2019
|
});
|
|
2003
|
-
const
|
|
2020
|
+
const offRunnerInvalidate = runner.on("invalidate", (e) => {
|
|
2004
2021
|
// After build/update, pull resolved handles and merge in-place (no graphChanged)
|
|
2005
2022
|
if (e?.reason === "graph-updated" || e?.reason === "graph-built") {
|
|
2006
2023
|
refreshResolvedHandles();
|
|
2007
2024
|
}
|
|
2008
2025
|
return add("runner", "invalidate")(e);
|
|
2009
2026
|
});
|
|
2010
|
-
const
|
|
2027
|
+
const offRunnerStats = runner.on("stats", (s) => {
|
|
2011
2028
|
if (!s)
|
|
2012
2029
|
return;
|
|
2013
2030
|
if (s.kind === "node-start") {
|
|
@@ -2110,9 +2127,11 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2110
2127
|
}
|
|
2111
2128
|
return add("runner", "stats")(s);
|
|
2112
2129
|
});
|
|
2113
|
-
const
|
|
2130
|
+
const offWbGraphChanged = wb.on("graphChanged", add("workbench", "graphChanged"));
|
|
2131
|
+
const offWbGraphUiChanged = wb.on("graphUiChanged", add("workbench", "graphUiChanged"));
|
|
2132
|
+
const offWbValidationChanged = wb.on("validationChanged", add("workbench", "validationChanged"));
|
|
2114
2133
|
// Ensure newly added nodes start as invalidated until first evaluation
|
|
2115
|
-
const
|
|
2134
|
+
const offWbAddNode = wb.on("graphChanged", (e) => {
|
|
2116
2135
|
const change = e.change;
|
|
2117
2136
|
if (change?.type === "addNode" && typeof change.nodeId === "string") {
|
|
2118
2137
|
const id = change.nodeId;
|
|
@@ -2122,17 +2141,14 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2122
2141
|
}));
|
|
2123
2142
|
}
|
|
2124
2143
|
});
|
|
2125
|
-
const
|
|
2126
|
-
const
|
|
2127
|
-
const off5b = wb.on("validationChanged", (r) => setValidation(r));
|
|
2128
|
-
const off6 = wb.on("selectionChanged", (sel) => {
|
|
2144
|
+
const offWbdSetValidation = wb.on("validationChanged", (r) => setValidation(r));
|
|
2145
|
+
const offWbSelectionChanged = wb.on("selectionChanged", (sel) => {
|
|
2129
2146
|
setSelectedNodeId(sel.nodes?.[0]);
|
|
2130
2147
|
setSelectedEdgeId(sel.edges?.[0]);
|
|
2131
2148
|
});
|
|
2132
|
-
const
|
|
2133
|
-
wb.refreshValidation();
|
|
2149
|
+
const offWbError = wb.on("error", add("workbench", "error"));
|
|
2134
2150
|
// Registry updates: swap registry and refresh graph validation/UI
|
|
2135
|
-
const
|
|
2151
|
+
const offRunnerRegistry = runner.on("registry", (newReg) => {
|
|
2136
2152
|
try {
|
|
2137
2153
|
setRegistry(newReg);
|
|
2138
2154
|
wb.setRegistry(newReg);
|
|
@@ -2148,29 +2164,40 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2148
2164
|
console.error("Failed to handle registry changed event");
|
|
2149
2165
|
}
|
|
2150
2166
|
});
|
|
2167
|
+
// Handle transport disconnect: reset runtime status when connection is lost
|
|
2168
|
+
const offRunnerTransport = runner.on("transport", (t) => {
|
|
2169
|
+
if (t.state === "disconnected") {
|
|
2170
|
+
console.info("[WorkbenchContext] Transport disconnected, resetting node status");
|
|
2171
|
+
setNodeStatus({});
|
|
2172
|
+
setEdgeStatus({});
|
|
2173
|
+
setFallbackStarts({});
|
|
2174
|
+
errorRunsRef.current = {};
|
|
2175
|
+
}
|
|
2176
|
+
});
|
|
2177
|
+
wb.refreshValidation();
|
|
2151
2178
|
return () => {
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2179
|
+
offRunnerValue();
|
|
2180
|
+
offRunnerError();
|
|
2181
|
+
offRunnerInvalidate();
|
|
2182
|
+
offRunnerStats();
|
|
2183
|
+
offWbGraphChanged();
|
|
2184
|
+
offWbGraphUiChanged();
|
|
2185
|
+
offWbValidationChanged();
|
|
2186
|
+
offWbError();
|
|
2187
|
+
offWbAddNode();
|
|
2188
|
+
offWbdSetValidation();
|
|
2189
|
+
offWbSelectionChanged();
|
|
2190
|
+
offRunnerRegistry();
|
|
2191
|
+
offRunnerTransport();
|
|
2164
2192
|
};
|
|
2165
2193
|
}, [runner, wb]);
|
|
2166
|
-
//
|
|
2194
|
+
// Keep runner.currentDef in sync with the workbench graph at all times.
|
|
2195
|
+
// When an engine/runtime exists, this also pushes incremental wiring changes into it.
|
|
2167
2196
|
React.useEffect(() => {
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
runner.update(def);
|
|
2171
|
-
}
|
|
2172
|
-
catch { }
|
|
2197
|
+
try {
|
|
2198
|
+
runner.update(def);
|
|
2173
2199
|
}
|
|
2200
|
+
catch { }
|
|
2174
2201
|
}, [runner, def, graphTick]);
|
|
2175
2202
|
const validationByNode = React.useMemo(() => {
|
|
2176
2203
|
const inputs = {};
|
|
@@ -2259,6 +2286,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2259
2286
|
edgeStatus,
|
|
2260
2287
|
valuesTick,
|
|
2261
2288
|
inputsMap,
|
|
2289
|
+
inputDefaultsMap,
|
|
2262
2290
|
outputsMap,
|
|
2263
2291
|
outputTypesMap,
|
|
2264
2292
|
validationByNode,
|
|
@@ -2301,6 +2329,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2301
2329
|
removeSystemError,
|
|
2302
2330
|
removeRegistryError,
|
|
2303
2331
|
inputsMap,
|
|
2332
|
+
inputDefaultsMap,
|
|
2304
2333
|
outputsMap,
|
|
2305
2334
|
validationByNode,
|
|
2306
2335
|
validationByEdge,
|
|
@@ -2386,7 +2415,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2386
2415
|
return String(value ?? "");
|
|
2387
2416
|
}
|
|
2388
2417
|
};
|
|
2389
|
-
const { registry, def, selectedNodeId, selectedEdgeId, inputsMap, outputsMap, outputTypesMap, nodeStatus, edgeStatus, validationByNode, validationByEdge, validationGlobal, valuesTick, updateEdgeType, systemErrors, registryErrors, clearSystemErrors, clearRegistryErrors, removeSystemError, removeRegistryError, } = useWorkbenchContext();
|
|
2418
|
+
const { registry, def, selectedNodeId, selectedEdgeId, inputsMap, inputDefaultsMap, outputsMap, outputTypesMap, nodeStatus, edgeStatus, validationByNode, validationByEdge, validationGlobal, valuesTick, updateEdgeType, systemErrors, registryErrors, clearSystemErrors, clearRegistryErrors, removeSystemError, removeRegistryError, } = useWorkbenchContext();
|
|
2390
2419
|
const nodeValidationIssues = validationByNode.issues;
|
|
2391
2420
|
const edgeValidationIssues = validationByEdge.issues;
|
|
2392
2421
|
const nodeValidationHandles = validationByNode;
|
|
@@ -2401,8 +2430,33 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2401
2430
|
.filter(([k]) => !sparkGraph.isInputPrivate(effectiveHandles.inputs, k))
|
|
2402
2431
|
.map(([k]) => k);
|
|
2403
2432
|
const outputHandles = Object.keys(effectiveHandles.outputs);
|
|
2404
|
-
const
|
|
2433
|
+
const nodeInputsRaw = selectedNodeId ? inputsMap[selectedNodeId] ?? {} : {};
|
|
2434
|
+
const nodeInputsDefaults = selectedNodeId
|
|
2435
|
+
? inputDefaultsMap[selectedNodeId] ?? {}
|
|
2436
|
+
: {};
|
|
2437
|
+
// Keep defaults separate for placeholder use (don't merge into nodeInputs)
|
|
2438
|
+
const nodeInputs = nodeInputsRaw;
|
|
2405
2439
|
const nodeOutputs = selectedNodeId ? outputsMap[selectedNodeId] ?? {} : {};
|
|
2440
|
+
// Helper to truncate long values
|
|
2441
|
+
const truncateValue = (str, maxLen = 50) => {
|
|
2442
|
+
if (str.length <= maxLen)
|
|
2443
|
+
return str;
|
|
2444
|
+
const start = Math.floor(maxLen / 2) - 5;
|
|
2445
|
+
const end = str.length - Math.floor(maxLen / 2) + 5;
|
|
2446
|
+
return `${str.slice(0, start)}...${str.slice(end)}`;
|
|
2447
|
+
};
|
|
2448
|
+
// Helper to copy to clipboard
|
|
2449
|
+
const copyToClipboard = (text) => {
|
|
2450
|
+
navigator.clipboard.writeText(text).catch(() => {
|
|
2451
|
+
// Fallback for older browsers
|
|
2452
|
+
const textarea = document.createElement("textarea");
|
|
2453
|
+
textarea.value = text;
|
|
2454
|
+
document.body.appendChild(textarea);
|
|
2455
|
+
textarea.select();
|
|
2456
|
+
document.execCommand("copy");
|
|
2457
|
+
document.body.removeChild(textarea);
|
|
2458
|
+
});
|
|
2459
|
+
};
|
|
2406
2460
|
const selectedNodeStatus = selectedNodeId
|
|
2407
2461
|
? nodeStatus?.[selectedNodeId]
|
|
2408
2462
|
: undefined;
|
|
@@ -2488,19 +2542,30 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2488
2542
|
}, children: [jsxRuntime.jsx("option", { value: "", children: "(infer from source)" }), Array.from(registry.types.keys()).map((tid) => (jsxRuntime.jsx("option", { value: tid, children: tid }, tid)))] })] })] }), selectedEdgeValidation.length > 0 && (jsxRuntime.jsxs("div", { className: "mt-2 text-xs bg-red-50 border border-red-200 rounded px-2 py-1", children: [jsxRuntime.jsx("div", { className: "font-semibold mb-1", children: "Validation" }), jsxRuntime.jsx("ul", { className: "list-disc ml-4", children: selectedEdgeValidation.map((m, i) => (jsxRuntime.jsxs("li", { className: "flex items-center gap-1", children: [jsxRuntime.jsx(IssueBadge, { level: m.level, size: 24, className: "w-6 h-6" }), jsxRuntime.jsx("span", { children: `${m.code}: ${m.message}` }), jsxRuntime.jsx("button", { className: "ml-2 text-[10px] px-1 py-[2px] border border-red-300 rounded text-red-700 hover:bg-red-50", onClick: (e) => {
|
|
2489
2543
|
e.stopPropagation();
|
|
2490
2544
|
deleteEdgeById(selectedEdge.id);
|
|
2491
|
-
}, title: "Delete this edge", children: "Delete edge" })] }, i))) })] }))] })) : (jsxRuntime.jsxs("div", { children: [selectedNode && (jsxRuntime.jsxs("div", { className: "mb-2", children: [jsxRuntime.jsxs("div", { children: ["Node: ", selectedNode.nodeId] }), jsxRuntime.jsxs("div", { children: ["Type: ", selectedNode.typeId] }), selectedNodeStatus?.activeRuns &&
|
|
2545
|
+
}, title: "Delete this edge", children: "Delete edge" })] }, i))) })] }))] })) : (jsxRuntime.jsxs("div", { children: [selectedNode && (jsxRuntime.jsxs("div", { className: "mb-2", children: [jsxRuntime.jsxs("div", { children: ["Node: ", selectedNode.nodeId] }), jsxRuntime.jsxs("div", { children: ["Type: ", selectedNode.typeId] }), !!selectedNodeStatus?.activeRuns &&
|
|
2492
2546
|
selectedNodeStatus.activeRuns > 0 && (jsxRuntime.jsxs("div", { className: "mt-1 text-xs text-blue-700 bg-blue-50 border border-blue-200 rounded px-2 py-1", children: [jsxRuntime.jsxs("div", { className: "font-semibold", children: ["Running (", selectedNodeStatus.activeRuns, ")"] }), selectedNodeStatus.activeRunIds &&
|
|
2493
2547
|
selectedNodeStatus.activeRunIds.length > 0 ? (jsxRuntime.jsxs("div", { className: "mt-1", children: [jsxRuntime.jsx("div", { className: "text-[10px] text-blue-600", children: "RunIds:" }), jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 mt-1", children: selectedNodeStatus.activeRunIds.map((runId, idx) => (jsxRuntime.jsx("span", { className: "text-[10px] px-1.5 py-0.5 bg-blue-100 border border-blue-300 rounded font-mono", children: runId }, idx))) })] })) : (jsxRuntime.jsx("div", { className: "text-[10px] text-blue-600 mt-1", children: "RunIds not available (some runs may have started without runId)" }))] })), !!selectedNodeStatus?.lastError && (jsxRuntime.jsx("div", { className: "mt-2 text-sm text-red-700 bg-red-50 border border-red-200 rounded px-2 py-1 break-words", children: String(selectedNodeStatus.lastError?.message ??
|
|
2494
2548
|
selectedNodeStatus.lastError) }))] })), jsxRuntime.jsxs("div", { className: "mb-2", children: [jsxRuntime.jsx("div", { className: "font-semibold mb-1", children: "Inputs" }), inputHandles.length === 0 ? (jsxRuntime.jsx("div", { className: "text-gray-500", children: "No inputs" })) : (inputHandles.map((h) => {
|
|
2495
2549
|
const typeId = sparkGraph.getInputTypeId(effectiveHandles.inputs, h);
|
|
2496
2550
|
const isLinked = def.edges.some((e) => e.target.nodeId === selectedNodeId &&
|
|
2497
2551
|
e.target.handle === h);
|
|
2552
|
+
const inbound = new Set(def.edges
|
|
2553
|
+
.filter((e) => e.target.nodeId === selectedNodeId &&
|
|
2554
|
+
e.target.handle === h)
|
|
2555
|
+
.map((e) => e.target.handle));
|
|
2556
|
+
const hasDefault = !inbound.has(h) && nodeInputsDefaults[h] !== undefined;
|
|
2557
|
+
const defaultStr = hasDefault
|
|
2558
|
+
? safeToString(typeId, nodeInputsDefaults[h])
|
|
2559
|
+
: undefined;
|
|
2498
2560
|
const commonProps = {
|
|
2499
2561
|
style: { flex: 1 },
|
|
2500
2562
|
disabled: isLinked,
|
|
2501
2563
|
};
|
|
2502
2564
|
const current = nodeInputs[h];
|
|
2565
|
+
const hasValue = current !== undefined && current !== null;
|
|
2503
2566
|
const value = drafts[h] ?? safeToString(typeId, current);
|
|
2567
|
+
const displayValue = hasValue ? value : "";
|
|
2568
|
+
const placeholder = hasDefault ? defaultStr : undefined;
|
|
2504
2569
|
const onChangeText = (text) => setDrafts((d) => ({ ...d, [h]: text }));
|
|
2505
2570
|
const commit = () => {
|
|
2506
2571
|
const draft = drafts[h];
|
|
@@ -2513,6 +2578,11 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2513
2578
|
const orig = originals[h] ?? safeToString(typeId, current);
|
|
2514
2579
|
setDrafts((d) => ({ ...d, [h]: orig }));
|
|
2515
2580
|
};
|
|
2581
|
+
const clearInput = () => {
|
|
2582
|
+
setInput(h, undefined);
|
|
2583
|
+
setDrafts((d) => ({ ...d, [h]: "" }));
|
|
2584
|
+
setOriginals((o) => ({ ...o, [h]: "" }));
|
|
2585
|
+
};
|
|
2516
2586
|
const isEnum = typeId?.startsWith("enum:");
|
|
2517
2587
|
const inIssues = selectedNodeHandleValidation.inputs.filter((m) => m.handle === h);
|
|
2518
2588
|
const hasValidation = inIssues.length > 0;
|
|
@@ -2520,25 +2590,43 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2520
2590
|
const title = inIssues
|
|
2521
2591
|
.map((v) => `${v.code}: ${v.message}`)
|
|
2522
2592
|
.join("; ");
|
|
2523
|
-
return (jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [jsxRuntime.jsxs("label", { className: "w-32 flex flex-col", children: [jsxRuntime.jsx("span", { children: prettyHandle(h) }), jsxRuntime.jsx("span", { className: "text-gray-500 text-[11px]", children: typeId })] }), hasValidation && (jsxRuntime.jsx(IssueBadge, { level: hasErr ? "error" : "warning", size: 24, className: "ml-1 w-6 h-6", title: title })), isEnum ? (jsxRuntime.jsxs("select", { className: "border border-gray-300 rounded px-2 py-1 focus:outline-none focus:ring-2 focus:ring-blue-500
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2593
|
+
return (jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [jsxRuntime.jsxs("label", { className: "w-32 flex flex-col", children: [jsxRuntime.jsx("span", { children: prettyHandle(h) }), jsxRuntime.jsx("span", { className: "text-gray-500 text-[11px]", children: typeId })] }), hasValidation && (jsxRuntime.jsx(IssueBadge, { level: hasErr ? "error" : "warning", size: 24, className: "ml-1 w-6 h-6", title: title })), isEnum ? (jsxRuntime.jsxs("div", { className: "flex items-center gap-1 flex-1", children: [jsxRuntime.jsxs("select", { className: "border border-gray-300 rounded px-2 py-1 focus:outline-none focus:ring-2 focus:ring-blue-500 flex-1", value: current !== undefined && current !== null
|
|
2594
|
+
? String(current)
|
|
2595
|
+
: "", onChange: (e) => {
|
|
2596
|
+
const val = e.target.value;
|
|
2597
|
+
const raw = val === "" ? undefined : Number(val);
|
|
2598
|
+
setInput(h, raw);
|
|
2599
|
+
// keep drafts/originals in sync with label for display elsewhere
|
|
2600
|
+
const display = safeToString(typeId, raw);
|
|
2601
|
+
setDrafts((d) => ({ ...d, [h]: display }));
|
|
2602
|
+
setOriginals((o) => ({ ...o, [h]: display }));
|
|
2603
|
+
}, ...commonProps, children: [jsxRuntime.jsx("option", { value: "", children: placeholder
|
|
2604
|
+
? `Default: ${placeholder}`
|
|
2605
|
+
: "(select)" }), registry.enums
|
|
2606
|
+
.get(typeId)
|
|
2607
|
+
?.options.map((opt) => (jsxRuntime.jsx("option", { value: String(opt.value), children: opt.label }, opt.value)))] }), hasValue && !isLinked && (jsxRuntime.jsx("button", { className: "flex-shrink-0 p-1 hover:bg-gray-100 rounded text-gray-500 hover:text-gray-700", onClick: clearInput, title: "Clear input value", children: jsxRuntime.jsx(react$1.XCircleIcon, { size: 16 }) }))] })) : isLinked ? (jsxRuntime.jsx("div", { className: "flex items-center gap-1 flex-1", children: jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: (() => {
|
|
2608
|
+
const displayStr = safeToString(typeId, current);
|
|
2609
|
+
const isLong = displayStr.length > 50;
|
|
2610
|
+
const truncated = isLong
|
|
2611
|
+
? truncateValue(displayStr)
|
|
2612
|
+
: displayStr;
|
|
2613
|
+
return (jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [jsxRuntime.jsx("span", { className: "truncate", children: truncated }), isLong && (jsxRuntime.jsx("button", { className: "flex-shrink-0 p-1 hover:bg-gray-100 rounded", onClick: () => copyToClipboard(displayStr), title: "Copy full value", children: jsxRuntime.jsx(react$1.CopyIcon, { size: 14 }) }))] }));
|
|
2614
|
+
})() }) })) : (jsxRuntime.jsxs("div", { className: "flex items-center gap-1 flex-1", children: [jsxRuntime.jsx("input", { className: "border border-gray-300 rounded px-2 py-1 focus:outline-none focus:ring-2 focus:ring-blue-500 flex-1", placeholder: placeholder
|
|
2615
|
+
? `Default: ${placeholder}`
|
|
2616
|
+
: undefined, value: displayValue, onChange: (e) => onChangeText(e.target.value), onBlur: commit, onKeyDown: (e) => {
|
|
2617
|
+
if (e.key === "Enter")
|
|
2618
|
+
commit();
|
|
2619
|
+
if (e.key === "Escape")
|
|
2620
|
+
revert();
|
|
2621
|
+
}, ...commonProps }), hasValue && !isLinked && (jsxRuntime.jsx("button", { className: "flex-shrink-0 p-1 hover:bg-gray-100 rounded text-gray-500 hover:text-gray-700", onClick: clearInput, title: "Clear input value", children: jsxRuntime.jsx(react$1.XCircleIcon, { size: 16 }) }))] }))] }, h));
|
|
2622
|
+
}))] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "font-semibold mb-1", children: "Outputs" }), outputHandles.length === 0 ? (jsxRuntime.jsx("div", { className: "text-gray-500", children: "No outputs" })) : (outputHandles.map((h) => (jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [jsxRuntime.jsxs("label", { className: "w-20 flex flex-col", children: [jsxRuntime.jsx("span", { children: prettyHandle(h) }), jsxRuntime.jsx("span", { className: "text-gray-500 text-[11px]", children: outputTypesMap[selectedNodeId]?.[h] ?? "" })] }), jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: (() => {
|
|
2540
2623
|
const { typeId, value } = resolveOutputDisplay(nodeOutputs[h], effectiveHandles.outputs[h]);
|
|
2541
|
-
|
|
2624
|
+
const displayStr = safeToString(typeId, value);
|
|
2625
|
+
const isLong = displayStr.length > 50;
|
|
2626
|
+
const truncated = isLong
|
|
2627
|
+
? truncateValue(displayStr)
|
|
2628
|
+
: displayStr;
|
|
2629
|
+
return (jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [jsxRuntime.jsx("span", { className: "truncate", children: truncated }), isLong && (jsxRuntime.jsx("button", { className: "flex-shrink-0 p-1 hover:bg-gray-100 rounded", onClick: () => copyToClipboard(displayStr), title: "Copy full value", children: jsxRuntime.jsx(react$1.CopyIcon, { size: 14 }) }))] }));
|
|
2542
2630
|
})() }), (() => {
|
|
2543
2631
|
const outIssues = selectedNodeHandleValidation.outputs.filter((m) => m.handle === h);
|
|
2544
2632
|
if (outIssues.length === 0)
|
|
@@ -2680,7 +2768,7 @@ function DefaultNodeHeader({ id, title, validation, right, showId, onInvalidate,
|
|
|
2680
2768
|
.join("; ") })), showId && jsxRuntime.jsxs("span", { className: "text-[10px] opacity-70", children: ["(", id, ")"] })] })] }));
|
|
2681
2769
|
}
|
|
2682
2770
|
function DefaultNodeContent({ data, isConnectable, }) {
|
|
2683
|
-
const { showValues, inputValues, outputValues, toString } = data;
|
|
2771
|
+
const { showValues, inputValues, inputDefaults, outputValues, toString } = data;
|
|
2684
2772
|
const inputEntries = data.inputHandles ?? [];
|
|
2685
2773
|
const outputEntries = data.outputHandles ?? [];
|
|
2686
2774
|
const status = data.status ?? { activeRuns: 0 };
|
|
@@ -2709,14 +2797,23 @@ function DefaultNodeContent({ data, isConnectable, }) {
|
|
|
2709
2797
|
if (!showValues)
|
|
2710
2798
|
return undefined;
|
|
2711
2799
|
if (kind === "input") {
|
|
2712
|
-
const
|
|
2713
|
-
|
|
2800
|
+
const value = inputValues?.[entry.id];
|
|
2801
|
+
const isDefault = value !== undefined &&
|
|
2802
|
+
inputDefaults?.[entry.id] !== undefined &&
|
|
2803
|
+
JSON.stringify(value) ===
|
|
2804
|
+
JSON.stringify(inputDefaults[entry.id]);
|
|
2805
|
+
const txt = toString(entry.typeId, value);
|
|
2806
|
+
const str = typeof txt === "string" ? txt : String(txt);
|
|
2807
|
+
return { text: str, isDefault };
|
|
2714
2808
|
}
|
|
2715
2809
|
const resolved = resolveOutputDisplay(outputValues?.[entry.id], entry.typeId);
|
|
2716
2810
|
const txt = toString(resolved.typeId, resolved.value);
|
|
2717
|
-
return
|
|
2811
|
+
return {
|
|
2812
|
+
text: typeof txt === "string" ? txt : String(txt),
|
|
2813
|
+
isDefault: false,
|
|
2814
|
+
};
|
|
2718
2815
|
})();
|
|
2719
|
-
return (jsxRuntime.jsxs("span", { className:
|
|
2816
|
+
return (jsxRuntime.jsxs("span", { className: `flex items-center gap-1 w-full ${valueText?.isDefault ? "text-gray-400" : ""}`, children: [kind === "output" ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [valueText !== undefined ? (jsxRuntime.jsx("span", { className: "opacity-60 truncate pl-1", style: { flex: 1, minWidth: 0, maxWidth: "100%" }, children: valueText.text })) : (jsxRuntime.jsx("span", { style: { flex: 1, minWidth: 0, maxWidth: "100%" } })), jsxRuntime.jsx("span", { className: "truncate shrink-0", style: valueText !== undefined ? { maxWidth: "40%" } : {}, children: prettyHandle(handleId) })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "truncate shrink-0", style: valueText !== undefined ? { maxWidth: "40%" } : {}, children: prettyHandle(handleId) }), valueText !== undefined && (jsxRuntime.jsx("span", { className: `truncate pr-1 ${valueText.isDefault ? "text-gray-400" : "opacity-60"}`, style: { flex: 1, minWidth: 0, maxWidth: "100%" }, children: valueText.text }))] })), hasAny && (jsxRuntime.jsx(IssueBadge, { level: hasErr ? "error" : "warning", size: 12, className: "shrink-0", title: title }))] }));
|
|
2720
2817
|
} })] }));
|
|
2721
2818
|
}
|
|
2722
2819
|
|
|
@@ -3013,7 +3110,7 @@ function NodeContextMenu({ open, clientPos, nodeId, onClose, }) {
|
|
|
3013
3110
|
}
|
|
3014
3111
|
|
|
3015
3112
|
const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, getDefaultNodeSize }, ref) => {
|
|
3016
|
-
const { wb, registry, inputsMap, outputsMap, valuesTick, nodeStatus, edgeStatus, validationByNode, validationByEdge, uiVersion, } = useWorkbenchContext();
|
|
3113
|
+
const { wb, registry, inputsMap, inputDefaultsMap, outputsMap, valuesTick, nodeStatus, edgeStatus, validationByNode, validationByEdge, uiVersion, } = useWorkbenchContext();
|
|
3017
3114
|
const nodeValidation = validationByNode;
|
|
3018
3115
|
const edgeValidation = validationByEdge.errors;
|
|
3019
3116
|
// Keep stable references for nodes/edges to avoid unnecessary updates
|
|
@@ -3108,9 +3205,28 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
3108
3205
|
const { nodes, edges } = React.useMemo(() => {
|
|
3109
3206
|
const def = wb.export();
|
|
3110
3207
|
const sel = wb.getSelection();
|
|
3208
|
+
// Merge defaults with inputs for node display (defaults shown in lighter gray)
|
|
3209
|
+
const inputsWithDefaults = {};
|
|
3210
|
+
for (const n of def.nodes) {
|
|
3211
|
+
const nodeInputs = inputsMap[n.nodeId] ?? {};
|
|
3212
|
+
const nodeDefaults = inputDefaultsMap[n.nodeId] ?? {};
|
|
3213
|
+
const inbound = new Set(def.edges
|
|
3214
|
+
.filter((e) => e.target.nodeId === n.nodeId)
|
|
3215
|
+
.map((e) => e.target.handle));
|
|
3216
|
+
const merged = { ...nodeInputs };
|
|
3217
|
+
for (const [h, v] of Object.entries(nodeDefaults)) {
|
|
3218
|
+
if (!inbound.has(h) && merged[h] === undefined) {
|
|
3219
|
+
merged[h] = v;
|
|
3220
|
+
}
|
|
3221
|
+
}
|
|
3222
|
+
if (Object.keys(merged).length > 0) {
|
|
3223
|
+
inputsWithDefaults[n.nodeId] = merged;
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
3111
3226
|
const out = toReactFlow(def, wb.getPositions(), registry, {
|
|
3112
3227
|
showValues,
|
|
3113
|
-
inputs:
|
|
3228
|
+
inputs: inputsWithDefaults,
|
|
3229
|
+
inputDefaults: inputDefaultsMap,
|
|
3114
3230
|
outputs: outputsMap,
|
|
3115
3231
|
resolveNodeType,
|
|
3116
3232
|
toString,
|
|
@@ -3349,7 +3465,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3349
3465
|
const off1 = wb.on("graphChanged", () => {
|
|
3350
3466
|
try {
|
|
3351
3467
|
const cur = wb.export();
|
|
3352
|
-
const inputs = runner.getInputs(
|
|
3468
|
+
const inputs = runner.getInputs();
|
|
3353
3469
|
onChange({ def: cur, inputs });
|
|
3354
3470
|
}
|
|
3355
3471
|
catch { }
|
|
@@ -3357,7 +3473,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3357
3473
|
const off2 = runner.on("value", () => {
|
|
3358
3474
|
try {
|
|
3359
3475
|
const cur = wb.export();
|
|
3360
|
-
const inputs = runner.getInputs(
|
|
3476
|
+
const inputs = runner.getInputs();
|
|
3361
3477
|
onChange({ def: cur, inputs });
|
|
3362
3478
|
}
|
|
3363
3479
|
catch { }
|
|
@@ -3403,7 +3519,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3403
3519
|
const downloadGraph = React.useCallback(() => {
|
|
3404
3520
|
try {
|
|
3405
3521
|
const def = wb.export();
|
|
3406
|
-
const inputs = runner.getInputs(
|
|
3522
|
+
const inputs = runner.getInputs();
|
|
3407
3523
|
const payload = { def, inputs };
|
|
3408
3524
|
const pretty = JSON.stringify(payload, null, 2);
|
|
3409
3525
|
const blob = new Blob([pretty], { type: "application/json" });
|