@bian-womp/spark-workbench 0.2.56 → 0.2.57

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 CHANGED
@@ -32,13 +32,6 @@ class DefaultUIExtensionRegistry {
32
32
  }
33
33
  return result;
34
34
  }
35
- registerIconProvider(provider) {
36
- this.iconProvider = provider;
37
- return this;
38
- }
39
- getIconProvider() {
40
- return this.iconProvider;
41
- }
42
35
  // React Flow renderers
43
36
  registerConnectionLineRenderer(renderer) {
44
37
  this.connectionLineRenderer = renderer;
@@ -82,6 +75,35 @@ class DefaultUIExtensionRegistry {
82
75
  getNodeContextMenuRenderer() {
83
76
  return this.nodeContextMenuRenderer;
84
77
  }
78
+ // Layout function overrides
79
+ registerEstimateNodeSize(override) {
80
+ this.estimateNodeSizeOverride = override;
81
+ return this;
82
+ }
83
+ getEstimateNodeSize() {
84
+ return this.estimateNodeSizeOverride;
85
+ }
86
+ registerCreateHandleBounds(override) {
87
+ this.createHandleBoundsOverride = override;
88
+ return this;
89
+ }
90
+ getCreateHandleBounds() {
91
+ return this.createHandleBoundsOverride;
92
+ }
93
+ registerCreateHandleLayout(override) {
94
+ this.createHandleLayoutOverride = override;
95
+ return this;
96
+ }
97
+ getCreateHandleLayout() {
98
+ return this.createHandleLayoutOverride;
99
+ }
100
+ registerLayoutNode(override) {
101
+ this.layoutNodeOverride = override;
102
+ return this;
103
+ }
104
+ getLayoutNode() {
105
+ return this.layoutNodeOverride;
106
+ }
85
107
  }
86
108
 
87
109
  class AbstractWorkbench {
@@ -1442,7 +1464,7 @@ function estimateNodeSize(args) {
1442
1464
  const baseWidth = showValues ? 320 : 240;
1443
1465
  const width = overrides?.width ?? baseWidth;
1444
1466
  const height = overrides?.height ?? NODE_HEADER_HEIGHT_PX + rows * NODE_ROW_HEIGHT_PX;
1445
- return { width, height, inputsCount, outputsCount, rowCount: rows };
1467
+ return { width, height };
1446
1468
  }
1447
1469
  /**
1448
1470
  * Calculate the Y position for handle layout (center of row).
@@ -1499,26 +1521,29 @@ function createHandleLayout(args) {
1499
1521
  y: getHandleLayoutY(args.rowIndex),
1500
1522
  };
1501
1523
  }
1502
- function layoutNode(args) {
1503
- const { node, registry, showValues, overrides } = args;
1524
+ function layoutNode(args, overrides) {
1525
+ const { node, registry, showValues, overrides: sizeOverrides } = args;
1504
1526
  const { inputs, outputs } = computeEffectiveHandles(node, registry);
1505
1527
  const inputOrder = Object.keys(inputs).filter((k) => !sparkGraph.isInputPrivate(inputs, k));
1506
1528
  const outputOrder = Object.keys(outputs);
1507
- const { width, height } = estimateNodeSize({
1529
+ const estimateNodeSizeFn = overrides?.estimateNodeSize ?? estimateNodeSize;
1530
+ const createHandleBoundsFn = overrides?.createHandleBounds ?? createHandleBounds;
1531
+ const createHandleLayoutFn = overrides?.createHandleLayout ?? createHandleLayout;
1532
+ const { width, height } = estimateNodeSizeFn({
1508
1533
  node,
1509
1534
  registry,
1510
1535
  showValues,
1511
- overrides,
1536
+ overrides: sizeOverrides,
1512
1537
  });
1513
1538
  const handles = [
1514
- ...inputOrder.map((id, i) => createHandleBounds({
1539
+ ...inputOrder.map((id, i) => createHandleBoundsFn({
1515
1540
  id,
1516
1541
  type: "target",
1517
1542
  position: react.Position.Left,
1518
1543
  rowIndex: i,
1519
1544
  nodeWidth: width,
1520
1545
  })),
1521
- ...outputOrder.map((id, i) => createHandleBounds({
1546
+ ...outputOrder.map((id, i) => createHandleBoundsFn({
1522
1547
  id,
1523
1548
  type: "source",
1524
1549
  position: react.Position.Right,
@@ -1527,13 +1552,13 @@ function layoutNode(args) {
1527
1552
  })),
1528
1553
  ];
1529
1554
  const handleLayout = [
1530
- ...inputOrder.map((id, i) => createHandleLayout({
1555
+ ...inputOrder.map((id, i) => createHandleLayoutFn({
1531
1556
  id,
1532
1557
  type: "target",
1533
1558
  position: react.Position.Left,
1534
1559
  rowIndex: i,
1535
1560
  })),
1536
- ...outputOrder.map((id, i) => createHandleLayout({
1561
+ ...outputOrder.map((id, i) => createHandleLayoutFn({
1537
1562
  id,
1538
1563
  type: "source",
1539
1564
  position: react.Position.Right,
@@ -1826,15 +1851,32 @@ function toReactFlow(def, positions, registry, opts) {
1826
1851
  // This map is still used later for certain checks; align with valid handles
1827
1852
  const nodeHandleMap = {};
1828
1853
  Object.assign(nodeHandleMap, validHandleMap);
1854
+ // Get layout function overrides from UI registry
1855
+ const layoutNodeOverride = opts.ui?.getLayoutNode() ?? layoutNode;
1856
+ const createHandleBoundsFn = opts.ui?.getCreateHandleBounds() ?? createHandleBounds;
1857
+ const createHandleLayoutFn = opts.ui?.getCreateHandleLayout() ?? createHandleLayout;
1858
+ const estimateNodeSizeFn = opts.ui?.getEstimateNodeSize() ?? estimateNodeSize;
1829
1859
  const nodes = def.nodes.map((n) => {
1830
1860
  const { inputs: inputSource, outputs: outputSource } = computeEffectiveHandles(n, registry);
1831
1861
  const overrideSize = opts.getDefaultNodeSize?.(n.typeId);
1832
- const geom = layoutNode({
1833
- node: n,
1834
- registry,
1835
- showValues: opts.showValues,
1836
- overrides: overrideSize,
1837
- });
1862
+ // If layoutNode is overridden, use it directly; otherwise use default with internal overrides
1863
+ const geom = layoutNodeOverride
1864
+ ? layoutNodeOverride({
1865
+ node: n,
1866
+ registry,
1867
+ showValues: opts.showValues,
1868
+ overrides: overrideSize,
1869
+ })
1870
+ : layoutNode({
1871
+ node: n,
1872
+ registry,
1873
+ showValues: opts.showValues,
1874
+ overrides: overrideSize,
1875
+ }, {
1876
+ estimateNodeSize: estimateNodeSizeFn,
1877
+ createHandleBounds: createHandleBoundsFn,
1878
+ createHandleLayout: createHandleLayoutFn,
1879
+ });
1838
1880
  const inputHandles = geom.inputOrder.map((id) => ({
1839
1881
  id,
1840
1882
  typeId: sparkGraph.getInputTypeId(inputSource, id),
@@ -1853,7 +1895,7 @@ function toReactFlow(def, positions, registry, opts) {
1853
1895
  const extraInputs = Array.from(missingInputsByNode[n.nodeId] || []);
1854
1896
  const extraOutputs = Array.from(missingOutputsByNode[n.nodeId] || []);
1855
1897
  const extraHandleLayoutLeft = extraInputs.map((id, i) => ({
1856
- ...createHandleLayout({
1898
+ ...createHandleLayoutFn({
1857
1899
  id,
1858
1900
  type: "target",
1859
1901
  position: react.Position.Left,
@@ -1862,7 +1904,7 @@ function toReactFlow(def, positions, registry, opts) {
1862
1904
  missing: true,
1863
1905
  }));
1864
1906
  const extraHandleLayoutRight = extraOutputs.map((id, i) => ({
1865
- ...createHandleLayout({
1907
+ ...createHandleLayoutFn({
1866
1908
  id,
1867
1909
  type: "source",
1868
1910
  position: react.Position.Right,
@@ -1876,14 +1918,14 @@ function toReactFlow(def, positions, registry, opts) {
1876
1918
  ...extraHandleLayoutRight,
1877
1919
  ];
1878
1920
  // Precompute handle bounds (including missing) so edges can render immediately
1879
- const missingBoundsLeft = extraInputs.map((id, i) => createHandleBounds({
1921
+ const missingBoundsLeft = extraInputs.map((id, i) => createHandleBoundsFn({
1880
1922
  id,
1881
1923
  type: "target",
1882
1924
  position: react.Position.Left,
1883
1925
  rowIndex: baseLeftCount + i,
1884
1926
  nodeWidth: geom.width,
1885
1927
  }));
1886
- const missingBoundsRight = extraOutputs.map((id, i) => createHandleBounds({
1928
+ const missingBoundsRight = extraOutputs.map((id, i) => createHandleBoundsFn({
1887
1929
  id,
1888
1930
  type: "source",
1889
1931
  position: react.Position.Right,
@@ -3691,6 +3733,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
3691
3733
  selectedNodeIds: new Set(sel.nodes),
3692
3734
  selectedEdgeIds: new Set(sel.edges),
3693
3735
  getDefaultNodeSize,
3736
+ ui,
3694
3737
  });
3695
3738
  // Retain references for unchanged items
3696
3739
  const stableNodes = retainStabilityById(prevNodesRef.current, out.nodes, isSameNode);