@pyreon/flow 0.10.0 → 0.11.1

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/src/edges.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { EdgePathResult, FlowNode, XYPosition } from './types'
2
- import { Position } from './types'
1
+ import type { EdgePathResult, FlowNode, XYPosition } from "./types"
2
+ import { Position } from "./types"
3
3
 
4
4
  /**
5
5
  * Auto-detect the best handle position based on relative node positions.
@@ -148,10 +148,7 @@ export function getBezierPath(params: {
148
148
  break
149
149
  }
150
150
 
151
- const center = getCenter(
152
- { x: sourceX, y: sourceY },
153
- { x: targetX, y: targetY },
154
- )
151
+ const center = getCenter({ x: sourceX, y: sourceY }, { x: targetX, y: targetY })
155
152
 
156
153
  return {
157
154
  path: `M${sourceX},${sourceY} C${sourceControlX},${sourceControlY} ${targetControlX},${targetControlY} ${targetX},${targetY}`,
@@ -184,46 +181,25 @@ export function getSmoothStepPath(params: {
184
181
  offset = 20,
185
182
  } = params
186
183
 
187
- const isHorizontalSource =
188
- sourcePosition === Position.Left || sourcePosition === Position.Right
189
- const isHorizontalTarget =
190
- targetPosition === Position.Left || targetPosition === Position.Right
184
+ const isHorizontalSource = sourcePosition === Position.Left || sourcePosition === Position.Right
185
+ const isHorizontalTarget = targetPosition === Position.Left || targetPosition === Position.Right
191
186
 
192
187
  // Calculate offset points
193
188
  const sourceOffsetX =
194
- sourcePosition === Position.Right
195
- ? offset
196
- : sourcePosition === Position.Left
197
- ? -offset
198
- : 0
189
+ sourcePosition === Position.Right ? offset : sourcePosition === Position.Left ? -offset : 0
199
190
  const sourceOffsetY =
200
- sourcePosition === Position.Bottom
201
- ? offset
202
- : sourcePosition === Position.Top
203
- ? -offset
204
- : 0
191
+ sourcePosition === Position.Bottom ? offset : sourcePosition === Position.Top ? -offset : 0
205
192
  const targetOffsetX =
206
- targetPosition === Position.Right
207
- ? offset
208
- : targetPosition === Position.Left
209
- ? -offset
210
- : 0
193
+ targetPosition === Position.Right ? offset : targetPosition === Position.Left ? -offset : 0
211
194
  const targetOffsetY =
212
- targetPosition === Position.Bottom
213
- ? offset
214
- : targetPosition === Position.Top
215
- ? -offset
216
- : 0
195
+ targetPosition === Position.Bottom ? offset : targetPosition === Position.Top ? -offset : 0
217
196
 
218
197
  const sX = sourceX + sourceOffsetX
219
198
  const sY = sourceY + sourceOffsetY
220
199
  const tX = targetX + targetOffsetX
221
200
  const tY = targetY + targetOffsetY
222
201
 
223
- const center = getCenter(
224
- { x: sourceX, y: sourceY },
225
- { x: targetX, y: targetY },
226
- )
202
+ const center = getCenter({ x: sourceX, y: sourceY }, { x: targetX, y: targetY })
227
203
 
228
204
  // Simple smoothstep: source → midpoint → target with rounded corners
229
205
  const midX = (sX + tX) / 2
@@ -261,10 +237,7 @@ export function getStraightPath(params: {
261
237
  targetY: number
262
238
  }): EdgePathResult {
263
239
  const { sourceX, sourceY, targetX, targetY } = params
264
- const center = getCenter(
265
- { x: sourceX, y: sourceY },
266
- { x: targetX, y: targetY },
267
- )
240
+ const center = getCenter({ x: sourceX, y: sourceY }, { x: targetX, y: targetY })
268
241
 
269
242
  return {
270
243
  path: `M${sourceX},${sourceY} L${targetX},${targetY}`,
@@ -304,14 +277,10 @@ export function getWaypointPath(params: {
304
277
  return getStraightPath({ sourceX, sourceY, targetX, targetY })
305
278
  }
306
279
 
307
- const allPoints = [
308
- { x: sourceX, y: sourceY },
309
- ...waypoints,
310
- { x: targetX, y: targetY },
311
- ]
280
+ const allPoints = [{ x: sourceX, y: sourceY }, ...waypoints, { x: targetX, y: targetY }]
312
281
 
313
282
  const segments = allPoints.map((p) => `${p.x},${p.y}`)
314
- const path = `M${segments.join(' L')}`
283
+ const path = `M${segments.join(" L")}`
315
284
 
316
285
  // Label at the middle waypoint
317
286
  const midIdx = Math.floor(waypoints.length / 2)
@@ -336,7 +305,7 @@ export function getEdgePath(
336
305
  targetPosition: Position,
337
306
  ): EdgePathResult {
338
307
  switch (type) {
339
- case 'smoothstep':
308
+ case "smoothstep":
340
309
  return getSmoothStepPath({
341
310
  sourceX,
342
311
  sourceY,
@@ -345,9 +314,9 @@ export function getEdgePath(
345
314
  targetY,
346
315
  targetPosition,
347
316
  })
348
- case 'straight':
317
+ case "straight":
349
318
  return getStraightPath({ sourceX, sourceY, targetX, targetY })
350
- case 'step':
319
+ case "step":
351
320
  return getStepPath({
352
321
  sourceX,
353
322
  sourceY,
package/src/flow.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { batch, computed, signal } from '@pyreon/reactivity'
2
- import { computeLayout } from './layout'
1
+ import { batch, computed, signal } from "@pyreon/reactivity"
2
+ import { computeLayout } from "./layout"
3
3
  import type {
4
4
  Connection,
5
5
  FlowConfig,
@@ -10,15 +10,15 @@ import type {
10
10
  LayoutOptions,
11
11
  NodeChange,
12
12
  XYPosition,
13
- } from './types'
13
+ } from "./types"
14
14
 
15
15
  /**
16
16
  * Generate a unique edge id from source/target.
17
17
  */
