@genome-spy/core 0.72.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 +6779 -5393
- package/dist/bundle/index.js +133 -121
- 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/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 +133 -14
- 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 +81 -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/webGLHelper.d.ts +25 -11
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +59 -33
- 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.map +1 -1
- package/dist/src/marks/mark.js +6 -1
- 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/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.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/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 +4 -2
|
@@ -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"}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import Genome from "./genome.js";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Resolves genome assemblies for locus scales.
|
|
5
|
+
*
|
|
6
|
+
* Keeps configured genome definitions and loaded `Genome` instances, supports
|
|
7
|
+
* named and inline assemblies, and deduplicates concurrent URL loads.
|
|
8
|
+
*
|
|
9
|
+
* `ensureAssembly(...)` is the async loading boundary. `getGenome(...)` is
|
|
10
|
+
* synchronous and expects required URL-backed assemblies to be ensured first.
|
|
11
|
+
*
|
|
12
|
+
* The default assembly comes from root `assembly`, a single configured genome,
|
|
13
|
+
* or a single already-loaded built-in genome.
|
|
14
|
+
*/
|
|
3
15
|
export default class GenomeStore {
|
|
4
16
|
/**
|
|
5
17
|
* @param {string} baseUrl
|
|
@@ -7,48 +19,427 @@ export default class GenomeStore {
|
|
|
7
19
|
constructor(baseUrl) {
|
|
8
20
|
/** @type {Map<string, Genome>} */
|
|
9
21
|
this.genomes = new Map();
|
|
22
|
+
|
|
23
|
+
this.#configuredGenomesByName = new Map();
|
|
24
|
+
this.#loadingPromisesByName = new Map();
|
|
25
|
+
this.#inlineAssemblyNamesByKey = new Map();
|
|
26
|
+
this.#nextInlineAssemblyIndex = 0;
|
|
27
|
+
this.#defaultAssemblyName = undefined;
|
|
28
|
+
|
|
10
29
|
this.baseUrl = baseUrl;
|
|
11
30
|
}
|
|
12
31
|
|
|
32
|
+
/** @type {Map<string, import("../spec/root.js").NamedGenomeConfig>} */
|
|
33
|
+
#configuredGenomesByName;
|
|
34
|
+
|
|
35
|
+
/** @type {Map<string, Promise<void>>} */
|
|
36
|
+
#loadingPromisesByName;
|
|
37
|
+
|
|
38
|
+
/** @type {Map<string, string>} */
|
|
39
|
+
#inlineAssemblyNamesByKey;
|
|
40
|
+
|
|
41
|
+
/** @type {number} */
|
|
42
|
+
#nextInlineAssemblyIndex;
|
|
43
|
+
|
|
44
|
+
/** @type {string | undefined} */
|
|
45
|
+
#defaultAssemblyName;
|
|
46
|
+
|
|
13
47
|
/**
|
|
14
48
|
* @param {import("../spec/genome.js").GenomeConfig} genomeConfig
|
|
15
49
|
*/
|
|
16
|
-
// eslint-disable-next-line require-await
|
|
17
50
|
async initialize(genomeConfig) {
|
|
18
|
-
const
|
|
19
|
-
this.
|
|
51
|
+
const { name, ...config } = genomeConfig;
|
|
52
|
+
this.configureGenomes(new Map([[name, config]]), name);
|
|
53
|
+
await this.ensureAssembly(name);
|
|
54
|
+
}
|
|
20
55
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
56
|
+
/**
|
|
57
|
+
* @param {Map<string, import("../spec/root.js").NamedGenomeConfig>} genomesByName
|
|
58
|
+
* @param {string} [defaultAssembly]
|
|
59
|
+
*/
|
|
60
|
+
configureGenomes(genomesByName, defaultAssembly) {
|
|
61
|
+
this.genomes.clear();
|
|
62
|
+
this.#loadingPromisesByName.clear();
|
|
63
|
+
this.#inlineAssemblyNamesByKey.clear();
|
|
64
|
+
this.#nextInlineAssemblyIndex = 0;
|
|
65
|
+
this.#configuredGenomesByName = new Map(genomesByName);
|
|
66
|
+
this.#defaultAssemblyName = defaultAssembly;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @returns {string | undefined}
|
|
71
|
+
*/
|
|
72
|
+
getDefaultAssemblyName() {
|
|
73
|
+
if (this.#defaultAssemblyName) {
|
|
74
|
+
return this.#defaultAssemblyName;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (this.#configuredGenomesByName.size === 1) {
|
|
78
|
+
return this.#configuredGenomesByName.keys().next().value;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (
|
|
82
|
+
this.#configuredGenomesByName.size === 0 &&
|
|
83
|
+
this.genomes.size === 1
|
|
84
|
+
) {
|
|
85
|
+
return this.genomes.keys().next().value;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return undefined;
|
|
26
89
|
}
|
|
27
90
|
|
|
28
91
|
/**
|
|
29
|
-
* @param {string
|
|
92
|
+
* @param {(string | import("../spec/scale.js").InlineLocusAssembly | undefined)[]} assemblies
|
|
93
|
+
*/
|
|
94
|
+
async ensureAssemblies(assemblies) {
|
|
95
|
+
/** @type {Promise<Genome>[]} */
|
|
96
|
+
const pending = [];
|
|
97
|
+
/** @type {Set<string>} */
|
|
98
|
+
const seenAssemblies = new Set();
|
|
99
|
+
|
|
100
|
+
for (const assembly of assemblies) {
|
|
101
|
+
if (!assembly) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const dedupKey = getAssemblyDedupKey(assembly);
|
|
106
|
+
if (seenAssemblies.has(dedupKey)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
seenAssemblies.add(dedupKey);
|
|
111
|
+
pending.push(this.ensureAssembly(assembly));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
await Promise.all(pending);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @param {string | import("../spec/scale.js").InlineLocusAssembly} assembly
|
|
119
|
+
* @returns {Promise<Genome>}
|
|
120
|
+
*/
|
|
121
|
+
async ensureAssembly(assembly) {
|
|
122
|
+
if (typeof assembly === "object") {
|
|
123
|
+
return this.#ensureInlineAssemblyGenome(assembly);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const existing = this.genomes.get(assembly);
|
|
127
|
+
if (existing) {
|
|
128
|
+
return existing;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const configured = this.#configuredGenomesByName.get(assembly);
|
|
132
|
+
if (configured) {
|
|
133
|
+
return this.#ensureConfiguredGenome(assembly, configured);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const builtIn = this.#getOrCreateBuiltInGenome(assembly);
|
|
137
|
+
if (builtIn) {
|
|
138
|
+
return builtIn;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
throw this.#createUnknownGenomeError(assembly);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @param {string | import("../spec/scale.js").InlineLocusAssembly} [name] If not given, a default genome is returned.
|
|
30
146
|
* @returns {Genome}
|
|
31
147
|
*/
|
|
32
148
|
getGenome(name) {
|
|
33
|
-
if (
|
|
34
|
-
|
|
149
|
+
if (name && typeof name == "object") {
|
|
150
|
+
return this.#getInlineAssemblyGenome(name);
|
|
35
151
|
}
|
|
36
152
|
|
|
37
|
-
if (name) {
|
|
153
|
+
if (typeof name === "string") {
|
|
38
154
|
const genome = this.genomes.get(name);
|
|
39
|
-
if (
|
|
155
|
+
if (genome) {
|
|
156
|
+
return genome;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (this.#configuredGenomesByName.has(name)) {
|
|
40
160
|
throw new Error(
|
|
41
|
-
`
|
|
161
|
+
`Genome ${name} has not been loaded yet. Call ensureAssembly("${name}") before accessing it.`
|
|
42
162
|
);
|
|
43
163
|
}
|
|
164
|
+
|
|
165
|
+
const builtIn = this.#getOrCreateBuiltInGenome(name);
|
|
166
|
+
if (builtIn) {
|
|
167
|
+
return builtIn;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
throw this.#createUnknownGenomeError(name);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const defaultAssemblyName = this.getDefaultAssemblyName();
|
|
174
|
+
if (defaultAssemblyName) {
|
|
175
|
+
return this.getGenome(defaultAssemblyName);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (this.#configuredGenomesByName.size > 1) {
|
|
179
|
+
throw new Error(
|
|
180
|
+
"Cannot pick a default genome! More than one have been configured!"
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (this.genomes.size === 0 && this.#configuredGenomesByName.size) {
|
|
185
|
+
throw new Error(
|
|
186
|
+
"Default genome is not loaded. Define root `assembly` or call ensureAssembly() first."
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (this.genomes.size > 1) {
|
|
191
|
+
throw new Error(
|
|
192
|
+
"Cannot pick a default genome! More than one have been configured!"
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (this.genomes.size === 0) {
|
|
197
|
+
throw new Error("No genomes have been configured!");
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return this.genomes.values().next().value;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @param {string} name
|
|
205
|
+
* @returns {Genome | undefined}
|
|
206
|
+
*/
|
|
207
|
+
#tryCreateBuiltInGenome(name) {
|
|
208
|
+
try {
|
|
209
|
+
return new Genome({ name });
|
|
210
|
+
} catch (_error) {
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* @param {string} name
|
|
217
|
+
* @returns {Error}
|
|
218
|
+
*/
|
|
219
|
+
#createUnknownGenomeError(name) {
|
|
220
|
+
return new Error(
|
|
221
|
+
`No genome with the name ${name} has been configured!`
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @param {string} name
|
|
227
|
+
* @returns {Genome | undefined}
|
|
228
|
+
*/
|
|
229
|
+
#getOrCreateBuiltInGenome(name) {
|
|
230
|
+
const builtIn = this.#tryCreateBuiltInGenome(name);
|
|
231
|
+
if (builtIn) {
|
|
232
|
+
this.genomes.set(name, builtIn);
|
|
233
|
+
return builtIn;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return undefined;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* @param {string} name
|
|
241
|
+
* @param {string} missingGenomeError
|
|
242
|
+
* @returns {Promise<Genome>}
|
|
243
|
+
*/
|
|
244
|
+
async #awaitLoadedGenomeFromPending(name, missingGenomeError) {
|
|
245
|
+
const pending = this.#loadingPromisesByName.get(name);
|
|
246
|
+
if (!pending) {
|
|
247
|
+
throw new Error(`No pending genome load for ${name}.`);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
await pending;
|
|
251
|
+
const loaded = this.genomes.get(name);
|
|
252
|
+
if (!loaded) {
|
|
253
|
+
throw new Error(missingGenomeError);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return loaded;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* @param {string} name
|
|
261
|
+
* @param {Genome} genome
|
|
262
|
+
* @returns {Promise<Genome>}
|
|
263
|
+
*/
|
|
264
|
+
async #loadGenome(name, genome) {
|
|
265
|
+
const loadPromise = genome.load(this.baseUrl);
|
|
266
|
+
this.#loadingPromisesByName.set(name, loadPromise);
|
|
267
|
+
|
|
268
|
+
try {
|
|
269
|
+
await loadPromise;
|
|
270
|
+
} catch (error) {
|
|
271
|
+
this.genomes.delete(name);
|
|
272
|
+
throw error;
|
|
273
|
+
} finally {
|
|
274
|
+
this.#loadingPromisesByName.delete(name);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return genome;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* @param {string} name
|
|
282
|
+
* @param {import("../spec/root.js").NamedGenomeConfig} config
|
|
283
|
+
* @returns {Promise<Genome>}
|
|
284
|
+
*/
|
|
285
|
+
async #ensureConfiguredGenome(name, config) {
|
|
286
|
+
const existing = this.genomes.get(name);
|
|
287
|
+
if (existing) {
|
|
288
|
+
if (this.#loadingPromisesByName.has(name)) {
|
|
289
|
+
return this.#awaitLoadedGenomeFromPending(
|
|
290
|
+
name,
|
|
291
|
+
`Loading genome ${name} failed before it became available.`
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
return existing;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (this.#loadingPromisesByName.has(name)) {
|
|
298
|
+
return this.#awaitLoadedGenomeFromPending(
|
|
299
|
+
name,
|
|
300
|
+
`Loading genome ${name} failed before it became available.`
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const genome = new Genome({
|
|
305
|
+
name,
|
|
306
|
+
...config,
|
|
307
|
+
});
|
|
308
|
+
this.genomes.set(name, genome);
|
|
309
|
+
|
|
310
|
+
if ("url" in config) {
|
|
311
|
+
return this.#loadGenome(name, genome);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return genome;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* @param {import("../spec/scale.js").InlineLocusAssembly} assembly
|
|
319
|
+
* @returns {Promise<Genome>}
|
|
320
|
+
*/
|
|
321
|
+
async #ensureInlineAssemblyGenome(assembly) {
|
|
322
|
+
this.#validateInlineAssembly(assembly);
|
|
323
|
+
|
|
324
|
+
const inlineName = this.#resolveInlineAssemblyName(assembly);
|
|
325
|
+
|
|
326
|
+
const existing = this.genomes.get(inlineName);
|
|
327
|
+
if (existing) {
|
|
328
|
+
if (this.#loadingPromisesByName.has(inlineName)) {
|
|
329
|
+
return this.#awaitLoadedGenomeFromPending(
|
|
330
|
+
inlineName,
|
|
331
|
+
`Loading inline assembly ${inlineName} failed before it became available.`
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
return existing;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (this.#loadingPromisesByName.has(inlineName)) {
|
|
338
|
+
return this.#awaitLoadedGenomeFromPending(
|
|
339
|
+
inlineName,
|
|
340
|
+
`Loading inline assembly ${inlineName} failed before it became available.`
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if ("contigs" in assembly) {
|
|
345
|
+
const genome = new Genome({
|
|
346
|
+
name: inlineName,
|
|
347
|
+
contigs: assembly.contigs,
|
|
348
|
+
});
|
|
349
|
+
this.genomes.set(inlineName, genome);
|
|
44
350
|
return genome;
|
|
45
|
-
}
|
|
46
|
-
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const genome = new Genome({
|
|
354
|
+
name: inlineName,
|
|
355
|
+
url: assembly.url,
|
|
356
|
+
});
|
|
357
|
+
this.genomes.set(inlineName, genome);
|
|
358
|
+
|
|
359
|
+
return this.#loadGenome(inlineName, genome);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* @param {import("../spec/scale.js").InlineLocusAssembly} assembly
|
|
364
|
+
* @returns {Genome}
|
|
365
|
+
*/
|
|
366
|
+
#getInlineAssemblyGenome(assembly) {
|
|
367
|
+
this.#validateInlineAssembly(assembly);
|
|
368
|
+
|
|
369
|
+
const inlineName = this.#resolveInlineAssemblyName(assembly);
|
|
370
|
+
const existing = this.genomes.get(inlineName);
|
|
371
|
+
if (existing) {
|
|
372
|
+
if (this.#loadingPromisesByName.has(inlineName)) {
|
|
47
373
|
throw new Error(
|
|
48
|
-
|
|
374
|
+
`Inline URL assembly ${inlineName} has not been loaded yet. Call ensureAssembly() before accessing it.`
|
|
49
375
|
);
|
|
50
376
|
}
|
|
51
|
-
return
|
|
377
|
+
return existing;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if ("url" in assembly) {
|
|
381
|
+
throw new Error(
|
|
382
|
+
"Inline URL assemblies must be loaded first. Call ensureAssembly() before accessing it."
|
|
383
|
+
);
|
|
52
384
|
}
|
|
385
|
+
|
|
386
|
+
const genome = new Genome({
|
|
387
|
+
name: inlineName,
|
|
388
|
+
contigs: assembly.contigs,
|
|
389
|
+
});
|
|
390
|
+
this.genomes.set(inlineName, genome);
|
|
391
|
+
|
|
392
|
+
return genome;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* @param {import("../spec/scale.js").InlineLocusAssembly} assembly
|
|
397
|
+
*/
|
|
398
|
+
#validateInlineAssembly(assembly) {
|
|
399
|
+
const hasContigs = "contigs" in assembly;
|
|
400
|
+
const hasUrl = "url" in assembly;
|
|
401
|
+
if (hasContigs === hasUrl) {
|
|
402
|
+
throw new Error(
|
|
403
|
+
"Inline `scale.assembly` objects must define exactly one of `contigs` or `url`."
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* @param {import("../spec/scale.js").InlineLocusAssembly} assembly
|
|
410
|
+
* @returns {string}
|
|
411
|
+
*/
|
|
412
|
+
#resolveInlineAssemblyName(assembly) {
|
|
413
|
+
const key = JSON.stringify(assembly);
|
|
414
|
+
const existingName = this.#inlineAssemblyNamesByKey.get(key);
|
|
415
|
+
if (existingName) {
|
|
416
|
+
return existingName;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
let candidate = `inline_assembly_${this.#nextInlineAssemblyIndex}`;
|
|
420
|
+
this.#nextInlineAssemblyIndex += 1;
|
|
421
|
+
while (
|
|
422
|
+
this.genomes.has(candidate) ||
|
|
423
|
+
this.#configuredGenomesByName.has(candidate) ||
|
|
424
|
+
this.#loadingPromisesByName.has(candidate)
|
|
425
|
+
) {
|
|
426
|
+
candidate = `inline_assembly_${this.#nextInlineAssemblyIndex}`;
|
|
427
|
+
this.#nextInlineAssemblyIndex += 1;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
this.#inlineAssemblyNamesByKey.set(key, candidate);
|
|
431
|
+
return candidate;
|
|
53
432
|
}
|
|
54
433
|
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* @param {string | import("../spec/scale.js").InlineLocusAssembly} assembly
|
|
437
|
+
* @returns {string}
|
|
438
|
+
*/
|
|
439
|
+
function getAssemblyDedupKey(assembly) {
|
|
440
|
+
if (typeof assembly === "string") {
|
|
441
|
+
return `name:${assembly}`;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return `inline:${JSON.stringify(assembly)}`;
|
|
445
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("../spec/root.js").RootConfig} RootConfig
|
|
3
|
+
* @typedef {import("../spec/root.js").NamedGenomeConfig} NamedGenomeDefinition
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {object} ResolvedRootGenomeConfig
|
|
7
|
+
* @prop {Map<string, NamedGenomeDefinition>} genomesByName
|
|
8
|
+
* @prop {string | undefined} defaultAssembly
|
|
9
|
+
* @prop {string | undefined} deprecationWarning
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Resolves root-level genome configuration into a canonical map and default
|
|
13
|
+
* assembly name.
|
|
14
|
+
*
|
|
15
|
+
* @param {RootConfig} rootConfig
|
|
16
|
+
* @returns {ResolvedRootGenomeConfig}
|
|
17
|
+
*/
|
|
18
|
+
export function resolveRootGenomeConfig(rootConfig: RootConfig): ResolvedRootGenomeConfig;
|
|
19
|
+
export type RootConfig = import("../spec/root.js").RootConfig;
|
|
20
|
+
export type NamedGenomeDefinition = import("../spec/root.js").NamedGenomeConfig;
|
|
21
|
+
export type ResolvedRootGenomeConfig = {
|
|
22
|
+
genomesByName: Map<string, NamedGenomeDefinition>;
|
|
23
|
+
defaultAssembly: string | undefined;
|
|
24
|
+
deprecationWarning: string | undefined;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=rootGenomeConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rootGenomeConfig.d.ts","sourceRoot":"","sources":["../../../src/genome/rootGenomeConfig.js"],"names":[],"mappings":"AAEA;;;GAGG;AAEH;;;;;GAKG;AAEH;;;;;;GAMG;AACH,oDAHW,UAAU,GACR,wBAAwB,CAkDpC;yBAlEY,OAAO,iBAAiB,EAAE,UAAU;oCACpC,OAAO,iBAAiB,EAAE,iBAAiB;;mBAK9C,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC;qBAClC,MAAM,GAAG,SAAS;wBAClB,MAAM,GAAG,SAAS"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { getContigs } from "./genomes.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import("../spec/root.js").RootConfig} RootConfig
|
|
5
|
+
* @typedef {import("../spec/root.js").NamedGenomeConfig} NamedGenomeDefinition
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {object} ResolvedRootGenomeConfig
|
|
10
|
+
* @prop {Map<string, NamedGenomeDefinition>} genomesByName
|
|
11
|
+
* @prop {string | undefined} defaultAssembly
|
|
12
|
+
* @prop {string | undefined} deprecationWarning
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Resolves root-level genome configuration into a canonical map and default
|
|
17
|
+
* assembly name.
|
|
18
|
+
*
|
|
19
|
+
* @param {RootConfig} rootConfig
|
|
20
|
+
* @returns {ResolvedRootGenomeConfig}
|
|
21
|
+
*/
|
|
22
|
+
export function resolveRootGenomeConfig(rootConfig) {
|
|
23
|
+
if (rootConfig.genome && rootConfig.genomes) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
"Do not mix deprecated `genome` with `genomes`. Use only `genomes` and `assembly`."
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (rootConfig.genome && rootConfig.assembly) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
"Do not mix deprecated `genome` with root `assembly`. Use `genomes` and `assembly`."
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (rootConfig.genome) {
|
|
36
|
+
const { name, ...config } = rootConfig.genome;
|
|
37
|
+
return {
|
|
38
|
+
genomesByName: new Map([[name, config]]),
|
|
39
|
+
defaultAssembly: name,
|
|
40
|
+
deprecationWarning: getLegacyGenomeWarning(),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** @type {Map<string, NamedGenomeDefinition>} */
|
|
45
|
+
const genomesByName = new Map();
|
|
46
|
+
for (const [name, config] of Object.entries(rootConfig.genomes ?? {})) {
|
|
47
|
+
genomesByName.set(name, config ?? {});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let defaultAssembly = rootConfig.assembly;
|
|
51
|
+
if (!defaultAssembly && genomesByName.size === 1) {
|
|
52
|
+
defaultAssembly = genomesByName.keys().next().value;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (
|
|
56
|
+
defaultAssembly &&
|
|
57
|
+
!genomesByName.has(defaultAssembly) &&
|
|
58
|
+
!isBuiltInAssembly(defaultAssembly)
|
|
59
|
+
) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
`Root assembly "${defaultAssembly}" is neither defined in \`genomes\` nor a built-in assembly.`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
genomesByName,
|
|
67
|
+
defaultAssembly,
|
|
68
|
+
deprecationWarning: undefined,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @returns {string}
|
|
74
|
+
*/
|
|
75
|
+
function getLegacyGenomeWarning() {
|
|
76
|
+
return (
|
|
77
|
+
"Root `genome` is deprecated and will be removed in a future version. " +
|
|
78
|
+
"Use root `genomes` and `assembly` instead. Built-in migration example: " +
|
|
79
|
+
'{"genome":{"name":"hg38"}} -> {"assembly":"hg38"}.'
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param {string} name
|
|
85
|
+
* @returns {boolean}
|
|
86
|
+
*/
|
|
87
|
+
function isBuiltInAssembly(name) {
|
|
88
|
+
try {
|
|
89
|
+
getContigs(name);
|
|
90
|
+
return true;
|
|
91
|
+
} catch (_error) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -25,7 +25,7 @@ export default class InteractionController {
|
|
|
25
25
|
datum: import("../data/flowNode.js").Datum;
|
|
26
26
|
uniqueId: number;
|
|
27
27
|
};
|
|
28
|
-
|
|
28
|
+
registerInteractionEvents(): void;
|
|
29
29
|
/**
|
|
30
30
|
* This method should be called in a mouseMove handler. If not called, the
|
|
31
31
|
* tooltip will be hidden.
|
|
@@ -37,4 +37,8 @@ export default class InteractionController {
|
|
|
37
37
|
updateTooltip<T>(datum: T, converter?: (arg0: T) => Promise<string | HTMLElement | import("lit").TemplateResult>): void;
|
|
38
38
|
#private;
|
|
39
39
|
}
|
|
40
|
+
export type ClientPointLike = {
|
|
41
|
+
clientX: number;
|
|
42
|
+
clientY: number;
|
|
43
|
+
};
|
|
40
44
|
//# sourceMappingURL=interactionController.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactionController.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/interactionController.js"],"names":[],"mappings":"AASA;IA2BI;;;;;;;;;;OAUG;IACH,mIATG;QAAmD,QAAQ,EAAnD,OAAO,iBAAiB,EAAE,OAAO;QACe,QAAQ,EAAxD,OAAO,sBAAsB,EAAE,OAAO;QACY,OAAO,EAAzD,OAAO,wBAAwB,EAAE,OAAO;QACQ,QAAQ,EAAxD,OAAO,sBAAsB,EAAE,OAAO;QACM,SAAS,EAArD,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI;QAC6C,eAAe,EAA9F,MAAM,CAAC,MAAM,EAAE,OAAO,8BAA8B,EAAE,cAAc,CAAC;QACjD,wBAAwB,EAA5C,MAAM,IAAI;QACY,mBAAmB,EAAzC,MAAM,MAAM;KACtB,EAgCA;IAED;cArDkB,OAAO,kBAAkB,EAAE,OAAO;eAAS,OAAO,qBAAqB,EAAE,KAAK;kBAAY,MAAM;MAuDjH;IAED,
|
|
1
|
+
{"version":3,"file":"interactionController.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/interactionController.js"],"names":[],"mappings":"AASA;IA2BI;;;;;;;;;;OAUG;IACH,mIATG;QAAmD,QAAQ,EAAnD,OAAO,iBAAiB,EAAE,OAAO;QACe,QAAQ,EAAxD,OAAO,sBAAsB,EAAE,OAAO;QACY,OAAO,EAAzD,OAAO,wBAAwB,EAAE,OAAO;QACQ,QAAQ,EAAxD,OAAO,sBAAsB,EAAE,OAAO;QACM,SAAS,EAArD,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI;QAC6C,eAAe,EAA9F,MAAM,CAAC,MAAM,EAAE,OAAO,8BAA8B,EAAE,cAAc,CAAC;QACjD,wBAAwB,EAA5C,MAAM,IAAI;QACY,mBAAmB,EAAzC,MAAM,MAAM;KACtB,EAgCA;IAED;cArDkB,OAAO,kBAAkB,EAAE,OAAO;eAAS,OAAO,qBAAqB,EAAE,KAAK;kBAAY,MAAM;MAuDjH;IAED,kCAwXC;IAkFD;;;;;;;OAOG;IACH,cAFa,CAAC,SAFH,CAAC,cACD,CAAS,IAAC,EAAD,CAAC,KAAE,OAAO,CAAC,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAYlF;;CACJ;8BAGY;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC"}
|