@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
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @typedef {import("../view/view.js").default} View
3
+ * @typedef {import("../types/viewContext.js").DataLoadingStatus} DataLoadingStatus
4
+ * @typedef {{ status: DataLoadingStatus, detail?: string }} LoadingStatus
5
+ * @typedef {{ view: View, status: DataLoadingStatus, detail?: string }} LoadingStatusChange
6
+ */
7
+ /**
8
+ * Central registry for per-view loading status that decouples data sources
9
+ * from UI rendering. Consumers can subscribe to changes and query the current
10
+ * status map when needed (e.g., for overlay rendering).
11
+ */
12
+ export default class LoadingStatusRegistry {
13
+ /**
14
+ * @param {View} view
15
+ * @param {DataLoadingStatus} status
16
+ * @param {string} [detail]
17
+ */
18
+ set(view: View, status: DataLoadingStatus, detail?: string): void;
19
+ /**
20
+ * @param {View} view
21
+ */
22
+ delete(view: View): void;
23
+ /**
24
+ * @param {View} view
25
+ * @returns {LoadingStatus | undefined}
26
+ */
27
+ get(view: View): LoadingStatus | undefined;
28
+ /**
29
+ * @returns {IterableIterator<[View, LoadingStatus]>}
30
+ */
31
+ entries(): IterableIterator<[View, LoadingStatus]>;
32
+ /**
33
+ * Subscribe to status changes.
34
+ *
35
+ * @param {(change: LoadingStatusChange) => void} listener
36
+ * @returns {() => void} Unsubscribe callback
37
+ */
38
+ subscribe(listener: (change: LoadingStatusChange) => void): () => void;
39
+ #private;
40
+ }
41
+ export type View = import("../view/view.js").default;
42
+ export type DataLoadingStatus = import("../types/viewContext.js").DataLoadingStatus;
43
+ export type LoadingStatus = {
44
+ status: DataLoadingStatus;
45
+ detail?: string;
46
+ };
47
+ export type LoadingStatusChange = {
48
+ view: View;
49
+ status: DataLoadingStatus;
50
+ detail?: string;
51
+ };
52
+ //# sourceMappingURL=loadingStatusRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadingStatusRegistry.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/loadingStatusRegistry.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH;IAOI;;;;OAIG;IACH,UAJW,IAAI,UACJ,iBAAiB,WACjB,MAAM,QAahB;IAED;;OAEG;IACH,aAFW,IAAI,QAkBd;IAED;;;OAGG;IACH,UAHW,IAAI,GACF,aAAa,GAAG,SAAS,CAIrC;IAED;;OAEG;IACH,WAFa,gBAAgB,CAAC,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAInD;IAED;;;;;OAKG;IACH,oBAHW,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,GACnC,MAAM,IAAI,CAOtB;;CACJ;mBApFY,OAAO,iBAAiB,EAAE,OAAO;gCACjC,OAAO,yBAAyB,EAAE,iBAAiB;4BACnD;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE;kCAC9C;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @typedef {import("../view/view.js").default} View
3
+ * @typedef {import("../types/viewContext.js").DataLoadingStatus} DataLoadingStatus
4
+ * @typedef {{ status: DataLoadingStatus, detail?: string }} LoadingStatus
5
+ * @typedef {{ view: View, status: DataLoadingStatus, detail?: string }} LoadingStatusChange
6
+ */
7
+
8
+ /**
9
+ * Central registry for per-view loading status that decouples data sources
10
+ * from UI rendering. Consumers can subscribe to changes and query the current
11
+ * status map when needed (e.g., for overlay rendering).
12
+ */
13
+ export default class LoadingStatusRegistry {
14
+ /** @type {Map<View, LoadingStatus>} */
15
+ #statuses = new Map();
16
+
17
+ /** @type {Set<(change: LoadingStatusChange) => void>} */
18
+ #listeners = new Set();
19
+
20
+ /**
21
+ * @param {View} view
22
+ * @param {DataLoadingStatus} status
23
+ * @param {string} [detail]
24
+ */
25
+ set(view, status, detail) {
26
+ if (!view) {
27
+ throw new Error("LoadingStatusRegistry.set requires a view.");
28
+ }
29
+
30
+ this.#statuses.set(view, { status, detail });
31
+
32
+ const change = { view, status, detail };
33
+ for (const listener of this.#listeners) {
34
+ listener(change);
35
+ }
36
+ }
37
+
38
+ /**
39
+ * @param {View} view
40
+ */
41
+ delete(view) {
42
+ const previous = this.#statuses.get(view);
43
+ if (!previous) {
44
+ return;
45
+ }
46
+
47
+ this.#statuses.delete(view);
48
+
49
+ const change = {
50
+ view,
51
+ status: previous.status,
52
+ detail: previous.detail,
53
+ };
54
+ for (const listener of this.#listeners) {
55
+ listener(change);
56
+ }
57
+ }
58
+
59
+ /**
60
+ * @param {View} view
61
+ * @returns {LoadingStatus | undefined}
62
+ */
63
+ get(view) {
64
+ return this.#statuses.get(view);
65
+ }
66
+
67
+ /**
68
+ * @returns {IterableIterator<[View, LoadingStatus]>}
69
+ */
70
+ entries() {
71
+ return this.#statuses.entries();
72
+ }
73
+
74
+ /**
75
+ * Subscribe to status changes.
76
+ *
77
+ * @param {(change: LoadingStatusChange) => void} listener
78
+ * @returns {() => void} Unsubscribe callback
79
+ */
80
+ subscribe(listener) {
81
+ this.#listeners.add(listener);
82
+ return () => {
83
+ this.#listeners.delete(listener);
84
+ };
85
+ }
86
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"viewContextFactory.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/viewContextFactory.js"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;GASG;AACH,2CALW,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,KAAK,OAAO,CAAC,OAAO,iBAAiB,EAAE,OAAO,CAAC,CAAA;CACvX,GACS,WAAW,CAkEvB;0BA7EY,OAAO,yBAAyB,EAAE,OAAO"}
1
+ {"version":3,"file":"viewContextFactory.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/viewContextFactory.js"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;GASG;AACH,2CALW,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,KAAK,OAAO,CAAC,OAAO,iBAAiB,EAAE,OAAO,CAAC,CAAA;CACvX,GACS,WAAW,CAiEvB;0BA5EY,OAAO,yBAAyB,EAAE,OAAO"}
@@ -58,7 +58,6 @@ export function createViewContext(options) {
58
58
  "updateTooltip",
59
59
  "getNamedDataFromProvider",
60
60
  "getCurrentHover",
61
- "setDataLoadingStatus",
62
61
  "addKeyboardListener",
63
62
  "addBroadcastListener",
64
63
  "removeBroadcastListener",
@@ -1 +1 @@
1
- {"version":3,"file":"viewDataInit.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/viewDataInit.js"],"names":[],"mappings":"AAOA;;;;;;;;;GASG;AACH,6CANW,OAAO,iBAAiB,EAAE,OAAO,YACjC,OAAO,qBAAqB,EAAE,OAAO,eACrC,OAAO,2BAA2B,EAAE,OAAO,mBAC3C,CAAC,QAAQ,EAAE,OAAO,qBAAqB,EAAE,OAAO,KAAK,IAAI,GACvD,OAAO,CAAC,OAAO,qBAAqB,EAAE,OAAO,CAAC,CAkC1D;AAED;;;;;;;;GAQG;AACH,oDALW,OAAO,iBAAiB,EAAE,OAAO,YACjC,OAAO,qBAAqB,EAAE,OAAO,eACrC,OAAO,2BAA2B,EAAE,OAAO,GACzC,OAAO,CAAC,OAAO,qBAAqB,EAAE,OAAO,CAAC,CAgD1D"}
1
+ {"version":3,"file":"viewDataInit.d.ts","sourceRoot":"","sources":["../../../src/genomeSpy/viewDataInit.js"],"names":[],"mappings":"AAOA;;;;;;;;;GASG;AACH,6CANW,OAAO,iBAAiB,EAAE,OAAO,YACjC,OAAO,qBAAqB,EAAE,OAAO,eACrC,OAAO,2BAA2B,EAAE,OAAO,mBAC3C,CAAC,QAAQ,EAAE,OAAO,qBAAqB,EAAE,OAAO,KAAK,IAAI,GACvD,OAAO,CAAC,OAAO,qBAAqB,EAAE,OAAO,CAAC,CAkC1D;AAED;;;;;;;;GAQG;AACH,oDALW,OAAO,iBAAiB,EAAE,OAAO,YACjC,OAAO,qBAAqB,EAAE,OAAO,eACrC,OAAO,2BAA2B,EAAE,OAAO,GACzC,OAAO,CAAC,OAAO,qBAAqB,EAAE,OAAO,CAAC,CA2E1D"}
@@ -63,6 +63,10 @@ export async function initializeVisibleViewData(
63
63
  dataFlow,
64
64
  fontManager
65
65
  ) {
66
+ // Initialize dataflow/graphics for views that have become visible since the
67
+ // initial load, while avoiding unnecessary data source reloads. If a view
68
+ // attaches downstream of an already completed collector, repropagate that
69
+ // collector instead of reloading the source.
66
70
  const visibilityPredicate = (
67
71
  /** @type {import("../view/view.js").default} */ view
68
72
  ) => view.isConfiguredVisible();
@@ -80,6 +84,23 @@ export async function initializeVisibleViewData(
80
84
  /** @type {import("../view/view.js").default} */ view
81
85
  ) => viewsToInitializeSet.has(view);
82
86
 
87
+ /** @type {Set<import("../data/collector.js").default>} */
88
+ const collectorsToRepropagate = new Set();
89
+ /** @type {import("../view/view.js").default[]} */
90
+ const viewsNeedingLoad = [];
91
+ for (const view of viewsToInitialize) {
92
+ if (view.spec.data) {
93
+ viewsNeedingLoad.push(view);
94
+ continue;
95
+ }
96
+ const collector = findCompletedAncestorCollector(view);
97
+ if (collector) {
98
+ collectorsToRepropagate.add(collector);
99
+ } else {
100
+ viewsNeedingLoad.push(view);
101
+ }
102
+ }
103
+
83
104
  const { dataFlow: builtDataFlow, graphicsPromises } = initializeViewSubtree(
84
105
  viewRoot,
85
106
  dataFlow,
@@ -89,17 +110,23 @@ export async function initializeVisibleViewData(
89
110
 
90
111
  await fontManager.waitUntilReady();
91
112
 
92
- const dataSourceRoots = collectDataSourceRoots(viewsToInitialize);
93
- await Promise.all(
94
- Array.from(dataSourceRoots.entries()).map(
95
- ([subtreeRoot, dataSources]) =>
96
- loadViewSubtreeData(subtreeRoot, dataSources, undefined, {
97
- // If a source is already loading, schedule a reload so new branches
98
- // added during lazy init receive a complete data propagation.
99
- queueReload: true,
100
- })
101
- )
102
- );
113
+ for (const collector of collectorsToRepropagate) {
114
+ collector.repropagate();
115
+ }
116
+
117
+ if (viewsNeedingLoad.length) {
118
+ const dataSourceRoots = collectDataSourceRoots(viewsNeedingLoad);
119
+ await Promise.all(
120
+ Array.from(dataSourceRoots.entries()).map(
121
+ ([subtreeRoot, dataSources]) =>
122
+ loadViewSubtreeData(subtreeRoot, dataSources, undefined, {
123
+ // If a source is already loading, schedule a reload so new branches
124
+ // added during lazy init receive a complete data propagation.
125
+ queueReload: true,
126
+ })
127
+ )
128
+ );
129
+ }
103
130
 
104
131
  await finalizeSubtreeGraphics(graphicsPromises);
105
132
 
@@ -158,3 +185,21 @@ function collectDataSourceRoots(views) {
158
185
 
159
186
  return roots;
160
187
  }
188
+
189
+ /**
190
+ * Finds the nearest completed collector in the dataParent chain.
191
+ *
192
+ * @param {import("../view/view.js").default} view
193
+ * @returns {import("../data/collector.js").default | undefined}
194
+ */
195
+ function findCompletedAncestorCollector(view) {
196
+ let current = view.dataParent;
197
+ while (current) {
198
+ const collector = current.flowHandle?.collector;
199
+ if (collector) {
200
+ return collector.completed ? collector : undefined;
201
+ }
202
+ current = current.dataParent;
203
+ }
204
+ return undefined;
205
+ }
@@ -66,8 +66,6 @@ export default class GenomeSpy {
66
66
  * @param {any} [payload]
67
67
  */
68
68
  broadcast(type: BroadcastEventType, payload?: any): void;
69
- loadingMessageElement: HTMLElement;
70
- loadingIndicatorsElement: HTMLElement;
71
69
  tooltip: import("./utils/ui/tooltip.js").default;
72
70
  /**
73
71
  * Unregisters all listeners, removes all created dom elements, removes all css classes from the container
@@ -1 +1 @@
1
- {"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"AA6CA;IAkBI;;;;;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,kCAAM,KAAK,OAAO,CAE8B;IAE/D,oFAAoF;IACpF,iBADW,MAAM,CAAC,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC,CAK9E;IAED,mBAAmB;IACnB,2CAAyB;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;IAiEG,mCAAkD;IAKlD,sCAAwD;IACxD,iDAAsB;IAM1B;;OAEG;IACH,gBAmBC;IA8ID;;;OAGG;IACH,UAFa,OAAO,CAAC,OAAO,CAAC,CAgC5B;IAED,2CAiBC;IAED,4BAEC;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,sBAEC;IAED,kBAEC;IAED,iCAEC;IAED,iCASC;IAED,uFAWC;;CACJ;;;;iCArhBY,eAAe,GAAG,QAAQ,GAAG,gBAAgB,GAAG,kBAAkB;4BAZnC,uBAAuB;qBAR9C,qBAAqB;wBAElB,yBAAyB;qBAL5B,oBAAoB"}
1
+ {"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"AA+CA;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,kCAAM,KAAK,OAAO,CAE8B;IAE/D,oFAAoF;IACpF,iBADW,MAAM,CAAC,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC,CAK9E;IAED,mBAAmB;IACnB,2CAAyB;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;IA4DG,iDAAsB;IAQ1B;;OAEG;IACH,gBAqBC;IAyJD;;;OAGG;IACH,UAFa,OAAO,CAAC,OAAO,CAAC,CAyC5B;IAED,2CAiBC;IAED,4BAEC;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,sBAEC;IAED,kBAEC;IAED,iCAEC;IAED,iCAYC;IAED,uFAWC;;CACJ;;;;iCAviBY,eAAe,GAAG,QAAQ,GAAG,gBAAgB,GAAG,kBAAkB;4BAbnC,uBAAuB;qBAR9C,qBAAqB;wBAElB,yBAAyB;qBAL5B,oBAAoB"}
@@ -5,6 +5,7 @@ import {
5
5
  createMessageBox,
6
6
  } from "./genomeSpy/containerUi.js";
7
7
  import LoadingIndicatorManager from "./genomeSpy/loadingIndicatorManager.js";
8
+ import LoadingStatusRegistry from "./genomeSpy/loadingStatusRegistry.js";
8
9
  import { createViewHighlighter } from "./genomeSpy/viewHighlight.js";
9
10
  import KeyboardListenerManager from "./genomeSpy/keyboardListenerManager.js";
10
11
  import EventListenerRegistry from "./genomeSpy/eventListenerRegistry.js";
@@ -35,6 +36,7 @@ import {
35
36
  configureViewOpacity,
36
37
  } from "./genomeSpy/viewHierarchyConfig.js";
37
38
  import { exportCanvas } from "./genomeSpy/canvasExport.js";
39
+ import { validateSelectorConstraints } from "./view/viewSelectors.js";
38
40
 
39
41
  /**
40
42
  * Events that are broadcasted to all views.
@@ -50,6 +52,8 @@ export default class GenomeSpy {
50
52
  #renderCoordinator;
51
53
  /** @type {LoadingIndicatorManager} */
52
54
  #loadingIndicatorManager;
55
+ /** @type {LoadingStatusRegistry} */
56
+ #loadingStatusRegistry;
53
57
  /** @type {InputBindingManager} */
54
58
  #inputBindingManager;
55
59
  /** @type {InteractionController} */
@@ -237,12 +241,8 @@ export default class GenomeSpy {
237
241
  }
238
242
 
239
243
  #prepareContainer() {
240
- const {
241
- canvasWrapper,
242
- loadingMessageElement,
243
- loadingIndicatorsElement,
244
- tooltip,
245
- } = createContainerUi(this.container);
244
+ const { canvasWrapper, loadingIndicatorsElement, tooltip } =
245
+ createContainerUi(this.container);
246
246
 
247
247
  this.#glHelper = new WebGLHelper(
248
248
  canvasWrapper,
@@ -253,16 +253,11 @@ export default class GenomeSpy {
253
253
  { powerPreference: this.options.powerPreference ?? "default" }
254
254
  );
255
255
 
256
- // The initial loading message that is shown until the first frame is rendered
257
- this.loadingMessageElement = loadingMessageElement;
258
- // A container for loading indicators (for lazy data sources.)
259
- // These could alternatively be included in the view hierarchy,
260
- // but it's easier this way – particularly if we want to show
261
- // some fancy animated spinners.
262
- this.loadingIndicatorsElement = loadingIndicatorsElement;
263
256
  this.tooltip = tooltip;
257
+ this.#loadingStatusRegistry = new LoadingStatusRegistry();
264
258
  this.#loadingIndicatorManager = new LoadingIndicatorManager(
265
- loadingIndicatorsElement
259
+ loadingIndicatorsElement,
260
+ this.#loadingStatusRegistry
266
261
  );
267
262
  }
268
263
 
@@ -285,6 +280,8 @@ export default class GenomeSpy {
285
280
 
286
281
  this.#inputBindingManager.remove();
287
282
 
283
+ this.#loadingIndicatorManager.destroy();
284
+
288
285
  while (this.container.firstChild) {
289
286
  this.container.firstChild.remove();
290
287
  }
@@ -311,8 +308,11 @@ export default class GenomeSpy {
311
308
  }
312
309
 
313
310
  #createViewContext() {
311
+ const dataFlow = new DataFlow();
312
+ dataFlow.loadingStatusRegistry = this.#loadingStatusRegistry;
313
+
314
314
  return createViewContext({
315
- dataFlow: new DataFlow(),
315
+ dataFlow,
316
316
  glHelper: this.#glHelper,
317
317
  animator: this.animator,
318
318
  genomeStore: this.genomeStore,
@@ -321,12 +321,6 @@ export default class GenomeSpy {
321
321
  getNamedDataFromProvider: this.getNamedDataFromProvider.bind(this),
322
322
  getCurrentHover: () =>
323
323
  this.#interactionController.getCurrentHover(),
324
- setDataLoadingStatus: (view, status, detail) =>
325
- this.#loadingIndicatorManager.setDataLoadingStatus(
326
- view,
327
- status,
328
- detail
329
- ),
330
324
  addKeyboardListener: (type, listener) => {
331
325
  // TODO: Listeners should be called only when the mouse pointer is inside the
332
326
  // container or the app covers the full document.
@@ -378,6 +372,8 @@ export default class GenomeSpy {
378
372
  VIEW_ROOT_NAME
379
373
  );
380
374
 
375
+ this.#loadingStatusRegistry.set(this.viewRoot, "loading");
376
+
381
377
  this.#canvasWrapper.style.flexGrow =
382
378
  this.viewRoot.getSize().height.grow > 0 ? "1" : "0";
383
379
 
@@ -385,6 +381,7 @@ export default class GenomeSpy {
385
381
 
386
382
  configureViewHierarchy(this.viewRoot);
387
383
  configureViewOpacity(this.viewRoot);
384
+ this.#logSelectorConstraintWarnings();
388
385
 
389
386
  // We should now have a complete view hierarchy. Let's update the canvas size
390
387
  // and ensure that the loading message is visible.
@@ -405,6 +402,17 @@ export default class GenomeSpy {
405
402
  this.#setupDpr();
406
403
  }
407
404
 
405
+ #logSelectorConstraintWarnings() {
406
+ const issues = validateSelectorConstraints(this.viewRoot);
407
+ if (!issues.length) {
408
+ return;
409
+ }
410
+
411
+ for (const issue of issues) {
412
+ console.warn("Selector constraints warning:", issue.message);
413
+ }
414
+ }
415
+
408
416
  /**
409
417
  * @param {import("./types/viewContext.js").default} context
410
418
  */
@@ -435,6 +443,7 @@ export default class GenomeSpy {
435
443
  * @returns {Promise<boolean>} true if the launch was successful
436
444
  */
437
445
  async launch() {
446
+ let launched = false;
438
447
  try {
439
448
  this.#prepareContainer();
440
449
 
@@ -445,6 +454,7 @@ export default class GenomeSpy {
445
454
  this.computeLayout();
446
455
  this.animator.requestRender();
447
456
 
457
+ launched = true;
448
458
  return true;
449
459
  } catch (reason) {
450
460
  const message = `${
@@ -456,13 +466,20 @@ export default class GenomeSpy {
456
466
  createMessageBox(this.container, message);
457
467
  }
458
468
 
469
+ if (this.viewRoot) {
470
+ this.#loadingStatusRegistry.set(
471
+ this.viewRoot,
472
+ "error",
473
+ message
474
+ );
475
+ }
476
+
459
477
  return false;
460
478
  } finally {
461
479
  this.#canvasWrapper.classList.remove("loading");
462
- // Transition listener doesn't appear to work on observablehq
463
- window.setTimeout(() => {
464
- this.loadingMessageElement.style.display = "none";
465
- }, 2000);
480
+ if (launched && this.viewRoot) {
481
+ this.#loadingStatusRegistry.set(this.viewRoot, "complete");
482
+ }
466
483
  }
467
484
  }
468
485
 
@@ -552,7 +569,10 @@ export default class GenomeSpy {
552
569
  /** @type {UnitView[]} */
553
570
  const views = [];
554
571
  this.viewRoot.visit((view) => {
555
- if (view instanceof UnitView && view.getDataAccessor("search")) {
572
+ if (
573
+ view instanceof UnitView &&
574
+ view.getSearchAccessors().length > 0
575
+ ) {
556
576
  views.push(view);
557
577
  }
558
578
  });
@@ -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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"}
@@ -940,6 +940,17 @@ export default class Mark {
940
940
  * initiated. The idea is to allow for parallel background compilation.
941
941
  */
942
942
  finalizeGraphicsInitialization() {
943
+ // Allow duplicate finalization calls when multiple init paths overlap.
944
+ if (this.programInfo) {
945
+ return;
946
+ }
947
+
948
+ if (!this.programStatus) {
949
+ throw new Error(
950
+ "No program status found! " + this.unitView.getPathString()
951
+ );
952
+ }
953
+
943
954
  const error = this.programStatus.getProgramErrors();
944
955
  if (error) {
945
956
  if (error.detail) {
@@ -1290,21 +1301,17 @@ export default class Mark {
1290
1301
  const locationSetter = this.programInfo.uniformSetters.uSampleFacet;
1291
1302
 
1292
1303
  if (opts && locationSetter) {
1293
- const pos = opts.locSize ? opts.locSize.location : 0.0;
1294
- const height = opts.locSize ? opts.locSize.size : 1.0;
1304
+ const scale = opts.pixelToUnit;
1305
+ const pos = opts.locSize.location * scale;
1306
+ const height = opts.locSize.size * scale;
1295
1307
 
1296
1308
  if (pos > 1.0 || pos + height < 0.0) {
1297
1309
  // Not visible
1298
1310
  return false;
1299
1311
  }
1300
1312
 
1301
- const targetPos = opts.targetLocSize
1302
- ? opts.targetLocSize.location
1303
- : pos;
1304
- const targetHeight = opts.targetLocSize
1305
- ? opts.targetLocSize.size
1306
- : height;
1307
-
1313
+ // No target locSize in the current API. Keep a consistent shader path
1314
+ // by repeating the current position/height.
1308
1315
  // Use WebGL directly, because twgl uses gl.uniform4fv, which has an
1309
1316
  // inferior performance. Based on profiling, this optimization gives
1310
1317
  // a significant performance boost.
@@ -1313,8 +1320,8 @@ export default class Mark {
1313
1320
  locationSetter.location, // TODO: Make a twgl pull request to fix typing
1314
1321
  pos,
1315
1322
  height,
1316
- targetPos,
1317
- targetHeight
1323
+ pos,
1324
+ height
1318
1325
  );
1319
1326
  }
1320
1327
 
@@ -38,7 +38,7 @@ export function fixPositional(encoding, channel) {
38
38
  if (!secondary) {
39
39
  if (primary.type == "quantitative") {
40
40
  // Bar plot, anchor the other end to zero
41
- secondary = { datum: 0, contributesToScaleDomain: false };
41
+ secondary = { datum: 0, domainInert: true };
42
42
  } else {
43
43
  secondary = { ...primary };
44
44
 
@@ -6,5 +6,10 @@ export function configureScale(_: any, scale: any, logger: any): void;
6
6
  * @returns {import("../encoder/encoder.js").VegaScale}
7
7
  */
8
8
  export default function createScale(_: import("../spec/scale.js").Scale, logger: any): import("../encoder/encoder.js").VegaScale;
9
- export function configureDomain(scale: any, _: any, logger: any): any;
9
+ export function configureDomain(scale: any, _: any, logger: any): {
10
+ domain: any;
11
+ count: any;
12
+ ordinalUnknown: any;
13
+ applyOrdinalUnknown: boolean;
14
+ };
10
15
  //# sourceMappingURL=scale.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scale.d.ts","sourceRoot":"","sources":["../../../src/scale/scale.js"],"names":[],"mappings":"AAoHA,sEAmBC;AAED;;;;;GAKG;AACH,uCAJW,OAAO,kBAAkB,EAAE,KAAK,UAChC,GAAC,GACC,OAAO,uBAAuB,EAAE,SAAS,CAoBrD;AAgCD,sEAuEC"}
1
+ {"version":3,"file":"scale.d.ts","sourceRoot":"","sources":["../../../src/scale/scale.js"],"names":[],"mappings":"AAgIA,sEAuBC;AAED;;;;;GAKG;AACH,uCAJW,OAAO,kBAAkB,EAAE,KAAK,UAChC,GAAC,GACC,OAAO,uBAAuB,EAAE,SAAS,CAoBrD;AA4CD;;;;;EAuGC"}