@bian-womp/spark-workbench 0.2.3 → 0.2.5
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 +26 -9
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/misc/DefaultContextMenu.d.ts.map +1 -1
- package/lib/cjs/src/misc/WorkbenchCanvas.d.ts +4 -0
- package/lib/cjs/src/misc/WorkbenchCanvas.d.ts.map +1 -1
- package/lib/cjs/src/misc/WorkbenchStudio.d.ts +4 -0
- package/lib/cjs/src/misc/WorkbenchStudio.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 +4 -0
- package/lib/cjs/src/misc/mapping.d.ts.map +1 -1
- package/lib/cjs/src/runtime/AbstractGraphRunner.d.ts +1 -0
- package/lib/cjs/src/runtime/AbstractGraphRunner.d.ts.map +1 -1
- package/lib/cjs/src/runtime/IGraphRunner.d.ts +1 -0
- package/lib/cjs/src/runtime/IGraphRunner.d.ts.map +1 -1
- package/lib/cjs/src/runtime/RemoteGraphRunner.d.ts +1 -0
- package/lib/cjs/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
- package/lib/esm/index.js +27 -10
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/misc/DefaultContextMenu.d.ts.map +1 -1
- package/lib/esm/src/misc/WorkbenchCanvas.d.ts +4 -0
- package/lib/esm/src/misc/WorkbenchCanvas.d.ts.map +1 -1
- package/lib/esm/src/misc/WorkbenchStudio.d.ts +4 -0
- package/lib/esm/src/misc/WorkbenchStudio.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 +4 -0
- package/lib/esm/src/misc/mapping.d.ts.map +1 -1
- package/lib/esm/src/runtime/AbstractGraphRunner.d.ts +1 -0
- package/lib/esm/src/runtime/AbstractGraphRunner.d.ts.map +1 -1
- package/lib/esm/src/runtime/IGraphRunner.d.ts +1 -0
- package/lib/esm/src/runtime/IGraphRunner.d.ts.map +1 -1
- package/lib/esm/src/runtime/RemoteGraphRunner.d.ts +1 -0
- package/lib/esm/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -350,6 +350,9 @@ class AbstractGraphRunner {
|
|
|
350
350
|
this.emit("value", { nodeId, handle, value, io: "input" });
|
|
351
351
|
}
|
|
352
352
|
}
|
|
353
|
+
triggerExternal(nodeId, event) {
|
|
354
|
+
this.engine?.triggerExternal(nodeId, event);
|
|
355
|
+
}
|
|
353
356
|
// Batch update multiple inputs on a node and trigger a single run
|
|
354
357
|
setInputs(nodeId, inputs) {
|
|
355
358
|
if (!inputs)
|
|
@@ -667,6 +670,14 @@ class RemoteGraphRunner extends AbstractGraphRunner {
|
|
|
667
670
|
flush() {
|
|
668
671
|
console.warn("Unsupported operation for remote runner");
|
|
669
672
|
}
|
|
673
|
+
triggerExternal(nodeId, event) {
|
|
674
|
+
this.ensureRemoteRunner().then(async (runner) => {
|
|
675
|
+
try {
|
|
676
|
+
await runner.getEngine().triggerExternal(nodeId, event);
|
|
677
|
+
}
|
|
678
|
+
catch { }
|
|
679
|
+
});
|
|
680
|
+
}
|
|
670
681
|
getOutputs(def) {
|
|
671
682
|
const out = {};
|
|
672
683
|
const cache = this.valueCache;
|
|
@@ -1111,8 +1122,10 @@ function toReactFlow(def, positions, registry, opts) {
|
|
|
1111
1122
|
const HEADER_SIZE = NODE_HEADER_HEIGHT_PX;
|
|
1112
1123
|
const ROW_SIZE = NODE_ROW_HEIGHT_PX;
|
|
1113
1124
|
const maxRows = Math.max(inputHandles.length, outputHandles.length);
|
|
1114
|
-
|
|
1115
|
-
const
|
|
1125
|
+
// Allow external override to dictate initial size
|
|
1126
|
+
const overrideSize = opts.getDefaultNodeSize?.(n.typeId);
|
|
1127
|
+
const initialWidth = overrideSize?.width ?? (opts.showValues ? 320 : 240);
|
|
1128
|
+
const initialHeight = overrideSize?.height ?? HEADER_SIZE + maxRows * ROW_SIZE;
|
|
1116
1129
|
// Precompute handle bounds so edges can render immediately without waiting for measurement
|
|
1117
1130
|
const handles = [
|
|
1118
1131
|
// Inputs on the left as targets
|
|
@@ -1381,8 +1394,8 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1381
1394
|
layers.push(layer);
|
|
1382
1395
|
q.splice(0, q.length, ...next);
|
|
1383
1396
|
}
|
|
1384
|
-
const X =
|
|
1385
|
-
const Y =
|
|
1397
|
+
const X = 720;
|
|
1398
|
+
const Y = 600;
|
|
1386
1399
|
const pos = {};
|
|
1387
1400
|
layers.forEach((layer, layerIndex) => {
|
|
1388
1401
|
layer.forEach((id, itemIndex) => {
|
|
@@ -1392,6 +1405,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1392
1405
|
wb.setPositions(pos);
|
|
1393
1406
|
}, [wb]);
|
|
1394
1407
|
const updateEdgeType = React.useCallback((edgeId, typeId) => wb.updateEdgeType(edgeId, typeId), [wb]);
|
|
1408
|
+
const triggerExternal = React.useCallback((nodeId, event) => runner.triggerExternal(nodeId, event), [runner]);
|
|
1395
1409
|
// Subscribe to runner/workbench events
|
|
1396
1410
|
React.useEffect(() => {
|
|
1397
1411
|
const add = (source, type) => (payload) => setEvents((prev) => {
|
|
@@ -1726,6 +1740,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1726
1740
|
flush,
|
|
1727
1741
|
runAutoLayout,
|
|
1728
1742
|
updateEdgeType,
|
|
1743
|
+
triggerExternal,
|
|
1729
1744
|
}), [
|
|
1730
1745
|
wb,
|
|
1731
1746
|
runner,
|
|
@@ -1753,6 +1768,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1753
1768
|
flush,
|
|
1754
1769
|
runAutoLayout,
|
|
1755
1770
|
wb,
|
|
1771
|
+
runner,
|
|
1756
1772
|
]);
|
|
1757
1773
|
return (jsxRuntime.jsx(WorkbenchContext.Provider, { value: value, children: children }));
|
|
1758
1774
|
}
|
|
@@ -2123,10 +2139,10 @@ function DefaultContextMenu({ open, clientPos, onAdd, onClose, }) {
|
|
|
2123
2139
|
onClose();
|
|
2124
2140
|
};
|
|
2125
2141
|
const renderTree = (tree, path = []) => {
|
|
2126
|
-
const entries = Object.entries(tree
|
|
2142
|
+
const entries = Object.entries(tree?.__children ?? {}).sort((a, b) => a[0].localeCompare(b[0]));
|
|
2127
2143
|
return (jsxRuntime.jsx("div", { children: entries.map(([key, child]) => {
|
|
2128
2144
|
const label = key;
|
|
2129
|
-
const hasChildren = Object.keys(child.__children).length > 0;
|
|
2145
|
+
const hasChildren = !!child?.__children && Object.keys(child.__children).length > 0;
|
|
2130
2146
|
const idKey = [...path, key].join(".");
|
|
2131
2147
|
if (!hasChildren) {
|
|
2132
2148
|
// Leaf: render only the action button, no group header
|
|
@@ -2213,7 +2229,7 @@ function NodeContextMenu({ open, clientPos, nodeId, onClose, }) {
|
|
|
2213
2229
|
}, children: [jsxRuntime.jsxs("div", { className: "px-2 py-1 font-semibold text-gray-700", children: ["Node (", nodeId, ")"] }), jsxRuntime.jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handleDelete, children: "Delete" }), jsxRuntime.jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handleDuplicate, children: "Duplicate" }), canRunPull && (jsxRuntime.jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handleRunPull, children: "Run (pull)" })), jsxRuntime.jsx("div", { className: "h-px bg-gray-200 my-1" }), jsxRuntime.jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handleCopyId, children: "Copy Node ID" })] }));
|
|
2214
2230
|
}
|
|
2215
2231
|
|
|
2216
|
-
const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement }, ref) => {
|
|
2232
|
+
const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, getDefaultNodeSize }, ref) => {
|
|
2217
2233
|
const { wb, registry, inputsMap, outputsMap, valuesTick, nodeStatus, edgeStatus, validationByNode, validationByEdge, } = useWorkbenchContext();
|
|
2218
2234
|
const nodeValidation = validationByNode;
|
|
2219
2235
|
const edgeValidation = validationByEdge.errors;
|
|
@@ -2316,6 +2332,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement }, r
|
|
|
2316
2332
|
edgeValidation,
|
|
2317
2333
|
selectedNodeIds: new Set(sel.nodes),
|
|
2318
2334
|
selectedEdgeIds: new Set(sel.edges),
|
|
2335
|
+
getDefaultNodeSize,
|
|
2319
2336
|
});
|
|
2320
2337
|
// Retain references for unchanged items
|
|
2321
2338
|
const stableNodes = retainStabilityById(prevNodesRef.current, out.nodes, isSameNode);
|
|
@@ -2442,7 +2459,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement }, r
|
|
|
2442
2459
|
const addNodeAt = (typeId, pos) => {
|
|
2443
2460
|
wb.addNode({ typeId, position: pos });
|
|
2444
2461
|
};
|
|
2445
|
-
return (jsxRuntime.jsx("div", { className: "w-full h-full", onContextMenu: onContextMenu, children: jsxRuntime.jsxs(react.ReactFlow, { nodes: throttled.nodes, edges: throttled.edges, nodeTypes: nodeTypes, onlyRenderVisibleElements: true, selectionOnDrag: true, onConnect: onConnect, onEdgesChange: onEdgesChange, onEdgesDelete: onEdgesDelete, onNodesDelete: onNodesDelete, onNodesChange: onNodesChange, deleteKeyCode: ["Backspace", "Delete"],
|
|
2462
|
+
return (jsxRuntime.jsx("div", { className: "w-full h-full", onContextMenu: onContextMenu, children: jsxRuntime.jsx(react.ReactFlowProvider, { children: jsxRuntime.jsxs(react.ReactFlow, { nodes: throttled.nodes, edges: throttled.edges, nodeTypes: nodeTypes, onlyRenderVisibleElements: true, selectionOnDrag: true, onInit: (inst) => (rfInstanceRef.current = inst), onConnect: onConnect, onEdgesChange: onEdgesChange, onEdgesDelete: onEdgesDelete, onNodesDelete: onNodesDelete, onNodesChange: onNodesChange, deleteKeyCode: ["Backspace", "Delete"], proOptions: { hideAttribution: true }, noDragClassName: "wb-nodrag", noWheelClassName: "wb-nowheel", noPanClassName: "wb-nopan", fitView: true, children: [jsxRuntime.jsx(react.Background, { variant: react.BackgroundVariant.Dots, gap: 12, size: 1 }), jsxRuntime.jsx(react.MiniMap, {}), jsxRuntime.jsx(react.Controls, {}), jsxRuntime.jsx(DefaultContextMenu, { open: menuOpen, clientPos: menuPos, onAdd: addNodeAt, onClose: () => setMenuOpen(false) }), jsxRuntime.jsx(NodeContextMenu, { open: nodeMenuOpen, clientPos: nodeMenuPos, nodeId: nodeAtMenu, onClose: () => setNodeMenuOpen(false) })] }) }) }));
|
|
2446
2463
|
});
|
|
2447
2464
|
|
|
2448
2465
|
function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, example, onExampleChange, engine, onEngineChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, overrides, onInit, onChange, }) {
|
|
@@ -2896,7 +2913,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
2896
2913
|
catch (err) {
|
|
2897
2914
|
alert(String(err?.message ?? err));
|
|
2898
2915
|
}
|
|
2899
|
-
}, 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, contextPanel: overrides?.contextPanel })] })] }));
|
|
2916
|
+
}, 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, getDefaultNodeSize: overrides?.getDefaultNodeSize }) }), jsxRuntime.jsx(Inspector, { setInput: setInput, debug: debug, autoScroll: autoScroll, hideWorkbench: hideWorkbench, onAutoScrollChange: onAutoScrollChange, onHideWorkbenchChange: onHideWorkbenchChange, toString: toString, toElement: toElement, contextPanel: overrides?.contextPanel })] })] }));
|
|
2900
2917
|
}
|
|
2901
2918
|
function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, autoScroll, onAutoScrollChange, overrides, onInit, onChange, }) {
|
|
2902
2919
|
const [registry, setRegistry] = React.useState(sparkGraph.createSimpleGraphRegistry());
|