loom-browser 0.0.9 → 0.0.10

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 (98) hide show
  1. package/dist/loom-react.esm.js +3877 -3173
  2. package/dist/loom-react.esm.min.js +1 -1
  3. package/dist/loom-react.esm.min.js.map +1 -1
  4. package/dist/loom-worker.js +191 -137
  5. package/dist/loom-worker.min.js +1 -1
  6. package/dist/loom-worker.min.js.map +1 -1
  7. package/dist/loom.esm.js +4163 -3412
  8. package/dist/loom.esm.min.js +1 -1
  9. package/dist/loom.esm.min.js.map +1 -1
  10. package/dist/loom.js +4174 -3415
  11. package/dist/loom.min.js +1 -1
  12. package/dist/loom.min.js.map +1 -1
  13. package/dist/tsconfig.src.tsbuildinfo +1 -1
  14. package/dist/types/browser/dom/browserExport.d.ts +32 -0
  15. package/dist/types/browser/dom/contextMenu.d.ts +64 -0
  16. package/dist/types/browser/dom/contextMenuManager.d.ts +49 -0
  17. package/dist/types/browser/dom/defaultProviders.d.ts +23 -0
  18. package/dist/types/browser/dom/genomeBrowser.d.ts +171 -0
  19. package/dist/types/browser/dom/pointerEventManager.d.ts +109 -0
  20. package/dist/types/browser/dom/roiOverlayManager.d.ts +38 -0
  21. package/dist/types/browser/dom/svgFeatureOverlay.d.ts +27 -0
  22. package/dist/types/browser/headless/errors.d.ts +10 -0
  23. package/dist/types/browser/headless/headlessGenomeBrowser.d.ts +391 -0
  24. package/dist/types/browser/headless/roiManager.d.ts +47 -0
  25. package/dist/types/browser/headless/session.d.ts +45 -0
  26. package/dist/types/browser/headless/trackDataManager.d.ts +48 -0
  27. package/dist/types/browser/headless/trackFactories.d.ts +145 -0
  28. package/dist/types/browser/index.d.ts +24 -0
  29. package/dist/types/browserExport.d.ts +32 -0
  30. package/dist/types/commandDispatcher.d.ts +1 -1
  31. package/dist/types/contextMenuManager.d.ts +49 -0
  32. package/dist/types/data/searchService.d.ts +24 -0
  33. package/dist/types/dataSourceWorkerProvider.d.ts +3 -3
  34. package/dist/types/dataSources/bigWigDataSource.d.ts +2 -2
  35. package/dist/types/dataSources/config.d.ts +40 -0
  36. package/dist/types/dataSources/configureDataSource.d.ts +17 -0
  37. package/dist/types/dataSources/createDataSource.d.ts +14 -0
  38. package/dist/types/dataSources/geneDataSource.d.ts +4 -3
  39. package/dist/types/dataSources/gtxDataSource.d.ts +2 -2
  40. package/dist/types/dataSources/memoryDataSource.d.ts +2 -2
  41. package/dist/types/dataSources/sequenceDataSource.d.ts +4 -1
  42. package/dist/types/dataSources/textFeatureSource.d.ts +4 -2
  43. package/dist/types/dataSources/wholeGenomeUtils.d.ts +37 -0
  44. package/dist/types/defaultProviders.d.ts +23 -0
  45. package/dist/types/errors.d.ts +10 -0
  46. package/dist/types/formats/featureParser.d.ts +1 -1
  47. package/dist/types/genomeBrowser.d.ts +18 -91
  48. package/dist/types/headlessGenomeBrowser.d.ts +88 -225
  49. package/dist/types/index.d.ts +21 -14
  50. package/dist/types/io/binaryParser.d.ts +0 -1
  51. package/dist/types/logger.d.ts +20 -0
  52. package/dist/types/pointerEventManager.d.ts +109 -0
  53. package/dist/types/react/GenomeBrowserContext.d.ts +1 -1
  54. package/dist/types/react/LoomBrowser.d.ts +4 -4
  55. package/dist/types/react/hooks/useBrowserEvent.d.ts +1 -1
  56. package/dist/types/react/hooks/useGenomeBrowser.d.ts +1 -1
  57. package/dist/types/react/hooks/useTrackManager.d.ts +1 -1
  58. package/dist/types/react/ui/ChromosomeSelect.d.ts +1 -1
  59. package/dist/types/react/ui/ExportControls.d.ts +1 -1
  60. package/dist/types/react/ui/LocusInput.d.ts +1 -1
  61. package/dist/types/react/ui/Navbar.d.ts +1 -1
  62. package/dist/types/react/ui/WindowSize.d.ts +1 -1
  63. package/dist/types/react/ui/ZoomControls.d.ts +1 -1
  64. package/dist/types/remoteProtocol.d.ts +1 -1
  65. package/dist/types/roiManager.d.ts +47 -0
  66. package/dist/types/roiOverlayManager.d.ts +38 -0
  67. package/dist/types/stateProjection.d.ts +1 -1
  68. package/dist/types/trackDataManager.d.ts +48 -0
  69. package/dist/types/trackFactories.d.ts +140 -0
  70. package/dist/types/trackSelector.d.ts +1 -1
  71. package/dist/types/tracks/annotation/annotationTrackCanvas.d.ts +0 -1
  72. package/dist/types/tracks/annotation/config.d.ts +61 -0
  73. package/dist/types/tracks/baseTrackCanvas.d.ts +10 -0
  74. package/dist/types/tracks/configDiff.d.ts +14 -0
  75. package/dist/types/tracks/interaction/config.d.ts +40 -0
  76. package/dist/types/tracks/ruler/config.d.ts +24 -0
  77. package/dist/types/tracks/sequence/config.d.ts +56 -0
  78. package/dist/types/tracks/sequence/sequenceTrackCanvas.d.ts +3 -0
  79. package/dist/types/tracks/wig/config.d.ts +77 -0
  80. package/dist/types/types/igvCompat.d.ts +36 -0
  81. package/dist/types/types.d.ts +48 -284
  82. package/dist/types/ui/components/LoomBrowserShell.d.ts +2 -2
  83. package/dist/types/ui/components/LoomChromosomeSelect.d.ts +1 -1
  84. package/dist/types/ui/components/LoomContextMenu.d.ts +1 -0
  85. package/dist/types/ui/components/LoomExportControls.d.ts +1 -1
  86. package/dist/types/ui/components/LoomLocusInput.d.ts +1 -1
  87. package/dist/types/ui/components/LoomNavbar.d.ts +1 -1
  88. package/dist/types/ui/components/LoomWindowSize.d.ts +1 -1
  89. package/dist/types/ui/components/LoomZoomControls.d.ts +1 -1
  90. package/dist/types/undoManager.d.ts +49 -0
  91. package/dist/types/worker/dataSourceRegistry.d.ts +2 -2
  92. package/dist/types/worker/serializedError.d.ts +16 -0
  93. package/dist/types/worker/taskTimeout.d.ts +21 -0
  94. package/dist/types/worker/webWorkerPool.d.ts +5 -2
  95. package/dist/types/worker/webWorkerProvider.d.ts +3 -0
  96. package/dist/types/workerDataSource.d.ts +2 -2
  97. package/dist/types/workerProvider.d.ts +2 -2
  98. package/package.json +1 -1
