loom-browser 0.0.6 → 0.0.7

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 (51) hide show
  1. package/dist/loom-data-worker.js +10458 -0
  2. package/dist/loom-data-worker.min.js +2 -0
  3. package/dist/loom-data-worker.min.js.map +1 -0
  4. package/dist/loom-react.esm.js +1005 -318
  5. package/dist/loom-react.esm.min.js +1 -1
  6. package/dist/loom-react.esm.min.js.map +1 -1
  7. package/dist/loom-worker.js +10591 -0
  8. package/dist/loom-worker.min.js +2 -0
  9. package/dist/loom-worker.min.js.map +1 -0
  10. package/dist/loom.esm.js +8427 -7693
  11. package/dist/loom.esm.min.js +1 -1
  12. package/dist/loom.esm.min.js.map +1 -1
  13. package/dist/loom.js +8429 -7693
  14. package/dist/loom.min.js +1 -1
  15. package/dist/loom.min.js.map +1 -1
  16. package/dist/tsconfig.src.tsbuildinfo +1 -1
  17. package/dist/types/bigwig/index.d.ts +2 -5
  18. package/dist/types/dataSourceWorkerProvider.d.ts +79 -0
  19. package/dist/types/dataSources/bigWigDataSource.d.ts +1 -3
  20. package/dist/types/dataSources/featureSourceFactory.d.ts +1 -2
  21. package/dist/types/dataSources/gtxDataSource.d.ts +1 -3
  22. package/dist/types/dataSources/textFeatureSource.d.ts +0 -4
  23. package/dist/types/genomeBrowser.d.ts +56 -1
  24. package/dist/types/gtx/index.d.ts +1 -4
  25. package/dist/types/headlessGenomeBrowser.d.ts +39 -2
  26. package/dist/types/index.d.ts +8 -2
  27. package/dist/types/mainThreadDataSourceProvider.d.ts +19 -0
  28. package/dist/types/react/LoomBrowser.d.ts +15 -1
  29. package/dist/types/session.d.ts +0 -3
  30. package/dist/types/svgFeatureOverlay.d.ts +27 -0
  31. package/dist/types/tabix/index.d.ts +0 -3
  32. package/dist/types/trackRegistry.d.ts +1 -4
  33. package/dist/types/tracks/annotation/annotationRenderer.d.ts +4 -1
  34. package/dist/types/tracks/annotation/annotationTrackCanvas.d.ts +9 -6
  35. package/dist/types/tracks/axis/axisRenderer.d.ts +2 -8
  36. package/dist/types/tracks/axis/index.d.ts +1 -1
  37. package/dist/types/tracks/baseTrackCanvas.d.ts +7 -1
  38. package/dist/types/tracks/interaction/interactionRenderer.d.ts +4 -1
  39. package/dist/types/tracks/trackLabel.d.ts +22 -0
  40. package/dist/types/tracks/wig/wigTrackCanvas.d.ts +2 -0
  41. package/dist/types/types.d.ts +18 -0
  42. package/dist/types/worker/dataSourceRegistry.d.ts +33 -0
  43. package/dist/types/worker/dataSourceWorkerScript.d.ts +13 -0
  44. package/dist/types/worker/unifiedWorkerScript.d.ts +17 -0
  45. package/dist/types/worker/webDataSourceWorkerProvider.d.ts +59 -0
  46. package/dist/types/worker/webUnifiedWorkerProvider.d.ts +64 -0
  47. package/dist/types/worker/webWorkerPool.d.ts +64 -0
  48. package/dist/types/worker/workerPoolScript.d.ts +17 -0
  49. package/dist/types/workerDataSource.d.ts +32 -0
  50. package/dist/types/workerProvider.d.ts +10 -3
  51. package/package.json +3 -1
@@ -6,15 +6,12 @@
6
6
  * by @gmod/bbi internally.
7
7
  */
8
8
  import type { WigFeature, WindowFunction, Locus } from '../types';
9
- import type { WorkerProvider } from '../workerProvider';
10
9
  export { BinaryParser } from '../io/binaryParser';
11
10
  export interface FetchBigWigOptions {
12
11
  /** Resolution in base pairs per pixel. Used to select an appropriate zoom level. */
13
12
  bpPerPixel?: number;
14
13
  /** Aggregation function for zoom-level data. Default: 'mean'. */
15
14
  windowFunction?: WindowFunction;
16
- /** @deprecated Worker dispatch is handled internally by @gmod/bbi. */
17
- workerProvider?: WorkerProvider;
18
15
  /** AbortSignal for cancelling in-flight HTTP requests. */
19
16
  signal?: AbortSignal;
20
17
  }
