@genome-spy/core 0.67.0 → 0.68.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 (172) hide show
  1. package/dist/bundle/index.es.js +7641 -6313
  2. package/dist/bundle/index.js +115 -134
  3. package/dist/schema.json +534 -132
  4. package/dist/src/data/collector.d.ts +20 -0
  5. package/dist/src/data/collector.d.ts.map +1 -1
  6. package/dist/src/data/collector.js +148 -0
  7. package/dist/src/data/dataFlow.d.ts +6 -0
  8. package/dist/src/data/dataFlow.d.ts.map +1 -1
  9. package/dist/src/data/dataFlow.js +10 -0
  10. package/dist/src/data/flowInit.d.ts.map +1 -1
  11. package/dist/src/data/flowInit.js +2 -3
  12. package/dist/src/data/flowNode.d.ts +8 -0
  13. package/dist/src/data/flowNode.d.ts.map +1 -1
  14. package/dist/src/data/flowNode.js +18 -0
  15. package/dist/src/data/keyIndex.d.ts +18 -0
  16. package/dist/src/data/keyIndex.d.ts.map +1 -0
  17. package/dist/src/data/keyIndex.js +241 -0
  18. package/dist/src/data/keyIndex.test.d.ts +2 -0
  19. package/dist/src/data/keyIndex.test.d.ts.map +1 -0
  20. package/dist/src/data/sources/dataSource.d.ts.map +1 -1
  21. package/dist/src/data/sources/dataSource.js +5 -1
  22. package/dist/src/data/sources/dataSourceFactory.d.ts +14 -12
  23. package/dist/src/data/sources/dataSourceFactory.d.ts.map +1 -1
  24. package/dist/src/data/sources/dataSourceFactory.js +52 -16
  25. package/dist/src/data/sources/lazy/mockLazySource.d.ts +29 -0
  26. package/dist/src/data/sources/lazy/mockLazySource.d.ts.map +1 -0
  27. package/dist/src/data/sources/lazy/mockLazySource.js +44 -0
  28. package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts +22 -1
  29. package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts.map +1 -1
  30. package/dist/src/data/sources/lazy/singleAxisLazySource.js +34 -2
  31. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
  32. package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +15 -0
  33. package/dist/src/data/sources/lazy/tabixSource.d.ts.map +1 -1
  34. package/dist/src/data/sources/lazy/tabixSource.js +15 -5
  35. package/dist/src/data/transforms/stack.d.ts.map +1 -1
  36. package/dist/src/data/transforms/stack.js +1 -0
  37. package/dist/src/encoder/accessor.d.ts +43 -0
  38. package/dist/src/encoder/accessor.d.ts.map +1 -1
  39. package/dist/src/encoder/accessor.js +164 -0
  40. package/dist/src/encoder/encoder.d.ts +11 -2
  41. package/dist/src/encoder/encoder.d.ts.map +1 -1
  42. package/dist/src/encoder/encoder.js +24 -4
  43. package/dist/src/encoder/metadataChannels.d.ts +15 -0
  44. package/dist/src/encoder/metadataChannels.d.ts.map +1 -0
  45. package/dist/src/encoder/metadataChannels.js +65 -0
  46. package/dist/src/encoder/metadataChannels.test.d.ts +2 -0
  47. package/dist/src/encoder/metadataChannels.test.d.ts.map +1 -0
  48. package/dist/src/genome/scaleLocus.d.ts.map +1 -1
  49. package/dist/src/genome/scaleLocus.js +14 -1
  50. package/dist/src/genomeSpy/containerUi.d.ts +0 -1
  51. package/dist/src/genomeSpy/containerUi.d.ts.map +1 -1
  52. package/dist/src/genomeSpy/containerUi.js +0 -14
  53. package/dist/src/genomeSpy/loadingIndicatorManager.d.ts +3 -7
  54. package/dist/src/genomeSpy/loadingIndicatorManager.d.ts.map +1 -1
  55. package/dist/src/genomeSpy/loadingIndicatorManager.js +68 -20
  56. package/dist/src/genomeSpy/loadingStatusRegistry.d.ts +52 -0
  57. package/dist/src/genomeSpy/loadingStatusRegistry.d.ts.map +1 -0
  58. package/dist/src/genomeSpy/loadingStatusRegistry.js +86 -0
  59. package/dist/src/genomeSpy/viewContextFactory.d.ts.map +1 -1
  60. package/dist/src/genomeSpy/viewContextFactory.js +0 -1
  61. package/dist/src/genomeSpy/viewDataInit.d.ts.map +1 -1
  62. package/dist/src/genomeSpy/viewDataInit.js +56 -11
  63. package/dist/src/genomeSpy.d.ts +0 -2
  64. package/dist/src/genomeSpy.d.ts.map +1 -1
  65. package/dist/src/genomeSpy.js +46 -26
  66. package/dist/src/marks/mark.d.ts.map +1 -1
  67. package/dist/src/marks/mark.js +18 -11
  68. package/dist/src/marks/markUtils.js +1 -1
  69. package/dist/src/scale/scale.d.ts +6 -1
  70. package/dist/src/scale/scale.d.ts.map +1 -1
  71. package/dist/src/scale/scale.js +83 -23
  72. package/dist/src/scales/axisResolution.d.ts.map +1 -1
  73. package/dist/src/scales/axisResolution.js +10 -0
  74. package/dist/src/scales/{scaleDomainAggregator.d.ts → domainPlanner.d.ts} +6 -3
  75. package/dist/src/scales/domainPlanner.d.ts.map +1 -0
  76. package/dist/src/scales/{scaleDomainAggregator.js → domainPlanner.js} +128 -10
  77. package/dist/src/scales/domainPlanner.test.d.ts +2 -0
  78. package/dist/src/scales/domainPlanner.test.d.ts.map +1 -0
  79. package/dist/src/scales/scaleInteractionController.d.ts +6 -0
  80. package/dist/src/scales/scaleInteractionController.d.ts.map +1 -1
  81. package/dist/src/scales/scaleInteractionController.js +41 -3
  82. package/dist/src/scales/scaleResolution.d.ts +19 -17
  83. package/dist/src/scales/scaleResolution.d.ts.map +1 -1
  84. package/dist/src/scales/scaleResolution.js +181 -70
  85. package/dist/src/scales/scaleResolution.test.d.ts.map +1 -1
  86. package/dist/src/selection/selection.d.ts +21 -0
  87. package/dist/src/selection/selection.d.ts.map +1 -1
  88. package/dist/src/selection/selection.js +82 -0
  89. package/dist/src/spec/channel.d.ts +52 -15
  90. package/dist/src/spec/data.d.ts +4 -0
  91. package/dist/src/spec/parameter.d.ts +16 -11
  92. package/dist/src/spec/testing.d.ts +12 -0
  93. package/dist/src/spec/testing.d.ts.map +1 -0
  94. package/dist/src/spec/testing.js +20 -0
  95. package/dist/src/spec/view.d.ts +45 -10
  96. package/dist/src/styles/genome-spy.css +3 -31
  97. package/dist/src/styles/genome-spy.css.d.ts +1 -1
  98. package/dist/src/styles/genome-spy.css.d.ts.map +1 -1
  99. package/dist/src/styles/genome-spy.css.js +0 -29
  100. package/dist/src/types/encoder.d.ts +37 -2
  101. package/dist/src/types/rendering.d.ts +4 -3
  102. package/dist/src/types/viewContext.d.ts +0 -14
  103. package/dist/src/utils/throttle.d.ts +4 -1
  104. package/dist/src/utils/throttle.d.ts.map +1 -1
  105. package/dist/src/utils/throttle.js +54 -23
  106. package/dist/src/utils/throttle.test.d.ts +2 -0
  107. package/dist/src/utils/throttle.test.d.ts.map +1 -0
  108. package/dist/src/utils/transition.d.ts +21 -0
  109. package/dist/src/utils/transition.d.ts.map +1 -1
  110. package/dist/src/utils/transition.js +28 -0
  111. package/dist/src/utils/ui/tooltip.d.ts.map +1 -1
  112. package/dist/src/utils/ui/tooltip.js +7 -1
  113. package/dist/src/utils/ui/tooltip.test.d.ts +2 -0
  114. package/dist/src/utils/ui/tooltip.test.d.ts.map +1 -0
  115. package/dist/src/view/axisGridView.d.ts.map +1 -1
  116. package/dist/src/view/axisGridView.js +22 -5
  117. package/dist/src/view/axisView.d.ts.map +1 -1
  118. package/dist/src/view/axisView.js +20 -5
  119. package/dist/src/view/concatView.js +3 -3
  120. package/dist/src/view/containerMutationHelper.js +1 -1
  121. package/dist/src/view/containerView.d.ts +9 -5
  122. package/dist/src/view/containerView.d.ts.map +1 -1
  123. package/dist/src/view/containerView.js +34 -9
  124. package/dist/src/view/dataReadiness.d.ts +46 -0
  125. package/dist/src/view/dataReadiness.d.ts.map +1 -0
  126. package/dist/src/view/dataReadiness.js +267 -0
  127. package/dist/src/view/dataReadiness.test.d.ts +2 -0
  128. package/dist/src/view/dataReadiness.test.d.ts.map +1 -0
  129. package/dist/src/view/facetView.d.ts.map +1 -1
  130. package/dist/src/view/facetView.js +7 -5
  131. package/dist/src/view/flowBuilder.d.ts.map +1 -1
  132. package/dist/src/view/flowBuilder.js +5 -1
  133. package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
  134. package/dist/src/view/gridView/gridChild.js +8 -0
  135. package/dist/src/view/gridView/gridView.d.ts.map +1 -1
  136. package/dist/src/view/gridView/gridView.js +119 -2
  137. package/dist/src/view/gridView/scrollbar.d.ts.map +1 -1
  138. package/dist/src/view/gridView/scrollbar.js +3 -0
  139. package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
  140. package/dist/src/view/gridView/selectionRect.js +20 -5
  141. package/dist/src/view/gridView/separatorView.d.ts +51 -0
  142. package/dist/src/view/gridView/separatorView.d.ts.map +1 -0
  143. package/dist/src/view/gridView/separatorView.js +275 -0
  144. package/dist/src/view/layerView.js +3 -3
  145. package/dist/src/view/layout/flexLayout.d.ts +0 -30
  146. package/dist/src/view/layout/flexLayout.d.ts.map +1 -1
  147. package/dist/src/view/layout/flexLayout.js +0 -86
  148. package/dist/src/view/paramMediator.d.ts +19 -0
  149. package/dist/src/view/paramMediator.d.ts.map +1 -1
  150. package/dist/src/view/paramMediator.js +86 -19
  151. package/dist/src/view/testUtils.d.ts.map +1 -1
  152. package/dist/src/view/testUtils.js +6 -1
  153. package/dist/src/view/unitView.d.ts +8 -13
  154. package/dist/src/view/unitView.d.ts.map +1 -1
  155. package/dist/src/view/unitView.js +110 -41
  156. package/dist/src/view/view.d.ts +22 -14
  157. package/dist/src/view/view.d.ts.map +1 -1
  158. package/dist/src/view/view.js +93 -9
  159. package/dist/src/view/viewFactory.d.ts.map +1 -1
  160. package/dist/src/view/viewFactory.js +20 -1
  161. package/dist/src/view/viewSelectors.d.ts +148 -0
  162. package/dist/src/view/viewSelectors.d.ts.map +1 -0
  163. package/dist/src/view/viewSelectors.js +773 -0
  164. package/dist/src/view/viewSelectors.test.d.ts +2 -0
  165. package/dist/src/view/viewSelectors.test.d.ts.map +1 -0
  166. package/dist/src/view/viewUtils.d.ts +0 -8
  167. package/dist/src/view/viewUtils.d.ts.map +1 -1
  168. package/dist/src/view/viewUtils.js +1 -21
  169. package/package.json +3 -3
  170. package/dist/src/scales/scaleDomainAggregator.d.ts.map +0 -1
  171. package/dist/src/scales/scaleDomainAggregator.test.d.ts +0 -2
  172. package/dist/src/scales/scaleDomainAggregator.test.d.ts.map +0 -1