@@ -0,0 +1,109 @@
1
+ /**
2
+ * PointerEventManager — pointer interaction state machine for GenomeBrowser.
3
+ *
4
+ * Owns all pointer-driven interaction state and handlers:
5
+ * - Drag-to-pan (pointer capture + rAF batching)
6
+ * - Sweep-to-zoom (ruler drag → selection overlay)
7
+ * - Click / double-click detection
8
+ * - Hover throttling
9
+ * - Scroll-wheel / trackpad pinch-to-zoom
10
+ * - Drag-to-reorder tracks
11
+ *
12
+ * Extracted from GenomeBrowser to isolate the complex pointer state machine
13
+ * from DOM layout and track lifecycle management.
14
+ *
15
+ * Layer 4 (DOM): requires DOM APIs.
16
+ */
17
+ import type { Track, Locus, TrackInteractionEvent, PopupDataItem } from './types';
18
+ import type { ManagedTrack } from './headlessGenomeBrowser';
19
+ import type { CumulativeOffsets, ChromSizes } from './genome/chromSizes';
20
+ import type { UndoEntryType } from './undoManager';
21
+ /** Callback interface for browser operations — wired by GenomeBrowser. */
22
+ export interface PointerBrowserAccess {
23
+ getLocus(): Locus;
24
+ /** Set locus directly without triggering data load (used during drag). */
25
+ setLocusDirect(locus: Locus): void;
26
+ clampLocus(locus: Locus): Locus;
27
+ /** Set locus with full data lifecycle (used for sweep zoom, WG click). */
28
+ setLocus(locus: Locus): void;
29
+ getViewportWidth(): number;
30
+ getManagedTracks(): readonly ManagedTrack[];
31
+ loadAllTracksIfNeeded(): void;
32
+ zoomAroundCenter(factor: number, centerBP: number): void;
33
+ resolveInteraction(track: Track, x: number, y: number): TrackInteractionEvent | null;
34
+ findTrackForTarget(target: EventTarget | null): Track | null;
35
+ isRulerCanvas(target: EventTarget | null): boolean;
36
+ showPopup(data: PopupDataItem[], position: {
37
+ x: number;
38
+ y: number;
39
+ }): void;
40
+ hidePopup(): void;
41
+ hideContextMenu(): void;
42
+ isOverlayTarget(e: Event): boolean;
43
+ setFeatureOverlaysSuppressed(suppressed: boolean): void;
44
+ emitLocusChange(locus: Locus): void;
45
+ emitTrackClick(event: TrackInteractionEvent): void;
46
+ emitTrackHover(event: TrackInteractionEvent): void;
47
+ emitTrackOrderChanged(tracks: Track[]): void;
48
+ snapshotForUndo(type: UndoEntryType): void;
49
+ getCumulativeOffsets(): CumulativeOffsets | undefined;
50
+ getChromSizes(): ChromSizes | undefined;
51
+ getTrackAxisDiv(track: Track): HTMLDivElement | undefined;
52
+ moveTrackInArray(fromIndex: number, toIndex: number): void;
53
+ syncDOMOrder(): void;
54
+ finalizeReorder(): void;
55
+ }
56
+ export declare class PointerEventManager {
57
+ private options;
58
+ private container;
59
+ private browser;
60
+ private axisColumnWidth;
61
+ private isDragging;
62
+ private lastPointerX;
63
+ private isSweeping;
64
+ private sweepStartX;
65
+ private sweepOverlay;
66
+ private sweepRulerCanvas;
67
+ private pointerDownX;
68
+ private pointerDownY;
69
+ private pointerDownTarget;
70
+ private lastClickTime;
71
+ private lastClickX;
72
+ private lastClickY;
73
+ private singleClickTimer;
74
+ private hoverThrottleId;
75
+ private _rafId;
76
+ private _preNavLocus;
77
+ private handlePointerDown;
78
+ private handlePointerMove;
79
+ private handlePointerUp;
80
+ private handleMouseMove;
81
+ private handleMouseLeave;
82
+ private handleWheel;
83
+ private wheelRafId;
84
+ private reorderDragTrack;
85
+ private reorderDragRow;
86
+ private reorderHandlers;
87
+ constructor(container: HTMLElement, browser: PointerBrowserAccess, axisColumnWidth: number, options: {
88
+ wheelZoom?: boolean;
89
+ });
90
+ /** Set up all pointer event handlers. */
91
+ setup(): void;
92
+ /** Tear down all pointer event handlers and clean up state. */
93
+ dispose(): void;
94
+ /** Set up drag-to-reorder pointer handlers on a track's axis div. */
95
+ setupReorderForTrack(track: Track, axisDiv: HTMLDivElement): void;
96
+ /** Remove reorder handlers for a track. */
97
+ teardownReorderForTrack(track: Track): void;
98
+ private createSweepOverlay;
99
+ private removeSweepOverlay;
100
+ private setupDragHandlers;
101
+ private handleClick;
102
+ private teardownDragHandlers;
103
+ private setupHoverHandlers;
104
+ private teardownHoverHandlers;
105
+ private setupWheelHandler;
106
+ private teardownWheelHandler;
107
+ /** Get the DOM row element for a track (via browser). */
108
+ private getTrackRow;
109
+ }
@@ -1,4 +1,4 @@
1
- import type { GenomeBrowser } from '../genomeBrowser';
1
+ import type { GenomeBrowser } from '../browser/dom/genomeBrowser';
2
2
  import type { ShellTheme } from '../ui/themes';
