@fusefactory/fuse-three-forcegraph 1.0.5 → 1.0.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.
Files changed (4) hide show
  1. package/README.md +61 -43
  2. package/dist/index.d.mts +869 -860
  3. package/dist/index.mjs +725 -649
  4. package/package.json +12 -12
package/dist/index.d.mts CHANGED
@@ -1,10 +1,48 @@
1
1
  import CameraControls from "camera-controls";
2
2
  import * as THREE from "three";
3
3
 
4
+ //#region core/Clock.d.ts
5
+ /**
6
+ * Clock - Unified timing for the force graph package
7
+ */
8
+ declare class Clock {
9
+ private previousTime;
10
+ private elapsedTime;
11
+ private deltaTime;
12
+ private isRunning;
13
+ private maxDeltaTime;
14
+ constructor();
15
+ /**
16
+ * Start the clock
17
+ */
18
+ start(): void;
19
+ /**
20
+ * Stop the clock
21
+ */
22
+ stop(): void;
23
+ /**
24
+ * Update the clock - call once per frame
25
+ * @returns delta time in seconds
26
+ */
27
+ update(): number;
28
+ /**
29
+ * Get delta time in seconds
30
+ */
31
+ getDeltaTime(): number;
32
+ /**
33
+ * Get total elapsed time in seconds
34
+ */
35
+ getElapsedTime(): number;
36
+ /**
37
+ * Check if clock is running
38
+ */
39
+ getIsRunning(): boolean;
40
+ }
41
+ //#endregion
4
42
  //#region types/iCameraMode.d.ts
5
43
  declare enum CameraMode {
6
44
  Orbit = "orbit",
7
- Map = "map"
45
+ Map = "map",
8
46
  }
9
47
  //#endregion
10
48
  //#region rendering/CameraController.d.ts
