loom-browser 0.0.5 → 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.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 };
@@ -14993,6 +15121,7 @@ tr.border-top td {
14993
15121
  exports.LoomWindowSize = LoomWindowSize;
14994
15122
  exports.LoomZoomControls = LoomZoomControls;
14995
15123
  exports.MainThreadProvider = MainThreadProvider;
15124
+ exports.MemoryDataSource = MemoryDataSource;
14996
15125
  exports.NodeWorkerProvider = NodeWorkerProvider;
14997
15126
  exports.READY_STATE_OPEN = READY_STATE_OPEN;
14998
15127
  exports.ROISet = ROISet;