@bian-womp/spark-workbench 0.2.36 → 0.2.37
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 +67 -10
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/misc/Inspector.d.ts.map +1 -1
- package/lib/cjs/src/misc/WorkbenchStudio.d.ts.map +1 -1
- package/lib/cjs/src/misc/context/WorkbenchContext.d.ts +4 -1
- 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/runtime/AbstractGraphRunner.d.ts.map +1 -1
- package/lib/esm/index.js +67 -10
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/misc/Inspector.d.ts.map +1 -1
- package/lib/esm/src/misc/WorkbenchStudio.d.ts.map +1 -1
- package/lib/esm/src/misc/context/WorkbenchContext.d.ts +4 -1
- 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/runtime/AbstractGraphRunner.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -343,7 +343,12 @@ class AbstractGraphRunner {
|
|
|
343
343
|
setInput(nodeId, handle, value) {
|
|
344
344
|
if (!this.stagedInputs[nodeId])
|
|
345
345
|
this.stagedInputs[nodeId] = {};
|
|
346
|
-
|
|
346
|
+
if (value === undefined) {
|
|
347
|
+
delete this.stagedInputs[nodeId][handle];
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
this.stagedInputs[nodeId][handle] = value;
|
|
351
|
+
}
|
|
347
352
|
if (this.engine) {
|
|
348
353
|
this.engine.setInput(nodeId, handle, value);
|
|
349
354
|
}
|
|
@@ -361,7 +366,14 @@ class AbstractGraphRunner {
|
|
|
361
366
|
return;
|
|
362
367
|
if (!this.stagedInputs[nodeId])
|
|
363
368
|
this.stagedInputs[nodeId] = {};
|
|
364
|
-
|
|
369
|
+
for (const [handle, value] of Object.entries(inputs)) {
|
|
370
|
+
if (value === undefined) {
|
|
371
|
+
delete this.stagedInputs[nodeId][handle];
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
this.stagedInputs[nodeId][handle] = value;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
365
377
|
if (this.engine) {
|
|
366
378
|
// Running: set all inputs
|
|
367
379
|
this.engine.setInputs(nodeId, inputs);
|
|
@@ -1738,14 +1750,19 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
1738
1750
|
const clearEvents = React.useCallback(() => setEvents([]), []);
|
|
1739
1751
|
const [systemErrors, setSystemErrors] = React.useState([]);
|
|
1740
1752
|
const [registryErrors, setRegistryErrors] = React.useState([]);
|
|
1753
|
+
const [inputValidationErrors, setInputValidationErrors] = React.useState([]);
|
|
1741
1754
|
const clearSystemErrors = React.useCallback(() => setSystemErrors([]), []);
|
|
1742
1755
|
const clearRegistryErrors = React.useCallback(() => setRegistryErrors([]), []);
|
|
1756
|
+
const clearInputValidationErrors = React.useCallback(() => setInputValidationErrors([]), []);
|
|
1743
1757
|
const removeSystemError = React.useCallback((index) => {
|
|
1744
1758
|
setSystemErrors((prev) => prev.filter((_, idx) => idx !== index));
|
|
1745
1759
|
}, []);
|
|
1746
1760
|
const removeRegistryError = React.useCallback((index) => {
|
|
1747
1761
|
setRegistryErrors((prev) => prev.filter((_, idx) => idx !== index));
|
|
1748
1762
|
}, []);
|
|
1763
|
+
const removeInputValidationError = React.useCallback((index) => {
|
|
1764
|
+
setInputValidationErrors((prev) => prev.filter((_, idx) => idx !== index));
|
|
1765
|
+
}, []);
|
|
1749
1766
|
// Fallback progress animation: drive progress to 100% over ~2 minutes
|
|
1750
1767
|
const FALLBACK_TOTAL_MS = 2 * 60 * 1000;
|
|
1751
1768
|
const [fallbackStarts, setFallbackStarts] = React.useState({});
|
|
@@ -1801,7 +1818,8 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
1801
1818
|
const out = {};
|
|
1802
1819
|
// Local: runtimeTypeId is not stored; derive from typed wrapper in outputsMap
|
|
1803
1820
|
for (const n of def.nodes) {
|
|
1804
|
-
const
|
|
1821
|
+
const effectiveHandles = computeEffectiveHandles(n, registry);
|
|
1822
|
+
const outputsDecl = effectiveHandles.outputs;
|
|
1805
1823
|
const handles = Object.keys(outputsDecl);
|
|
1806
1824
|
const cur = {};
|
|
1807
1825
|
for (const h of handles) {
|
|
@@ -1962,10 +1980,13 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
1962
1980
|
const offRunnerValue = runner.on("value", (e) => {
|
|
1963
1981
|
if (e?.io === "input") {
|
|
1964
1982
|
const nodeId = e?.nodeId;
|
|
1983
|
+
const handle = e?.handle;
|
|
1965
1984
|
setNodeStatus((s) => ({
|
|
1966
1985
|
...s,
|
|
1967
1986
|
[nodeId]: { ...s[nodeId], invalidated: true },
|
|
1968
1987
|
}));
|
|
1988
|
+
// Clear validation errors for this input when a valid value is set
|
|
1989
|
+
setInputValidationErrors((prev) => prev.filter((err) => !(err.nodeId === nodeId && err.handle === handle)));
|
|
1969
1990
|
}
|
|
1970
1991
|
return add("runner", "value")(e);
|
|
1971
1992
|
});
|
|
@@ -1974,6 +1995,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
1974
1995
|
const nodeError = e;
|
|
1975
1996
|
const registryError = e;
|
|
1976
1997
|
const systemError = e;
|
|
1998
|
+
const inputValidationError = e;
|
|
1977
1999
|
if (edgeError.kind === "edge-convert") {
|
|
1978
2000
|
const edgeId = edgeError.edgeId;
|
|
1979
2001
|
setEdgeStatus((s) => ({
|
|
@@ -2009,6 +2031,18 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2009
2031
|
return [...prev, registryError];
|
|
2010
2032
|
});
|
|
2011
2033
|
}
|
|
2034
|
+
else if (inputValidationError.kind === "input-validation") {
|
|
2035
|
+
// Track input validation errors for UI display
|
|
2036
|
+
setInputValidationErrors((prev) => {
|
|
2037
|
+
// Avoid duplicates by checking nodeId, handle, and typeId
|
|
2038
|
+
if (prev.some((err) => err.nodeId === inputValidationError.nodeId &&
|
|
2039
|
+
err.handle === inputValidationError.handle &&
|
|
2040
|
+
err.typeId === inputValidationError.typeId)) {
|
|
2041
|
+
return prev;
|
|
2042
|
+
}
|
|
2043
|
+
return [...prev, inputValidationError];
|
|
2044
|
+
});
|
|
2045
|
+
}
|
|
2012
2046
|
else if (systemError.kind === "system") {
|
|
2013
2047
|
// Track custom errors for UI display
|
|
2014
2048
|
setSystemErrors((prev) => {
|
|
@@ -2132,7 +2166,14 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2132
2166
|
}
|
|
2133
2167
|
return add("runner", "stats")(s);
|
|
2134
2168
|
});
|
|
2135
|
-
const offWbGraphChanged = wb.on("graphChanged",
|
|
2169
|
+
const offWbGraphChanged = wb.on("graphChanged", (event) => {
|
|
2170
|
+
// Clear validation errors for removed nodes
|
|
2171
|
+
if (event.change?.type === "removeNode") {
|
|
2172
|
+
const removedNodeId = event.change.nodeId;
|
|
2173
|
+
setInputValidationErrors((prev) => prev.filter((err) => err.nodeId !== removedNodeId));
|
|
2174
|
+
}
|
|
2175
|
+
return add("workbench", "graphChanged")(event);
|
|
2176
|
+
});
|
|
2136
2177
|
const offWbGraphUiChanged = wb.on("graphUiChanged", add("workbench", "graphUiChanged"));
|
|
2137
2178
|
const offWbValidationChanged = wb.on("validationChanged", add("workbench", "validationChanged"));
|
|
2138
2179
|
// Ensure newly added nodes start as invalidated until first evaluation
|
|
@@ -2302,10 +2343,13 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2302
2343
|
clearEvents,
|
|
2303
2344
|
systemErrors,
|
|
2304
2345
|
registryErrors,
|
|
2346
|
+
inputValidationErrors,
|
|
2305
2347
|
clearSystemErrors,
|
|
2306
2348
|
clearRegistryErrors,
|
|
2349
|
+
clearInputValidationErrors,
|
|
2307
2350
|
removeSystemError,
|
|
2308
2351
|
removeRegistryError,
|
|
2352
|
+
removeInputValidationError,
|
|
2309
2353
|
isRunning,
|
|
2310
2354
|
engineKind,
|
|
2311
2355
|
start,
|
|
@@ -2330,10 +2374,13 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2330
2374
|
valuesTick,
|
|
2331
2375
|
systemErrors,
|
|
2332
2376
|
registryErrors,
|
|
2377
|
+
inputValidationErrors,
|
|
2333
2378
|
clearSystemErrors,
|
|
2334
2379
|
clearRegistryErrors,
|
|
2380
|
+
clearInputValidationErrors,
|
|
2335
2381
|
removeSystemError,
|
|
2336
2382
|
removeRegistryError,
|
|
2383
|
+
removeInputValidationError,
|
|
2337
2384
|
inputsMap,
|
|
2338
2385
|
inputDefaultsMap,
|
|
2339
2386
|
outputsMap,
|
|
@@ -2421,7 +2468,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2421
2468
|
return String(value ?? "");
|
|
2422
2469
|
}
|
|
2423
2470
|
};
|
|
2424
|
-
const { registry, def, selectedNodeId, selectedEdgeId, inputsMap, inputDefaultsMap, outputsMap, outputTypesMap, nodeStatus, edgeStatus, validationByNode, validationByEdge, validationGlobal, valuesTick, updateEdgeType, systemErrors, registryErrors, clearSystemErrors, clearRegistryErrors, removeSystemError, removeRegistryError, } = useWorkbenchContext();
|
|
2471
|
+
const { registry, def, selectedNodeId, selectedEdgeId, inputsMap, inputDefaultsMap, outputsMap, outputTypesMap, nodeStatus, edgeStatus, validationByNode, validationByEdge, validationGlobal, valuesTick, updateEdgeType, systemErrors, registryErrors, inputValidationErrors, clearSystemErrors, clearRegistryErrors, clearInputValidationErrors, removeSystemError, removeRegistryError, removeInputValidationError, } = useWorkbenchContext();
|
|
2425
2472
|
const nodeValidationIssues = validationByNode.issues;
|
|
2426
2473
|
const edgeValidationIssues = validationByEdge.issues;
|
|
2427
2474
|
const nodeValidationHandles = validationByNode;
|
|
@@ -2532,7 +2579,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2532
2579
|
}
|
|
2533
2580
|
catch { }
|
|
2534
2581
|
};
|
|
2535
|
-
return (jsxRuntime.jsxs("div", { className: `${widthClass} border-l border-gray-300 p-3 flex flex-col h-full min-h-0 overflow-auto`, children: [jsxRuntime.jsxs("div", { className: "flex-1 overflow-auto", children: [contextPanel && jsxRuntime.jsx("div", { className: "mb-2", children: contextPanel }), systemErrors.length > 0 && (jsxRuntime.jsxs("div", { className: "mb-2 space-y-1", children: [systemErrors.map((err, i) => (jsxRuntime.jsxs("div", { className: "text-xs text-red-700 bg-red-50 border border-red-200 rounded px-2 py-1 flex items-start justify-between gap-2", children: [jsxRuntime.jsxs("div", { className: "flex-1", children: [jsxRuntime.jsx("div", { className: "font-semibold", children: err.code ? `Error ${err.code}` : "Error" }), jsxRuntime.jsx("div", { className: "break-words", children: err.message })] }), jsxRuntime.jsx("button", { className: "text-red-500 hover:text-red-700 text-[10px] px-1", onClick: () => removeSystemError(i), title: "Dismiss", children: jsxRuntime.jsx(react$1.XIcon, { size: 10 }) })] }, i))), systemErrors.length > 1 && (jsxRuntime.jsx("button", { className: "text-xs text-red-600 hover:text-red-800 underline", onClick: clearSystemErrors, children: "Clear all" }))] })), registryErrors.length > 0 && (jsxRuntime.jsxs("div", { className: "mb-2 space-y-1", children: [registryErrors.map((err, i) => (jsxRuntime.jsxs("div", { className: "text-xs text-amber-700 bg-amber-50 border border-amber-200 rounded px-2 py-1 flex items-start justify-between gap-2", children: [jsxRuntime.jsxs("div", { className: "flex-1", children: [jsxRuntime.jsx("div", { className: "font-semibold", children: "Registry Error" }), jsxRuntime.jsx("div", { className: "break-words", children: err.message }), err.attempt && err.maxAttempts && (jsxRuntime.jsxs("div", { className: "text-[10px] text-amber-600 mt-1", children: ["Attempt ", err.attempt, " of ", err.maxAttempts] }))] }), jsxRuntime.jsx("button", { className: "text-amber-500 hover:text-amber-700 text-[10px] px-1", onClick: () => removeRegistryError(i), title: "Dismiss", children: jsxRuntime.jsx(react$1.XIcon, { size: 10 }) })] }, i))), registryErrors.length > 1 && (jsxRuntime.jsx("button", { className: "text-xs text-amber-600 hover:text-amber-800 underline", onClick: clearRegistryErrors, children: "Clear all" }))] })), jsxRuntime.jsx("div", { className: "font-semibold mb-2", children: "Inspector" }), jsxRuntime.jsxs("div", { className: "text-xs text-gray-500 mb-2", children: ["valuesTick: ", valuesTick] }), jsxRuntime.jsx("div", { className: "flex-1", children: !selectedNode && !selectedEdge ? (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "text-gray-500", children: "Select a node or edge." }), globalValidationIssues && globalValidationIssues.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: globalValidationIssues.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}` }), !!m.data?.edgeId && (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) => {
|
|
2582
|
+
return (jsxRuntime.jsxs("div", { className: `${widthClass} border-l border-gray-300 p-3 flex flex-col h-full min-h-0 overflow-auto`, children: [jsxRuntime.jsxs("div", { className: "flex-1 overflow-auto", children: [contextPanel && jsxRuntime.jsx("div", { className: "mb-2", children: contextPanel }), inputValidationErrors.length > 0 && (jsxRuntime.jsxs("div", { className: "mb-2 space-y-1", children: [inputValidationErrors.map((err, i) => (jsxRuntime.jsxs("div", { className: "text-xs text-red-700 bg-red-50 border border-red-200 rounded px-2 py-1 flex items-start justify-between gap-2", children: [jsxRuntime.jsxs("div", { className: "flex-1", children: [jsxRuntime.jsx("div", { className: "font-semibold", children: "Input Validation Error" }), jsxRuntime.jsx("div", { className: "break-words", children: err.message }), jsxRuntime.jsxs("div", { className: "text-[10px] text-red-600 mt-1", children: [err.nodeId, ".", err.handle, " (type: ", err.typeId, ")"] })] }), jsxRuntime.jsx("button", { className: "text-red-500 hover:text-red-700 text-[10px] px-1", onClick: () => removeInputValidationError(i), title: "Dismiss", children: jsxRuntime.jsx(react$1.XIcon, { size: 10 }) })] }, i))), inputValidationErrors.length > 1 && (jsxRuntime.jsx("button", { className: "text-xs text-red-600 hover:text-red-800 underline", onClick: clearInputValidationErrors, children: "Clear all" }))] })), systemErrors.length > 0 && (jsxRuntime.jsxs("div", { className: "mb-2 space-y-1", children: [systemErrors.map((err, i) => (jsxRuntime.jsxs("div", { className: "text-xs text-red-700 bg-red-50 border border-red-200 rounded px-2 py-1 flex items-start justify-between gap-2", children: [jsxRuntime.jsxs("div", { className: "flex-1", children: [jsxRuntime.jsx("div", { className: "font-semibold", children: err.code ? `Error ${err.code}` : "Error" }), jsxRuntime.jsx("div", { className: "break-words", children: err.message })] }), jsxRuntime.jsx("button", { className: "text-red-500 hover:text-red-700 text-[10px] px-1", onClick: () => removeSystemError(i), title: "Dismiss", children: jsxRuntime.jsx(react$1.XIcon, { size: 10 }) })] }, i))), systemErrors.length > 1 && (jsxRuntime.jsx("button", { className: "text-xs text-red-600 hover:text-red-800 underline", onClick: clearSystemErrors, children: "Clear all" }))] })), registryErrors.length > 0 && (jsxRuntime.jsxs("div", { className: "mb-2 space-y-1", children: [registryErrors.map((err, i) => (jsxRuntime.jsxs("div", { className: "text-xs text-amber-700 bg-amber-50 border border-amber-200 rounded px-2 py-1 flex items-start justify-between gap-2", children: [jsxRuntime.jsxs("div", { className: "flex-1", children: [jsxRuntime.jsx("div", { className: "font-semibold", children: "Registry Error" }), jsxRuntime.jsx("div", { className: "break-words", children: err.message }), err.attempt && err.maxAttempts && (jsxRuntime.jsxs("div", { className: "text-[10px] text-amber-600 mt-1", children: ["Attempt ", err.attempt, " of ", err.maxAttempts] }))] }), jsxRuntime.jsx("button", { className: "text-amber-500 hover:text-amber-700 text-[10px] px-1", onClick: () => removeRegistryError(i), title: "Dismiss", children: jsxRuntime.jsx(react$1.XIcon, { size: 10 }) })] }, i))), registryErrors.length > 1 && (jsxRuntime.jsx("button", { className: "text-xs text-amber-600 hover:text-amber-800 underline", onClick: clearRegistryErrors, children: "Clear all" }))] })), jsxRuntime.jsx("div", { className: "font-semibold mb-2", children: "Inspector" }), jsxRuntime.jsxs("div", { className: "text-xs text-gray-500 mb-2", children: ["valuesTick: ", valuesTick] }), jsxRuntime.jsx("div", { className: "flex-1", children: !selectedNode && !selectedEdge ? (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "text-gray-500", children: "Select a node or edge." }), globalValidationIssues && globalValidationIssues.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: globalValidationIssues.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}` }), !!m.data?.edgeId && (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) => {
|
|
2536
2583
|
e.stopPropagation();
|
|
2537
2584
|
deleteEdgeById(m.data?.edgeId);
|
|
2538
2585
|
}, title: "Delete referenced edge", children: "Delete edge" }))] }, i))) })] }))] })) : selectedEdge ? (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "mb-2", children: [jsxRuntime.jsxs("div", { children: ["Edge: ", selectedEdge.id] }), jsxRuntime.jsxs("div", { children: [selectedEdge.source.nodeId, ".", selectedEdge.source.handle, " \u2192", " ", selectedEdge.target.nodeId, ".", selectedEdge.target.handle] }), (() => {
|
|
@@ -2570,13 +2617,20 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2570
2617
|
const current = nodeInputs[h];
|
|
2571
2618
|
const hasValue = current !== undefined && current !== null;
|
|
2572
2619
|
const value = drafts[h] ?? safeToString(typeId, current);
|
|
2573
|
-
const displayValue =
|
|
2620
|
+
const displayValue = value;
|
|
2574
2621
|
const placeholder = hasDefault ? defaultStr : undefined;
|
|
2575
2622
|
const onChangeText = (text) => setDrafts((d) => ({ ...d, [h]: text }));
|
|
2576
2623
|
const commit = () => {
|
|
2577
2624
|
const draft = drafts[h];
|
|
2578
2625
|
if (draft === undefined)
|
|
2579
2626
|
return;
|
|
2627
|
+
// Only commit if draft differs from current value
|
|
2628
|
+
const currentDisplay = safeToString(typeId, current);
|
|
2629
|
+
if (draft === currentDisplay) {
|
|
2630
|
+
// No change, just sync originals without calling setInput
|
|
2631
|
+
setOriginals((o) => ({ ...o, [h]: draft }));
|
|
2632
|
+
return;
|
|
2633
|
+
}
|
|
2580
2634
|
setInput(h, draft);
|
|
2581
2635
|
setOriginals((o) => ({ ...o, [h]: draft }));
|
|
2582
2636
|
};
|
|
@@ -3394,9 +3448,12 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3394
3448
|
state: "local",
|
|
3395
3449
|
});
|
|
3396
3450
|
const selectedNode = def.nodes.find((n) => n.nodeId === selectedNodeId);
|
|
3397
|
-
|
|
3451
|
+
selectedNode
|
|
3398
3452
|
? registry.nodes.get(selectedNode.typeId)
|
|
3399
3453
|
: undefined;
|
|
3454
|
+
const effectiveHandles = selectedNode
|
|
3455
|
+
? computeEffectiveHandles(selectedNode, registry)
|
|
3456
|
+
: { inputs: {}, outputs: {}, inputDefaults: {} };
|
|
3400
3457
|
const [exampleState, setExampleState] = React.useState(example ?? "");
|
|
3401
3458
|
const defaultExamples = React.useMemo(() => [
|
|
3402
3459
|
{
|
|
@@ -3684,7 +3741,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3684
3741
|
const isLinked = def.edges.some((e) => e.target.nodeId === selectedNodeId && e.target.handle === handle);
|
|
3685
3742
|
if (isLinked)
|
|
3686
3743
|
return;
|
|
3687
|
-
const typeId =
|
|
3744
|
+
const typeId = effectiveHandles.inputs[handle];
|
|
3688
3745
|
let value = raw;
|
|
3689
3746
|
const parseArray = (s, map) => {
|
|
3690
3747
|
const str = String(s).trim();
|
|
@@ -3761,7 +3818,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3761
3818
|
}
|
|
3762
3819
|
}
|
|
3763
3820
|
runner.setInput(selectedNodeId, handle, value);
|
|
3764
|
-
}, [selectedNodeId, def.edges,
|
|
3821
|
+
}, [selectedNodeId, def.edges, effectiveHandles, runner]);
|
|
3765
3822
|
const setInput = React.useMemo(() => {
|
|
3766
3823
|
if (overrides?.setInput) {
|
|
3767
3824
|
return overrides.setInput(baseSetInput, {
|