microboard-temp 0.13.20 → 0.13.22

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/dist/esm/index.js CHANGED
@@ -54428,6 +54428,7 @@ class ForceGraphEngine {
54428
54428
  tickTimer = null;
54429
54429
  syncTimer = null;
54430
54430
  lastSyncedPositions = new Map;
54431
+ activeComponents = new Map;
54431
54432
  TICK_MS = 33;
54432
54433
  SYNC_MS = 300;
54433
54434
  SOFTENING_SQ = 100 * 100;
@@ -54435,18 +54436,74 @@ class ForceGraphEngine {
54435
54436
  constructor(board) {
54436
54437
  this.board = board;
54437
54438
  }
54438
- start() {
54439
- if (this.tickTimer !== null)
54439
+ enableForGraph(startNodeId) {
54440
+ if (this.isNodeInActiveGraph(startNodeId))
54440
54441
  return;
54441
- for (const item of this.getNodes()) {
54442
- const pos = item.transformation.getTranslation();
54443
- this.lastSyncedPositions.set(item.getId(), { x: pos.x, y: pos.y });
54444
- this.velocities.set(item.getId(), { vx: 0, vy: 0 });
54442
+ const nodeIds = this.bfsComponent(startNodeId);
54443
+ const targetGap = this.calibrateTargetGap(nodeIds);
54444
+ this.activeComponents.set(startNodeId, { nodeIds, targetGap });
54445
+ for (const id of nodeIds) {
54446
+ if (!this.velocities.has(id)) {
54447
+ this.velocities.set(id, { vx: 0, vy: 0 });
54448
+ }
54449
+ const item = this.board.items.getById(id);
54450
+ if (item && !this.lastSyncedPositions.has(id)) {
54451
+ const pos = item.transformation.getTranslation();
54452
+ this.lastSyncedPositions.set(id, { x: pos.x, y: pos.y });
54453
+ }
54454
+ }
54455
+ this.ensureRunning();
54456
+ }
54457
+ disableForGraph(nodeId) {
54458
+ const compId = this.findComponentId(nodeId);
54459
+ if (!compId)
54460
+ return;
54461
+ this.activeComponents.delete(compId);
54462
+ if (this.activeComponents.size === 0) {
54463
+ this.stopTimers();
54464
+ }
54465
+ }
54466
+ isNodeInActiveGraph(nodeId) {
54467
+ return !!this.findComponentId(nodeId);
54468
+ }
54469
+ getComponentTargetGap(nodeId) {
54470
+ const compId = this.findComponentId(nodeId);
54471
+ return compId ? this.activeComponents.get(compId)?.targetGap : undefined;
54472
+ }
54473
+ setComponentTargetGap(nodeId, gap) {
54474
+ const compId = this.findComponentId(nodeId);
54475
+ if (!compId)
54476
+ return;
54477
+ const comp = this.activeComponents.get(compId);
54478
+ if (!comp)
54479
+ return;
54480
+ comp.targetGap = gap;
54481
+ this.wake();
54482
+ }
54483
+ hasActiveComponents() {
54484
+ return this.activeComponents.size > 0;
54485
+ }
54486
+ wake() {
54487
+ if (this.activeComponents.size > 0 && this.tickTimer === null) {
54488
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54445
54489
  }
54446
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54447
- this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
54448
54490
  }
54449
54491
  stop() {
54492
+ this.stopTimers();
54493
+ this.syncPositions();
54494
+ this.velocities.clear();
54495
+ this.lastSyncedPositions.clear();
54496
+ this.activeComponents.clear();
54497
+ }
54498
+ ensureRunning() {
54499
+ if (this.tickTimer === null) {
54500
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54501
+ }
54502
+ if (this.syncTimer === null) {
54503
+ this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
54504
+ }
54505
+ }
54506
+ stopTimers() {
54450
54507
  if (this.tickTimer !== null) {
54451
54508
  clearInterval(this.tickTimer);
54452
54509
  this.tickTimer = null;
@@ -54455,9 +54512,56 @@ class ForceGraphEngine {
54455
54512
  clearInterval(this.syncTimer);
54456
54513
  this.syncTimer = null;
54457
54514
  }
54458
- this.syncPositions();
54459
- this.velocities.clear();
54460
- this.lastSyncedPositions.clear();
54515
+ }
54516
+ findComponentId(nodeId) {
54517
+ for (const [compId, { nodeIds }] of this.activeComponents) {
54518
+ if (nodeIds.has(nodeId))
54519
+ return compId;
54520
+ }
54521
+ return;
54522
+ }
54523
+ bfsComponent(startNodeId) {
54524
+ const visited = new Set;
54525
+ const queue = [startNodeId];
54526
+ const connectors = this.getConnectors();
54527
+ while (queue.length > 0) {
54528
+ const nodeId = queue.shift();
54529
+ if (visited.has(nodeId))
54530
+ continue;
54531
+ visited.add(nodeId);
54532
+ for (const connector of connectors) {
54533
+ const { startItem, endItem } = connector.getConnectedItems();
54534
+ if (startItem?.getId() === nodeId && endItem && !visited.has(endItem.getId())) {
54535
+ queue.push(endItem.getId());
54536
+ }
54537
+ if (endItem?.getId() === nodeId && startItem && !visited.has(startItem.getId())) {
54538
+ queue.push(startItem.getId());
54539
+ }
54540
+ }
54541
+ }
54542
+ return visited;
54543
+ }
54544
+ calibrateTargetGap(nodeIds) {
54545
+ let totalMaxDim = 0;
54546
+ let count = 0;
54547
+ for (const id of nodeIds) {
54548
+ const item = this.board.items.getById(id);
54549
+ if (!item)
54550
+ continue;
54551
+ const mbr = item.getMbr();
54552
+ totalMaxDim += Math.max(mbr.getWidth(), mbr.getHeight());
54553
+ count++;
54554
+ }
54555
+ const avgMaxDim = count > 0 ? totalMaxDim / count : 100;
54556
+ return avgMaxDim * 1.5;
54557
+ }
54558
+ getActiveNodeIds() {
54559
+ const all6 = new Set;
54560
+ for (const { nodeIds } of this.activeComponents.values()) {
54561
+ for (const id of nodeIds)
54562
+ all6.add(id);
54563
+ }
54564
+ return all6;
54461
54565
  }
54462
54566
  getNodes() {
54463
54567
  return this.board.items.listAll().filter((item) => !EXCLUDED_TYPES.has(item.itemType) && !item.transformation.isLocked);
@@ -54467,8 +54571,10 @@ class ForceGraphEngine {
54467
54571
  }
54468
54572
  tick() {
54469
54573
  const dt = this.TICK_MS / 1000;
54470
- const nodes = this.getNodes();
54471
- if (nodes.length < 2)
54574
+ const activeIds = this.getActiveNodeIds();
54575
+ const allNodes = this.getNodes();
54576
+ const nodes = allNodes.filter((item) => activeIds.has(item.getId()));
54577
+ if (nodes.length < 1)
54472
54578
  return;
54473
54579
  const snapMap = new Map;
54474
54580
  for (const item of nodes) {
@@ -54509,7 +54615,9 @@ class ForceGraphEngine {
54509
54615
  const dx = s2.cx - s1.cx;
54510
54616
  const dy = s2.cy - s1.cy;
54511
54617
  const dist = Math.sqrt(dx * dx + dy * dy) + 0.001;
54512
- const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + conf.FG_TARGET_GAP;
54618
+ const compId = this.findComponentId(s1.id);
54619
+ const targetGap = compId ? this.activeComponents.get(compId)?.targetGap ?? conf.FG_TARGET_GAP : conf.FG_TARGET_GAP;
54620
+ const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + targetGap;
54513
54621
  const stretch = dist - targetDist;
54514
54622
  const forceMag = stretch * conf.FG_SPRING_K;
54515
54623
  const fx = dx / dist * forceMag;
@@ -54570,7 +54678,8 @@ class ForceGraphEngine {
54570
54678
  }
54571
54679
  }
54572
54680
  syncPositions() {
54573
- const nodes = this.getNodes();
54681
+ const activeIds = this.getActiveNodeIds();
54682
+ const nodes = this.getNodes().filter((item) => activeIds.has(item.getId()));
54574
54683
  if (nodes.length === 0)
54575
54684
  return;
54576
54685
  const movedItems = nodes.map((item) => {
@@ -54594,11 +54703,6 @@ class ForceGraphEngine {
54594
54703
  };
54595
54704
  this.board.events.emit(operation);
54596
54705
  }
54597
- wake() {
54598
- if (this.tickTimer === null && this.syncTimer !== null) {
54599
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54600
- }
54601
- }
54602
54706
  }
54603
54707
 
54604
54708
  // src/Board.ts
@@ -55674,20 +55778,28 @@ class Board {
55674
55778
  return this.gravity !== null;
55675
55779
  }
55676
55780
  forceGraph = null;
55677
- enableForceGraph() {
55678
- if (this.forceGraph)
55679
- return;
55680
- this.forceGraph = new ForceGraphEngine(this);
55681
- this.forceGraph.start();
55781
+ enableForceGraph(nodeId) {
55782
+ if (!this.forceGraph) {
55783
+ this.forceGraph = new ForceGraphEngine(this);
55784
+ }
55785
+ this.forceGraph.enableForGraph(nodeId);
55682
55786
  }
55683
- disableForceGraph() {
55787
+ disableForceGraph(nodeId) {
55684
55788
  if (!this.forceGraph)
55685
55789
  return;
55686
- this.forceGraph.stop();
55687
- this.forceGraph = null;
55790
+ this.forceGraph.disableForGraph(nodeId);
55791
+ if (!this.forceGraph.hasActiveComponents()) {
55792
+ this.forceGraph = null;
55793
+ }
55794
+ }
55795
+ isNodeInForceGraph(nodeId) {
55796
+ return this.forceGraph?.isNodeInActiveGraph(nodeId) ?? false;
55797
+ }
55798
+ getForceGraphGap(nodeId) {
55799
+ return this.forceGraph?.getComponentTargetGap(nodeId);
55688
55800
  }
55689
- isForceGraphEnabled() {
55690
- return this.forceGraph !== null;
55801
+ setForceGraphGap(nodeId, gap) {
55802
+ this.forceGraph?.setComponentTargetGap(nodeId, gap);
55691
55803
  }
55692
55804
  wakeForceGraph() {
55693
55805
  this.forceGraph?.wake();
package/dist/esm/node.js CHANGED
@@ -56896,6 +56896,7 @@ class ForceGraphEngine {
56896
56896
  tickTimer = null;
56897
56897
  syncTimer = null;
56898
56898
  lastSyncedPositions = new Map;
56899
+ activeComponents = new Map;
56899
56900
  TICK_MS = 33;
56900
56901
  SYNC_MS = 300;
56901
56902
  SOFTENING_SQ = 100 * 100;
@@ -56903,18 +56904,74 @@ class ForceGraphEngine {
56903
56904
  constructor(board) {
56904
56905
  this.board = board;
56905
56906
  }
56906
- start() {
56907
- if (this.tickTimer !== null)
56907
+ enableForGraph(startNodeId) {
56908
+ if (this.isNodeInActiveGraph(startNodeId))
56908
56909
  return;
56909
- for (const item of this.getNodes()) {
56910
- const pos = item.transformation.getTranslation();
56911
- this.lastSyncedPositions.set(item.getId(), { x: pos.x, y: pos.y });
56912
- this.velocities.set(item.getId(), { vx: 0, vy: 0 });
56910
+ const nodeIds = this.bfsComponent(startNodeId);
56911
+ const targetGap = this.calibrateTargetGap(nodeIds);
56912
+ this.activeComponents.set(startNodeId, { nodeIds, targetGap });
56913
+ for (const id of nodeIds) {
56914
+ if (!this.velocities.has(id)) {
56915
+ this.velocities.set(id, { vx: 0, vy: 0 });
56916
+ }
56917
+ const item = this.board.items.getById(id);
56918
+ if (item && !this.lastSyncedPositions.has(id)) {
56919
+ const pos = item.transformation.getTranslation();
56920
+ this.lastSyncedPositions.set(id, { x: pos.x, y: pos.y });
56921
+ }
56922
+ }
56923
+ this.ensureRunning();
56924
+ }
56925
+ disableForGraph(nodeId) {
56926
+ const compId = this.findComponentId(nodeId);
56927
+ if (!compId)
56928
+ return;
56929
+ this.activeComponents.delete(compId);
56930
+ if (this.activeComponents.size === 0) {
56931
+ this.stopTimers();
56932
+ }
56933
+ }
56934
+ isNodeInActiveGraph(nodeId) {
56935
+ return !!this.findComponentId(nodeId);
56936
+ }
56937
+ getComponentTargetGap(nodeId) {
56938
+ const compId = this.findComponentId(nodeId);
56939
+ return compId ? this.activeComponents.get(compId)?.targetGap : undefined;
56940
+ }
56941
+ setComponentTargetGap(nodeId, gap) {
56942
+ const compId = this.findComponentId(nodeId);
56943
+ if (!compId)
56944
+ return;
56945
+ const comp = this.activeComponents.get(compId);
56946
+ if (!comp)
56947
+ return;
56948
+ comp.targetGap = gap;
56949
+ this.wake();
56950
+ }
56951
+ hasActiveComponents() {
56952
+ return this.activeComponents.size > 0;
56953
+ }
56954
+ wake() {
56955
+ if (this.activeComponents.size > 0 && this.tickTimer === null) {
56956
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
56913
56957
  }
56914
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
56915
- this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
56916
56958
  }
56917
56959
  stop() {
56960
+ this.stopTimers();
56961
+ this.syncPositions();
56962
+ this.velocities.clear();
56963
+ this.lastSyncedPositions.clear();
56964
+ this.activeComponents.clear();
56965
+ }
56966
+ ensureRunning() {
56967
+ if (this.tickTimer === null) {
56968
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
56969
+ }
56970
+ if (this.syncTimer === null) {
56971
+ this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
56972
+ }
56973
+ }
56974
+ stopTimers() {
56918
56975
  if (this.tickTimer !== null) {
56919
56976
  clearInterval(this.tickTimer);
56920
56977
  this.tickTimer = null;
@@ -56923,9 +56980,56 @@ class ForceGraphEngine {
56923
56980
  clearInterval(this.syncTimer);
56924
56981
  this.syncTimer = null;
56925
56982
  }
56926
- this.syncPositions();
56927
- this.velocities.clear();
56928
- this.lastSyncedPositions.clear();
56983
+ }
56984
+ findComponentId(nodeId) {
56985
+ for (const [compId, { nodeIds }] of this.activeComponents) {
56986
+ if (nodeIds.has(nodeId))
56987
+ return compId;
56988
+ }
56989
+ return;
56990
+ }
56991
+ bfsComponent(startNodeId) {
56992
+ const visited = new Set;
56993
+ const queue = [startNodeId];
56994
+ const connectors = this.getConnectors();
56995
+ while (queue.length > 0) {
56996
+ const nodeId = queue.shift();
56997
+ if (visited.has(nodeId))
56998
+ continue;
56999
+ visited.add(nodeId);
57000
+ for (const connector of connectors) {
57001
+ const { startItem, endItem } = connector.getConnectedItems();
57002
+ if (startItem?.getId() === nodeId && endItem && !visited.has(endItem.getId())) {
57003
+ queue.push(endItem.getId());
57004
+ }
57005
+ if (endItem?.getId() === nodeId && startItem && !visited.has(startItem.getId())) {
57006
+ queue.push(startItem.getId());
57007
+ }
57008
+ }
57009
+ }
57010
+ return visited;
57011
+ }
57012
+ calibrateTargetGap(nodeIds) {
57013
+ let totalMaxDim = 0;
57014
+ let count = 0;
57015
+ for (const id of nodeIds) {
57016
+ const item = this.board.items.getById(id);
57017
+ if (!item)
57018
+ continue;
57019
+ const mbr = item.getMbr();
57020
+ totalMaxDim += Math.max(mbr.getWidth(), mbr.getHeight());
57021
+ count++;
57022
+ }
57023
+ const avgMaxDim = count > 0 ? totalMaxDim / count : 100;
57024
+ return avgMaxDim * 1.5;
57025
+ }
57026
+ getActiveNodeIds() {
57027
+ const all6 = new Set;
57028
+ for (const { nodeIds } of this.activeComponents.values()) {
57029
+ for (const id of nodeIds)
57030
+ all6.add(id);
57031
+ }
57032
+ return all6;
56929
57033
  }
56930
57034
  getNodes() {
56931
57035
  return this.board.items.listAll().filter((item) => !EXCLUDED_TYPES.has(item.itemType) && !item.transformation.isLocked);
@@ -56935,8 +57039,10 @@ class ForceGraphEngine {
56935
57039
  }
56936
57040
  tick() {
56937
57041
  const dt = this.TICK_MS / 1000;
56938
- const nodes = this.getNodes();
56939
- if (nodes.length < 2)
57042
+ const activeIds = this.getActiveNodeIds();
57043
+ const allNodes = this.getNodes();
57044
+ const nodes = allNodes.filter((item) => activeIds.has(item.getId()));
57045
+ if (nodes.length < 1)
56940
57046
  return;
56941
57047
  const snapMap = new Map;
56942
57048
  for (const item of nodes) {
@@ -56977,7 +57083,9 @@ class ForceGraphEngine {
56977
57083
  const dx = s2.cx - s1.cx;
56978
57084
  const dy = s2.cy - s1.cy;
56979
57085
  const dist = Math.sqrt(dx * dx + dy * dy) + 0.001;
56980
- const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + conf.FG_TARGET_GAP;
57086
+ const compId = this.findComponentId(s1.id);
57087
+ const targetGap = compId ? this.activeComponents.get(compId)?.targetGap ?? conf.FG_TARGET_GAP : conf.FG_TARGET_GAP;
57088
+ const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + targetGap;
56981
57089
  const stretch = dist - targetDist;
56982
57090
  const forceMag = stretch * conf.FG_SPRING_K;
56983
57091
  const fx = dx / dist * forceMag;
@@ -57038,7 +57146,8 @@ class ForceGraphEngine {
57038
57146
  }
57039
57147
  }
57040
57148
  syncPositions() {
57041
- const nodes = this.getNodes();
57149
+ const activeIds = this.getActiveNodeIds();
57150
+ const nodes = this.getNodes().filter((item) => activeIds.has(item.getId()));
57042
57151
  if (nodes.length === 0)
57043
57152
  return;
57044
57153
  const movedItems = nodes.map((item) => {
@@ -57062,11 +57171,6 @@ class ForceGraphEngine {
57062
57171
  };
57063
57172
  this.board.events.emit(operation);
57064
57173
  }
57065
- wake() {
57066
- if (this.tickTimer === null && this.syncTimer !== null) {
57067
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
57068
- }
57069
- }
57070
57174
  }
57071
57175
 
57072
57176
  // src/Board.ts
@@ -58142,20 +58246,28 @@ class Board {
58142
58246
  return this.gravity !== null;
58143
58247
  }
58144
58248
  forceGraph = null;
58145
- enableForceGraph() {
58146
- if (this.forceGraph)
58147
- return;
58148
- this.forceGraph = new ForceGraphEngine(this);
58149
- this.forceGraph.start();
58249
+ enableForceGraph(nodeId) {
58250
+ if (!this.forceGraph) {
58251
+ this.forceGraph = new ForceGraphEngine(this);
58252
+ }
58253
+ this.forceGraph.enableForGraph(nodeId);
58150
58254
  }
58151
- disableForceGraph() {
58255
+ disableForceGraph(nodeId) {
58152
58256
  if (!this.forceGraph)
58153
58257
  return;
58154
- this.forceGraph.stop();
58155
- this.forceGraph = null;
58258
+ this.forceGraph.disableForGraph(nodeId);
58259
+ if (!this.forceGraph.hasActiveComponents()) {
58260
+ this.forceGraph = null;
58261
+ }
58262
+ }
58263
+ isNodeInForceGraph(nodeId) {
58264
+ return this.forceGraph?.isNodeInActiveGraph(nodeId) ?? false;
58265
+ }
58266
+ getForceGraphGap(nodeId) {
58267
+ return this.forceGraph?.getComponentTargetGap(nodeId);
58156
58268
  }
58157
- isForceGraphEnabled() {
58158
- return this.forceGraph !== null;
58269
+ setForceGraphGap(nodeId, gap) {
58270
+ this.forceGraph?.setComponentTargetGap(nodeId, gap);
58159
58271
  }
58160
58272
  wakeForceGraph() {
58161
58273
  this.forceGraph?.wake();
@@ -140,9 +140,16 @@ export declare class Board {
140
140
  disableGravity(): void;
141
141
  isGravityEnabled(): boolean;
142
142
  private forceGraph;
143
- enableForceGraph(): void;
144
- disableForceGraph(): void;
145
- isForceGraphEnabled(): boolean;
143
+ /** Enable force-directed layout for the connected component containing `nodeId`. */
144
+ enableForceGraph(nodeId: string): void;
145
+ /** Disable graph mode for the component containing `nodeId`. */
146
+ disableForceGraph(nodeId: string): void;
147
+ /** Returns true if `nodeId` is currently in an active force-directed component. */
148
+ isNodeInForceGraph(nodeId: string): boolean;
149
+ /** Get the connector target gap (px) for the component containing `nodeId`. */
150
+ getForceGraphGap(nodeId: string): number | undefined;
151
+ /** Set the connector target gap (px) for the component containing `nodeId`. */
152
+ setForceGraphGap(nodeId: string, gap: number): void;
146
153
  /** Call after dragging a node to re-wake the physics engine if it was sleeping. */
147
154
  wakeForceGraph(): void;
148
155
  }
@@ -5,17 +5,49 @@ export declare class ForceGraphEngine {
5
5
  private tickTimer;
6
6
  private syncTimer;
7
7
  private lastSyncedPositions;
8
+ /** Active components: componentId → { nodeIds, targetGap }
9
+ * componentId is the nodeId that was passed to enableForGraph(). */
10
+ private activeComponents;
8
11
  private readonly TICK_MS;
9
12
  private readonly SYNC_MS;
10
13
  private readonly SOFTENING_SQ;
11
14
  private readonly MIN_MOVE_PX;
12
15
  constructor(board: Board);
13
- start(): void;
16
+ /**
17
+ * Enable force-directed layout for the connected component containing `startNodeId`.
18
+ * BFS walks the connector graph to find all nodes in the component.
19
+ * `targetGap` is auto-calibrated from the average node size; callers may override via conf.
20
+ */
21
+ enableForGraph(startNodeId: string): void;
22
+ /**
23
+ * Disable graph mode for the component containing `nodeId`.
24
+ * Stops the engine entirely if no components remain active.
25
+ */
26
+ disableForGraph(nodeId: string): void;
27
+ isNodeInActiveGraph(nodeId: string): boolean;
28
+ /** Get the current target gap for the component containing `nodeId`. Returns undefined if not active. */
29
+ getComponentTargetGap(nodeId: string): number | undefined;
30
+ /** Update the target gap (connector length) for the component containing `nodeId` and re-wake. */
31
+ setComponentTargetGap(nodeId: string, gap: number): void;
32
+ hasActiveComponents(): boolean;
33
+ /** Re-wake physics after a node is manually dragged. */
34
+ wake(): void;
35
+ /** Full stop — called when Board destroys the engine. */
14
36
  stop(): void;
37
+ private ensureRunning;
38
+ private stopTimers;
39
+ /** Find the componentId (Map key) for the component containing `nodeId`. */
40
+ private findComponentId;
41
+ /** BFS through connector graph starting from `startNodeId`. */
42
+ private bfsComponent;
43
+ /**
44
+ * Auto-calibrate spring target gap from the average max(w, h) of nodes in the component.
45
+ * Larger nodes → longer springs so items visually breathe.
46
+ */
47
+ private calibrateTargetGap;
48
+ private getActiveNodeIds;
15
49
  private getNodes;
16
50
  private getConnectors;
17
51
  private tick;
18
52
  private syncPositions;
19
- /** Re-wake the engine after user moves a node (dragging disturbs equilibrium). */
20
- wake(): void;
21
53
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "microboard-temp",
3
- "version": "0.13.20",
3
+ "version": "0.13.22",
4
4
  "description": "A flexible interactive whiteboard library",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",