microboard-temp 0.13.19 → 0.13.21

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,60 @@ 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
+ hasActiveComponents() {
54470
+ return this.activeComponents.size > 0;
54471
+ }
54472
+ wake() {
54473
+ if (this.activeComponents.size > 0 && this.tickTimer === null) {
54474
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54445
54475
  }
54446
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54447
- this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
54448
54476
  }
54449
54477
  stop() {
54478
+ this.stopTimers();
54479
+ this.syncPositions();
54480
+ this.velocities.clear();
54481
+ this.lastSyncedPositions.clear();
54482
+ this.activeComponents.clear();
54483
+ }
54484
+ ensureRunning() {
54485
+ if (this.tickTimer === null) {
54486
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54487
+ }
54488
+ if (this.syncTimer === null) {
54489
+ this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
54490
+ }
54491
+ }
54492
+ stopTimers() {
54450
54493
  if (this.tickTimer !== null) {
54451
54494
  clearInterval(this.tickTimer);
54452
54495
  this.tickTimer = null;
@@ -54455,9 +54498,56 @@ class ForceGraphEngine {
54455
54498
  clearInterval(this.syncTimer);
54456
54499
  this.syncTimer = null;
54457
54500
  }
54458
- this.syncPositions();
54459
- this.velocities.clear();
54460
- this.lastSyncedPositions.clear();
54501
+ }
54502
+ findComponentId(nodeId) {
54503
+ for (const [compId, { nodeIds }] of this.activeComponents) {
54504
+ if (nodeIds.has(nodeId))
54505
+ return compId;
54506
+ }
54507
+ return;
54508
+ }
54509
+ bfsComponent(startNodeId) {
54510
+ const visited = new Set;
54511
+ const queue = [startNodeId];
54512
+ const connectors = this.getConnectors();
54513
+ while (queue.length > 0) {
54514
+ const nodeId = queue.shift();
54515
+ if (visited.has(nodeId))
54516
+ continue;
54517
+ visited.add(nodeId);
54518
+ for (const connector of connectors) {
54519
+ const { startItem, endItem } = connector.getConnectedItems();
54520
+ if (startItem?.getId() === nodeId && endItem && !visited.has(endItem.getId())) {
54521
+ queue.push(endItem.getId());
54522
+ }
54523
+ if (endItem?.getId() === nodeId && startItem && !visited.has(startItem.getId())) {
54524
+ queue.push(startItem.getId());
54525
+ }
54526
+ }
54527
+ }
54528
+ return visited;
54529
+ }
54530
+ calibrateTargetGap(nodeIds) {
54531
+ let totalMaxDim = 0;
54532
+ let count = 0;
54533
+ for (const id of nodeIds) {
54534
+ const item = this.board.items.getById(id);
54535
+ if (!item)
54536
+ continue;
54537
+ const mbr = item.getMbr();
54538
+ totalMaxDim += Math.max(mbr.getWidth(), mbr.getHeight());
54539
+ count++;
54540
+ }
54541
+ const avgMaxDim = count > 0 ? totalMaxDim / count : 100;
54542
+ return avgMaxDim * 0.3 + conf.FG_TARGET_GAP;
54543
+ }
54544
+ getActiveNodeIds() {
54545
+ const all6 = new Set;
54546
+ for (const { nodeIds } of this.activeComponents.values()) {
54547
+ for (const id of nodeIds)
54548
+ all6.add(id);
54549
+ }
54550
+ return all6;
54461
54551
  }
54462
54552
  getNodes() {
54463
54553
  return this.board.items.listAll().filter((item) => !EXCLUDED_TYPES.has(item.itemType) && !item.transformation.isLocked);
@@ -54467,8 +54557,10 @@ class ForceGraphEngine {
54467
54557
  }
54468
54558
  tick() {
54469
54559
  const dt = this.TICK_MS / 1000;
54470
- const nodes = this.getNodes();
54471
- if (nodes.length < 2)
54560
+ const activeIds = this.getActiveNodeIds();
54561
+ const allNodes = this.getNodes();
54562
+ const nodes = allNodes.filter((item) => activeIds.has(item.getId()));
54563
+ if (nodes.length < 1)
54472
54564
  return;
54473
54565
  const snapMap = new Map;
54474
54566
  for (const item of nodes) {
@@ -54509,7 +54601,9 @@ class ForceGraphEngine {
54509
54601
  const dx = s2.cx - s1.cx;
54510
54602
  const dy = s2.cy - s1.cy;
54511
54603
  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;
54604
+ const compId = this.findComponentId(s1.id);
54605
+ const targetGap = compId ? this.activeComponents.get(compId)?.targetGap ?? conf.FG_TARGET_GAP : conf.FG_TARGET_GAP;
54606
+ const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + targetGap;
54513
54607
  const stretch = dist - targetDist;
54514
54608
  const forceMag = stretch * conf.FG_SPRING_K;
54515
54609
  const fx = dx / dist * forceMag;
@@ -54527,10 +54621,13 @@ class ForceGraphEngine {
54527
54621
  continue;
54528
54622
  const dx = s2.cx - s1.cx;
54529
54623
  const dy = s2.cy - s1.cy;
54530
- const distSq = dx * dx + dy * dy + this.SOFTENING_SQ;
54531
- const repMag = conf.FG_REPULSION / distSq;
54532
- const fx = dx * repMag;
54533
- const fy = dy * repMag;
54624
+ const centerDist = Math.sqrt(dx * dx + dy * dy) + 0.001;
54625
+ const r1 = Math.max(s1.w, s1.h) * 0.5;
54626
+ const r2 = Math.max(s2.w, s2.h) * 0.5;
54627
+ const edgeDist = Math.max(centerDist - r1 - r2, 1);
54628
+ const repMag = conf.FG_REPULSION / (edgeDist * edgeDist + this.SOFTENING_SQ);
54629
+ const fx = dx / centerDist * repMag;
54630
+ const fy = dy / centerDist * repMag;
54534
54631
  ax.set(s1.id, (ax.get(s1.id) ?? 0) - fx);
54535
54632
  ay.set(s1.id, (ay.get(s1.id) ?? 0) - fy);
54536
54633
  ax.set(s2.id, (ax.get(s2.id) ?? 0) + fx);
@@ -54567,7 +54664,8 @@ class ForceGraphEngine {
54567
54664
  }
54568
54665
  }
54569
54666
  syncPositions() {
54570
- const nodes = this.getNodes();
54667
+ const activeIds = this.getActiveNodeIds();
54668
+ const nodes = this.getNodes().filter((item) => activeIds.has(item.getId()));
54571
54669
  if (nodes.length === 0)
54572
54670
  return;
54573
54671
  const movedItems = nodes.map((item) => {
@@ -54591,11 +54689,6 @@ class ForceGraphEngine {
54591
54689
  };
54592
54690
  this.board.events.emit(operation);
54593
54691
  }
54594
- wake() {
54595
- if (this.tickTimer === null && this.syncTimer !== null) {
54596
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54597
- }
54598
- }
54599
54692
  }
54600
54693
 
54601
54694
  // src/Board.ts
@@ -55671,20 +55764,22 @@ class Board {
55671
55764
  return this.gravity !== null;
55672
55765
  }
55673
55766
  forceGraph = null;
55674
- enableForceGraph() {
55675
- if (this.forceGraph)
55676
- return;
55677
- this.forceGraph = new ForceGraphEngine(this);
55678
- this.forceGraph.start();
55767
+ enableForceGraph(nodeId) {
55768
+ if (!this.forceGraph) {
55769
+ this.forceGraph = new ForceGraphEngine(this);
55770
+ }
55771
+ this.forceGraph.enableForGraph(nodeId);
55679
55772
  }
55680
- disableForceGraph() {
55773
+ disableForceGraph(nodeId) {
55681
55774
  if (!this.forceGraph)
55682
55775
  return;
55683
- this.forceGraph.stop();
55684
- this.forceGraph = null;
55776
+ this.forceGraph.disableForGraph(nodeId);
55777
+ if (!this.forceGraph.hasActiveComponents()) {
55778
+ this.forceGraph = null;
55779
+ }
55685
55780
  }
55686
- isForceGraphEnabled() {
55687
- return this.forceGraph !== null;
55781
+ isNodeInForceGraph(nodeId) {
55782
+ return this.forceGraph?.isNodeInActiveGraph(nodeId) ?? false;
55688
55783
  }
55689
55784
  wakeForceGraph() {
55690
55785
  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,60 @@ 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
+ hasActiveComponents() {
56938
+ return this.activeComponents.size > 0;
56939
+ }
56940
+ wake() {
56941
+ if (this.activeComponents.size > 0 && this.tickTimer === null) {
56942
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
56913
56943
  }
56914
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
56915
- this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
56916
56944
  }
56917
56945
  stop() {
56946
+ this.stopTimers();
56947
+ this.syncPositions();
56948
+ this.velocities.clear();
56949
+ this.lastSyncedPositions.clear();
56950
+ this.activeComponents.clear();
56951
+ }
56952
+ ensureRunning() {
56953
+ if (this.tickTimer === null) {
56954
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
56955
+ }
56956
+ if (this.syncTimer === null) {
56957
+ this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
56958
+ }
56959
+ }
56960
+ stopTimers() {
56918
56961
  if (this.tickTimer !== null) {
56919
56962
  clearInterval(this.tickTimer);
56920
56963
  this.tickTimer = null;
@@ -56923,9 +56966,56 @@ class ForceGraphEngine {
56923
56966
  clearInterval(this.syncTimer);
56924
56967
  this.syncTimer = null;
56925
56968
  }
56926
- this.syncPositions();
56927
- this.velocities.clear();
56928
- this.lastSyncedPositions.clear();
56969
+ }
56970
+ findComponentId(nodeId) {
56971
+ for (const [compId, { nodeIds }] of this.activeComponents) {
56972
+ if (nodeIds.has(nodeId))
56973
+ return compId;
56974
+ }
56975
+ return;
56976
+ }
56977
+ bfsComponent(startNodeId) {
56978
+ const visited = new Set;
56979
+ const queue = [startNodeId];
56980
+ const connectors = this.getConnectors();
56981
+ while (queue.length > 0) {
56982
+ const nodeId = queue.shift();
56983
+ if (visited.has(nodeId))
56984
+ continue;
56985
+ visited.add(nodeId);
56986
+ for (const connector of connectors) {
56987
+ const { startItem, endItem } = connector.getConnectedItems();
56988
+ if (startItem?.getId() === nodeId && endItem && !visited.has(endItem.getId())) {
56989
+ queue.push(endItem.getId());
56990
+ }
56991
+ if (endItem?.getId() === nodeId && startItem && !visited.has(startItem.getId())) {
56992
+ queue.push(startItem.getId());
56993
+ }
56994
+ }
56995
+ }
56996
+ return visited;
56997
+ }
56998
+ calibrateTargetGap(nodeIds) {
56999
+ let totalMaxDim = 0;
57000
+ let count = 0;
57001
+ for (const id of nodeIds) {
57002
+ const item = this.board.items.getById(id);
57003
+ if (!item)
57004
+ continue;
57005
+ const mbr = item.getMbr();
57006
+ totalMaxDim += Math.max(mbr.getWidth(), mbr.getHeight());
57007
+ count++;
57008
+ }
57009
+ const avgMaxDim = count > 0 ? totalMaxDim / count : 100;
57010
+ return avgMaxDim * 0.3 + conf.FG_TARGET_GAP;
57011
+ }
57012
+ getActiveNodeIds() {
57013
+ const all6 = new Set;
57014
+ for (const { nodeIds } of this.activeComponents.values()) {
57015
+ for (const id of nodeIds)
57016
+ all6.add(id);
57017
+ }
57018
+ return all6;
56929
57019
  }
56930
57020
  getNodes() {
56931
57021
  return this.board.items.listAll().filter((item) => !EXCLUDED_TYPES.has(item.itemType) && !item.transformation.isLocked);
@@ -56935,8 +57025,10 @@ class ForceGraphEngine {
56935
57025
  }
56936
57026
  tick() {
56937
57027
  const dt = this.TICK_MS / 1000;
56938
- const nodes = this.getNodes();
56939
- if (nodes.length < 2)
57028
+ const activeIds = this.getActiveNodeIds();
57029
+ const allNodes = this.getNodes();
57030
+ const nodes = allNodes.filter((item) => activeIds.has(item.getId()));
57031
+ if (nodes.length < 1)
56940
57032
  return;
56941
57033
  const snapMap = new Map;
56942
57034
  for (const item of nodes) {
@@ -56977,7 +57069,9 @@ class ForceGraphEngine {
56977
57069
  const dx = s2.cx - s1.cx;
56978
57070
  const dy = s2.cy - s1.cy;
56979
57071
  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;
57072
+ const compId = this.findComponentId(s1.id);
57073
+ const targetGap = compId ? this.activeComponents.get(compId)?.targetGap ?? conf.FG_TARGET_GAP : conf.FG_TARGET_GAP;
57074
+ const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + targetGap;
56981
57075
  const stretch = dist - targetDist;
56982
57076
  const forceMag = stretch * conf.FG_SPRING_K;
56983
57077
  const fx = dx / dist * forceMag;
@@ -56995,10 +57089,13 @@ class ForceGraphEngine {
56995
57089
  continue;
56996
57090
  const dx = s2.cx - s1.cx;
56997
57091
  const dy = s2.cy - s1.cy;
56998
- const distSq = dx * dx + dy * dy + this.SOFTENING_SQ;
56999
- const repMag = conf.FG_REPULSION / distSq;
57000
- const fx = dx * repMag;
57001
- const fy = dy * repMag;
57092
+ const centerDist = Math.sqrt(dx * dx + dy * dy) + 0.001;
57093
+ const r1 = Math.max(s1.w, s1.h) * 0.5;
57094
+ const r2 = Math.max(s2.w, s2.h) * 0.5;
57095
+ const edgeDist = Math.max(centerDist - r1 - r2, 1);
57096
+ const repMag = conf.FG_REPULSION / (edgeDist * edgeDist + this.SOFTENING_SQ);
57097
+ const fx = dx / centerDist * repMag;
57098
+ const fy = dy / centerDist * repMag;
57002
57099
  ax.set(s1.id, (ax.get(s1.id) ?? 0) - fx);
57003
57100
  ay.set(s1.id, (ay.get(s1.id) ?? 0) - fy);
57004
57101
  ax.set(s2.id, (ax.get(s2.id) ?? 0) + fx);
@@ -57035,7 +57132,8 @@ class ForceGraphEngine {
57035
57132
  }
57036
57133
  }
57037
57134
  syncPositions() {
57038
- const nodes = this.getNodes();
57135
+ const activeIds = this.getActiveNodeIds();
57136
+ const nodes = this.getNodes().filter((item) => activeIds.has(item.getId()));
57039
57137
  if (nodes.length === 0)
57040
57138
  return;
57041
57139
  const movedItems = nodes.map((item) => {
@@ -57059,11 +57157,6 @@ class ForceGraphEngine {
57059
57157
  };
57060
57158
  this.board.events.emit(operation);
57061
57159
  }
57062
- wake() {
57063
- if (this.tickTimer === null && this.syncTimer !== null) {
57064
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
57065
- }
57066
- }
57067
57160
  }
57068
57161
 
57069
57162
  // src/Board.ts
@@ -58139,20 +58232,22 @@ class Board {
58139
58232
  return this.gravity !== null;
58140
58233
  }
58141
58234
  forceGraph = null;
58142
- enableForceGraph() {
58143
- if (this.forceGraph)
58144
- return;
58145
- this.forceGraph = new ForceGraphEngine(this);
58146
- this.forceGraph.start();
58235
+ enableForceGraph(nodeId) {
58236
+ if (!this.forceGraph) {
58237
+ this.forceGraph = new ForceGraphEngine(this);
58238
+ }
58239
+ this.forceGraph.enableForGraph(nodeId);
58147
58240
  }
58148
- disableForceGraph() {
58241
+ disableForceGraph(nodeId) {
58149
58242
  if (!this.forceGraph)
58150
58243
  return;
58151
- this.forceGraph.stop();
58152
- this.forceGraph = null;
58244
+ this.forceGraph.disableForGraph(nodeId);
58245
+ if (!this.forceGraph.hasActiveComponents()) {
58246
+ this.forceGraph = null;
58247
+ }
58153
58248
  }
58154
- isForceGraphEnabled() {
58155
- return this.forceGraph !== null;
58249
+ isNodeInForceGraph(nodeId) {
58250
+ return this.forceGraph?.isNodeInActiveGraph(nodeId) ?? false;
58156
58251
  }
58157
58252
  wakeForceGraph() {
58158
58253
  this.forceGraph?.wake();
@@ -140,9 +140,12 @@ 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;
146
149
  /** Call after dragging a node to re-wake the physics engine if it was sleeping. */
147
150
  wakeForceGraph(): void;
148
151
  }
@@ -5,17 +5,45 @@ 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
+ hasActiveComponents(): boolean;
29
+ /** Re-wake physics after a node is manually dragged. */
30
+ wake(): void;
31
+ /** Full stop — called when Board destroys the engine. */
14
32
  stop(): void;
33
+ private ensureRunning;
34
+ private stopTimers;
35
+ /** Find the componentId (Map key) for the component containing `nodeId`. */
36
+ private findComponentId;
37
+ /** BFS through connector graph starting from `startNodeId`. */
38
+ private bfsComponent;
39
+ /**
40
+ * Auto-calibrate spring target gap from the average max(w, h) of nodes in the component.
41
+ * Larger nodes → longer springs so items visually breathe.
42
+ */
43
+ private calibrateTargetGap;
44
+ private getActiveNodeIds;
15
45
  private getNodes;
16
46
  private getConnectors;
17
47
  private tick;
18
48
  private syncPositions;
19
- /** Re-wake the engine after user moves a node (dragging disturbs equilibrium). */
20
- wake(): void;
21
49
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "microboard-temp",
3
- "version": "0.13.19",
3
+ "version": "0.13.21",
4
4
  "description": "A flexible interactive whiteboard library",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",