loom-browser 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/loom-react.esm.js +957 -9
- package/dist/loom-react.esm.min.js +1 -1
- package/dist/loom-react.esm.min.js.map +1 -1
- package/dist/loom.esm.js +138 -2
- package/dist/loom.esm.min.js +1 -1
- package/dist/loom.esm.min.js.map +1 -1
- package/dist/loom.js +138 -1
- package/dist/loom.min.js +1 -1
- package/dist/loom.min.js.map +1 -1
- package/dist/tsconfig.src.tsbuildinfo +1 -1
- package/dist/types/dataSources/memoryDataSource.d.ts +32 -0
- package/dist/types/headlessGenomeBrowser.d.ts +33 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/react/GenomeBrowserContext.d.ts +3 -0
- package/dist/types/react/index.d.ts +2 -0
- package/dist/types/react/tracks/BedTrack.d.ts +8 -3
- package/dist/types/react/tracks/WigTrack.d.ts +6 -3
- package/dist/types/react/ui/ChromosomeSelect.d.ts +7 -0
- package/dist/types/react/ui/ExportControls.d.ts +7 -0
- package/dist/types/react/ui/LocusInput.d.ts +7 -0
- package/dist/types/react/ui/Navbar.d.ts +10 -0
- package/dist/types/react/ui/WindowSize.d.ts +7 -0
- package/dist/types/react/ui/ZoomControls.d.ts +7 -0
- package/dist/types/react/ui/ensureRegistered.d.ts +5 -0
- package/dist/types/react/ui/index.d.ts +12 -0
- package/dist/types/react/ui/types.d.ts +24 -0
- package/dist/types/types.d.ts +4 -1
- package/package.json +1 -1
package/dist/loom.js
CHANGED
|
@@ -9102,6 +9102,72 @@
|
|
|
9102
9102
|
}
|
|
9103
9103
|
}
|
|
9104
9104
|
|
|
9105
|
+
/**
|
|
9106
|
+
* DataSource backed by an in-memory feature array.
|
|
9107
|
+
*
|
|
9108
|
+
* Wraps a pre-loaded feature array in a FeatureCache for spatial queries,
|
|
9109
|
+
* enabling inline features to flow through the same data lifecycle as
|
|
9110
|
+
* URL-based data sources.
|
|
9111
|
+
*
|
|
9112
|
+
* Layer 1 (Data + Layout): no DOM, no canvas.
|
|
9113
|
+
*/
|
|
9114
|
+
/**
|
|
9115
|
+
* DataSource that serves features from an in-memory array.
|
|
9116
|
+
*
|
|
9117
|
+
* Features are indexed in a FeatureCache on construction for efficient
|
|
9118
|
+
* spatial queries. Calling `setFeatures()` replaces the cache entirely.
|
|
9119
|
+
*/
|
|
9120
|
+
class MemoryDataSource {
|
|
9121
|
+
constructor(features) {
|
|
9122
|
+
this.cache = new FeatureCache(features);
|
|
9123
|
+
}
|
|
9124
|
+
/** Replace the in-memory features and rebuild the spatial index. */
|
|
9125
|
+
setFeatures(features) {
|
|
9126
|
+
this.cache = new FeatureCache(features);
|
|
9127
|
+
}
|
|
9128
|
+
/** Set a chromosome name resolver for alias resolution. */
|
|
9129
|
+
setChromNameResolver(resolver) {
|
|
9130
|
+
this._resolveChromName = resolver;
|
|
9131
|
+
}
|
|
9132
|
+
/** Set cumulative offsets for whole genome view coordinate transformation. */
|
|
9133
|
+
setCumulativeOffsets(offsets) {
|
|
9134
|
+
this._cumulativeOffsets = offsets;
|
|
9135
|
+
}
|
|
9136
|
+
async fetch(locus, _bpPerPixel, _signal) {
|
|
9137
|
+
if (isWholeGenomeView(locus) && this._cumulativeOffsets) {
|
|
9138
|
+
return this.fetchWG();
|
|
9139
|
+
}
|
|
9140
|
+
const chr = this._resolveChromName
|
|
9141
|
+
? this._resolveChromName(locus.chr)
|
|
9142
|
+
: locus.chr;
|
|
9143
|
+
return this.cache.queryFeatures(chr, locus.start, locus.end);
|
|
9144
|
+
}
|
|
9145
|
+
fetchWG() {
|
|
9146
|
+
const offsets = this._cumulativeOffsets;
|
|
9147
|
+
const chrNames = mainChromosomeNames(Object.fromEntries(offsets.chromosomeNames.map(name => { var _a; return [name, (_a = offsets.offsets[name]) !== null && _a !== void 0 ? _a : 0]; })));
|
|
9148
|
+
const wgFeatures = [];
|
|
9149
|
+
const allByChrom = this.cache.getAllFeatures();
|
|
9150
|
+
for (const chr of chrNames) {
|
|
9151
|
+
const features = allByChrom[chr];
|
|
9152
|
+
if (!features)
|
|
9153
|
+
continue;
|
|
9154
|
+
const offset = offsets.offsets[chr];
|
|
9155
|
+
if (offset === undefined)
|
|
9156
|
+
continue;
|
|
9157
|
+
for (const f of features) {
|
|
9158
|
+
wgFeatures.push({
|
|
9159
|
+
...f,
|
|
9160
|
+
chr: 'all',
|
|
9161
|
+
start: offset + f.start,
|
|
9162
|
+
end: offset + f.end,
|
|
9163
|
+
});
|
|
9164
|
+
}
|
|
9165
|
+
}
|
|
9166
|
+
wgFeatures.sort((a, b) => a.start - b.start);
|
|
9167
|
+
return wgFeatures;
|
|
9168
|
+
}
|
|
9169
|
+
}
|
|
9170
|
+
|
|
9105
9171
|
/**
|
|
9106
9172
|
* Stateless renderer for interaction (arc/BEDPE) tracks.
|
|
9107
9173
|
*
|
|
@@ -9672,6 +9738,11 @@
|
|
|
9672
9738
|
indexed: config.indexed,
|
|
9673
9739
|
workerProvider,
|
|
9674
9740
|
});
|
|
9741
|
+
case 'memory':
|
|
9742
|
+
// Memory data sources are created directly with features by the caller.
|
|
9743
|
+
// This path is only hit during session restore, where in-memory features
|
|
9744
|
+
// are not available — return an empty MemoryDataSource as a placeholder.
|
|
9745
|
+
return new MemoryDataSource([]);
|
|
9675
9746
|
}
|
|
9676
9747
|
}
|
|
9677
9748
|
// ─── Built-in track creators ─────────────────────────────────────────────────
|
|
@@ -10123,6 +10194,9 @@
|
|
|
10123
10194
|
return `ucsc:${(_b = config.genome) !== null && _b !== void 0 ? _b : ''}:${(_c = config.track) !== null && _c !== void 0 ? _c : ''}`;
|
|
10124
10195
|
case 'text':
|
|
10125
10196
|
return `text:${config.url}:${(_d = config.format) !== null && _d !== void 0 ? _d : ''}:${(_e = config.indexURL) !== null && _e !== void 0 ? _e : ''}`;
|
|
10197
|
+
case 'memory':
|
|
10198
|
+
// Each memory data source is unique — no deduplication.
|
|
10199
|
+
return `memory:${Math.random()}`;
|
|
10126
10200
|
}
|
|
10127
10201
|
}
|
|
10128
10202
|
|
|
@@ -11233,6 +11307,60 @@
|
|
|
11233
11307
|
this.managedTracks[this.managedTracks.length - 1].metadata = options.metadata;
|
|
11234
11308
|
return track;
|
|
11235
11309
|
}
|
|
11310
|
+
/** Add a BigWig-style signal track backed by in-memory features (no URL required). */
|
|
11311
|
+
addWigTrackWithFeatures(features, options) {
|
|
11312
|
+
const { canvas } = this.canvasProvider.createCanvas(0, 0);
|
|
11313
|
+
const track = new WigTrackCanvas(canvas, {
|
|
11314
|
+
locus: this._locus,
|
|
11315
|
+
features: [],
|
|
11316
|
+
config: options === null || options === void 0 ? void 0 : options.config,
|
|
11317
|
+
height: options === null || options === void 0 ? void 0 : options.height,
|
|
11318
|
+
background: options === null || options === void 0 ? void 0 : options.background,
|
|
11319
|
+
theme: this.theme,
|
|
11320
|
+
canvasProvider: this.canvasProvider,
|
|
11321
|
+
name: options === null || options === void 0 ? void 0 : options.name,
|
|
11322
|
+
sequenceProvider: this.sequenceProvider,
|
|
11323
|
+
});
|
|
11324
|
+
const dataSource = new MemoryDataSource(features);
|
|
11325
|
+
if (this.cumulativeOffsets) {
|
|
11326
|
+
dataSource.setCumulativeOffsets(this.cumulativeOffsets);
|
|
11327
|
+
}
|
|
11328
|
+
if (this.genome) {
|
|
11329
|
+
dataSource.setChromNameResolver(alias => this.genome.getChromosomeName(alias));
|
|
11330
|
+
}
|
|
11331
|
+
const dataSourceConfig = { type: 'memory' };
|
|
11332
|
+
this.addTrack(track, dataSource, dataSourceConfig, options === null || options === void 0 ? void 0 : options.maxTrackHeight);
|
|
11333
|
+
if (options === null || options === void 0 ? void 0 : options.metadata)
|
|
11334
|
+
this.managedTracks[this.managedTracks.length - 1].metadata = options.metadata;
|
|
11335
|
+
return track;
|
|
11336
|
+
}
|
|
11337
|
+
/** Add a BED/annotation track backed by in-memory features (no URL required). Features must include `chr`. */
|
|
11338
|
+
addBedTrackWithFeatures(features, options) {
|
|
11339
|
+
const { canvas } = this.canvasProvider.createCanvas(0, 0);
|
|
11340
|
+
const track = new AnnotationTrackCanvas(canvas, {
|
|
11341
|
+
locus: this._locus,
|
|
11342
|
+
features: [],
|
|
11343
|
+
config: options === null || options === void 0 ? void 0 : options.config,
|
|
11344
|
+
height: options === null || options === void 0 ? void 0 : options.height,
|
|
11345
|
+
background: options === null || options === void 0 ? void 0 : options.background,
|
|
11346
|
+
theme: this.theme,
|
|
11347
|
+
canvasProvider: this.canvasProvider,
|
|
11348
|
+
workerProvider: this.workerProvider,
|
|
11349
|
+
name: options === null || options === void 0 ? void 0 : options.name,
|
|
11350
|
+
});
|
|
11351
|
+
const dataSource = new MemoryDataSource(features);
|
|
11352
|
+
if (this.cumulativeOffsets) {
|
|
11353
|
+
dataSource.setCumulativeOffsets(this.cumulativeOffsets);
|
|
11354
|
+
}
|
|
11355
|
+
if (this.genome) {
|
|
11356
|
+
dataSource.setChromNameResolver(alias => this.genome.getChromosomeName(alias));
|
|
11357
|
+
}
|
|
11358
|
+
const dataSourceConfig = { type: 'memory' };
|
|
11359
|
+
this.addTrack(track, dataSource, dataSourceConfig, options === null || options === void 0 ? void 0 : options.maxTrackHeight);
|
|
11360
|
+
if (options === null || options === void 0 ? void 0 : options.metadata)
|
|
11361
|
+
this.managedTracks[this.managedTracks.length - 1].metadata = options.metadata;
|
|
11362
|
+
return track;
|
|
11363
|
+
}
|
|
11236
11364
|
/** Add a DNA/RNA sequence track. Data fetching is handled automatically via the genome's sequence provider. */
|
|
11237
11365
|
addSequenceTrack(options) {
|
|
11238
11366
|
const trackConfig = { type: 'sequence', config: options === null || options === void 0 ? void 0 : options.config };
|
|
@@ -12102,6 +12230,13 @@
|
|
|
12102
12230
|
this.events.on(BrowserEvent.DataLoaded, ({ track }) => {
|
|
12103
12231
|
this.updateAxisContent(track);
|
|
12104
12232
|
});
|
|
12233
|
+
// Repaint axis canvases when theme changes (track canvases update via
|
|
12234
|
+
// track.setTheme(), but axis sidebar is managed here in GenomeBrowser).
|
|
12235
|
+
this.events.on(BrowserEvent.ThemeChanged, () => {
|
|
12236
|
+
for (const mt of this.managedTracks) {
|
|
12237
|
+
this.updateAxisContent(mt.track);
|
|
12238
|
+
}
|
|
12239
|
+
});
|
|
12105
12240
|
// Re-render ROI overlays when ROIs change or viewport moves
|
|
12106
12241
|
this.events.on(BrowserEvent.ROIAdded, () => this.renderROIOverlays());
|
|
12107
12242
|
this.events.on(BrowserEvent.ROIRemoved, () => this.renderROIOverlays());
|
|
@@ -12304,9 +12439,10 @@
|
|
|
12304
12439
|
const { axisDiv } = entry;
|
|
12305
12440
|
const rawInfo = (_a = track.getAxisInfo) === null || _a === void 0 ? void 0 : _a.call(track);
|
|
12306
12441
|
if (!rawInfo) {
|
|
12307
|
-
// No axis info —
|
|
12442
|
+
// No axis info — keep the column for alignment but clear content
|
|
12308
12443
|
axisDiv.innerHTML = "";
|
|
12309
12444
|
axisDiv.style.borderRight = "none";
|
|
12445
|
+
axisDiv.style.backgroundColor = this.theme.palette.background;
|
|
12310
12446
|
entry.axisCanvas = null;
|
|
12311
12447
|
return;
|
|
12312
12448
|
}
|
|
@@ -14985,6 +15121,7 @@ tr.border-top td {
|
|
|
14985
15121
|
exports.LoomWindowSize = LoomWindowSize;
|
|
14986
15122
|
exports.LoomZoomControls = LoomZoomControls;
|
|
14987
15123
|
exports.MainThreadProvider = MainThreadProvider;
|
|
15124
|
+
exports.MemoryDataSource = MemoryDataSource;
|
|
14988
15125
|
exports.NodeWorkerProvider = NodeWorkerProvider;
|
|
14989
15126
|
exports.READY_STATE_OPEN = READY_STATE_OPEN;
|
|
14990
15127
|
exports.ROISet = ROISet;
|