@genome-spy/core 0.76.0 → 0.78.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/dist/bundle/browser-KWU9rWZT.js +123 -0
  3. package/dist/bundle/esm-CT3ygiMq.js +1084 -0
  4. package/dist/bundle/{esm-D_euN86T.js → esm-DAnOffpD.js} +2 -2
  5. package/dist/bundle/{esm-BimDEpBb.js → esm-DNtC3H80.js} +2 -2
  6. package/dist/bundle/{esm-CngqBe45.js → esm-DVOHLB1e.js} +2 -2
  7. package/dist/bundle/esm-NIYEaYkc.js +1221 -0
  8. package/dist/bundle/index.es.js +3007 -2787
  9. package/dist/bundle/index.js +110 -99
  10. package/dist/schema.json +825 -112
  11. package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
  12. package/dist/src/data/sources/lazy/bigWigSource.js +31 -11
  13. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts +19 -3
  14. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
  15. package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +34 -13
  16. package/dist/src/data/transforms/filterScoredLabels.d.ts.map +1 -1
  17. package/dist/src/data/transforms/filterScoredLabels.js +3 -2
  18. package/dist/src/embedFactory.d.ts.map +1 -1
  19. package/dist/src/embedFactory.js +2 -0
  20. package/dist/src/genomeSpy/headlessBootstrap.d.ts.map +1 -1
  21. package/dist/src/genomeSpy/headlessBootstrap.js +2 -0
  22. package/dist/src/genomeSpy/interactionController.d.ts +4 -1
  23. package/dist/src/genomeSpy/interactionController.d.ts.map +1 -1
  24. package/dist/src/genomeSpy/interactionController.js +57 -13
  25. package/dist/src/genomeSpy/viewContextFactory.d.ts.map +1 -1
  26. package/dist/src/genomeSpy/viewContextFactory.js +1 -0
  27. package/dist/src/genomeSpyBase.d.ts +6 -0
  28. package/dist/src/genomeSpyBase.d.ts.map +1 -1
  29. package/dist/src/genomeSpyBase.js +16 -1
  30. package/dist/src/index.d.ts +1 -0
  31. package/dist/src/index.d.ts.map +1 -1
  32. package/dist/src/index.js +1 -0
  33. package/dist/src/marks/__snapshots__/shaderSnapshot.test.js.snap +2 -2
  34. package/dist/src/marks/mark.d.ts.map +1 -1
  35. package/dist/src/marks/mark.js +0 -6
  36. package/dist/src/marks/rect.vertex.glsl.js +1 -1
  37. package/dist/src/minimal.d.ts +1 -0
  38. package/dist/src/minimal.d.ts.map +1 -1
  39. package/dist/src/minimal.js +1 -0
  40. package/dist/src/paramRuntime/embedParamApi.d.ts +26 -0
  41. package/dist/src/paramRuntime/embedParamApi.d.ts.map +1 -0
  42. package/dist/src/paramRuntime/embedParamApi.js +133 -0
  43. package/dist/src/scales/domainExpressions.d.ts +21 -0
  44. package/dist/src/scales/domainExpressions.d.ts.map +1 -0
  45. package/dist/src/scales/domainExpressions.js +43 -0
  46. package/dist/src/scales/domainPlanner.d.ts +12 -1
  47. package/dist/src/scales/domainPlanner.d.ts.map +1 -1
  48. package/dist/src/scales/domainPlanner.js +55 -36
  49. package/dist/src/scales/scaleInstanceManager.d.ts +1 -0
  50. package/dist/src/scales/scaleInstanceManager.d.ts.map +1 -1
  51. package/dist/src/scales/scaleInstanceManager.js +5 -0
  52. package/dist/src/scales/scaleInteractionController.d.ts +8 -4
  53. package/dist/src/scales/scaleInteractionController.d.ts.map +1 -1
  54. package/dist/src/scales/scaleInteractionController.js +55 -7
  55. package/dist/src/scales/scalePropsResolver.d.ts +6 -1
  56. package/dist/src/scales/scalePropsResolver.d.ts.map +1 -1
  57. package/dist/src/scales/scalePropsResolver.js +35 -10
  58. package/dist/src/scales/scaleResolution.d.ts +19 -3
  59. package/dist/src/scales/scaleResolution.d.ts.map +1 -1
  60. package/dist/src/scales/scaleResolution.js +141 -20
  61. package/dist/src/scales/scaleRules.d.ts +10 -0
  62. package/dist/src/scales/scaleRules.d.ts.map +1 -1
  63. package/dist/src/scales/scaleRules.js +38 -1
  64. package/dist/src/scales/viewLevelScaleConfig.d.ts +45 -0
  65. package/dist/src/scales/viewLevelScaleConfig.d.ts.map +1 -0
  66. package/dist/src/scales/viewLevelScaleConfig.js +138 -0
  67. package/dist/src/selection/index.d.ts +8 -0
  68. package/dist/src/selection/index.d.ts.map +1 -0
  69. package/dist/src/selection/index.js +12 -0
  70. package/dist/src/spec/scale.d.ts +19 -6
  71. package/dist/src/spec/view.d.ts +11 -0
  72. package/dist/src/styles/genome-spy.css +12 -1
  73. package/dist/src/styles/genome-spy.css.d.ts +1 -1
  74. package/dist/src/styles/genome-spy.css.d.ts.map +1 -1
  75. package/dist/src/styles/genome-spy.css.js +12 -1
  76. package/dist/src/types/embedApi.d.ts +54 -0
  77. package/dist/src/types/scaleResolutionApi.d.ts +28 -1
  78. package/dist/src/types/viewContext.d.ts +11 -0
  79. package/dist/src/utils/ui/tooltip.d.ts +4 -0
  80. package/dist/src/utils/ui/tooltip.d.ts.map +1 -1
  81. package/dist/src/utils/ui/tooltip.js +57 -10
  82. package/dist/src/view/containerMutationHelper.d.ts.map +1 -1
  83. package/dist/src/view/containerMutationHelper.js +11 -3
  84. package/package.json +3 -3
  85. package/dist/bundle/browser-BTgw5ieH.js +0 -126
  86. package/dist/bundle/esm-Bvlm1uVk.js +0 -1015
  87. package/dist/bundle/esm-C49STiCR.js +0 -1248
