@bian-womp/spark-workbench 0.1.18 → 0.1.19
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 +30 -16
- 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 +1 -0
- package/lib/cjs/src/misc/WorkbenchStudio.d.ts.map +1 -1
- package/lib/cjs/src/misc/hooks.d.ts.map +1 -1
- package/lib/cjs/src/misc/mapping.d.ts +1 -1
- package/lib/cjs/src/misc/mapping.d.ts.map +1 -1
- package/lib/esm/index.js +31 -17
- 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 +1 -0
- package/lib/esm/src/misc/WorkbenchStudio.d.ts.map +1 -1
- package/lib/esm/src/misc/hooks.d.ts.map +1 -1
- package/lib/esm/src/misc/mapping.d.ts +1 -1
- package/lib/esm/src/misc/mapping.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -659,6 +659,14 @@ function useWorkbenchBridge(wb) {
|
|
|
659
659
|
return;
|
|
660
660
|
if (!params.sourceHandle || !params.targetHandle)
|
|
661
661
|
return;
|
|
662
|
+
// Prevent duplicate edges between the same endpoints
|
|
663
|
+
const def = wb.export();
|
|
664
|
+
const exists = def.edges.some((e) => e.source.nodeId === params.source &&
|
|
665
|
+
e.source.handle === params.sourceHandle &&
|
|
666
|
+
e.target.nodeId === params.target &&
|
|
667
|
+
e.target.handle === params.targetHandle);
|
|
668
|
+
if (exists)
|
|
669
|
+
return;
|
|
662
670
|
wb.connect({
|
|
663
671
|
source: { nodeId: params.source, handle: params.sourceHandle },
|
|
664
672
|
target: { nodeId: params.target, handle: params.targetHandle },
|
|
@@ -916,7 +924,9 @@ function toReactFlow(def, positions, registry, opts) {
|
|
|
916
924
|
const nodeHandleMap = {};
|
|
917
925
|
const nodes = def.nodes.map((n) => {
|
|
918
926
|
const desc = registry.nodes.get(n.typeId);
|
|
919
|
-
const inputHandles = Object.entries(desc?.inputs ?? {})
|
|
927
|
+
const inputHandles = Object.entries(desc?.inputs ?? {})
|
|
928
|
+
.filter(([id]) => !sparkGraph.isInputPrivate(desc?.inputs, id))
|
|
929
|
+
.map(([id, v]) => ({ id, typeId: sparkGraph.getInputTypeId(desc?.inputs, id) }));
|
|
920
930
|
const outputHandles = Object.entries(desc?.outputs ?? {}).map(([id, typeId]) => ({ id, typeId: formatDeclaredTypeSignature(typeId) }));
|
|
921
931
|
nodeHandleMap[n.nodeId] = {
|
|
922
932
|
inputs: new Set(inputHandles.map((h) => h.id)),
|
|
@@ -1110,8 +1120,8 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1110
1120
|
layers.push(layer);
|
|
1111
1121
|
q.splice(0, q.length, ...next);
|
|
1112
1122
|
}
|
|
1113
|
-
const X =
|
|
1114
|
-
const Y =
|
|
1123
|
+
const X = 960;
|
|
1124
|
+
const Y = 480;
|
|
1115
1125
|
const pos = {};
|
|
1116
1126
|
layers.forEach((layer, layerIndex) => {
|
|
1117
1127
|
layer.forEach((id, itemIndex) => {
|
|
@@ -1521,7 +1531,9 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
1521
1531
|
const selectedDesc = selectedNode
|
|
1522
1532
|
? registry.nodes.get(selectedNode.typeId)
|
|
1523
1533
|
: undefined;
|
|
1524
|
-
const inputHandles = Object.
|
|
1534
|
+
const inputHandles = Object.entries(selectedDesc?.inputs ?? {})
|
|
1535
|
+
.filter(([k]) => !sparkGraph.isInputPrivate(selectedDesc?.inputs, k))
|
|
1536
|
+
.map(([k]) => k);
|
|
1525
1537
|
const outputHandles = Object.keys(selectedDesc?.outputs ?? {});
|
|
1526
1538
|
const nodeInputs = selectedNodeId ? inputsMap[selectedNodeId] ?? {} : {};
|
|
1527
1539
|
const nodeOutputs = selectedNodeId ? outputsMap[selectedNodeId] ?? {} : {};
|
|
@@ -1568,7 +1580,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
1568
1580
|
const nextDrafts = { ...drafts };
|
|
1569
1581
|
const nextOriginals = { ...originals };
|
|
1570
1582
|
for (const h of handles) {
|
|
1571
|
-
const typeId = desc?.inputs
|
|
1583
|
+
const typeId = sparkGraph.getInputTypeId(desc?.inputs, h);
|
|
1572
1584
|
const current = nodeInputs[h];
|
|
1573
1585
|
const display = safeToString(typeId, current);
|
|
1574
1586
|
const wasOriginal = originals[h];
|
|
@@ -1588,7 +1600,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
1588
1600
|
const widthClass = debug ? "w-[480px]" : "w-[320px]";
|
|
1589
1601
|
return (jsxRuntime.jsxs("div", { className: `${widthClass} border-l border-gray-300 p-3 flex flex-col h-full min-h-0 overflow-hidden`, children: [jsxRuntime.jsx("div", { className: "font-semibold mb-2", children: "Inspector" }), jsxRuntime.jsx("div", { className: "flex-1 overflow-auto", 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}` })] }, 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] }), jsxRuntime.jsxs("div", { children: ["Type: ", selectedEdge.typeId] })] }), 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}` })] }, 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?.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 ??
|
|
1590
1602
|
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) => {
|
|
1591
|
-
const typeId = (selectedDesc?.inputs
|
|
1603
|
+
const typeId = sparkGraph.getInputTypeId(selectedDesc?.inputs, h);
|
|
1592
1604
|
const isLinked = def.edges.some((e) => e.target.nodeId === selectedNodeId &&
|
|
1593
1605
|
e.target.handle === h);
|
|
1594
1606
|
const commonProps = {
|
|
@@ -1616,7 +1628,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
1616
1628
|
const title = inIssues
|
|
1617
1629
|
.map((v) => `${v.code}: ${v.message}`)
|
|
1618
1630
|
.join("; ");
|
|
1619
|
-
return (jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [jsxRuntime.jsxs("label", { className: "w-32", children: [h, jsxRuntime.jsx("span", { className: "text-gray-500
|
|
1631
|
+
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: 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 w-full", value: current !== undefined && current !== null
|
|
1620
1632
|
? String(current)
|
|
1621
1633
|
: "", onChange: (e) => {
|
|
1622
1634
|
const val = e.target.value;
|
|
@@ -1954,7 +1966,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
1954
1966
|
const selectedDesc = selectedNode
|
|
1955
1967
|
? registry.nodes.get(selectedNode.typeId)
|
|
1956
1968
|
: undefined;
|
|
1957
|
-
const [exampleState, setExampleState] = React.useState(example ?? "
|
|
1969
|
+
const [exampleState, setExampleState] = React.useState(example ?? "");
|
|
1958
1970
|
const defaultExamples = React.useMemo(() => [
|
|
1959
1971
|
{
|
|
1960
1972
|
id: "simple",
|
|
@@ -2111,7 +2123,9 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
2111
2123
|
}, [setRegistry, wb]);
|
|
2112
2124
|
// Ensure initial example is loaded (and sync when example prop changes)
|
|
2113
2125
|
React.useEffect(() => {
|
|
2114
|
-
|
|
2126
|
+
if (!example)
|
|
2127
|
+
return;
|
|
2128
|
+
applyExample(example);
|
|
2115
2129
|
}, [example, wb]);
|
|
2116
2130
|
React.useEffect(() => {
|
|
2117
2131
|
if (!engine)
|
|
@@ -2182,7 +2196,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
2182
2196
|
break;
|
|
2183
2197
|
}
|
|
2184
2198
|
case "base.bool": {
|
|
2185
|
-
value =
|
|
2199
|
+
value = raw === "true" || raw === "1" ? true : false;
|
|
2186
2200
|
break;
|
|
2187
2201
|
}
|
|
2188
2202
|
case "base.string": {
|
|
@@ -2319,14 +2333,14 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
2319
2333
|
return overrides.toElement(baseToElement, { registry });
|
|
2320
2334
|
return baseToElement;
|
|
2321
2335
|
}, [overrides, baseToElement, registry]);
|
|
2322
|
-
return (jsxRuntime.jsxs("div", { className: "w-full h-screen flex flex-col", children: [jsxRuntime.jsxs("div", { className: "p-2 border-b border-gray-300 flex gap-2 items-center", children: [runner.isRunning() ? (jsxRuntime.jsxs("span", { className: "ml-2 text-sm text-green-700", children: ["Running: ", runner.getRunningEngine()] })) : (jsxRuntime.jsx("span", { className: "ml-2 text-sm text-gray-500", children: "Stopped" })), jsxRuntime.jsx("label", { className: "ml-2 text-sm", children: "Example:" }), jsxRuntime.
|
|
2336
|
+
return (jsxRuntime.jsxs("div", { className: "w-full h-screen flex flex-col", children: [jsxRuntime.jsxs("div", { className: "p-2 border-b border-gray-300 flex gap-2 items-center", children: [runner.isRunning() ? (jsxRuntime.jsxs("span", { className: "ml-2 text-sm text-green-700", children: ["Running: ", runner.getRunningEngine()] })) : (jsxRuntime.jsx("span", { className: "ml-2 text-sm text-gray-500", children: "Stopped" })), jsxRuntime.jsx("label", { className: "ml-2 text-sm", children: "Example:" }), jsxRuntime.jsxs("select", { className: "border border-gray-300 rounded px-2 py-1", value: exampleState, onChange: (e) => applyExample(e.target.value), disabled: runner.isRunning(), title: runner.isRunning()
|
|
2323
2337
|
? "Stop engine before switching example"
|
|
2324
|
-
: undefined, children: examples.map((ex) => (jsxRuntime.jsx("option", { value: ex.id, children: ex.label }, ex.id))) }), jsxRuntime.jsx("label", { className: "ml-2 text-sm", children: "Backend:" }), jsxRuntime.jsxs("select", { className: "border border-gray-300 rounded px-2 py-1", value: backendKind, onChange: (e) => onBackendKindChange(e.target.value), disabled: runner.isRunning(), title: runner.isRunning()
|
|
2338
|
+
: undefined, children: [jsxRuntime.jsx("option", { value: "", children: "Select Example\u2026" }), examples.map((ex) => (jsxRuntime.jsx("option", { value: ex.id, children: ex.label }, ex.id)))] }), jsxRuntime.jsx("label", { className: "ml-2 text-sm", children: "Backend:" }), jsxRuntime.jsxs("select", { className: "border border-gray-300 rounded px-2 py-1", value: backendKind, onChange: (e) => onBackendKindChange(e.target.value), disabled: runner.isRunning(), title: runner.isRunning()
|
|
2325
2339
|
? "Stop engine before switching backend"
|
|
2326
2340
|
: undefined, children: [jsxRuntime.jsx("option", { value: "local", children: "Local" }), jsxRuntime.jsx("option", { value: "remote-http", children: "Remote (HTTP)" }), jsxRuntime.jsx("option", { value: "remote-ws", children: "Remote (WebSocket)" })] }), backendKind === "remote-http" && (jsxRuntime.jsx("input", { className: "ml-2 border border-gray-300 rounded px-2 py-1 w-72", placeholder: "http://127.0.0.1:18080", value: httpBaseUrl, onChange: (e) => onHttpBaseUrlChange(e.target.value) })), backendKind === "remote-ws" && (jsxRuntime.jsx("input", { className: "ml-2 border border-gray-300 rounded px-2 py-1 w-72", placeholder: "ws://127.0.0.1:18081", value: wsUrl, onChange: (e) => onWsUrlChange(e.target.value) })), jsxRuntime.jsxs("select", { className: "border border-gray-300 rounded px-2 py-1", value: runner.getRunningEngine() ?? engine ?? "", onChange: (e) => {
|
|
2327
2341
|
const kind = e.target.value || undefined;
|
|
2328
2342
|
onEngineChange?.(kind);
|
|
2329
|
-
}, children: [jsxRuntime.jsx("option", { value: "", children: "Select Engine\u2026" }), jsxRuntime.jsx("option", { value: "push", children: "Push" }), jsxRuntime.jsx("option", { value: "batched", children: "Batched" }), jsxRuntime.jsx("option", { value: "pull", children: "Pull" }), jsxRuntime.jsx("option", { value: "hybrid", children: "Hybrid" }), jsxRuntime.jsx("option", { value: "step", children: "Step" })] }), runner.getRunningEngine() === "step" && (jsxRuntime.jsx("button", { className: "ml-2", onClick: () => runner.step(), disabled: !runner.isRunning(), children: "Step" })), runner.getRunningEngine() === "batched" && (jsxRuntime.jsx("button", { className: "ml-2", onClick: () => runner.flush(), disabled: !runner.isRunning(), children: "Flush" })), runner.isRunning() ? (jsxRuntime.jsx("button", { onClick: () => runner.dispose(), disabled: !runner.isRunning(), children: "Stop" })) : (jsxRuntime.jsx("button", { onClick: () => {
|
|
2343
|
+
}, children: [jsxRuntime.jsx("option", { value: "", children: "Select Engine\u2026" }), jsxRuntime.jsx("option", { value: "push", children: "Push" }), jsxRuntime.jsx("option", { value: "batched", children: "Batched" }), jsxRuntime.jsx("option", { value: "pull", children: "Pull" }), jsxRuntime.jsx("option", { value: "hybrid", children: "Hybrid" }), jsxRuntime.jsx("option", { value: "step", children: "Step" })] }), runner.getRunningEngine() === "step" && (jsxRuntime.jsx("button", { className: "ml-2 border border-gray-300 rounded px-2 py-1.5", onClick: () => runner.step(), disabled: !runner.isRunning(), children: "Step" })), runner.getRunningEngine() === "batched" && (jsxRuntime.jsx("button", { className: "ml-2 border border-gray-300 rounded px-2 py-1.5", onClick: () => runner.flush(), disabled: !runner.isRunning(), children: "Flush" })), runner.isRunning() ? (jsxRuntime.jsx("button", { className: "border border-gray-300 rounded px-2 py-1.5", onClick: () => runner.dispose(), disabled: !runner.isRunning(), children: "Stop" })) : (jsxRuntime.jsx("button", { className: "border border-gray-300 rounded px-2 py-1.5", onClick: () => {
|
|
2330
2344
|
const kind = engine;
|
|
2331
2345
|
if (!kind)
|
|
2332
2346
|
return alert("Select an engine first.");
|
|
@@ -2336,7 +2350,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
2336
2350
|
catch (err) {
|
|
2337
2351
|
alert(String(err?.message ?? err));
|
|
2338
2352
|
}
|
|
2339
|
-
}, disabled: !engine, children: "Start" })), jsxRuntime.jsx("button", { onClick: runAutoLayout, children: "Auto Layout" }), jsxRuntime.jsx("button", { className: "ml-2", onClick: () => canvasRef.current?.fitView?.(), title: "Fit View", children: "Fit View" }), jsxRuntime.jsx("button", { className: "ml-2", onClick: downloadGraph, children: "Download Graph" }), jsxRuntime.jsxs("label", { className: "ml-2 flex items-center gap-1", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: debug, onChange: (e) => onDebugChange(e.target.checked) }), jsxRuntime.jsx("span", { children: "Debug events" })] }), jsxRuntime.jsxs("label", { className: "ml-2 flex items-center gap-1", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: showValues, onChange: (e) => onShowValuesChange(e.target.checked) }), jsxRuntime.jsx("span", { children: "Show values in nodes" })] })] }), jsxRuntime.jsxs("div", { className: "flex flex-1 min-h-0", children: [jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: jsxRuntime.jsx(WorkbenchCanvas, { ref: canvasRef, showValues: showValues, toString: toString, toElement: toElement }) }), jsxRuntime.jsx(Inspector, { setInput: setInput, debug: debug, autoScroll: autoScroll, hideWorkbench: hideWorkbench, onAutoScrollChange: onAutoScrollChange, onHideWorkbenchChange: onHideWorkbenchChange, toString: toString, toElement: toElement })] })] }));
|
|
2353
|
+
}, disabled: !engine, children: "Start" })), jsxRuntime.jsx("button", { className: "border border-gray-300 rounded px-2 py-1.5", onClick: runAutoLayout, children: "Auto Layout" }), jsxRuntime.jsx("button", { className: "ml-2 border border-gray-300 rounded px-2 py-1.5", onClick: () => canvasRef.current?.fitView?.(), title: "Fit View", children: "Fit View" }), jsxRuntime.jsx("button", { className: "ml-2 border border-gray-300 rounded px-2 py-1.5", onClick: downloadGraph, children: "Download Graph" }), jsxRuntime.jsxs("label", { className: "ml-2 flex items-center gap-1", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: debug, onChange: (e) => onDebugChange(e.target.checked) }), jsxRuntime.jsx("span", { children: "Debug events" })] }), jsxRuntime.jsxs("label", { className: "ml-2 flex items-center gap-1", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: showValues, onChange: (e) => onShowValuesChange(e.target.checked) }), jsxRuntime.jsx("span", { children: "Show values in nodes" })] })] }), jsxRuntime.jsxs("div", { className: "flex flex-1 min-h-0", children: [jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: jsxRuntime.jsx(WorkbenchCanvas, { ref: canvasRef, showValues: showValues, toString: toString, toElement: toElement }) }), jsxRuntime.jsx(Inspector, { setInput: setInput, debug: debug, autoScroll: autoScroll, hideWorkbench: hideWorkbench, onAutoScrollChange: onAutoScrollChange, onHideWorkbenchChange: onHideWorkbenchChange, toString: toString, toElement: toElement })] })] }));
|
|
2340
2354
|
}
|
|
2341
2355
|
function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, autoScroll, onAutoScrollChange, overrides, }) {
|
|
2342
2356
|
const [registry, setRegistry] = React.useState(sparkGraph.createSimpleGraphRegistry());
|
|
@@ -2352,9 +2366,9 @@ function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, bac
|
|
|
2352
2366
|
// Allow external UI registration (e.g., node renderers) with access to wb
|
|
2353
2367
|
React.useEffect(() => {
|
|
2354
2368
|
const baseRegisterUI = (_wb) => { };
|
|
2355
|
-
overrides?.registerUI?.(baseRegisterUI, { wb });
|
|
2369
|
+
overrides?.registerUI?.(baseRegisterUI, { wb, wbRunner: runner });
|
|
2356
2370
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2357
|
-
}, [wb, overrides]);
|
|
2371
|
+
}, [wb, runner, overrides]);
|
|
2358
2372
|
return (jsxRuntime.jsx(WorkbenchProvider, { wb: wb, runner: runner, registry: registry, setRegistry: setRegistry, children: jsxRuntime.jsx(WorkbenchStudioCanvas, { setRegistry: setRegistry, autoScroll: autoScroll, onAutoScrollChange: onAutoScrollChange, example: example, onExampleChange: onExampleChange, engine: engine, onEngineChange: onEngineChange, backendKind: backendKind, onBackendKindChange: (v) => {
|
|
2359
2373
|
if (runner.isRunning())
|
|
2360
2374
|
runner.dispose();
|