loom-browser 0.0.7 → 0.0.8

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.
@@ -269,6 +269,8 @@ export declare class HeadlessGenomeBrowser {
269
269
  private inflightFetches;
270
270
  /** Timer for debouncing data loads during rapid zoom/pan. */
271
271
  private loadDebounceTimer;
272
+ /** Set to true by dispose() to suppress post-dispose promise handlers. */
273
+ private _disposed;
272
274
  /** When true, sortTracks() is a no-op. Used for batch track additions (e.g. loadSession). */
273
275
  private _deferSort;
274
276
  /** Canvas provider for environment abstraction. Available for convenience API / future use. */
@@ -420,6 +422,8 @@ export declare class HeadlessGenomeBrowser {
420
422
  removeROI(roiId: string): boolean;
421
423
  /** Update an ROI by ID. Returns the updated ROI, or undefined if not found. */
422
424
  updateROI(roiId: string, changes: Partial<Omit<ROI, 'id'>>): ROI | undefined;
425
+ /** Remove a specific ROI set by instance. Returns true if found and removed. */
426
+ removeROISet(set: ROISet): boolean;
423
427
  /** Remove all ROI sets. */
424
428
  clearROIs(): void;
425
429
  /** Get all ROIs across all sets (flattened). */
@@ -81,6 +81,7 @@ export interface LoomBrowserHandle {
81
81
  reloadData(): void;
82
82
  addROI(roi: ROI, setName?: string): ROI;
83
83
  addROISet(config: ROISetConfig): ROISet;
84
+ removeROISet(set: ROISet): boolean;
84
85
  removeROI(roiId: string): boolean;
85
86
  updateROI(roiId: string, changes: Partial<Omit<ROI, 'id'>>): ROI | undefined;
86
87
  clearROIs(): void;
@@ -0,0 +1,14 @@
1
+ import type { ROI } from '../types';
2
+ export interface ROISetProps {
3
+ /** ROI features to display. The set is recreated when this array changes. */
4
+ rois: ROI[];
5
+ /** Name for the ROI set. Default: 'Declarative'. */
6
+ name?: string;
7
+ /** Default color for ROIs in this set (individual ROI colors take precedence). */
8
+ color?: string;
9
+ }
10
+ /**
11
+ * Declarative ROI set component. Renders nothing — manages ROIs on the
12
+ * GenomeBrowser via context. Add/remove `<ROISet>` children to control ROIs.
13
+ */
14
+ export declare function DeclarativeROISet({ rois, name, color }: ROISetProps): null;
@@ -1,3 +1,4 @@
1
1
  export { useGenomeBrowser } from './useGenomeBrowser';
2
2
  export { useBrowserEvent } from './useBrowserEvent';
3
3
  export { useLocus } from './useLocus';
4
+ export type { TrackClickEvent, TrackEventHandlers } from './useTrackManager';
@@ -1,5 +1,16 @@
1
1
  import type { Track } from '../../types';
2
2
  import type { GenomeBrowser } from '../../genomeBrowser';
3
+ /** Per-track click event with typed features. */
4
+ export interface TrackClickEvent<F> {
5
+ features: F[];
6
+ genomicLocation: number;
7
+ x: number;
8
+ y: number;
9
+ }
10
+ export interface TrackEventHandlers<F> {
11
+ onClick?: (event: TrackClickEvent<F>) => void;
12
+ onContextMenu?: (event: TrackClickEvent<F>) => void;
13
+ }
3
14
  /**
4
15
  * Internal hook that manages track add/remove/update lifecycle.
5
16
  *
@@ -7,5 +18,6 @@ import type { GenomeBrowser } from '../../genomeBrowser';
7
18
  * @param recreationDeps When these change, the track is removed and re-added (new data source).
8
19
  * @param updateTrack Called when only updateDeps change (in-place config update).
9
20
  * @param updateDeps When these change (but recreationDeps don't), updateTrack is called.
21
+ * @param eventHandlers Optional typed click/context-menu handlers scoped to this track.
10
22
  */
11
- export declare function useTrackManager<T extends Track>(addTrack: (browser: GenomeBrowser) => T, recreationDeps: unknown[], updateTrack?: (track: T, browser: GenomeBrowser) => void, updateDeps?: unknown[]): T | null;
23
+ export declare function useTrackManager<T extends Track, F = unknown>(addTrack: (browser: GenomeBrowser) => T, recreationDeps: unknown[], updateTrack?: (track: T, browser: GenomeBrowser) => void, updateDeps?: unknown[], eventHandlers?: TrackEventHandlers<F>): T | null;
@@ -1,8 +1,11 @@
1
1
  export { LoomBrowser } from './LoomBrowser';
2
2
  export type { LoomBrowserProps, LoomBrowserHandle } from './LoomBrowser';
3
3
  export { useGenomeBrowser, useBrowserEvent, useLocus } from './hooks';
4
+ export type { TrackClickEvent } from './hooks';
4
5
  export { RulerTrack, WigTrack, GeneTrack, BedTrack, SequenceTrack, InteractionTrack, GtxTrack, } from './tracks';
5
6
  export type { RulerTrackProps, WigTrackProps, GeneTrackProps, BedTrackProps, SequenceTrackProps, InteractionTrackProps, GtxTrackProps, } from './tracks';
7
+ export { DeclarativeROISet as ROISet } from './ROISet';
8
+ export type { ROISetProps } from './ROISet';
6
9
  export { ChromosomeSelect, LocusInput, ZoomControls, WindowSize, ExportControls, Navbar, } from './ui';
7
10
  export type { ChromosomeSelectProps, LocusInputProps, ZoomControlsProps, WindowSizeProps, ExportControlsProps, NavbarProps, } from './ui';
8
11
  export { GenomeBrowserContext } from './GenomeBrowserContext';
@@ -1,11 +1,13 @@
1
1
  import type { AnnotationFeature, AnnotationRenderConfig, TextFileFormat } from '../../types';
2
+ import type { TrackClickEvent } from '../hooks/useTrackManager';
3
+ type BedFeature = AnnotationFeature & {
4
+ chr: string;
5
+ };
2
6
  export interface BedTrackProps {
3
7
  /** URL to a BED/peak file. Mutually exclusive with `features`. */
4
8
  url?: string;
5
9
  /** In-memory annotation features. Mutually exclusive with `url`. Features must include `chr`. */
6
- features?: (AnnotationFeature & {
7
- chr: string;
8
- })[];
10
+ features?: BedFeature[];
9
11
  config?: Partial<AnnotationRenderConfig>;
10
12
  height?: number;
11
13
  background?: string;
@@ -15,5 +17,12 @@ export interface BedTrackProps {
15
17
  maxTrackHeight?: number;
16
18
  name?: string;
17
19
  metadata?: Record<string, string>;
20
+ /** Compute per-feature color. Applied to in-memory features before rendering. */
21
+ colorBy?: (feature: BedFeature) => string;
22
+ /** Called when this track is clicked. Features are typed as BedFeature. */
23
+ onClick?: (event: TrackClickEvent<BedFeature>) => void;
24
+ /** Called when this track is right-clicked. */
25
+ onContextMenu?: (event: TrackClickEvent<BedFeature>) => void;
18
26
  }
19
- export declare function BedTrack({ url, features, config, height, background, format, indexURL, indexed, maxTrackHeight, name, metadata }: BedTrackProps): null;
27
+ export declare function BedTrack({ url, features, config, height, background, format, indexURL, indexed, maxTrackHeight, name, metadata, colorBy, onClick, onContextMenu }: BedTrackProps): null;
28
+ export {};
@@ -1,4 +1,5 @@
1
- import type { AnnotationRenderConfig } from '../../types';
1
+ import type { AnnotationFeature, AnnotationRenderConfig } from '../../types';
2
+ import type { TrackClickEvent } from '../hooks/useTrackManager';
2
3
  export interface GeneTrackProps {
3
4
  config?: Partial<AnnotationRenderConfig>;
4
5
  height?: number;
@@ -10,5 +11,9 @@ export interface GeneTrackProps {
10
11
  maxTrackHeight?: number;
11
12
  name?: string;
12
13
  metadata?: Record<string, string>;
14
+ /** Called when this track is clicked. Features are typed as AnnotationFeature. */
15
+ onClick?: (event: TrackClickEvent<AnnotationFeature>) => void;
16
+ /** Called when this track is right-clicked. */
17
+ onContextMenu?: (event: TrackClickEvent<AnnotationFeature>) => void;
13
18
  }
14
- export declare function GeneTrack({ config, height, background, genome, track, maxTrackHeight, name, metadata }: GeneTrackProps): null;
19
+ export declare function GeneTrack({ config, height, background, genome, track, maxTrackHeight, name, metadata, onClick, onContextMenu }: GeneTrackProps): null;
@@ -1,4 +1,5 @@
1
- import type { WigRenderConfig, WindowFunction } from '../../types';
1
+ import type { WigFeature, WigRenderConfig, WindowFunction } from '../../types';
2
+ import type { TrackClickEvent } from '../hooks/useTrackManager';
2
3
  export interface GtxTrackProps {
3
4
  url: string;
4
5
  experimentId: string;
@@ -9,5 +10,9 @@ export interface GtxTrackProps {
9
10
  maxTrackHeight?: number;
10
11
  name?: string;
11
12
  metadata?: Record<string, string>;
13
+ /** Called when this track is clicked. Features are typed as WigFeature. */
14
+ onClick?: (event: TrackClickEvent<WigFeature>) => void;
15
+ /** Called when this track is right-clicked. */
16
+ onContextMenu?: (event: TrackClickEvent<WigFeature>) => void;
12
17
  }
13
- export declare function GtxTrack({ url, experimentId, config, height, background, windowFunction, maxTrackHeight, name, metadata }: GtxTrackProps): null;
18
+ export declare function GtxTrack({ url, experimentId, config, height, background, windowFunction, maxTrackHeight, name, metadata, onClick, onContextMenu }: GtxTrackProps): null;
@@ -1,4 +1,5 @@
1
1
  import type { InteractionRenderConfig, TextFileFormat } from '../../types';
2
+ import type { TrackClickEvent } from '../hooks/useTrackManager';
2
3
  export interface InteractionTrackProps {
3
4
  url: string;
4
5
  config?: Partial<InteractionRenderConfig>;
@@ -8,5 +9,9 @@ export interface InteractionTrackProps {
8
9
  indexed?: boolean;
9
10
  name?: string;
10
11
  metadata?: Record<string, string>;
12
+ /** Called when this track is clicked. */
13
+ onClick?: (event: TrackClickEvent<unknown>) => void;
14
+ /** Called when this track is right-clicked. */
15
+ onContextMenu?: (event: TrackClickEvent<unknown>) => void;
11
16
  }
12
- export declare function InteractionTrack({ url, config, background, format, indexURL, indexed, name, metadata }: InteractionTrackProps): null;
17
+ export declare function InteractionTrack({ url, config, background, format, indexURL, indexed, name, metadata, onClick, onContextMenu }: InteractionTrackProps): null;
@@ -1,4 +1,5 @@
1
1
  import type { WigFeature, WigRenderConfig, WindowFunction } from '../../types';
2
+ import type { TrackClickEvent } from '../hooks/useTrackManager';
2
3
  export interface WigTrackProps {
3
4
  /** URL to a BigWig file. Mutually exclusive with `features`. */
4
5
  url?: string;
@@ -11,5 +12,9 @@ export interface WigTrackProps {
11
12
  maxTrackHeight?: number;
12
13
  name?: string;
13
14
  metadata?: Record<string, string>;
15
+ /** Called when this track is clicked. Features are typed as WigFeature. */
16
+ onClick?: (event: TrackClickEvent<WigFeature>) => void;
17
+ /** Called when this track is right-clicked. */
18
+ onContextMenu?: (event: TrackClickEvent<WigFeature>) => void;
14
19
  }
15
- export declare function WigTrack({ url, features, config, height, background, windowFunction, maxTrackHeight, name, metadata }: WigTrackProps): null;
20
+ export declare function WigTrack({ url, features, config, height, background, windowFunction, maxTrackHeight, name, metadata, onClick, onContextMenu }: WigTrackProps): null;
@@ -51,6 +51,7 @@ export declare class AnnotationTrackCanvas extends BaseTrackCanvas<AnnotationRen
51
51
  setFeatures(features: AnnotationFeature[]): void;
52
52
  protected computeHeight(_width: number): number;
53
53
  protected getBackground(): string;
54
+ protected renderLabelOverlay(ctx: CanvasRenderingContext2D, _width: number, height: number): void;
54
55
  protected doRender(ctx: CanvasRenderingContext2D, _width: number, _height: number, rc: RenderContext): void;
55
56
  getAxisInfo(): AxisInfo | undefined;
56
57
  getContextMenuItems(_x: number, _y: number): ContextMenuItem[];
@@ -93,6 +93,12 @@ export declare abstract class BaseTrackCanvas<TConfig> implements Track {
93
93
  * Mirrors igv.js TrackViewport.createZoomInNotice (js/trackViewport.ts).
94
94
  */
95
95
  protected renderZoomInNotice(ctx: CanvasRenderingContext2D, width: number, height: number): void;
96
+ /**
97
+ * Render the track name label overlay. Called after error/zoom-in notices
98
+ * so labels remain visible even when the track can't render data.
99
+ * No-op by default — subclasses with name labels should override.
100
+ */
101
+ protected renderLabelOverlay(_ctx: CanvasRenderingContext2D, _width: number, _height: number): void;
96
102
  /**
97
103
  * Render this track onto an arbitrary context (e.g. Canvas2SVG for SVG export).
98
104
  * Skips DPR scaling and canvas-element lifecycle — draws directly at the given
@@ -37,6 +37,7 @@ export declare class InteractionTrackCanvas extends BaseTrackCanvas<InteractionR
37
37
  setFeatures(features: InteractionFeature[]): void;
38
38
  protected computeHeight(_width: number): number;
39
39
  protected getBackground(): string;
40
+ protected renderLabelOverlay(ctx: CanvasRenderingContext2D, _width: number, height: number): void;
40
41
  protected doRender(ctx: CanvasRenderingContext2D, _width: number, _height: number, rc: RenderContext): void;
41
42
  /** Hit-test: find features at canvas-relative pixel coordinates. */
42
43
  hitTest(x: number, y: number): HitTestResult<InteractionFeature>[];
@@ -71,6 +71,7 @@ export declare class WigTrackCanvas extends BaseTrackCanvas<WigRenderConfig> {
71
71
  private augmentWithSequence;
72
72
  protected computeHeight(_width: number): number;
73
73
  protected getBackground(): string;
74
+ protected renderLabelOverlay(ctx: CanvasRenderingContext2D, _width: number, height: number): void;
74
75
  protected doRender(ctx: CanvasRenderingContext2D, _width: number, height: number, rc: RenderContext): void;
75
76
  getAxisInfo(): AxisInfo | undefined;
76
77
  getContextMenuItems(_x: number, _y: number): ContextMenuItem[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loom-browser",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "main": "dist/loom.esm.js",
5
5
  "module": "dist/loom.esm.js",
6
6
  "types": "dist/types/index.d.ts",