18
18
  function edgeId(edge: FlowEdge): string {
19
19
  if (edge.id) return edge.id
20
- const sh = edge.sourceHandle ? `-${edge.sourceHandle}` : ''
21
- const th = edge.targetHandle ? `-${edge.targetHandle}` : ''
20
+ const sh = edge.sourceHandle ? `-${edge.sourceHandle}` : ""
21
+ const th = edge.targetHandle ? `-${edge.targetHandle}` : ""
22
22
  return `e-${edge.source}${sh}-${edge.target}${th}`
23
23
  }
24
24
 
@@ -51,7 +51,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
51
51
  const {
52
52
  nodes: initialNodes = [],
53
53
  edges: initialEdges = [],
54
- defaultEdgeType = 'bezier',
54
+ defaultEdgeType = "bezier",
55
55
  minZoom = 0.1,
56
56
  maxZoom = 4,
57
57
  snapToGrid = false,
@@ -112,22 +112,18 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
112
112
  batch(() => {
113
113
  nodes.update((nds) => nds.filter((n) => n.id !== id))
114
114
  // Remove connected edges
115
- edges.update((eds) =>
116
- eds.filter((e) => e.source !== id && e.target !== id),
117
- )
115
+ edges.update((eds) => eds.filter((e) => e.source !== id && e.target !== id))
118
116
  selectedNodeIds.update((set) => {
119
117
  const next = new Set(set)
120
118
  next.delete(id)
121
119
  return next
122
120
  })
123
121
  })
124
- emitNodeChanges([{ type: 'remove', id }])
122
+ emitNodeChanges([{ type: "remove", id }])
125
123
  }
126
124
 
127
125
  function updateNode(id: string, update: Partial<FlowNode>): void {
128
- nodes.update((nds) =>
129
- nds.map((n) => (n.id === id ? { ...n, ...update } : n)),
130
- )
126
+ nodes.update((nds) => nds.map((n) => (n.id === id ? { ...n, ...update } : n)))
131
127
  }
132
128
 
