@pyreon/flow 0.11.5 → 0.11.7

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.
@@ -1,17 +1,17 @@
1
- import { describe, expect, it } from "vitest"
1
+ import { describe, expect, it } from 'vitest'
2
2
  import {
3
3
  getBezierPath,
4
4
  getSmartHandlePositions,
5
5
  getSmoothStepPath,
6
6
  getWaypointPath,
7
- } from "../edges"
8
- import { createFlow } from "../flow"
9
- import { Position } from "../types"
7
+ } from '../edges'
8
+ import { createFlow } from '../flow'
9
+ import { Position } from '../types'
10
10
 
11
11
  // ─── Edge paths — additional coverage ────────────────────────────────────────
12
12
 
13
- describe("edge paths — additional branches", () => {
14
- it("getBezierPath with Top/Left source positions", () => {
13
+ describe('edge paths — additional branches', () => {
14
+ it('getBezierPath with Top/Left source positions', () => {
15
15
  const top = getBezierPath({
16
16
  sourceX: 100,
17
17
  sourceY: 100,
@@ -33,7 +33,7 @@ describe("edge paths — additional branches", () => {
33
33
  expect(left.path).toMatch(/^M/)
34
34
  })
35
35
 
36
- it("getBezierPath with all target positions", () => {
36
+ it('getBezierPath with all target positions', () => {
37
37
  for (const pos of [Position.Top, Position.Right, Position.Bottom, Position.Left]) {
38
38
  const result = getBezierPath({
39
39
  sourceX: 0,
@@ -47,7 +47,7 @@ describe("edge paths — additional branches", () => {
47
47
  }
48
48
  })
49
49
 
50
- it("getSmoothStepPath with horizontal→horizontal positions", () => {
50
+ it('getSmoothStepPath with horizontal→horizontal positions', () => {
51
51
  const result = getSmoothStepPath({
52
52
  sourceX: 0,
53
53
  sourceY: 0,
@@ -59,7 +59,7 @@ describe("edge paths — additional branches", () => {
59
59
  expect(result.path).toMatch(/^M/)
60
60
  })
61
61
 
62
- it("getSmoothStepPath with vertical→vertical positions", () => {
62
+ it('getSmoothStepPath with vertical→vertical positions', () => {
63
63
  const result = getSmoothStepPath({
64
64
  sourceX: 0,
65
65
  sourceY: 0,
@@ -71,7 +71,7 @@ describe("edge paths — additional branches", () => {
71
71
  expect(result.path).toMatch(/^M/)
72
72
  })
73
73
 
74
- it("getSmoothStepPath with vertical→horizontal", () => {
74
+ it('getSmoothStepPath with vertical→horizontal', () => {
75
75
  const result = getSmoothStepPath({
76
76
  sourceX: 0,
77
77
  sourceY: 0,
@@ -83,7 +83,7 @@ describe("edge paths — additional branches", () => {
83
83
  expect(result.path).toMatch(/^M/)
84
84
  })
85
85
 
86
- it("getSmoothStepPath with Left source", () => {
86
+ it('getSmoothStepPath with Left source', () => {
87
87
  const result = getSmoothStepPath({
88
88
  sourceX: 200,
89
89
  sourceY: 0,
@@ -95,7 +95,7 @@ describe("edge paths — additional branches", () => {
95
95
  expect(result.path).toMatch(/^M/)
96
96
  })
97
97
 
98
- it("getSmoothStepPath with Bottom target", () => {
98
+ it('getSmoothStepPath with Bottom target', () => {
99
99
  const result = getSmoothStepPath({
100
100
  sourceX: 0,
101
101
  sourceY: 0,
@@ -107,45 +107,45 @@ describe("edge paths — additional branches", () => {
107
107
  expect(result.path).toMatch(/^M/)
108
108
  })
109
109
 
110
- it("getSmartHandlePositions with nodes at various positions", () => {
110
+ it('getSmartHandlePositions with nodes at various positions', () => {
111
111
  // Target to the left
112
112
  const leftward = getSmartHandlePositions(
113
- { id: "1", position: { x: 200, y: 0 }, data: {} },
114
- { id: "2", position: { x: 0, y: 0 }, data: {} },
113
+ { id: '1', position: { x: 200, y: 0 }, data: {} },
114
+ { id: '2', position: { x: 0, y: 0 }, data: {} },
115
115
  )
116
116
  expect(leftward.sourcePosition).toBe(Position.Left)
117
117
  expect(leftward.targetPosition).toBe(Position.Right)
118
118
 
119
119
  // Target below
120
120
  const downward = getSmartHandlePositions(
121
- { id: "1", position: { x: 0, y: 0 }, data: {} },
122
- { id: "2", position: { x: 0, y: 300 }, data: {} },
121
+ { id: '1', position: { x: 0, y: 0 }, data: {} },
122
+ { id: '2', position: { x: 0, y: 300 }, data: {} },
123
123
  )
124
124
  expect(downward.sourcePosition).toBe(Position.Bottom)
125
125
  expect(downward.targetPosition).toBe(Position.Top)
126
126
 
127
127
  // Target above
128
128
  const upward = getSmartHandlePositions(
129
- { id: "1", position: { x: 0, y: 300 }, data: {} },
130
- { id: "2", position: { x: 0, y: 0 }, data: {} },
129
+ { id: '1', position: { x: 0, y: 300 }, data: {} },
130
+ { id: '2', position: { x: 0, y: 0 }, data: {} },
131
131
  )
132
132
  expect(upward.sourcePosition).toBe(Position.Top)
133
133
  expect(upward.targetPosition).toBe(Position.Bottom)
134
134
  })
135
135
 
136
- it("getSmartHandlePositions with configured handles", () => {
136
+ it('getSmartHandlePositions with configured handles', () => {
137
137
  const result = getSmartHandlePositions(
138
138
  {
139
- id: "1",
139
+ id: '1',
140
140
  position: { x: 0, y: 0 },
141
141
  data: {},
142
- sourceHandles: [{ type: "source", position: Position.Bottom, id: "out" }],
142
+ sourceHandles: [{ type: 'source', position: Position.Bottom, id: 'out' }],
143
143
  },
144
144
  {
145
- id: "2",
145
+ id: '2',
146
146
  position: { x: 200, y: 200 },
147
147
  data: {},
148
- targetHandles: [{ type: "target", position: Position.Top, id: "in" }],
148
+ targetHandles: [{ type: 'target', position: Position.Top, id: 'in' }],
149
149
  },
150
150
  )
151
151
  // Should use configured handle positions
@@ -153,7 +153,7 @@ describe("edge paths — additional branches", () => {
153
153
  expect(result.targetPosition).toBe(Position.Top)
154
154
  })
155
155
 
156
- it("getWaypointPath with single waypoint", () => {
156
+ it('getWaypointPath with single waypoint', () => {
157
157
  const result = getWaypointPath({
158
158
  sourceX: 0,
159
159
  sourceY: 0,
@@ -161,7 +161,7 @@ describe("edge paths — additional branches", () => {
161
161
  targetY: 0,
162
162
  waypoints: [{ x: 100, y: 50 }],
163
163
  })
164
- expect(result.path).toBe("M0,0 L100,50 L200,0")
164
+ expect(result.path).toBe('M0,0 L100,50 L200,0')
165
165
  expect(result.labelX).toBe(100)
166
166
  expect(result.labelY).toBe(50)
167
167
  })
@@ -169,20 +169,20 @@ describe("edge paths — additional branches", () => {
169
169
 
170
170
  // ─── Flow — advanced operations ──────────────────────────────────────────────
171
171
 
172
- describe("createFlow — advanced", () => {
173
- describe("resolveCollisions", () => {
174
- it("pushes overlapping nodes apart", () => {
172
+ describe('createFlow — advanced', () => {
173
+ describe('resolveCollisions', () => {
174
+ it('pushes overlapping nodes apart', () => {
175
175
  const flow = createFlow({
176
176
  nodes: [
177
177
  {
178
- id: "1",
178
+ id: '1',
179
179
  position: { x: 0, y: 0 },
180
180
  width: 100,
181
181
  height: 50,
182
182
  data: {},
183
183
  },
184
184
  {
185
- id: "2",
185
+ id: '2',
186
186
  position: { x: 50, y: 0 },
187
187
  width: 100,
188
188
  height: 50,
@@ -191,25 +191,25 @@ describe("createFlow — advanced", () => {
191
191
  ],
192
192
  })
193
193
 
194
- flow.resolveCollisions("1")
194
+ flow.resolveCollisions('1')
195
195
  // Node 2 should have moved (either X or Y)
196
- const node2 = flow.getNode("2")!
196
+ const node2 = flow.getNode('2')!
197
197
  const moved = node2.position.x !== 50 || node2.position.y !== 0
198
198
  expect(moved).toBe(true)
199
199
  })
200
200
 
201
- it("does nothing when no overlaps", () => {
201
+ it('does nothing when no overlaps', () => {
202
202
  const flow = createFlow({
203
203
  nodes: [
204
204
  {
205
- id: "1",
205
+ id: '1',
206
206
  position: { x: 0, y: 0 },
207
207
  width: 100,
208
208
  height: 50,
209
209
  data: {},
210
210
  },
211
211
  {
212
- id: "2",
212
+ id: '2',
213
213
  position: { x: 500, y: 500 },
214
214
  width: 100,
215
215
  height: 50,
@@ -218,22 +218,22 @@ describe("createFlow — advanced", () => {
218
218
  ],
219
219
  })
220
220
 
221
- flow.resolveCollisions("1")
222
- expect(flow.getNode("2")!.position).toEqual({ x: 500, y: 500 })
221
+ flow.resolveCollisions('1')
222
+ expect(flow.getNode('2')!.position).toEqual({ x: 500, y: 500 })
223
223
  })
224
224
 
225
- it("resolves vertical overlaps", () => {
225
+ it('resolves vertical overlaps', () => {
226
226
  const flow = createFlow({
227
227
  nodes: [
228
228
  {
229
- id: "1",
229
+ id: '1',
230
230
  position: { x: 0, y: 0 },
231
231
  width: 200,
232
232
  height: 50,
233
233
  data: {},
234
234
  },
235
235
  {
236
- id: "2",
236
+ id: '2',
237
237
  position: { x: 0, y: 30 },
238
238
  width: 200,
239
239
  height: 50,
@@ -242,121 +242,121 @@ describe("createFlow — advanced", () => {
242
242
  ],
243
243
  })
244
244
 
245
- flow.resolveCollisions("1")
246
- const node2 = flow.getNode("2")!
245
+ flow.resolveCollisions('1')
246
+ const node2 = flow.getNode('2')!
247
247
  // Should push vertically since horizontal overlap is larger
248
248
  expect(node2.position.y).not.toBe(30)
249
249
  })
250
250
  })
251
251
 
252
- describe("getChildNodes / getAbsolutePosition", () => {
253
- it("returns child nodes of a group", () => {
252
+ describe('getChildNodes / getAbsolutePosition', () => {
253
+ it('returns child nodes of a group', () => {
254
254
  const flow = createFlow({
255
255
  nodes: [
256
256
  {
257
- id: "group",
257
+ id: 'group',
258
258
  position: { x: 0, y: 0 },
259
259
  group: true,
260
260
  data: {},
261
261
  },
262
262
  {
263
- id: "child1",
263
+ id: 'child1',
264
264
  position: { x: 10, y: 10 },
265
- parentId: "group",
265
+ parentId: 'group',
266
266
  data: {},
267
267
  },
268
268
  {
269
- id: "child2",
269
+ id: 'child2',
270
270
  position: { x: 20, y: 20 },
271
- parentId: "group",
271
+ parentId: 'group',
272
272
  data: {},
273
273
  },
274
- { id: "other", position: { x: 100, y: 100 }, data: {} },
274
+ { id: 'other', position: { x: 100, y: 100 }, data: {} },
275
275
  ],
276
276
  })
277
277
 
278
- const children = flow.getChildNodes("group")
278
+ const children = flow.getChildNodes('group')
279
279
  expect(children).toHaveLength(2)
280
- expect(children.map((n) => n.id)).toEqual(expect.arrayContaining(["child1", "child2"]))
280
+ expect(children.map((n) => n.id)).toEqual(expect.arrayContaining(['child1', 'child2']))
281
281
  })
282
282
 
283
- it("getAbsolutePosition accounts for parent offset", () => {
283
+ it('getAbsolutePosition accounts for parent offset', () => {
284
284
  const flow = createFlow({
285
285
  nodes: [
286
286
  {
287
- id: "parent",
287
+ id: 'parent',
288
288
  position: { x: 100, y: 200 },
289
289
  data: {},
290
290
  },
291
291
  {
292
- id: "child",
292
+ id: 'child',
293
293
  position: { x: 10, y: 20 },
294
- parentId: "parent",
294
+ parentId: 'parent',
295
295
  data: {},
296
296
  },
297
297
  ],
298
298
  })
299
299
 
300
- const abs = flow.getAbsolutePosition("child")
300
+ const abs = flow.getAbsolutePosition('child')
301
301
  expect(abs).toEqual({ x: 110, y: 220 })
302
302
  })
303
303
 
304
- it("getAbsolutePosition for root node returns position", () => {
304
+ it('getAbsolutePosition for root node returns position', () => {
305
305
  const flow = createFlow({
306
- nodes: [{ id: "1", position: { x: 50, y: 75 }, data: {} }],
306
+ nodes: [{ id: '1', position: { x: 50, y: 75 }, data: {} }],
307
307
  })
308
308
 
309
- expect(flow.getAbsolutePosition("1")).toEqual({ x: 50, y: 75 })
309
+ expect(flow.getAbsolutePosition('1')).toEqual({ x: 50, y: 75 })
310
310
  })
311
311
 
312
- it("getAbsolutePosition for missing node returns 0,0", () => {
312
+ it('getAbsolutePosition for missing node returns 0,0', () => {
313
313
  const flow = createFlow()
314
- expect(flow.getAbsolutePosition("missing")).toEqual({ x: 0, y: 0 })
314
+ expect(flow.getAbsolutePosition('missing')).toEqual({ x: 0, y: 0 })
315
315
  })
316
316
  })
317
317
 
318
- describe("moveSelectedNodes", () => {
319
- it("moves all selected nodes by delta", () => {
318
+ describe('moveSelectedNodes', () => {
319
+ it('moves all selected nodes by delta', () => {
320
320
  const flow = createFlow({
321
321
  nodes: [
322
- { id: "1", position: { x: 0, y: 0 }, data: {} },
323
- { id: "2", position: { x: 100, y: 0 }, data: {} },
324
- { id: "3", position: { x: 200, y: 0 }, data: {} },
322
+ { id: '1', position: { x: 0, y: 0 }, data: {} },
323
+ { id: '2', position: { x: 100, y: 0 }, data: {} },
324
+ { id: '3', position: { x: 200, y: 0 }, data: {} },
325
325
  ],
326
326
  })
327
327
 
328
- flow.selectNode("1")
329
- flow.selectNode("2", true)
328
+ flow.selectNode('1')
329
+ flow.selectNode('2', true)
330
330
  flow.moveSelectedNodes(50, 25)
331
331
 
332
- expect(flow.getNode("1")!.position).toEqual({ x: 50, y: 25 })
333
- expect(flow.getNode("2")!.position).toEqual({ x: 150, y: 25 })
334
- expect(flow.getNode("3")!.position).toEqual({ x: 200, y: 0 }) // not selected
332
+ expect(flow.getNode('1')!.position).toEqual({ x: 50, y: 25 })
333
+ expect(flow.getNode('2')!.position).toEqual({ x: 150, y: 25 })
334
+ expect(flow.getNode('3')!.position).toEqual({ x: 200, y: 0 }) // not selected
335
335
  })
336
336
 
337
- it("does nothing with no selection", () => {
337
+ it('does nothing with no selection', () => {
338
338
  const flow = createFlow({
339
- nodes: [{ id: "1", position: { x: 0, y: 0 }, data: {} }],
339
+ nodes: [{ id: '1', position: { x: 0, y: 0 }, data: {} }],
340
340
  })
341
341
 
342
342
  flow.moveSelectedNodes(100, 100)
343
- expect(flow.getNode("1")!.position).toEqual({ x: 0, y: 0 })
343
+ expect(flow.getNode('1')!.position).toEqual({ x: 0, y: 0 })
344
344
  })
345
345
  })
346
346
 
347
- describe("getSnapLines", () => {
348
- it("snaps to aligned nodes", () => {
347
+ describe('getSnapLines', () => {
348
+ it('snaps to aligned nodes', () => {
349
349
  const flow = createFlow({
350
350
  nodes: [
351
351
  {
352
- id: "1",
352
+ id: '1',
353
353
  position: { x: 100, y: 100 },
354
354
  width: 100,
355
355
  height: 50,
356
356
  data: {},
357
357
  },
358
358
  {
359
- id: "2",
359
+ id: '2',
360
360
  position: { x: 300, y: 200 },
361
361
  width: 100,
362
362
  height: 50,
@@ -366,23 +366,23 @@ describe("createFlow — advanced", () => {
366
366
  })
367
367
 
368
368
  // Move node 2 close to node 1's center X
369
- const snap = flow.getSnapLines("2", { x: 98, y: 200 })
369
+ const snap = flow.getSnapLines('2', { x: 98, y: 200 })
370
370
  expect(snap.x).not.toBeNull()
371
371
  expect(snap.snappedPosition.x).not.toBe(98)
372
372
  })
373
373
 
374
- it("returns null lines when no alignment", () => {
374
+ it('returns null lines when no alignment', () => {
375
375
  const flow = createFlow({
376
376
  nodes: [
377
377
  {
378
- id: "1",
378
+ id: '1',
379
379
  position: { x: 0, y: 0 },
380
380
  width: 100,
381
381
  height: 50,
382
382
  data: {},
383
383
  },
384
384
  {
385
- id: "2",
385
+ id: '2',
386
386
  position: { x: 500, y: 500 },
387
387
  width: 100,
388
388
  height: 50,
@@ -391,23 +391,23 @@ describe("createFlow — advanced", () => {
391
391
  ],
392
392
  })
393
393
 
394
- const snap = flow.getSnapLines("2", { x: 500, y: 500 })
394
+ const snap = flow.getSnapLines('2', { x: 500, y: 500 })
395
395
  expect(snap.x).toBeNull()
396
396
  expect(snap.y).toBeNull()
397
397
  })
398
398
 
399
- it("snaps to left edge alignment", () => {
399
+ it('snaps to left edge alignment', () => {
400
400
  const flow = createFlow({
401
401
  nodes: [
402
402
  {
403
- id: "1",
403
+ id: '1',
404
404
  position: { x: 100, y: 0 },
405
405
  width: 100,
406
406
  height: 50,
407
407
  data: {},
408
408
  },
409
409
  {
410
- id: "2",
410
+ id: '2',
411
411
  position: { x: 100, y: 100 },
412
412
  width: 100,
413
413
  height: 50,
@@ -417,22 +417,22 @@ describe("createFlow — advanced", () => {
417
417
  })
418
418
 
419
419
  // Node 2 is already aligned on left edge
420
- const snap = flow.getSnapLines("2", { x: 102, y: 100 })
420
+ const snap = flow.getSnapLines('2', { x: 102, y: 100 })
421
421
  expect(snap.snappedPosition.x).toBe(100) // snapped to left edge
422
422
  })
423
423
 
424
- it("snaps to right edge alignment", () => {
424
+ it('snaps to right edge alignment', () => {
425
425
  const flow = createFlow({
426
426
  nodes: [
427
427
  {
428
- id: "1",
428
+ id: '1',
429
429
  position: { x: 100, y: 0 },
430
430
  width: 100,
431
431
  height: 50,
432
432
  data: {},
433
433
  },
434
434
  {
435
- id: "2",
435
+ id: '2',
436
436
  position: { x: 100, y: 100 },
437
437
  width: 100,
438
438
  height: 50,
@@ -442,24 +442,24 @@ describe("createFlow — advanced", () => {
442
442
  })
443
443
 
444
444
  // Move node 2 so right edges almost align
445
- const snap = flow.getSnapLines("2", { x: 98, y: 100 })
445
+ const snap = flow.getSnapLines('2', { x: 98, y: 100 })
446
446
  // Right edge of node1: 200, right edge of moved node2: 98+100=198
447
447
  // Diff = 2, within threshold 5
448
448
  expect(snap.snappedPosition.x).toBe(100) // snapped
449
449
  })
450
450
 
451
- it("snaps to center Y alignment", () => {
451
+ it('snaps to center Y alignment', () => {
452
452
  const flow = createFlow({
453
453
  nodes: [
454
454
  {
455
- id: "1",
455
+ id: '1',
456
456
  position: { x: 0, y: 100 },
457
457
  width: 100,
458
458
  height: 50,
459
459
  data: {},
460
460
  },
461
461
  {
462
- id: "2",
462
+ id: '2',
463
463
  position: { x: 200, y: 0 },
464
464
  width: 100,
465
465
  height: 50,
@@ -470,22 +470,22 @@ describe("createFlow — advanced", () => {
470
470
 
471
471
  // center Y of node1 = 100+25 = 125
472
472
  // Move node2 so its center Y is close: y + 25 ≈ 125 → y ≈ 100
473
- const snap = flow.getSnapLines("2", { x: 200, y: 102 })
473
+ const snap = flow.getSnapLines('2', { x: 200, y: 102 })
474
474
  expect(snap.snappedPosition.y).toBe(100) // snapped to center Y
475
475
  })
476
476
 
477
- it("snaps to bottom edge alignment", () => {
477
+ it('snaps to bottom edge alignment', () => {
478
478
  const flow = createFlow({
479
479
  nodes: [
480
480
  {
481
- id: "1",
481
+ id: '1',
482
482
  position: { x: 0, y: 0 },
483
483
  width: 100,
484
484
  height: 50,
485
485
  data: {},
486
486
  },
487
487
  {
488
- id: "2",
488
+ id: '2',
489
489
  position: { x: 200, y: 0 },
490
490
  width: 100,
491
491
  height: 50,
@@ -496,75 +496,75 @@ describe("createFlow — advanced", () => {
496
496
 
497
497
  // bottom of node1 = 50, bottom of node2 = y + 50
498
498
  // For snap: abs(y+50 - 50) < 5 → abs(y) < 5
499
- const snap = flow.getSnapLines("2", { x: 200, y: 3 })
499
+ const snap = flow.getSnapLines('2', { x: 200, y: 3 })
500
500
  expect(snap.snappedPosition.y).toBe(0) // snapped to bottom edge
501
501
  })
502
502
 
503
- it("returns original position for missing node", () => {
503
+ it('returns original position for missing node', () => {
504
504
  const flow = createFlow()
505
- const snap = flow.getSnapLines("missing", { x: 100, y: 200 })
505
+ const snap = flow.getSnapLines('missing', { x: 100, y: 200 })
506
506
  expect(snap.snappedPosition).toEqual({ x: 100, y: 200 })
507
507
  })
508
508
  })
509
509
 
510
- describe("reconnectEdge", () => {
511
- it("changes edge source", () => {
510
+ describe('reconnectEdge', () => {
511
+ it('changes edge source', () => {
512
512
  const flow = createFlow({
513
513
  nodes: [
514
- { id: "1", position: { x: 0, y: 0 }, data: {} },
515
- { id: "2", position: { x: 100, y: 0 }, data: {} },
516
- { id: "3", position: { x: 200, y: 0 }, data: {} },
514
+ { id: '1', position: { x: 0, y: 0 }, data: {} },
515
+ { id: '2', position: { x: 100, y: 0 }, data: {} },
516
+ { id: '3', position: { x: 200, y: 0 }, data: {} },
517
517
  ],
518
- edges: [{ id: "e1", source: "1", target: "2" }],
518
+ edges: [{ id: 'e1', source: '1', target: '2' }],
519
519
  })
520
520
 
521
- flow.reconnectEdge("e1", { source: "3" })
522
- expect(flow.getEdge("e1")!.source).toBe("3")
523
- expect(flow.getEdge("e1")!.target).toBe("2") // unchanged
521
+ flow.reconnectEdge('e1', { source: '3' })
522
+ expect(flow.getEdge('e1')!.source).toBe('3')
523
+ expect(flow.getEdge('e1')!.target).toBe('2') // unchanged
524
524
  })
525
525
 
526
- it("changes edge target", () => {
526
+ it('changes edge target', () => {
527
527
  const flow = createFlow({
528
528
  nodes: [
529
- { id: "1", position: { x: 0, y: 0 }, data: {} },
530
- { id: "2", position: { x: 100, y: 0 }, data: {} },
531
- { id: "3", position: { x: 200, y: 0 }, data: {} },
529
+ { id: '1', position: { x: 0, y: 0 }, data: {} },
530
+ { id: '2', position: { x: 100, y: 0 }, data: {} },
531
+ { id: '3', position: { x: 200, y: 0 }, data: {} },
532
532
  ],
533
- edges: [{ id: "e1", source: "1", target: "2" }],
533
+ edges: [{ id: 'e1', source: '1', target: '2' }],
534
534
  })
535
535
 
536
- flow.reconnectEdge("e1", { target: "3" })
537
- expect(flow.getEdge("e1")!.target).toBe("3")
536
+ flow.reconnectEdge('e1', { target: '3' })
537
+ expect(flow.getEdge('e1')!.target).toBe('3')
538
538
  })
539
539
  })
540
540
 
541
- describe("edge with custom id and handle", () => {
542
- it("generates id from source/target handles", () => {
541
+ describe('edge with custom id and handle', () => {
542
+ it('generates id from source/target handles', () => {
543
543
  const flow = createFlow({
544
544
  nodes: [
545
- { id: "1", position: { x: 0, y: 0 }, data: {} },
546
- { id: "2", position: { x: 100, y: 0 }, data: {} },
545
+ { id: '1', position: { x: 0, y: 0 }, data: {} },
546
+ { id: '2', position: { x: 100, y: 0 }, data: {} },
547
547
  ],
548
548
  edges: [
549
549
  {
550
- source: "1",
551
- target: "2",
552
- sourceHandle: "out",
553
- targetHandle: "in",
550
+ source: '1',
551
+ target: '2',
552
+ sourceHandle: 'out',
553
+ targetHandle: 'in',
554
554
  },
555
555
  ],
556
556
  })
557
557
 
558
- expect(flow.edges()[0]!.id).toBe("e-1-out-2-in")
558
+ expect(flow.edges()[0]!.id).toBe('e-1-out-2-in')
559
559
  })
560
560
  })
561
561
 
562
- describe("fitView with initial config", () => {
563
- it("fits view on creation when config.fitView is true", () => {
562
+ describe('fitView with initial config', () => {
563
+ it('fits view on creation when config.fitView is true', () => {
564
564
  const flow = createFlow({
565
565
  nodes: [
566
- { id: "1", position: { x: 0, y: 0 }, data: {} },
567
- { id: "2", position: { x: 500, y: 500 }, data: {} },
566
+ { id: '1', position: { x: 0, y: 0 }, data: {} },
567
+ { id: '2', position: { x: 500, y: 500 }, data: {} },
568
568
  ],
569
569
  fitView: true,
570
570
  })
@@ -575,19 +575,19 @@ describe("createFlow — advanced", () => {
575
575
  })
576
576
  })
577
577
 
578
- describe("proximity connect with connection rules", () => {
579
- it("respects connection rules", () => {
578
+ describe('proximity connect with connection rules', () => {
579
+ it('respects connection rules', () => {
580
580
  const flow = createFlow({
581
581
  nodes: [
582
582
  {
583
- id: "1",
584
- type: "output",
583
+ id: '1',
584
+ type: 'output',
585
585
  position: { x: 0, y: 0 },
586
586
  data: {},
587
587
  },
588
588
  {
589
- id: "2",
590
- type: "input",
589
+ id: '2',
590
+ type: 'input',
591
591
  position: { x: 100, y: 0 },
592
592
  data: {},
593
593
  },
@@ -597,37 +597,37 @@ describe("createFlow — advanced", () => {
597
597
  },
598
598
  })
599
599
 
600
- expect(flow.getProximityConnection("1", 200)).toBeNull()
600
+ expect(flow.getProximityConnection('1', 200)).toBeNull()
601
601
  })
602
602
  })
603
603
 
604
- describe("undo/redo edge cases", () => {
605
- it("undo with empty history does nothing", () => {
604
+ describe('undo/redo edge cases', () => {
605
+ it('undo with empty history does nothing', () => {
606
606
  const flow = createFlow({
607
- nodes: [{ id: "1", position: { x: 0, y: 0 }, data: {} }],
607
+ nodes: [{ id: '1', position: { x: 0, y: 0 }, data: {} }],
608
608
  })
609
609
 
610
610
  flow.undo()
611
611
  expect(flow.nodes()).toHaveLength(1)
612
612
  })
613
613
 
614
- it("redo with empty redo stack does nothing", () => {
614
+ it('redo with empty redo stack does nothing', () => {
615
615
  const flow = createFlow({
616
- nodes: [{ id: "1", position: { x: 0, y: 0 }, data: {} }],
616
+ nodes: [{ id: '1', position: { x: 0, y: 0 }, data: {} }],
617
617
  })
618
618
 
619
619
  flow.redo()
620
620
  expect(flow.nodes()).toHaveLength(1)
621
621
  })
622
622
 
623
- it("multiple undo/redo cycles", () => {
623
+ it('multiple undo/redo cycles', () => {
624
624
  const flow = createFlow()
625
625
 
626
626
  flow.pushHistory()
627
- flow.addNode({ id: "1", position: { x: 0, y: 0 }, data: {} })
627
+ flow.addNode({ id: '1', position: { x: 0, y: 0 }, data: {} })
628
628
 
629
629
  flow.pushHistory()
630
- flow.addNode({ id: "2", position: { x: 100, y: 0 }, data: {} })
630
+ flow.addNode({ id: '2', position: { x: 100, y: 0 }, data: {} })
631
631
 
632
632
  expect(flow.nodes()).toHaveLength(2)
633
633
 
@@ -645,22 +645,22 @@ describe("createFlow — advanced", () => {
645
645
  })
646
646
  })
647
647
 
648
- describe("copy/paste with edges", () => {
649
- it("copies connected edges between selected nodes", () => {
648
+ describe('copy/paste with edges', () => {
649
+ it('copies connected edges between selected nodes', () => {
650
650
  const flow = createFlow({
651
651
  nodes: [
652
- { id: "1", position: { x: 0, y: 0 }, data: {} },
653
- { id: "2", position: { x: 100, y: 0 }, data: {} },
654
- { id: "3", position: { x: 200, y: 0 }, data: {} },
652
+ { id: '1', position: { x: 0, y: 0 }, data: {} },
653
+ { id: '2', position: { x: 100, y: 0 }, data: {} },
654
+ { id: '3', position: { x: 200, y: 0 }, data: {} },
655
655
  ],
656
656
  edges: [
657
- { source: "1", target: "2" },
658
- { source: "2", target: "3" },
657
+ { source: '1', target: '2' },
658
+ { source: '2', target: '3' },
659
659
  ],
660
660
  })
661
661
 
662
- flow.selectNode("1")
663
- flow.selectNode("2", true)
662
+ flow.selectNode('1')
663
+ flow.selectNode('2', true)
664
664
  flow.copySelected()
665
665
  flow.paste()
666
666
 
@@ -670,9 +670,9 @@ describe("createFlow — advanced", () => {
670
670
  expect(flow.edges()).toHaveLength(3)
671
671
  })
672
672
 
673
- it("copy with no selection does nothing", () => {
673
+ it('copy with no selection does nothing', () => {
674
674
  const flow = createFlow({
675
- nodes: [{ id: "1", position: { x: 0, y: 0 }, data: {} }],
675
+ nodes: [{ id: '1', position: { x: 0, y: 0 }, data: {} }],
676
676
  })
677
677
 
678
678
  flow.copySelected()
@@ -681,10 +681,10 @@ describe("createFlow — advanced", () => {
681
681
  })
682
682
  })
683
683
 
684
- describe("listener callbacks", () => {
685
- it("onNodeDragStart/End can be registered", () => {
684
+ describe('listener callbacks', () => {
685
+ it('onNodeDragStart/End can be registered', () => {
686
686
  const flow = createFlow({
687
- nodes: [{ id: "1", position: { x: 0, y: 0 }, data: {} }],
687
+ nodes: [{ id: '1', position: { x: 0, y: 0 }, data: {} }],
688
688
  })
689
689
 
690
690
  const starts: string[] = []
@@ -694,32 +694,32 @@ describe("createFlow — advanced", () => {
694
694
  flow.onNodeDragEnd((n) => ends.push(n.id))
695
695
 
696
696
  // Emit manually via _emit
697
- flow._emit.nodeDragStart(flow.getNode("1")!)
698
- flow._emit.nodeDragEnd(flow.getNode("1")!)
697
+ flow._emit.nodeDragStart(flow.getNode('1')!)
698
+ flow._emit.nodeDragEnd(flow.getNode('1')!)
699
699
 
700
- expect(starts).toEqual(["1"])
701
- expect(ends).toEqual(["1"])
700
+ expect(starts).toEqual(['1'])
701
+ expect(ends).toEqual(['1'])
702
702
  })
703
703
 
704
- it("onNodeDoubleClick", () => {
704
+ it('onNodeDoubleClick', () => {
705
705
  const flow = createFlow({
706
- nodes: [{ id: "1", position: { x: 0, y: 0 }, data: {} }],
706
+ nodes: [{ id: '1', position: { x: 0, y: 0 }, data: {} }],
707
707
  })
708
708
 
709
709
  const clicked: string[] = []
710
710
  flow.onNodeDoubleClick((n) => clicked.push(n.id))
711
711
 
712
- flow._emit.nodeDoubleClick(flow.getNode("1")!)
713
- expect(clicked).toEqual(["1"])
712
+ flow._emit.nodeDoubleClick(flow.getNode('1')!)
713
+ expect(clicked).toEqual(['1'])
714
714
  })
715
715
 
716
- it("onNodeClick / onEdgeClick", () => {
716
+ it('onNodeClick / onEdgeClick', () => {
717
717
  const flow = createFlow({
718
718
  nodes: [
719
- { id: "1", position: { x: 0, y: 0 }, data: {} },
720
- { id: "2", position: { x: 100, y: 0 }, data: {} },
719
+ { id: '1', position: { x: 0, y: 0 }, data: {} },
720
+ { id: '2', position: { x: 100, y: 0 }, data: {} },
721
721
  ],
722
- edges: [{ id: "e1", source: "1", target: "2" }],
722
+ edges: [{ id: 'e1', source: '1', target: '2' }],
723
723
  })
724
724
 
725
725
  const nodeClicks: string[] = []
@@ -728,29 +728,29 @@ describe("createFlow — advanced", () => {
728
728
  flow.onNodeClick((n) => nodeClicks.push(n.id))
729
729
  flow.onEdgeClick((e) => edgeClicks.push(e.id!))
730
730
 
731
- flow._emit.nodeClick(flow.getNode("1")!)
732
- flow._emit.edgeClick(flow.getEdge("e1")!)
731
+ flow._emit.nodeClick(flow.getNode('1')!)
732
+ flow._emit.edgeClick(flow.getEdge('e1')!)
733
733
 
734
- expect(nodeClicks).toEqual(["1"])
735
- expect(edgeClicks).toEqual(["e1"])
734
+ expect(nodeClicks).toEqual(['1'])
735
+ expect(edgeClicks).toEqual(['e1'])
736
736
  })
737
737
  })
738
738
 
739
- describe("containerSize", () => {
740
- it("containerSize signal exists with defaults", () => {
739
+ describe('containerSize', () => {
740
+ it('containerSize signal exists with defaults', () => {
741
741
  const flow = createFlow()
742
742
  expect(flow.containerSize()).toEqual({ width: 800, height: 600 })
743
743
  })
744
744
 
745
- it("containerSize can be updated", () => {
745
+ it('containerSize can be updated', () => {
746
746
  const flow = createFlow()
747
747
  flow.containerSize.set({ width: 1200, height: 900 })
748
748
  expect(flow.containerSize()).toEqual({ width: 1200, height: 900 })
749
749
  })
750
750
  })
751
751
 
752
- describe("clampToExtent", () => {
753
- it("returns position unchanged when no extent", () => {
752
+ describe('clampToExtent', () => {
753
+ it('returns position unchanged when no extent', () => {
754
754
  const flow = createFlow()
755
755
  expect(flow.clampToExtent({ x: -999, y: -999 })).toEqual({
756
756
  x: -999,
@@ -758,7 +758,7 @@ describe("createFlow — advanced", () => {
758
758
  })
759
759
  })
760
760
 
761
- it("clamps to extent boundaries", () => {
761
+ it('clamps to extent boundaries', () => {
762
762
  const flow = createFlow({
763
763
  nodeExtent: [
764
764
  [0, 0],
@@ -776,18 +776,18 @@ describe("createFlow — advanced", () => {
776
776
  })
777
777
  })
778
778
 
779
- describe("edge default type", () => {
780
- it("uses defaultEdgeType from config", () => {
779
+ describe('edge default type', () => {
780
+ it('uses defaultEdgeType from config', () => {
781
781
  const flow = createFlow({
782
782
  nodes: [
783
- { id: "1", position: { x: 0, y: 0 }, data: {} },
784
- { id: "2", position: { x: 100, y: 0 }, data: {} },
783
+ { id: '1', position: { x: 0, y: 0 }, data: {} },
784
+ { id: '2', position: { x: 100, y: 0 }, data: {} },
785
785
  ],
786
- edges: [{ source: "1", target: "2" }],
787
- defaultEdgeType: "straight",
786
+ edges: [{ source: '1', target: '2' }],
787
+ defaultEdgeType: 'straight',
788
788
  })
789
789
 
790
- expect(flow.edges()[0]!.type).toBe("straight")
790
+ expect(flow.edges()[0]!.type).toBe('straight')
791
791
  })
792
792
  })
793
793
  })