Skip to content

Commit 75d6c35

Browse files
committed
refactor: consolidate routing/dimension magic constants into routing/constants and dimensions
1 parent 6241544 commit 75d6c35

6 files changed

Lines changed: 67 additions & 19 deletions

File tree

src/lib/components/FlowCanvas.svelte

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import { nodeRegistry } from '$lib/nodes';
3737
import { NODE_TYPES } from '$lib/constants/nodeTypes';
3838
import { GRID_SIZE, SNAP_GRID, BACKGROUND_GAP } from '$lib/constants/grid';
39+
import { DEFAULT_NODE_WIDTH, DEFAULT_NODE_HEIGHT } from '$lib/constants/dimensions';
3940
import { shallowEqualArray, shallowEqualRecord } from '$lib/utils/shallowEqual';
4041
import type { NodeInstance, Connection, Annotation } from '$lib/nodes/types';
4142
import type { EventInstance } from '$lib/events/types';
@@ -274,8 +275,8 @@
274275
if (portIndex >= ports.length) return null;
275276
276277
const rotation = (nodeData.params?.['_rotation'] as number) || 0;
277-
const width = node.measured?.width ?? node.width ?? 80;
278-
const height = node.measured?.height ?? node.height ?? 40;
278+
const width = node.measured?.width ?? node.width ?? DEFAULT_NODE_WIDTH;
279+
const height = node.measured?.height ?? node.height ?? DEFAULT_NODE_HEIGHT;
279280
280281
// Calculate port offset from center based on rotation
281282
const portCount = ports.length;
@@ -739,8 +740,8 @@
739740
changedNodeIds.add(node.id);
740741
741742
// Incrementally update grid obstacle for this node
742-
const width = node.measured?.width ?? node.width ?? 80;
743-
const height = node.measured?.height ?? node.height ?? 40;
743+
const width = node.measured?.width ?? node.width ?? DEFAULT_NODE_WIDTH;
744+
const height = node.measured?.height ?? node.height ?? DEFAULT_NODE_HEIGHT;
744745
routingStore.updateNodeBounds(node.id, {
745746
x: snappedX - width / 2,
746747
y: snappedY - height / 2,

src/lib/components/edges/OrthogonalEdge.svelte

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import { routingStore, type PortInfo } from '$lib/stores/routing';
2525
import { historyStore } from '$lib/stores/history';
2626
import { screenToFlow } from '$lib/utils/viewUtils';
27-
import { GRID_SIZE } from '$lib/routing/constants';
27+
import { GRID_SIZE, EDGE_SOURCE_OFFSET, EDGE_TARGET_OFFSET, EDGE_CORNER_RADIUS } from '$lib/routing/constants';
2828
import type { RouteResult, Direction } from '$lib/routing';
2929
import type { Waypoint } from '$lib/types/nodes';
3030
@@ -201,8 +201,8 @@
201201
// Offset to start/end path at handle tips (not centers)
202202
// Source: small inset from handle edge
203203
// Target: larger offset to leave room for arrowhead
204-
const sourceOffset = 0.5;
205-
const targetOffset = 4.5;
204+
const sourceOffset = EDGE_SOURCE_OFFSET;
205+
const targetOffset = EDGE_TARGET_OFFSET;
206206
207207
// Adjusted source position based on handle direction
208208
const adjustedSource = $derived(() => {
@@ -226,8 +226,7 @@
226226
return { x, y };
227227
});
228228
229-
// Corner radius for bends (0.5G = 5px)
230-
const CORNER_RADIUS = 5;
229+
const CORNER_RADIUS = EDGE_CORNER_RADIUS;
231230
232231
/**
233232
* Build SVG path with rounded corners using quadratic bezier curves

src/lib/constants/dimensions.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ export const NODE = {
1919
borderWidth: 1
2020
} as const;
2121

22+
/**
23+
* Fallback node width/height used when xyflow has not yet measured a node.
24+
* Re-exported so callers don't inline the magic numbers.
25+
*/
26+
export const DEFAULT_NODE_WIDTH = NODE.baseWidth;
27+
export const DEFAULT_NODE_HEIGHT = NODE.baseHeight;
28+
2229
/** Handle (port connector) dimensions */
2330
export const HANDLE = {
2431
/** Width of horizontal handles (rotation 0, 2): 1 grid unit */

src/lib/routing/constants.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,25 @@ export const HANDLE_OFFSET = G.unit / 2;
2121

2222
/** Arrow head length - stub should start within arrowhead (0.25 grid units = 2.5px) */
2323
export const ARROW_INSET = G.unit / 4;
24+
25+
/** How many routes to recompute synchronously before yielding to the browser. */
26+
export const ASYNC_BATCH_SIZE = 8;
27+
28+
/** Merge user waypoints closer than this many pixels. */
29+
export const WAYPOINT_MERGE_THRESHOLD = 15;
30+
31+
/** Treat three waypoints as collinear if the middle one is within this many pixels of the line. */
32+
export const WAYPOINT_COLLINEAR_THRESHOLD = 5;
33+
34+
/** Default routing-context padding around node bounds (in pixels). */
35+
export const ROUTING_CONTEXT_PADDING = 100;
36+
37+
/**
38+
* Sub-pixel offsets that pull the visible edge endpoint slightly out of the
39+
* handle hitbox so the rounded corner geometry doesn't overlap the port.
40+
*/
41+
export const EDGE_SOURCE_OFFSET = 0.5;
42+
export const EDGE_TARGET_OFFSET = 4.5;
43+
44+
/** Rounded-corner radius for orthogonal edges (in pixels). */
45+
export const EDGE_CORNER_RADIUS = 5;

src/lib/routing/index.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,18 @@ export { calculateRoute, calculateRouteWithWaypoints, calculateSimpleRoute, getP
99
export { SparseGrid } from './gridBuilder';
1010

1111
// Constants used by FlowCanvas
12-
export { ROUTING_MARGIN, HANDLE_OFFSET, ARROW_INSET } from './constants';
12+
export {
13+
ROUTING_MARGIN,
14+
HANDLE_OFFSET,
15+
ARROW_INSET,
16+
ASYNC_BATCH_SIZE,
17+
WAYPOINT_MERGE_THRESHOLD,
18+
WAYPOINT_COLLINEAR_THRESHOLD,
19+
ROUTING_CONTEXT_PADDING,
20+
EDGE_SOURCE_OFFSET,
21+
EDGE_TARGET_OFFSET,
22+
EDGE_CORNER_RADIUS
23+
} from './constants';
1324

1425
// Types
1526
export type { Bounds, RoutingContext, RouteResult, Direction, PortStub } from './types';

src/lib/stores/routing.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,18 @@ import { writable, derived, get } from 'svelte/store';
66
import type { Position } from '$lib/types/common';
77
import type { Connection, Waypoint } from '$lib/types/nodes';
88
import type { RoutingContext, RouteResult, Bounds, Direction, PortStub } from '$lib/routing';
9-
import { calculateRoute, calculateRouteWithWaypoints, calculateSimpleRoute, getPathCells, ROUTING_MARGIN } from '$lib/routing';
9+
import {
10+
calculateRoute,
11+
calculateRouteWithWaypoints,
12+
calculateSimpleRoute,
13+
getPathCells,
14+
ROUTING_MARGIN,
15+
ASYNC_BATCH_SIZE,
16+
WAYPOINT_MERGE_THRESHOLD,
17+
WAYPOINT_COLLINEAR_THRESHOLD,
18+
ROUTING_CONTEXT_PADDING
19+
} from '$lib/routing';
20+
import { DEFAULT_NODE_WIDTH, DEFAULT_NODE_HEIGHT } from '$lib/constants/dimensions';
1021
import { SparseGrid } from '$lib/routing/gridBuilder';
1122
import { generateId } from '$lib/stores/utils';
1223
import { graphStore } from '$lib/stores/graph';
@@ -53,9 +64,6 @@ function hashRouteInputs(
5364
return `${sourcePos.x},${sourcePos.y}|${targetPos.x},${targetPos.y}|${sourceDir}|${targetDir}|${wpHash}`;
5465
}
5566

56-
/** Number of routes to calculate per async batch before yielding to browser */
57-
const ASYNC_BATCH_SIZE = 8;
58-
5967
interface RoutingState {
6068
/** Cached routes by connection ID */
6169
routes: Map<string, RouteResult>;
@@ -734,8 +742,8 @@ export const routingStore = {
734742
const sourcePos = sourceInfo?.position || null;
735743
const targetPos = targetInfo?.position || null;
736744

737-
const MERGE_THRESHOLD = 15; // Pixels - merge waypoints closer than this
738-
const COLLINEAR_THRESHOLD = 5; // Pixels - consider collinear if deviation less than this
745+
const MERGE_THRESHOLD = WAYPOINT_MERGE_THRESHOLD;
746+
const COLLINEAR_THRESHOLD = WAYPOINT_COLLINEAR_THRESHOLD;
739747

740748
// Helper to check if point is collinear with prev and next
741749
const isCollinear = (prev: Position, curr: Position, next: Position): boolean => {
@@ -856,7 +864,7 @@ export const routingStore = {
856864
*/
857865
export function buildRoutingContext(
858866
nodes: Array<{ id: string; position: Position; width?: number; height?: number; measured?: { width?: number; height?: number } }>,
859-
padding = 100
867+
padding = ROUTING_CONTEXT_PADDING
860868
): { nodeBounds: Map<string, Bounds>; canvasBounds: Bounds } {
861869
const nodeBounds = new Map<string, Bounds>();
862870

@@ -866,8 +874,8 @@ export function buildRoutingContext(
866874
let maxY = -Infinity;
867875

868876
for (const node of nodes) {
869-
const width = node.measured?.width ?? node.width ?? 80;
870-
const height = node.measured?.height ?? node.height ?? 40;
877+
const width = node.measured?.width ?? node.width ?? DEFAULT_NODE_WIDTH;
878+
const height = node.measured?.height ?? node.height ?? DEFAULT_NODE_HEIGHT;
871879

872880
// Node position is center (nodeOrigin = [0.5, 0.5])
873881
const left = node.position.x - width / 2;

0 commit comments

Comments
 (0)