@@ -1 +1 @@
1
- {"version":3,"file":"bigWigSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/bigWigSource.js"],"names":[],"mappings":"AAQA;;GAEG;AACH;IAOI;;;OAGG;IACH,oBAHW,OAAO,uBAAuB,EAAE,UAAU,QAC1C,OAAO,uBAAuB,EAAE,OAAO,EAoCjD;IArBG,mDAYC;IA+DL;;;;OAIG;IACH,wBAFW,MAAM,EAAE,iBAqBlB;IAED;;;OAGG;IAEH,uBAJW,MAAM,EAAE,kBACR,MAAM,iBA2BhB;;CACJ;qCAhKoC,+BAA+B"}
1
+ {"version":3,"file":"bigWigSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/bigWigSource.js"],"names":[],"mappings":"AAQA;;GAEG;AACH;IAOI;;;OAGG;IACH,oBAHW,OAAO,uBAAuB,EAAE,UAAU,QAC1C,OAAO,uBAAuB,EAAE,OAAO,EAoCjD;IArBG,mDAYC;IA+DL;;;;OAIG;IACH,wBAFW,MAAM,EAAE,iBAqBlB;IAED;;;OAGG;IAEH,uBAJW,MAAM,EAAE,kBACR,MAAM,iBAkChB;;CACJ;qCAvKoC,+BAA+B"}
@@ -142,23 +142,30 @@ export default class BigWigSource extends SingleAxisWindowedSource {
142
142
  async loadInterval(interval, reductionLevel) {
143
143
  const scale =
144
144
  1 / 2 / reductionLevel / withoutExprRef(this.params.pixelsPerBin);
145
- const featureChunks = await this.discretizeAndLoad(
146
- interval,
147
- (d, signal) =>
145
+ const featureChunks = await this.discretizeAndLoad(interval, {
146
+ load: (d, signal) =>
148
147
  this.#bbi
149
148
  .getFeatures(d.chrom, d.startPos, d.endPos, {
150
149
  scale,
151
150
  signal,
152
151
  })
153
- .then((features) =>
154
- features.map((f) => ({
155
- chrom: d.chrom,
156
- start: f.start,
157
- end: f.end,
158
- score: f.score,
159
- }))
152
+ .then((features) => mapFeatures(d.chrom, features)),
153
+ loadBatch: (intervals, signal) =>
154
+ this.#bbi
155
+ .getFeaturesMulti(
156
+ intervals.map((d) => ({
157
+ refName: d.chrom,
158
+ start: d.startPos,
159
+ end: d.endPos,
160
+ })),
161
+ { scale, signal }
160
162
  )
161
- );
163
+ .then((featureChunks) =>
164
+ featureChunks.map((features, i) =>
165
+ mapFeatures(intervals[i].chrom, features)
166
+ )
167
+ ),
168
+ });
162
169
 
163
170
  if (featureChunks) {
164
171
  this.publishData(featureChunks);
@@ -176,6 +183,19 @@ function isBigWigSource(params) {
176
183
 
177
184
  registerBuiltInLazyDataSource(isBigWigSource, BigWigSource);
178
185
 
186
+ /**
187
+ * @param {string} chrom
188
+ * @param {import("@gmod/bbi").Feature[]} features
189
+ */
190
+ function mapFeatures(chrom, features) {
191
+ return features.map((f) => ({
192
+ chrom,
193
+ start: f.start,
194
+ end: f.end,
195
+ score: f.score,
196
+ }));
197
+ }
198
+
179
199
  /**
180
200
  * @param {number[]} domain
181
201
  * @param {number} widthInPixels view width in pixels
@@ -1,3 +1,13 @@
1
+ /**
2
+ * @template T
3
+ * @typedef {(discreteInterval: import("@genome-spy/core/genome/genome.js").DiscreteChromosomeInterval, signal: AbortSignal) => Promise<T>} DiscreteIntervalLoader
4
+ */
5
+ /**
6
+ * @template T
7
+ * @typedef {object} DiscreteIntervalLoaders
8
+ * @prop {DiscreteIntervalLoader<T>} load
9
+ * @prop {(discreteIntervals: import("@genome-spy/core/genome/genome.js").DiscreteChromosomeInterval[], signal: AbortSignal) => Promise<T[]>} [loadBatch]
10
+ */
1
11
  /**
2
12
  * Divides the domain into windows and loads the data for one or two consecutive windows
3
13
  * that cover the visible interval.
@@ -36,15 +46,16 @@ export default class SingleAxisWindowedSource extends SingleAxisLazySource {
36
46
  protected reloadLastDomain(): void;
37
47
  /**
38
48
  * Splits the interval into discrete chromosomal intervals – one for each chromosome –
39
- * and loads the data for each of them. Handles abort signals and errors.
49
+ * and loads the data using a batched loader when available. Handles abort signals
50
+ * and errors.
40
51
  *
41
52
  * @param {number[]} interval
42
- * @param {(discreteInteval: import("@genome-spy/core/genome/genome.js").DiscreteChromosomeInterval, signal: AbortSignal) => Promise<T>} loader
53
+ * @param {DiscreteIntervalLoader<T> | DiscreteIntervalLoaders<T>} loader
43
54
  * @return {Promise<T[]>}
44
55
  * @template T
45
56
  * @protected
46
57
  */
47
- protected discretizeAndLoad<T>(interval: number[], loader: (discreteInteval: import("@genome-spy/core/genome/genome.js").DiscreteChromosomeInterval, signal: AbortSignal) => Promise<T>): Promise<T[]>;
58
+ protected discretizeAndLoad<T>(interval: number[], loader: DiscreteIntervalLoader<T> | DiscreteIntervalLoaders<T>): Promise<T[]>;
48
59
  /**
49
60
  *
50
61
  * @param {number[]} interval Domain
@@ -55,5 +66,10 @@ export default class SingleAxisWindowedSource extends SingleAxisLazySource {
55
66
  protected callIfWindowsChanged(interval: number[], windowSize: number, callback: (arg0: number[]) => void): void;
56
67
  #private;
57
68
  }
69
+ export type DiscreteIntervalLoader<T> = (discreteInterval: import("@genome-spy/core/genome/genome.js").DiscreteChromosomeInterval, signal: AbortSignal) => Promise<T>;
70
+ export type DiscreteIntervalLoaders<T> = {
71
+ load: DiscreteIntervalLoader<T>;
72
+ loadBatch?: (discreteIntervals: import("@genome-spy/core/genome/genome.js").DiscreteChromosomeInterval[], signal: AbortSignal) => Promise<T[]>;
73
+ };
58
74
  import SingleAxisLazySource from "./singleAxisLazySource.js";
59
75
  //# sourceMappingURL=singleAxisWindowedSource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"singleAxisWindowedSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/singleAxisWindowedSource.js"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH;IAWI;;;OAGG;IACH,kBAHU;QAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,4BAA4B,EAAE,OAAO,CAAA;KAAC,CAGvE;IAEP;;;OAGG;IACH,0CAHW,OAAO,uBAAuB,EAAE,aAAa,QAqBvD;IAED;;;;OAIG;IACH,wBAFW,MAAM,EAAE,QAqBlB;IAeD;;;;;OAKG;IACH,iCAHW,MAAM,EAAE,iBAKlB;IArBD;;OAEG;IACH,mCAQC;IAyBD;;;;;;;;;OASG;IACH,4BAHa,CAAC,YAHH,MAAM,EAAE,UACR,CAAC,eAAe,EAAE,OAAO,mCAAmC,EAAE,0BAA0B,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3H,OAAO,CAAC,CAAC,EAAE,CAAC,CAyCvB;IAED;;;;;;OAMG;IACH,yCALW,MAAM,EAAE,cACR,MAAM,YACN,CAAS,IAAQ,EAAR,MAAM,EAAE,KAAE,IAAI,QAyBjC;;CACJ;iCA9LgC,2BAA2B"}
1
+ {"version":3,"file":"singleAxisWindowedSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/singleAxisWindowedSource.js"],"names":[],"mappings":"AAIA;;;GAGG;AAEH;;;;;GAKG;AAEH;;;;;GAKG;AACH;IAWI;;;OAGG;IACH,kBAHU;QAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,4BAA4B,EAAE,OAAO,CAAA;KAAC,CAGvE;IAEP;;;OAGG;IACH,0CAHW,OAAO,uBAAuB,EAAE,aAAa,QAqBvD;IAED;;;;OAIG;IACH,wBAFW,MAAM,EAAE,QAqBlB;IAeD;;;;;OAKG;IACH,iCAHW,MAAM,EAAE,iBAKlB;IArBD;;OAEG;IACH,mCAQC;IAyBD;;;;;;;;;;OAUG;IACH,4BAHa,CAAC,YAHH,MAAM,EAAE,UACR,sBAAsB,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,CAAC,CAAC,GACrD,OAAO,CAAC,CAAC,EAAE,CAAC,CAiDvB;IAED;;;;;;OAMG;IACH,yCALW,MAAM,EAAE,cACR,MAAM,YACN,CAAS,IAAQ,EAAR,MAAM,EAAE,KAAE,IAAI,QAyBjC;;CACJ;mCAhNY,CAAC,IACD,CAAC,gBAAgB,EAAE,OAAO,mCAAmC,EAAE,0BAA0B,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC;oCAI7H,CAAC;UAEJ,sBAAsB,CAAC,CAAC,CAAC;gBACzB,CAAC,iBAAiB,EAAE,OAAO,mCAAmC,EAAE,0BAA0B,EAAE,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC;;iCAX3G,2BAA2B"}
@@ -2,6 +2,18 @@ import { withoutExprRef } from "../../../paramRuntime/paramUtils.js";
2
2
  import { debounce } from "../../../utils/debounce.js";
3
3
  import SingleAxisLazySource from "./singleAxisLazySource.js";
4
4
 
5
+ /**
6
+ * @template T
7
+ * @typedef {(discreteInterval: import("@genome-spy/core/genome/genome.js").DiscreteChromosomeInterval, signal: AbortSignal) => Promise<T>} DiscreteIntervalLoader
8
+ */
9
+
10
+ /**
11
+ * @template T
12
+ * @typedef {object} DiscreteIntervalLoaders
13
+ * @prop {DiscreteIntervalLoader<T>} load
14
+ * @prop {(discreteIntervals: import("@genome-spy/core/genome/genome.js").DiscreteChromosomeInterval[], signal: AbortSignal) => Promise<T[]>} [loadBatch]
15
+ */
16
+
5
17
  /**
6
18
  * Divides the domain into windows and loads the data for one or two consecutive windows
7
19
  * that cover the visible interval.
@@ -113,10 +125,11 @@ export default class SingleAxisWindowedSource extends SingleAxisLazySource {
113
125
 
114
126
  /**
115
127
  * Splits the interval into discrete chromosomal intervals – one for each chromosome –
116
- * and loads the data for each of them. Handles abort signals and errors.
128
+ * and loads the data using a batched loader when available. Handles abort signals
129
+ * and errors.
117
130
  *
118
131
  * @param {number[]} interval
119
- * @param {(discreteInteval: import("@genome-spy/core/genome/genome.js").DiscreteChromosomeInterval, signal: AbortSignal) => Promise<T>} loader
132
+ * @param {DiscreteIntervalLoader<T> | DiscreteIntervalLoaders<T>} loader
120
133
  * @return {Promise<T[]>}
121
134
  * @template T
122
135
  * @protected
@@ -130,21 +143,29 @@ export default class SingleAxisWindowedSource extends SingleAxisLazySource {
130
143
  this.#abortController = new AbortController();
131
144
  const signal = this.#abortController.signal;
132
145
 
133
- // GMOD libraries expect a single chromosome/sequence for each request.
134
- // Thus, we split the interval into discrete intervals representing
135
- // individual chromosomes and load the data for each of them separately
136
- // but in parallel.
146
+ // Lazy sources load data using chromosome coordinates. The continuous
147
+ // scale domain must be split before it can be passed to the source.
137
148
  const discreteChromosomeIntervals =
138
149
  this.genome.continuousToDiscreteChromosomeIntervals(interval);
139
150
 
151
+ const loaders = typeof loader == "function" ? { load: loader } : loader;
152
+
140
153
  try {
141
- const resultByChrom = await Promise.all(
142
- discreteChromosomeIntervals.map(
143
- async (
144
- /** @type {import("@genome-spy/core/genome/genome.js").DiscreteChromosomeInterval} */ d
145
- ) => loader(d, signal)
146
- )
147
- );
154
+ const resultByChrom = loaders.loadBatch
155
+ ? await loaders.loadBatch(discreteChromosomeIntervals, signal)
156
+ : await Promise.all(
157
+ discreteChromosomeIntervals.map(
158
+ async (
159
+ /** @type {import("@genome-spy/core/genome/genome.js").DiscreteChromosomeInterval} */ d
160
+ ) => loaders.load(d, signal)
161
+ )
162
+ );
163
+
164
+ if (resultByChrom.length !== discreteChromosomeIntervals.length) {
165
+ throw new Error(
166
+ "Batched lazy loader must return one chunk per interval."
167
+ );
168
+ }
148
169
 
149
170
  if (!signal.aborted) {
150
171
  this.setLoadingStatus("complete");
@@ -1 +1 @@
1
- {"version":3,"file":"filterScoredLabels.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/filterScoredLabels.js"],"names":[],"mappings":"AAOA;IAcI;;;;OAIG;IACH,oBAHW,OAAO,yBAAyB,EAAE,wBAAwB,QAC1D,OAAO,oBAAoB,EAAE,OAAO,EAkD9C;IA9DD;;;;OAIG;IACH,kDAEC;IAUG,mEAAoB;IAEpB,oBAAoB;IACpB,OADW,GAAG,EAAE,CACD;IAEf,mBAAoC;IAMpC,sDAA8C;IAC9C,oDAAgE;IAChE,wDAAuD;IACvD,sDAAmD;IACnD,mDAA6C;IAC7C,mDAA6C;IAC7C,gCAAgC;IAChC,cADW,CAAS,IAAG,EAAH,GAAG,KAAE,GAAG,CAGd;IACd,gBAAuC;IAEvC,uCAAuC;IACvC,iBADW,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CACH;IAEhC,8DAAuD;IAIvD,qBAAuE;IA8B3E,4BAsEC;IAKG,sBAAuB;CAU9B;sBAzKqB,gBAAgB;2BAFX,+BAA+B"}
1
+ {"version":3,"file":"filterScoredLabels.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/filterScoredLabels.js"],"names":[],"mappings":"AAOA;IAcI;;;;OAIG;IACH,oBAHW,OAAO,yBAAyB,EAAE,wBAAwB,QAC1D,OAAO,oBAAoB,EAAE,OAAO,EAmD9C;IA/DD;;;;OAIG;IACH,kDAEC;IAUG,mEAAoB;IAEpB,oBAAoB;IACpB,OADW,GAAG,EAAE,CACD;IAEf,mBAAoC;IAMpC,sDAA8C;IAC9C,oDAAgE;IAChE,wDAAuD;IACvD,sDAAmD;IACnD,mDAA6C;IAC7C,mDAA6C;IAC7C,gCAAgC;IAChC,cADW,CAAS,IAAG,EAAH,GAAG,KAAE,GAAG,CAGd;IACd,gBAAuC;IAEvC,uCAAuC;IACvC,iBADW,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CACH;IAEhC,8DAAuD;IAIvD,qBAAuE;IA+B3E,4BAsEC;IAKG,sBAAuB;CAU9B;sBA1KqB,gBAAgB;2BAFX,+BAA+B"}
@@ -59,8 +59,9 @@ export default class FilterScoredLabelsTransform extends Transform {
59
59
  const callback = () => this._filterAndPropagate();
60
60
  this.schedule = () => view.context.animator.requestTransition(callback);
61
61
 
62
- // Propagate when the domain changes
63
- const domainListener = () => this.schedule();
62
+ // Propagate immediately when the domain changes so inertial zoom frames
63
+ // render with labels computed for the current scale domain.
64
+ const domainListener = () => this._filterAndPropagate();
64
65
  this.resolution.addEventListener("domain", domainListener);
65
66
  this.registerDisposer(() =>
66
67
  this.resolution.removeEventListener("domain", domainListener)
@@ -1 +1 @@
1
- {"version":3,"file":"embedFactory.d.ts","sourceRoot":"","sources":["../../src/embedFactory.js"],"names":[],"mappings":"AAKA;;;GAGG;AACH,uCAHW,KAAK,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,gBAAgB,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,OAAO,qBAAqB,EAAE,YAAY,KAAK,OAAO,gBAAgB,EAAE,OAAO,GAC7J,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,gBAAgB,EAAE,QAAQ,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,qBAAqB,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,qBAAqB,EAAE,WAAW,CAAC,CAmFpM;AAaD;;;;;GAKG;AACH,8BAFW,MAAM,gBAmBhB"}
1
+ {"version":3,"file":"embedFactory.d.ts","sourceRoot":"","sources":["../../src/embedFactory.js"],"names":[],"mappings":"AAKA;;;GAGG;AACH,uCAHW,KAAK,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,gBAAgB,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,OAAO,qBAAqB,EAAE,YAAY,KAAK,OAAO,gBAAgB,EAAE,OAAO,GAC7J,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,gBAAgB,EAAE,QAAQ,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,qBAAqB,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,qBAAqB,EAAE,WAAW,CAAC,CAqFpM;AAaD;;;;;GAKG;AACH,8BAFW,MAAM,gBAmBhB"}
@@ -79,6 +79,8 @@ export function createEmbed(GenomeSpy) {
79
79
  return genomeSpy.getNamedScaleResolutions().get(name);
80
80
  },
81
81
 
82
+ getParam: genomeSpy.getParam.bind(genomeSpy),
83
+
82
84
  awaitVisibleLazyData:
83
85
  genomeSpy.awaitVisibleLazyData.bind(genomeSpy),
84
86
  getRenderedBounds: genomeSpy.getRenderedBounds.bind(genomeSpy),
@@ -1 +1 @@
1
- {"version":3,"file":"headlessBootstrap.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/headlessBootstrap.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"headlessBootstrap.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/headlessBootstrap.js"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ import { resolveBaseConfig } from "../config/resolveConfig.js";
14
14
  import { createViewContext } from "./viewContextFactory.js";
15
15
  import { ViewFactory, VIEW_ROOT_NAME } from "../view/viewFactory.js";
16
16
  import { ensureAssembliesForView } from "../genome/assemblyPreflight.js";
17
+ import { attachViewLevelScaleConfigs } from "../scales/viewLevelScaleConfig.js";
17
18
  import {
18
19
  configureViewHierarchy,
19
20
  configureViewOpacity,
@@ -196,6 +197,7 @@ export async function createHeadlessEngine(spec, options = {}) {
196
197
  VIEW_ROOT_NAME
197
198
  );
198
199
 
200
+ attachViewLevelScaleConfigs(view);
199
201
  await ensureAssembliesForView(view, context.genomeStore);
200
202
  prepareViewHierarchy(view);
201
203
 
@@ -30,7 +30,10 @@ export default class InteractionController {
30
30
  * @param {MouseEvent} [mouseEvent]
31
31
  */
32
32
  resumeHoverTracking(mouseEvent?: MouseEvent): void;
33
- registerInteractionEvents(): void;
33
+ /**
34
+ * @returns {() => void}
35
+ */
36
+ registerInteractionEvents(): () => void;
34
37
  /**
35
38
  * This method should be called in a mouseMove handler. If not called, the
36
39
  * tooltip will be hidden.
@@ -1 +1 @@
1
- {"version":3,"file":"interactionController.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/interactionController.js"],"names":[],"mappings":"AAWA;IAoCI;;;;;;;;;;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,EAiCA;IAED;cA3DkB,OAAO,kBAAkB,EAAE,OAAO;eAAS,OAAO,qBAAqB,EAAE,KAAK;kBAAY,MAAM;MA6DjH;IAED,6BAQC;IAED;;OAEG;IACH,iCAFW,UAAU,QA8CpB;IAED,kCAycC;IA+JD;;;;;;;OAOG;IACH,cAFa,CAAC,SAFH,CAAC,cACD,CAAS,IAAC,EAAD,CAAC,KAAE,OAAO,CAAC,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAgBlF;;CACJ;8BAGY;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC"}
1
+ {"version":3,"file":"interactionController.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/interactionController.js"],"names":[],"mappings":"AAWA;IA2CI;;;;;;;;;;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,EAiCA;IAED;cAlEkB,OAAO,kBAAkB,EAAE,OAAO;eAAS,OAAO,qBAAqB,EAAE,KAAK;kBAAY,MAAM;MAoEjH;IAED,6BAQC;IAED;;OAEG;IACH,iCAFW,UAAU,QA8CpB;IAED;;OAEG;IACH,6BAFa,MAAM,IAAI,CA6etB;IA+JD;;;;;;;OAOG;IACH,cAFa,CAAC,SAFH,CAAC,cACD,CAAS,IAAC,EAAD,CAAC,KAAE,OAAO,CAAC,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAgBlF;;CACJ;8BAGY;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC"}
@@ -45,6 +45,13 @@ export default class InteractionController {
45
45
  #suppressTooltipUntilMouseMove = false;
46
46
  #hoverTrackingSuspensionCount = 0;
47
47
  #postRenderHoverRefreshRequested = false;
48
+
49
+ #dismissStickyTooltip() {
50
+ this.#tooltip.sticky = false;
51
+ this.#suppressTooltipUntilMouseMove = true;
52
+ this.#tooltip.clear();
53
+ }
54
+
48
55
  /**
49
56
  * @param {object} options
50
57
  * @param {import("../view/view.js").default} options.viewRoot
@@ -153,14 +160,49 @@ export default class InteractionController {
153
160
  this.#cursorManager.clear();
154
161
  }
155
162
 
163
+ /**
164
+ * @returns {() => void}
165
+ */
156
166
  registerInteractionEvents() {
157
167
  const canvas = this.#glHelper.canvas;
168
+ /** @type {Array<() => void>} */
169
+ const removers = [];
170
+
171
+ /**
172
+ * @param {EventTarget} target
173
+ * @param {string} type
174
+ * @param {EventListener} listener
175
+ * @param {AddEventListenerOptions} [options]
176
+ */
177
+ const addListener = (target, type, listener, options) => {
178
+ target.addEventListener(type, listener, options);
179
+ removers.push(() =>
180
+ target.removeEventListener(type, listener, options)
181
+ );
182
+ };
158
183
 
159
184
  let lastWheelEvent = performance.now();
160
185
  let longPressTriggered = false;
161
186
  /** @type {{ pointerCount: 1 | 2, centerX: number, centerY: number, distance: number } | undefined} */
162
187
  let previousTouchGesture;
163
188
 
189
+ if (globalThis.document?.addEventListener) {
190
+ addListener(
191
+ document,
192
+ "mousedown",
193
+ (/** @type {MouseEvent} */ event) => {
194
+ if (
195
+ this.#tooltip.sticky &&
196
+ !event.composedPath().includes(canvas) &&
197
+ !this.#tooltip.containsEvent(event)
198
+ ) {
199
+ this.#dismissStickyTooltip();
200
+ }
201
+ },
202
+ { capture: true }
203
+ );
204
+ }
205
+
164
206
  /**
165
207
  * @param {Point} point
166
208
  * @param {import("../utils/interactionEvent.js").InteractionUiEvent} uiEvent
@@ -343,15 +385,13 @@ export default class InteractionController {
343
385
  }
344
386
  };
345
387
 
346
- canvas.addEventListener("mousedown", (/** @type {MouseEvent} */ e) => {
388
+ addListener(canvas, "mousedown", (/** @type {MouseEvent} */ e) => {
347
389
  this.#mouseDownCoords = Point.fromMouseEvent(e);
348
390
  this.#longPressPending = false;
349
391
  const hasModifier = e.shiftKey || e.ctrlKey || e.metaKey;
350
392
 
351
393
  if (this.#tooltip.sticky) {
352
- this.#tooltip.sticky = false;
353
- this.#suppressTooltipUntilMouseMove = true;
354
- this.#tooltip.clear();
394
+ this.#dismissStickyTooltip();
355
395
  // Dismiss the sticky tooltip before routing the press so the
356
396
  // click only affects the tooltip state.
357
397
  longPressTriggered = true;
@@ -427,7 +467,7 @@ export default class InteractionController {
427
467
  "mousemove",
428
468
  "contextmenu",
429
469
  "dblclick",
430
- ].forEach((type) => canvas.addEventListener(type, listener));
470
+ ].forEach((type) => addListener(canvas, type, listener));
431
471
 
432
472
  /**
433
473
  * @param {number} clientX
@@ -574,25 +614,23 @@ export default class InteractionController {
574
614
  previousTouchGesture = readTouchGesture(touchEvent.touches);
575
615
  };
576
616
 
577
- canvas.addEventListener("touchstart", handleTouchStartOrMove, {
617
+ addListener(canvas, "touchstart", handleTouchStartOrMove, {
578
618
  passive: false,
579
619
  });
580
- canvas.addEventListener("touchmove", handleTouchStartOrMove, {
620
+ addListener(canvas, "touchmove", handleTouchStartOrMove, {
581
621
  passive: false,
582
622
  });
583
- canvas.addEventListener("touchend", handleTouchEndOrCancel, {
623
+ addListener(canvas, "touchend", handleTouchEndOrCancel, {
584
624
  passive: false,
585
625
  });
586
- canvas.addEventListener("touchcancel", handleTouchEndOrCancel, {
626
+ addListener(canvas, "touchcancel", handleTouchEndOrCancel, {
587
627
  passive: false,
588
628
  });
589
629
 
590
630
  // Prevent text selections etc while dragging
591
- canvas.addEventListener("dragstart", (event) =>
592
- event.stopPropagation()
593
- );
631
+ addListener(canvas, "dragstart", (event) => event.stopPropagation());
594
632
 
595
- canvas.addEventListener("mouseout", (event) => {
633
+ addListener(canvas, "mouseout", (event) => {
596
634
  if (this.#isInteractionFrozen()) {
597
635
  return;
598
636
  }
@@ -610,6 +648,12 @@ export default class InteractionController {
610
648
  this.#tooltip.clear();
611
649
  this.#currentHover = null;
612
650
  });
651
+
652
+ return () => {
653
+ for (const remove of removers) {
654
+ remove();
655
+ }
656
+ };
613
657
  }
614
658
 
615
659
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"viewContextFactory.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/viewContextFactory.js"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;GAUG;AACH,2CANW,OAAO,CAAC,WAAW,CAAC,GAAG;IAC7B,6BAA6B,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,iBAAiB,EAAE,QAAQ,GAAG,OAAO,iBAAiB,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,OAAO,0BAA0B,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,OAAO,iBAAiB,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,iBAAiB,EAAE,QAAQ,KAAK,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,yBAAyB,EAAE,iBAAiB,KAAK,OAAO,CAAC,OAAO,iBAAiB,EAAE,OAAO,CAAC,CAAA;IACrb,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B,GACS,WAAW,CAwEvB;0BApFY,OAAO,yBAAyB,EAAE,OAAO"}
1
+ {"version":3,"file":"viewContextFactory.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/viewContextFactory.js"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;GAUG;AACH,2CANW,OAAO,CAAC,WAAW,CAAC,GAAG;IAC7B,6BAA6B,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,iBAAiB,EAAE,QAAQ,GAAG,OAAO,iBAAiB,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,OAAO,0BAA0B,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,OAAO,iBAAiB,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,iBAAiB,EAAE,QAAQ,KAAK,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,yBAAyB,EAAE,iBAAiB,KAAK,OAAO,CAAC,OAAO,iBAAiB,EAAE,OAAO,CAAC,CAAA;IACrb,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B,GACS,WAAW,CAyEvB;0BArFY,OAAO,yBAAyB,EAAE,OAAO"}
@@ -60,6 +60,7 @@ export function createViewContext(options) {
60
60
  /** @type {(keyof ViewContext)[]} */
61
61
  const methodNames = [
62
62
  "requestLayoutReflow",
63
+ "renderImmediately",
63
64
  "updateTooltip",
64
65
  "getNamedDataFromProvider",
65
66
  "getCurrentHover",
@@ -53,6 +53,12 @@ export default class GenomeSpy {
53
53
  * @param {any[]} data
54
54
  */
55
55
  updateNamedData(name: string, data: any[]): void;
56
+ /**
57
+ * Returns a handle for a named parameter.
58
+ *
59
+ * @param {string} name
60
+ */
61
+ getParam(name: string): import("./types/embedApi.js").ParamApi<import("./types/embedApi.js").ParamValue>;
56
62
  /**
57
63
  * @param {string} type
58
64
  * @param {(event: any) => void} listener
@@ -1 +1 @@
1
- {"version":3,"file":"genomeSpyBase.d.ts","sourceRoot":"","sources":["../../src/genomeSpyBase.js"],"names":[],"mappings":"AA8CA;;;GAGG;AAEH;IAoBI;;;;;OAKG;IAEH;;;;;OAKG;IACH,uBAJW,WAAW,qDAEX,OAAO,qBAAqB,EAAE,YAAY,EA0CpD;IAvCG,uBAA0B;IAC1B,oDAAsB;IAItB,sCAAsC;IACtC,wCAAgB;IAEhB,yBAAoC;IAEpC,4CAA4C;IAC5C,oBADW,CAAC,CAAS,IAAM,EAAN,MAAM,KAAE,MAAM,EAAE,CAAC,EAAE,CACZ;IAE5B,mBAAoD;IAEpD,0BAA0B;IAC1B,aADW,WAAW,CACM;IAE5B;;;;;OAKG;IACH,yBAFU,CAAC,IAAI,qEAAM,KAAK,OAAO,CAE8B;IAE/D,oFAAoF;IACpF,iBADW,MAAM,CAAC,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC,CAK9E;IAED,mBAAmB;IACnB,8EAAyB;IAIzB,YAAkC;IAatC;;;OAGG;IACH,oCAFW,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,EAAE,QAIjC;IAED;;OAEG;IACH,+BAFW,MAAM,YAShB;IAED;;;;OAIG;IACH,sBAHW,MAAM,QACN,GAAG,EAAE,QAYf;IAED;;;OAGG;IACH,uBAHW,MAAM,YACN,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAI9B;IAED;;;OAGG;IACH,0BAHW,MAAM,YACN,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAI9B;IAED;;;;;OAKG;IACH,gBAHW,kBAAkB,YAClB,GAAG,QAMb;IAmEG,iDAAsB;IAQ1B;;OAEG;IACH,gBAqBC;IAyND;;;OAGG;IACH,UAFa,OAAO,CAAC,OAAO,CAAC,CAyC5B;IAED,2CAiBC;IAED;;;;;OAKG;IACH,8BAFW,WAAW,iBAerB;IAED;;;;;;;OAOG;IACH,cAFa,CAAC,SAFH,CAAC,cACD,CAAS,IAAC,EAAD,CAAC,KAAE,OAAO,CAAC,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAKlF;IAED;;;;;;;;OAQG;IACH,4BANW,MAAM,kBACN,MAAM,qBACN,MAAM,eACN,MAAM,UAuBhB;IAED;;;MAEC;IAED;eACwB,MAAM,GAAG,SAAS;gBAAU,MAAM,GAAG,SAAS;MAcrE;IAED,sBAGC;IAED,kBAEC;IAED,iCAEC;IAED,oEAYC;IAED,uFAWC;;CACJ;;;;iCA/oBY,eAAe,GAAG,QAAQ,GAAG,gBAAgB,GAAG,kBAAkB;4BAtBnC,uBAAuB;qBAP9C,qBAAqB;wBAElB,yBAAyB;qBAL5B,oBAAoB"}
1
+ {"version":3,"file":"genomeSpyBase.d.ts","sourceRoot":"","sources":["../../src/genomeSpyBase.js"],"names":[],"mappings":"AAgDA;;;GAGG;AAEH;IAoBI;;;;;OAKG;IAEH;;;;;OAKG;IACH,uBAJW,WAAW,qDAEX,OAAO,qBAAqB,EAAE,YAAY,EA0CpD;IAvCG,uBAA0B;IAC1B,oDAAsB;IAItB,sCAAsC;IACtC,wCAAgB;IAEhB,yBAAoC;IAEpC,4CAA4C;IAC5C,oBADW,CAAC,CAAS,IAAM,EAAN,MAAM,KAAE,MAAM,EAAE,CAAC,EAAE,CACZ;IAE5B,mBAAoD;IAEpD,0BAA0B;IAC1B,aADW,WAAW,CACM;IAE5B;;;;;OAKG;IACH,yBAFU,CAAC,IAAI,qEAAM,KAAK,OAAO,CAE8B;IAE/D,oFAAoF;IACpF,iBADW,MAAM,CAAC,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC,CAK9E;IAED,mBAAmB;IACnB,8EAAyB;IAIzB,YAAkC;IAatC;;;OAGG;IACH,oCAFW,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,EAAE,QAIjC;IAED;;OAEG;IACH,+BAFW,MAAM,YAShB;IAED;;;;OAIG;IACH,sBAHW,MAAM,QACN,GAAG,EAAE,QAYf;IAED;;;;OAIG;IACH,eAFW,MAAM,oFAIhB;IAED;;;OAGG;IACH,uBAHW,MAAM,YACN,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAI9B;IAED;;;OAGG;IACH,0BAHW,MAAM,YACN,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAI9B;IAED;;;;;OAKG;IACH,gBAHW,kBAAkB,YAClB,GAAG,QAMb;IAmEG,iDAAsB;IAQ1B;;OAEG;IACH,gBAqBC;IA2ND;;;OAGG;IACH,UAFa,OAAO,CAAC,OAAO,CAAC,CA2C5B;IAED,2CAiBC;IAED;;;;;OAKG;IACH,8BAFW,WAAW,iBAerB;IAED;;;;;;;OAOG;IACH,cAFa,CAAC,SAFH,CAAC,cACD,CAAS,IAAC,EAAD,CAAC,KAAE,OAAO,CAAC,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAKlF;IAED;;;;;;;;OAQG;IACH,4BANW,MAAM,kBACN,MAAM,qBACN,MAAM,eACN,MAAM,UAuBhB;IAED;;;MAEC;IAED;eACwB,MAAM,GAAG,SAAS;gBAAU,MAAM,GAAG,SAAS;MAcrE;IAED,sBAGC;IAED,kBAEC;IAED,iCAEC;IAED,oEAYC;IAED,uFAWC;;CACJ;;;;iCA5pBY,eAAe,GAAG,QAAQ,GAAG,gBAAgB,GAAG,kBAAkB;4BAxBnC,uBAAuB;qBAP9C,qBAAqB;wBAElB,yBAAyB;qBAL5B,oBAAoB"}
@@ -31,8 +31,10 @@ import { createViewContext } from "./genomeSpy/viewContextFactory.js";
31
31
  import { prepareViewHierarchy } from "./genomeSpy/headlessBootstrap.js";
32
32
  import { exportCanvas } from "./genomeSpy/canvasExport.js";
33
33
  import { validateSelectorConstraints } from "./view/viewSelectors.js";
34
+ import { resolveEmbedParam } from "./paramRuntime/embedParamApi.js";
34
35
  import SingleAxisWindowedSource from "./data/sources/lazy/singleAxisWindowedSource.js";
35
36
  import { ensureAssembliesForView } from "./genome/assemblyPreflight.js";
37
+ import { attachViewLevelScaleConfigs } from "./scales/viewLevelScaleConfig.js";
36
38
  import { resolveRootGenomeConfig } from "./genome/rootGenomeConfig.js";
37
39
  import { awaitSubtreeLazyReady } from "./view/dataReadiness.js";
38
40
  import { INTERNAL_DEFAULT_CONFIG } from "./config/defaultConfig.js";
@@ -171,6 +173,15 @@ export default class GenomeSpy {
171
173
  this.animator.requestRender();
172
174
  }
173
175
 
176
+ /**
177
+ * Returns a handle for a named parameter.
178
+ *
179
+ * @param {string} name
180
+ */
181
+ getParam(name) {
182
+ return resolveEmbedParam(this.viewRoot, name);
183
+ }
184
+
174
185
  /**
175
186
  * @param {string} type
176
187
  * @param {(event: any) => void} listener
@@ -360,6 +371,7 @@ export default class GenomeSpy {
360
371
  this.#extraBroadcastListeners.add(type, listener),
361
372
  removeBroadcastListener: (type, listener) =>
362
373
  this.#extraBroadcastListeners.remove(type, listener),
374
+ renderImmediately: this.renderAll.bind(this),
363
375
  isViewConfiguredVisible: this.viewVisibilityPredicate,
364
376
  isViewSpec: (spec) => this.viewFactory.isViewSpec(spec),
365
377
  getBaseConfig: () => baseConfig,
@@ -428,6 +440,7 @@ export default class GenomeSpy {
428
440
  // Reminder: assemblies must be ensured after view creation (imports and
429
441
  // inheritance resolved), but before any code path that may touch scales
430
442
  // (e.g. step-based sizes, dynamic opacity, encoder initialization).
443
+ attachViewLevelScaleConfigs(this.viewRoot);
431
444
  await ensureAssembliesForView(this.viewRoot, this.genomeStore);
432
445
 
433
446
  this.#loadingStatusRegistry.set(this.viewRoot, "loading");
@@ -524,7 +537,9 @@ export default class GenomeSpy {
524
537
 
525
538
  await this.#prepareViewsAndData();
526
539
 
527
- this.#interactionController.registerInteractionEvents();
540
+ this.#destructionCallbacks.push(
541
+ this.#interactionController.registerInteractionEvents()
542
+ );
528
543
 
529
544
  this.computeLayout();
530
545
  this.animator.requestRender();
@@ -1,4 +1,5 @@
1
1
  export const embed: (el: HTMLElement | string, spec: import("./spec/root.js").RootSpec | string, options?: import("./types/embedApi.js").EmbedOptions) => Promise<import("./types/embedApi.js").EmbedResult>;
2
+ export { intervalSelection } from "./selection/index.js";
2
3
  import GenomeSpy from "./genomeSpy.js";
3
4
  import { html } from "lit";
4
5
  import icon from "./img/bowtie.svg";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.js"],"names":[],"mappings":"AAWA,6MAA4C;sBAPtB,gBAAgB;qBAJjB,KAAK;iBAKT,kBAAkB;oBACf,6BAA6B;yBACX,mBAAmB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.js"],"names":[],"mappings":"AAWA,6MAA4C;;sBAPtB,gBAAgB;qBAJjB,KAAK;iBAKT,kBAAkB;oBACf,6BAA6B;yBACX,mBAAmB"}
package/dist/src/index.js CHANGED
@@ -12,3 +12,4 @@ export { GenomeSpy, html, icon, favIcon };
12
12
  export const embed = createEmbed(GenomeSpy);
13
13
 
14
14
  export { loadSpec };
15
+ export { intervalSelection } from "./selection/index.js";
@@ -5488,8 +5488,8 @@ void main(void) {
5488
5488
 
5489
5489
  vec2 size = pos2 - pos1;
5490
5490
 
5491
- if (size.x <= 0.0 || size.y <= 0.0) {
5492
- // Early exit. May increase performance or not...
5491
+ if (size.x < 0.0 || size.y < 0.0) {
5492
+ // Keep zero-sized rects alive so min-size clamping can stabilize them.
5493
5493
  gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
5494
5494
  return;
5495
5495
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
@@ -1118,12 +1118,6 @@ export default class Mark {
1118
1118
  }
1119
1119
 
1120
1120
  if (this.bufferInfo) {
1121
- // A hack to prevent WebGL: INVALID_OPERATION: drawArrays: no buffer is bound to enabled attribute
1122
- // TODO: Consider using bufferSubData or DYNAMIC_DRAW etc...
1123
- for (let i = 0; i < 8; i++) {
1124
- gl.disableVertexAttribArray(i);
1125
- }
1126
-
1127
1121
  Object.values(this.bufferInfo.attribs).forEach((attribInfo) =>
1128
1122
  this.gl.deleteBuffer(attribInfo.buffer)
1129
1123
  );
@@ -1,2 +1,2 @@
1
- const shader = "flat out lowp vec4 vFillColor;flat out lowp vec4 vStrokeColor;flat out float vHalfStrokeWidth;flat out vec4 vCornerRadii;\n#if defined(ROUNDED_CORNERS) || defined(STROKED) || defined(SHADOW)\nout vec2 vPosInPixels;\n#endif\nflat out vec2 vHalfSizeInPixels;/***Adjusts the vertex position to ensure that the rectangle is at least `minSpan`*wide or high. Returns a value that reflects the amount of clamping and can be*used to adjust the opacity of the rectangle.**pos: vertex position*frac: vertex position within the rectangle,[0,1]*size: width or height of the rectangle*minSize: minimum width or height of the rectangle*/float clampMinSize(inout float pos,float frac,float size,float minSize){if(minSize>0.0&&size<minSize){pos+=(frac-0.5)*(minSize-size);return size/minSize;}return 1.0;}void sort(inout float a,inout float b){if(a>b){float tmp=b;b=a;a=tmp;}}/***The vertex position wrt the rectangle specified by(x,x2,y,y2).*[0,0]=[x,y],[1,1]=[x2,y2].*The x or y component may contain fractional values if the rectangle*have been tessellated.*/vec2 getVertexPos(){int index=gl_VertexID % 6;return vec2(index==0||index==1||index==3 ? 0.0 : 1.0,index==0||index==1||index==2 ? 0.0 : 1.0);}void main(void){vec2 frac=getVertexPos();vec2 normalizedMinSize=vec2(uMinWidth,uMinHeight)/uViewportSize;vec4 cornerRadii=vec4(uCornerRadiusTopRight,uCornerRadiusBottomRight,uCornerRadiusTopLeft,uCornerRadiusBottomLeft);float x=getScaled_x();float x2=getScaled_x2();float y=getScaled_y();float y2=getScaled_y2();sort(x,x2);sort(y,y2);float clampMargin=1.0;vec2 pos1=vec2(clamp(x,0.0-clampMargin,1.0+clampMargin),y);vec2 pos2=vec2(clamp(x2,0.0-clampMargin,1.0+clampMargin),y2);vec2 size=pos2-pos1;if(size.x<=0.0||size.y<=0.0){gl_Position=vec4(0.0,0.0,0.0,1.0);return;}vec2 pos=pos1+frac*size;size.y*=getSampleFacetHeight(pos);float opaFactor=uViewOpacity*max(uMinOpacity,clampMinSize(pos.x,frac.x,size.x,normalizedMinSize.x)*clampMinSize(pos.y,frac.y,size.y,normalizedMinSize.y));size=max(size,normalizedMinSize);pos=applySampleFacet(pos);\n#if defined(ROUNDED_CORNERS) || defined(STROKED) || defined(SHADOW)\nfloat aaPadding=1.0/uDevicePixelRatio;float shadowPadding=uShadowBlur+max(abs(uShadowOffsetX),abs(uShadowOffsetY));float strokeWidth=getScaled_strokeWidth();float strokeOpacity=getScaled_strokeOpacity()*opaFactor;vec2 centeredFrac=frac-0.5;vec2 expand=centeredFrac*(strokeWidth+aaPadding+shadowPadding*2.0)/uViewportSize;pos+=expand;vec2 sizeInPixels=size*uViewportSize;vPosInPixels=(centeredFrac+expand/size)*sizeInPixels;vHalfSizeInPixels=sizeInPixels/2.0;vCornerRadii=min(cornerRadii,min(vHalfSizeInPixels.x,vHalfSizeInPixels.y));vHalfStrokeWidth=strokeWidth/2.0;vStrokeColor=vec4(getScaled_stroke()*strokeOpacity,strokeOpacity);\n#endif\ngl_Position=unitToNdc(pos);float fillOpacity=getScaled_fillOpacity()*opaFactor;vFillColor=vec4(getScaled_fill()*fillOpacity,fillOpacity);setupPicking();}";
1
+ const shader = "flat out lowp vec4 vFillColor;flat out lowp vec4 vStrokeColor;flat out float vHalfStrokeWidth;flat out vec4 vCornerRadii;\n#if defined(ROUNDED_CORNERS) || defined(STROKED) || defined(SHADOW)\nout vec2 vPosInPixels;\n#endif\nflat out vec2 vHalfSizeInPixels;/***Adjusts the vertex position to ensure that the rectangle is at least `minSpan`*wide or high. Returns a value that reflects the amount of clamping and can be*used to adjust the opacity of the rectangle.**pos: vertex position*frac: vertex position within the rectangle,[0,1]*size: width or height of the rectangle*minSize: minimum width or height of the rectangle*/float clampMinSize(inout float pos,float frac,float size,float minSize){if(minSize>0.0&&size<minSize){pos+=(frac-0.5)*(minSize-size);return size/minSize;}return 1.0;}void sort(inout float a,inout float b){if(a>b){float tmp=b;b=a;a=tmp;}}/***The vertex position wrt the rectangle specified by(x,x2,y,y2).*[0,0]=[x,y],[1,1]=[x2,y2].*The x or y component may contain fractional values if the rectangle*have been tessellated.*/vec2 getVertexPos(){int index=gl_VertexID % 6;return vec2(index==0||index==1||index==3 ? 0.0 : 1.0,index==0||index==1||index==2 ? 0.0 : 1.0);}void main(void){vec2 frac=getVertexPos();vec2 normalizedMinSize=vec2(uMinWidth,uMinHeight)/uViewportSize;vec4 cornerRadii=vec4(uCornerRadiusTopRight,uCornerRadiusBottomRight,uCornerRadiusTopLeft,uCornerRadiusBottomLeft);float x=getScaled_x();float x2=getScaled_x2();float y=getScaled_y();float y2=getScaled_y2();sort(x,x2);sort(y,y2);float clampMargin=1.0;vec2 pos1=vec2(clamp(x,0.0-clampMargin,1.0+clampMargin),y);vec2 pos2=vec2(clamp(x2,0.0-clampMargin,1.0+clampMargin),y2);vec2 size=pos2-pos1;if(size.x<0.0||size.y<0.0){gl_Position=vec4(0.0,0.0,0.0,1.0);return;}vec2 pos=pos1+frac*size;size.y*=getSampleFacetHeight(pos);float opaFactor=uViewOpacity*max(uMinOpacity,clampMinSize(pos.x,frac.x,size.x,normalizedMinSize.x)*clampMinSize(pos.y,frac.y,size.y,normalizedMinSize.y));size=max(size,normalizedMinSize);pos=applySampleFacet(pos);\n#if defined(ROUNDED_CORNERS) || defined(STROKED) || defined(SHADOW)\nfloat aaPadding=1.0/uDevicePixelRatio;float shadowPadding=uShadowBlur+max(abs(uShadowOffsetX),abs(uShadowOffsetY));float strokeWidth=getScaled_strokeWidth();float strokeOpacity=getScaled_strokeOpacity()*opaFactor;vec2 centeredFrac=frac-0.5;vec2 expand=centeredFrac*(strokeWidth+aaPadding+shadowPadding*2.0)/uViewportSize;pos+=expand;vec2 sizeInPixels=size*uViewportSize;vPosInPixels=(centeredFrac+expand/size)*sizeInPixels;vHalfSizeInPixels=sizeInPixels/2.0;vCornerRadii=min(cornerRadii,min(vHalfSizeInPixels.x,vHalfSizeInPixels.y));vHalfStrokeWidth=strokeWidth/2.0;vStrokeColor=vec4(getScaled_stroke()*strokeOpacity,strokeOpacity);\n#endif\ngl_Position=unitToNdc(pos);float fillOpacity=getScaled_fillOpacity()*opaFactor;vFillColor=vec4(getScaled_fill()*fillOpacity,fillOpacity);setupPicking();}";
2
2
  export default shader;
@@ -1,4 +1,5 @@
1
1
  export const embed: (el: HTMLElement | string, spec: import("./spec/root.js").RootSpec | string, options?: import("./types/embedApi.js").EmbedOptions) => Promise<import("./types/embedApi.js").EmbedResult>;
2
+ export { intervalSelection } from "./selection/index.js";
2
3
  import GenomeSpy from "./genomeSpyBase.js";
3
4
  import { html } from "lit";
4
5
  import icon from "./img/bowtie.svg";
@@ -1 +1 @@
1
- {"version":3,"file":"minimal.d.ts","sourceRoot":"","sources":["../../src/minimal.js"],"names":[],"mappings":"AAmBA,6MAA4C;sBARtB,oBAAoB;qBAJrB,KAAK;iBAKT,kBAAkB;oBACf,6BAA6B;yBACX,mBAAmB"}
1
+ {"version":3,"file":"minimal.d.ts","sourceRoot":"","sources":["../../src/minimal.js"],"names":[],"mappings":"AAmBA,6MAA4C;;sBARtB,oBAAoB;qBAJrB,KAAK;iBAKT,kBAAkB;oBACf,6BAA6B;yBACX,mBAAmB"}
@@ -20,3 +20,4 @@ export { GenomeSpy, html, icon, favIcon };
20
20
  export const embed = createEmbed(GenomeSpy);
21
21
 
22
22
  export { loadSpec };
23
+ export { intervalSelection } from "./selection/index.js";