133
129
  function updateNodePosition(id: string, position: XYPosition): void {
@@ -142,10 +138,8 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
142
138
  const node = getNode(id)
143
139
  pos = clampToExtent(pos, node?.width, node?.height)
144
140
 
145
- nodes.update((nds) =>
146
- nds.map((n) => (n.id === id ? { ...n, position: pos } : n)),
147
- )
148
- emitNodeChanges([{ type: 'position', id, position: pos }])
141
+ nodes.update((nds) => nds.map((n) => (n.id === id ? { ...n, position: pos } : n)))
142
+ emitNodeChanges([{ type: "position", id, position: pos }])
149
143
  }
150
144
 
151
145
  // ── Edge operations ──────────────────────────────────────────────────────
@@ -193,7 +187,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
193
187
  const sourceNode = getNode(connection.source)
194
188
  if (!sourceNode) return false
195
189
 
196
- const sourceType = sourceNode.type ?? 'default'
190
+ const sourceType = sourceNode.type ?? "default"
197
191
  const rule = connectionRules[sourceType]
198
192
  if (!rule) return true // no rule = allow
199
193
 
@@ -201,7 +195,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
201
195
  const targetNode = getNode(connection.target)
202
196
  if (!targetNode) return false
203
197
 
204
- const targetType = targetNode.type ?? 'default'
198
+ const targetType = targetNode.type ?? "default"
205
199
  return rule.outputs.includes(targetType)
206
200
  }
207
201
 
@@ -275,13 +269,8 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
275
269
 
276
270
  // ── Viewport ─────────────────────────────────────────────────────────────
277
271
 
