@runtypelabs/react-flow 0.1.5 → 0.1.6

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.
@@ -6,9 +6,9 @@ import type { FlowStepType } from '../flow-step-types'
6
6
  // ============================================================================
7
7
 
8
8
  const NODE_WIDTH = 280
9
- const NODE_HEIGHT = 200 // Increased for better card visibility
10
- const NODE_SPACING_X = 350 // Horizontal space between main steps
11
- const NODE_SPACING_Y = 80 // Vertical space between branch steps
9
+ const NODE_HEIGHT = 200 // Increased for better card visibility
10
+ const NODE_SPACING_X = 350 // Horizontal space between main steps
11
+ const NODE_SPACING_Y = 80 // Vertical space between branch steps
12
12
  const BRANCH_OFFSET_X = 350 // Horizontal offset for branches to the right of conditional
13
13
  const BRANCH_OFFSET_Y = -80 // Vertical offset for true branch (above center)
14
14
  const FALSE_BRANCH_GAP = 100 // Gap between true and false branches
@@ -35,9 +35,9 @@ export function flowStepsToNodes(
35
35
  steps: FlowStep[],
36
36
  options?: FlowStepsToNodesOptions
37
37
  ): RuntypeNode[] {
38
- const {
39
- onChange,
40
- onDelete,
38
+ const {
39
+ onChange,
40
+ onDelete,
41
41
  startPosition = { x: 50, y: 200 },
42
42
  idPrefix = '',
43
43
  parentId,
@@ -68,77 +68,80 @@ export function flowStepsToNodes(
68
68
  draggable: true,
69
69
  selectable: true,
70
70
  }
71
-
71
+
72
72
  if (parentId) {
73
73
  node.parentId = parentId
74
74
  }
75
75
 
76
76
  nodes.push(node)
77
-
77
+
78
78
  // DEBUG: Log node positions
79
79
  console.log(`[flowStepsToNodes] Placed "${step.name}" (${step.type}) at x=${currentX}`)
80
-
80
+
81
81
  // Handle conditional branches - position to the right with true above, false below
82
82
  if (step.type === 'conditional' && step.config) {
83
83
  const config = step.config as { trueSteps?: FlowStep[]; falseSteps?: FlowStep[] }
84
84
  const branchX = currentX + BRANCH_OFFSET_X
85
-
85
+
86
86
  // Calculate branch lengths (horizontal extent)
87
87
  const trueBranchLength = config.trueSteps?.length || 0
88
88
  const falseBranchLength = config.falseSteps?.length || 0
89
89
  const maxBranchLength = Math.max(trueBranchLength, falseBranchLength)
90
-
90
+
91
91
  // Calculate true branch height (vertical extent for stacking)
92
92
  const trueBranchHeight = trueBranchLength * (NODE_HEIGHT + NODE_SPACING_Y)
93
-
93
+
94
94
  // True branch nodes (positioned to the right, above center)
95
95
  if (config.trueSteps && config.trueSteps.length > 0) {
96
96
  const trueBranchY = startPosition.y + BRANCH_OFFSET_Y
97
97
  const trueBranchNodes = flowStepsToNodes(config.trueSteps, {
98
98
  onChange,
99
99
  onDelete,
100
- startPosition: {
101
- x: branchX,
102
- y: trueBranchY
100
+ startPosition: {
101
+ x: branchX,
102
+ y: trueBranchY,
103
103
  },
104
104
  idPrefix: `${nodeId}-true-`,
105
105
  parentId: nodeId,
106
106
  })
107
-
107
+
108
108
  nodes.push(...trueBranchNodes)
109
109
  maxBranchY = Math.max(maxBranchY, trueBranchY + trueBranchHeight)
110
110
  }
111
-
111
+
112
112
  // False branch nodes (positioned to the right, below center)
113
113
  if (config.falseSteps && config.falseSteps.length > 0) {
114
114
  // Position false branch below true branch (or at center + gap if no true branch)
115
- const falseBranchY = trueBranchLength > 0
116
- ? startPosition.y + BRANCH_OFFSET_Y + trueBranchHeight + FALSE_BRANCH_GAP
117
- : startPosition.y + NODE_HEIGHT + NODE_SPACING_Y
118
-
115
+ const falseBranchY =
116
+ trueBranchLength > 0
117
+ ? startPosition.y + BRANCH_OFFSET_Y + trueBranchHeight + FALSE_BRANCH_GAP
118
+ : startPosition.y + NODE_HEIGHT + NODE_SPACING_Y
119
+
119
120
  const falseBranchNodes = flowStepsToNodes(config.falseSteps, {
120
121
  onChange,
121
122
  onDelete,
122
- startPosition: {
123
- x: branchX,
124
- y: falseBranchY
123
+ startPosition: {
124
+ x: branchX,
125
+ y: falseBranchY,
125
126
  },
126
127
  idPrefix: `${nodeId}-false-`,
127
128
  parentId: nodeId,
128
129
  })
129
-
130
+
130
131
  nodes.push(...falseBranchNodes)
131
132
  const falseBranchHeight = config.falseSteps.length * (NODE_HEIGHT + NODE_SPACING_Y)
132
133
  maxBranchY = Math.max(maxBranchY, falseBranchY + falseBranchHeight)
133
134
  }
134
-
135
+
135
136
  // Skip past the conditional AND all its branch steps
136
137
  // Branches start at branchX, so we need to account for:
137
138
  // - The offset from conditional to first branch step (BRANCH_OFFSET_X)
138
139
  // - All the branch steps (maxBranchLength * (NODE_WIDTH + NODE_SPACING_X))
139
140
  if (maxBranchLength > 0) {
140
- const advance = BRANCH_OFFSET_X + (maxBranchLength * (NODE_WIDTH + NODE_SPACING_X))
141
- console.log(`[flowStepsToNodes] Conditional "${step.name}" has ${maxBranchLength} branch steps, advancing currentX by ${advance}`)
141
+ const advance = BRANCH_OFFSET_X + maxBranchLength * (NODE_WIDTH + NODE_SPACING_X)
142
+ console.log(
143
+ `[flowStepsToNodes] Conditional "${step.name}" has ${maxBranchLength} branch steps, advancing currentX by ${advance}`
144
+ )
142
145
  currentX += advance
143
146
  console.log(`[flowStepsToNodes] After conditional, currentX = ${currentX}`)
144
147
  } else {
@@ -162,19 +165,21 @@ export function flowStepsToNodes(
162
165
  */
163
166
  export function nodesToFlowSteps(nodes: RuntypeNode[]): FlowStep[] {
164
167
  // Filter out branch nodes (handled within conditional steps)
165
- const topLevelNodes = nodes.filter(n => !n.parentId && !n.id.includes('-true-') && !n.id.includes('-false-'))
166
-
168
+ const topLevelNodes = nodes.filter(
169
+ (n) => !n.parentId && !n.id.includes('-true-') && !n.id.includes('-false-')
170
+ )
171
+
167
172
  // Sort by X position to determine order (horizontal layout)
168
173
  const sortedNodes = [...topLevelNodes].sort((a, b) => a.position.x - b.position.x)
169
-
174
+
170
175
  return sortedNodes.map((node, index) => {
171
176
  const step = node.data.step
172
-
177
+
173
178
  // Handle conditional steps - extract nested steps
174
179
  if (step.type === 'conditional') {
175
180
  const trueSteps = extractBranchSteps(nodes, node.id, 'true')
176
181
  const falseSteps = extractBranchSteps(nodes, node.id, 'false')
177
-
182
+
178
183
  return {
179
184
  ...step,
180
185
  order: index,
@@ -185,7 +190,7 @@ export function nodesToFlowSteps(nodes: RuntypeNode[]): FlowStep[] {
185
190
  },
186
191
  }
187
192
  }
188
-
193
+
189
194
  return {
190
195
  ...step,
191
196
  order: index,
@@ -196,14 +201,18 @@ export function nodesToFlowSteps(nodes: RuntypeNode[]): FlowStep[] {
196
201
  /**
197
202
  * Extract branch steps from conditional node
198
203
  */
199
- function extractBranchSteps(nodes: RuntypeNode[], parentId: string, branch: 'true' | 'false'): FlowStep[] {
204
+ function extractBranchSteps(
205
+ nodes: RuntypeNode[],
206
+ parentId: string,
207
+ branch: 'true' | 'false'
208
+ ): FlowStep[] {
200
209
  // Match nodes with the branch prefix pattern
201
210
  const branchPrefix = `${parentId}-${branch}-`
202
- const branchNodes = nodes.filter(n => n.id.startsWith(branchPrefix))
203
-
211
+ const branchNodes = nodes.filter((n) => n.id.startsWith(branchPrefix))
212
+
204
213
  // Sort by X position (horizontal layout within branches)
205
214
  const sortedBranchNodes = [...branchNodes].sort((a, b) => a.position.x - b.position.x)
206
-
215
+
207
216
  return sortedBranchNodes.map((node, index) => ({
208
217
  ...node.data.step,
209
218
  order: index,
@@ -221,24 +230,25 @@ export function createEdgesFromNodes(nodes: RuntypeNode[]): RuntypeEdge[] {
221
230
  const edges: RuntypeEdge[] = []
222
231
 
223
232
  // Helper to check if a node is a branch node
224
- const isBranchNode = (n: RuntypeNode) => n.parentId || n.id.includes('-true-') || n.id.includes('-false-')
225
-
233
+ const isBranchNode = (n: RuntypeNode) =>
234
+ n.parentId || n.id.includes('-true-') || n.id.includes('-false-')
235
+
226
236
  // Get top-level nodes sorted by X position (horizontal layout)
227
237
  const topLevelNodes = nodes
228
- .filter(n => !isBranchNode(n))
238
+ .filter((n) => !isBranchNode(n))
229
239
  .sort((a, b) => a.position.x - b.position.x)
230
-
240
+
231
241
  // Create sequential edges for top-level nodes
232
242
  // Skip conditionals - their branches connect to the next step instead
233
243
  for (let i = 0; i < topLevelNodes.length - 1; i++) {
234
244
  const sourceNode = topLevelNodes[i]
235
245
  const targetNode = topLevelNodes[i + 1]
236
-
246
+
237
247
  // Skip edge from conditional - branches will connect to next step
238
248
  if (sourceNode.data.step.type === 'conditional') {
239
249
  continue
240
250
  }
241
-
251
+
242
252
  edges.push({
243
253
  id: `edge-${sourceNode.id}-${targetNode.id}`,
244
254
  source: sourceNode.id,
@@ -249,29 +259,30 @@ export function createEdgesFromNodes(nodes: RuntypeNode[]): RuntypeEdge[] {
249
259
  data: { stepOrder: i },
250
260
  })
251
261
  }
252
-
262
+
253
263
  // Create edges for conditional branches
254
- const conditionalNodes = nodes.filter(n => n.data.step.type === 'conditional' && !isBranchNode(n))
255
-
264
+ const conditionalNodes = nodes.filter(
265
+ (n) => n.data.step.type === 'conditional' && !isBranchNode(n)
266
+ )
267
+
256
268
  for (const conditionalNode of conditionalNodes) {
257
269
  const conditionalId = conditionalNode.id
258
- const conditionalIndex = topLevelNodes.findIndex(n => n.id === conditionalId)
259
- const nextMainStep = conditionalIndex < topLevelNodes.length - 1
260
- ? topLevelNodes[conditionalIndex + 1]
261
- : null
262
-
270
+ const conditionalIndex = topLevelNodes.findIndex((n) => n.id === conditionalId)
271
+ const nextMainStep =
272
+ conditionalIndex < topLevelNodes.length - 1 ? topLevelNodes[conditionalIndex + 1] : null
273
+
263
274
  // Find true branch nodes (contain -true- after the conditional ID)
264
275
  // Sort by X position since branches flow horizontally
265
276
  const trueBranchNodes = nodes
266
- .filter(n => n.id.startsWith(`${conditionalId}-true-`))
277
+ .filter((n) => n.id.startsWith(`${conditionalId}-true-`))
267
278
  .sort((a, b) => a.position.x - b.position.x)
268
-
279
+
269
280
  // Find false branch nodes (contain -false- after the conditional ID)
270
281
  // Sort by X position since branches flow horizontally
271
282
  const falseBranchNodes = nodes
272
- .filter(n => n.id.startsWith(`${conditionalId}-false-`))
283
+ .filter((n) => n.id.startsWith(`${conditionalId}-false-`))
273
284
  .sort((a, b) => a.position.x - b.position.x)
274
-
285
+
275
286
  // Connect conditional to first true branch node (branch goes right)
276
287
  if (trueBranchNodes.length > 0) {
277
288
  edges.push({
@@ -288,7 +299,7 @@ export function createEdgesFromNodes(nodes: RuntypeNode[]): RuntypeEdge[] {
288
299
  labelBgBorderRadius: 4,
289
300
  style: { stroke: '#22c55e', strokeWidth: 2 },
290
301
  })
291
-
302
+
292
303
  // Connect true branch nodes sequentially (horizontal connections)
293
304
  for (let i = 0; i < trueBranchNodes.length - 1; i++) {
294
305
  edges.push({
@@ -301,7 +312,7 @@ export function createEdgesFromNodes(nodes: RuntypeNode[]): RuntypeEdge[] {
301
312
  style: { stroke: '#22c55e', strokeWidth: 1.5 },
302
313
  })
303
314
  }
304
-
315
+
305
316
  // Connect last true branch node to next main step (convergence)
306
317
  if (nextMainStep) {
307
318
  const lastTrueNode = trueBranchNodes[trueBranchNodes.length - 1]
@@ -332,7 +343,7 @@ export function createEdgesFromNodes(nodes: RuntypeNode[]): RuntypeEdge[] {
332
343
  style: { stroke: '#22c55e', strokeWidth: 2 },
333
344
  })
334
345
  }
335
-
346
+
336
347
  // Connect conditional to first false branch node (branch goes right, below true)
337
348
  if (falseBranchNodes.length > 0) {
338
349
  edges.push({
@@ -349,7 +360,7 @@ export function createEdgesFromNodes(nodes: RuntypeNode[]): RuntypeEdge[] {
349
360
  labelBgBorderRadius: 4,
350
361
  style: { stroke: '#ef4444', strokeWidth: 2 },
351
362
  })
352
-
363
+
353
364
  // Connect false branch nodes sequentially (horizontal connections)
354
365
  for (let i = 0; i < falseBranchNodes.length - 1; i++) {
355
366
  edges.push({
@@ -362,7 +373,7 @@ export function createEdgesFromNodes(nodes: RuntypeNode[]): RuntypeEdge[] {
362
373
  style: { stroke: '#ef4444', strokeWidth: 1.5 },
363
374
  })
364
375
  }
365
-
376
+
366
377
  // Connect last false branch node to next main step (convergence)
367
378
  if (nextMainStep) {
368
379
  const lastFalseNode = falseBranchNodes[falseBranchNodes.length - 1]
@@ -393,7 +404,7 @@ export function createEdgesFromNodes(nodes: RuntypeNode[]): RuntypeEdge[] {
393
404
  style: { stroke: '#ef4444', strokeWidth: 2 },
394
405
  })
395
406
  }
396
-
407
+
397
408
  // Handle case where conditional has no branches - connect directly to next step
398
409
  if (trueBranchNodes.length === 0 && falseBranchNodes.length === 0 && nextMainStep) {
399
410
  edges.push({
@@ -406,7 +417,7 @@ export function createEdgesFromNodes(nodes: RuntypeNode[]): RuntypeEdge[] {
406
417
  })
407
418
  }
408
419
  }
409
-
420
+
410
421
  return edges
411
422
  }
412
423
 
@@ -419,13 +430,13 @@ export function createEdgesFromNodes(nodes: RuntypeNode[]): RuntypeEdge[] {
419
430
  */
420
431
  export function getDefaultStepName(type: FlowStepType): string {
421
432
  const names: Record<FlowStepType, string> = {
422
- 'prompt': 'AI Prompt',
433
+ prompt: 'AI Prompt',
423
434
  'fetch-url': 'Fetch URL',
424
435
  'retrieve-record': 'Retrieve Record',
425
436
  'fetch-github': 'Fetch GitHub',
426
437
  'api-call': 'API Call',
427
438
  'transform-data': 'Transform Data',
428
- 'conditional': 'Conditional',
439
+ conditional: 'Conditional',
429
440
  'set-variable': 'Set Variable',
430
441
  'upsert-record': 'Upsert Record',
431
442
  'send-email': 'Send Email',
@@ -433,13 +444,13 @@ export function getDefaultStepName(type: FlowStepType): string {
433
444
  'send-event': 'Send Event',
434
445
  'send-stream': 'Send Stream',
435
446
  'update-record': 'Update Record',
436
- 'search': 'Search',
447
+ search: 'Search',
437
448
  'generate-embedding': 'Generate Embedding',
438
449
  'vector-search': 'Vector Search',
439
450
  'tool-call': 'Tool Call',
440
451
  'wait-until': 'Wait Until',
441
452
  }
442
-
453
+
443
454
  return names[type] || type
444
455
  }
445
456
 
@@ -448,7 +459,7 @@ export function getDefaultStepName(type: FlowStepType): string {
448
459
  */
449
460
  export function createDefaultStep(type: FlowStepType, order: number = 0): FlowStep {
450
461
  const id = `step-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
451
-
462
+
452
463
  const baseStep = {
453
464
  id,
454
465
  type,
@@ -456,7 +467,7 @@ export function createDefaultStep(type: FlowStepType, order: number = 0): FlowSt
456
467
  order,
457
468
  enabled: true,
458
469
  }
459
-
470
+
460
471
  switch (type) {
461
472
  case 'prompt':
462
473
  return {
@@ -469,7 +480,7 @@ export function createDefaultStep(type: FlowStepType, order: number = 0): FlowSt
469
480
  outputVariable: `${type}_result`,
470
481
  },
471
482
  }
472
-
483
+
473
484
  case 'fetch-url':
474
485
  return {
475
486
  ...baseStep,
@@ -482,7 +493,7 @@ export function createDefaultStep(type: FlowStepType, order: number = 0): FlowSt
482
493
  outputVariable: 'fetch_result',
483
494
  },
484
495
  }
485
-
496
+
486
497
  case 'transform-data':
487
498
  return {
488
499
  ...baseStep,
@@ -491,7 +502,7 @@ export function createDefaultStep(type: FlowStepType, order: number = 0): FlowSt
491
502
  outputVariable: 'transform_result',
492
503
  },
493
504
  }
494
-
505
+
495
506
  case 'conditional':
496
507
  return {
497
508
  ...baseStep,
@@ -501,7 +512,7 @@ export function createDefaultStep(type: FlowStepType, order: number = 0): FlowSt
501
512
  falseSteps: [],
502
513
  },
503
514
  }
504
-
515
+
505
516
  case 'send-email':
506
517
  return {
507
518
  ...baseStep,
@@ -513,7 +524,7 @@ export function createDefaultStep(type: FlowStepType, order: number = 0): FlowSt
513
524
  outputVariable: 'email_result',
514
525
  },
515
526
  }
516
-
527
+
517
528
  default:
518
529
  return {
519
530
  ...baseStep,
@@ -541,4 +552,3 @@ export function cloneStep(step: FlowStep): FlowStep {
541
552
  config: JSON.parse(JSON.stringify(step.config)),
542
553
  }
543
554
  }
544
-
@@ -50,17 +50,17 @@ export function autoLayout(
50
50
  // Build adjacency map from edges
51
51
  const adjacencyMap = new Map<string, string[]>()
52
52
  const incomingMap = new Map<string, string[]>()
53
-
53
+
54
54
  for (const edge of edges) {
55
55
  const existing = adjacencyMap.get(edge.source) || []
56
56
  adjacencyMap.set(edge.source, [...existing, edge.target])
57
-
57
+
58
58
  const incoming = incomingMap.get(edge.target) || []
59
59
  incomingMap.set(edge.target, [...incoming, edge.source])
60
60
  }
61
61
 
62
62
  // Find root nodes (nodes with no incoming edges)
63
- const rootNodes = nodes.filter(node => {
63
+ const rootNodes = nodes.filter((node) => {
64
64
  const incoming = incomingMap.get(node.id)
65
65
  return !incoming || incoming.length === 0
66
66
  })
@@ -76,7 +76,7 @@ export function autoLayout(
76
76
 
77
77
  // Position nodes using BFS
78
78
  const queue: Array<{ nodeId: string; x: number; y: number; depth: number }> = []
79
-
79
+
80
80
  // Start with root nodes
81
81
  let startX = startPosition.x
82
82
  for (const rootNode of rootNodes) {
@@ -86,25 +86,25 @@ export function autoLayout(
86
86
 
87
87
  while (queue.length > 0) {
88
88
  const { nodeId, x, y, depth } = queue.shift()!
89
-
89
+
90
90
  if (visited.has(nodeId)) continue
91
91
  visited.add(nodeId)
92
-
92
+
93
93
  positionedNodes.set(nodeId, { x, y })
94
-
94
+
95
95
  // Get children
96
96
  const children = adjacencyMap.get(nodeId) || []
97
- const node = nodes.find(n => n.id === nodeId)
98
-
97
+ const node = nodes.find((n) => n.id === nodeId)
98
+
99
99
  // Check if this is a conditional node
100
100
  const isConditional = node?.data.step.type === 'conditional'
101
-
101
+
102
102
  if (isConditional && children.length > 0) {
103
103
  // Position conditional branches side by side
104
- const trueBranch = children.filter(c => c.includes('-true-'))
105
- const falseBranch = children.filter(c => c.includes('-false-'))
106
- const normalChildren = children.filter(c => !c.includes('-true-') && !c.includes('-false-'))
107
-
104
+ const trueBranch = children.filter((c) => c.includes('-true-'))
105
+ const falseBranch = children.filter((c) => c.includes('-false-'))
106
+ const normalChildren = children.filter((c) => !c.includes('-true-') && !c.includes('-false-'))
107
+
108
108
  // Position true branch to the right
109
109
  let trueY = y + nodeHeight + verticalSpacing
110
110
  for (const childId of trueBranch) {
@@ -118,7 +118,7 @@ export function autoLayout(
118
118
  trueY += nodeHeight + verticalSpacing
119
119
  }
120
120
  }
121
-
121
+
122
122
  // Position false branch to the left
123
123
  let falseY = y + nodeHeight + verticalSpacing
124
124
  for (const childId of falseBranch) {
@@ -132,7 +132,7 @@ export function autoLayout(
132
132
  falseY += nodeHeight + verticalSpacing
133
133
  }
134
134
  }
135
-
135
+
136
136
  // Position normal children below
137
137
  const maxBranchY = Math.max(trueY, falseY)
138
138
  let childY = maxBranchY
@@ -151,7 +151,7 @@ export function autoLayout(
151
151
  // Position children in sequence
152
152
  let childY = y + nodeHeight + verticalSpacing
153
153
  let childX = x
154
-
154
+
155
155
  for (let i = 0; i < children.length; i++) {
156
156
  const childId = children[i]
157
157
  if (!visited.has(childId)) {
@@ -178,7 +178,7 @@ export function autoLayout(
178
178
  }
179
179
 
180
180
  // Apply positions to nodes
181
- return nodes.map(node => {
181
+ return nodes.map((node) => {
182
182
  const position = positionedNodes.get(node.id)
183
183
  if (position) {
184
184
  return {
@@ -220,7 +220,7 @@ export function centerNodes(
220
220
  const offsetY = (viewportHeight - contentHeight) / 2 - minY
221
221
 
222
222
  // Apply offset
223
- return nodes.map(node => ({
223
+ return nodes.map((node) => ({
224
224
  ...node,
225
225
  position: {
226
226
  x: node.position.x + offsetX,
@@ -232,11 +232,8 @@ export function centerNodes(
232
232
  /**
233
233
  * Align nodes to a grid
234
234
  */
235
- export function snapToGrid(
236
- nodes: RuntypeNode[],
237
- gridSize: number = 20
238
- ): RuntypeNode[] {
239
- return nodes.map(node => ({
235
+ export function snapToGrid(nodes: RuntypeNode[], gridSize: number = 20): RuntypeNode[] {
236
+ return nodes.map((node) => ({
240
237
  ...node,
241
238
  position: {
242
239
  x: Math.round(node.position.x / gridSize) * gridSize,
@@ -281,4 +278,3 @@ export function getNodesBoundingBox(nodes: RuntypeNode[]): {
281
278
  height: maxY - minY,
282
279
  }
283
280
  }
284
-
package/tsconfig.json CHANGED
@@ -26,4 +26,3 @@
26
26
  "include": ["src/**/*"],
27
27
  "exclude": ["dist", "node_modules", "**/*.test.ts", "**/*.test.tsx"]
28
28
  }
29
-
package/tsup.config.ts CHANGED
@@ -12,4 +12,3 @@ export default defineConfig({
12
12
  external: ['react', 'react-dom', '@xyflow/react'],
13
13
  treeshake: true,
14
14
  })
15
-