3
3
  export interface GenomeBrowserContextValue {
4
4
  /** The underlying GenomeBrowser instance. null before initialization or during SSR. */
@@ -5,9 +5,9 @@ import type { WorkerProvider } from '../workerProvider';
5
5
  import type { PopupProvider } from '../popupProvider';
6
6
  import type { ContextMenuProvider } from '../contextMenuProvider';
7
7
  import type { RemoteSocket } from '../remoteProtocol';
8
- import { GenomeBrowser } from '../genomeBrowser';
9
- import type { ManagedTrack } from '../headlessGenomeBrowser';
10
- import type { CreateTrackFromSessionOptions } from '../session';
8
+ import { GenomeBrowser } from '../browser/dom/genomeBrowser';
9
+ import type { ManagedTrack } from '../browser/headless/headlessGenomeBrowser';
10
+ import type { CreateTrackFromSessionOptions } from '../browser/headless/session';
11
11
  import type { TrackSelector } from '../trackSelector';
12
12
  import { ROISet } from '../roi/roiSet';
13
13
  export interface LoomBrowserProps {
@@ -67,7 +67,7 @@ export interface LoomBrowserProps {
67
67
  export interface LoomBrowserHandle {
68
68
  /** The underlying GenomeBrowser instance. null during SSR. */
69
69
  readonly browser: GenomeBrowser | null;
70
- search(query: string): boolean;
70
+ search(query: string): Promise<boolean>;
71
71
  zoomIn(factor?: number): void;
72
72
  zoomOut(factor?: number): void;
73
73
  addTrackFromConfig(config: TrackSessionConfig): Track;
@@ -1,4 +1,4 @@
1
- import type { BrowserEvents } from '../../headlessGenomeBrowser';
1
+ import type { BrowserEvents } from '../../browser/headless/headlessGenomeBrowser';
2
2
  /**
3
3
  * Subscribe to a typed browser event. Automatically subscribes/unsubscribes
4
4
  * with the browser lifecycle. Uses a stable ref for the handler to avoid
@@ -1,4 +1,4 @@
1
- import type { GenomeBrowser } from '../../genomeBrowser';
1
+ import type { GenomeBrowser } from '../../browser/dom/genomeBrowser';
2
2
  /**
3
3
  * Access the GenomeBrowser instance from context.
4
4
  * Returns null before the browser initializes (SSR or first render).
@@ -1,5 +1,5 @@
1
1
  import type { Track } from '../../types';
2
- import type { GenomeBrowser } from '../../genomeBrowser';
2
+ import type { GenomeBrowser } from '../../browser/dom/genomeBrowser';
3
3
  /** Per-track click event with typed features. */
4
4
  export interface TrackClickEvent<F> {
5
5
  features: F[];
@@ -1,4 +1,4 @@
1
- import type { GenomeBrowser } from '../../genomeBrowser';
1
+ import type { GenomeBrowser } from '../../browser/dom/genomeBrowser';
2
2
  import './types';
3
3
  export interface ChromosomeSelectProps {
4
4
  /** Override the browser from context. */
@@ -1,4 +1,4 @@
1
- import type { GenomeBrowser } from '../../genomeBrowser';
1
+ import type { GenomeBrowser } from '../../browser/dom/genomeBrowser';
2
2
  import './types';
3
3
  export interface ExportControlsProps {
4
4
  /** Override the browser from context. */
@@ -1,4 +1,4 @@
1
- import type { GenomeBrowser } from '../../genomeBrowser';
1
+ import type { GenomeBrowser } from '../../browser/dom/genomeBrowser';
2
2
  import './types';
3
3
  export interface LocusInputProps {
4
4
  /** Override the browser from context. */
@@ -1,4 +1,4 @@
1
- import type { GenomeBrowser } from '../../genomeBrowser';
1
+ import type { GenomeBrowser } from '../../browser/dom/genomeBrowser';
2
2
  import type { ShellTheme } from '../../ui/themes';
3
3
  import './types';
4
4
  export interface NavbarProps {
@@ -1,4 +1,4 @@
1
- import type { GenomeBrowser } from '../../genomeBrowser';
1
+ import type { GenomeBrowser } from '../../browser/dom/genomeBrowser';
2
2
  import './types';
3
3
  export interface WindowSizeProps {
4
4
  /** Override the browser from context. */
@@ -1,4 +1,4 @@
1
- import type { GenomeBrowser } from '../../genomeBrowser';
1
+ import type { GenomeBrowser } from '../../browser/dom/genomeBrowser';
2
2
  import './types';
3
3
  export interface ZoomControlsProps {
4
4
  /** Override the browser from context. */
@@ -8,7 +8,7 @@
8
8
  * The `RemoteSocket` interface is minimal and testable — works with browser
9
9
  * WebSocket, the `ws` npm package, or mock implementations.
10
10
  */
11
- import type { HeadlessGenomeBrowser } from './headlessGenomeBrowser';
11
+ import type { HeadlessGenomeBrowser } from './browser/headless/headlessGenomeBrowser';
12
12
  import type { CommandDispatcherOptions } from './commandDispatcher';
13
13
  /** Inbound: agent/server sends a command request. */
14
14
  export interface RequestMessage {
@@ -0,0 +1,47 @@
1
+ /**
2
+ * ROIManager — manages Region of Interest sets for a genome browser.
3
+ *
4
+ * Extracted from HeadlessGenomeBrowser to isolate ROI CRUD operations
5
+ * into a single-responsibility module. Owns the `roiSets` array and
6
+ * emits events through a callback interface.
7
+ *
8
+ * Layer 3 (Headless): no DOM dependencies.
9
+ */
10
+ import type { ROI, ROISetConfig, Locus } from './types';
11
+ import { ROISet } from './roi/roiSet';
12
+ /** Callback interface for ROI events — wired by HeadlessGenomeBrowser to its EventEmitter. */
13
+ export interface ROIEventCallbacks {
14
+ onROIAdded(roi: ROI, set: ROISet): void;
15
+ onROIRemoved(roi: ROI, set: ROISet): void;
16
+ onROIChanged(roi: ROI, changes: Partial<ROI>, set: ROISet): void;
17
+ }
18
+ export declare class ROIManager {
19
+ private roiSets;
20
+ private callbacks;
21
+ constructor(callbacks: ROIEventCallbacks);
22
+ /**
23
+ * Add a single ROI to a named set. Creates a user-defined set if it doesn't exist.
24
+ * Returns the ROI (with generated ID if none provided).
25
+ */
26
+ addROI(roi: ROI, setName?: string): ROI;
27
+ /** Add a full ROI set from config. Returns the created ROISet. */
28
+ addROISet(config: ROISetConfig): ROISet;
29
+ /** Remove an ROI by ID (searches all sets). Returns true if found and removed. */
30
+ removeROI(roiId: string): boolean;
31
+ /** Update an ROI by ID. Returns the updated ROI, or undefined if not found. */
32
+ updateROI(roiId: string, changes: Partial<Omit<ROI, 'id'>>): ROI | undefined;
33
+ /** Remove a specific ROI set by instance. Returns true if found and removed. */
34
+ removeROISet(set: ROISet): boolean;
35
+ /** Remove all ROI sets. */
36
+ clear(): void;
37
+ /** Get all ROIs across all sets (flattened). */
38
+ getROIs(): ROI[];
39
+ /** Get all ROI sets. */
40
+ getROISets(): readonly ROISet[];
41
+ /** Find ROIs overlapping a genomic region (searches all sets). */
42
+ findROIsAtLocus(chr: string, start: number, end: number): ROI[];
43
+ /** Get ROIs visible in the given viewport locus. */
44
+ getVisibleROIs(locus: Locus): ROI[];
45
+ /** Serialize all ROI sets for session persistence. Returns undefined if empty. */
46
+ serialize(): ROISetConfig[] | undefined;
47
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * ROIOverlayManager — DOM-based Region of Interest overlay rendering.
3
+ *
4
+ * Manages ROI region elements (colored overlays with labels) positioned
5
+ * over the track viewport. Uses DOM elements (not canvas) for easy
6
+ * hover/click interaction without re-rendering track canvases.
7
+ *
8
+ * Extracted from GenomeBrowser to isolate ROI DOM lifecycle management.
9
+ *
10
+ * Layer 4 (DOM): requires DOM APIs.
11
+ */
12
+ import type { ROI, Locus } from './types';
13
+ /** Callback interface for ROI overlay events — wired by GenomeBrowser. */
14
+ export interface ROIOverlayCallbacks {
15
+ onROIClick(roiId: string, e: MouseEvent): void;
16
+ onROIContextMenu(roiId: string, e: MouseEvent): void;
17
+ }
18
+ export declare class ROIOverlayManager {
19
+ private container;
20
+ private axisColumnWidth;
21
+ private overlayContainer;
22
+ private roiElements;
23
+ private callbacks;
24
+ constructor(container: HTMLElement, axisColumnWidth: number, callbacks: ROIOverlayCallbacks);
25
+ /**
26
+ * Render ROI overlays for the given visible ROIs.
27
+ * Creates/updates/removes DOM elements to match the current viewport.
28
+ */
29
+ render(visibleROIs: ROI[], locus: Locus, viewportWidth: number): void;
30
+ /** Remove all ROI elements and the overlay container. */
31
+ clear(): void;
32
+ /** Alias for clear — clean up all ROI overlay resources. */
33
+ dispose(): void;
34
+ /** Ensure the ROI overlay container exists and is sized correctly. */
35
+ private ensureContainer;
36
+ /** Create a styled DOM element for an ROI region. */
37
+ private createElement;
38
+ }
@@ -10,7 +10,7 @@
10
10
  * Swappable: consumers can extend or replace this class for custom projection logic.
11
11
  */
12
12
  import type { Locus, TrackFeatureSummary, ROISetConfig } from './types';
13
- import type { HeadlessGenomeBrowser, ManagedTrack } from './headlessGenomeBrowser';
13
+ import type { HeadlessGenomeBrowser, ManagedTrack } from './browser/headless/headlessGenomeBrowser';
14
14
  /** Zoom level classification based on viewport span. */
15
15
  export type ZoomLevel = 'base' | 'element' | 'gene' | 'region' | 'chromosome' | 'genome';
16
16
  /** Concise summary of a single track, suitable for LLM consumption. */
@@ -0,0 +1,48 @@
1
+ /**
2
+ * TrackDataManager — data lifecycle management for genome browser tracks.
3
+ *
4
+ * Extracted from HeadlessGenomeBrowser to isolate data fetching concerns:
5
+ * - Debounced loading during rapid zoom/pan
6
+ * - Cache validation and coverage checks
7
+ * - Fetch deduplication across tracks sharing the same data source
8
+ * - Inflight request tracking and abort management
9
+ * - Visibility window enforcement
10
+ *
11
+ * Layer 3 (Headless): no DOM dependencies.
12
+ */
13
+ import type { Locus, Track, DataSource } from './types';
14
+ import type { ManagedTrack } from './headlessGenomeBrowser';
15
+ import type { DataSourceWorkerProvider } from './dataSourceWorkerProvider';
16
+ /** Callback interface for data lifecycle events — wired by HeadlessGenomeBrowser. */
17
+ export interface DataEventCallbacks {
18
+ onDataLoaded(track: Track): void;
19
+ onDataError(track: Track, error: Error): void;
20
+ }
21
+ export declare class TrackDataManager {
22
+ /** Inflight fetch promises keyed by (cacheKey + fetchRegion + bpPerPixel) for deduplication. */
23
+ private inflightFetches;
24
+ /** Timer for debouncing data loads during rapid zoom/pan. */
25
+ private loadDebounceTimer;
26
+ /** Set to true by dispose() to suppress post-dispose promise handlers. */
27
+ private _disposed;
28
+ private callbacks;
29
+ private dataSourceWorkerProvider?;
30
+ constructor(callbacks: DataEventCallbacks, dataSourceWorkerProvider?: DataSourceWorkerProvider);
31
+ /**
32
+ * Debounced wrapper around loadAllTracksIfNeeded.
33
+ * During rapid zoom/pan, this coalesces multiple setLocus() calls into a
34
+ * single data fetch cycle after the interaction settles (100ms quiet period).
35
+ * Abort in-flight requests immediately so they don't race with the eventual fetch.
36
+ */
37
+ debouncedLoad(managedTracks: ManagedTrack[], locus: Locus, viewportWidth: number): void;
38
+ loadAllTracksIfNeeded(managedTracks: ManagedTrack[], locus: Locus, viewportWidth: number): void;
39
+ /**
40
+ * Load data for a single track, deduplicating against inflight fetches
41
+ * from other tracks with the same data source identity.
42
+ */
43
+ loadTrackWithDedup(mt: ManagedTrack, managedTracks: ManagedTrack[], locus: Locus, viewportWidth: number): void;
44
+ /** Clean up: cancel debounce timer, mark as disposed. */
45
+ dispose(): void;
46
+ /** Destroy a worker-resident data source. */
47
+ destroyWorkerDataSource(dataSource: DataSource): void;
48
+ }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Track convenience factories — create and wire tracks with data sources.
3
+ *
4
+ * Extracted from HeadlessGenomeBrowser to isolate repetitive track creation
5
+ * boilerplate. Each factory:
6
+ * 1. Creates a canvas via CanvasProvider
7
+ * 2. Creates a TrackCanvas instance
8
+ * 3. Builds a DataSourceConfig
9
+ * 4. Creates a worker proxy or direct data source
10
+ * 5. Wires chromosome alias resolution + cumulative offsets
11
+ * 6. Returns the track + data source + config for the browser to register
12
+ *
13
+ * Layer 3 (Headless): no DOM dependencies.
14
+ */
15
+ import type { Locus, DataSource, DataSourceConfig, WindowFunction, WigFeature, BedFeature, WigRenderConfig, AnnotationRenderConfig, RulerRenderConfig, SequenceRenderConfig, InteractionRenderConfig, TextFileFormat, SequenceProvider, Genome } from './types';
16
+ import type { CanvasProvider } from './canvasProvider';
17
+ import type { DataSourceWorkerProvider } from './dataSourceWorkerProvider';
18
+ import type { RenderTheme } from './themes/renderTheme';
19
+ import type { ChromSizes, CumulativeOffsets } from './genome/chromSizes';
20
+ import { WorkerDataSource } from './workerDataSource';
21
+ import { RulerTrackCanvas } from './tracks/ruler/rulerTrackCanvas';
22
+ import { WigTrackCanvas } from './tracks/wig/wigTrackCanvas';
23
+ import { AnnotationTrackCanvas } from './tracks/annotation/annotationTrackCanvas';
24
+ import { InteractionTrackCanvas } from './tracks/interaction/interactionTrackCanvas';
25
+ export interface AddRulerOptions {
26
+ config?: Partial<RulerRenderConfig>;
27
+ maxTrackHeight?: number;
28
+ }
29
+ export interface AddWigTrackOptions {
30
+ config?: Partial<WigRenderConfig>;
31
+ height?: number;
32
+ background?: string;
33
+ windowFunction?: WindowFunction;
34
+ maxTrackHeight?: number;
35
+ name?: string;
36
+ metadata?: Record<string, string>;
37
+ }
38
+ export interface AddGtxTrackOptions {
39
+ experimentId: string;
40
+ config?: Partial<WigRenderConfig>;
41
+ height?: number;
42
+ background?: string;
43
+ windowFunction?: WindowFunction;
44
+ maxTrackHeight?: number;
45
+ name?: string;
46
+ metadata?: Record<string, string>;
47
+ }
48
+ export interface AddSequenceTrackOptions {
49
+ config?: Partial<SequenceRenderConfig>;
50
+ maxTrackHeight?: number;
51
+ }
52
+ export interface AddBedTrackOptions {
53
+ config?: Partial<AnnotationRenderConfig>;
54
+ height?: number;
55
+ background?: string;
56
+ format?: TextFileFormat;
57
+ indexURL?: string;
58
+ indexed?: boolean;
59
+ maxTrackHeight?: number;
60
+ name?: string;
61
+ metadata?: Record<string, string>;
62
+ }
63
+ export interface AddInteractionTrackOptions {
64
+ config?: Partial<InteractionRenderConfig>;
65
+ background?: string;
66
+ format?: TextFileFormat;
67
+ indexURL?: string;
68
+ indexed?: boolean;
69
+ name?: string;
70
+ metadata?: Record<string, string>;
71
+ }
72
+ export interface AddAnnotationTrackOptions {
73
+ config?: Partial<AnnotationRenderConfig>;
74
+ height?: number;
75
+ background?: string;
76
+ genome?: string;
77
+ track?: string;
78
+ maxTrackHeight?: number;
79
+ name?: string;
80
+ metadata?: Record<string, string>;
81
+ }
82
+ export interface AddWigTrackWithFeaturesOptions {
83
+ config?: Partial<WigRenderConfig>;
84
+ height?: number;
85
+ background?: string;
86
+ maxTrackHeight?: number;
87
+ name?: string;
88
+ metadata?: Record<string, string>;
89
+ }
90
+ export interface AddBedTrackWithFeaturesOptions {
91
+ config?: Partial<AnnotationRenderConfig>;
92
+ height?: number;
93
+ background?: string;
94
+ maxTrackHeight?: number;
95
+ name?: string;
96
+ metadata?: Record<string, string>;
97
+ }
98
+ /** Context needed by all factories — passed from HeadlessGenomeBrowser. */
99
+ export interface TrackFactoryContext {
100
+ locus: Locus;
101
+ canvasProvider: CanvasProvider;
102
+ theme: RenderTheme;
103
+ genome?: Genome;
104
+ chromSizes?: ChromSizes;
105
+ cumulativeOffsets?: CumulativeOffsets;
106
+ sequenceProvider?: SequenceProvider;
107
+ dataSourceWorkerProvider?: DataSourceWorkerProvider;
108
+ }
109
+ /** Result of a factory — the browser registers this via addTrack(). */
110
+ export interface FactoryResult<T> {
111
+ track: T;
112
+ dataSource?: DataSource;
113
+ dataSourceConfig?: DataSourceConfig;
114
+ maxTrackHeight?: number;
115
+ metadata?: Record<string, string>;
116
+ order?: number;
117
+ /** Post-registration callback (e.g., wiring onWindowFunctionChange). */
118
+ onRegistered?: (findMT: () => {
119
+ cache: null | unknown;
120
+ dataSourceConfig: DataSourceConfig | null;
121
+ }) => void;
122
+ }
123
+ /**
124
+ * Create a WorkerDataSource proxy for worker-eligible configs, or return null
125
+ * if dataSourceWorkerProvider is not set. Handles create + chrom alias + offsets wiring.
126
+ */
127
+ export declare function createWorkerDataSource<F>(config: DataSourceConfig, ctx: Pick<TrackFactoryContext, 'dataSourceWorkerProvider' | 'genome' | 'cumulativeOffsets'>): WorkerDataSource<F> | null;
128
+ /**
129
+ * Wire chromosome alias resolution and cumulative offsets on a direct (non-worker) data source.
130
+ * Consolidates the pattern repeated 7+ times in the old HeadlessGenomeBrowser.
131
+ */
132
+ export declare function wireDataSource(ds: DataSource, ctx: Pick<TrackFactoryContext, 'genome' | 'cumulativeOffsets'>): void;
133
+ export declare function createRuler(ctx: TrackFactoryContext, options?: AddRulerOptions): FactoryResult<RulerTrackCanvas>;
134
+ export declare function createWigTrack(ctx: TrackFactoryContext, url: string, options?: AddWigTrackOptions): FactoryResult<WigTrackCanvas>;
135
+ export declare function createGtxTrack(ctx: TrackFactoryContext, url: string, options: AddGtxTrackOptions): FactoryResult<WigTrackCanvas>;
136
+ export declare function createGeneTrack(ctx: TrackFactoryContext, options?: AddAnnotationTrackOptions): FactoryResult<AnnotationTrackCanvas>;
137
+ export declare function createBedTrack(ctx: TrackFactoryContext, url: string, options?: AddBedTrackOptions): FactoryResult<AnnotationTrackCanvas>;
138
+ export declare function createInteractionTrack(ctx: TrackFactoryContext, url: string, options?: AddInteractionTrackOptions): FactoryResult<InteractionTrackCanvas>;
139
+ export declare function createWigTrackWithFeatures(ctx: TrackFactoryContext, features: WigFeature[], options?: AddWigTrackWithFeaturesOptions): FactoryResult<WigTrackCanvas>;
140
+ export declare function createBedTrackWithFeatures(ctx: TrackFactoryContext, features: BedFeature[], options?: AddBedTrackWithFeaturesOptions): FactoryResult<AnnotationTrackCanvas>;
@@ -13,7 +13,7 @@
13
13
  * browser.findTracks({ type: 'wig', where: { biosample: 'K562' } })
14
14
  * ```
15
15
  */
16
- import type { ManagedTrack } from './headlessGenomeBrowser';
16
+ import type { ManagedTrack } from './browser/headless/headlessGenomeBrowser';
17
17
  /** Selector for matching tracks by ID, name, type, and/or metadata. */
18
18
  export interface TrackSelector {
19
19
  /** Exact match against track ID. */
@@ -14,7 +14,6 @@ import type { AnnotationFeature, AnnotationRenderConfig, Locus, RenderContext, A
14
14
  import type { CanvasProvider } from '../../canvasProvider';
15
15
  import type { RenderTheme } from '../../themes/renderTheme';
16
16
  import { BaseTrackCanvas } from '../baseTrackCanvas';
17
- export type { Locus } from '../../types';
18
17
  export interface AnnotationTrackCanvasOptions {
19
18
  locus: Locus;
20
19
  features: AnnotationFeature[];
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Annotation track render configuration.
3
+ *
4
+ * Controls rendering of gene, BED, GFF, and peak features.
5
+ *
6
+ * Layer 2 (Track Canvases): no DOM.
7
+ */
8
+ /** Display mode for gene features. */
9
+ export type DisplayMode = 'COLLAPSED' | 'SQUISHED' | 'EXPANDED';
10
+ /** Configuration controlling how annotation features (gene, BED, GFF, peaks) are rendered. */
11
+ export interface AnnotationRenderConfig {
12
+ displayMode: DisplayMode;
13
+ featureHeight: number;
14
+ margin: number;
15
+ /** Row height in EXPANDED mode (featureHeight + label space + padding). */
16
+ expandedRowHeight: number;
17
+ /** Row height in SQUISHED mode. */
18
+ squishedRowHeight: number;
19
+ /** Pixel spacing between strand-direction arrows. */
20
+ arrowSpacing: number;
21
+ /** Default fill color for CDS exons. */
22
+ color: string;
23
+ /** Color for features on the opposite strand (if desired). */
24
+ altColor?: string;
25
+ /** Which feature property to use as the label. */
26
+ labelField: string;
27
+ /** CSS font string for labels, e.g. "10px sans-serif". */
28
+ font: string;
29
+ /** Whether to draw labels. */
30
+ drawLabels: boolean;
31
+ /** Label display mode — "SLANT" rotates labels 45°. */
32
+ labelDisplayMode?: 'SLANT';
33
+ /** UTR fill color. Defaults to main color. */
34
+ utrColor?: string;
35
+ /** Alt UTR color (for - strand when altColor is set). */
36
+ altUtrColor?: string;
37
+ /** Exon stroke outline color. No outline when undefined. */
38
+ borderColor?: string;
39
+ /** Exon outline width. Default: 0 (no outline). */
40
+ borderWidth?: number;
41
+ /** Rounded corner radius for exon rects. Default: 0 (square). */
42
+ borderRadius?: number;
43
+ /** Intron line color. Defaults to main color. */
44
+ intronColor?: string;
45
+ /** Intron line width. Default: 1. */
46
+ intronLineWidth?: number;
47
+ /** Dash pattern for intron lines, e.g. [3, 3]. Default: [] (solid). */
48
+ intronDash?: number[];
49
+ /** Strand arrow color on intron lines. Defaults to current stroke color. */
50
+ arrowColor?: string;
51
+ /** Strand arrow color inside exons. Default: 'white'. */
52
+ arrowInExonColor?: string;
53
+ /** Label text color. Defaults to feature color. */
54
+ labelColor?: string;
55
+ /** Background color behind labels. When set, fills behind labels instead of clearing to transparent. */
56
+ labelBackground?: string;
57
+ /** Separate CSS font string for labels. Defaults to `font`. */
58
+ labelFont?: string;
59
+ }
60
+ /** Returns sensible defaults for annotation feature rendering. */
61
+ export declare function defaultAnnotationRenderConfig(): AnnotationRenderConfig;
@@ -35,6 +35,16 @@ export declare abstract class BaseTrackCanvas<TConfig> implements Track {
35
35
  * Set to undefined or 0 to disable (always fetch). Set > 0 to enable.
36
36
  */
37
37
  visibilityWindow?: number;
38
+ /**
39
+ * Callback invoked just before setConfig() applies changes.
40
+ * The browser registers this to snapshot state for undo (capturing pre-mutation state).
41
+ */
42
+ onBeforeConfigChange?: () => void;
43
+ /**
44
+ * Callback invoked after setConfig() merges new config and re-renders.
45
+ * The browser registers this to emit TrackConfigChanged.
46
+ */
47
+ onConfigChanged?: () => void;
38
48
  abstract readonly type: string;
39
49
  get canvas(): HTMLCanvasElement;
40
50
  get locus(): Locus;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Typed config diff utility for track session serialization.
3
+ *
4
+ * Compares a track's current config against theme defaults and returns
5
+ * only the fields that differ. Eliminates the `as Record<string, unknown>`
6
+ * casts previously duplicated across track canvas serializeConfig() methods.
7
+ *
8
+ * Layer 2 (Track Canvases): no DOM.
9
+ */
10
+ /**
11
+ * Compute the diff between a config object and its defaults.
12
+ * Returns a Partial containing only changed fields, or undefined if no changes.
13
+ */
14
+ export declare function diffConfig<T extends object>(config: T, defaults: T): Partial<T> | undefined;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Interaction track render configuration.
3
+ *
4
+ * Controls rendering of chromatin interaction arcs (Hi-C, ChIA-PET, BEDPE).
5
+ *
6
+ * Layer 2 (Track Canvases): no DOM.
7
+ */
8
+ /** Arc orientation: arcs open upward or downward. */
9
+ export type ArcOrientation = 'UP' | 'DOWN';
10
+ /** Display mode for interaction arcs. */
11
+ export type ArcDisplayMode = 'nested' | 'proportional';
12
+ /** Configuration controlling how interaction features are rendered as arcs. */
13
+ export interface InteractionRenderConfig {
14
+ /** Track height in CSS pixels. Default: 250. */
15
+ height: number;
16
+ /** Arc direction. Default: 'UP'. */
17
+ arcOrientation: ArcOrientation;
18
+ /** Display mode. Default: 'nested'. */
19
+ displayMode: ArcDisplayMode;
20
+ /** Show small rectangles at feature endpoints. Default: true. */
21
+ showBlocks: boolean;
22
+ /** Height of endpoint rectangles in pixels. Default: 3. */
23
+ blockHeight: number;
24
+ /** Arc stroke width in pixels. Default: 1. */
25
+ thickness: number;
26
+ /** Default arc color. Default: 'rgb(180,25,137)'. */
27
+ color: string;
28
+ /** Fill alpha for arcs. Default: 0.02. */
29
+ alpha: number;
30
+ /** Use log scale for proportional arc heights. Default: true. */
31
+ logScale: boolean;
32
+ /** Background color. Default: '#ffffff'. */
33
+ background: string;
34
+ /** Font for inter-chromosome labels. Default: '8px sans-serif'. */
35
+ font: string;
36
+ /** Whether to use score-based shading. Default: false. */
37
+ useScore: boolean;
38
+ }
39
+ /** Returns sensible defaults for interaction rendering. */
40
+ export declare function defaultInteractionRenderConfig(): InteractionRenderConfig;