278
- function fitView(
279
- nodeIds?: string[],
280
- padding = config.fitViewPadding ?? 0.1,
281
- ): void {
282
- const targetNodes = nodeIds
283
- ? nodes.peek().filter((n) => nodeIds.includes(n.id))
284
- : nodes.peek()
272
+ function fitView(nodeIds?: string[], padding = config.fitViewPadding ?? 0.1): void {
273
+ const targetNodes = nodeIds ? nodes.peek().filter((n) => nodeIds.includes(n.id)) : nodes.peek()
285
274
 
286
275
  if (targetNodes.length === 0) return
287
276
 
@@ -302,8 +291,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
302
291
  const graphWidth = maxX - minX
303
292
  const graphHeight = maxY - minY
304
293
 
305
- const { width: containerWidth, height: containerHeight } =
306
- containerSize.peek()
294
+ const { width: containerWidth, height: containerHeight } = containerSize.peek()
307
295
 
308
296
  const zoomX = containerWidth / (graphWidth * (1 + padding * 2))
309
297
  const zoomY = containerHeight / (graphHeight * (1 + padding * 2))
@@ -360,29 +348,19 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
360
348
  const screenW = w * v.zoom
361
349
  const screenH = h * v.zoom
362
350
  const { width: cw, height: ch } = containerSize.peek()
363
- return (
364
- screenX + screenW > 0 &&
365
- screenX < cw &&
366
- screenY + screenH > 0 &&
367
- screenY < ch
368
- )
351
+ return screenX + screenW > 0 && screenX < cw && screenY + screenH > 0 && screenY < ch
369
352
  }
370
353
 
371
354
  // ── Layout ───────────────────────────────────────────────────────────────
372
355
 
373
356
  async function layout(
374
- algorithm: LayoutAlgorithm = 'layered',
357
+ algorithm: LayoutAlgorithm = "layered",
375
358
  options: LayoutOptions = {},
376
359
  ): Promise<void> {
377
360
  const currentNodes = nodes.peek()
378
361
  const currentEdges = edges.peek()
379
362
 
380
- const positions = await computeLayout(
381
- currentNodes,
382
- currentEdges,
383
- algorithm,
384
- options,
385
- )
363
+ const positions = await computeLayout(currentNodes, currentEdges, algorithm, options)
386
364
 
387
365
  const animate = options.animate !== false
388
366
  const duration = options.animationDuration ?? 300
@@ -400,9 +378,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
400
378
  }
401
379
 
402
380
  // Animated transition — interpolate positions over duration
403
- const startPositions = new Map(
404
- currentNodes.map((n) => [n.id, { ...n.position }]),
405
- )
381
+ const startPositions = new Map(currentNodes.map((n) => [n.id, { ...n.position }]))
406
382
  const targetPositions = new Map(positions.map((p) => [p.id, p.position]))
407
383
 
408
384
  const startTime = performance.now()
@@ -445,9 +421,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
445
421
  // ── Graph queries ────────────────────────────────────────────────────────
446
422
 
447
423
  function getConnectedEdges(nodeId: string): FlowEdge[] {
448
- return edges
449
- .peek()
450
- .filter((e) => e.source === nodeId || e.target === nodeId)
424
+ return edges.peek().filter((e) => e.source === nodeId || e.target === nodeId)
451
425
  }
452
426
 
453
427
  function getIncomers(nodeId: string): FlowNode[] {
@@ -469,9 +443,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
469
443
  return () => connectListeners.delete(callback)
470
444
  }
471
445
 
472
- function onNodesChange(
473
- callback: (changes: NodeChange[]) => void,
474
- ): () => void {
446
+ function onNodesChange(callback: (changes: NodeChange[]) => void): () => void {
475
447
  nodesChangeListeners.add(callback)
476
448
  return () => nodesChangeListeners.delete(callback)
477
449
  }
@@ -738,11 +710,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
738
710
 
739
711
  // ── Edge waypoints ──────────────────────────────────────────────────────
740
712
 
741
- function addEdgeWaypoint(
742
- edgeIdentifier: string,
743
- point: XYPosition,
744
- index?: number,
745
- ): void {
713
+ function addEdgeWaypoint(edgeIdentifier: string, point: XYPosition, index?: number): void {
746
714
  edges.update((eds) =>
747
715
  eds.map((e) => {
748
716
  if (e.id !== edgeIdentifier) return e
@@ -769,11 +737,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
769
737
  )
770
738
  }
771
739
 
772
- function updateEdgeWaypoint(
773
- edgeIdentifier: string,
774
- index: number,
775
- point: XYPosition,
776
- ): void {
740
+ function updateEdgeWaypoint(edgeIdentifier: string, index: number, point: XYPosition): void {
777
741
  edges.update((eds) =>
778
742
  eds.map((e) => {
779
743
  if (e.id !== edgeIdentifier) return e
@@ -788,10 +752,7 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
788
752
 
789
753
  // ── Proximity connect ───────────────────────────────────────────────────
790
754
 
791
- function getProximityConnection(
792
- nodeId: string,
793
- threshold = 50,
794
- ): Connection | null {
755
+ function getProximityConnection(nodeId: string, threshold = 50): Connection | null {
795
756
  const node = getNode(nodeId)
796
757
  if (!node) return null
797
758
 
@@ -888,18 +849,14 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
888
849
  // Push in the direction of least overlap
889
850
  if (overlapX < overlapY) {
890
851
  const dx =
891
- node.position.x < other.position.x
892
- ? -(overlapX + spacing) / 2
893
- : (overlapX + spacing) / 2
852
+ node.position.x < other.position.x ? -(overlapX + spacing) / 2 : (overlapX + spacing) / 2
894
853
  updateNodePosition(other.id, {
895
854
  x: other.position.x - dx,
896
855
  y: other.position.y,
897
856
  })
898
857
  } else {
899
858
  const dy =
900
- node.position.y < other.position.y
901
- ? -(overlapY + spacing) / 2
902
- : (overlapY + spacing) / 2
859
+ node.position.y < other.position.y ? -(overlapY + spacing) / 2 : (overlapY + spacing) / 2
903
860
  updateNodePosition(other.id, {
904
861
  x: other.position.x,
905
862
  y: other.position.y - dy,
@@ -910,30 +867,17 @@ export function createFlow(config: FlowConfig = {}): FlowInstance {
910
867
 
911
868
  // ── Node extent (drag boundaries) ──────────────────────────────────────
912
869
 
913
- function setNodeExtent(
914
- extent: [[number, number], [number, number]] | null,
915
- ): void {
870
+ function setNodeExtent(extent: [[number, number], [number, number]] | null): void {
916
871
  nodeExtent = extent
917
872
  }
918
873
 
919
- let nodeExtent: [[number, number], [number, number]] | null =
920
- config.nodeExtent ?? null
874
+ let nodeExtent: [[number, number], [number, number]] | null = config.nodeExtent ?? null
921
875
 
922
- function clampToExtent(
923
- position: XYPosition,
924
- nodeWidth = 150,
925
- nodeHeight = 40,
926
- ): XYPosition {
876
+ function clampToExtent(position: XYPosition, nodeWidth = 150, nodeHeight = 40): XYPosition {
927
877
  if (!nodeExtent) return position
928
878
  return {
929
- x: Math.min(
930
- Math.max(position.x, nodeExtent[0][0]),
931
- nodeExtent[1][0] - nodeWidth,
932
- ),
933
- y: Math.min(
934
- Math.max(position.y, nodeExtent[0][1]),
935
- nodeExtent[1][1] - nodeHeight,
936
- ),
879
+ x: Math.min(Math.max(position.x, nodeExtent[0][0]), nodeExtent[1][0] - nodeWidth),
880
+ y: Math.min(Math.max(position.y, nodeExtent[0][1]), nodeExtent[1][1] - nodeHeight),
937
881
  }
938
882
  }
939
883
 
package/src/index.ts CHANGED
@@ -24,18 +24,18 @@
24
24
  * ```
25
25
  */
26
26
 
27
- export { Background } from './components/background'
28
- export { Controls } from './components/controls'
29
- export type { FlowComponentProps } from './components/flow-component'
27
+ export { Background } from "./components/background"
28
+ export { Controls } from "./components/controls"
29
+ export type { FlowComponentProps } from "./components/flow-component"
30
30
  // Components
31
- export { Flow } from './components/flow-component'
32
- export { Handle } from './components/handle'
33
- export { MiniMap } from './components/minimap'
34
- export type { NodeResizerProps } from './components/node-resizer'
35
- export { NodeResizer } from './components/node-resizer'
36
- export type { NodeToolbarProps } from './components/node-toolbar'
37
- export { NodeToolbar } from './components/node-toolbar'
38
- export { Panel } from './components/panel'
31
+ export { Flow } from "./components/flow-component"
32
+ export { Handle } from "./components/handle"
33
+ export { MiniMap } from "./components/minimap"
34
+ export type { NodeResizerProps } from "./components/node-resizer"
35
+ export { NodeResizer } from "./components/node-resizer"
36
+ export type { NodeToolbarProps } from "./components/node-toolbar"
37
+ export { NodeToolbar } from "./components/node-toolbar"
38
+ export { Panel } from "./components/panel"
39
39
  // Edge path utilities
40
40
  export {
41
41
  getBezierPath,
@@ -46,13 +46,13 @@ export {
46
46
  getStepPath,
47
47
  getStraightPath,
48
48
  getWaypointPath,
49
- } from './edges'
49
+ } from "./edges"
50
50
  // Core
51
- export { createFlow } from './flow'
51
+ export { createFlow } from "./flow"
52
52
  // Layout
53
- export { computeLayout } from './layout'
53
+ export { computeLayout } from "./layout"
54
54
  // Styles
55
- export { flowStyles } from './styles'
55
+ export { flowStyles } from "./styles"
56
56
  export type {
57
57
  BackgroundProps,
58
58
  Connection,
@@ -78,6 +78,6 @@ export type {
78
78
  Rect,
79
79
  Viewport,
80
80
  XYPosition,
81
- } from './types'
81
+ } from "./types"
82
82
  // Types
83
- export { Position } from './types'
83
+ export { Position } from "./types"
package/src/layout.ts CHANGED
@@ -1,27 +1,22 @@
1
- import type {
2
- FlowEdge,
3
- FlowNode,
4
- LayoutAlgorithm,
5
- LayoutOptions,
6
- } from './types'
1
+ import type { FlowEdge, FlowNode, LayoutAlgorithm, LayoutOptions } from "./types"
7
2
 
8
3
  // ─── ELK algorithm mapping ───────────────────────────────────────────────────
9
4
 
10
5
  const ELK_ALGORITHMS: Record<LayoutAlgorithm, string> = {
11
- layered: 'org.eclipse.elk.layered',
12
- force: 'org.eclipse.elk.force',
13
- stress: 'org.eclipse.elk.stress',
14
- tree: 'org.eclipse.elk.mrtree',
15
- radial: 'org.eclipse.elk.radial',
16
- box: 'org.eclipse.elk.box',
17
- rectpacking: 'org.eclipse.elk.rectpacking',
6
+ layered: "org.eclipse.elk.layered",
7
+ force: "org.eclipse.elk.force",
8
+ stress: "org.eclipse.elk.stress",
9
+ tree: "org.eclipse.elk.mrtree",
10
+ radial: "org.eclipse.elk.radial",
11
+ box: "org.eclipse.elk.box",
12
+ rectpacking: "org.eclipse.elk.rectpacking",
18
13
  }
19
14
 
20
15
  const ELK_DIRECTIONS: Record<string, string> = {
21
- UP: 'UP',
22
- DOWN: 'DOWN',
23
- LEFT: 'LEFT',
24
- RIGHT: 'RIGHT',
16
+ UP: "UP",
17
+ DOWN: "DOWN",
18
+ LEFT: "LEFT",
19
+ RIGHT: "RIGHT",
25
20
  }
26
21
 
27
22
  // ─── Lazy-loaded ELK instance ────────────────────────────────────────────────
@@ -33,7 +28,7 @@ async function getELK(): Promise<any> {
33
28
  if (elkInstance) return elkInstance
34
29
  if (elkPromise) return elkPromise
35
30
 
36
- elkPromise = import('elkjs/lib/elk.bundled.js').then((mod) => {
31
+ elkPromise = import("elkjs/lib/elk.bundled.js").then((mod) => {
37
32
  const ELK = mod.default || mod
38
33
  elkInstance = new ELK()
39
34
  return elkInstance
@@ -74,35 +69,32 @@ function toElkGraph(
74
69
  options: LayoutOptions,
75
70
  ): ElkGraph {
76
71
  const layoutOptions: Record<string, string> = {
77
- 'elk.algorithm': ELK_ALGORITHMS[algorithm] ?? ELK_ALGORITHMS.layered,
72
+ "elk.algorithm": ELK_ALGORITHMS[algorithm] ?? ELK_ALGORITHMS.layered,
78
73
  }
79
74
 
80
75
  if (options.direction) {
81
- layoutOptions['elk.direction'] = ELK_DIRECTIONS[options.direction] ?? 'DOWN'
76
+ layoutOptions["elk.direction"] = ELK_DIRECTIONS[options.direction] ?? "DOWN"
82
77
  }
83
78
 
84
79
  if (options.nodeSpacing !== undefined) {
85
- layoutOptions['elk.spacing.nodeNode'] = String(options.nodeSpacing)
80
+ layoutOptions["elk.spacing.nodeNode"] = String(options.nodeSpacing)
86
81
  }
87
82
 
88
83
  if (options.layerSpacing !== undefined) {
89
- layoutOptions['elk.layered.spacing.nodeNodeBetweenLayers'] = String(
90
- options.layerSpacing,
91
- )
84
+ layoutOptions["elk.layered.spacing.nodeNodeBetweenLayers"] = String(options.layerSpacing)
92
85
  }
93
86
 
94
87
  if (options.edgeRouting) {
95
88
  const routingMap: Record<string, string> = {
96
- orthogonal: 'ORTHOGONAL',
97
- splines: 'SPLINES',
98
- polyline: 'POLYLINE',
89
+ orthogonal: "ORTHOGONAL",
90
+ splines: "SPLINES",
91
+ polyline: "POLYLINE",
99
92
  }
100
- layoutOptions['elk.edgeRouting'] =
101
- routingMap[options.edgeRouting] ?? 'ORTHOGONAL'
93
+ layoutOptions["elk.edgeRouting"] = routingMap[options.edgeRouting] ?? "ORTHOGONAL"
102
94
  }
103
95
 
104
96
  return {
105
- id: 'root',
97
+ id: "root",
106
98
  layoutOptions,
107
99
  children: nodes.map((node) => ({
108
100
  id: node.id,
@@ -138,7 +130,7 @@ function toElkGraph(
138
130
  export async function computeLayout(
139
131
  nodes: FlowNode[],
140
132
  edges: FlowEdge[],
141
- algorithm: LayoutAlgorithm = 'layered',
133
+ algorithm: LayoutAlgorithm = "layered",
142
134
  options: LayoutOptions = {},
143
135
  ): Promise<Array<{ id: string; position: { x: number; y: number } }>> {
144
136
  const elk = await getELK()