loom-browser 0.0.8 → 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 (99) 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 -227
  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/tracks/BedTrack.d.ts +1 -5
  59. package/dist/types/react/ui/ChromosomeSelect.d.ts +1 -1
  60. package/dist/types/react/ui/ExportControls.d.ts +1 -1
  61. package/dist/types/react/ui/LocusInput.d.ts +1 -1
  62. package/dist/types/react/ui/Navbar.d.ts +1 -1
  63. package/dist/types/react/ui/WindowSize.d.ts +1 -1
  64. package/dist/types/react/ui/ZoomControls.d.ts +1 -1
  65. package/dist/types/remoteProtocol.d.ts +1 -1
  66. package/dist/types/roiManager.d.ts +47 -0
  67. package/dist/types/roiOverlayManager.d.ts +38 -0
  68. package/dist/types/stateProjection.d.ts +1 -1
  69. package/dist/types/trackDataManager.d.ts +48 -0
  70. package/dist/types/trackFactories.d.ts +140 -0
  71. package/dist/types/trackSelector.d.ts +1 -1
  72. package/dist/types/tracks/annotation/annotationTrackCanvas.d.ts +0 -1
  73. package/dist/types/tracks/annotation/config.d.ts +61 -0
  74. package/dist/types/tracks/baseTrackCanvas.d.ts +10 -0
  75. package/dist/types/tracks/configDiff.d.ts +14 -0
  76. package/dist/types/tracks/interaction/config.d.ts +40 -0
  77. package/dist/types/tracks/ruler/config.d.ts +24 -0
  78. package/dist/types/tracks/sequence/config.d.ts +56 -0
  79. package/dist/types/tracks/sequence/sequenceTrackCanvas.d.ts +3 -0
  80. package/dist/types/tracks/wig/config.d.ts +77 -0
  81. package/dist/types/types/igvCompat.d.ts +36 -0
  82. package/dist/types/types.d.ts +49 -285
  83. package/dist/types/ui/components/LoomBrowserShell.d.ts +2 -2
  84. package/dist/types/ui/components/LoomChromosomeSelect.d.ts +1 -1
  85. package/dist/types/ui/components/LoomContextMenu.d.ts +1 -0
  86. package/dist/types/ui/components/LoomExportControls.d.ts +1 -1
  87. package/dist/types/ui/components/LoomLocusInput.d.ts +1 -1
  88. package/dist/types/ui/components/LoomNavbar.d.ts +1 -1
  89. package/dist/types/ui/components/LoomWindowSize.d.ts +1 -1
  90. package/dist/types/ui/components/LoomZoomControls.d.ts +1 -1
  91. package/dist/types/undoManager.d.ts +49 -0
  92. package/dist/types/worker/dataSourceRegistry.d.ts +2 -2
  93. package/dist/types/worker/serializedError.d.ts +16 -0
  94. package/dist/types/worker/taskTimeout.d.ts +21 -0
  95. package/dist/types/worker/webWorkerPool.d.ts +5 -2
  96. package/dist/types/worker/webWorkerProvider.d.ts +3 -0
  97. package/dist/types/workerDataSource.d.ts +2 -2
  98. package/dist/types/workerProvider.d.ts +2 -2
  99. package/package.json +1 -1
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Browser export utilities — SVG and PNG export for the DOM GenomeBrowser.
3
+ *
4
+ * Pure functions that render the multi-track browser state to SVG/PNG,
5
+ * including axis columns and ROI overlays.
6
+ *
7
+ * Extracted from GenomeBrowser to isolate export logic.
8
+ *
9
+ * Layer 4 (DOM): requires DOM APIs (for PNG rendering via Image/Canvas).
10
+ */
11
+ import type { Locus, ROI } from '../../types';
12
+ import type { ManagedTrack } from '../headless/headlessGenomeBrowser';
13
+ import type { RenderTheme } from '../../themes/renderTheme';
14
+ /**
15
+ * Render the DOM browser view as an SVG string, including axis columns.
16
+ *
17
+ * Pure function — takes all needed state as parameters.
18
+ * Matches igv.js Browser.toSVG() which calls renderSVGAxis() for each TrackView.
19
+ */
20
+ export declare function renderDOMBrowserSVG(managedTracks: readonly ManagedTrack[], locus: Locus, theme: RenderTheme, visibleROIs: ROI[], axisColumnWidth: number, options?: {
21
+ width?: number;
22
+ containerWidth?: number;
23
+ backdropColor?: string;
24
+ }): string;
25
+ /**
26
+ * Convert an SVG string to a PNG data URL.
27
+ *
28
+ * Pipeline: SVG string → Blob → object URL → Image → Canvas (DPR-scaled) → toDataURL.
29
+ */
30
+ export declare function svgToPNG(svgString: string, width: number, height: number, dpr: number): Promise<string>;
31
+ /** Trigger a file download via a temporary anchor element. */
32
+ export declare function triggerDownload(filename: string, url: string): void;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Common context menu item factories.
3
+ *
4
+ * Stateless functions that return ContextMenuItem[] — no DOM, no side effects.
5
+ * The ContextMenuCallbacks interface decouples menu items from browser-level
6
+ * actions (removing tracks, showing dialogs).
7
+ *
8
+ * `numericDataMenuItems()` mirrors igv.js `TrackBase.numericDataMenuItems()`
9
+ * (js/trackBase.ts lines 510-552), which is shared by WigTrack, BAMTrack,
10
+ * QTLTrack, GCNVTrack, CNVPytorTrack, GWASTrack, InteractionTrack, and
11
+ * MergedTrack — any track with a Y-axis data range.
12
+ */
13
+ import type { ContextMenuItem, NumericState, Track, ROI, Locus } from '../../types';
14
+ /**
15
+ * Callback interface for common menu actions that require browser-level
16
+ * coordination. GenomeBrowser provides the implementation.
17
+ */
18
+ export interface ContextMenuCallbacks {
19
+ /** Set the track's pixel height and re-render. */
20
+ setTrackHeight(track: Track, height: number): void;
21
+ /** Remove the track from the browser. */
22
+ removeTrack(track: Track): void;
23
+ /** Show an input dialog. Returns the entered value, or null if cancelled. */
24
+ promptInput(label: string, currentValue: string | number): Promise<string | null>;
25
+ }
26
+ /** Common menu items that apply to all tracks (set height, remove). */
27
+ export declare function commonContextMenuItems(track: Track, callbacks: ContextMenuCallbacks): ContextMenuItem[];
28
+ /**
29
+ * Menu items for quantitative/numeric tracks: set data range, log scale, autoscale.
30
+ *
31
+ * Mirrors igv.js `TrackBase.numericDataMenuItems()` (js/trackBase.ts lines 510-552).
32
+ * In igv.js this is a method on TrackBase used by 8 track classes. In our
33
+ * architecture it's a stateless factory that takes the track's NumericState
34
+ * (state + callbacks combined), matching our separation of data from DOM.
35
+ *
36
+ * Items produced:
37
+ * 1. "Set data range" — prompts for min/max, disables autoscale when set
38
+ * (mirrors igv.js DataRangeDialog → TrackBase.setDataRange)
39
+ * 2. "Log scale" checkbox — only if logScale is supported (state.logScale !== undefined)
40
+ * (mirrors igv.js conditional on this.logScale !== undefined)
41
+ * 3. "Autoscale" checkbox
42
+ * (mirrors igv.js autoScaleHandler)
43
+ */
44
+ export declare function numericDataMenuItems(state: NumericState, promptInput: ContextMenuCallbacks['promptInput']): ContextMenuItem[];
45
+ /**
46
+ * Callback interface for ROI menu actions that require browser-level coordination.
47
+ */
48
+ export interface ROIMenuCallbacks {
49
+ /** Navigate the browser to the ROI's genomic region. */
50
+ goToRegion(locus: Locus): void;
51
+ /** Update an ROI's properties. */
52
+ updateROI(roiId: string, changes: Partial<Omit<ROI, 'id'>>): void;
53
+ /** Remove an ROI by ID. */
54
+ removeROI(roiId: string): void;
55
+ /** Show an input dialog. Returns the entered value, or null if cancelled. */
56
+ promptInput(label: string, currentValue: string | number): Promise<string | null>;
57
+ }
58
+ /**
59
+ * Context menu items for an ROI region.
60
+ *
61
+ * Mirrors igv.js ROIMenu (js/roi/ROIMenu.ts) but with stateless factory pattern.
62
+ * Items: edit name, edit description, set color, separator, go to region, remove.
63
+ */
64
+ export declare function roiContextMenuItems(roi: ROI, callbacks: ROIMenuCallbacks): ContextMenuItem[];
@@ -0,0 +1,49 @@
1
+ /**
2
+ * ContextMenuManager — handles right-click context menus for tracks and ROIs.
3
+ *
4
+ * Manages the contextmenu event listener, lazy input dialog creation,
5
+ * track-specific and common menu item assembly, and ROI context menus.
6
+ *
7
+ * Extracted from GenomeBrowser to isolate context menu lifecycle.
8
+ *
9
+ * Layer 4 (DOM): requires DOM APIs.
10
+ */
11
+ import type { Track, TrackContextMenuEvent, ROI, Locus } from '../../types';
12
+ import type { ContextMenuProvider } from '../../contextMenuProvider';
13
+ import type { PopupProvider } from '../../popupProvider';
14
+ /** Callback interface for context menu actions that require browser-level coordination. */
15
+ export interface ContextMenuManagerCallbacks {
16
+ findTrackForTarget(target: EventTarget | null): Track | null;
17
+ getLocus(): Locus;
18
+ getViewportWidth(): number;
19
+ removeTrack(track: Track): void;
20
+ onAxisUpdate(track: Track): void;
21
+ updateROI(roiId: string, changes: Partial<Omit<ROI, 'id'>>): ROI | undefined;
22
+ removeROI(roiId: string): boolean;
23
+ setLocus(locus: Locus): void;
24
+ emitTrackContextMenu(event: TrackContextMenuEvent): void;
25
+ emitROIContextMenu(event: {
26
+ roi: ROI;
27
+ genomicLocation: number;
28
+ x: number;
29
+ y: number;
30
+ }): void;
31
+ }
32
+ export declare class ContextMenuManager {
33
+ private container;
34
+ private axisColumnWidth;
35
+ private contextMenuProvider;
36
+ private popupProvider;
37
+ private callbacks;
38
+ private handleContextMenu;
39
+ private inputDialog;
40
+ constructor(container: HTMLElement, axisColumnWidth: number, contextMenuProvider: ContextMenuProvider | undefined, popupProvider: PopupProvider | undefined, callbacks: ContextMenuManagerCallbacks);
41
+ /** Attach the contextmenu event listener to the container. */
42
+ setup(): void;
43
+ /** Show context menu for an ROI region. */
44
+ showROIContextMenu(roi: ROI, e: MouseEvent): void;
45
+ /** Remove context menu listener and dispose of input dialog. */
46
+ dispose(): void;
47
+ /** Lazy-create the input dialog element. Consolidates duplicated creation logic. */
48
+ private ensureInputDialog;
49
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Default provider factories for GenomeBrowser.
3
+ *
4
+ * Creates lazy-loaded Web Component-based providers for popups and context menus.
5
+ * Separated to keep GenomeBrowser focused on browser orchestration.
6
+ *
7
+ * Layer 4 (DOM): requires DOM APIs.
8
+ */
9
+ import type { ContextMenuProvider } from '../../contextMenuProvider';
10
+ import type { PopupProvider } from '../../popupProvider';
11
+ /**
12
+ * Create a default ContextMenuProvider using <loom-context-menu>.
13
+ * This avoids statically importing the Web Component class (which extends
14
+ * HTMLElement and breaks SSR). The custom element self-registers on first
15
+ * import of ui/components/LoomContextMenu, but GenomeBrowser is always
16
+ * DOM-attached so we can safely trigger registration here.
17
+ */
18
+ export declare function createDefaultContextMenuProvider(): ContextMenuProvider;
19
+ /**
20
+ * Create a default PopupProvider using <loom-popup>.
21
+ * Same lazy/SSR-safe pattern as createDefaultContextMenuProvider.
22
+ */
23
+ export declare function createDefaultPopupProvider(): PopupProvider;
@@ -0,0 +1,171 @@
1
+ /**
2
+ * DOM-attached GenomeBrowser — extends HeadlessGenomeBrowser with pointer events,
3
+ * ResizeObserver, canvas stacking, and sweep-to-zoom.
4
+ *
5
+ * Coordinates multiple Track instances, stacking them vertically in a container.
6
+ * Static rendering is the base — interactivity (drag-to-pan) is enabled by default
7
+ * but can be disabled via `interactive: false`.
8
+ *
9
+ * Ruler tracks get special treatment: dragging on a ruler creates a selection
10
+ * overlay (sweep-to-zoom) instead of panning.
11
+ *
12
+ * Delegates to focused single-responsibility modules:
13
+ * - PointerEventManager: drag/pan/sweep/click/hover/wheel/reorder
14
+ * - ROIOverlayManager: DOM-based ROI region rendering
15
+ * - ContextMenuManager: right-click context menus for tracks and ROIs
16
+ * - browserExport: SVG/PNG export utilities
17
+ *
18
+ * Usage:
19
+ * const browser = new GenomeBrowser(container, {
20
+ * locus: { chr: 'chr17', start: 7668000, end: 7688000 },
21
+ * })
22
+ * browser.addTrack(rulerTrack)
23
+ * browser.addTrack(geneTrack)
24
+ * // Drag to pan — works out of the box.
25
+ * // Drag on ruler — sweep to zoom.
26
+ * // Cleanup:
27
+ * browser.dispose()
28
+ */
29
+ import type { Track, DataSource, SessionConfig, DataSourceConfig } from "../../types";
30
+ import { HeadlessGenomeBrowser } from "../headless/headlessGenomeBrowser";
31
+ import type { HeadlessGenomeBrowserOptions } from "../headless/headlessGenomeBrowser";
32
+ import type { RemoteSocket } from "../../remoteProtocol";
33
+ import type { CreateTrackFromSessionOptions } from "../headless/session";
34
+ export { BrowserEvent } from "../headless/headlessGenomeBrowser";
35
+ export type { BrowserEvents } from "../headless/headlessGenomeBrowser";
36
+ export interface GenomeBrowserOptions extends HeadlessGenomeBrowserOptions {
37
+ /** Enable mouse/touch drag to pan. Default: true. */
38
+ interactive?: boolean;
39
+ /** Enable trackpad pinch and scroll-wheel zoom. Default: true when interactive. */
40
+ wheelZoom?: boolean;
41
+ /**
42
+ * Auto-create a unified web worker pool for off-main-thread tasks and data fetching.
43
+ * - `true`: create a pool with `navigator.hardwareConcurrency` workers (capped at 4)
44
+ * - `number`: create a pool with that many workers
45
+ * - `false` / `undefined`: no auto-created workers (main-thread fallback)
46
+ *
47
+ * Ignored when `workerProvider` is explicitly passed.
48
+ *
49
+ * Uses `import.meta.url` to resolve the worker script. If worker creation
50
+ * fails (e.g. due to CSP or bundler issues), falls back silently to
51
+ * main-thread execution.
52
+ *
53
+ * For bundler users who need custom worker instantiation, pass
54
+ * `workerFactory` instead (see example below).
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * // Simple — auto-detect pool size:
59
+ * new GenomeBrowser(container, { locus, workers: true })
60
+ *
61
+ * // Explicit pool size:
62
+ * new GenomeBrowser(container, { locus, workers: 2 })
63
+ *
64
+ * // Bundler users (webpack 5, Vite) — custom factory:
65
+ * new GenomeBrowser(container, {
66
+ * locus,
67
+ * workerFactory: () => new Worker(
68
+ * new URL('loom/dist/loom-worker.js', import.meta.url)
69
+ * ),
70
+ * })
71
+ * ```
72
+ */
73
+ workers?: boolean | number;
74
+ /**
75
+ * Factory function that creates Worker instances for the worker pool.
76
+ * Use this with bundlers (webpack 5, Vite) that require the
77
+ * `new Worker(new URL(...))` pattern.
78
+ *
79
+ * Ignored when `workerProvider` is explicitly passed.
80
+ * When set, `workers` defaults to `true` (pool size = hardwareConcurrency, capped at 4).
81
+ */
82
+ workerFactory?: () => Worker;
83
+ }
84
+ export declare class GenomeBrowser extends HeadlessGenomeBrowser {
85
+ private container;
86
+ private interactive;
87
+ private resizeObserver;
88
+ private trackRows;
89
+ private remoteConnection;
90
+ private featureOverlays;
91
+ /** Worker provider auto-created by `workers` option. Disposed on cleanup. */
92
+ private ownedWorkerProvider;
93
+ private handleKeyDown;
94
+ private handleDocMouseDown;
95
+ private pointerManager;
96
+ private roiOverlayManager;
97
+ private contextMenuManager;
98
+ constructor(container: HTMLElement, options: GenomeBrowserOptions);
99
+ /** Build a DOM row for a track (axis column + viewport wrapper). */
100
+ private _buildTrackRow;
101
+ /** Post-registration UI setup for a track row (axis content, cursors, drag handlers). */
102
+ private _setupTrackRowUI;
103
+ /** Add a track and attach its canvas to the container. */
104
+ addTrack<F>(track: Track, dataSource?: DataSource<F>, dataSourceConfig?: DataSourceConfig, maxTrackHeight?: number, order?: number): string;
105
+ /** Remove a track and its row from the container. */
106
+ removeTrack(trackOrId: Track | string): void;
107
+ /** Move a track and reorder the DOM rows to match. */
108
+ moveTrack(track: Track, toIndex: number): void;
109
+ /**
110
+ * Load a session, replacing all current tracks.
111
+ * Removes existing canvases from the DOM, then delegates to the headless
112
+ * implementation which recreates tracks. New canvases are attached via addTrack().
113
+ */
114
+ loadSession(session: SessionConfig, options?: CreateTrackFromSessionOptions): void;
115
+ /** Re-render all tracks, reading width from the DOM container. */
116
+ render(): void;
117
+ /**
118
+ * Attach a remote WebSocket connection.
119
+ * Incoming command messages are automatically dispatched.
120
+ * Browser events are automatically forwarded.
121
+ */
122
+ attachRemote(socket: RemoteSocket): void;
123
+ /** Detach the remote connection and stop forwarding events. */
124
+ detachRemote(): void;
125
+ dispose(): void;
126
+ /**
127
+ * Update the axis content for a track based on its getAxisInfo().
128
+ * Uses a canvas for quantitative axes (tick marks + labels) matching igv.js paintAxis,
129
+ * and a DOM label for annotation tracks (e.g., gene track name).
130
+ */
131
+ private updateAxisContent;
132
+ /**
133
+ * Prepare an axis canvas at the correct size with DPR scaling,
134
+ * then delegate to the stateless render function.
135
+ */
136
+ private paintAxisCanvas;
137
+ /** Check if a pointer event target is a ruler track canvas. */
138
+ private isRulerCanvas;
139
+ /** Check if an event originated inside an overlay UI component (Shadow DOM) or ROI element. */
140
+ private isOverlayTarget;
141
+ /** Find the track whose canvas contains the given event target. */
142
+ private findTrackForTarget;
143
+ /** Sync DOM after any sort (addTrack, addGeneTrack, etc.). */
144
+ protected onTracksSorted(): void;
145
+ /** Reorder DOM rows to match managedTracks order. */
146
+ private syncDOMOrder;
147
+ private setupUndoKeyboardHandler;
148
+ private teardownUndoKeyboardHandler;
149
+ private renderROIOverlays;
150
+ /** Update all feature overlays after render. */
151
+ private updateFeatureOverlays;
152
+ /** Update the feature overlay for a single track. */
153
+ private updateFeatureOverlay;
154
+ /**
155
+ * Export the current view as an SVG string, including axis columns.
156
+ * Overrides HeadlessGenomeBrowser.toSVG() to add axis rendering.
157
+ */
158
+ toSVG(options?: {
159
+ width?: number;
160
+ backdropColor?: string;
161
+ }): string;
162
+ /**
163
+ * Export the current view as a PNG data URL.
164
+ * Pipeline: toSVG() → Blob → Image → Canvas (DPR-scaled) → toDataURL.
165
+ */
166
+ toPNG(): Promise<string>;
167
+ /** Download the current view as an SVG file. */
168
+ saveSVGtoFile(filename?: string): void;
169
+ /** Download the current view as a PNG file. */
170
+ savePNGtoFile(filename?: string): Promise<void>;
171
+ }
@@ -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 '../headless/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
+ }
@@ -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
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * SVG overlay for interactive feature highlighting.
3
+ *
4
+ * Positions transparent SVG `<rect>` elements on top of a track's canvas,
5
+ * providing native CSS `:hover` states and click targets without canvas repaints.
6
+ * Follows the same DOM-over-canvas pattern used by ROI overlays in GenomeBrowser.
7
+ *
8
+ * On hover, features get a tinted fill matching their own color plus a subtle
9
+ * glow/shadow effect, making the canvas-rendered feature feel highlighted.
10
+ */
11
+ import type { FeatureRect } from '../../types';
12
+ export declare class SVGFeatureOverlay {
13
+ private svg;
14
+ private group;
15
+ private defs;
16
+ /** Callback fired when a feature rect is clicked. */
17
+ onFeatureClick?: (rect: FeatureRect, event: MouseEvent) => void;
18
+ constructor(container: HTMLElement);
19
+ /** Rebuild SVG rects from feature geometry. */
20
+ update(rects: FeatureRect[]): void;
21
+ /** Suppress pointer events on overlay rects (e.g., during drag). */
22
+ setSuppressed(suppressed: boolean): void;
23
+ dispose(): void;
24
+ /** Create an SVG filter that produces a colored glow. */
25
+ private createGlowFilter;
26
+ private createRect;
27
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shared error utilities for the Loom genome browser.
3
+ *
4
+ * Consolidates error classification and normalization patterns
5
+ * previously scattered across multiple modules.
6
+ */
7
+ /** Check if an error is an AbortError (from fetch abort, signal abort, or worker abort). */
8
+ export declare function isAbortError(err: unknown): boolean;
9
+ /** Normalize an unknown thrown value into an Error instance. */
10
+ export declare function normalizeError(err: unknown): Error;