@genome-spy/core 0.71.0 → 0.73.0
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/LICENSE +1 -1
- package/dist/bundle/index.es.js +6842 -5365
- package/dist/bundle/index.js +159 -140
- package/dist/bundle/parquetRead-BnAGCa4_.js +1663 -0
- package/dist/schema.json +281 -17
- package/dist/src/data/formats/bed.d.ts +8 -0
- package/dist/src/data/formats/bed.d.ts.map +1 -0
- package/dist/src/data/formats/bed.js +53 -0
- package/dist/src/data/formats/bedpe.d.ts +8 -0
- package/dist/src/data/formats/bedpe.d.ts.map +1 -0
- package/dist/src/data/formats/bedpe.js +160 -0
- package/dist/src/data/formats/parquet.d.ts +12 -0
- package/dist/src/data/formats/parquet.d.ts.map +1 -0
- package/dist/src/data/formats/parquet.js +29 -0
- package/dist/src/data/formats/parquetRead.d.ts +18 -0
- package/dist/src/data/formats/parquetRead.d.ts.map +1 -0
- package/dist/src/data/formats/parquetRead.js +326 -0
- package/dist/src/data/sources/dataUtils.d.ts +16 -0
- package/dist/src/data/sources/dataUtils.d.ts.map +1 -1
- package/dist/src/data/sources/dataUtils.js +53 -3
- package/dist/src/data/sources/urlSource.d.ts +4 -0
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +141 -17
- package/dist/src/encoder/encoder.d.ts +2 -2
- package/dist/src/fonts/bmFontManager.d.ts +1 -1
- package/dist/src/genome/assemblyPreflight.d.ts +31 -0
- package/dist/src/genome/assemblyPreflight.d.ts.map +1 -0
- package/dist/src/genome/assemblyPreflight.js +99 -0
- package/dist/src/genome/genome.d.ts +2 -2
- package/dist/src/genome/genome.d.ts.map +1 -1
- package/dist/src/genome/genome.js +4 -0
- package/dist/src/genome/genomeStore.d.ts +34 -3
- package/dist/src/genome/genomeStore.d.ts.map +1 -1
- package/dist/src/genome/genomeStore.js +409 -18
- package/dist/src/genome/rootGenomeConfig.d.ts +26 -0
- package/dist/src/genome/rootGenomeConfig.d.ts.map +1 -0
- package/dist/src/genome/rootGenomeConfig.js +94 -0
- package/dist/src/genomeSpy/interactionController.d.ts +5 -1
- package/dist/src/genomeSpy/interactionController.d.ts.map +1 -1
- package/dist/src/genomeSpy/interactionController.js +244 -29
- package/dist/src/genomeSpy/renderCoordinator.js +1 -1
- package/dist/src/genomeSpy.d.ts +13 -3
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +83 -7
- package/dist/src/gl/canvasSizeHelper.d.ts +74 -0
- package/dist/src/gl/canvasSizeHelper.d.ts.map +1 -0
- package/dist/src/gl/canvasSizeHelper.js +203 -0
- package/dist/src/gl/hashTable.d.ts +78 -0
- package/dist/src/gl/hashTable.d.ts.map +1 -0
- package/dist/src/gl/hashTable.js +164 -0
- package/dist/src/gl/includes/common.glsl.js +1 -1
- package/dist/src/gl/webGLHelper.d.ts +25 -11
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +71 -39
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -2
- package/dist/src/marks/link.d.ts.map +1 -1
- package/dist/src/marks/link.js +5 -3
- package/dist/src/marks/mark.d.ts +1 -1
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +8 -4
- package/dist/src/scales/domainPlanner.d.ts +34 -3
- package/dist/src/scales/domainPlanner.d.ts.map +1 -1
- package/dist/src/scales/domainPlanner.js +247 -26
- package/dist/src/scales/scaleInstanceManager.d.ts +2 -1
- package/dist/src/scales/scaleInstanceManager.d.ts.map +1 -1
- package/dist/src/scales/scaleInstanceManager.js +10 -11
- package/dist/src/scales/scaleInteractionController.d.ts.map +1 -1
- package/dist/src/scales/scaleInteractionController.js +16 -14
- package/dist/src/scales/scaleResolution.d.ts +16 -0
- package/dist/src/scales/scaleResolution.d.ts.map +1 -1
- package/dist/src/scales/scaleResolution.js +314 -54
- package/dist/src/scales/scaleResolutionTestUtils.d.ts +21 -0
- package/dist/src/scales/scaleResolutionTestUtils.d.ts.map +1 -0
- package/dist/src/scales/scaleResolutionTestUtils.js +33 -0
- package/dist/src/scales/selectionDomainUtils.d.ts +22 -0
- package/dist/src/scales/selectionDomainUtils.d.ts.map +1 -0
- package/dist/src/scales/selectionDomainUtils.js +79 -0
- package/dist/src/scales/zoomDomainUtils.d.ts +18 -0
- package/dist/src/scales/zoomDomainUtils.d.ts.map +1 -0
- package/dist/src/scales/zoomDomainUtils.js +69 -0
- package/dist/src/screenshotHarness.d.ts +16 -0
- package/dist/src/screenshotHarness.d.ts.map +1 -0
- package/dist/src/screenshotHarness.js +242 -0
- package/dist/src/singlePageApp.js +1 -1
- package/dist/src/spec/data.d.ts +23 -3
- package/dist/src/spec/genome.d.ts +22 -2
- package/dist/src/spec/parameter.d.ts +39 -2
- package/dist/src/spec/root.d.ts +20 -1
- package/dist/src/spec/scale.d.ts +41 -5
- package/dist/src/styles/genome-spy.css +8 -0
- package/dist/src/styles/genome-spy.css.d.ts +1 -1
- package/dist/src/styles/genome-spy.css.d.ts.map +1 -1
- package/dist/src/styles/genome-spy.css.js +8 -0
- package/dist/src/tooltip/dataTooltipHandler.js +59 -10
- package/dist/src/types/embedApi.d.ts +19 -0
- package/dist/src/utils/inferSpecBaseUrl.d.ts +14 -0
- package/dist/src/utils/inferSpecBaseUrl.d.ts.map +1 -0
- package/dist/src/utils/inferSpecBaseUrl.js +73 -0
- package/dist/src/utils/interactionEvent.d.ts +53 -3
- package/dist/src/utils/interactionEvent.d.ts.map +1 -1
- package/dist/src/utils/interactionEvent.js +62 -1
- package/dist/src/utils/radixSort.d.ts.map +1 -1
- package/dist/src/utils/radixSort.js +26 -1
- package/dist/src/view/containerMutationHelper.d.ts.map +1 -1
- package/dist/src/view/containerMutationHelper.js +8 -0
- package/dist/src/view/dataReadiness.d.ts +2 -2
- package/dist/src/view/dataReadiness.d.ts.map +1 -1
- package/dist/src/view/dataReadiness.js +63 -58
- package/dist/src/view/facetView.d.ts +1 -1
- package/dist/src/view/facetView.js +1 -1
- package/dist/src/view/gridView/gridChild.d.ts +7 -0
- package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
- package/dist/src/view/gridView/gridChild.js +180 -11
- package/dist/src/view/gridView/gridView.d.ts.map +1 -1
- package/dist/src/view/gridView/gridView.js +60 -17
- package/dist/src/view/unitView.d.ts +1 -1
- package/dist/src/view/zoom.d.ts +14 -2
- package/dist/src/view/zoom.d.ts.map +1 -1
- package/dist/src/view/zoom.js +373 -76
- package/package.json +5 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urlSource.d.ts","sourceRoot":"","sources":["../../../../src/data/sources/urlSource.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"urlSource.d.ts","sourceRoot":"","sources":["../../../../src/data/sources/urlSource.js"],"names":[],"mappings":"AA+IA;;;GAGG;AACH,gCAHW,OAAO,CAAC,OAAO,oBAAoB,EAAE,IAAI,CAAC,GACxC,IAAI,IAAI,OAAO,oBAAoB,EAAE,OAAO,CAIxD;AAzID;;;GAGG;AACH;IACI;;;OAGG;IACH,oBAHW,OAAO,oBAAoB,EAAE,OAAO,QACpC,OAAO,oBAAoB,EAAE,OAAO,EAc9C;IATG,6CAMC;IAED,gBAAiC;;CA6GxC;uBA3IsB,iBAAiB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { read } from "vega-loader";
|
|
2
|
-
import { getFormat, responseType } from "./dataUtils.js";
|
|
2
|
+
import { getFormat, hasGzipExtension, responseType } from "./dataUtils.js";
|
|
3
3
|
import DataSource from "./dataSource.js";
|
|
4
4
|
import {
|
|
5
5
|
activateExprRefProps,
|
|
@@ -7,14 +7,13 @@ import {
|
|
|
7
7
|
} from "../../paramRuntime/paramUtils.js";
|
|
8
8
|
import { concatUrl } from "../../utils/url.js";
|
|
9
9
|
|
|
10
|
+
const gzipMimeTypes = new Set(["application/gzip", "application/x-gzip"]);
|
|
11
|
+
const textDecoder = new TextDecoder();
|
|
12
|
+
|
|
10
13
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
14
|
+
* Loads eager data from URLs and transparently decompresses gzip-compatible
|
|
15
|
+
* payloads before handing them to the registered format reader.
|
|
13
16
|
*/
|
|
14
|
-
export function isUrlData(data) {
|
|
15
|
-
return "url" in data;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
17
|
export default class UrlSource extends DataSource {
|
|
19
18
|
/**
|
|
20
19
|
* @param {import("../../spec/data.js").UrlData} params
|
|
@@ -48,6 +47,7 @@ export default class UrlSource extends DataSource {
|
|
|
48
47
|
*/
|
|
49
48
|
async #loadUrlsFromFile(props) {
|
|
50
49
|
const listUrl = concatUrl(this.baseUrl, props.urlsFromFile);
|
|
50
|
+
const format = { type: props.type ?? "tsv" };
|
|
51
51
|
|
|
52
52
|
const result = await fetch(listUrl);
|
|
53
53
|
|
|
@@ -56,10 +56,14 @@ export default class UrlSource extends DataSource {
|
|
|
56
56
|
`Cannot load "${listUrl}": ${result.status} ${result.statusText}`
|
|
57
57
|
);
|
|
58
58
|
}
|
|
59
|
-
const
|
|
59
|
+
const content = await readResponseBody(
|
|
60
|
+
result,
|
|
61
|
+
listUrl,
|
|
62
|
+
responseType(format.type)
|
|
63
|
+
);
|
|
60
64
|
|
|
61
65
|
const files = /** @type {string[] | {url: string}[]} */ (
|
|
62
|
-
read(
|
|
66
|
+
read(content, format)
|
|
63
67
|
)
|
|
64
68
|
.map((u) => (typeof u === "string" ? u : u.url))
|
|
65
69
|
.map((u) => concatUrl(listUrl, u));
|
|
@@ -94,11 +98,7 @@ export default class UrlSource extends DataSource {
|
|
|
94
98
|
if (!result.ok) {
|
|
95
99
|
throw new Error(`${result.status} ${result.statusText}`);
|
|
96
100
|
}
|
|
97
|
-
|
|
98
|
-
return typeof result[type] == "function"
|
|
99
|
-
? // @ts-ignore
|
|
100
|
-
result[type]()
|
|
101
|
-
: result.text();
|
|
101
|
+
return await readResponseBody(result, url, type);
|
|
102
102
|
} catch (e) {
|
|
103
103
|
throw new Error(
|
|
104
104
|
`Could not load data: ${url}. Reason: ${e.message}`
|
|
@@ -110,15 +110,20 @@ export default class UrlSource extends DataSource {
|
|
|
110
110
|
* @param {any} content
|
|
111
111
|
* @param {string} [url]
|
|
112
112
|
*/
|
|
113
|
-
const readAndParse = (content, url) => {
|
|
113
|
+
const readAndParse = async (content, url) => {
|
|
114
114
|
try {
|
|
115
|
-
/** @type {any[]} */
|
|
116
|
-
const
|
|
115
|
+
/** @type {any[] | Promise<any[]>} */
|
|
116
|
+
const dataOrPromise = read(content, format);
|
|
117
|
+
const data =
|
|
118
|
+
dataOrPromise instanceof Promise
|
|
119
|
+
? await dataOrPromise
|
|
120
|
+
: dataOrPromise;
|
|
117
121
|
this.beginBatch({ type: "file", url: url });
|
|
118
122
|
for (const d of data) {
|
|
119
123
|
this._propagate(d);
|
|
120
124
|
}
|
|
121
125
|
} catch (e) {
|
|
126
|
+
console.warn(e);
|
|
122
127
|
throw new Error(`Cannot parse: ${url}: ${e.message}`);
|
|
123
128
|
}
|
|
124
129
|
};
|
|
@@ -135,3 +140,122 @@ export default class UrlSource extends DataSource {
|
|
|
135
140
|
this.complete();
|
|
136
141
|
}
|
|
137
142
|
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @param {Partial<import("../../spec/data.js").Data>} data
|
|
146
|
+
* @returns {data is import("../../spec/data.js").UrlData}
|
|
147
|
+
*/
|
|
148
|
+
export function isUrlData(data) {
|
|
149
|
+
return "url" in data;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @param {Uint8Array} bytes
|
|
154
|
+
*/
|
|
155
|
+
function hasGzipMagic(bytes) {
|
|
156
|
+
return (
|
|
157
|
+
bytes.length >= 10 &&
|
|
158
|
+
bytes[0] == 0x1f &&
|
|
159
|
+
bytes[1] == 0x8b &&
|
|
160
|
+
bytes[2] == 0x08 &&
|
|
161
|
+
(bytes[3] & 0xe0) == 0
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @param {string | null} contentType
|
|
167
|
+
*/
|
|
168
|
+
function isGzipMimeType(contentType) {
|
|
169
|
+
if (!contentType) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return gzipMimeTypes.has(contentType.split(";")[0].trim().toLowerCase());
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* @param {string | null} contentEncoding
|
|
178
|
+
*/
|
|
179
|
+
function hasGzipContentEncoding(contentEncoding) {
|
|
180
|
+
if (!contentEncoding) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return contentEncoding
|
|
185
|
+
.toLowerCase()
|
|
186
|
+
.split(",")
|
|
187
|
+
.some((encoding) => encoding.trim() == "gzip");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @param {Uint8Array} bytes
|
|
192
|
+
* @returns {ArrayBuffer}
|
|
193
|
+
*/
|
|
194
|
+
function toArrayBuffer(bytes) {
|
|
195
|
+
return new Uint8Array(bytes).buffer;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @param {Uint8Array} bytes
|
|
200
|
+
*/
|
|
201
|
+
async function decompressGzip(bytes) {
|
|
202
|
+
if (typeof DecompressionStream != "function") {
|
|
203
|
+
throw new Error(
|
|
204
|
+
"Gzip-compressed URL data requires DecompressionStream support."
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const body = new Response(toArrayBuffer(bytes)).body;
|
|
209
|
+
if (!body) {
|
|
210
|
+
throw new Error(
|
|
211
|
+
"Cannot create a readable stream for gzip decompression."
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const stream = body.pipeThrough(new DecompressionStream("gzip"));
|
|
216
|
+
return new Uint8Array(await new Response(stream).arrayBuffer());
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* @param {Response} response
|
|
221
|
+
* @param {string} url
|
|
222
|
+
* @param {string} type
|
|
223
|
+
*/
|
|
224
|
+
async function readResponseBody(response, url, type) {
|
|
225
|
+
const gzipHint =
|
|
226
|
+
hasGzipExtension(url) ||
|
|
227
|
+
isGzipMimeType(response.headers.get("content-type")) ||
|
|
228
|
+
hasGzipContentEncoding(response.headers.get("content-encoding"));
|
|
229
|
+
|
|
230
|
+
if (!gzipHint) {
|
|
231
|
+
return readResponseUsingType(response, type);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
235
|
+
const bodyBytes = hasGzipMagic(bytes) ? await decompressGzip(bytes) : bytes;
|
|
236
|
+
return deserializeBytes(bodyBytes, type);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* @param {Response} response
|
|
241
|
+
* @param {string} type
|
|
242
|
+
*/
|
|
243
|
+
function readResponseUsingType(response, type) {
|
|
244
|
+
// @ts-ignore
|
|
245
|
+
return typeof response[type] == "function"
|
|
246
|
+
? // @ts-ignore
|
|
247
|
+
response[type]()
|
|
248
|
+
: response.text();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* @param {Uint8Array} bytes
|
|
253
|
+
* @param {string} type
|
|
254
|
+
*/
|
|
255
|
+
function deserializeBytes(bytes, type) {
|
|
256
|
+
if (type == "arrayBuffer") {
|
|
257
|
+
return toArrayBuffer(bytes);
|
|
258
|
+
} else {
|
|
259
|
+
return textDecoder.decode(bytes);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
@@ -54,12 +54,12 @@ export function isChannelDefWithScale(channelDef: import("../spec/channel.js").C
|
|
|
54
54
|
/**
|
|
55
55
|
* @param {import("../spec/channel.js").ChannelDef} channelDef
|
|
56
56
|
*/
|
|
57
|
-
export function findChannelDefWithScale(channelDef: import("../spec/channel.js").ChannelDef): import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, string> | import("../spec/channel.js").PositionFieldDef | import("../spec/channel.js").
|
|
57
|
+
export function findChannelDefWithScale(channelDef: import("../spec/channel.js").ChannelDef): import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, string> | import("../spec/channel.js").PositionFieldDef | import("../spec/channel.js").ChromPosDef | import("../spec/channel.js").PositionDatumDef | import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, number> | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").ValueDefBase<string | import("../spec/parameter.js").ExprRef> & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").DomainContributionMixins) | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").ValueDefBase<number | import("../spec/parameter.js").ExprRef> & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").DomainContributionMixins) | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").FieldDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").DomainContributionMixins & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>) | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").DatumDef<import("../spec/parameter.js").ExprRef | import("../spec/channel.js").Scalar> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").DomainContributionMixins);
|
|
58
58
|
/**
|
|
59
59
|
* @param {import("../view/unitView.js").default} view
|
|
60
60
|
* @param {import("../spec/channel.js").Channel} channel
|
|
61
61
|
*/
|
|
62
|
-
export function getChannelDefWithScale(view: import("../view/unitView.js").default, channel: import("../spec/channel.js").Channel): import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, string> | import("../spec/channel.js").PositionFieldDef | import("../spec/channel.js").
|
|
62
|
+
export function getChannelDefWithScale(view: import("../view/unitView.js").default, channel: import("../spec/channel.js").Channel): import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, string> | import("../spec/channel.js").PositionFieldDef | import("../spec/channel.js").ChromPosDef | import("../spec/channel.js").PositionDatumDef | (import("../spec/channel.js").FieldDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").DomainContributionMixins & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").XIndexDef) | (import("../spec/channel.js").ChromPosDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").DomainContributionMixins & import("../spec/channel.js").TypeMixins<"locus"> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").XIndexDef) | (import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").DatumDef<import("../spec/parameter.js").ExprRef | import("../spec/channel.js").Scalar> & import("../spec/channel.js").DomainContributionMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").XIndexDef) | import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, number> | import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").TypeForShape>, string>;
|
|
63
63
|
/**
|
|
64
64
|
* @param {import("../spec/channel.js").ChannelDef} channelDef
|
|
65
65
|
* @returns {channelDef is import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>}
|
|
@@ -51,7 +51,7 @@ export default class BmFontManager {
|
|
|
51
51
|
* @param {FontWeight | keyof WEIGHTS} weight
|
|
52
52
|
* @returns {FontEntry}
|
|
53
53
|
*/
|
|
54
|
-
getFont(family: string, style?: FontStyle, weight?: FontWeight | ("bold" | "normal" | "
|
|
54
|
+
getFont(family: string, style?: FontStyle, weight?: FontWeight | ("bold" | "normal" | "thin" | "light" | "regular" | "medium" | "black")): FontEntry;
|
|
55
55
|
/**
|
|
56
56
|
*
|
|
57
57
|
* @param {FontEntry} fontEntry An uninitialized font entry
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("../spec/scale.js").Scale["assembly"]} AssemblyReference
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {object} AssemblyPreflightResult
|
|
6
|
+
* @prop {AssemblyReference[]} assemblies
|
|
7
|
+
* @prop {boolean} needsDefaultAssembly
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* @param {import("../view/view.js").default} viewRoot
|
|
11
|
+
* @returns {AssemblyPreflightResult}
|
|
12
|
+
*/
|
|
13
|
+
export function collectAssembliesFromViewHierarchy(viewRoot: import("../view/view.js").default): AssemblyPreflightResult;
|
|
14
|
+
/**
|
|
15
|
+
* Ensures that all assemblies required by the given view hierarchy are loaded
|
|
16
|
+
* before any scale initialization path can run.
|
|
17
|
+
*
|
|
18
|
+
* Reminder: call this immediately after view hierarchy creation and before
|
|
19
|
+
* operations that can implicitly initialize scales (for example, step-based
|
|
20
|
+
* size resolution, dynamic opacity setup, or encoder initialization).
|
|
21
|
+
*
|
|
22
|
+
* @param {import("../view/view.js").default} viewRoot
|
|
23
|
+
* @param {import("./genomeStore.js").default} genomeStore
|
|
24
|
+
*/
|
|
25
|
+
export function ensureAssembliesForView(viewRoot: import("../view/view.js").default, genomeStore: import("./genomeStore.js").default): Promise<void>;
|
|
26
|
+
export type AssemblyReference = import("../spec/scale.js").Scale["assembly"];
|
|
27
|
+
export type AssemblyPreflightResult = {
|
|
28
|
+
assemblies: AssemblyReference[];
|
|
29
|
+
needsDefaultAssembly: boolean;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=assemblyPreflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assemblyPreflight.d.ts","sourceRoot":"","sources":["../../../src/genome/assemblyPreflight.js"],"names":[],"mappings":"AAEA;;GAEG;AAEH;;;;GAIG;AAEH;;;GAGG;AACH,6DAHW,OAAO,iBAAiB,EAAE,OAAO,GAC/B,uBAAuB,CAsBnC;AAED;;;;;;;;;;GAUG;AACH,kDAHW,OAAO,iBAAiB,EAAE,OAAO,eACjC,OAAO,kBAAkB,EAAE,OAAO,iBAgB5C;gCA5DY,OAAO,kBAAkB,EAAE,KAAK,CAAC,UAAU,CAAC;;gBAK/C,iBAAiB,EAAE;0BACnB,OAAO"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { visitAddressableViews } from "../view/viewSelectors.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import("../spec/scale.js").Scale["assembly"]} AssemblyReference
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {object} AssemblyPreflightResult
|
|
9
|
+
* @prop {AssemblyReference[]} assemblies
|
|
10
|
+
* @prop {boolean} needsDefaultAssembly
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {import("../view/view.js").default} viewRoot
|
|
15
|
+
* @returns {AssemblyPreflightResult}
|
|
16
|
+
*/
|
|
17
|
+
export function collectAssembliesFromViewHierarchy(viewRoot) {
|
|
18
|
+
/** @type {AssemblyReference[]} */
|
|
19
|
+
const assemblies = [];
|
|
20
|
+
let needsDefaultAssembly = false;
|
|
21
|
+
|
|
22
|
+
const resolutions = collectRelevantScaleResolutions(viewRoot);
|
|
23
|
+
for (const resolution of resolutions) {
|
|
24
|
+
const requirement = resolution.getAssemblyRequirement();
|
|
25
|
+
if (requirement.assembly) {
|
|
26
|
+
assemblies.push(requirement.assembly);
|
|
27
|
+
}
|
|
28
|
+
if (requirement.needsDefaultAssembly) {
|
|
29
|
+
needsDefaultAssembly = true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
assemblies,
|
|
35
|
+
needsDefaultAssembly,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Ensures that all assemblies required by the given view hierarchy are loaded
|
|
41
|
+
* before any scale initialization path can run.
|
|
42
|
+
*
|
|
43
|
+
* Reminder: call this immediately after view hierarchy creation and before
|
|
44
|
+
* operations that can implicitly initialize scales (for example, step-based
|
|
45
|
+
* size resolution, dynamic opacity setup, or encoder initialization).
|
|
46
|
+
*
|
|
47
|
+
* @param {import("../view/view.js").default} viewRoot
|
|
48
|
+
* @param {import("./genomeStore.js").default} genomeStore
|
|
49
|
+
*/
|
|
50
|
+
export async function ensureAssembliesForView(viewRoot, genomeStore) {
|
|
51
|
+
const { assemblies, needsDefaultAssembly } =
|
|
52
|
+
collectAssembliesFromViewHierarchy(viewRoot);
|
|
53
|
+
if (needsDefaultAssembly) {
|
|
54
|
+
const defaultAssembly = genomeStore.getDefaultAssemblyName();
|
|
55
|
+
if (!defaultAssembly) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
"No default assembly has been configured. Set root `assembly`, define exactly one entry in root `genomes`, or set `scale.assembly` on each locus scale."
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
assemblies.push(defaultAssembly);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
await genomeStore.ensureAssemblies(assemblies);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Collects scale resolutions that can influence user-authored views while
|
|
68
|
+
* excluding internal helper subtrees (axis/grid/etc.).
|
|
69
|
+
*
|
|
70
|
+
* Reminder: implicit root wrappers are marked non-addressable, so include the
|
|
71
|
+
* root ancestry explicitly before traversing addressable views.
|
|
72
|
+
*
|
|
73
|
+
* @param {import("../view/view.js").default} viewRoot
|
|
74
|
+
* @returns {Set<import("../scales/scaleResolution.js").default>}
|
|
75
|
+
*/
|
|
76
|
+
function collectRelevantScaleResolutions(viewRoot) {
|
|
77
|
+
/** @type {Set<import("../scales/scaleResolution.js").default>} */
|
|
78
|
+
const resolutions = new Set();
|
|
79
|
+
|
|
80
|
+
/** @type {import("../spec/channel.js").PrimaryPositionalChannel[]} */
|
|
81
|
+
const locusChannels = ["x", "y"];
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param {import("../view/view.js").default} view
|
|
85
|
+
*/
|
|
86
|
+
const collectFromView = (view) => {
|
|
87
|
+
for (const channel of locusChannels) {
|
|
88
|
+
const resolution = view.getScaleResolution(channel);
|
|
89
|
+
if (resolution) {
|
|
90
|
+
resolutions.add(resolution);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
collectFromView(viewRoot);
|
|
96
|
+
visitAddressableViews(viewRoot, collectFromView);
|
|
97
|
+
|
|
98
|
+
return resolutions;
|
|
99
|
+
}
|
|
@@ -62,11 +62,11 @@ export default class Genome {
|
|
|
62
62
|
config: {
|
|
63
63
|
name: string;
|
|
64
64
|
} | {
|
|
65
|
-
url: string;
|
|
66
65
|
name: string;
|
|
66
|
+
url: string;
|
|
67
67
|
} | {
|
|
68
|
-
contigs: import("../spec/genome.js").Contig[];
|
|
69
68
|
name: string;
|
|
69
|
+
contigs: import("../spec/genome.js").Contig[];
|
|
70
70
|
};
|
|
71
71
|
/** @type {(Chromosome & ChromosomeAnnotation)[]} */
|
|
72
72
|
chromosomes: (Chromosome & ChromosomeAnnotation)[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genome.d.ts","sourceRoot":"","sources":["../../../src/genome/genome.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"genome.d.ts","sourceRoot":"","sources":["../../../src/genome/genome.js"],"names":[],"mappings":"AA2XA;;;GAGG;AACH,gDAFW,MAAM;;;IAOhB;AAED;;;;GAIG;AACH,0CAHW,GAAG,GACF,KAAK,IAAI,gBAAgB,CAIpC;AAED;;;;GAIG;AACH,kDAHW,GAAG,EAAE,GACJ,KAAK,IAAI,gBAAgB,EAAE,CAItC;AAED;;;GAGG;AACH,sCAHW,GAAG,GACD,KAAK,IAAI,YAAY,CASjC;AAED;;;GAGG;AACH,yCAHW,GAAG,GACD,KAAK,IAAI,OAAO,mBAAmB,EAAE,eAAe,CAIhE;AAED;;;GAGG;AACH,4CAHW,GAAG,GACD,KAAK,IAAI,OAAO,mBAAmB,EAAE,kBAAkB,CAInE;AA5aD;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;IACI;;OAEG;IACH,oBAFW,YAAY,EA6CtB;IA1CG;;;;;;;;MAA2C;IAc3C,oDAAoD;IACpD,aADW,CAAC,UAAU,GAAG,oBAAoB,CAAC,EAAE,CAC3B;IAErB,2CAA2C;IAC3C,0BADW,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,CACE;IAEzC,sEAAsE;IACtE,mBADW,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,UAAU,GAAG,oBAAoB,CAAC,CAChC;IAElC,uBAAuB;IACvB,cADW,MAAM,EAAE,CACG;IAEtB,kBAAkB;IAkBtB,mBAEC;IAED;;OAEG;IACH,cAFW,MAAM,iBAmBhB;IAED,wBAEC;IAED;;;OAGG;IACH,0BAFW,UAAU,EAAE,QA+CtB;IAED,sBAEC;IAED;;;;;OAKG;IACH,oBAHW,MAAM,GAAG,MAAM,OACf,MAAM,UAShB;IAED;;;OAGG;IACH,4BAFW,MAAM,qCAgBhB;IAED;;;;OAIG;IACH,6BAHW,MAAM,GACJ,gBAAgB,CAY5B;IAED;;;OAGG;IACH,oBAFW,MAAM,qCAIhB;IAED;;;;;;;;;;OAUG;IACH,yBAHW,MAAM,EAAE,GACN,MAAM,CAIlB;IAED;;;;;;OAMG;IACH,2BAHW,MAAM,GACJ,MAAM,CAQlB;IAED;;;OAGG;IACH,gCAHW,MAAM,EAAE,GACN,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAUhD;IAED;;;;;;OAMG;IACH,kCAFW,gBAAgB,EAAE,YAgB5B;IAED;;;;;OAKG;IACH,wCAHW,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,GAClC,0BAA0B,EAAE,CAiCxC;IAED;;;;OAIG;IACH,4DAFW,MAAM,EAAE,gCAOlB;IAED;;;;OAIG;IACH,mBAHW,MAAM,GACJ,CAAC,MAAM,EAAE,MAAM,CAAC,CAgC5B;CACJ;2BAjXY,OAAO,mBAAmB,EAAE,YAAY;+BACxC,OAAO,mBAAmB,EAAE,gBAAgB;;UAG/C,MAAM;UACN,MAAM;;;;;;WAGN,MAAM;;;;YACN,MAAM;;;;qBACN,MAAM;;;;mBACN,MAAM;wBACN,MAAM,EAAE;;;;SACR,OAAO;;;WAGP,MAAM;cACN,MAAM;YACN,MAAM"}
|
|
@@ -111,6 +111,10 @@ export default class Genome {
|
|
|
111
111
|
* @param {Chromosome[]} chromSizes
|
|
112
112
|
*/
|
|
113
113
|
setChromSizes(chromSizes) {
|
|
114
|
+
this.chromosomes = [];
|
|
115
|
+
this.cumulativeChromPositions = new Map();
|
|
116
|
+
this.chromosomesByName = new Map();
|
|
117
|
+
|
|
114
118
|
let pos = 0;
|
|
115
119
|
this.startByIndex = [0];
|
|
116
120
|
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves genome assemblies for locus scales.
|
|
3
|
+
*
|
|
4
|
+
* Keeps configured genome definitions and loaded `Genome` instances, supports
|
|
5
|
+
* named and inline assemblies, and deduplicates concurrent URL loads.
|
|
6
|
+
*
|
|
7
|
+
* `ensureAssembly(...)` is the async loading boundary. `getGenome(...)` is
|
|
8
|
+
* synchronous and expects required URL-backed assemblies to be ensured first.
|
|
9
|
+
*
|
|
10
|
+
* The default assembly comes from root `assembly`, a single configured genome,
|
|
11
|
+
* or a single already-loaded built-in genome.
|
|
12
|
+
*/
|
|
1
13
|
export default class GenomeStore {
|
|
2
14
|
/**
|
|
3
15
|
* @param {string} baseUrl
|
|
@@ -9,12 +21,31 @@ export default class GenomeStore {
|
|
|
9
21
|
/**
|
|
10
22
|
* @param {import("../spec/genome.js").GenomeConfig} genomeConfig
|
|
11
23
|
*/
|
|
12
|
-
initialize(genomeConfig: import("../spec/genome.js").GenomeConfig): Promise<void
|
|
24
|
+
initialize(genomeConfig: import("../spec/genome.js").GenomeConfig): Promise<void>;
|
|
13
25
|
/**
|
|
14
|
-
* @param {string
|
|
26
|
+
* @param {Map<string, import("../spec/root.js").NamedGenomeConfig>} genomesByName
|
|
27
|
+
* @param {string} [defaultAssembly]
|
|
28
|
+
*/
|
|
29
|
+
configureGenomes(genomesByName: Map<string, import("../spec/root.js").NamedGenomeConfig>, defaultAssembly?: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* @returns {string | undefined}
|
|
32
|
+
*/
|
|
33
|
+
getDefaultAssemblyName(): string | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* @param {(string | import("../spec/scale.js").InlineLocusAssembly | undefined)[]} assemblies
|
|
36
|
+
*/
|
|
37
|
+
ensureAssemblies(assemblies: (string | import("../spec/scale.js").InlineLocusAssembly | undefined)[]): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* @param {string | import("../spec/scale.js").InlineLocusAssembly} assembly
|
|
40
|
+
* @returns {Promise<Genome>}
|
|
41
|
+
*/
|
|
42
|
+
ensureAssembly(assembly: string | import("../spec/scale.js").InlineLocusAssembly): Promise<Genome>;
|
|
43
|
+
/**
|
|
44
|
+
* @param {string | import("../spec/scale.js").InlineLocusAssembly} [name] If not given, a default genome is returned.
|
|
15
45
|
* @returns {Genome}
|
|
16
46
|
*/
|
|
17
|
-
getGenome(name?: string): Genome;
|
|
47
|
+
getGenome(name?: string | import("../spec/scale.js").InlineLocusAssembly): Genome;
|
|
48
|
+
#private;
|
|
18
49
|
}
|
|
19
50
|
import Genome from "./genome.js";
|
|
20
51
|
//# sourceMappingURL=genomeStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genomeStore.d.ts","sourceRoot":"","sources":["../../../src/genome/genomeStore.js"],"names":[],"mappings":"AAEA;IACI;;OAEG;IACH,qBAFW,MAAM,
|
|
1
|
+
{"version":3,"file":"genomeStore.d.ts","sourceRoot":"","sources":["../../../src/genome/genomeStore.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH;IACI;;OAEG;IACH,qBAFW,MAAM,EAahB;IAVG,kCAAkC;IAClC,SADW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CACN;IAQxB,gBAAsB;IAkB1B;;OAEG;IACH,yBAFW,OAAO,mBAAmB,EAAE,YAAY,iBAMlD;IAED;;;OAGG;IACH,gCAHW,GAAG,CAAC,MAAM,EAAE,OAAO,iBAAiB,EAAE,iBAAiB,CAAC,oBACxD,MAAM,QAShB;IAED;;OAEG;IACH,0BAFa,MAAM,GAAG,SAAS,CAmB9B;IAED;;OAEG;IACH,6BAFW,CAAC,MAAM,GAAG,OAAO,kBAAkB,EAAE,mBAAmB,GAAG,SAAS,CAAC,EAAE,iBAuBjF;IAED;;;OAGG;IACH,yBAHW,MAAM,GAAG,OAAO,kBAAkB,EAAE,mBAAmB,GACrD,OAAO,CAAC,MAAM,CAAC,CAuB3B;IAED;;;OAGG;IACH,iBAHW,MAAM,GAAG,OAAO,kBAAkB,EAAE,mBAAmB,GACrD,MAAM,CAuDlB;;CAwOJ;mBAhbkB,aAAa"}
|