@bian-womp/spark-workbench 0.2.55 → 0.2.56
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 +107 -49
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/misc/NodeHandles.d.ts +1 -3
- package/lib/cjs/src/misc/NodeHandles.d.ts.map +1 -1
- package/lib/cjs/src/misc/WorkbenchCanvas.d.ts.map +1 -1
- package/lib/cjs/src/misc/constants.d.ts +2 -1
- package/lib/cjs/src/misc/constants.d.ts.map +1 -1
- package/lib/cjs/src/misc/layout.d.ts +46 -0
- package/lib/cjs/src/misc/layout.d.ts.map +1 -1
- package/lib/cjs/src/misc/mapping.d.ts.map +1 -1
- package/lib/esm/index.js +103 -50
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/misc/NodeHandles.d.ts +1 -3
- package/lib/esm/src/misc/NodeHandles.d.ts.map +1 -1
- package/lib/esm/src/misc/WorkbenchCanvas.d.ts.map +1 -1
- package/lib/esm/src/misc/constants.d.ts +2 -1
- package/lib/esm/src/misc/constants.d.ts.map +1 -1
- package/lib/esm/src/misc/layout.d.ts +46 -0
- package/lib/esm/src/misc/layout.d.ts.map +1 -1
- package/lib/esm/src/misc/mapping.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -1414,7 +1414,8 @@ function summarizeDeep(value) {
|
|
|
1414
1414
|
|
|
1415
1415
|
// Shared UI constants for node layout to keep mapping and rendering in sync
|
|
1416
1416
|
const NODE_HEADER_HEIGHT_PX = 24;
|
|
1417
|
-
const NODE_ROW_HEIGHT_PX =
|
|
1417
|
+
const NODE_ROW_HEIGHT_PX = 18;
|
|
1418
|
+
const HANDLE_SIZE_PX = 12;
|
|
1418
1419
|
|
|
1419
1420
|
function computeEffectiveHandles(node, registry) {
|
|
1420
1421
|
const desc = registry.nodes.get(node.typeId);
|
|
@@ -1443,6 +1444,61 @@ function estimateNodeSize(args) {
|
|
|
1443
1444
|
const height = overrides?.height ?? NODE_HEADER_HEIGHT_PX + rows * NODE_ROW_HEIGHT_PX;
|
|
1444
1445
|
return { width, height, inputsCount, outputsCount, rowCount: rows };
|
|
1445
1446
|
}
|
|
1447
|
+
/**
|
|
1448
|
+
* Calculate the Y position for handle layout (center of row).
|
|
1449
|
+
* Used for positioning handles in React Flow.
|
|
1450
|
+
*/
|
|
1451
|
+
function getHandleLayoutY(rowIndex) {
|
|
1452
|
+
return (NODE_HEADER_HEIGHT_PX +
|
|
1453
|
+
rowIndex * NODE_ROW_HEIGHT_PX +
|
|
1454
|
+
NODE_ROW_HEIGHT_PX / 2);
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* Calculate the Y position for handle bounds (top + centering offset).
|
|
1458
|
+
* Used for hit-testing and edge routing.
|
|
1459
|
+
*/
|
|
1460
|
+
function getHandleBoundsY(rowIndex) {
|
|
1461
|
+
return (NODE_HEADER_HEIGHT_PX +
|
|
1462
|
+
rowIndex * NODE_ROW_HEIGHT_PX +
|
|
1463
|
+
(NODE_ROW_HEIGHT_PX - HANDLE_SIZE_PX) / 2 +
|
|
1464
|
+
1);
|
|
1465
|
+
}
|
|
1466
|
+
/**
|
|
1467
|
+
* Calculate the X position for handle bounds based on position and node width.
|
|
1468
|
+
*/
|
|
1469
|
+
function getHandleBoundsX(position, nodeWidth) {
|
|
1470
|
+
if (position === react.Position.Left) {
|
|
1471
|
+
return -HANDLE_SIZE_PX / 2 + 1;
|
|
1472
|
+
}
|
|
1473
|
+
else {
|
|
1474
|
+
return nodeWidth - HANDLE_SIZE_PX / 2 - 1;
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
/**
|
|
1478
|
+
* Create handle bounds object for hit-testing/edge routing.
|
|
1479
|
+
*/
|
|
1480
|
+
function createHandleBounds(args) {
|
|
1481
|
+
return {
|
|
1482
|
+
id: args.id,
|
|
1483
|
+
type: args.type,
|
|
1484
|
+
position: args.position,
|
|
1485
|
+
x: getHandleBoundsX(args.position, args.nodeWidth),
|
|
1486
|
+
y: getHandleBoundsY(args.rowIndex),
|
|
1487
|
+
width: HANDLE_SIZE_PX,
|
|
1488
|
+
height: HANDLE_SIZE_PX,
|
|
1489
|
+
};
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* Create handle layout object for React Flow rendering.
|
|
1493
|
+
*/
|
|
1494
|
+
function createHandleLayout(args) {
|
|
1495
|
+
return {
|
|
1496
|
+
id: args.id,
|
|
1497
|
+
type: args.type,
|
|
1498
|
+
position: args.position,
|
|
1499
|
+
y: getHandleLayoutY(args.rowIndex),
|
|
1500
|
+
};
|
|
1501
|
+
}
|
|
1446
1502
|
function layoutNode(args) {
|
|
1447
1503
|
const { node, registry, showValues, overrides } = args;
|
|
1448
1504
|
const { inputs, outputs } = computeEffectiveHandles(node, registry);
|
|
@@ -1454,40 +1510,34 @@ function layoutNode(args) {
|
|
|
1454
1510
|
showValues,
|
|
1455
1511
|
overrides,
|
|
1456
1512
|
});
|
|
1457
|
-
const HEADER = NODE_HEADER_HEIGHT_PX;
|
|
1458
|
-
const ROW = NODE_ROW_HEIGHT_PX;
|
|
1459
1513
|
const handles = [
|
|
1460
|
-
...inputOrder.map((id, i) => ({
|
|
1514
|
+
...inputOrder.map((id, i) => createHandleBounds({
|
|
1461
1515
|
id,
|
|
1462
1516
|
type: "target",
|
|
1463
1517
|
position: react.Position.Left,
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
width: 1,
|
|
1467
|
-
height: ROW + 2,
|
|
1518
|
+
rowIndex: i,
|
|
1519
|
+
nodeWidth: width,
|
|
1468
1520
|
})),
|
|
1469
|
-
...outputOrder.map((id, i) => ({
|
|
1521
|
+
...outputOrder.map((id, i) => createHandleBounds({
|
|
1470
1522
|
id,
|
|
1471
1523
|
type: "source",
|
|
1472
1524
|
position: react.Position.Right,
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
width: 1,
|
|
1476
|
-
height: ROW + 2,
|
|
1525
|
+
rowIndex: i,
|
|
1526
|
+
nodeWidth: width,
|
|
1477
1527
|
})),
|
|
1478
1528
|
];
|
|
1479
1529
|
const handleLayout = [
|
|
1480
|
-
...inputOrder.map((id, i) => ({
|
|
1530
|
+
...inputOrder.map((id, i) => createHandleLayout({
|
|
1481
1531
|
id,
|
|
1482
1532
|
type: "target",
|
|
1483
1533
|
position: react.Position.Left,
|
|
1484
|
-
|
|
1534
|
+
rowIndex: i,
|
|
1485
1535
|
})),
|
|
1486
|
-
...outputOrder.map((id, i) => ({
|
|
1536
|
+
...outputOrder.map((id, i) => createHandleLayout({
|
|
1487
1537
|
id,
|
|
1488
1538
|
type: "source",
|
|
1489
1539
|
position: react.Position.Right,
|
|
1490
|
-
|
|
1540
|
+
rowIndex: i,
|
|
1491
1541
|
})),
|
|
1492
1542
|
];
|
|
1493
1543
|
return { width, height, inputOrder, outputOrder, handles, handleLayout };
|
|
@@ -1802,20 +1852,22 @@ function toReactFlow(def, positions, registry, opts) {
|
|
|
1802
1852
|
const baseRightCount = geom.outputOrder.length;
|
|
1803
1853
|
const extraInputs = Array.from(missingInputsByNode[n.nodeId] || []);
|
|
1804
1854
|
const extraOutputs = Array.from(missingOutputsByNode[n.nodeId] || []);
|
|
1805
|
-
const HEADER = NODE_HEADER_HEIGHT_PX;
|
|
1806
|
-
const ROW = NODE_ROW_HEIGHT_PX;
|
|
1807
1855
|
const extraHandleLayoutLeft = extraInputs.map((id, i) => ({
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1856
|
+
...createHandleLayout({
|
|
1857
|
+
id,
|
|
1858
|
+
type: "target",
|
|
1859
|
+
position: react.Position.Left,
|
|
1860
|
+
rowIndex: baseLeftCount + i,
|
|
1861
|
+
}),
|
|
1812
1862
|
missing: true,
|
|
1813
1863
|
}));
|
|
1814
1864
|
const extraHandleLayoutRight = extraOutputs.map((id, i) => ({
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1865
|
+
...createHandleLayout({
|
|
1866
|
+
id,
|
|
1867
|
+
type: "source",
|
|
1868
|
+
position: react.Position.Right,
|
|
1869
|
+
rowIndex: baseRightCount + i,
|
|
1870
|
+
}),
|
|
1819
1871
|
missing: true,
|
|
1820
1872
|
}));
|
|
1821
1873
|
const handleLayout = [
|
|
@@ -1824,23 +1876,19 @@ function toReactFlow(def, positions, registry, opts) {
|
|
|
1824
1876
|
...extraHandleLayoutRight,
|
|
1825
1877
|
];
|
|
1826
1878
|
// Precompute handle bounds (including missing) so edges can render immediately
|
|
1827
|
-
const missingBoundsLeft = extraInputs.map((id, i) => ({
|
|
1879
|
+
const missingBoundsLeft = extraInputs.map((id, i) => createHandleBounds({
|
|
1828
1880
|
id,
|
|
1829
1881
|
type: "target",
|
|
1830
1882
|
position: react.Position.Left,
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
width: 1,
|
|
1834
|
-
height: ROW + 2,
|
|
1883
|
+
rowIndex: baseLeftCount + i,
|
|
1884
|
+
nodeWidth: geom.width,
|
|
1835
1885
|
}));
|
|
1836
|
-
const missingBoundsRight = extraOutputs.map((id, i) => ({
|
|
1886
|
+
const missingBoundsRight = extraOutputs.map((id, i) => createHandleBounds({
|
|
1837
1887
|
id,
|
|
1838
1888
|
type: "source",
|
|
1839
1889
|
position: react.Position.Right,
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
width: 1,
|
|
1843
|
-
height: ROW + 2,
|
|
1890
|
+
rowIndex: baseRightCount + i,
|
|
1891
|
+
nodeWidth: geom.width,
|
|
1844
1892
|
}));
|
|
1845
1893
|
const handles = [
|
|
1846
1894
|
...geom.handles,
|
|
@@ -1851,7 +1899,7 @@ function toReactFlow(def, positions, registry, opts) {
|
|
|
1851
1899
|
const baseRows = Math.max(baseLeftCount, baseRightCount);
|
|
1852
1900
|
const newRows = Math.max(baseLeftCount + extraInputs.length, baseRightCount + extraOutputs.length);
|
|
1853
1901
|
const initialWidth = geom.width;
|
|
1854
|
-
const initialHeight = geom.height + Math.max(0, newRows - baseRows) *
|
|
1902
|
+
const initialHeight = geom.height + Math.max(0, newRows - baseRows) * NODE_ROW_HEIGHT_PX;
|
|
1855
1903
|
return {
|
|
1856
1904
|
id: n.nodeId,
|
|
1857
1905
|
data: {
|
|
@@ -1987,7 +2035,7 @@ function getHandleClassName(args) {
|
|
|
1987
2035
|
else {
|
|
1988
2036
|
borderColor = "!border-gray-500 dark:!border-gray-400";
|
|
1989
2037
|
}
|
|
1990
|
-
return cx("!w-3 !h-3 !bg-white !dark:bg-stone-900", borderColor, kind === "output" && "!rounded-none");
|
|
2038
|
+
return cx("!w-3 !h-3 !bg-white/50 !dark:bg-stone-900", borderColor, kind === "output" && "!rounded-none");
|
|
1991
2039
|
}
|
|
1992
2040
|
|
|
1993
2041
|
function generateTimestamp() {
|
|
@@ -3059,7 +3107,7 @@ function NodeHandleItem({ kind, id, type, position, y, isConnectable, className,
|
|
|
3059
3107
|
textOverflow: "ellipsis",
|
|
3060
3108
|
}, children: renderLabel({ kind, id }) }))] }));
|
|
3061
3109
|
}
|
|
3062
|
-
function NodeHandles({ data, isConnectable,
|
|
3110
|
+
function NodeHandles({ data, isConnectable, getClassName, renderLabel, labelClassName = "absolute text-[11px] text-gray-700 dark:text-gray-300 pointer-events-none", }) {
|
|
3063
3111
|
const layout = data.handleLayout ?? [];
|
|
3064
3112
|
const byId = React.useMemo(() => {
|
|
3065
3113
|
const m = new Map();
|
|
@@ -3090,28 +3138,26 @@ function NodeHandles({ data, isConnectable, inputClassName = "!w-2 !h-2 !bg-gray
|
|
|
3090
3138
|
const placed = byId.get(`target:${h.id}`) ?? byId.get(h.id);
|
|
3091
3139
|
const position = placed?.position ?? react.Position.Left;
|
|
3092
3140
|
const y = placed?.y;
|
|
3093
|
-
const cls = getClassName?.({ kind: "input", id: h.id, type: "target" }) ??
|
|
3094
|
-
inputClassName;
|
|
3141
|
+
const cls = getClassName?.({ kind: "input", id: h.id, type: "target" }) ?? "";
|
|
3095
3142
|
return (jsxRuntime.jsx(NodeHandleItem, { kind: "input", id: h.id, type: "target", position: position, y: y, isConnectable: isConnectable, className: cls, labelClassName: labelClassName, renderLabel: renderLabel }, h.id));
|
|
3096
3143
|
}), missingInputs.map((h) => {
|
|
3097
3144
|
const key = `missing-input:${h.id}`;
|
|
3098
3145
|
const position = h.position ?? react.Position.Left;
|
|
3099
3146
|
const y = h.y;
|
|
3100
3147
|
const cls = "!w-3 !h-3 !bg-amber-400 !border-amber-500";
|
|
3101
|
-
return (jsxRuntime.jsx(NodeHandleItem, { kind: "input", id: h.id, type: "target", position: position, y: y, isConnectable: false, className: cls
|
|
3148
|
+
return (jsxRuntime.jsx(NodeHandleItem, { kind: "input", id: h.id, type: "target", position: position, y: y, isConnectable: false, className: `${cls} wb-nodrag wb-nowheel`, labelClassName: labelClassName, renderLabel: renderLabel }, key));
|
|
3102
3149
|
}), (data.outputHandles ?? []).map((h) => {
|
|
3103
3150
|
const placed = byId.get(`source:${h.id}`) ?? byId.get(h.id);
|
|
3104
3151
|
const position = placed?.position ?? react.Position.Right;
|
|
3105
3152
|
const y = placed?.y;
|
|
3106
|
-
const cls = getClassName?.({ kind: "output", id: h.id, type: "source" }) ??
|
|
3107
|
-
|
|
3108
|
-
return (jsxRuntime.jsx(NodeHandleItem, { kind: "output", id: h.id, type: "source", position: position, y: y, isConnectable: isConnectable, className: `${cls} wb-nodrag wb-nowheel`, labelClassName: labelClassName, renderLabel: renderLabel }, h.id));
|
|
3153
|
+
const cls = getClassName?.({ kind: "output", id: h.id, type: "source" }) ?? "";
|
|
3154
|
+
return (jsxRuntime.jsx(NodeHandleItem, { kind: "output", id: h.id, type: "source", position: position, y: y, isConnectable: isConnectable, className: cls, labelClassName: labelClassName, renderLabel: renderLabel }, h.id));
|
|
3109
3155
|
}), missingOutputs.map((h) => {
|
|
3110
3156
|
const key = `missing-output:${h.id}`;
|
|
3111
3157
|
const position = h.position ?? react.Position.Right;
|
|
3112
3158
|
const y = h.y;
|
|
3113
3159
|
const cls = "!w-3 !h-3 !bg-amber-400 !border-amber-500 !rounded-none wb-nodrag wb-nowheel";
|
|
3114
|
-
return (jsxRuntime.jsx(NodeHandleItem, { kind: "output", id: h.id, type: "source", position: position, y: y, isConnectable: false, className: cls
|
|
3160
|
+
return (jsxRuntime.jsx(NodeHandleItem, { kind: "output", id: h.id, type: "source", position: position, y: y, isConnectable: false, className: `${cls} wb-nodrag wb-nowheel`, labelClassName: labelClassName, renderLabel: renderLabel }, key));
|
|
3115
3161
|
})] }));
|
|
3116
3162
|
}
|
|
3117
3163
|
|
|
@@ -3140,7 +3186,7 @@ const DefaultNode = React.memo(function DefaultNode({ id, data, selected, isConn
|
|
|
3140
3186
|
status,
|
|
3141
3187
|
validation,
|
|
3142
3188
|
});
|
|
3143
|
-
return (jsxRuntime.jsxs("div", { className: cx("rounded-lg bg-white/
|
|
3189
|
+
return (jsxRuntime.jsxs("div", { className: cx("rounded-lg bg-white/50 !dark:bg-stone-900", containerBorder), style: {
|
|
3144
3190
|
position: "relative",
|
|
3145
3191
|
minWidth: typeof data.renderWidth === "number" ? data.renderWidth : undefined,
|
|
3146
3192
|
minHeight: typeof data.renderHeight === "number" ? data.renderHeight : undefined,
|
|
@@ -3519,6 +3565,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
3519
3565
|
const { wb, registry, inputsMap, inputDefaultsMap, outputsMap, outputTypesMap, valuesTick, nodeStatus, edgeStatus, validationByNode, validationByEdge, uiVersion, runner, engineKind, } = useWorkbenchContext();
|
|
3520
3566
|
const nodeValidation = validationByNode;
|
|
3521
3567
|
const edgeValidation = validationByEdge.errors;
|
|
3568
|
+
const [registryVersion, setRegistryVersion] = React.useState(0);
|
|
3522
3569
|
// Keep stable references for nodes/edges to avoid unnecessary updates
|
|
3523
3570
|
const prevNodesRef = React.useRef([]);
|
|
3524
3571
|
const prevEdgesRef = React.useRef([]);
|
|
@@ -3789,7 +3836,13 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
3789
3836
|
const onCloseNodeMenu = React.useCallback(() => {
|
|
3790
3837
|
setNodeMenuOpen(false);
|
|
3791
3838
|
}, []);
|
|
3792
|
-
|
|
3839
|
+
React.useEffect(() => {
|
|
3840
|
+
const off = runner.on("registry", () => {
|
|
3841
|
+
setRegistryVersion((v) => v + 1);
|
|
3842
|
+
});
|
|
3843
|
+
return () => off();
|
|
3844
|
+
}, [runner]);
|
|
3845
|
+
const nodeIds = React.useMemo(() => Array.from(registry.nodes.keys()), [registry, registryVersion]);
|
|
3793
3846
|
const defaultContextMenuHandlers = React.useMemo(() => ({
|
|
3794
3847
|
onAddNode: addNodeAt,
|
|
3795
3848
|
onClose: onCloseMenu,
|
|
@@ -4409,11 +4462,16 @@ exports.WorkbenchProvider = WorkbenchProvider;
|
|
|
4409
4462
|
exports.WorkbenchStudio = WorkbenchStudio;
|
|
4410
4463
|
exports.computeEffectiveHandles = computeEffectiveHandles;
|
|
4411
4464
|
exports.countVisibleHandles = countVisibleHandles;
|
|
4465
|
+
exports.createHandleBounds = createHandleBounds;
|
|
4466
|
+
exports.createHandleLayout = createHandleLayout;
|
|
4412
4467
|
exports.download = download;
|
|
4413
4468
|
exports.estimateNodeSize = estimateNodeSize;
|
|
4414
4469
|
exports.formatDataUrlAsLabel = formatDataUrlAsLabel;
|
|
4415
4470
|
exports.formatDeclaredTypeSignature = formatDeclaredTypeSignature;
|
|
4471
|
+
exports.getHandleBoundsX = getHandleBoundsX;
|
|
4472
|
+
exports.getHandleBoundsY = getHandleBoundsY;
|
|
4416
4473
|
exports.getHandleClassName = getHandleClassName;
|
|
4474
|
+
exports.getHandleLayoutY = getHandleLayoutY;
|
|
4417
4475
|
exports.getNodeBorderClassNames = getNodeBorderClassNames;
|
|
4418
4476
|
exports.layoutNode = layoutNode;
|
|
4419
4477
|
exports.preformatValueForDisplay = preformatValueForDisplay;
|