@bian-womp/spark-workbench 0.3.27 → 0.3.29
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 +58 -26
- package/lib/cjs/index.cjs.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/WorkbenchStudio.d.ts.map +1 -1
- package/lib/cjs/src/misc/context/WorkbenchContext.d.ts +2 -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/misc/mapping.d.ts +3 -1
- package/lib/cjs/src/misc/mapping.d.ts.map +1 -1
- package/lib/esm/index.js +59 -27
- package/lib/esm/index.js.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/WorkbenchStudio.d.ts.map +1 -1
- package/lib/esm/src/misc/context/WorkbenchContext.d.ts +2 -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/misc/mapping.d.ts +3 -1
- package/lib/esm/src/misc/mapping.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -2760,11 +2760,11 @@ function toReactFlow(def, positions, sizes, registry, opts) {
|
|
|
2760
2760
|
const EDGE_STYLE_RUNNING = { stroke: "#3b82f6" };
|
|
2761
2761
|
// Build a map of valid handles per node up-front and cache handle data
|
|
2762
2762
|
const validHandleMap = {};
|
|
2763
|
-
const nodeHandlesCache = {};
|
|
2764
2763
|
for (const n of def.nodes) {
|
|
2765
|
-
const
|
|
2766
|
-
|
|
2767
|
-
|
|
2764
|
+
const { inputs, outputs } = opts.handles[n.nodeId] || {
|
|
2765
|
+
inputs: {},
|
|
2766
|
+
outputs: {},
|
|
2767
|
+
};
|
|
2768
2768
|
const inputOrder = Object.keys(inputs).filter((k) => !sparkGraph.isInputPrivate(inputs, k));
|
|
2769
2769
|
const outputOrder = Object.keys(outputs);
|
|
2770
2770
|
validHandleMap[n.nodeId] = {
|
|
@@ -2822,7 +2822,11 @@ function toReactFlow(def, positions, sizes, registry, opts) {
|
|
|
2822
2822
|
});
|
|
2823
2823
|
};
|
|
2824
2824
|
const nodes = def.nodes.map((n) => {
|
|
2825
|
-
const
|
|
2825
|
+
const effectiveHandles = opts.handles[n.nodeId] || {
|
|
2826
|
+
inputs: {},
|
|
2827
|
+
outputs: {},
|
|
2828
|
+
};
|
|
2829
|
+
const { inputs: inputSource, outputs: outputSource } = effectiveHandles;
|
|
2826
2830
|
const overrideSize = opts.getDefaultNodeSize?.(n.typeId);
|
|
2827
2831
|
const customSize = sizes?.[n.nodeId];
|
|
2828
2832
|
const sizeOverrides = customSize
|
|
@@ -2855,6 +2859,7 @@ function toReactFlow(def, positions, sizes, registry, opts) {
|
|
|
2855
2859
|
params: n.params,
|
|
2856
2860
|
inputHandles,
|
|
2857
2861
|
outputHandles,
|
|
2862
|
+
handles: opts.handles[n.nodeId],
|
|
2858
2863
|
inputConnected: Object.fromEntries(inputHandles.map((h) => [
|
|
2859
2864
|
h.id,
|
|
2860
2865
|
!!connectedInputs[n.nodeId]?.has(h.id),
|
|
@@ -2866,7 +2871,10 @@ function toReactFlow(def, positions, sizes, registry, opts) {
|
|
|
2866
2871
|
initialWidth: initialGeom.width,
|
|
2867
2872
|
initialHeight: initialGeom.height,
|
|
2868
2873
|
inputValues: opts.inputs?.[n.nodeId],
|
|
2869
|
-
inputDefaults:
|
|
2874
|
+
inputDefaults: {
|
|
2875
|
+
...opts.handles?.[n.nodeId]?.inputDefaults,
|
|
2876
|
+
...opts.inputDefaults?.[n.nodeId],
|
|
2877
|
+
},
|
|
2870
2878
|
outputValues: opts.outputs?.[n.nodeId],
|
|
2871
2879
|
handleMetadata,
|
|
2872
2880
|
status: opts.nodeStatus?.[n.nodeId],
|
|
@@ -2916,8 +2924,8 @@ function toReactFlow(def, positions, sizes, registry, opts) {
|
|
|
2916
2924
|
: undefined;
|
|
2917
2925
|
const edgeTypeId = e.typeId || undefined;
|
|
2918
2926
|
// Get handle type information from cached handles
|
|
2919
|
-
const sourceHandles =
|
|
2920
|
-
const targetHandles =
|
|
2927
|
+
const sourceHandles = opts.handles[e.source.nodeId];
|
|
2928
|
+
const targetHandles = opts.handles[e.target.nodeId];
|
|
2921
2929
|
const sourceNode = def.nodes.find((n) => n.nodeId === e.source.nodeId);
|
|
2922
2930
|
const targetNode = def.nodes.find((n) => n.nodeId === e.target.nodeId);
|
|
2923
2931
|
const sourceHandleTypeId = sourceHandles?.outputs[e.source.handle]
|
|
@@ -3943,6 +3951,13 @@ function WorkbenchProvider({ wb, runner, overrides, uiVersion, children, }) {
|
|
|
3943
3951
|
offRunnerStatus();
|
|
3944
3952
|
};
|
|
3945
3953
|
}, [runner]);
|
|
3954
|
+
const handlesMap = React.useMemo(() => {
|
|
3955
|
+
const out = {};
|
|
3956
|
+
for (const n of wb.def.nodes) {
|
|
3957
|
+
out[n.nodeId] = computeEffectiveHandles(n, wb.registry);
|
|
3958
|
+
}
|
|
3959
|
+
return out;
|
|
3960
|
+
}, [wb, wb.def, graphTick, wb.registry, registryVersion]);
|
|
3946
3961
|
// Def and IO values
|
|
3947
3962
|
const inputsMap = React.useMemo(() => runner.getInputs(wb.def), [runner, wb, wb.def, valuesTick]);
|
|
3948
3963
|
const inputDefaultsMap = React.useMemo(() => runner.getInputDefaults(wb.def), [runner, wb, wb.def, valuesTick]);
|
|
@@ -3951,8 +3966,7 @@ function WorkbenchProvider({ wb, runner, overrides, uiVersion, children, }) {
|
|
|
3951
3966
|
const out = {};
|
|
3952
3967
|
// Local: runtimeTypeId is not stored; derive from typed wrapper in outputsMap
|
|
3953
3968
|
for (const n of wb.def.nodes) {
|
|
3954
|
-
const
|
|
3955
|
-
const outputsDecl = effectiveHandles.outputs;
|
|
3969
|
+
const outputsDecl = handlesMap[n.nodeId]?.outputs ?? {};
|
|
3956
3970
|
const handles = Object.keys(outputsDecl);
|
|
3957
3971
|
const cur = {};
|
|
3958
3972
|
for (const h of handles) {
|
|
@@ -3965,7 +3979,7 @@ function WorkbenchProvider({ wb, runner, overrides, uiVersion, children, }) {
|
|
|
3965
3979
|
out[n.nodeId] = cur;
|
|
3966
3980
|
}
|
|
3967
3981
|
return out;
|
|
3968
|
-
}, [wb, wb.def, outputsMap,
|
|
3982
|
+
}, [wb, wb.def, outputsMap, handlesMap]);
|
|
3969
3983
|
// Initialize nodes and derive invalidated status from persisted metadata
|
|
3970
3984
|
React.useEffect(() => {
|
|
3971
3985
|
const workbenchRuntimeState = wb.getRuntimeState() ?? { nodes: {} };
|
|
@@ -4738,6 +4752,7 @@ function WorkbenchProvider({ wb, runner, overrides, uiVersion, children, }) {
|
|
|
4738
4752
|
nodeStatus,
|
|
4739
4753
|
edgeStatus,
|
|
4740
4754
|
valuesTick,
|
|
4755
|
+
handlesMap,
|
|
4741
4756
|
inputsMap,
|
|
4742
4757
|
inputDefaultsMap,
|
|
4743
4758
|
outputsMap,
|
|
@@ -4788,6 +4803,7 @@ function WorkbenchProvider({ wb, runner, overrides, uiVersion, children, }) {
|
|
|
4788
4803
|
removeSystemError,
|
|
4789
4804
|
removeRegistryError,
|
|
4790
4805
|
removeInputValidationError,
|
|
4806
|
+
handlesMap,
|
|
4791
4807
|
inputsMap,
|
|
4792
4808
|
inputDefaultsMap,
|
|
4793
4809
|
outputsMap,
|
|
@@ -5298,24 +5314,31 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
5298
5314
|
return String(value ?? "");
|
|
5299
5315
|
}
|
|
5300
5316
|
};
|
|
5301
|
-
const { wb, registryVersion, selectedNodeId, selectedEdgeId, inputsMap, inputDefaultsMap, outputsMap, outputTypesMap, nodeStatus, edgeStatus, validationByNode, validationByEdge, validationGlobal, valuesTick, updateEdgeType, systemErrors, registryErrors, inputValidationErrors, clearSystemErrors, clearRegistryErrors, clearInputValidationErrors, removeSystemError, removeRegistryError, removeInputValidationError, } = useWorkbenchContext();
|
|
5317
|
+
const { wb, registryVersion, selectedNodeId, selectedEdgeId, inputsMap, inputDefaultsMap, outputsMap, outputTypesMap, nodeStatus, edgeStatus, validationByNode, validationByEdge, validationGlobal, valuesTick, updateEdgeType, systemErrors, registryErrors, inputValidationErrors, clearSystemErrors, clearRegistryErrors, clearInputValidationErrors, removeSystemError, removeRegistryError, removeInputValidationError, handlesMap, } = useWorkbenchContext();
|
|
5302
5318
|
const nodeValidationIssues = validationByNode.issues;
|
|
5303
5319
|
const edgeValidationIssues = validationByEdge.issues;
|
|
5304
5320
|
const nodeValidationHandles = validationByNode;
|
|
5305
5321
|
const globalValidationIssues = validationGlobal;
|
|
5306
5322
|
const selectedNode = wb.def.nodes.find((n) => n.nodeId === selectedNodeId);
|
|
5307
5323
|
const selectedEdge = wb.def.edges.find((e) => e.id === selectedEdgeId);
|
|
5308
|
-
// Use
|
|
5324
|
+
// Use precomputed handles map from context
|
|
5309
5325
|
const effectiveHandles = selectedNode
|
|
5310
|
-
?
|
|
5311
|
-
|
|
5326
|
+
? handlesMap[selectedNode.nodeId] ?? {
|
|
5327
|
+
inputs: {},
|
|
5328
|
+
outputs: {},
|
|
5329
|
+
inputDefaults: {},
|
|
5330
|
+
}
|
|
5331
|
+
: { inputs: {}, outputs: {}, inputDefaults: {} };
|
|
5312
5332
|
const inputHandles = Object.entries(effectiveHandles.inputs)
|
|
5313
5333
|
.filter(([k]) => !sparkGraph.isInputPrivate(effectiveHandles.inputs, k))
|
|
5314
5334
|
.map(([k]) => k);
|
|
5315
5335
|
const outputHandles = Object.keys(effectiveHandles.outputs);
|
|
5316
5336
|
const nodeInputsRaw = selectedNodeId ? inputsMap[selectedNodeId] ?? {} : {};
|
|
5317
5337
|
const nodeInputsDefaults = selectedNodeId
|
|
5318
|
-
?
|
|
5338
|
+
? {
|
|
5339
|
+
...effectiveHandles.inputDefaults,
|
|
5340
|
+
...inputDefaultsMap[selectedNodeId],
|
|
5341
|
+
}
|
|
5319
5342
|
: {};
|
|
5320
5343
|
// Keep defaults separate for placeholder use (don't merge into nodeInputs)
|
|
5321
5344
|
const nodeInputs = nodeInputsRaw;
|
|
@@ -5877,7 +5900,7 @@ const SelectionBoundOverlay = ({ selection, rfInstance, viewportTick }) => {
|
|
|
5877
5900
|
|
|
5878
5901
|
const WorkbenchCanvasComponent = React.forwardRef((props, ref) => {
|
|
5879
5902
|
const { showValues, toString, toElement, getDefaultNodeSize, reactFlowProps, } = props;
|
|
5880
|
-
const { wb, inputsMap, inputDefaultsMap, outputsMap, outputTypesMap, valuesTick, nodeStatus, edgeStatus, validationByNode, validationByEdge, uiVersion, registryVersion, runner, overrides, runNode, runFromHere, runMode, } = useWorkbenchContext();
|
|
5903
|
+
const { wb, handlesMap, inputsMap, inputDefaultsMap, outputsMap, outputTypesMap, valuesTick, nodeStatus, edgeStatus, validationByNode, validationByEdge, uiVersion, registryVersion, runner, overrides, runNode, runFromHere, runMode, } = useWorkbenchContext();
|
|
5881
5904
|
const nodeValidation = validationByNode;
|
|
5882
5905
|
const edgeValidation = validationByEdge.errors;
|
|
5883
5906
|
const [historyState, setHistoryState] = React.useState(wb.getHistory());
|
|
@@ -5943,6 +5966,7 @@ const WorkbenchCanvasComponent = React.forwardRef((props, ref) => {
|
|
|
5943
5966
|
};
|
|
5944
5967
|
// Expose imperative API
|
|
5945
5968
|
const rfInstanceRef = React.useRef(null);
|
|
5969
|
+
const containerRef = React.useRef(null);
|
|
5946
5970
|
React.useImperativeHandle(ref, () => ({
|
|
5947
5971
|
fitView: () => {
|
|
5948
5972
|
try {
|
|
@@ -5992,14 +6016,13 @@ const WorkbenchCanvasComponent = React.forwardRef((props, ref) => {
|
|
|
5992
6016
|
});
|
|
5993
6017
|
return () => off();
|
|
5994
6018
|
}, [wb]);
|
|
5995
|
-
// Memoize customData to prevent unnecessary recomputations
|
|
5996
|
-
const customData = React.useMemo(() => wb.getCustomData(), [wb]);
|
|
5997
6019
|
const rfData = React.useMemo(() => {
|
|
5998
6020
|
const out = toReactFlow(wb.def, wb.getPositions(), wb.getSizes(), wb.registry, {
|
|
5999
6021
|
showValues,
|
|
6000
6022
|
inputs: inputsMap,
|
|
6001
6023
|
inputDefaults: inputDefaultsMap,
|
|
6002
6024
|
outputs: outputsMap,
|
|
6025
|
+
handles: handlesMap,
|
|
6003
6026
|
resolveNodeType,
|
|
6004
6027
|
toString,
|
|
6005
6028
|
toElement,
|
|
@@ -6011,7 +6034,7 @@ const WorkbenchCanvasComponent = React.forwardRef((props, ref) => {
|
|
|
6011
6034
|
selectedEdgeIds: new Set(selection.edges),
|
|
6012
6035
|
getDefaultNodeSize,
|
|
6013
6036
|
ui,
|
|
6014
|
-
customData,
|
|
6037
|
+
customData: wb.getCustomData(),
|
|
6015
6038
|
});
|
|
6016
6039
|
// Retain references for unchanged items
|
|
6017
6040
|
const stableNodes = retainStabilityById(prevNodesRef.current, out.nodes, isSameNode);
|
|
@@ -6107,8 +6130,8 @@ const WorkbenchCanvasComponent = React.forwardRef((props, ref) => {
|
|
|
6107
6130
|
inputsMap,
|
|
6108
6131
|
inputDefaultsMap,
|
|
6109
6132
|
outputsMap,
|
|
6133
|
+
handlesMap,
|
|
6110
6134
|
valuesTick,
|
|
6111
|
-
registryVersion,
|
|
6112
6135
|
toString,
|
|
6113
6136
|
toElement,
|
|
6114
6137
|
nodeStatus,
|
|
@@ -6117,7 +6140,6 @@ const WorkbenchCanvasComponent = React.forwardRef((props, ref) => {
|
|
|
6117
6140
|
edgeValidation,
|
|
6118
6141
|
resolveNodeType,
|
|
6119
6142
|
selection,
|
|
6120
|
-
customData,
|
|
6121
6143
|
ui,
|
|
6122
6144
|
getDefaultNodeSize,
|
|
6123
6145
|
wb,
|
|
@@ -6350,8 +6372,14 @@ const WorkbenchCanvasComponent = React.forwardRef((props, ref) => {
|
|
|
6350
6372
|
if (!enableKeyboardShortcuts)
|
|
6351
6373
|
return;
|
|
6352
6374
|
const handleKeyDown = async (e) => {
|
|
6353
|
-
//
|
|
6375
|
+
// Check if target is inside WorkbenchCanvas container
|
|
6354
6376
|
const target = e.target;
|
|
6377
|
+
if (!containerRef.current ||
|
|
6378
|
+
!(containerRef.current.contains(target) ||
|
|
6379
|
+
containerRef.current == target)) {
|
|
6380
|
+
return;
|
|
6381
|
+
}
|
|
6382
|
+
// Ignore if typing in input/textarea
|
|
6355
6383
|
if (target.tagName === "INPUT" ||
|
|
6356
6384
|
target.tagName === "TEXTAREA" ||
|
|
6357
6385
|
target.isContentEditable) {
|
|
@@ -6525,7 +6553,7 @@ const WorkbenchCanvasComponent = React.forwardRef((props, ref) => {
|
|
|
6525
6553
|
return () => off();
|
|
6526
6554
|
}, [wb]);
|
|
6527
6555
|
const { onInit: userOnInit, ...restReactFlowProps } = reactFlowProps || {};
|
|
6528
|
-
return (jsxRuntime.jsxs("div", { className: "w-full h-full relative overflow-hidden", onContextMenu: onContextMenu, children: [jsxRuntime.jsxs(react.ReactFlowProvider, { children: [jsxRuntime.jsxs(react.ReactFlow, { ...restReactFlowProps, nodes: rfData.nodes, edges: rfData.edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, connectionLineComponent: connectionLineRenderer, selectionOnDrag: true, onInit: (inst) => {
|
|
6556
|
+
return (jsxRuntime.jsxs("div", { ref: containerRef, className: "w-full h-full relative overflow-hidden", tabIndex: 0, onContextMenu: onContextMenu, children: [jsxRuntime.jsxs(react.ReactFlowProvider, { children: [jsxRuntime.jsxs(react.ReactFlow, { ...restReactFlowProps, nodes: rfData.nodes, edges: rfData.edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, connectionLineComponent: connectionLineRenderer, selectionOnDrag: true, onInit: (inst) => {
|
|
6529
6557
|
rfInstanceRef.current = inst;
|
|
6530
6558
|
const savedViewport = wb.getViewport();
|
|
6531
6559
|
if (savedViewport) {
|
|
@@ -6547,13 +6575,17 @@ const WorkbenchCanvasComponent = React.forwardRef((props, ref) => {
|
|
|
6547
6575
|
const WorkbenchCanvas = WorkbenchCanvasComponent;
|
|
6548
6576
|
|
|
6549
6577
|
function WorkbenchStudioCanvas({ autoScroll, onAutoScrollChange, example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, overrides, onInit, onChange, }) {
|
|
6550
|
-
const { wb, registryVersion, runner, selectedNodeId, runAutoLayout, runMode, setRunMode, isRunning, } = useWorkbenchContext();
|
|
6578
|
+
const { wb, registryVersion, runner, selectedNodeId, handlesMap, runAutoLayout, runMode, setRunMode, isRunning, } = useWorkbenchContext();
|
|
6551
6579
|
const [transportStatus, setTransportStatus] = React.useState({
|
|
6552
6580
|
state: "local",
|
|
6553
6581
|
});
|
|
6554
6582
|
const selectedNode = wb.def.nodes.find((n) => n.nodeId === selectedNodeId);
|
|
6555
6583
|
const effectiveHandles = selectedNode
|
|
6556
|
-
?
|
|
6584
|
+
? handlesMap[selectedNode.nodeId] ?? {
|
|
6585
|
+
inputs: {},
|
|
6586
|
+
outputs: {},
|
|
6587
|
+
inputDefaults: {},
|
|
6588
|
+
}
|
|
6557
6589
|
: { inputs: {}, outputs: {}, inputDefaults: {} };
|
|
6558
6590
|
const [exampleState, setExampleState] = React.useState(example ?? "");
|
|
6559
6591
|
const isGraphRunning = isRunning();
|