@@ -47,7 +44,7 @@ export interface BigWigTotalSummary {
47
44
  */
48
45
  export declare class BigWigReader {
49
46
  private readonly bw;
50
- constructor(url: string, _workerProvider?: WorkerProvider);
47
+ constructor(url: string);
51
48
  loadHeader(signal?: AbortSignal): Promise<BigWigHeader>;
52
49
  getTotalSummary(signal?: AbortSignal): Promise<BigWigTotalSummary | undefined>;
53
50
  readFeatures(chr: string, bpStart: number, bpEnd: number, bpPerPixel?: number, windowFunction?: WindowFunction, signal?: AbortSignal): Promise<WigFeature[]>;
@@ -61,6 +58,6 @@ export declare function fetchBigWigFeatures(url: string, locus: Locus, options?:
61
58
  * Fetch BigWig features across all specified chromosomes for whole genome view.
62
59
  * Returns features with per-chromosome coordinates (caller transforms to genome-wide).
63
60
  */
64
- export declare function fetchBigWigWGFeatures(url: string, chromNames: string[], bpPerPixel: number, options?: Pick<FetchBigWigOptions, 'windowFunction' | 'workerProvider' | 'signal'>): Promise<WigFeature[]>;
61
+ export declare function fetchBigWigWGFeatures(url: string, chromNames: string[], bpPerPixel: number, options?: Pick<FetchBigWigOptions, 'windowFunction' | 'signal'>): Promise<WigFeature[]>;
65
62
  /** Clear the BigWig reader cache (useful for testing or memory management). */
66
63
  export declare function clearBigWigCache(): void;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * DataSourceWorkerProvider — manages long-lived DataSource instances inside workers.
3
+ *
4
+ * Unlike the stateless WorkerProvider (fire-and-forget tasks), this provider
5
+ * creates persistent DataSource instances in workers that cache parsed headers,
6
+ * indices, and reader state across fetch calls.
7
+ *
8
+ * Inspired by JBrowse 2's RPC adapter system (GMOD/jbrowse-components).
9
+ *
10
+ * Layer 1 (Data + Layout): no DOM.
11
+ */
12
+ import type { DataSourceConfig, Locus } from './types';
13
+ /** Main thread → Worker messages. */
14
+ export type DataSourceWorkerRequest = {
15
+ type: 'create';
16
+ instanceId: string;
17
+ config: DataSourceConfig;
18
+ } | {
19
+ type: 'fetch';
20
+ instanceId: string;
21
+ fetchId: number;
22
+ locus: Locus;
23
+ bpPerPixel: number;
24
+ } | {
25
+ type: 'configure';
26
+ instanceId: string;
27
+ method: string;
28
+ args: unknown[];
29
+ } | {
30
+ type: 'cancel';
31
+ fetchId: number;
32
+ } | {
33
+ type: 'destroy';
34
+ instanceId: string;
35
+ };
36
+ /** Worker → Main thread messages. */
37
+ export type DataSourceWorkerResponse = {
38
+ type: 'ready';
39
+ } | {
40
+ type: 'fetchResult';
41
+ fetchId: number;
42
+ features: unknown[];
43
+ } | {
44
+ type: 'fetchError';
45
+ fetchId: number;
46
+ error: string;
47
+ };
48
+ /**
49
+ * Manages DataSource instances that live inside web workers.
50
+ *
51
+ * Each DataSource is identified by a unique `instanceId` (assigned by the caller).
52
+ * The provider routes messages to the correct worker using sticky routing
53
+ * (same URL → same worker) to preserve reader caches.
54
+ */
55
+ export interface DataSourceWorkerProvider {
56
+ /**
57
+ * Create a DataSource instance inside a worker.
58
+ * The instance persists until `destroy()` is called.
59
+ */
60
+ create(instanceId: string, config: DataSourceConfig): void;
61
+ /**
62
+ * Fetch features from a worker-resident DataSource.
63
+ * Supports cancellation via AbortSignal → cancel message.
64
+ */
65
+ fetch<F>(instanceId: string, locus: Locus, bpPerPixel: number, signal: AbortSignal): Promise<F[]>;
66
+ /**
67
+ * Send a configuration update to a worker-resident DataSource.
68
+ * Used for serializable setter calls like setCumulativeOffsets, setWindowFunction.
69
+ */
70
+ configure(instanceId: string, method: string, ...args: unknown[]): void;
71
+ /**
72
+ * Destroy a worker-resident DataSource instance.
73
+ */
74
+ destroy(instanceId: string): void;
75
+ /**
76
+ * Shut down all workers and release resources.
77
+ */
78
+ dispose(): void;
79
+ }
@@ -1,13 +1,11 @@
1
1
  import type { DataSource, Locus, WigFeature, WindowFunction } from '../types';
2
- import type { WorkerProvider } from '../workerProvider';
3
2
  import type { CumulativeOffsets } from '../genome/chromSizes';
4
3
  export declare class BigWigDataSource implements DataSource<WigFeature> {
5
4
  private url;
6
5
  private _windowFunction;
7
- private workerProvider?;
8
6
  private _cumulativeOffsets?;
9
7
  private _resolveChromName?;
10
- constructor(url: string, windowFunction?: WindowFunction, workerProvider?: WorkerProvider);
8
+ constructor(url: string, windowFunction?: WindowFunction);
11
9
  get windowFunction(): WindowFunction;
12
10
  /** Update the window function for future fetches. */
13
11
  setWindowFunction(wf: WindowFunction): void;
@@ -10,7 +10,6 @@
10
10
  * Layer 1 (Data + Layout): no DOM.
11
11
  */
12
12
  import type { DataSource } from '../types';
13
- import type { WorkerProvider } from '../workerProvider';
14
13
  export interface FeatureSourceConfig {
15
14
  /** URL to the data file. */
16
15
  url: string;
@@ -43,4 +42,4 @@ export interface FeatureSourceResult {
43
42
  *
44
43
  * Port of js/feature/featureSource.ts factory routing logic.
45
44
  */
46
- export declare function createFeatureSource(config: FeatureSourceConfig, workerProvider?: WorkerProvider): FeatureSourceResult;
45
+ export declare function createFeatureSource(config: FeatureSourceConfig): FeatureSourceResult;
@@ -16,17 +16,15 @@
16
16
  * Layer 1 (Data + Layout): no DOM, no canvas.
17
17
  */
18
18
  import type { DataSource, Locus, WigFeature, WindowFunction } from '../types';
19
- import type { WorkerProvider } from '../workerProvider';
20
19
  import type { CumulativeOffsets } from '../genome/chromSizes';
21
20
  export declare class GtxDataSource implements DataSource<WigFeature> {
22
21
  private url;
23
22
  private experimentId;
24
23
  private _windowFunction;
25
- private workerProvider?;
26
24
  private _cumulativeOffsets?;
27
25
  private _resolveChromName?;
28
26
  private reader;
29
- constructor(url: string, experimentId: string, windowFunction?: WindowFunction, workerProvider?: WorkerProvider);
27
+ constructor(url: string, experimentId: string, windowFunction?: WindowFunction);
30
28
  get windowFunction(): WindowFunction;
31
29
  /** Update the window function for future fetches. */
32
30
  setWindowFunction(wf: WindowFunction): void;
@@ -13,7 +13,6 @@
13
13
  import type { DataSource, Locus, TextFileFormat } from '../types';
14
14
  import type { CacheableFeature } from '../featureCache';
15
15
  import type { CumulativeOffsets } from '../genome/chromSizes';
16
- import type { WorkerProvider } from '../workerProvider';
17
16
  export interface TextFeatureSourceConfig {
18
17
  /** URL to the data file. */
19
18
  url: string;
@@ -25,8 +24,6 @@ export interface TextFeatureSourceConfig {
25
24
  indexed?: boolean;
26
25
  /** For GFF: whether to assemble transcript models. Default: true. */
27
26
  assembleGFF?: boolean;
28
- /** Worker provider for offloading CPU-intensive tasks. */
29
- workerProvider?: WorkerProvider;
30
27
  }
31
28
  /**
32
29
  * DataSource for text-based genomic feature files.
@@ -39,7 +36,6 @@ export declare class TextFeatureSource<F extends CacheableFeature = CacheableFea
39
36
  private readonly format;
40
37
  private readonly assembleGFF;
41
38
  private readonly _indexed;
42
- private readonly workerProvider?;
43
39
  private _resolveChromName?;
44
40
  private _cumulativeOffsets?;
45
41
  private tabixReader?;
@@ -32,6 +32,48 @@ export interface GenomeBrowserOptions extends HeadlessGenomeBrowserOptions {
32
32
  interactive?: boolean;
33
33
  /** Enable trackpad pinch and scroll-wheel zoom. Default: true when interactive. */
34
34
  wheelZoom?: boolean;
35
+ /**
36
+ * Auto-create a unified web worker pool for off-main-thread tasks and data fetching.
37
+ * - `true`: create a pool with `navigator.hardwareConcurrency` workers (capped at 4)
38
+ * - `number`: create a pool with that many workers
39
+ * - `false` / `undefined`: no auto-created workers (main-thread fallback)
40
+ *
41
+ * Ignored when `workerProvider` is explicitly passed.
42
+ *
43
+ * Uses `import.meta.url` to resolve the worker script. If worker creation
44
+ * fails (e.g. due to CSP or bundler issues), falls back silently to
45
+ * main-thread execution.
46
+ *
47
+ * For bundler users who need custom worker instantiation, pass
48
+ * `workerFactory` instead (see example below).
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * // Simple — auto-detect pool size:
53
+ * new GenomeBrowser(container, { locus, workers: true })
54
+ *
55
+ * // Explicit pool size:
56
+ * new GenomeBrowser(container, { locus, workers: 2 })
57
+ *
58
+ * // Bundler users (webpack 5, Vite) — custom factory:
59
+ * new GenomeBrowser(container, {
60
+ * locus,
61
+ * workerFactory: () => new Worker(
62
+ * new URL('loom/dist/loom-worker.js', import.meta.url)
63
+ * ),
64
+ * })
65
+ * ```
66
+ */
67
+ workers?: boolean | number;
68
+ /**
69
+ * Factory function that creates Worker instances for the worker pool.
70
+ * Use this with bundlers (webpack 5, Vite) that require the
71
+ * `new Worker(new URL(...))` pattern.
72
+ *
73
+ * Ignored when `workerProvider` is explicitly passed.
74
+ * When set, `workers` defaults to `true` (pool size = hardwareConcurrency, capped at 4).
75
+ */
76
+ workerFactory?: () => Worker;
35
77
  }
36
78
  export declare class GenomeBrowser extends HeadlessGenomeBrowser {
37
79
  private container;
@@ -69,9 +111,16 @@ export declare class GenomeBrowser extends HeadlessGenomeBrowser {
69
111
  private wheelRafId;
70
112
  private roiOverlayContainer;
71
113
  private roiElements;
114
+ private featureOverlays;
115
+ /** Worker provider auto-created by `workers` option. Disposed on cleanup. */
116
+ private ownedWorkerProvider;
72
117
  constructor(container: HTMLElement, options: GenomeBrowserOptions);
118
+ /** Build a DOM row for a track (axis column + viewport wrapper). */
119
+ private _buildTrackRow;
120
+ /** Post-registration UI setup for a track row (axis content, cursors, drag handlers). */
121
+ private _setupTrackRowUI;
73
122
  /** Add a track and attach its canvas to the container. */
74
- addTrack<F>(track: Track, dataSource?: DataSource<F>, dataSourceConfig?: DataSourceConfig, maxTrackHeight?: number): string;
123
+ addTrack<F>(track: Track, dataSource?: DataSource<F>, dataSourceConfig?: DataSourceConfig, maxTrackHeight?: number, order?: number): string;
75
124
  /** Remove a track and its row from the container. */
76
125
  removeTrack(trackOrId: Track | string): void;
77
126
  /** Move a track and reorder the DOM rows to match. */
@@ -121,6 +170,8 @@ export declare class GenomeBrowser extends HeadlessGenomeBrowser {
121
170
  private teardownHoverHandlers;
122
171
  private setupContextMenuHandler;
123
172
  private teardownContextMenuHandler;
173
+ /** Sync DOM after any sort (addTrack, addGeneTrack, etc.). */
174
+ protected onTracksSorted(): void;
124
175
  /** Reorder DOM rows to match managedTracks order. */
125
176
  private syncDOMOrder;
126
177
  /** Set up drag-to-reorder pointer handlers on an axis div. */
@@ -147,6 +198,10 @@ export declare class GenomeBrowser extends HeadlessGenomeBrowser {
147
198
  * DOM-based (not canvas) for easy hover/click interaction without
148
199
  * re-rendering track canvases.
149
200
  */
201
+ /** Update all feature overlays after render. */
202
+ private updateFeatureOverlays;
203
+ /** Update the feature overlay for a single track. */
204
+ private updateFeatureOverlay;
150
205
  private renderROIOverlays;
151
206
  /** Create a styled DOM element for an ROI region. */
152
207
  private createROIElement;
@@ -11,14 +11,11 @@
11
11
  export { GtxReader } from './gtxReader';
12
12
  export type { GtxHeader, ChromEntry, ExperimentEntry } from './gtxReader';
13
13
  import type { WigFeature, WindowFunction, Locus } from '../types';
14
- import type { WorkerProvider } from '../workerProvider';
15
14
  export interface FetchGtxOptions {
16
15
  /** Resolution in base pairs per pixel. Used to select an appropriate zoom level. */
17
16
  bpPerPixel?: number;
18
17
  /** Aggregation function for zoom-level data. Default: 'mean'. */
19
18
  windowFunction?: WindowFunction;
20
- /** Worker provider for offloading decode work (reserved for future use). */
21
- workerProvider?: WorkerProvider;
22
19
  /** AbortSignal for cancelling in-flight HTTP requests. */
23
20
  signal?: AbortSignal;
24
21
  }
@@ -30,7 +27,7 @@ export declare function fetchGtxFeatures(url: string, experimentId: string, locu
30
27
  * Fetch GTX features across all specified chromosomes for whole genome view.
31
28
  * Returns features with per-chromosome coordinates (caller transforms to genome-wide).
32
29
  */
33
- export declare function fetchGtxWGFeatures(url: string, experimentId: string, chromNames: string[], bpPerPixel: number, options?: Pick<FetchGtxOptions, 'windowFunction' | 'workerProvider' | 'signal'>): Promise<WigFeature[]>;
30
+ export declare function fetchGtxWGFeatures(url: string, experimentId: string, chromNames: string[], bpPerPixel: number, options?: Pick<FetchGtxOptions, 'windowFunction' | 'signal'>): Promise<WigFeature[]>;
34
31
  /**
35
32
  * Fetch GTX features for multiple experiments simultaneously.
36
33
  * Optimizes network by merging byte ranges for experiments in the same tiles.
@@ -20,6 +20,7 @@ import type { Locus, Track, DataSource, FeatureCacheEntry, SessionConfig, TrackS
20
20
  import { ROISet } from './roi/roiSet';
21
21
  import type { CanvasProvider } from './canvasProvider';
22
22
  import type { WorkerProvider } from './workerProvider';
23
+ import type { DataSourceWorkerProvider } from './dataSourceWorkerProvider';
23
24
  import type { PopupProvider } from './popupProvider';
24
25
  import type { ContextMenuProvider } from './contextMenuProvider';
25
26
  import type { RenderTheme } from './themes/renderTheme';
@@ -122,7 +123,9 @@ export interface HeadlessGenomeBrowserOptions {
122
123
  viewportWidth?: number;
123
124
  /** Canvas provider for environment abstraction. Default: DOMCanvasProvider. */
124
125
  canvasProvider?: CanvasProvider;
125
- /** Worker provider for offloading CPU-intensive tasks. Default: main-thread execution. */
126
+ /** Worker provider for offloading CPU-intensive tasks. Default: main-thread execution.
127
+ * If this also implements DataSourceWorkerProvider (e.g. WebWorkerPool),
128
+ * it will be used for data fetching automatically. */
126
129
  workerProvider?: WorkerProvider;
127
130
  /** Popup provider for rendering feature popups on click/hover. Default in GenomeBrowser: DefaultPopupProvider. Pass null to disable. */
128
131
  popupProvider?: PopupProvider | null;
@@ -264,10 +267,16 @@ export declare class HeadlessGenomeBrowser {
264
267
  protected roiSets: ROISet[];
265
268
  /** Inflight fetch promises keyed by (cacheKey + fetchRegion + bpPerPixel) for deduplication. */
266
269
  private inflightFetches;
270
+ /** Timer for debouncing data loads during rapid zoom/pan. */
271
+ private loadDebounceTimer;
272
+ /** When true, sortTracks() is a no-op. Used for batch track additions (e.g. loadSession). */
273
+ private _deferSort;
267
274
  /** Canvas provider for environment abstraction. Available for convenience API / future use. */
268
275
  readonly canvasProvider: CanvasProvider;
269
276
  /** Worker provider for offloading CPU-intensive tasks. */
270
277
  readonly workerProvider?: WorkerProvider;
278
+ /** Data source worker provider for running DataSources in web workers. */
279
+ readonly dataSourceWorkerProvider?: DataSourceWorkerProvider;
271
280
  /** Popup provider for rendering feature popups on click/hover. */
272
281
  readonly popupProvider?: PopupProvider;
273
282
  /** Context menu provider for right-click menus. */
@@ -293,6 +302,11 @@ export declare class HeadlessGenomeBrowser {
293
302
  /** Agent-friendly state projection manager. Lazily created on first access. */
294
303
  get state(): StateProjection;
295
304
  constructor(options: HeadlessGenomeBrowserOptions);
305
+ /**
306
+ * Create a WorkerDataSource proxy for worker-eligible configs, or return null
307
+ * if dataSourceWorkerProvider is not set. Handles create + chrom alias + offsets wiring.
308
+ */
309
+ private createWorkerDataSource;
296
310
  /** Clamp a locus to valid chromosome bounds. No-op if chromSizes is not set. */
297
311
  protected clamp(locus: Locus): Locus;
298
312
  /** Subscribe to a browser event. Returns an unsubscribe function. */
@@ -306,7 +320,7 @@ export declare class HeadlessGenomeBrowser {
306
320
  */
307
321
  setViewportWidth(width: number): void;
308
322
  /** Add a track with an optional data source for automatic data management. */
309
- addTrack<F>(track: Track, dataSource?: DataSource<F>, dataSourceConfig?: DataSourceConfig, maxTrackHeight?: number): string;
323
+ addTrack<F>(track: Track, dataSource?: DataSource<F>, dataSourceConfig?: DataSourceConfig, maxTrackHeight?: number, order?: number): string;
310
324
  /** Remove a track by reference or by stable string ID. */
311
325
  removeTrack(trackOrId: Track | string): void;
312
326
  /**
@@ -314,6 +328,22 @@ export declare class HeadlessGenomeBrowser {
314
328
  * Emits BrowserEvent.TrackOrderChanged with the new track order.
315
329
  */
316
330
  moveTrack(track: Track, toIndex: number): void;
331
+ /**
332
+ * Sort tracks by priority (descending): positive = top, 0 = middle, negative = bottom.
333
+ * Priority comes from the track type default + per-track `order` override.
334
+ * Within the same effective priority, insertion order is preserved (stable sort).
335
+ */
336
+ private sortTracks;
337
+ /** Hook for subclasses to react to track order changes (e.g., DOM reorder). */
338
+ protected onTracksSorted(): void;
339
+ /**
340
+ * Persist current array positions into mt.order so future sorts preserve
341
+ * manual reordering. Uses descending values (top track = highest) scaled
342
+ * above the type-priority range so explicit order dominates.
343
+ */
344
+ protected _assignOrderFromPosition(): void;
345
+ /** Find the ManagedTrack entry for a given track canvas. */
346
+ private findMT;
317
347
  /** Get the current track order. */
318
348
  getTrackOrder(): Track[];
319
349
  /** Find a managed track by its stable string ID. Returns undefined if not found. */
@@ -478,6 +508,13 @@ export declare class HeadlessGenomeBrowser {
478
508
  * Returns null if the track has no features at the given point.
479
509
  */
480
510
  protected resolveInteraction(track: Track, x: number, y: number): TrackInteractionEvent | null;
511
+ /**
512
+ * Debounced wrapper around loadAllTracksIfNeeded.
513
+ * During rapid zoom/pan, this coalesces multiple setLocus() calls into a
514
+ * single data fetch cycle after the interaction settles (100ms quiet period).
515
+ * Abort in-flight requests immediately so they don't race with the eventual fetch.
516
+ */
517
+ private debouncedLoad;
481
518
  protected loadAllTracksIfNeeded(): void;
482
519
  /**
483
520
  * Load data for a single track, deduplicating against inflight fetches
@@ -10,7 +10,13 @@ export { MainThreadProvider, mainThreadProvider } from './workerProvider';
10
10
  export { WebWorkerProvider } from './worker/webWorkerProvider';
11
11
  export type { WebWorkerProviderOptions } from './worker/webWorkerProvider';
12
12
  export { NodeWorkerProvider } from './worker/nodeWorkerProvider';
13
+ export type { DataSourceWorkerProvider, DataSourceWorkerRequest, DataSourceWorkerResponse } from './dataSourceWorkerProvider';
14
+ export { WorkerDataSource } from './workerDataSource';
15
+ export { WebWorkerPool } from './worker/webWorkerPool';
16
+ export type { WebWorkerPoolOptions } from './worker/webWorkerPool';
13
17
  export { BaseTrackCanvas } from './tracks/baseTrackCanvas';
18
+ export { renderTrackNameLabel } from './tracks/trackLabel';
19
+ export type { TrackNameLabelOptions } from './tracks/trackLabel';
14
20
  export type { AnnotationFeature, Exon, AnnotationRenderConfig, RenderContext, DisplayMode, Locus, Track, RulerRenderConfig, AxisInfo, TrackFeatureSummary, WigFeatureSummary, AnnotationFeatureSummary, InteractionFeatureSummary } from './types';
15
21
  export type { WigFeature, WigRenderConfig, WigColorValue, WigGraphType, WindowFunction, WigGuideLine } from './types';
16
22
  export type { SequenceRenderConfig, SequenceType, SequenceTrackSessionConfig, SequenceSessionOverrides } from './types';
@@ -18,7 +24,7 @@ export { defaultSequenceRenderConfig } from './types';
18
24
  export type { InteractionFeature, InteractionRenderConfig, ArcOrientation, ArcDisplayMode, InteractionTrackSessionConfig, InteractionSessionOverrides } from './types';
19
25
  export { defaultInteractionRenderConfig } from './types';
20
26
  export type { DataSource, FeatureCacheEntry, DataDrivenTrack } from './types';
21
- export type { PopupDataItem, HitTestResult, TrackInteractionEvent, ContextMenuItem, TrackContextMenuEvent, NumericState, ROI, ROISetConfig, ROIInteractionEvent } from './types';
27
+ export type { PopupDataItem, HitTestResult, TrackInteractionEvent, ContextMenuItem, TrackContextMenuEvent, NumericState, ROI, ROISetConfig, ROIInteractionEvent, FeatureRect } from './types';
22
28
  export type { SessionConfig, TrackSessionConfig, WigTrackSessionConfig, AnnotationTrackSessionConfig, RulerTrackSessionConfig, WigSessionOverrides, AnnotationSessionOverrides, RulerSessionOverrides, DataSourceConfig, BigWigDataSourceConfig, GtxDataSourceConfig, UCSCDataSourceConfig, TextDataSourceConfig, MemoryDataSourceConfig, SequenceProvider, IgvSessionObject, IgvReferenceConfig, IgvTrackConfig, Chromosome, Genome, GenomeConfig, ChromAliasRecord, Strand, TextFileFormat, BedFeature, PeakFeature, BedGraphFeature, GFFRecord, GFFFeature, TextFeature, } from './types';
23
29
  export { defaultAnnotationRenderConfig, defaultRulerRenderConfig, defaultWigRenderConfig } from './types';
24
30
  export type { Packable } from './pack';
@@ -30,7 +36,7 @@ export { renderRulerTrack, renderWholeGenomeRuler } from './tracks/ruler/rulerRe
30
36
  export type { WholeGenomeRulerContext } from './tracks/ruler/rulerRenderer';
31
37
  export { RulerTrackCanvas } from './tracks/ruler/rulerTrackCanvas';
32
38
  export type { RulerTrackCanvasOptions } from './tracks/ruler/rulerTrackCanvas';
33
- export { renderQuantitativeAxis, renderLabelAxis, prettyPrintNumber } from './tracks/axis/axisRenderer';
39
+ export { renderQuantitativeAxis, prettyPrintNumber } from './tracks/axis/axisRenderer';
34
40
  export { renderWigTrack } from './tracks/wig/wigRenderer';
35
41
  export { WigTrackCanvas } from './tracks/wig/wigTrackCanvas';
36
42
  export type { WigTrackCanvasOptions } from './tracks/wig/wigTrackCanvas';
@@ -0,0 +1,19 @@
1
+ /**
2
+ * MainThreadDataSourceProvider — fallback DataSourceWorkerProvider that runs
3
+ * DataSources directly on the main thread with no serialization overhead.
4
+ *
5
+ * Analogous to JBrowse 2's MainThreadRpcDriver.
6
+ * Used when web workers are unavailable or for debugging.
7
+ *
8
+ * Layer 1 (Data + Layout): no DOM.
9
+ */
10
+ import type { DataSourceWorkerProvider } from './dataSourceWorkerProvider';
11
+ import type { DataSourceConfig, Locus } from './types';
12
+ export declare class MainThreadDataSourceProvider implements DataSourceWorkerProvider {
13
+ private readonly instances;
14
+ create(instanceId: string, config: DataSourceConfig): void;
15
+ fetch<F>(instanceId: string, locus: Locus, bpPerPixel: number, signal: AbortSignal): Promise<F[]>;
16
+ configure(instanceId: string, method: string, ...args: unknown[]): void;
17
+ destroy(instanceId: string): void;
18
+ dispose(): void;
19
+ }
@@ -25,7 +25,21 @@ export interface LoomBrowserProps {
25
25
  interactive?: boolean;
26
26
  /** Enable wheel zoom. Default: true. */
27
27
  wheelZoom?: boolean;
28
- /** Worker provider for off-main-thread tasks. */
28
+ /**
29
+ * Auto-create a unified web worker pool. `true` for auto pool size,
30
+ * or a number for explicit pool size. See GenomeBrowserOptions.workers.
31
+ */
32
+ workers?: boolean | number;
33
+ /**
34
+ * Factory for custom worker instantiation (webpack 5, Vite).
35
+ * See GenomeBrowserOptions.workerFactory.
36
+ */
37
+ workerFactory?: () => Worker;
38
+ /**
39
+ * Worker provider for off-main-thread tasks.
40
+ * If this also implements DataSourceWorkerProvider (e.g. WebWorkerPool),
41
+ * it will be used for data fetching automatically.
42
+ */
29
43
  workerProvider?: WorkerProvider;
30
44
  /** Popup provider. Pass null to disable. */
31
45
  popupProvider?: PopupProvider | null;
@@ -15,13 +15,10 @@
15
15
  */
16
16
  import type { SessionConfig, TrackSessionConfig, IgvSessionObject, Locus, SequenceProvider } from './types';
17
17
  import type { CanvasProvider } from './canvasProvider';
18
- import type { WorkerProvider } from './workerProvider';
19
18
  import type { RenderTheme } from './themes/renderTheme';
20
19
  export type { CreatedTrack } from './trackRegistry';
21
20
  export declare const SESSION_VERSION = "1.0";
22
21
  export interface CreateDataSourceOptions {
23
- /** Worker provider for offloading CPU-intensive tasks in data sources. */
24
- workerProvider?: WorkerProvider;
25
22
  }
26
23
  /**
27
24
  * @deprecated Use the track registry (`createTrackFromConfig`) instead, which
@@ -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
+ }
@@ -5,12 +5,9 @@
5
5
  * All BGZF decompression, index parsing, and block fetching is handled
6
6
  * by @gmod/tabix internally.
7
7
  */
8
- import type { WorkerProvider } from '../workerProvider';
9
8
  export interface TabixReaderOptions {
10
9
  /** URL to the .tbi index file. Defaults to `url + '.tbi'`. */
11
10
  indexUrl?: string;
12
- /** @deprecated Worker dispatch is handled internally by @gmod/tabix. */
13
- workerProvider?: WorkerProvider;
14
11
  }
15
12
  export interface TabixHeader {
16
13
  nref: number;
@@ -13,13 +13,11 @@
13
13
  */
14
14
  import type { Locus, Track, DataSource, DataSourceConfig, TrackSessionConfig, SequenceProvider } from './types';
15
15
  import type { CanvasProvider } from './canvasProvider';
16
- import type { WorkerProvider } from './workerProvider';
17
16
  import type { RenderTheme } from './themes/renderTheme';
18
17
  /** Context passed to every track creator function. */
19
18
  export interface TrackCreatorContext {
20
19
  locus: Locus;
21
20
  canvasProvider: CanvasProvider;
22
- workerProvider?: WorkerProvider;
23
21
  theme?: Partial<RenderTheme>;
24
22
  /** Sequence provider from the genome, used by sequence tracks. */
25
23
  sequenceProvider?: SequenceProvider;
@@ -65,7 +63,7 @@ export declare function getTrackCreator(type: string): TrackCreator | undefined;
65
63
  * Mirrors igv.js `knownTrackTypes()` (js/trackFactory.ts).
66
64
  */
67
65
  export declare function knownTrackTypes(): Set<string>;
68
- export declare function createDataSource(config: DataSourceConfig, workerProvider?: WorkerProvider): DataSource;
66
+ export declare function createDataSource(config: DataSourceConfig): DataSource;
69
67
  /**
70
68
  * Create a track from a session config using the registry.
71
69
  *
@@ -75,7 +73,6 @@ export declare function createDataSource(config: DataSourceConfig, workerProvide
75
73
  */
76
74
  export declare function createTrackFromConfig(trackConfig: TrackSessionConfig, locus: Locus, options?: {
77
75
  canvasProvider?: CanvasProvider;
78
- workerProvider?: WorkerProvider;
79
76
  theme?: Partial<RenderTheme>;
80
77
  sequenceProvider?: SequenceProvider;
81
78
  }): CreatedTrack;
@@ -8,10 +8,13 @@
8
8
  * intron lines, strand arrows, labels, and per-feature colors.
9
9
  */
10
10
  import type { AnnotationFeature, AnnotationRenderConfig, RenderContext } from '../../types';
11
+ import type { TrackNameLabelOptions } from '../trackLabel';
11
12
  /**
12
13
  * Render a set of annotation features onto a canvas context.
13
14
  *
14
15
  * Features should already have `.row` assigned (via `pack()`).
15
16
  * The canvas should be sized and cleared before calling this.
16
17
  */
17
- export declare function renderAnnotationTrack(ctx: CanvasRenderingContext2D, features: AnnotationFeature[], config: AnnotationRenderConfig, rc: RenderContext): void;
18
+ export declare function renderAnnotationTrack(ctx: CanvasRenderingContext2D, features: AnnotationFeature[], config: AnnotationRenderConfig, rc: RenderContext,
19
+ /** Optional track name label overlay (top-left corner). */
20
+ trackLabel?: TrackNameLabelOptions): void;
@@ -10,9 +10,8 @@
10
10
  * const track = new AnnotationTrackCanvas(canvas, { locus, features })
11
11
  * track.attachTo(containerDiv)
12
12
  */
13
- import type { AnnotationFeature, AnnotationRenderConfig, Locus, RenderContext, AnnotationTrackSessionConfig, HitTestResult, AxisInfo, ContextMenuItem } from '../../types';
13
+ import type { AnnotationFeature, AnnotationRenderConfig, Locus, RenderContext, AnnotationTrackSessionConfig, HitTestResult, AxisInfo, ContextMenuItem, FeatureRect } from '../../types';
14
14
  import type { CanvasProvider } from '../../canvasProvider';
15
- import type { WorkerProvider } from '../../workerProvider';
16
15
  import type { RenderTheme } from '../../themes/renderTheme';
17
16
  import { BaseTrackCanvas } from '../baseTrackCanvas';
18
17
  export type { Locus } from '../../types';
@@ -29,8 +28,6 @@ export interface AnnotationTrackCanvasOptions {
29
28
  background?: string;
30
29
  /** Canvas provider for environment abstraction. Default: DOMCanvasProvider. */
31
30
  canvasProvider?: CanvasProvider;
32
- /** Worker provider for offloading CPU-intensive tasks (packing). */
33
- workerProvider?: WorkerProvider;
34
31
  /** Track name for axis label. */
35
32
  name?: string;
36
33
  }
@@ -39,21 +36,27 @@ export declare class AnnotationTrackCanvas extends BaseTrackCanvas<AnnotationRen
39
36
  private fixedHeight;
40
37
  private background;
41
38
  private _name;
42
- private workerProvider?;
39
+ /** User-set config overrides, re-applied on theme change. */
40
+ private _userOverrides;
41
+ private _userBackground;
43
42
  /** Most recently packed features, available after render(). */
44
43
  private packedFeatures;
45
44
  /** Whether packedFeatures was pre-computed by async worker (skip sync pack in computeHeight). */
46
45
  private packedReady;
47
46
  readonly type = "annotation";
48
47
  constructor(canvas: HTMLCanvasElement, options: AnnotationTrackCanvasOptions);
49
- /** Update features and re-render. Dispatches async pack when workerProvider is set. */
48
+ /** Set or clear the fixed pixel height. When set, overrides auto-computed row-based height. */
49
+ setFixedHeight(height: number | undefined): void;
50
+ /** Update features and re-render. */
50
51
  setFeatures(features: AnnotationFeature[]): void;
51
52
  protected computeHeight(_width: number): number;
52
53
  protected getBackground(): string;
53
54
  protected doRender(ctx: CanvasRenderingContext2D, _width: number, _height: number, rc: RenderContext): void;
54
55
  getAxisInfo(): AxisInfo | undefined;
55
56
  getContextMenuItems(_x: number, _y: number): ContextMenuItem[];
57
+ getFeatureRects(): FeatureRect[];
56
58
  hitTest(x: number, y: number): HitTestResult<AnnotationFeature>[];
59
+ setConfig(config: Partial<AnnotationRenderConfig>): void;
57
60
  setTheme(theme: RenderTheme): void;
58
61
  serializeConfig(theme: RenderTheme): AnnotationTrackSessionConfig;
59
62
  }
@@ -4,16 +4,10 @@
4
4
  * These are pure canvas renderers — they take a 2D context, axis info, and
5
5
  * dimensions, and paint the axis. No DOM, no state, no side effects.
6
6
  *
7
- * Two variants:
8
- * - renderQuantitativeAxis: tick marks + data range labels for numeric tracks (wig)
9
- * - renderLabelAxis: centered rotated text label for annotation tracks (gene)
7
+ * renderQuantitativeAxis: background, color strip, track label, and
8
+ * tick marks + data range labels (when data is available) for numeric tracks.
10
9
  */
11
10
  import type { AxisInfo } from '../../types';
12
11
  /** Format a number for axis labels (ported from igv.js paintAxis.ts). */
13
12
  export declare function prettyPrintNumber(n: number): string;
14
13
  export declare function renderQuantitativeAxis(ctx: CanvasRenderingContext2D, info: AxisInfo, width: number, height: number): void;
15
- /**
16
- * Paint a label-only axis (e.g., gene track name).
17
- * Renders a vertically-rotated centered text label.
18
- */
19
- export declare function renderLabelAxis(ctx: CanvasRenderingContext2D, info: AxisInfo, width: number, height: number): void;
@@ -1 +1 @@
1
- export { renderQuantitativeAxis, renderLabelAxis, prettyPrintNumber } from './axisRenderer';
1
+ export { renderQuantitativeAxis, prettyPrintNumber } from './axisRenderer';