@@ -42,70 +80,70 @@ declare class CameraController {
42
80
  constructor(domelement: HTMLElement, config?: CameraConfig);
43
81
  private setupDefaultControls;
44
82
  /**
45
- * Set camera control mode
46
- */
83
+ * Set camera control mode
84
+ */
47
85
  setMode(mode: CameraMode): void;
48
86
  /**
49
- * Set camera boundary
50
- */
87
+ * Set camera boundary
88
+ */
51
89
  setBoundary(box: THREE.Box3): void;
52
90
  /**
53
- * Update camera controls (should be called in render loop)
54
- * Only autorotate if enabled and user is inactive
55
- */
91
+ * Update camera controls (should be called in render loop)
92
+ * Only autorotate if enabled and user is inactive
93
+ */
56
94
  update(delta: number): boolean;
57
95
  /**
58
- * Set autorotate enabled/disabled
59
- */
96
+ * Set autorotate enabled/disabled
97
+ */
60
98
  setAutorotate(enabled: boolean, speed?: number): void;
61
99
  /**
62
- * Set user activity state
63
- */
100
+ * Set user activity state
101
+ */
64
102
  setUserIsActive(isActive: boolean): void;
65
103
  /**
66
- * Configure camera controls
67
- */
104
+ * Configure camera controls
105
+ */
68
106
  configureControls(config: ControlsConfig): void;
69
107
  /**
70
- * Resize camera when window resizes
71
- */
108
+ * Resize camera when window resizes
109
+ */
72
110
  resize(width: number, height: number): void;
73
111
  /**
74
- * Animate camera to look at a specific target from a specific position
75
- */
112
+ * Animate camera to look at a specific target from a specific position
113
+ */
76
114
  setLookAt(position: THREE.Vector3, target: THREE.Vector3, enableTransition?: boolean): Promise<void>;
77
115
  /**
78
- * Reset camera to default position
79
- */
80
- reset(enableTransition?: boolean): Promise<void>;
116
+ * Reset camera to default position
117
+ */
118
+ reset(position?: THREE.Vector3, target?: THREE.Vector3, enableTransition?: boolean): Promise<void>;
81
119
  /**
82
- * Enable/disable controls
83
- */
120
+ * Enable/disable controls
121
+ */
84
122
  setEnabled(enabled: boolean): void;
85
123
  /**
86
- * Get current camera target (look-at point)
87
- */
124
+ * Get current camera target (look-at point)
125
+ */
88
126
  getTarget(out?: THREE.Vector3): THREE.Vector3;
89
127
  /**
90
- * Dispose camera manager and clean up
91
- */
128
+ * Dispose camera manager and clean up
129
+ */
92
130
  dispose(): void;
93
131
  /**
94
- * Clear camera bounds (remove boundary restrictions)
95
- */
132
+ * Clear camera bounds (remove boundary restrictions)
133
+ */
96
134
  clearBounds(): void;
97
135
  /**
98
- * Get current scene bounds
99
- */
136
+ * Get current scene bounds
137
+ */
100
138
  getSceneBounds(): THREE.Box3 | null;
101
139
  /**
102
- * Update scene bounds used by the camera manager.
103
- * Stores the bounds for future use (e.g. constraining controls).
104
- */
140
+ * Update scene bounds used by the camera manager.
141
+ * Stores the bounds for future use (e.g. constraining controls).
142
+ */
105
143
  updateBounds(box: THREE.Box3): void;
106
144
  /**
107
- * Unified configuration method
108
- */
145
+ * Unified configuration method
146
+ */
109
147
  setOptions(options: {
110
148
  controls?: ControlsConfig;
111
149
  autoRotate?: boolean;
@@ -113,6 +151,9 @@ declare class CameraController {
113
151
  }): void;
114
152
  }
115
153
  //#endregion
154
+ //#region rendering/PostProcessing.d.ts
155
+ type AntialiasingMode = 'msaa' | 'smaa' | 'fxaa' | 'none';
156
+ //#endregion
116
157
  //#region types/iGraphLink.d.ts
117
158
  interface GraphLink {
118
159
  source: string;
@@ -142,7 +183,7 @@ declare enum NodeState {
142
183
  // = 1 rendered, not influencing simulation,
143
184
  Fixed = 2,
144
185
  // = 2 rendered, influencing simulation, but not moving
145
- Active = 3
186
+ Active = 3,
146
187
  }
147
188
  //#endregion
148
189
  //#region types/iGraphData.d.ts
@@ -242,85 +283,29 @@ interface TooltipConfig {
242
283
  cursorHandler?: CursorHandler;
243
284
  }
244
285
  //#endregion
245
- //#region rendering/PostProcessing.d.ts
246
- type AntialiasingMode = 'msaa' | 'smaa' | 'fxaa' | 'none';
247
- //#endregion
248
- //#region core/EventEmitter.d.ts
249
- declare class EventEmitter {
250
- private listeners;
251
- protected listenerCount(event: string): number;
252
- on(event: string, listener: Function): () => void;
253
- off(event: string, listener: Function): void;
254
- emit(event: string, ...args: any[]): void;
255
- }
256
- //#endregion
257
- //#region controls/InputProcessor.d.ts
286
+ //#region textures/PickBuffer.d.ts
258
287
  /**
259
- * Manages pointer/mouse input and emits interaction events
260
- * Uses GPU picking for efficient node detection
288
+ * Manages GPU picking buffer for mouse interaction
289
+ * Separate from simulation buffers as it has different lifecycle
261
290
  */
262
- declare class InputProcessor extends EventEmitter {
263
- private pickFn;
264
- private canvas;
265
- private viewport;
266
- private readonly CLICK_THRESHOLD;
267
- private readonly HOVER_TO_POP_MS;
268
- private pointer;
269
- private canvasPointer;
270
- private isPointerDown;
271
- private isDragging;
272
- private mouseDownTime;
273
- private draggedIndex;
274
- private currentHoverIndex;
275
- private hoverStartTime;
276
- private hoverProgress;
277
- private hasPopped;
278
- private isTouch;
279
- private readonly TOUCH_MOVE_THRESHOLD;
280
- private pointerDownX;
281
- private pointerDownY;
282
- private lastClientX;
283
- private lastClientY;
284
- constructor(pickFn: (x: number, y: number) => number, // Injected
285
- canvas: HTMLCanvasElement, viewport: {
286
- width: number;
287
- height: number;
288
- });
289
- private setupEventListeners;
290
- private handlePointerMove;
291
- private handlePointerDown;
292
- private handlePointerUp;
293
- private handlePointerLeave;
294
- private updateHover;
295
- /**
296
- * Update hover state even when pointer is stationary
297
- * Called from render loop
298
- */
299
- update(): void;
300
- private updatePointer;
291
+ declare class PickBuffer {
292
+ private renderer;
293
+ private pickTarget;
294
+ constructor(renderer: THREE.WebGLRenderer);
301
295
  /**
302
- * Update viewport dimensions on resize
303
- */
296
+ * Ensure pick buffer matches viewport size
297
+ */
304
298
  resize(width: number, height: number): void;
305
- dispose(): void;
306
- }
307
- //#endregion
308
- //#region controls/handlers/HoverHandler.d.ts
309
- declare class HoverHandler extends EventEmitter {
310
- private getNodeByIndex;
311
- constructor(getNodeByIndex: (index: number) => GraphNode | null);
312
- private handleHoverStart;
313
- private handleHover;
314
- private handlePop;
315
- private handleHoverEnd;
316
- dispose(): void;
317
- }
318
- //#endregion
319
- //#region controls/handlers/ClickHandler.d.ts
320
- declare class ClickHandler extends EventEmitter {
321
- private getNodeByIndex;
322
- constructor(getNodeByIndex: (index: number) => GraphNode | null);
323
- private handleClick;
299
+ private createPickBuffer;
300
+ /**
301
+ * Read node ID at pixel coordinates
302
+ */
303
+ readIdAt(x: number, y: number): number;
304
+ /**
305
+ * Render scene to pick buffer
306
+ */
307
+ render(scene: THREE.Scene, camera: THREE.Camera): void;
308
+ getTarget(): THREE.WebGLRenderTarget | null;
324
309
  dispose(): void;
325
310
  }
326
311
  //#endregion
@@ -338,51 +323,51 @@ declare class SimulationBuffers {
338
323
  private isInitialized;
339
324
  constructor(renderer: THREE.WebGLRenderer);
340
325
  /**
341
- * Check if buffers are initialized
342
- */
326
+ * Check if buffers are initialized
327
+ */
343
328
  isReady(): boolean;
344
329
  /**
345
- * Initialize buffers with point count and initial positions
346
- */
330
+ * Initialize buffers with point count and initial positions
331
+ */
347
332
  init(pointsCount: number, initialPositions?: Float32Array): void;
348
333
  /**
349
- * Resize buffers (re-initializes with new size)
350
- */
334
+ * Resize buffers (re-initializes with new size)
335
+ */
351
336
  resize(pointsCount: number, preserveData?: boolean): void;
352
337
  private calculateTextureSize;
353
338
  private createDynamicBuffer;
354
339
  /**
355
- * Initialize position buffers from initial data
356
- */
340
+ * Initialize position buffers from initial data
341
+ */
357
342
  setInitialPositions(positionArray: Float32Array): void;
358
343
  /**
359
- * Update current and previous positions, but keep original positions intact
360
- */
344
+ * Update current and previous positions, but keep original positions intact
345
+ */
361
346
  updateCurrentPositions(positionArray: Float32Array): void;
362
347
  /**
363
- * Set original positions (anchors) separately from current positions
364
- */
348
+ * Set original positions (anchors) separately from current positions
349
+ */
365
350
  setOriginalPositions(positionArray: Float32Array): void;
366
351
  /**
367
- * Initialize velocity buffers (usually to zero)
368
- */
352
+ * Initialize velocity buffers (usually to zero)
353
+ */
369
354
  initVelocities(): void;
370
355
  /**
371
- * Swap position buffers (ping-pong)
372
- */
356
+ * Swap position buffers (ping-pong)
357
+ */
373
358
  swapPositions(): void;
374
359
  /**
375
- * Swap velocity buffers (ping-pong)
376
- */
360
+ * Swap velocity buffers (ping-pong)
361
+ */
377
362
  swapVelocities(): void;
378
363
  /**
379
- * Reset positions to original state
380
- */
364
+ * Reset positions to original state
365
+ */
381
366
  resetPositions(): void;
382
367
  /**
383
- * Read current positions back from GPU (expensive operation)
384
- * Returns RGBA float array (x, y, z, state)
385
- */
368
+ * Read current positions back from GPU (expensive operation)
369
+ * Returns RGBA float array (x, y, z, state)
370
+ */
386
371
  readPositions(): Float32Array;
387
372
  getCurrentPositionTarget(): THREE.WebGLRenderTarget | null;
388
373
  getPreviousPositionTarget(): THREE.WebGLRenderTarget | null;
@@ -401,619 +386,569 @@ declare class SimulationBuffers {
401
386
  dispose(): void;
402
387
  }
403
388
  //#endregion
404
- //#region types/iAttractor.d.ts
405
- /**
406
- * Simple 3D vector type
407
- */
408
- interface Vec3 {
409
- x: number;
410
- y: number;
411
- z: number;
412
- }
413
- /**
414
- * Attractor - A point in space that attracts nodes of specific groups
415
- */
416
- interface Attractor {
417
- /** Unique identifier */
418
- id: string;
419
- /** Position in world space */
420
- position: Vec3;
421
- /** Radius of attraction (default: 0.0) - nodes within this radius are not pulled further */
422
- radius?: number;
423
- /** Groups of nodes attracted to this attractor (empty = attracts all) */
424
- groups: string[];
425
- /** Strength of attraction (default: 1.0) */
426
- strength?: number;
427
- }
428
- /**
429
- * Resolved attractor with defaults applied
430
- */
431
- interface ResolvedAttractor {
432
- id: string;
433
- position: Vec3;
434
- groups: string[];
435
- strength: number;
436
- radius: number;
437
- }
438
- //#endregion
439
- //#region textures/StaticAssets.d.ts
389
+ //#region rendering/links/LinksRenderer.d.ts
440
390
  /**
441
- * Manages read-only GPU textures created at initialization
442
- * These never change during simulation (except for mode changes)
443
- *
444
- * Node data: radii, colors
445
- * Link data: source/target indices, properties
391
+ * LinksRenderer - Renders links as line segments
392
+ * Uses shared SimulationBuffers for node positions
393
+ * Manages link-specific opacity and highlighting
446
394
  */
447
- declare class StaticAssets {
448
- private nodeRadiiTexture;
449
- private nodeColorsTexture;
450
- private linkIndicesTexture;
451
- private linkPropertiesTexture;
452
- private nodeLinkMapTexture;
453
- private nodeTextureSize;
454
- private linkTextureSize;
455
- constructor();
395
+ declare class LinksRenderer {
396
+ private scene;
397
+ private renderer;
398
+ private lines;
399
+ private links;
400
+ private nodeIndexMap;
401
+ private linkIndexMap;
402
+ private interpolationSteps;
403
+ params: {
404
+ noiseStrength: number;
405
+ defaultAlpha: number;
406
+ highlightAlpha: number;
407
+ dimmedAlpha: number;
408
+ is2D: boolean;
409
+ };
410
+ private linkOpacity;
411
+ private simulationBuffers;
412
+ constructor(scene: THREE.Scene, renderer: THREE.WebGLRenderer);
456
413
  /**
457
- * Set/update node radii texture
458
- */
459
- setNodeRadii(radii: Float32Array, textureSize: number): void;
414
+ * Create link geometry and materials
415
+ * Receives shared buffers as dependencies
416
+ */
417
+ create(links: GraphLink[], nodes: GraphNode[], simulationBuffers: SimulationBuffers): void;
460
418
  /**
461
- * Set/update node colors texture
462
- */
463
- setNodeColors(colors: Float32Array, textureSize: number): void;
419
+ * Update position texture from simulation
420
+ * This is the SHARED texture used by both nodes and links
421
+ */
422
+ setPositionTexture(positionTexture: THREE.Texture): void;
464
423
  /**
465
- * Set link indices (source/target pairs)
466
- * Format: [sourceX, sourceY, targetX, targetY] per link
467
- */
468
- setLinkIndices(linkIndices: Float32Array, textureSize: number): void;
424
+ * Update shader uniforms (called each frame)
425
+ */
426
+ update(time: number): void;
469
427
  /**
470
- * Set link properties (strength, distance, etc.)
471
- */
472
- setLinkProperties(linkProperties: Float32Array, textureSize: number): void;
473
- setNodeLinkMap(linkMap: Float32Array, textureSize: number): void;
428
+ * Update link opacity (called every frame)
429
+ */
430
+ updateOpacity(): void;
474
431
  /**
475
- * Create a data texture with proper settings for GPU compute
476
- */
477
- private createTexture;
478
- getNodeRadiiTexture(): THREE.DataTexture | null;
479
- getNodeColorsTexture(): THREE.DataTexture | null;
480
- getLinkIndicesTexture(): THREE.DataTexture | null;
481
- getLinkPropertiesTexture(): THREE.DataTexture | null;
482
- getLinkMapTexture(): THREE.DataTexture | null;
483
- getNodeTextureSize(): number;
484
- getLinkTextureSize(): number;
432
+ * Highlight links connected to a specific node
433
+ */
434
+ highlightConnectedLinks(nodeId: string, step?: number): void;
485
435
  /**
486
- * Check if assets are ready
487
- */
488
- hasNodeAssets(): boolean;
489
- hasLinkAssets(): boolean;
436
+ * Highlight links connected to any of the given nodes
437
+ */
438
+ highlightConnectedToNodes(nodeIds: Set<string>, step?: number): void;
490
439
  /**
491
- * Cleanup
492
- */
493
- dispose(): void;
494
- }
495
- declare const staticAssets: StaticAssets;
496
- //#endregion
497
- //#region simulation/BasePass.d.ts
498
- interface PassContext {
499
- scene: THREE.Scene;
500
- camera: THREE.Camera;
501
- quad: THREE.BufferGeometry;
502
- simBuffers: SimulationBuffers;
503
- assets: StaticAssets;
504
- renderer: THREE.WebGLRenderer;
505
- config: ForceConfig;
506
- textureSize: number;
507
- }
508
- /**
509
- * Base class for GPU force simulation passes
510
- * Each pass operates on simulation buffers and can read from static assets
511
- */
512
- declare abstract class BasePass {
513
- protected material: THREE.ShaderMaterial | null;
514
- protected enabled: boolean;
440
+ * Clear all highlights (return to defaultAlpha)
441
+ */
442
+ clearHighlights(step?: number): void;
515
443
  /**
516
- * Get the name/identifier for this pass
517
- */
518
- abstract getName(): string;
444
+ * Update noise strength parameter
445
+ */
446
+ setNoiseStrength(strength: number): void;
519
447
  /**
520
- * Initialize the shader material for this pass
521
- */
522
- abstract initMaterial(context: PassContext): void;
448
+ * Update alpha parameters
449
+ */
450
+ setAlphaParams(params: {
451
+ defaultAlpha?: number;
452
+ highlightAlpha?: number;
453
+ dimmedAlpha?: number;
454
+ }): void;
523
455
  /**
524
- * Update uniforms before executing the pass
525
- */
526
- abstract updateUniforms(context: PassContext): void;
456
+ * Unified configuration method
457
+ */
458
+ setOptions(options: LinkOptions): void;
527
459
  /**
528
- * Execute the pass (renders to current velocity target)
529
- */
530
- execute(context: PassContext): void;
460
+ * Refresh shader uniforms when params change
461
+ */
462
+ refreshUniforms(): void;
531
463
  /**
532
- * Render the compute shader
533
- */
534
- protected render(context: PassContext): void;
464
+ * Handle window resize
465
+ */
466
+ resize(width: number, height: number): void;
535
467
  /**
536
- * Create a shader material helper
537
- */
538
- protected createMaterial(vertexShader: string, fragmentShader: string, uniforms: {
539
- [uniform: string]: THREE.IUniform;
540
- }): THREE.ShaderMaterial;
468
+ * Set visibility of links
469
+ */
470
+ setVisible(visible: boolean): void;
541
471
  /**
542
- * Safe uniform setter - avoids TypeScript strict null check issues
543
- */
544
- protected setUniform(name: string, value: unknown): void;
472
+ * Check if links are visible
473
+ */
474
+ isVisible(): boolean;
545
475
  /**
546
- * Enable or disable this pass
547
- */
548
- setEnabled(enabled: boolean): void;
476
+ * Cleanup
477
+ */
478
+ dispose(): void;
549
479
  /**
550
- * Check if pass is enabled
551
- */
552
- isEnabled(): boolean;
480
+ * Build node index mapping
481
+ */
482
+ private buildNodeMapping;
553
483
  /**
554
- * Get the material for external access
555
- */
556
- getMaterial(): THREE.ShaderMaterial | null;
484
+ * Builds the instanced link geometry and per-link attribute buffers used by the renderer.
485
+ *
486
+ * This method:
487
+ * - Creates a line-segment template with interpolation parameter `t` for each vertex pair.
488
+ * - Encodes link endpoints as texture-space coordinates (`instanceLinkA` / `instanceLinkB`)
489
+ * so shaders can fetch node positions from a node texture.
490
+ * - Derives endpoint colors from source/target node categories.
491
+ * - Assigns a stable per-instance alpha lookup index.
492
+ * - Computes a category-based visibility rank from the **target node category**.
493
+ *
494
+ * Rank/alpha behavior:
495
+ * - Categories are ranked by `groupOrder` (unknown categories are appended).
496
+ * - The rank is converted to an attenuation factor with inverted weighting:
497
+ * `instanceRank = 1.0 - 0.75 * (rank / maxRank)`.
498
+ * - This means rank `0` keeps full weight (`1.0`), while the highest rank trends to `0.25`.
499
+ *
500
+ * Also returns a `linkIndexMap` keyed as `"sourceId-targetId"` for quick instance lookup.
501
+ *
502
+ * @param links - Graph links to encode as geometry instances.
503
+ * @param nodes - Graph nodes used for category/color lookup.
504
+ * @param nodeTextureSize - Width/height of the square node data texture used for index-to-UV conversion.
505
+ * @param groupOrder - Preferred category ordering for rank assignment (earlier = stronger visibility).
506
+ * @returns An object containing:
507
+ * - `geometry`: the populated `THREE.InstancedBufferGeometry`
508
+ * - `linkIndexMap`: map from link id (`"sourceId-targetId"`) to instance index
509
+ */
510
+ private createLinkGeometry;
557
511
  /**
558
- * Cleanup resources
559
- */
560
- dispose(): void;
561
- }
562
- //#endregion
563
- //#region simulation/passes/AttractorPass.d.ts
564
- /**
565
- * Attractor force pass - attracts nodes to attractor points based on group membership
566
- *
567
- * Usage:
568
- * attractorPass.setAttractors([
569
- * { id: 'center', position: { x: 0, y: 0, z: 0 }, categories: ['root'] }, // categories acts as groups
570
- * { id: 'left', position: { x: -100, y: 0, z: 0 }, categories: ['artwork', 'series'] }
571
- * ])
572
- */
573
- declare class AttractorPass extends BasePass {
574
- private attractors;
575
- private groupMap;
576
- private attractorsTexture;
577
- private attractorGroupsTexture;
578
- private attractorParamsTexture;
579
- private nodeGroupsTexture;
580
- getName(): string;
581
- initMaterial(context: PassContext): void;
582
- updateUniforms(context: PassContext): void;
583
- /**
584
- * Set attractors for the simulation
585
- */
586
- setAttractors(attractors: Attractor[]): void;
587
- /**
588
- * Add a single attractor
589
- */
590
- addAttractor(attractor: Attractor): void;
591
- /**
592
- * Remove an attractor by ID
593
- */
594
- removeAttractor(id: string): void;
595
- /**
596
- * Update an existing attractor's position
597
- */
598
- updateAttractorPosition(id: string, position: Vec3): void;
599
- /**
600
- * Get current attractors
601
- */
602
- getAttractors(): ResolvedAttractor[];
603
- /**
604
- * Set node groups from graph data
605
- * Call this when graph data changes or grouping criteria changes
606
- */
607
- setNodeGroups(groups: string[][], textureSize: number): void;
512
+ * Build all link-related textures for simulation
513
+ * - linkIndicesData: child node INDEX per link entry (organized by parent)
514
+ * - linkPropertiesData: strength/distance per link entry
515
+ * - nodeLinkMapData: per-node metadata (startX, startY, count, hasLinks)
516
+ */
517
+ private buildLinkTextures;
608
518
  /**
609
- * Get the group map (group name -> index)
610
- */
611
- getGroupMap(): Map<string, number>;
612
- private createAttractorTextures;
613
- private updateAttractorTextures;
614
- dispose(): void;
519
+ * Create render material with all uniforms
520
+ */
521
+ private createRenderMaterial;
522
+ }
523
+ interface LinkOptions {
524
+ visible?: boolean;
525
+ noiseStrength?: number;
526
+ alpha?: {
527
+ default?: number;
528
+ highlight?: number;
529
+ dimmed?: number;
530
+ };
615
531
  }
616
532
  //#endregion
617
- //#region simulation/ForceSimulation.d.ts
618
- /**
619
- * ForceSimulation - GPU-based force simulation
620
- *
621
- * Simple architecture:
622
- * - Single shared config object (ForceConfig)
623
- * - All passes read directly from config via PassContext
624
- * - Enable flags control which passes execute
625
- * - No manual syncing required
626
- */
627
- declare class ForceSimulation {
533
+ //#region rendering/nodes/NodesRenderer.d.ts
534
+ declare class NodesRenderer {
535
+ private scene;
628
536
  private renderer;
537
+ private points;
538
+ private pickMaterial;
539
+ private nodeIndexMap;
540
+ private idArray;
541
+ private nodeOpacity;
542
+ private targets;
543
+ params: {
544
+ defaultAlpha: number;
545
+ highlightAlpha: number;
546
+ dimmedAlpha: number;
547
+ };
629
548
  private simulationBuffers;
630
- private computeScene;
631
- private computeCamera;
632
- private computeQuad;
633
- private velocityCarryPass;
634
- private collisionPass;
635
- private manyBodyPass;
636
- private gravityPass;
637
- private linkPass;
638
- private elasticPass;
639
- private attractorPass;
640
- private dragPass;
641
- private integratePass;
642
- private forcePasses;
643
- readonly config: ForceConfig;
644
- private isInitialized;
645
- private iterationCount;
646
- constructor(renderer: THREE.WebGLRenderer);
647
- private createComputeQuad;
648
- /**
649
- * Initialize simulation with buffers
650
- */
651
- initialize(simulationBuffers: SimulationBuffers): void;
652
- private createContext;
653
- /**
654
- * Check if a pass should execute based on config
655
- */
656
- private shouldExecutePass;
549
+ private pickBuffer;
550
+ constructor(scene: THREE.Scene, renderer: THREE.WebGLRenderer);
551
+ create(nodes: GraphNode[], simulationBuffers: SimulationBuffers, pickBuffer: PickBuffer): void;
552
+ setPositionTexture(positionTexture: THREE.Texture): void;
553
+ pick(pixelX: number, pixelY: number, camera: THREE.Camera): number;
554
+ highlight(nodeIds: string[], step?: number): void;
555
+ clearHighlights(step?: number): void;
657
556
  /**
658
- * Run one simulation step
659
- */
660
- step(deltaTime?: number): void;
557
+ * Update node opacity (called every frame)
558
+ */
559
+ updateOpacity(): void;
560
+ resize(width: number, height: number): void;
561
+ dispose(): void;
562
+ private buildNodeMapping;
661
563
  /**
662
- * Get config for GUI binding
663
- * Modify this object directly - changes take effect on next step()
664
- */
665
- getConfig(): ForceConfig;
564
+ * Create all node data in one pass
565
+ * Returns: colors, sizes, radii, nodeIds, pointIndices, alphaIndex
566
+ */
567
+ private createNodeData;
568
+ private createGeometry;
569
+ private createRenderMaterial;
570
+ private createPickMaterial;
571
+ }
572
+ //#endregion
573
+ //#region rendering/GraphScene.d.ts
574
+ /**
575
+ * GraphScene - Manages the 3D scene, camera, and renderers
576
+ * Responsibilities:
577
+ * - Scene setup and lifecycle
578
+ * - Node and link rendering
579
+ * - Camera control
580
+ * - Tooltip management
581
+ * - Mode application (visual changes)
582
+ */
583
+ declare class GraphScene {
584
+ readonly scene: THREE.Scene;
585
+ readonly renderer: THREE.WebGLRenderer;
586
+ readonly camera: CameraController;
587
+ private nodeRenderer;
588
+ private clock;
589
+ private linkRenderer;
590
+ private postProcessing;
591
+ private antialiasingMode;
592
+ constructor(canvas: HTMLCanvasElement, cameraConfig?: CameraConfig, antialiasing?: AntialiasingMode);
666
593
  /**
667
- * Re-heat the simulation (set alpha to 1)
668
- */
669
- reheat(amt?: number): void;
670
- startDrag(index: number, targetWorldPos: THREE.Vector3): void;
671
- updateDrag(targetWorldPos: THREE.Vector3): void;
672
- endDrag(): void;
594
+ * Initialize scene with nodes and links
595
+ */
596
+ create(nodes: GraphNode[], links: GraphLink[], simulationBuffers: SimulationBuffers, pickBuffer: PickBuffer, groupOrder?: string[]): void;
673
597
  /**
674
- * Set attractors for category-based attraction
675
- * @param attractors Array of attractor definitions
676
- */
677
- setAttractors(attractors: Attractor[]): void;
598
+ * Apply visual mode (colors, sizes, camera position)
599
+ */
600
+ applyMode(mode: string, options?: {
601
+ transitionDuration?: number;
602
+ cameraTransitionDuration?: number;
603
+ }): void;
678
604
  /**
679
- * Add a single attractor
680
- */
681
- addAttractor(attractor: Attractor): void;
605
+ * Update position textures from simulation
606
+ */
607
+ updatePositions(positionTexture: THREE.Texture): void;
682
608
  /**
683
- * Remove an attractor by ID
684
- */
685
- removeAttractor(id: string): void;
609
+ * Update time-based uniforms (called each frame with elapsed time)
610
+ */
611
+ update(elapsedTime: number): void;
686
612
  /**
687
- * Update an attractor's position (useful for animated attractors)
688
- */
689
- updateAttractorPosition(id: string, position: Vec3): void;
613
+ * GPU picking at canvas coordinates
614
+ */
615
+ pick(pixelX: number, pixelY: number): number;
690
616
  /**
691
- * Get current attractors
692
- */
693
- getAttractors(): Attractor[];
617
+ * Render the scene
618
+ */
619
+ render(): void;
694
620
  /**
695
- * Set node logic for attractor matching
696
- * Call this when graph data changes
697
- */
698
- setNodeGroups(groups: (string | string[])[]): void;
699
- setNodeGroupsFromData<T>(data: T[], accessor: (item: T, index: number) => string | string[] | undefined): void;
621
+ * Handle window resize
622
+ */
623
+ resize(width: number, height: number): void;
700
624
  /**
701
- * Get the attractor pass for direct access
702
- */
703
- getAttractorPass(): AttractorPass;
704
- getAlpha(): number;
705
- getIterationCount(): number;
706
- reset(): void;
625
+ * Cleanup all resources
626
+ */
707
627
  dispose(): void;
708
- }
709
- //#endregion
710
- //#region controls/handlers/DragHandler.d.ts
711
- declare class DragHandler extends EventEmitter {
712
- private getNodeByIndex;
713
- private cameraController?;
714
- private forceSimulation?;
715
- private viewport?;
716
- private isDragging;
717
- private raycaster;
718
- private dragPlane;
719
- private pointer;
720
- constructor(getNodeByIndex: (index: number) => GraphNode | null, cameraController?: CameraController, forceSimulation?: ForceSimulation, viewport?: {
721
- width: number;
722
- height: number;
723
- });
724
628
  /**
725
- * Set up drag plane perpendicular to camera, passing through a world point
726
- */
727
- private setupDragPlane;
728
- private handleDragStart;
729
- private handleDrag;
730
- private handleDragEnd;
731
- /**
732
- * Convert screen coordinates to world position on drag plane
733
- */
734
- private screenToWorld;
735
- /**
736
- * Update viewport dimensions on resize
737
- */
738
- resize(width: number, height: number): void;
739
- dispose(): void;
629
+ * Switch antialiasing mode at runtime.
630
+ * Cannot switch to 'msaa' at runtime (requires renderer recreation).
631
+ * For 'smaa', 'fxaa', or 'none': creates or updates the post-processing pipeline.
632
+ */
633
+ setAntialiasing(mode: AntialiasingMode): void;
634
+ private applyDefaultMode;
635
+ getCamera(): CameraController;
636
+ getNodeRenderer(): NodesRenderer | null;
637
+ getLinkRenderer(): LinksRenderer | null;
740
638
  }
741
639
  //#endregion
742
- //#region textures/PickBuffer.d.ts
640
+ //#region types/iAttractor.d.ts
743
641
  /**
744
- * Manages GPU picking buffer for mouse interaction
745
- * Separate from simulation buffers as it has different lifecycle
642
+ * Simple 3D vector type
746
643
  */
747
- declare class PickBuffer {
748
- private renderer;
749
- private pickTarget;
750
- constructor(renderer: THREE.WebGLRenderer);
751
- /**
752
- * Ensure pick buffer matches viewport size
753
- */
754
- resize(width: number, height: number): void;
755
- private createPickBuffer;
756
- /**
757
- * Read node ID at pixel coordinates
758
- */
759
- readIdAt(x: number, y: number): number;
760
- /**
761
- * Render scene to pick buffer
762
- */
763
- render(scene: THREE.Scene, camera: THREE.Camera): void;
764
- getTarget(): THREE.WebGLRenderTarget | null;
765
- dispose(): void;
644
+ interface Vec3 {
645
+ x: number;
646
+ y: number;
647
+ z: number;
648
+ }
649
+ /**
650
+ * Attractor - A point in space that attracts nodes of specific groups
651
+ */
652
+ interface Attractor {
653
+ /** Unique identifier */
654
+ id: string;
655
+ /** Position in world space */
656
+ position: Vec3;
657
+ /** Radius of attraction (default: 0.0) - nodes within this radius are not pulled further */
658
+ radius?: number;
659
+ /** Groups of nodes attracted to this attractor (empty = attracts all) */
660
+ groups: string[];
661
+ /** Strength of attraction (default: 1.0) */
662
+ strength?: number;
663
+ }
664
+ /**
665
+ * Resolved attractor with defaults applied
666
+ */
667
+ interface ResolvedAttractor {
668
+ id: string;
669
+ position: Vec3;
670
+ groups: string[];
671
+ strength: number;
672
+ radius: number;
766
673
  }
767
674
  //#endregion
768
- //#region rendering/links/LinksRenderer.d.ts
675
+ //#region textures/StaticAssets.d.ts
769
676
  /**
770
- * LinksRenderer - Renders links as line segments
771
- * Uses shared SimulationBuffers for node positions
772
- * Manages link-specific opacity and highlighting
677
+ * Manages read-only GPU textures created at initialization
678
+ * These never change during simulation (except for mode changes)
679
+ *
680
+ * Node data: radii, colors
681
+ * Link data: source/target indices, properties
773
682
  */
774
- declare class LinksRenderer {
775
- private scene;
776
- private renderer;
777
- private lines;
778
- private links;
779
- private nodeIndexMap;
780
- private linkIndexMap;
781
- private interpolationSteps;
782
- params: {
783
- noiseStrength: number;
784
- defaultAlpha: number;
785
- highlightAlpha: number;
786
- dimmedAlpha: number;
787
- is2D: boolean;
788
- };
789
- private linkOpacity;
790
- private simulationBuffers;
791
- constructor(scene: THREE.Scene, renderer: THREE.WebGLRenderer);
792
- /**
793
- * Create link geometry and materials
794
- * Receives shared buffers as dependencies
795
- */
796
- create(links: GraphLink[], nodes: GraphNode[], simulationBuffers: SimulationBuffers): void;
683
+ declare class StaticAssets {
684
+ private nodeRadiiTexture;
685
+ private nodeColorsTexture;
686
+ private linkIndicesTexture;
687
+ private linkPropertiesTexture;
688
+ private nodeLinkMapTexture;
689
+ private nodeTextureSize;
690
+ private linkTextureSize;
691
+ constructor();
797
692
  /**
798
- * Update position texture from simulation
799
- * This is the SHARED texture used by both nodes and links
800
- */
801
- setPositionTexture(positionTexture: THREE.Texture): void;
693
+ * Set/update node radii texture
694
+ */
695
+ setNodeRadii(radii: Float32Array, textureSize: number): void;
802
696
  /**
803
- * Update shader uniforms (called each frame)
804
- */
805
- update(time: number): void;
697
+ * Set/update node colors texture
698
+ */
699
+ setNodeColors(colors: Float32Array, textureSize: number): void;
806
700
  /**
807
- * Update link opacity (called every frame)
808
- */
809
- updateOpacity(): void;
701
+ * Set link indices (source/target pairs)
702
+ * Format: [sourceX, sourceY, targetX, targetY] per link
703
+ */
704
+ setLinkIndices(linkIndices: Float32Array, textureSize: number): void;
810
705
  /**
811
- * Highlight links connected to a specific node
812
- */
813
- highlightConnectedLinks(nodeId: string, step?: number): void;
706
+ * Set link properties (strength, distance, etc.)
707
+ */
708
+ setLinkProperties(linkProperties: Float32Array, textureSize: number): void;
709
+ setNodeLinkMap(linkMap: Float32Array, textureSize: number): void;
814
710
  /**
815
- * Highlight links connected to any of the given nodes
816
- */
817
- highlightConnectedToNodes(nodeIds: Set<string>, step?: number): void;
711
+ * Create a data texture with proper settings for GPU compute
712
+ */
713
+ private createTexture;
714
+ getNodeRadiiTexture(): THREE.DataTexture | null;
715
+ getNodeColorsTexture(): THREE.DataTexture | null;
716
+ getLinkIndicesTexture(): THREE.DataTexture | null;
717
+ getLinkPropertiesTexture(): THREE.DataTexture | null;
718
+ getLinkMapTexture(): THREE.DataTexture | null;
719
+ getNodeTextureSize(): number;
720
+ getLinkTextureSize(): number;
818
721
  /**
819
- * Clear all highlights (return to defaultAlpha)
820
- */
821
- clearHighlights(step?: number): void;
722
+ * Check if assets are ready
723
+ */
724
+ hasNodeAssets(): boolean;
725
+ hasLinkAssets(): boolean;
822
726
  /**
823
- * Update noise strength parameter
824
- */
825
- setNoiseStrength(strength: number): void;
727
+ * Cleanup
728
+ */
729
+ dispose(): void;
730
+ }
731
+ declare const staticAssets: StaticAssets;
732
+ //#endregion
733
+ //#region simulation/BasePass.d.ts
734
+ interface PassContext {
735
+ scene: THREE.Scene;
736
+ camera: THREE.Camera;
737
+ quad: THREE.BufferGeometry;
738
+ simBuffers: SimulationBuffers;
739
+ assets: StaticAssets;
740
+ renderer: THREE.WebGLRenderer;
741
+ config: ForceConfig;
742
+ textureSize: number;
743
+ }
744
+ /**
745
+ * Base class for GPU force simulation passes
746
+ * Each pass operates on simulation buffers and can read from static assets
747
+ */
748
+ declare abstract class BasePass {
749
+ protected material: THREE.ShaderMaterial | null;
750
+ protected enabled: boolean;
826
751
  /**
827
- * Update alpha parameters
828
- */
829
- setAlphaParams(params: {
830
- defaultAlpha?: number;
831
- highlightAlpha?: number;
832
- dimmedAlpha?: number;
833
- }): void;
752
+ * Get the name/identifier for this pass
753
+ */
754
+ abstract getName(): string;
834
755
  /**
835
- * Unified configuration method
836
- */
837
- setOptions(options: LinkOptions): void;
756
+ * Initialize the shader material for this pass
757
+ */
758
+ abstract initMaterial(context: PassContext): void;
838
759
  /**
839
- * Refresh shader uniforms when params change
840
- */
841
- refreshUniforms(): void;
760
+ * Update uniforms before executing the pass
761
+ */
762
+ abstract updateUniforms(context: PassContext): void;
842
763
  /**
843
- * Handle window resize
844
- */
845
- resize(width: number, height: number): void;
764
+ * Execute the pass (renders to current velocity target)
765
+ */
766
+ execute(context: PassContext): void;
846
767
  /**
847
- * Set visibility of links
848
- */
849
- setVisible(visible: boolean): void;
768
+ * Render the compute shader
769
+ */
770
+ protected render(context: PassContext): void;
850
771
  /**
851
- * Check if links are visible
852
- */
853
- isVisible(): boolean;
772
+ * Create a shader material helper
773
+ */
774
+ protected createMaterial(vertexShader: string, fragmentShader: string, uniforms: {
775
+ [uniform: string]: THREE.IUniform;
776
+ }): THREE.ShaderMaterial;
854
777
  /**
855
- * Cleanup
856
- */
857
- dispose(): void;
778
+ * Safe uniform setter - avoids TypeScript strict null check issues
779
+ */
780
+ protected setUniform(name: string, value: unknown): void;
858
781
  /**
859
- * Build node index mapping
860
- */
861
- private buildNodeMapping;
782
+ * Enable or disable this pass
783
+ */
784
+ setEnabled(enabled: boolean): void;
862
785
  /**
863
- * Builds the instanced link geometry and per-link attribute buffers used by the renderer.
864
- *
865
- * This method:
866
- * - Creates a line-segment template with interpolation parameter `t` for each vertex pair.
867
- * - Encodes link endpoints as texture-space coordinates (`instanceLinkA` / `instanceLinkB`)
868
- * so shaders can fetch node positions from a node texture.
869
- * - Derives endpoint colors from source/target node categories.
870
- * - Assigns a stable per-instance alpha lookup index.
871
- * - Computes a category-based visibility rank from the **target node category**.
872
- *
873
- * Rank/alpha behavior:
874
- * - Categories are ranked by `groupOrder` (unknown categories are appended).
875
- * - The rank is converted to an attenuation factor with inverted weighting:
876
- * `instanceRank = 1.0 - 0.75 * (rank / maxRank)`.
877
- * - This means rank `0` keeps full weight (`1.0`), while the highest rank trends to `0.25`.
878
- *
879
- * Also returns a `linkIndexMap` keyed as `"sourceId-targetId"` for quick instance lookup.
880
- *
881
- * @param links - Graph links to encode as geometry instances.
882
- * @param nodes - Graph nodes used for category/color lookup.
883
- * @param nodeTextureSize - Width/height of the square node data texture used for index-to-UV conversion.
884
- * @param groupOrder - Preferred category ordering for rank assignment (earlier = stronger visibility).
885
- * @returns An object containing:
886
- * - `geometry`: the populated `THREE.InstancedBufferGeometry`
887
- * - `linkIndexMap`: map from link id (`"sourceId-targetId"`) to instance index
888
- */
889
- private createLinkGeometry;
786
+ * Check if pass is enabled
787
+ */
788
+ isEnabled(): boolean;
890
789
  /**
891
- * Build all link-related textures for simulation
892
- * - linkIndicesData: child node INDEX per link entry (organized by parent)
893
- * - linkPropertiesData: strength/distance per link entry
894
- * - nodeLinkMapData: per-node metadata (startX, startY, count, hasLinks)
895
- */
896
- private buildLinkTextures;
790
+ * Get the material for external access
791
+ */
792
+ getMaterial(): THREE.ShaderMaterial | null;
897
793
  /**
898
- * Create render material with all uniforms
899
- */
900
- private createRenderMaterial;
901
- }
902
- interface LinkOptions {
903
- visible?: boolean;
904
- noiseStrength?: number;
905
- alpha?: {
906
- default?: number;
907
- highlight?: number;
908
- dimmed?: number;
909
- };
794
+ * Cleanup resources
795
+ */
796
+ dispose(): void;
910
797
  }
911
798
  //#endregion
912
- //#region rendering/nodes/NodesRenderer.d.ts
913
- declare class NodesRenderer {
914
- private scene;
915
- private renderer;
916
- private points;
917
- private pickMaterial;
918
- private nodeIndexMap;
919
- private idArray;
920
- private nodeOpacity;
921
- private targets;
922
- params: {
923
- defaultAlpha: number;
924
- highlightAlpha: number;
925
- dimmedAlpha: number;
926
- };
927
- private simulationBuffers;
928
- private pickBuffer;
929
- constructor(scene: THREE.Scene, renderer: THREE.WebGLRenderer);
930
- create(nodes: GraphNode[], simulationBuffers: SimulationBuffers, pickBuffer: PickBuffer): void;
931
- setPositionTexture(positionTexture: THREE.Texture): void;
932
- pick(pixelX: number, pixelY: number, camera: THREE.Camera): number;
933
- highlight(nodeIds: string[], step?: number): void;
934
- clearHighlights(step?: number): void;
799
+ //#region simulation/passes/AttractorPass.d.ts
800
+ /**
801
+ * Attractor force pass - attracts nodes to attractor points based on group membership
802
+ *
803
+ * Usage:
804
+ * attractorPass.setAttractors([
805
+ * { id: 'center', position: { x: 0, y: 0, z: 0 }, categories: ['root'] }, // categories acts as groups
806
+ * { id: 'left', position: { x: -100, y: 0, z: 0 }, categories: ['artwork', 'series'] }
807
+ * ])
808
+ */
809
+ declare class AttractorPass extends BasePass {
810
+ private attractors;
811
+ private groupMap;
812
+ private attractorsTexture;
813
+ private attractorGroupsTexture;
814
+ private attractorParamsTexture;
815
+ private nodeGroupsTexture;
816
+ getName(): string;
817
+ initMaterial(context: PassContext): void;
818
+ updateUniforms(context: PassContext): void;
935
819
  /**
936
- * Update node opacity (called every frame)
937
- */
938
- updateOpacity(): void;
939
- resize(width: number, height: number): void;
940
- dispose(): void;
941
- private buildNodeMapping;
820
+ * Set attractors for the simulation
821
+ */
822
+ setAttractors(attractors: Attractor[]): void;
942
823
  /**
943
- * Create all node data in one pass
944
- * Returns: colors, sizes, radii, nodeIds, pointIndices, alphaIndex
945
- */
946
- private createNodeData;
947
- private createGeometry;
948
- private createRenderMaterial;
949
- private createPickMaterial;
824
+ * Add a single attractor
825
+ */
826
+ addAttractor(attractor: Attractor): void;
827
+ /**
828
+ * Remove an attractor by ID
829
+ */
830
+ removeAttractor(id: string): void;
831
+ /**
832
+ * Update an existing attractor's position
833
+ */
834
+ updateAttractorPosition(id: string, position: Vec3): void;
835
+ /**
836
+ * Get current attractors
837
+ */
838
+ getAttractors(): ResolvedAttractor[];
839
+ /**
840
+ * Set node groups from graph data
841
+ * Call this when graph data changes or grouping criteria changes
842
+ */
843
+ setNodeGroups(groups: string[][], textureSize: number): void;
844
+ /**
845
+ * Get the group map (group name -> index)
846
+ */
847
+ getGroupMap(): Map<string, number>;
848
+ private createAttractorTextures;
849
+ private updateAttractorTextures;
850
+ dispose(): void;
950
851
  }
951
852
  //#endregion
952
- //#region rendering/GraphScene.d.ts
853
+ //#region simulation/ForceSimulation.d.ts
953
854
  /**
954
- * GraphScene - Manages the 3D scene, camera, and renderers
955
- * Responsibilities:
956
- * - Scene setup and lifecycle
957
- * - Node and link rendering
958
- * - Camera control
959
- * - Tooltip management
960
- * - Mode application (visual changes)
855
+ * ForceSimulation - GPU-based force simulation
856
+ *
857
+ * Simple architecture:
858
+ * - Single shared config object (ForceConfig)
859
+ * - All passes read directly from config via PassContext
860
+ * - Enable flags control which passes execute
861
+ * - No manual syncing required
961
862
  */
962
- declare class GraphScene {
963
- readonly scene: THREE.Scene;
964
- readonly renderer: THREE.WebGLRenderer;
965
- readonly camera: CameraController;
966
- private nodeRenderer;
967
- private clock;
968
- private linkRenderer;
969
- private postProcessing;
970
- private antialiasingMode;
971
- constructor(canvas: HTMLCanvasElement, cameraConfig?: CameraConfig, antialiasing?: AntialiasingMode);
863
+ declare class ForceSimulation {
864
+ private renderer;
865
+ private simulationBuffers;
866
+ private computeScene;
867
+ private computeCamera;
868
+ private computeQuad;
869
+ private velocityCarryPass;
870
+ private collisionPass;
871
+ private manyBodyPass;
872
+ private gravityPass;
873
+ private linkPass;
874
+ private elasticPass;
875
+ private attractorPass;
876
+ private dragPass;
877
+ private integratePass;
878
+ private forcePasses;
879
+ readonly config: ForceConfig;
880
+ private isInitialized;
881
+ private iterationCount;
882
+ private readonly FIXED_DT;
883
+ private readonly MAX_STEPS_PER_FRAME;
884
+ private timeAccumulator;
885
+ constructor(renderer: THREE.WebGLRenderer);
886
+ private createComputeQuad;
972
887
  /**
973
- * Initialize scene with nodes and links
974
- */
975
- create(nodes: GraphNode[], links: GraphLink[], simulationBuffers: SimulationBuffers, pickBuffer: PickBuffer, groupOrder?: string[]): void;
888
+ * Initialize simulation with buffers
889
+ */
890
+ initialize(simulationBuffers: SimulationBuffers): void;
891
+ private createContext;
976
892
  /**
977
- * Apply visual mode (colors, sizes, camera position)
978
- */
979
- applyMode(mode: string, options?: {
980
- transitionDuration?: number;
981
- cameraTransitionDuration?: number;
982
- }): void;
893
+ * Check if a pass should execute based on config
894
+ */
895
+ private shouldExecutePass;
983
896
  /**
984
- * Update position textures from simulation
985
- */
986
- updatePositions(positionTexture: THREE.Texture): void;
897
+ * Run simulation steps using a fixed timestep accumulator.
898
+ * Regardless of monitor refresh rate, physics always steps at 1/60s intervals.
899
+ */
900
+ step(deltaTime?: number): void;
987
901
  /**
988
- * Update time-based uniforms (called each frame with elapsed time)
989
- */
990
- update(elapsedTime: number): void;
902
+ * Execute one fixed-rate physics step (always at 1/60s)
903
+ */
904
+ private fixedStep;
991
905
  /**
992
- * GPU picking at canvas coordinates
993
- */
994
- pick(pixelX: number, pixelY: number): number;
906
+ * Get config for GUI binding
907
+ * Modify this object directly - changes take effect on next step()
908
+ */
909
+ getConfig(): ForceConfig;
995
910
  /**
996
- * Render the scene
997
- */
998
- render(): void;
911
+ * Re-heat the simulation (set alpha to 1)
912
+ */
913
+ reheat(amt?: number): void;
914
+ startDrag(index: number, targetWorldPos: THREE.Vector3): void;
915
+ updateDrag(targetWorldPos: THREE.Vector3): void;
916
+ endDrag(): void;
999
917
  /**
1000
- * Handle window resize
1001
- */
1002
- resize(width: number, height: number): void;
918
+ * Set attractors for category-based attraction
919
+ * @param attractors Array of attractor definitions
920
+ */
921
+ setAttractors(attractors: Attractor[]): void;
1003
922
  /**
1004
- * Cleanup all resources
1005
- */
1006
- dispose(): void;
923
+ * Add a single attractor
924
+ */
925
+ addAttractor(attractor: Attractor): void;
1007
926
  /**
1008
- * Switch antialiasing mode at runtime.
1009
- * Cannot switch to 'msaa' at runtime (requires renderer recreation).
1010
- * For 'smaa', 'fxaa', or 'none': creates or updates the post-processing pipeline.
1011
- */
1012
- setAntialiasing(mode: AntialiasingMode): void;
1013
- private applyDefaultMode;
1014
- getCamera(): CameraController;
1015
- getNodeRenderer(): NodesRenderer | null;
1016
- getLinkRenderer(): LinksRenderer | null;
927
+ * Remove an attractor by ID
928
+ */
929
+ removeAttractor(id: string): void;
930
+ /**
931
+ * Update an attractor's position (useful for animated attractors)
932
+ */
933
+ updateAttractorPosition(id: string, position: Vec3): void;
934
+ /**
935
+ * Get current attractors
936
+ */
937
+ getAttractors(): Attractor[];
938
+ /**
939
+ * Set node logic for attractor matching
940
+ * Call this when graph data changes
941
+ */
942
+ setNodeGroups(groups: (string | string[])[]): void;
943
+ setNodeGroupsFromData<T>(data: T[], accessor: (item: T, index: number) => string | string[] | undefined): void;
944
+ /**
945
+ * Get the attractor pass for direct access
946
+ */
947
+ getAttractorPass(): AttractorPass;
948
+ getAlpha(): number;
949
+ getIterationCount(): number;
950
+ reset(): void;
951
+ dispose(): void;
1017
952
  }
1018
953
  //#endregion
1019
954
  //#region ui/TooltipManager.d.ts
@@ -1028,35 +963,35 @@ declare class TooltipManager {
1028
963
  private onCloseCallback?;
1029
964
  constructor(container: HTMLElement, canvas: HTMLCanvasElement, config?: TooltipConfig);
1030
965
  /**
1031
- * Show grab cursor when hovering over a node
1032
- */
966
+ * Show grab cursor when hovering over a node
967
+ */
1033
968
  showGrabIcon(x: number, y: number, progress: number): void;
1034
969
  hideGrabIcon(): void;
1035
970
  /**
1036
- * Show preview tooltip (triggered by pop event when hover reaches 1.0)
1037
- */
971
+ * Show preview tooltip (triggered by pop event when hover reaches 1.0)
972
+ */
1038
973
  showPreview(node: GraphNode, x: number, y: number): void;
1039
974
  hidePreview(): void;
1040
975
  /**
1041
- * Show full tooltip (triggered by click)
1042
- */
976
+ * Show full tooltip (triggered by click)
977
+ */
1043
978
  showFull(node: GraphNode, x: number, y: number): void;
1044
979
  hideFull(): void;
1045
980
  /**
1046
- * Set callback for when tooltip is closed
1047
- */
981
+ * Set callback for when tooltip is closed
982
+ */
1048
983
  setOnCloseCallback(callback: () => void): void;
1049
984
  /**
1050
- * Add close button to tooltip
1051
- */
985
+ * Add close button to tooltip
986
+ */
1052
987
  private addCloseButton;
1053
988
  /**
1054
- * Remove close button from tooltip
1055
- */
989
+ * Remove close button from tooltip
990
+ */
1056
991
  private removeCloseButton;
1057
992
  /**
1058
- * Hide all tooltips
1059
- */
993
+ * Hide all tooltips
994
+ */
1060
995
  hideAll(): void;
1061
996
  showMainTooltip(content: string, x: number, y: number): void;
1062
997
  hideMainTooltip(): void;
@@ -1064,12 +999,123 @@ declare class TooltipManager {
1064
999
  hideChainTooltips(): void;
1065
1000
  updateMainTooltipPos(x: number, y: number): void;
1066
1001
  /**
1067
- * Set main tooltip visibility (doesn't affect open state or content)
1068
- */
1002
+ * Set main tooltip visibility (doesn't affect open state or content)
1003
+ */
1069
1004
  setMainTooltipVisibility(visible: boolean): void;
1070
1005
  dispose(): void;
1071
1006
  }
1072
1007
  //#endregion
1008
+ //#region core/EventEmitter.d.ts
1009
+ declare class EventEmitter {
1010
+ private listeners;
1011
+ protected listenerCount(event: string): number;
1012
+ on(event: string, listener: Function): () => void;
1013
+ off(event: string, listener: Function): void;
1014
+ emit(event: string, ...args: any[]): void;
1015
+ }
1016
+ //#endregion
1017
+ //#region controls/handlers/ClickHandler.d.ts
1018
+ declare class ClickHandler extends EventEmitter {
1019
+ private getNodeByIndex;
1020
+ constructor(getNodeByIndex: (index: number) => GraphNode | null);
1021
+ private handleClick;
1022
+ dispose(): void;
1023
+ }
1024
+ //#endregion
1025
+ //#region controls/handlers/DragHandler.d.ts
1026
+ declare class DragHandler extends EventEmitter {
1027
+ private getNodeByIndex;
1028
+ private cameraController?;
1029
+ private forceSimulation?;
1030
+ private viewport?;
1031
+ private isDragging;
1032
+ private raycaster;
1033
+ private dragPlane;
1034
+ private pointer;
1035
+ constructor(getNodeByIndex: (index: number) => GraphNode | null, cameraController?: CameraController, forceSimulation?: ForceSimulation, viewport?: {
1036
+ width: number;
1037
+ height: number;
1038
+ });
1039
+ /**
1040
+ * Set up drag plane perpendicular to camera, passing through a world point
1041
+ */
1042
+ private setupDragPlane;
1043
+ private handleDragStart;
1044
+ private handleDrag;
1045
+ private handleDragEnd;
1046
+ /**
1047
+ * Convert screen coordinates to world position on drag plane
1048
+ */
1049
+ private screenToWorld;
1050
+ /**
1051
+ * Update viewport dimensions on resize
1052
+ */
1053
+ resize(width: number, height: number): void;
1054
+ dispose(): void;
1055
+ }
1056
+ //#endregion
1057
+ //#region controls/handlers/HoverHandler.d.ts
1058
+ declare class HoverHandler extends EventEmitter {
1059
+ private getNodeByIndex;
1060
+ constructor(getNodeByIndex: (index: number) => GraphNode | null);
1061
+ private handleHoverStart;
1062
+ private handleHover;
1063
+ private handlePop;
1064
+ private handleHoverEnd;
1065
+ dispose(): void;
1066
+ }
1067
+ //#endregion
1068
+ //#region controls/InputProcessor.d.ts
1069
+ /**
1070
+ * Manages pointer/mouse input and emits interaction events
1071
+ * Uses GPU picking for efficient node detection
1072
+ */
1073
+ declare class InputProcessor extends EventEmitter {
1074
+ private pickFn;
1075
+ private canvas;
1076
+ private viewport;
1077
+ private readonly CLICK_THRESHOLD;
1078
+ private readonly HOVER_TO_POP_MS;
1079
+ private pointer;
1080
+ private canvasPointer;
1081
+ private isPointerDown;
1082
+ private isDragging;
1083
+ private mouseDownTime;
1084
+ private draggedIndex;
1085
+ private currentHoverIndex;
1086
+ private hoverStartTime;
1087
+ private hoverProgress;
1088
+ private hasPopped;
1089
+ private isTouch;
1090
+ private readonly TOUCH_MOVE_THRESHOLD;
1091
+ private pointerDownX;
1092
+ private pointerDownY;
1093
+ private lastClientX;
1094
+ private lastClientY;
1095
+ constructor(pickFn: (x: number, y: number) => number, // Injected
1096
+ canvas: HTMLCanvasElement, viewport: {
1097
+ width: number;
1098
+ height: number;
1099
+ });
1100
+ private setupEventListeners;
1101
+ private handlePointerMove;
1102
+ private handlePointerDown;
1103
+ private handlePointerUp;
1104
+ private handlePointerLeave;
1105
+ private updateHover;
1106
+ /**
1107
+ * Update hover state even when pointer is stationary
1108
+ * Called from render loop
1109
+ */
1110
+ update(): void;
1111
+ private updatePointer;
1112
+ /**
1113
+ * Update viewport dimensions on resize
1114
+ */
1115
+ resize(width: number, height: number): void;
1116
+ dispose(): void;
1117
+ }
1118
+ //#endregion
1073
1119
  //#region controls/InteractionManager.d.ts
1074
1120
  declare class InteractionManager {
1075
1121
  private graphScene?;
@@ -1090,9 +1136,9 @@ declare class InteractionManager {
1090
1136
  private wireEvents;
1091
1137
  private wireTooltipEvents;
1092
1138
  /**
1093
- * Wire visual feedback events (opacity, highlighting)
1094
- * Centralized control of visual responses to interactions
1095
- */
1139
+ * Wire visual feedback events (opacity, highlighting)
1140
+ * Centralized control of visual responses to interactions
1141
+ */
1096
1142
  private wireVisualFeedbackEvents;
1097
1143
  getPointerInput(): InputProcessor;
1098
1144
  getHoverHandler(): HoverHandler;
@@ -1101,51 +1147,13 @@ declare class InteractionManager {
1101
1147
  getTooltipManager(): TooltipManager;
1102
1148
  isTooltipStickyOpen(): boolean;
1103
1149
  /**
1104
- * Update viewport dimensions on resize
1105
- */
1150
+ * Update viewport dimensions on resize
1151
+ */
1106
1152
  resize(width: number, height: number): void;
1107
1153
  cleanup(): void;
1108
1154
  dispose(): void;
1109
1155
  }
1110
1156
  //#endregion
1111
- //#region core/Clock.d.ts
1112
- /**
1113
- * Clock - Unified timing for the force graph package
1114
- */
1115
- declare class Clock {
1116
- private previousTime;
1117
- private elapsedTime;
1118
- private deltaTime;
1119
- private isRunning;
1120
- private maxDeltaTime;
1121
- constructor();
1122
- /**
1123
- * Start the clock
1124
- */
1125
- start(): void;
1126
- /**
1127
- * Stop the clock
1128
- */
1129
- stop(): void;
1130
- /**
1131
- * Update the clock - call once per frame
1132
- * @returns delta time in seconds
1133
- */
1134
- update(): number;
1135
- /**
1136
- * Get delta time in seconds
1137
- */
1138
- getDeltaTime(): number;
1139
- /**
1140
- * Get total elapsed time in seconds
1141
- */
1142
- getElapsedTime(): number;
1143
- /**
1144
- * Check if clock is running
1145
- */
1146
- getIsRunning(): boolean;
1147
- }
1148
- //#endregion
1149
1157
  //#region core/GraphStore.d.ts
1150
1158
  /**
1151
1159
  * GraphStore - Central data management
@@ -1166,68 +1174,68 @@ declare class GraphStore {
1166
1174
  private nodeToLinks;
1167
1175
  constructor();
1168
1176
  /**
1169
- * Set graph data (replaces all)
1170
- */
1177
+ * Set graph data (replaces all)
1178
+ */
1171
1179
  setData(data: GraphData): void;
1172
1180
  /**
1173
- * Add nodes
1174
- */
1181
+ * Add nodes
1182
+ */
1175
1183
  addNodes(nodes: GraphNode[]): void;
1176
1184
  /**
1177
- * Remove nodes (and connected links)
1178
- */
1185
+ * Remove nodes (and connected links)
1186
+ */
1179
1187
  removeNodes(nodeIds: string[]): void;
1180
1188
  /**
1181
- * Add links
1182
- */
1189
+ * Add links
1190
+ */
1183
1191
  addLinks(links: GraphLink[]): void;
1184
1192
  /**
1185
- * Remove links
1186
- */
1193
+ * Remove links
1194
+ */
1187
1195
  removeLinks(linkIds: string[]): void;
1188
1196
  /**
1189
- * Get all nodes as array
1190
- */
1197
+ * Get all nodes as array
1198
+ */
1191
1199
  getNodes(): GraphNode[];
1192
1200
  /**
1193
- * Get all links as array
1194
- */
1201
+ * Get all links as array
1202
+ */
1195
1203
  getLinks(): GraphLink[];
1196
1204
  /**
1197
- * Get connected node IDs for a given node
1198
- */
1205
+ * Get connected node IDs for a given node
1206
+ */
1199
1207
  getConnectedNodeIds(nodeId: string): string[];
1200
1208
  /**
1201
- * Get node by ID
1202
- */
1209
+ * Get node by ID
1210
+ */
1203
1211
  getNodeById(id: string): GraphNode | null;
1204
1212
  /**
1205
- * Get node by index
1206
- */
1213
+ * Get node by index
1214
+ */
1207
1215
  getNodeByIndex(index: number): GraphNode | null;
1208
1216
  /**
1209
- * Get node index
1210
- */
1217
+ * Get node index
1218
+ */
1211
1219
  getNodeIndex(id: string): number;
1212
1220
  /**
1213
- * Get link by ID
1214
- */
1221
+ * Get link by ID
1222
+ */
1215
1223
  getLinkById(id: string): GraphLink | null;
1216
1224
  /**
1217
- * Get links connected to node
1218
- */
1225
+ * Get links connected to node
1226
+ */
1219
1227
  getNodeLinks(nodeId: string): GraphLink[];
1220
1228
  /**
1221
- * Get node count
1222
- */
1229
+ * Get node count
1230
+ */
1223
1231
  getNodeCount(): number;
1224
1232
  /**
1225
- * Get link count
1226
- */
1233
+ * Get link count
1234
+ */
1227
1235
  getLinkCount(): number;
1228
1236
  /**
1229
- * Clear all data
1230
- */
1237
+ * Clear all data
1238
+ */
1231
1239
  clear(): void;
1232
1240
  private getLinkId;
1233
1241
  private addLinkConnectivity;
@@ -1269,132 +1277,133 @@ declare class Engine {
1269
1277
  private smoothedTooltipPos;
1270
1278
  constructor(canvas: HTMLCanvasElement, options?: EngineOptions);
1271
1279
  /**
1272
- * Handle window resize event
1273
- */
1280
+ * Handle window resize event
1281
+ */
1274
1282
  private handleWindowResize;
1275
1283
  /**
1276
- * Set graph data
1277
- */
1284
+ * Set graph data
1285
+ */
1278
1286
  setData(data: GraphData): void;
1279
1287
  /**
1280
- * Update node states based on a callback
1281
- * This allows changing visibility/behavior without resetting the simulation
1282
- */
1288
+ * Update node states based on a callback
1289
+ * This allows changing visibility/behavior without resetting the simulation
1290
+ */
1283
1291
  updateNodeStates(callback: (node: GraphNode) => NodeState): void;
1284
1292
  /**
1285
- * Set target positions for elastic force (tree layout, etc.)
1286
- * Writes positions into the "original positions" GPU buffer that ElasticPass reads from,
1287
- * without touching current positions or node states.
1288
- * Must be called AFTER applyPreset() since updateNodeStates() overwrites original positions.
1289
- */
1293
+ * Set target positions for elastic force (tree layout, etc.)
1294
+ * Writes positions into the "original positions" GPU buffer that ElasticPass reads from,
1295
+ * without touching current positions or node states.
1296
+ * Must be called AFTER applyPreset() since updateNodeStates() overwrites original positions.
1297
+ */
1290
1298
  setTargetPositions(targets: Map<string, {
1291
1299
  x: number;
1292
1300
  y: number;
1293
1301
  z: number;
1294
1302
  }>): void;
1295
1303
  /**
1296
- * Reheat the simulation
1297
- */
1304
+ * Reheat the simulation
1305
+ */
1298
1306
  reheat(alpha?: number): void;
1299
1307
  /**
1300
- * Set alpha decay
1301
- */
1308
+ * Set alpha decay
1309
+ */
1302
1310
  setAlphaDecay(decay: number): void;
1303
1311
  /**
1304
- * Get current alpha
1305
- */
1312
+ * Get current alpha
1313
+ */
1306
1314
  getAlpha(): number;
1307
- /**Apply a preset to the graph
1308
- */
1315
+ /**
1316
+ Apply a preset to the graph
1317
+ */
1309
1318
  applyPreset(preset: GraphPreset): void;
1310
1319
  /**
1311
- *
1312
- * Start render loop
1313
- */
1320
+ *
1321
+ * Start render loop
1322
+ */
1314
1323
  start(): void;
1315
1324
  /**
1316
- * Stop render loop
1317
- */
1325
+ * Stop render loop
1326
+ */
1318
1327
  stop(): void;
1319
1328
  /**
1320
- * Render loop
1321
- */
1329
+ * Render loop
1330
+ */
1322
1331
  private animate;
1323
1332
  /**
1324
- * GPU pick node at canvas coordinates
1325
- */
1333
+ * GPU pick node at canvas coordinates
1334
+ */
1326
1335
  pickNode(x: number, y: number): string | null;
1327
1336
  /**
1328
- * Get node by ID
1329
- */
1337
+ * Get node by ID
1338
+ */
1330
1339
  getNodeById(id: string): GraphNode | null;
1331
1340
  /**
1332
- * Highlight nodes
1333
- */
1341
+ * Highlight nodes
1342
+ */
1334
1343
  highlightNodes(nodeIds: string[]): void;
1335
1344
  /**
1336
- * Clear highlights
1337
- */
1345
+ * Clear highlights
1346
+ */
1338
1347
  clearHighlights(): void;
1339
1348
  /**
1340
- * Get node position in 3D space
1341
- */
1349
+ * Get node position in 3D space
1350
+ */
1342
1351
  getNodePosition(nodeId: string): THREE.Vector3 | null;
1343
1352
  /**
1344
- * Get node screen position from world position
1345
- * Returns position and visibility info (whether node is on screen and in front of camera)
1346
- */
1353
+ * Get node screen position from world position
1354
+ * Returns position and visibility info (whether node is on screen and in front of camera)
1355
+ */
1347
1356
  getNodeScreenPosition(nodeId: string): {
1348
1357
  x: number;
1349
1358
  y: number;
1350
1359
  visible: boolean;
1351
1360
  } | null;
1352
1361
  /**
1353
- * Update sticky tooltip position to follow node during camera movement
1354
- * Uses lerp smoothing to filter out micro-jitter from force simulation
1355
- */
1362
+ * Update sticky tooltip position to follow node during camera movement
1363
+ * Uses lerp smoothing to filter out micro-jitter from force simulation
1364
+ */
1356
1365
  private updateStickyTooltipPosition;
1357
1366
  /**
1358
- * Programmatically select a node (highlight + tooltip)
1359
- */
1367
+ * Programmatically select a node (highlight + tooltip)
1368
+ */
1360
1369
  selectNode(nodeId: string): void;
1361
1370
  /**
1362
- * Resize canvas and all dependent components
1363
- */
1371
+ * Resize canvas and all dependent components
1372
+ */
1364
1373
  resize(width: number, height: number): void;
1365
1374
  /**
1366
- * Get the unified clock for timing information
1367
- */
1375
+ * Get the unified clock for timing information
1376
+ */
1368
1377
  getClock(): Clock;
1369
1378
  /**
1370
- * Get all nodes
1371
- */
1379
+ * Get all nodes
1380
+ */
1372
1381
  get nodes(): GraphNode[];
1373
1382
  /**
1374
- * Get all links
1375
- */
1383
+ * Get all links
1384
+ */
1376
1385
  get links(): GraphLink[];
1377
1386
  /**
1378
- * Get force simulation for external configuration (GUI binding)
1379
- */
1387
+ * Get force simulation for external configuration (GUI binding)
1388
+ */
1380
1389
  get simulation(): ForceSimulation;
1381
1390
  /**
1382
- * Get camera controller for external configuration
1383
- */
1391
+ * Get camera controller for external configuration
1392
+ */
1384
1393
  get camera(): CameraController;
1385
1394
  /**
1386
- * Set camera mode (Orbit, Map, Fly)
1387
- */
1395
+ * Set camera mode (Orbit, Map, Fly)
1396
+ */
1388
1397
  setCameraMode(mode: CameraMode): void;
1389
1398
  /**
1390
- * Set antialiasing mode at runtime.
1391
- * Supports switching between 'smaa', 'fxaa', and 'none'.
1392
- * Cannot switch to 'msaa' at runtime (requires renderer recreation).
1393
- */
1399
+ * Set antialiasing mode at runtime.
1400
+ * Supports switching between 'smaa', 'fxaa', and 'none'.
1401
+ * Cannot switch to 'msaa' at runtime (requires renderer recreation).
1402
+ */
1394
1403
  setAntialiasing(mode: AntialiasingMode): void;
1395
1404
  /**
1396
- * Animate camera to look at a specific target from a specific position
1397
- */
1405
+ * Animate camera to look at a specific target from a specific position
1406
+ */
1398
1407
  setCameraLookAt(position: {
1399
1408
  x: number;
1400
1409
  y: number;
@@ -1405,16 +1414,16 @@ declare class Engine {
1405
1414
  z: number;
1406
1415
  }, transitionDuration?: number): Promise<void>;
1407
1416
  /**
1408
- * Focus camera on a specific target node
1409
- */
1417
+ * Focus camera on a specific target node
1418
+ */
1410
1419
  setCameraFocus(target: {
1411
1420
  x: number;
1412
1421
  y: number;
1413
1422
  z: number;
1414
1423
  }, distance: number, transitionDuration?: number): Promise<void>;
1415
1424
  /**
1416
- * Cleanup
1417
- */
1425
+ * Cleanup
1426
+ */
1418
1427
  dispose(): void;
1419
1428
  private calculateTextureSize;
1420
1429
  }
@@ -1463,68 +1472,68 @@ declare class StyleRegistry {
1463
1472
  private defaultNodeStyle;
1464
1473
  private defaultLinkStyle;
1465
1474
  /**
1466
- * Convert color input to THREE.Color
1467
- */
1475
+ * Convert color input to THREE.Color
1476
+ */
1468
1477
  private toColor;
1469
1478
  /**
1470
- * Set the default style for nodes without a category
1471
- */
1479
+ * Set the default style for nodes without a category
1480
+ */
1472
1481
  setDefaultNodeStyle(style: Partial<NodeStyle>): void;
1473
1482
  /**
1474
- * Set the default style for links without a category
1475
- */
1483
+ * Set the default style for links without a category
1484
+ */
1476
1485
  setDefaultLinkStyle(style: Partial<LinkStyle>): void;
1477
1486
  /**
1478
- * Register a style for a node category
1479
- */
1487
+ * Register a style for a node category
1488
+ */
1480
1489
  setNodeStyle(category: string, style: NodeStyle): void;
1481
1490
  /**
1482
- * Register multiple node styles at once
1483
- */
1491
+ * Register multiple node styles at once
1492
+ */
1484
1493
  setNodeStyles(styles: Record<string, NodeStyle>): void;
1485
1494
  /**
1486
- * Register a style for a link category
1487
- */
1495
+ * Register a style for a link category
1496
+ */
1488
1497
  setLinkStyle(category: string, style: LinkStyle): void;
1489
1498
  /**
1490
- * Register multiple link styles at once
1491
- */
1499
+ * Register multiple link styles at once
1500
+ */
1492
1501
  setLinkStyles(styles: Record<string, LinkStyle>): void;
1493
1502
  /**
1494
- * Get the resolved style for a node category
1495
- */
1503
+ * Get the resolved style for a node category
1504
+ */
1496
1505
  getNodeStyle(category?: string): ResolvedNodeStyle;
1497
1506
  /**
1498
- * Get the resolved style for a link category
1499
- */
1507
+ * Get the resolved style for a link category
1508
+ */
1500
1509
  getLinkStyle(category?: string): ResolvedLinkStyle;
1501
1510
  /**
1502
- * Check if a node category exists
1503
- */
1511
+ * Check if a node category exists
1512
+ */
1504
1513
  hasNodeStyle(category: string): boolean;
1505
1514
  /**
1506
- * Check if a link category exists
1507
- */
1515
+ * Check if a link category exists
1516
+ */
1508
1517
  hasLinkStyle(category: string): boolean;
1509
1518
  /**
1510
- * Remove a node style
1511
- */
1519
+ * Remove a node style
1520
+ */
1512
1521
  removeNodeStyle(category: string): void;
1513
1522
  /**
1514
- * Remove a link style
1515
- */
1523
+ * Remove a link style
1524
+ */
1516
1525
  removeLinkStyle(category: string): void;
1517
1526
  /**
1518
- * Clear all styles
1519
- */
1527
+ * Clear all styles
1528
+ */
1520
1529
  clear(): void;
1521
1530
  /**
1522
- * Get all registered node categories
1523
- */
1531
+ * Get all registered node categories
1532
+ */
1524
1533
  getNodeCategories(): string[];
1525
1534
  /**
1526
- * Get all registered link categories
1527
- */
1535
+ * Get all registered link categories
1536
+ */
1528
1537
  getLinkCategories(): string[];
1529
1538
  }
1530
1539
  declare const styleRegistry: StyleRegistry;