@@ -33,7 +33,11 @@ export default class DataSource extends FlowNode {
33
33
  * @protected
34
34
  */
35
35
  setLoadingStatus(status, detail) {
36
- this.view.context.setDataLoadingStatus(this.view, status, detail);
36
+ this.view.context.dataFlow.loadingStatusRegistry.set(
37
+ this.view,
38
+ status,
39
+ detail
40
+ );
37
41
  }
38
42
 
39
43
  get paramMediator() {
@@ -1,17 +1,19 @@
1
+ /**
2
+ * Registers a lazy data source for a custom type.
3
+ *
4
+ * @template {import("../../spec/data.js").LazyDataParams} P
5
+ * @param {LazySourceEntry<P>["guard"]} guard
6
+ * @param {LazySourceEntry<P>["Source"]} Source
7
+ * @returns {() => void}
8
+ */
9
+ export function registerLazyDataSource<P extends import("../../spec/data.js").LazyDataParams>(guard: LazySourceEntry<P>["guard"], Source: LazySourceEntry<P>["Source"]): () => void;
1
10
  /**
2
11
  * @param {Partial<import("../../spec/data.js").Data>} params
3
12
  * @param {import("../../view/view.js").default} view
4
13
  */
5
- export default function createDataSource(params: Partial<import("../../spec/data.js").Data>, view: import("../../view/view.js").default): InlineSource | UrlSource | SequenceSource | AxisTickSource | AxisGenomeSource | IndexedFastaSource | BigWigSource | BigBedSource | BamSource | Gff3Source | VcfSource;
6
- import InlineSource from "./inlineSource.js";
7
- import UrlSource from "./urlSource.js";
8
- import SequenceSource from "./sequenceSource.js";
9
- import AxisTickSource from "./lazy/axisTickSource.js";
10
- import AxisGenomeSource from "./lazy/axisGenomeSource.js";
11
- import IndexedFastaSource from "./lazy/indexedFastaSource.js";
12
- import BigWigSource from "./lazy/bigWigSource.js";
13
- import BigBedSource from "./lazy/bigBedSource.js";
14
- import BamSource from "./lazy/bamSource.js";
15
- import Gff3Source from "./lazy/gff3Source.js";
16
- import VcfSource from "./lazy/vcfSource.js";
14
+ export default function createDataSource(params: Partial<import("../../spec/data.js").Data>, view: import("../../view/view.js").default): import("./dataSource.js").default;
15
+ export type LazySourceEntry<P extends import("../../spec/data.js").LazyDataParams> = {
16
+ guard: (params: import("../../spec/data.js").LazyDataParams) => params is P;
17
+ Source: new (params: P, view: import("../../view/view.js").default) => import("./dataSource.js").default;
18
+ };
17
19
  //# sourceMappingURL=dataSourceFactory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dataSourceFactory.d.ts","sourceRoot":"","sources":["../../../../src/data/sources/dataSourceFactory.js"],"names":[],"mappings":"AAYA;;;GAGG;AACH,iDAHW,OAAO,CAAC,OAAO,oBAAoB,EAAE,IAAI,CAAC,QAC1C,OAAO,oBAAoB,EAAE,OAAO,yKAgB9C;yBA9B0C,mBAAmB;sBACzB,gBAAgB;2BACD,qBAAqB;2BAC9C,0BAA0B;6BACxB,4BAA4B;+BAC1B,8BAA8B;yBACpC,wBAAwB;yBACxB,wBAAwB;sBAC3B,qBAAqB;uBACpB,sBAAsB;sBACvB,qBAAqB"}
1
+ {"version":3,"file":"dataSourceFactory.d.ts","sourceRoot":"","sources":["../../../../src/data/sources/dataSourceFactory.js"],"names":[],"mappings":"AAuBA;;;;;;;GAOG;AACH,uCAL2D,CAAC,SAA/C,OAAQ,oBAAoB,EAAE,cAAe,SAC/C,eAAe,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAC3B,eAAe,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAC1B,MAAM,IAAI,CAYtB;AAED;;;GAGG;AACH,iDAHW,OAAO,CAAC,OAAO,oBAAoB,EAAE,IAAI,CAAC,QAC1C,OAAO,oBAAoB,EAAE,OAAO,qCAgB9C;4BAhD0D,CAAC,SAA/C,OAAQ,oBAAoB,EAAE,cAAe,IAC7C;IACR,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,oBAAoB,EAAE,cAAc,KAAK,MAAM,IAAI,CAAC,CAAC;IAC5E,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,oBAAoB,EAAE,OAAO,KAAK,OAAO,iBAAiB,EAAE,OAAO,CAAA;CACzG"}
@@ -10,6 +10,37 @@ import BamSource from "./lazy/bamSource.js";
10
10
  import Gff3Source from "./lazy/gff3Source.js";
11
11
  import VcfSource from "./lazy/vcfSource.js";
12
12
 
13
+ /**
14
+ * @template {import("../../spec/data.js").LazyDataParams} P
15
+ * @typedef {{
16
+ * guard: (params: import("../../spec/data.js").LazyDataParams) => params is P,
17
+ * Source: new (params: P, view: import("../../view/view.js").default) => import("./dataSource.js").default
18
+ * }} LazySourceEntry
19
+ */
20
+
21
+ /** @type {LazySourceEntry<any>[]} */
22
+ const customLazySources = [];
23
+
24
+ /**
25
+ * Registers a lazy data source for a custom type.
26
+ *
27
+ * @template {import("../../spec/data.js").LazyDataParams} P
28
+ * @param {LazySourceEntry<P>["guard"]} guard
29
+ * @param {LazySourceEntry<P>["Source"]} Source
30
+ * @returns {() => void}
31
+ */
32
+ export function registerLazyDataSource(guard, Source) {
33
+ /** @type {LazySourceEntry<any>} */
34
+ const entry = { guard, Source };
35
+ customLazySources.push(entry);
36
+ return () => {
37
+ const index = customLazySources.indexOf(entry);
38
+ if (index >= 0) {
39
+ customLazySources.splice(index, 1);
40
+ }
41
+ };
42
+ }
43
+
13
44
  /**
14
45
  * @param {Partial<import("../../spec/data.js").Data>} params
15
46
  * @param {import("../../view/view.js").default} view
@@ -109,27 +140,32 @@ function isVcfSource(params) {
109
140
  return params?.type == "vcf";
110
141
  }
111
142
 
143
+ /** @type {LazySourceEntry<any>[]} */
144
+ const builtinLazySources = [
145
+ { guard: isAxisTickSource, Source: AxisTickSource },
146
+ { guard: isAxisGenomeSource, Source: AxisGenomeSource },
147
+ { guard: isIndexedFastaSource, Source: IndexedFastaSource },
148
+ { guard: isBigWigSource, Source: BigWigSource },
149
+ { guard: isBigBedSource, Source: BigBedSource },
150
+ { guard: isBamSource, Source: BamSource },
151
+ { guard: isGff3Source, Source: Gff3Source },
152
+ { guard: isVcfSource, Source: VcfSource },
153
+ ];
154
+
112
155
  /**
113
156
  * @param {import("../../spec/data.js").LazyDataParams} params
114
157
  * @param {import("../../view/view.js").default} view
115
158
  */
116
159
  function createLazyDataSource(params, view) {
117
- if (isAxisTickSource(params)) {
118
- return new AxisTickSource(params, view);
119
- } else if (isAxisGenomeSource(params)) {
120
- return new AxisGenomeSource(params, view);
121
- } else if (isIndexedFastaSource(params)) {
122
- return new IndexedFastaSource(params, view);
123
- } else if (isBigWigSource(params)) {
124
- return new BigWigSource(params, view);
125
- } else if (isBigBedSource(params)) {
126
- return new BigBedSource(params, view);
127
- } else if (isBamSource(params)) {
128
- return new BamSource(params, view);
129
- } else if (isGff3Source(params)) {
130
- return new Gff3Source(params, view);
131
- } else if (isVcfSource(params)) {
132
- return new VcfSource(params, view);
160
+ for (const entry of customLazySources) {
161
+ if (entry.guard(params)) {
162
+ return new entry.Source(/** @type {any} */ (params), view);
163
+ }
164
+ }
165
+ for (const entry of builtinLazySources) {
166
+ if (entry.guard(params)) {
167
+ return new entry.Source(/** @type {any} */ (params), view);
168
+ }
133
169
  }
134
170
 
135
171
  throw new Error(
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Testing-only lazy data source that delays data publishing.
3
+ * Register via registerLazyDataSource in tests to avoid production exposure.
4
+ */
5
+ export default class MockLazySource extends SingleAxisLazySource {
6
+ /**
7
+ * @param {{ channel?: import("../../../spec/channel.js").PrimaryPositionalChannel, delay?: number, data?: import("../../flowNode.js").Datum[] }} params
8
+ * @param {import("../../../view/view.js").default} view
9
+ */
10
+ constructor(params: {
11
+ channel?: import("../../../spec/channel.js").PrimaryPositionalChannel;
12
+ delay?: number;
13
+ data?: import("../../flowNode.js").Datum[];
14
+ }, view: import("../../../view/view.js").default);
15
+ params: {
16
+ channel?: import("../../../spec/channel.js").PrimaryPositionalChannel;
17
+ delay?: number;
18
+ data?: import("../../flowNode.js").Datum[];
19
+ };
20
+ delay: number;
21
+ /** @type {ReturnType<typeof setTimeout> | undefined} */
22
+ pendingTimer: ReturnType<typeof setTimeout> | undefined;
23
+ /**
24
+ * @override
25
+ */
26
+ override onDomainChanged(): void;
27
+ }
28
+ import SingleAxisLazySource from "./singleAxisLazySource.js";
29
+ //# sourceMappingURL=mockLazySource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mockLazySource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/mockLazySource.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH;IACI;;;OAGG;IACH,oBAHW;QAAE,OAAO,CAAC,EAAE,OAAO,0BAA0B,EAAE,wBAAwB,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,mBAAmB,EAAE,KAAK,EAAE,CAAA;KAAE,QACrI,OAAO,uBAAuB,EAAE,OAAO,EAgBjD;IAXG;kBANmB,OAAO,0BAA0B,EAAE,wBAAwB;gBAAU,MAAM;eAAS,OAAO,mBAAmB,EAAE,KAAK,EAAE;MAMtH;IACpB,cAA8B;IAC9B,wDAAwD;IACxD,cADW,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,SAAS,CACvB;IAUjC;;OAEG;IACH,iCAYC;CACJ;iCA3CgC,2BAA2B"}
@@ -0,0 +1,44 @@
1
+ import SingleAxisLazySource from "./singleAxisLazySource.js";
2
+
3
+ /**
4
+ * Testing-only lazy data source that delays data publishing.
5
+ * Register via registerLazyDataSource in tests to avoid production exposure.
6
+ */
7
+ export default class MockLazySource extends SingleAxisLazySource {
8
+ /**
9
+ * @param {{ channel?: import("../../../spec/channel.js").PrimaryPositionalChannel, delay?: number, data?: import("../../flowNode.js").Datum[] }} params
10
+ * @param {import("../../../view/view.js").default} view
11
+ */
12
+ constructor(params, view) {
13
+ super(view, params.channel ?? "x");
14
+
15
+ this.params = params;
16
+ this.delay = params.delay ?? 0;
17
+ /** @type {ReturnType<typeof setTimeout> | undefined} */
18
+ this.pendingTimer = undefined;
19
+
20
+ this.view.registerDisposer(() => {
21
+ if (this.pendingTimer) {
22
+ clearTimeout(this.pendingTimer);
23
+ this.pendingTimer = undefined;
24
+ }
25
+ });
26
+ }
27
+
28
+ /**
29
+ * @override
30
+ */
31
+ onDomainChanged() {
32
+ if (this.pendingTimer) {
33
+ clearTimeout(this.pendingTimer);
34
+ this.pendingTimer = undefined;
35
+ }
36
+
37
+ const data = this.params.data ?? [];
38
+ this.pendingTimer = setTimeout(() => {
39
+ this.pendingTimer = undefined;
40
+ this.publishData([data]);
41
+ this.requestRender();
42
+ }, this.delay);
43
+ }
44
+ }
@@ -1,9 +1,16 @@
1
+ /**
2
+ * @typedef {Partial<Record<import("../../../spec/channel.js").PrimaryPositionalChannel, number[]>>} DataReadinessRequest
3
+ */
4
+ /**
5
+ * @typedef {{isDataReadyForDomain: (request: DataReadinessRequest) => boolean}} DataReadinessCheckable
6
+ */
1
7
  /**
2
8
  * Base class for data sources that listen a domain and propagate data lazily.
3
9
  *
4
10
  * @abstract
11
+ * @implements {DataReadinessCheckable}
5
12
  */
6
- export default class SingleAxisLazySource extends DataSource {
13
+ export default class SingleAxisLazySource extends DataSource implements DataReadinessCheckable {
7
14
  /**
8
15
  * @param {import("../../../view/view.js").default} view
9
16
  * @param {import("../../../spec/channel.js").PrimaryPositionalChannel} channel
@@ -14,6 +21,11 @@ export default class SingleAxisLazySource extends DataSource {
14
21
  * @protected
15
22
  */
16
23
  protected initializedPromise: Promise<void>;
24
+ /**
25
+ * @type {number[] | undefined}
26
+ * @protected
27
+ */
28
+ protected _lastLoadedDomain: number[] | undefined;
17
29
  /** @type {import("../../../spec/channel.js").PrimaryPositionalChannel} */
18
30
  channel: import("../../../spec/channel.js").PrimaryPositionalChannel;
19
31
  scaleResolution: import("../../../scales/scaleResolution.js").default;
@@ -48,6 +60,15 @@ export default class SingleAxisLazySource extends DataSource {
48
60
  * @protected
49
61
  */
50
62
  protected publishData(chunks: import("../../flowNode.js").Datum[][]): void;
63
+ /**
64
+ * @param {DataReadinessRequest} request
65
+ * @returns {boolean}
66
+ */
67
+ isDataReadyForDomain(request: DataReadinessRequest): boolean;
51
68
  }
69
+ export type DataReadinessRequest = Partial<Record<import("../../../spec/channel.js").PrimaryPositionalChannel, number[]>>;
70
+ export type DataReadinessCheckable = {
71
+ isDataReadyForDomain: (request: DataReadinessRequest) => boolean;
72
+ };
52
73
  import DataSource from "../dataSource.js";
53
74
  //# sourceMappingURL=singleAxisLazySource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"singleAxisLazySource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/singleAxisLazySource.js"],"names":[],"mappings":"AAIA;;;;GAIG;AACH;IAOI;;;OAGG;IACH,kBAHW,OAAO,uBAAuB,EAAE,OAAO,WACvC,OAAO,0BAA0B,EAAE,wBAAwB,EA+CrE;IAvDD;;;OAGG;IACH,4CAAuC;IAmBnC,2EAA2E;IAC3E,SADW,OAAO,0BAA0B,EAAE,wBAAwB,CAChD;IAEtB,sEAA4D;IA+BhE;;;;OAIG;IACH,oEASC;IAED;;;;;;OAMG;IACH,wBAJW,MAAM,EAAE,iBACR,OAAO,yBAAyB,EAAE,gBAAgB,EAAE,QAK9D;IAED;;;;;OAKG;IACH,gCAGC;IAQD;;;;;;;;OAQG;IACH,8BAHW,OAAO,mBAAmB,EAAE,KAAK,EAAE,EAAE,QAgB/C;CACJ;uBArIsB,kBAAkB"}
1
+ {"version":3,"file":"singleAxisLazySource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/singleAxisLazySource.js"],"names":[],"mappings":"AAGA;;GAEG;AAEH;;GAEG;AAEH;;;;;GAKG;AACH,wEAFgB,sBAAsB;IAelC;;;OAGG;IACH,kBAHW,OAAO,uBAAuB,EAAE,OAAO,WACvC,OAAO,0BAA0B,EAAE,wBAAwB,EA+CrE;IA7DD;;;OAGG;IACH,4CAAuC;IAEvC;;;OAGG;IACH,6BAHU,MAAM,EAAE,GAAG,SAAS,CAGZ;IAmBd,2EAA2E;IAC3E,SADW,OAAO,0BAA0B,EAAE,wBAAwB,CAChD;IAEtB,sEAA4D;IA+BhE;;;;OAIG;IACH,oEASC;IAED;;;;;;OAMG;IACH,wBAJW,MAAM,EAAE,iBACR,OAAO,yBAAyB,EAAE,gBAAgB,EAAE,QAK9D;IAED;;;;;OAKG;IACH,gCAGC;IAQD;;;;;;;;OAQG;IACH,8BAHW,OAAO,mBAAmB,EAAE,KAAK,EAAE,EAAE,QAe/C;IAED;;;OAGG;IACH,8BAHW,oBAAoB,GAClB,OAAO,CAenB;CACJ;mCAlKY,OAAO,CAAC,MAAM,CAAC,OAAO,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,EAAE,CAAC,CAAC;qCAItF;IAAC,oBAAoB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAA;CAAC;uBAPxD,kBAAkB"}
@@ -1,11 +1,19 @@
1
1
  import UnitView from "../../../view/unitView.js";
2
2
  import DataSource from "../dataSource.js";
3
- import { reconfigureScaleDomains } from "../../../scales/scaleResolution.js";
3
+
4
+ /**
5
+ * @typedef {Partial<Record<import("../../../spec/channel.js").PrimaryPositionalChannel, number[]>>} DataReadinessRequest
6
+ */
7
+
8
+ /**
9
+ * @typedef {{isDataReadyForDomain: (request: DataReadinessRequest) => boolean}} DataReadinessCheckable
10
+ */
4
11
 
5
12
  /**
6
13
  * Base class for data sources that listen a domain and propagate data lazily.
7
14
  *
8
15
  * @abstract
16
+ * @implements {DataReadinessCheckable}
9
17
  */
10
18
  export default class SingleAxisLazySource extends DataSource {
11
19
  /**
@@ -14,6 +22,12 @@ export default class SingleAxisLazySource extends DataSource {
14
22
  */
15
23
  initializedPromise = Promise.resolve();
16
24
 
25
+ /**
26
+ * @type {number[] | undefined}
27
+ * @protected
28
+ */
29
+ _lastLoadedDomain;
30
+
17
31
  /**
18
32
  * @param {import("../../../view/view.js").default} view
19
33
  * @param {import("../../../spec/channel.js").PrimaryPositionalChannel} channel
@@ -119,6 +133,7 @@ export default class SingleAxisLazySource extends DataSource {
119
133
  * @protected
120
134
  */
121
135
  publishData(chunks) {
136
+ this._lastLoadedDomain = Array.from(this.scaleResolution.getDomain());
122
137
  this.reset();
123
138
  this.beginBatch({ type: "file" });
124
139
 
@@ -129,7 +144,24 @@ export default class SingleAxisLazySource extends DataSource {
129
144
  }
130
145
 
131
146
  this.complete();
147
+ }
148
+
149
+ /**
150
+ * @param {DataReadinessRequest} request
151
+ * @returns {boolean}
152
+ */
153
+ isDataReadyForDomain(request) {
154
+ const domain = request[this.channel];
155
+ if (!domain || !this._lastLoadedDomain) {
156
+ return false;
157
+ }
132
158
 
133
- reconfigureScaleDomains(this.view);
159
+ const [min, max] =
160
+ domain[0] <= domain[1] ? domain : [domain[1], domain[0]];
161
+ const [loadedMin, loadedMax] =
162
+ this._lastLoadedDomain[0] <= this._lastLoadedDomain[1]
163
+ ? this._lastLoadedDomain
164
+ : [this._lastLoadedDomain[1], this._lastLoadedDomain[0]];
165
+ return min >= loadedMin && max <= loadedMax;
134
166
  }
135
167
  }
@@ -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;IAcD;;;;;OAKG;IACH,iCAHW,MAAM,EAAE,iBAKlB;IApBD;;OAEG;IACH,mCAOC;IAYD;;;;;;;;;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,CAwCvB;IAED;;;;;;OAMG;IACH,yCALW,MAAM,EAAE,cACR,MAAM,YACN,CAAS,IAAQ,EAAR,MAAM,EAAE,KAAE,IAAI,QAyBjC;;CACJ;iCA/KgC,2BAA2B"}
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"}
@@ -83,6 +83,7 @@ export default class SingleAxisWindowedSource extends SingleAxisLazySource {
83
83
 
84
84
  this.#lastDomain = [0, 0];
85
85
  this.#lastQuantizedInterval = [0, 0];
86
+ this._lastLoadedDomain = undefined;
86
87
 
87
88
  this.onDomainChanged(domain);
88
89
  }
@@ -97,6 +98,19 @@ export default class SingleAxisWindowedSource extends SingleAxisLazySource {
97
98
  // Override me if needed
98
99
  }
99
100
 
101
+ /**
102
+ * @param {import("../../flowNode.js").Datum[][]} chunks
103
+ * @protected
104
+ */
105
+ publishData(chunks) {
106
+ // Preserve window coverage; base publishData would overwrite it with the current scale domain.
107
+ const loadedDomain = this._lastLoadedDomain;
108
+ super.publishData(chunks);
109
+ if (loadedDomain) {
110
+ this._lastLoadedDomain = loadedDomain;
111
+ }
112
+ }
113
+
100
114
  /**
101
115
  * Splits the interval into discrete chromosomal intervals – one for each chromosome –
102
116
  * and loads the data for each of them. Handles abort signals and errors.
@@ -134,6 +148,7 @@ export default class SingleAxisWindowedSource extends SingleAxisLazySource {
134
148
 
135
149
  if (!signal.aborted) {
136
150
  this.setLoadingStatus("complete");
151
+ this._lastLoadedDomain = Array.from(interval);
137
152
  return resultByChrom;
138
153
  }
139
154
  } catch (e) {
@@ -1 +1 @@
1
- {"version":3,"file":"tabixSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/tabixSource.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH,iCAHa,CAAC;IAOV;;;OAGG;IACH,oBAHW,OAAO,uBAAuB,EAAE,SAAS,QACzC,OAAO,uBAAuB,EAAE,OAAO,EAkDjD;IAnCG,kDAAgC;IAQhC,iCA0BE;IAqCN;;;OAGG;IACH,gCAHW,MAAM,iBAKhB;IAED;;;;;OAKG;IACH,gCAHW,MAAM,EAAE,GACN,CAAC,EAAE,CAKf;;CACJ;qCApHoC,+BAA+B"}
1
+ {"version":3,"file":"tabixSource.d.ts","sourceRoot":"","sources":["../../../../../src/data/sources/lazy/tabixSource.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH,iCAHa,CAAC;IAOV;;;OAGG;IACH,oBAHW,OAAO,uBAAuB,EAAE,SAAS,QACzC,OAAO,uBAAuB,EAAE,OAAO,EA4DjD;IA7CG,kDAAgC;IAQhC,iCAoCE;IAqCN;;;OAGG;IACH,gCAHW,MAAM,iBAKhB;IAED;;;;;OAKG;IACH,gCAHW,MAAM,EAAE,GACN,CAAC,EAAE,CAKf;;CACJ;qCA9HoC,+BAA+B"}
@@ -34,7 +34,7 @@ export default class TabixSource extends SingleAxisWindowedSource {
34
34
 
35
35
  this.setupDebouncing(this.params);
36
36
 
37
- this.initializedPromise = new Promise((resolve) => {
37
+ this.initializedPromise = new Promise((resolve, reject) => {
38
38
  Promise.all([
39
39
  import("@gmod/tabix"),
40
40
  import("generic-filehandle2"),
@@ -55,10 +55,20 @@ export default class TabixSource extends SingleAxisWindowedSource {
55
55
  : undefined,
56
56
  });
57
57
 
58
- const header = await this.#tbiIndex.getHeader();
59
- await this._handleHeader(header);
60
-
61
- resolve();
58
+ try {
59
+ this.setLoadingStatus("loading");
60
+ const header = await this.#tbiIndex.getHeader();
61
+ await this._handleHeader(header);
62
+ this.setLoadingStatus("complete");
63
+ resolve();
64
+ } catch (e) {
65
+ this.load();
66
+ this.setLoadingStatus(
67
+ "error",
68
+ `${this.params.url}: ${e.message}`
69
+ );
70
+ reject(e);
71
+ }
62
72
  });
63
73
  });
64
74
  }
@@ -1 +1 @@
1
- {"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/stack.js"],"names":[],"mappings":"AAMA;IAKI;;OAEG;IACH,oBAFW,OAAO,yBAAyB,EAAE,WAAW,EAQvD;IAJG,sDAAoB;IAEpB,oBAAoB;IACpB,QADW,GAAG,EAAE,CACA;CAmHvB;sBAlIqB,gBAAgB"}
1
+ {"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../../../src/data/transforms/stack.js"],"names":[],"mappings":"AAMA;IAKI;;OAEG;IACH,oBAFW,OAAO,yBAAyB,EAAE,WAAW,EAQvD;IAJG,sDAAoB;IAEpB,oBAAoB;IACpB,QADW,GAAG,EAAE,CACA;CAoHvB;sBAnIqB,gBAAgB"}
@@ -21,6 +21,7 @@ export default class StackTransform extends Transform {
21
21
  }
22
22
 
23
23
  reset() {
24
+ super.reset();
24
25
  this.buffer = [];
25
26
  }
26
27
 
@@ -15,4 +15,47 @@ export function createAccessor(channel: import("../spec/channel.js").Channel, ch
15
15
  * @param {import("../view/paramMediator.js").default} paramMediator
16
16
  */
17
17
  export function createConditionalAccessors(channel: import("../spec/channel.js").Channel, channelDef: import("../spec/channel.js").ChannelDef, paramMediator: import("../view/paramMediator.js").default): import("../types/encoder.js").Accessor<import("../spec/channel.js").Scalar>[];
18
+ /**
19
+ * @param {import("../types/encoder.js").Accessor} accessor
20
+ * @returns {accessor is import("../types/encoder.js").ScaleAccessor}
21
+ */
22
+ export function isScaleAccessor(accessor: import("../types/encoder.js").Accessor): accessor is import("../types/encoder.js").ScaleAccessor;
23
+ /**
24
+ * Builds domain key strings in the format:
25
+ * - domainKeyBase: <scaleChannel>|<kind>|<value>
26
+ * - domainKey: <type>|<domainKeyBase>
27
+ *
28
+ * @param {object} options
29
+ * @param {import("../spec/channel.js").ChannelWithScale} options.scaleChannel
30
+ * @param {DomainKeySource} options.source
31
+ * @param {import("../spec/channel.js").Type} [options.type]
32
+ * @returns {{ domainKeyBase: string, domainKey?: string }}
33
+ */
34
+ export function buildDomainKey({ scaleChannel, source, type }: {
35
+ scaleChannel: import("../spec/channel.js").ChannelWithScale;
36
+ source: DomainKeySource;
37
+ type?: import("../spec/channel.js").Type;
38
+ }): {
39
+ domainKeyBase: string;
40
+ domainKey?: string;
41
+ };
42
+ /**
43
+ * @param {import("../types/encoder.js").ScaleAccessor} accessor
44
+ * @param {import("../spec/channel.js").Type} type
45
+ * @returns {string}
46
+ */
47
+ export function getAccessorDomainKey(accessor: import("../types/encoder.js").ScaleAccessor, type: import("../spec/channel.js").Type): string;
48
+ export type DomainKeySource = {
49
+ kind: "field";
50
+ value: string;
51
+ } | {
52
+ kind: "expr";
53
+ value: string;
54
+ } | {
55
+ kind: "datum";
56
+ value: import("../spec/channel.js").Scalar | import("../spec/parameter.js").ExprRef;
57
+ } | {
58
+ kind: "value";
59
+ value: import("../spec/channel.js").Scalar | import("../spec/parameter.js").ExprRef;
60
+ };
18
61
  //# sourceMappingURL=accessor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"accessor.d.ts","sourceRoot":"","sources":["../../../src/encoder/accessor.js"],"names":[],"mappings":"AAaA;;;;;GAKG;AACH,wCALW,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,oBAAoB,EAAE,UAAU,GAAG,OAAO,oBAAoB,EAAE,WAAW,CAAC,OAAO,oBAAoB,EAAE,UAAU,CAAC,iBAC3H,OAAO,0BAA0B,EAAE,OAAO,GACxC,OAAO,qBAAqB,EAAE,QAAQ,CA+FlD;AAED;;;;;;;;GAQG;AACH,oDAJW,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,oBAAoB,EAAE,UAAU,iBACvC,OAAO,0BAA0B,EAAE,OAAO,iFAgCpD"}
1
+ {"version":3,"file":"accessor.d.ts","sourceRoot":"","sources":["../../../src/encoder/accessor.js"],"names":[],"mappings":"AAaA;;;;;GAKG;AACH,wCALW,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,oBAAoB,EAAE,UAAU,GAAG,OAAO,oBAAoB,EAAE,WAAW,CAAC,OAAO,oBAAoB,EAAE,UAAU,CAAC,iBAC3H,OAAO,0BAA0B,EAAE,OAAO,GACxC,OAAO,qBAAqB,EAAE,QAAQ,CAmHlD;AAED;;;;;;;;GAQG;AACH,oDAJW,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,oBAAoB,EAAE,UAAU,iBACvC,OAAO,0BAA0B,EAAE,OAAO,iFAgCpD;AAED;;;GAGG;AACH,0CAHW,OAAO,qBAAqB,EAAE,QAAQ,GACpC,QAAQ,IAAI,OAAO,qBAAqB,EAAE,aAAa,CAInE;AA6DD;;;;;;;;;;GAUG;AACH,+DALG;IAA+D,YAAY,EAAnE,OAAO,oBAAoB,EAAE,gBAAgB;IACpB,MAAM,EAA/B,eAAe;IAC6B,IAAI,GAAhD,OAAO,oBAAoB,EAAE,IAAI;CACzC,GAAU;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAYzD;AAED;;;;GAIG;AACH,+CAJW,OAAO,qBAAqB,EAAE,aAAa,QAC3C,OAAO,oBAAoB,EAAE,IAAI,GAC/B,MAAM,CAgBlB;8BApGY;IACN,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB,GAAG;IACA,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACjB,GAAG;IACA,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,oBAAoB,EAAE,MAAM,GAAG,OAAO,sBAAsB,EAAE,OAAO,CAAC;CACvF,GAAG;IACA,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,oBAAoB,EAAE,MAAM,GAAG,OAAO,sBAAsB,EAAE,OAAO,CAAC;CACvF"}