@genome-spy/core 0.64.0 → 0.65.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 (104) hide show
  1. package/dist/bundle/{index-CCJIjehY.js → AbortablePromiseCache-CcuMrnn7.js} +22 -91
  2. package/dist/bundle/browser-txUcLy2H.js +123 -0
  3. package/dist/bundle/index-BQpbYrv4.js +1712 -0
  4. package/dist/bundle/index-BhtHKLUo.js +73 -0
  5. package/dist/bundle/index-C0llXMqm.js +280 -0
  6. package/dist/bundle/index-CCe8rnZz.js +716 -0
  7. package/dist/bundle/index-CD7FLu9x.js +269 -0
  8. package/dist/bundle/{index-C08YCM2T.js → index-D-w7Mmt9.js} +246 -126
  9. package/dist/bundle/index-D74H8TTz.js +508 -0
  10. package/dist/bundle/index-DhcU-Gk-.js +1487 -0
  11. package/dist/bundle/index.es.js +4878 -4680
  12. package/dist/bundle/index.js +151 -167
  13. package/dist/bundle/inflate-DRgHi_KK.js +1050 -0
  14. package/dist/schema.json +9 -1
  15. package/dist/src/data/collector.d.ts +7 -2
  16. package/dist/src/data/collector.d.ts.map +1 -1
  17. package/dist/src/data/collector.js +13 -2
  18. package/dist/src/data/dataFlow.d.ts +20 -42
  19. package/dist/src/data/dataFlow.d.ts.map +1 -1
  20. package/dist/src/data/dataFlow.js +57 -80
  21. package/dist/src/data/dataFlow.test.js +35 -2
  22. package/dist/src/data/flowHandle.d.ts +15 -0
  23. package/dist/src/data/flowHandle.d.ts.map +1 -0
  24. package/dist/src/data/flowHandle.js +13 -0
  25. package/dist/src/data/flowInit.d.ts +85 -0
  26. package/dist/src/data/flowInit.d.ts.map +1 -0
  27. package/dist/src/data/flowInit.js +238 -0
  28. package/dist/src/data/flowInit.test.d.ts +2 -0
  29. package/dist/src/data/flowInit.test.d.ts.map +1 -0
  30. package/dist/src/data/flowInit.test.js +413 -0
  31. package/dist/src/data/flowOptimizer.d.ts +6 -4
  32. package/dist/src/data/flowOptimizer.d.ts.map +1 -1
  33. package/dist/src/data/flowOptimizer.js +29 -14
  34. package/dist/src/data/flowOptimizer.test.js +20 -15
  35. package/dist/src/data/sources/lazy/bamSource.js +1 -1
  36. package/dist/src/data/sources/lazy/bigBedSource.js +1 -1
  37. package/dist/src/data/sources/lazy/bigWigSource.js +1 -1
  38. package/dist/src/data/sources/lazy/gff3Source.d.ts +2 -6
  39. package/dist/src/data/sources/lazy/gff3Source.d.ts.map +1 -1
  40. package/dist/src/data/sources/lazy/gff3Source.js +4 -8
  41. package/dist/src/data/sources/lazy/indexedFastaSource.d.ts.map +1 -1
  42. package/dist/src/data/sources/lazy/indexedFastaSource.js +17 -17
  43. package/dist/src/data/sources/lazy/tabixSource.js +1 -1
  44. package/dist/src/genomeSpy.d.ts +1 -1
  45. package/dist/src/genomeSpy.d.ts.map +1 -1
  46. package/dist/src/genomeSpy.js +18 -61
  47. package/dist/src/marks/mark.d.ts +1 -0
  48. package/dist/src/marks/mark.d.ts.map +1 -1
  49. package/dist/src/marks/mark.js +22 -1
  50. package/dist/src/spec/sampleView.d.ts +3 -2
  51. package/dist/src/types/viewContext.d.ts +1 -1
  52. package/dist/src/view/axisResolution.d.ts +5 -0
  53. package/dist/src/view/axisResolution.d.ts.map +1 -1
  54. package/dist/src/view/axisResolution.js +16 -1
  55. package/dist/src/view/facetView.d.ts.map +1 -1
  56. package/dist/src/view/facetView.js +1 -0
  57. package/dist/src/view/flowBuilder.d.ts +2 -2
  58. package/dist/src/view/flowBuilder.d.ts.map +1 -1
  59. package/dist/src/view/flowBuilder.js +21 -4
  60. package/dist/src/view/gridView/gridView.d.ts.map +1 -1
  61. package/dist/src/view/gridView/gridView.js +13 -0
  62. package/dist/src/view/gridView/selectionRect.d.ts +8 -4
  63. package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
  64. package/dist/src/view/gridView/selectionRect.js +28 -3
  65. package/dist/src/view/gridView/selectionRect.test.d.ts +2 -0
  66. package/dist/src/view/gridView/selectionRect.test.d.ts.map +1 -0
  67. package/dist/src/view/gridView/selectionRect.test.js +87 -0
  68. package/dist/src/view/paramMediator.d.ts +2 -1
  69. package/dist/src/view/paramMediator.d.ts.map +1 -1
  70. package/dist/src/view/paramMediator.js +13 -1
  71. package/dist/src/view/paramMediator.test.js +22 -0
  72. package/dist/src/view/scaleResolution.d.ts +5 -0
  73. package/dist/src/view/scaleResolution.d.ts.map +1 -1
  74. package/dist/src/view/scaleResolution.js +10 -0
  75. package/dist/src/view/testUtils.d.ts.map +1 -1
  76. package/dist/src/view/testUtils.js +16 -4
  77. package/dist/src/view/unitView.d.ts.map +1 -1
  78. package/dist/src/view/unitView.js +58 -8
  79. package/dist/src/view/view.d.ts +17 -1
  80. package/dist/src/view/view.d.ts.map +1 -1
  81. package/dist/src/view/view.js +57 -1
  82. package/dist/src/view/viewDispose.test.d.ts +2 -0
  83. package/dist/src/view/viewDispose.test.d.ts.map +1 -0
  84. package/dist/src/view/viewDispose.test.js +110 -0
  85. package/dist/src/view/viewUtils.d.ts +4 -4
  86. package/dist/src/view/viewUtils.d.ts.map +1 -1
  87. package/dist/src/view/viewUtils.js +19 -15
  88. package/dist/src/view/viewUtils.test.d.ts +2 -0
  89. package/dist/src/view/viewUtils.test.d.ts.map +1 -0
  90. package/dist/src/view/viewUtils.test.js +87 -0
  91. package/package.json +10 -10
  92. package/dist/bundle/__vite-browser-external-C--ziKoh.js +0 -8
  93. package/dist/bundle/_commonjsHelpers-DjF3Plf2.js +0 -26
  94. package/dist/bundle/index-5ajWdKly.js +0 -1319
  95. package/dist/bundle/index-B03-Om4z.js +0 -274
  96. package/dist/bundle/index-BftNdA0O.js +0 -27
  97. package/dist/bundle/index-Bg7C4Xat.js +0 -2750
  98. package/dist/bundle/index-C3QR8Lv6.js +0 -2131
  99. package/dist/bundle/index-DTcHjAHp.js +0 -505
  100. package/dist/bundle/index-DnIkxb0L.js +0 -1025
  101. package/dist/bundle/index-Ww3TAo6_.js +0 -71
  102. package/dist/bundle/index-g8iXgW0W.js +0 -651
  103. package/dist/bundle/long-B-FASCSo.js +0 -2387
  104. package/dist/bundle/remoteFile-BuaqFGWk.js +0 -94
@@ -1 +1 @@
1
- {"version":3,"file":"flowBuilder.d.ts","sourceRoot":"","sources":["../../../src/view/flowBuilder.js"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH,gFAHW,QAAQ,6BAAM,yCAkMxB;AAED;;;;;;GAMG;AACH;;;IAgGc;;;OAGG;;EAYhB;AAgCD;;;;;;GAMG;AACH,4BAFwB,CAAC,SAAZ,qCAAU,cAFZ,CAAC,iBACA,uCAAW;;;0BAwBG,OAAO,CAAC,QAAQ,CAAC,OAAO,qBAAqB,EAAE,KAAK,CAAC,CAAC;EAkB/E;qBA5ZoB,qBAAqB;sBANpB,sBAAsB"}
1
+ {"version":3,"file":"flowBuilder.d.ts","sourceRoot":"","sources":["../../../src/view/flowBuilder.js"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH,gFAHW,QAAQ,YAmNlB;AAED;;;;;;GAMG;AACH;;;IAgGc;;;OAGG;;EAYhB;AAgCD;;;;;;GAMG;AACH,4BAFwB,CAAC,SAAZ,qCAAU,cAFZ,CAAC,iBACA,uCAAW;;;0BAwBG,OAAO,CAAC,QAAQ,CAAC,OAAO,qBAAqB,EAAE,KAAK,CAAC,CAAC;EAkB/E;qBA7aoB,qBAAqB;sBANpB,sBAAsB"}
@@ -24,7 +24,7 @@ import { nodesToTreesWithAccessor, visitTree } from "../utils/trees.js";
24
24
 
25
25
  /**
26
26
  * @param {View} root
27
- * @param {DataFlow<View>} [existingFlow] Add data flow
27
+ * @param {DataFlow} [existingFlow] Add data flow
28
28
  * graphs to an existing DataFlow object.
29
29
  */
30
30
  export function buildDataFlow(root, existingFlow) {
@@ -41,7 +41,7 @@ export function buildDataFlow(root, existingFlow) {
41
41
  /** @type {FlowNode} */
42
42
  let currentNode;
43
43
 
44
- /** @type {DataFlow<View>} */
44
+ /** @type {DataFlow} */
45
45
  const dataFlow = existingFlow ?? new DataFlow();
46
46
 
47
47
  /** @type {(function():void)[]} */
@@ -122,6 +122,15 @@ export function buildDataFlow(root, existingFlow) {
122
122
  /** @param {View} view */
123
123
  const processView = (view) => {
124
124
  if (view.spec.data) {
125
+ const previousDataSource = view.flowHandle?.dataSource;
126
+ if (
127
+ previousDataSource &&
128
+ previousDataSource.view === view &&
129
+ !previousDataSource.identifier
130
+ ) {
131
+ dataFlow.removeDataSource(previousDataSource);
132
+ }
133
+
125
134
  const dataSource = isNamedData(view.spec.data)
126
135
  ? new NamedSource(
127
136
  view.spec.data,
@@ -132,7 +141,9 @@ export function buildDataFlow(root, existingFlow) {
132
141
 
133
142
  currentNode = dataSource;
134
143
  nodeStack.push(dataSource);
135
- dataFlow.addDataSource(dataSource, view);
144
+ dataFlow.addDataSource(dataSource);
145
+ view.flowHandle ??= {};
146
+ view.flowHandle.dataSource = dataSource;
136
147
  }
137
148
 
138
149
  if (view.spec.transform) {
@@ -186,7 +197,13 @@ export function buildDataFlow(root, existingFlow) {
186
197
  });
187
198
 
188
199
  appendNode(collector);
189
- dataFlow.addCollector(collector, view);
200
+ const previousCollector = view.flowHandle?.collector;
201
+ if (previousCollector) {
202
+ dataFlow.removeCollector(previousCollector);
203
+ }
204
+ dataFlow.addCollector(collector);
205
+ view.flowHandle ??= {};
206
+ view.flowHandle.collector = collector;
190
207
  }
191
208
  };
192
209
 
@@ -1 +1 @@
1
- {"version":3,"file":"gridView.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/gridView.js"],"names":[],"mappings":"AAqyBA;;GAEG;AACH,+EAUC;AAED;;;;;GAKG;AACH,4CAJW,OAAO,wBAAwB,EAAE,OAAO,UACxC,OAAO,oBAAoB,EAAE,UAAU,YACvC,QAAQ,aAmBlB;AAxzBD;;;;;;;;;;;;;;;GAeG;AACH;IA6BI;;;;;;;;;OASG;IACH,kBARW,OAAO,oBAAoB,EAAE,aAAa,WAC1C,OAAO,4BAA4B,EAAE,OAAO,gBAC5C,aAAa,kDAEb,MAAM,WACN,MAAM,YACN,OAAO,YAAY,EAAE,WAAW,EAoB1C;IARG,iDAAgB;IAOhB,uBAA0B;IAG9B;;OAEG;IACH,sDAIC;IAeD;;OAEG;IACH,mBAFW,8BAAM,QAOhB;IAqBD;;OAEG;IACH,+CAEC;IAED,yBAEC;IAED;;OAEG;IACH,wCAmCC;;CAwkBJ;qBA9vB0D,gBAAgB;sBADrD,wBAAwB;0BAEpB,qBAAqB"}
1
+ {"version":3,"file":"gridView.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/gridView.js"],"names":[],"mappings":"AAkzBA;;GAEG;AACH,+EAUC;AAED;;;;;GAKG;AACH,4CAJW,OAAO,wBAAwB,EAAE,OAAO,UACxC,OAAO,oBAAoB,EAAE,UAAU,YACvC,QAAQ,aAmBlB;AAr0BD;;;;;;;;;;;;;;;GAeG;AACH;IA6BI;;;;;;;;;OASG;IACH,kBARW,OAAO,oBAAoB,EAAE,aAAa,WAC1C,OAAO,4BAA4B,EAAE,OAAO,gBAC5C,aAAa,kDAEb,MAAM,WACN,MAAM,YACN,OAAO,YAAY,EAAE,WAAW,EAoB1C;IARG,iDAAgB;IAOhB,uBAA0B;IAG9B;;OAEG;IACH,sDAIC;IAeD;;OAEG;IACH,mBAFW,8BAAM,QAUhB;IA+BD;;OAEG;IACH,+CAEC;IAED,yBAEC;IAED;;OAEG;IACH,wCAmCC;;CAwkBJ;qBA3wB0D,gBAAgB;sBADrD,wBAAwB;0BAEpB,qBAAqB"}
@@ -118,6 +118,9 @@ export default class GridView extends ContainerView {
118
118
  * @param {View[]} views
119
119
  */
120
120
  setChildren(views) {
121
+ for (const gridChild of this.#children) {
122
+ this.#disposeGridChild(gridChild);
123
+ }
121
124
  this.#children = [];
122
125
  for (const view of views) {
123
126
  this.appendChild(view);
@@ -133,6 +136,7 @@ export default class GridView extends ContainerView {
133
136
  (gridChild) => gridChild.view == child
134
137
  );
135
138
  if (i >= 0) {
139
+ this.#disposeGridChild(this.#children[i]);
136
140
  this.#children[i] = new GridChild(
137
141
  replacement,
138
142
  this,
@@ -143,6 +147,15 @@ export default class GridView extends ContainerView {
143
147
  }
144
148
  }
145
149
 
150
+ /**
151
+ * @param {GridChild} gridChild
152
+ */
153
+ #disposeGridChild(gridChild) {
154
+ for (const view of gridChild.getChildren()) {
155
+ view.disposeSubtree();
156
+ }
157
+ }
158
+
146
159
  /**
147
160
  * Read-only view to children
148
161
  */
@@ -1,14 +1,18 @@
1
1
  export default class SelectionRect extends LayerView {
2
- /**
3
- * @typedef {import("../../spec/channel.js").PrimaryPositionalChannel} PrimaryPositionalChannel
4
- * @typedef {import("../../types/selectionTypes.js").IntervalSelection} IntervalSelection
5
- */
6
2
  /**
7
3
  * @param {import("./gridChild.js").default} gridChild
8
4
  * @param {import("../paramMediator.js").ExprRefFunction} selectionExpr
9
5
  * @param {import("../../spec/parameter.js").BrushConfig} [brushConfig]
10
6
  */
11
7
  constructor(gridChild: import("./gridChild.js").default, selectionExpr: import("../paramMediator.js").ExprRefFunction, brushConfig?: import("../../spec/parameter.js").BrushConfig);
8
+ /**
9
+ * @typedef {import("../../spec/channel.js").PrimaryPositionalChannel} PrimaryPositionalChannel
10
+ * @typedef {import("../../types/selectionTypes.js").IntervalSelection} IntervalSelection
11
+ */
12
+ /** @type {import("../paramMediator.js").ExprRefFunction} */
13
+ _selectionExpr: import("../paramMediator.js").ExprRefFunction;
14
+ /** @type {() => void} */
15
+ _selectionListener: () => void;
12
16
  }
13
17
  import LayerView from "../layerView.js";
14
18
  //# sourceMappingURL=selectionRect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"selectionRect.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/selectionRect.js"],"names":[],"mappings":"AAGA;IACI;;;OAGG;IAEH;;;;OAIG;IACH,uBAJW,OAAO,gBAAgB,EAAE,OAAO,iBAChC,OAAO,qBAAqB,EAAE,eAAe,gBAC7C,OAAO,yBAAyB,EAAE,WAAW,EA0IvD;CACJ;sBAtJqB,iBAAiB"}
1
+ {"version":3,"file":"selectionRect.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/selectionRect.js"],"names":[],"mappings":"AAGA;IAYI;;;;OAIG;IACH,uBAJW,OAAO,gBAAgB,EAAE,OAAO,iBAChC,OAAO,qBAAqB,EAAE,eAAe,gBAC7C,OAAO,yBAAyB,EAAE,WAAW,EAqJvD;IAnKD;;;OAGG;IAEH,4DAA4D;IAC5D,gBADW,OAAO,qBAAqB,EAAE,eAAe,CACzC;IAEf,yBAAyB;IACzB,oBADW,MAAM,IAAI,CACF;CAmKtB;sBA/KqB,iBAAiB"}
@@ -7,6 +7,12 @@ export default class SelectionRect extends LayerView {
7
7
  * @typedef {import("../../types/selectionTypes.js").IntervalSelection} IntervalSelection
8
8
  */
9
9
 
10
+ /** @type {import("../paramMediator.js").ExprRefFunction} */
11
+ _selectionExpr;
12
+
13
+ /** @type {() => void} */
14
+ _selectionListener;
15
+
10
16
  /**
11
17
  * @param {import("./gridChild.js").default} gridChild
12
18
  * @param {import("../paramMediator.js").ExprRefFunction} selectionExpr
@@ -135,7 +141,10 @@ export default class SelectionRect extends LayerView {
135
141
  }
136
142
  );
137
143
 
138
- selectionExpr.addListener(() => {
144
+ /** @type {import("../paramMediator.js").ExprRefFunction} */
145
+ this._selectionExpr = selectionExpr;
146
+
147
+ this._selectionListener = () => {
139
148
  const selection =
140
149
  /** @type {import("../../types/selectionTypes.js").IntervalSelection} */ (
141
150
  selectionExpr()
@@ -143,11 +152,27 @@ export default class SelectionRect extends LayerView {
143
152
 
144
153
  const datasource =
145
154
  /** @type {import("../../data/sources/inlineSource.js").default} */ (
146
- this.context.dataFlow.findDataSourceByKey(this)
155
+ this.flowHandle?.dataSource
147
156
  );
148
157
 
158
+ if (!datasource) {
159
+ throw new Error(
160
+ "Cannot find selection rect data source handle!"
161
+ );
162
+ }
163
+
149
164
  datasource.updateDynamicData(selectionToData(selection));
150
- });
165
+ };
166
+
167
+ selectionExpr.addListener(this._selectionListener);
168
+ }
169
+
170
+ /**
171
+ * @override
172
+ */
173
+ dispose() {
174
+ this._selectionExpr.removeListener(this._selectionListener);
175
+ super.dispose();
151
176
  }
152
177
  }
153
178
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=selectionRect.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectionRect.test.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/selectionRect.test.js"],"names":[],"mappings":""}
@@ -0,0 +1,87 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+
3
+ import ConcatView from "../concatView.js";
4
+ import UnitView from "../unitView.js";
5
+ import SelectionRect from "./selectionRect.js";
6
+ import { createTestViewContext } from "../testUtils.js";
7
+ import { buildDataFlow } from "../flowBuilder.js";
8
+ import { optimizeDataFlow } from "../../data/flowOptimizer.js";
9
+ import { syncFlowHandles } from "../../data/flowInit.js";
10
+
11
+ describe("SelectionRect", () => {
12
+ it("uses flow handles for dynamic data updates", () => {
13
+ const context = createTestViewContext();
14
+ const parent = new ConcatView(
15
+ { hconcat: [] },
16
+ context,
17
+ null,
18
+ null,
19
+ "p"
20
+ );
21
+
22
+ /** @type {import("../../spec/view.js").UnitSpec} */
23
+ const unitSpec = {
24
+ data: { values: [{ x: 0, y: 0 }] },
25
+ mark: "point",
26
+ encoding: {
27
+ x: { field: "x", type: "quantitative" },
28
+ y: { field: "y", type: "quantitative" },
29
+ },
30
+ };
31
+
32
+ const unitView = new UnitView(unitSpec, context, parent, parent, "u");
33
+
34
+ let selection = {
35
+ intervals: { x: [0, 1], y: [2, 3] },
36
+ };
37
+
38
+ /** @type {(listener: () => void) => void} */
39
+ const addListener = () => undefined;
40
+ /** @type {(listener: () => void) => void} */
41
+ const removeListener = () => undefined;
42
+ /** @type {() => void} */
43
+ const invalidate = () => undefined;
44
+
45
+ /** @type {import("../paramMediator.js").ExprRefFunction} */
46
+ const selectionExpr = Object.assign(() => selection, {
47
+ addListener,
48
+ removeListener,
49
+ invalidate,
50
+ identifier: () => "selection",
51
+ fields: [],
52
+ globals: [],
53
+ code: "selection",
54
+ });
55
+
56
+ const gridChild = /** @type {import("./gridChild.js").default} */ (
57
+ /** @type {unknown} */ ({
58
+ layoutParent: parent,
59
+ view: unitView,
60
+ })
61
+ );
62
+
63
+ const selectionRect = new SelectionRect(gridChild, selectionExpr);
64
+
65
+ const flow = buildDataFlow(selectionRect, context.dataFlow);
66
+ syncFlowHandles(selectionRect, optimizeDataFlow(flow));
67
+
68
+ const dataSource =
69
+ /** @type {import("../../data/sources/inlineSource.js").default} */ (
70
+ selectionRect.flowHandle?.dataSource
71
+ );
72
+ expect(dataSource).toBeDefined();
73
+
74
+ // Selection updates should push new interval data to the inline source.
75
+ const updateSpy = vi.spyOn(dataSource, "updateDynamicData");
76
+ selection = {
77
+ intervals: { x: [5, 6], y: [7, 8] },
78
+ };
79
+
80
+ selectionRect._selectionListener();
81
+
82
+ expect(updateSpy).toHaveBeenCalledTimes(1);
83
+ expect(updateSpy).toHaveBeenCalledWith([
84
+ { _x: 5, _x2: 6, _y: 7, _y2: 8 },
85
+ ]);
86
+ });
87
+ });
@@ -58,7 +58,7 @@ export function makeConstantExprRef(value: any): ExprRefFunction;
58
58
  * TODO: The proposed JavaScript signals may provide a better way to implement this.
59
59
  * https://github.com/proposal-signals/proposal-signals
60
60
  *
61
- * @typedef {import("../utils/expression.js").ExpressionFunction & { addListener: (listener: () => void) => void, invalidate: () => void, identifier: () => string}} ExprRefFunction
61
+ * @typedef {import("../utils/expression.js").ExpressionFunction & { addListener: (listener: () => void) => void, removeListener: (listener: () => void) => void, invalidate: () => void, identifier: () => string}} ExprRefFunction
62
62
  */
63
63
  export default class ParamMediator {
64
64
  /**
@@ -142,6 +142,7 @@ export default class ParamMediator {
142
142
  */
143
143
  export type ExprRefFunction = import("../utils/expression.js").ExpressionFunction & {
144
144
  addListener: (listener: () => void) => void;
145
+ removeListener: (listener: () => void) => void;
145
146
  invalidate: () => void;
146
147
  identifier: () => string;
147
148
  };
@@ -1 +1 @@
1
- {"version":3,"file":"paramMediator.d.ts","sourceRoot":"","sources":["../../../src/view/paramMediator.js"],"names":[],"mappings":"AAmVA;;;GAGG;AACH,6BAHW,GAAG,GACD,CAAC,IAAI,OAAO,sBAAsB,EAAE,OAAO,CAIvD;AAED;;;;;;;GAOG;AACH,+BAHa,CAAC,KADH,CAAC,GAAG,OAAO,sBAAsB,EAAE,OAAO,GAExC,CAAC,CAWb;AAED;;;GAGG;AACH,sFAFa,KAAK,IAAI,OAAO,sBAAsB,EAAE,iBAAiB,CAIrE;AAED;;;GAGG;AACH,uFAFa,KAAK,IAAI,OAAO,sBAAsB,EAAE,kBAAkB,CAItE;AAED;;;;;;;;;;GAUG;AACH,qCAF4E,CAAC,SAA/D,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,sBAAsB,EAAE,OAAO,CAAE,iBAJhE,aAAa,SACb,CAAC,aACD,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,IAAI,GAuCjB,CAAC,CACtB;AAED;;;;;;GAMG;AACH,4CAHW,MAAM,GACJ,MAAM,CAUlB;AAED;;;;;;;GAOG;AACH,2CAHW,GAAG,GACD,eAAe,CAW3B;AAtcD;;;;;;;;GAQG;AACH;IA2BI;;;;;OAKG;IACH,2BALW,MAAM,aAAa,EAU7B;IA7BD;;;OAGG;IACH,0BAHU,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,CAGvB;IA2Bf;;;OAGG;IACH,wEAzCqB,GAAG,KAAK,IAAI,CA2GhC;IAED;;;;;;;OAOG;IACH,eAFa,CAAC,aAJH,MAAM,gBACN,CAAC,YACD,OAAO,GACL,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAgC9B;IAED;;;OAGG;IACH,qBAFW,MAAM,WA1Ic,GAAG,KAAK,IAAI,CAkJ1C;IAED;;;OAGG;IACH,oBAFW,MAAM,OAIhB;IAED;;;OAGG;IACH,qBAFW,MAAM,OAKhB;IAED;;OAEG;IACH,oBACsB,WAAW,CAAC,MAAM,2CAAY,CAGnD;IAED;;;;OAIG;IACH,gCAHW,MAAM,GACJ,aAAa,CAQzB;IAID;;;;OAIG;IACH,uBAFW,MAAM,mBA4EhB;IAED;;;;OAIG;IACH,qBAFW,MAAM,OAKhB;IAED;;;;;OAKG;IACH,sBAFa,OAAO,CAiBnB;;CACJ;;;;;;;;8BA/TY,OAAO,wBAAwB,EAAE,kBAAkB,GAAG;IAAE,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,MAAM,CAAA;CAAC"}
1
+ {"version":3,"file":"paramMediator.d.ts","sourceRoot":"","sources":["../../../src/view/paramMediator.js"],"names":[],"mappings":"AA8VA;;;GAGG;AACH,6BAHW,GAAG,GACD,CAAC,IAAI,OAAO,sBAAsB,EAAE,OAAO,CAIvD;AAED;;;;;;;GAOG;AACH,+BAHa,CAAC,KADH,CAAC,GAAG,OAAO,sBAAsB,EAAE,OAAO,GAExC,CAAC,CAWb;AAED;;;GAGG;AACH,sFAFa,KAAK,IAAI,OAAO,sBAAsB,EAAE,iBAAiB,CAIrE;AAED;;;GAGG;AACH,uFAFa,KAAK,IAAI,OAAO,sBAAsB,EAAE,kBAAkB,CAItE;AAED;;;;;;;;;;GAUG;AACH,qCAF4E,CAAC,SAA/D,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,sBAAsB,EAAE,OAAO,CAAE,iBAJhE,aAAa,SACb,CAAC,aACD,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,IAAI,GAuCjB,CAAC,CACtB;AAED;;;;;;GAMG;AACH,4CAHW,MAAM,GACJ,MAAM,CAUlB;AAED;;;;;;;GAOG;AACH,2CAHW,GAAG,GACD,eAAe,CAY3B;AAldD;;;;;;;;GAQG;AACH;IA2BI;;;;;OAKG;IACH,2BALW,MAAM,aAAa,EAU7B;IA7BD;;;OAGG;IACH,0BAHU,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,CAGvB;IA2Bf;;;OAGG;IACH,wEAzCqB,GAAG,KAAK,IAAI,CA2GhC;IAED;;;;;;;OAOG;IACH,eAFa,CAAC,aAJH,MAAM,gBACN,CAAC,YACD,OAAO,GACL,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAgC9B;IAED;;;OAGG;IACH,qBAFW,MAAM,WA1Ic,GAAG,KAAK,IAAI,CAkJ1C;IAED;;;OAGG;IACH,oBAFW,MAAM,OAIhB;IAED;;;OAGG;IACH,qBAFW,MAAM,OAKhB;IAED;;OAEG;IACH,oBACsB,WAAW,CAAC,MAAM,2CAAY,CAGnD;IAED;;;;OAIG;IACH,gCAHW,MAAM,GACJ,aAAa,CAQzB;IAID;;;;OAIG;IACH,uBAFW,MAAM,mBAuFhB;IAED;;;;OAIG;IACH,qBAFW,MAAM,OAKhB;IAED;;;;;OAKG;IACH,sBAFa,OAAO,CAiBnB;;CACJ;;;;;;;;8BA1UY,OAAO,wBAAwB,EAAE,kBAAkB,GAAG;IAAE,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,MAAM,CAAA;CAAC"}
@@ -16,7 +16,7 @@ import {
16
16
  * TODO: The proposed JavaScript signals may provide a better way to implement this.
17
17
  * https://github.com/proposal-signals/proposal-signals
18
18
  *
19
- * @typedef {import("../utils/expression.js").ExpressionFunction & { addListener: (listener: () => void) => void, invalidate: () => void, identifier: () => string}} ExprRefFunction
19
+ * @typedef {import("../utils/expression.js").ExpressionFunction & { addListener: (listener: () => void) => void, removeListener: (listener: () => void) => void, invalidate: () => void, identifier: () => string}} ExprRefFunction
20
20
  */
21
21
  export default class ParamMediator {
22
22
  /**
@@ -280,6 +280,16 @@ export default class ParamMediator {
280
280
  }
281
281
  };
282
282
 
283
+ /**
284
+ * @param {() => void} listener
285
+ */
286
+ fn.removeListener = (listener) => {
287
+ for (const [param, mediator] of mediatorsForParams) {
288
+ mediator.paramListeners.get(param)?.delete(listener);
289
+ }
290
+ myListeners.delete(listener);
291
+ };
292
+
283
293
  /**
284
294
  * Detach listeners. This must be called if the expression is no longer used.
285
295
  * TODO: What if the expression is used in multiple places?
@@ -290,6 +300,7 @@ export default class ParamMediator {
290
300
  mediator.paramListeners.get(param)?.delete(listener);
291
301
  }
292
302
  }
303
+ myListeners.clear();
293
304
  };
294
305
 
295
306
  // TODO: This should contain unique identifier for each parameter.
@@ -457,6 +468,7 @@ export function validateParameterName(name) {
457
468
  export function makeConstantExprRef(value) {
458
469
  return Object.assign(() => value, {
459
470
  addListener: () => /** @type {void} */ (undefined),
471
+ removeListener: () => /** @type {void} */ (undefined),
460
472
  invalidate: () => /** @type {void} */ (undefined),
461
473
  identifier: () => "constant",
462
474
  fields: [],
@@ -87,6 +87,28 @@ describe("Single-level ParamMediator", () => {
87
87
  expect(result).toBe(51);
88
88
  });
89
89
 
90
+ test("Expression removeListener detaches a listener", () => {
91
+ const pm = new ParamMediator();
92
+ const setter = pm.allocateSetter("foo", 42);
93
+ const expr = pm.createExpression("foo + 1");
94
+
95
+ let calls = 0;
96
+
97
+ const listener = () => {
98
+ calls++;
99
+ };
100
+
101
+ expr.addListener(listener);
102
+
103
+ setter(50);
104
+ expect(calls).toBe(1);
105
+
106
+ expr.removeListener(listener);
107
+
108
+ setter(60);
109
+ expect(calls).toBe(1);
110
+ });
111
+
90
112
  test("Expression parameter handles dependencies", () => {
91
113
  const pm = new ParamMediator();
92
114
  const setter = pm.registerParam({ name: "foo", value: 42 });
@@ -66,6 +66,11 @@ export default class ScaleResolution implements ScaleResolutionApi {
66
66
  * @param {ScaleResolutionMember} newMember
67
67
  */
68
68
  addMember(newMember: ScaleResolutionMember): void;
69
+ /**
70
+ * @param {UnitView} view
71
+ * @returns {boolean}
72
+ */
73
+ removeMembersByView(view: import("./unitView.js").default): boolean;
69
74
  /**
70
75
  * Extracts and unions the data domains of all participating views.
71
76
  *
@@ -1 +1 @@
1
- {"version":3,"file":"scaleResolution.d.ts","sourceRoot":"","sources":["../../../src/view/scaleResolution.js"],"names":[],"mappings":"AAm/BA;;;;;;;;;;GAUG;AACH,6CAFW,OAAO,WAAW,EAAE,OAAO,GAAG,OAAO,WAAW,EAAE,OAAO,EAAE,QA4BrE;AA3+BD,2BAA4B,cAAc,CAAC;AAC3C,sBAAuB,SAAS,CAAC;AACjC,sBAAuB,SAAS,CAAC;AACjC,oBAAqB,OAAO,CAAC;AAC7B,oBAAqB,OAAO,CAAC;AAE7B;;;;;;;;GAQG;AACH;;;;;;;GAOG;AACH;IA4CI;;OAEG;IACH,2DASC;IARG,8CAAsB;IACtB,yDAAyD;IACzD,SADW,qBAAqB,EAAE,CACjB;IACjB,0FAA0F;IAC1F,MADW,OAAO,oBAAoB,EAAE,IAAI,CAC5B;IAEhB,iEAAiE;IACjE,MADW,MAAM,CACI;IAWzB,2BAMC;IAED;;;;;;;OAOG;IACH,4KAEC;IAED;;;OAGG;IACH,+KAEC;IAcD;;;;;OAKG;IACH,qBAFW,qBAAqB,QAqD/B;IA8MD;;;;OAIG;IACH,+DAOC;IAED;;OAEG;IACH,oBA6CC;IAED;;OAEG;IACH;eApakC,OAAO,kBAAkB,EAAE,KAAK;MA4cjE;IAED,mBAEC;IAED;;OAEG;IACH,oBAFa,mFAA6B,CAOzC;IAED;;;;OAIG;IACH,oBAKC;IAED;;OAEG;IACH,sBAGC;IAUD;;;;;;;OAOG;IACH,kBALW,MAAM,eACN,MAAM,OACN,MAAM,GACJ,OAAO,CAmEnB;IAED;;;;;;OAMG;IACH,eAJW,mFAA6B,aAC7B,OAAO,GAAG,MAAM,iBA0D1B;IAED;;;;OAIG;IACH,qBAcC;IAED;;;;;OAKG;IACH,uBAOC;IAED;;;;;;;OAOG;IACH,wBAoBC;IAiED;;;OAGG;IACH,aAFa,OAAO,qBAAqB,EAAE,OAAO,CAajD;IAID;;;;;OAKG;IACH,uBAFW,MAAM,yDAUhB;IAED;;OAEG;IACH,iBAFW,MAAM,yDAKhB;IAED;;;OAGG;IACH,qBAHW,MAAM,+CAAmB,GACvB,MAAM,CAQlB;IAED;;;OAGG;IACH,8BAHW,kFAA4B,GAC1B,MAAM,EAAE,CAOpB;;CACJ;kCAr2B+B,CAAC,SAApB,6CAAkB;;;;UAGrB,OAAO,eAAe,EAAE,OAAO;aAC/B,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB;sBAChD,CAAC,OAAO,+CAAkB,EAAE,IAAI,EAAE,OAAO,oBAAoB,EAAE,IAAI,kDAAgB"}
1
+ {"version":3,"file":"scaleResolution.d.ts","sourceRoot":"","sources":["../../../src/view/scaleResolution.js"],"names":[],"mappings":"AA6/BA;;;;;;;;;;GAUG;AACH,6CAFW,OAAO,WAAW,EAAE,OAAO,GAAG,OAAO,WAAW,EAAE,OAAO,EAAE,QA4BrE;AAr/BD,2BAA4B,cAAc,CAAC;AAC3C,sBAAuB,SAAS,CAAC;AACjC,sBAAuB,SAAS,CAAC;AACjC,oBAAqB,OAAO,CAAC;AAC7B,oBAAqB,OAAO,CAAC;AAE7B;;;;;;;;GAQG;AACH;;;;;;;GAOG;AACH;IA4CI;;OAEG;IACH,2DASC;IARG,8CAAsB;IACtB,yDAAyD;IACzD,SADW,qBAAqB,EAAE,CACjB;IACjB,0FAA0F;IAC1F,MADW,OAAO,oBAAoB,EAAE,IAAI,CAC5B;IAEhB,iEAAiE;IACjE,MADW,MAAM,CACI;IAWzB,2BAMC;IAED;;;;;;;OAOG;IACH,4KAEC;IAED;;;OAGG;IACH,+KAEC;IAcD;;;;;OAKG;IACH,qBAFW,qBAAqB,QAqD/B;IAED;;;OAGG;IACH,4DAFa,OAAO,CAMnB;IA8MD;;;;OAIG;IACH,+DAOC;IAED;;OAEG;IACH,oBA6CC;IAED;;OAEG;IACH;eA9akC,OAAO,kBAAkB,EAAE,KAAK;MAsdjE;IAED,mBAEC;IAED;;OAEG;IACH,oBAFa,mFAA6B,CAOzC;IAED;;;;OAIG;IACH,oBAKC;IAED;;OAEG;IACH,sBAGC;IAUD;;;;;;;OAOG;IACH,kBALW,MAAM,eACN,MAAM,OACN,MAAM,GACJ,OAAO,CAmEnB;IAED;;;;;;OAMG;IACH,eAJW,mFAA6B,aAC7B,OAAO,GAAG,MAAM,iBA0D1B;IAED;;;;OAIG;IACH,qBAcC;IAED;;;;;OAKG;IACH,uBAOC;IAED;;;;;;;OAOG;IACH,wBAoBC;IAiED;;;OAGG;IACH,aAFa,OAAO,qBAAqB,EAAE,OAAO,CAajD;IAID;;;;;OAKG;IACH,uBAFW,MAAM,yDAUhB;IAED;;OAEG;IACH,iBAFW,MAAM,yDAKhB;IAED;;;OAGG;IACH,qBAHW,MAAM,+CAAmB,GACvB,MAAM,CAQlB;IAED;;;OAGG;IACH,8BAHW,kFAA4B,GAC1B,MAAM,EAAE,CAOpB;;CACJ;kCA/2B+B,CAAC,SAApB,6CAAkB;;;;UAGrB,OAAO,eAAe,EAAE,OAAO;aAC/B,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB;sBAChD,CAAC,OAAO,+CAAkB,EAAE,IAAI,EAAE,OAAO,oBAAoB,EAAE,IAAI,kDAAgB"}
@@ -231,6 +231,16 @@ export default class ScaleResolution {
231
231
  this.members.push(newMember);
232
232
  }
233
233
 
234
+ /**
235
+ * @param {UnitView} view
236
+ * @returns {boolean}
237
+ */
238
+ removeMembersByView(view) {
239
+ const before = this.members.length;
240
+ this.members = this.members.filter((member) => member.view !== view);
241
+ return this.members.length !== before;
242
+ }
243
+
234
244
  /**
235
245
  * Returns true if the domain has been defined explicitly, i.e. not extracted from the data.
236
246
  */
@@ -1 +1 @@
1
- {"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../../../src/view/testUtils.js"],"names":[],"mappings":"AAiBA;;;GAGG;AACH,2DAHW,OAAO,kBAAkB,EAAE,kBAAkB,6CA+CvD;AAGS,uBAAC,CAAC,SAAS,OAAO,WAAW,EAAE,OAAO,QAAQ,QAAQ,aAAa;IAAE,KAAI,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE,uBAAuB,OAAO,kBAAkB,EAAE,kBAAkB,GAAK,OAAO,CAAC,CAAC,CAAC,CAAA;AAgBhL,oCAAC,CAAC,SAAS,OAAO,WAAW,EAAE,OAAO,QAAQ,QAAQ,aAAa;IAAE,KAAI,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE,YAAY,WAAW,YAAY;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAC,GAAK,OAAO,CAAC,CAAC,CAAC,CAAA;;;;;uBAhFpL,OAAO,iBAAiB,EAAE,QAAQ;;;;;0BAClC,OAAO,yBAAyB,EAAE,OAAO"}
1
+ {"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../../../src/view/testUtils.js"],"names":[],"mappings":"AAoBA;;;GAGG;AACH,2DAHW,OAAO,kBAAkB,EAAE,kBAAkB,6CAwDvD;AAGS,uBAAC,CAAC,SAAS,OAAO,WAAW,EAAE,OAAO,QAAQ,QAAQ,aAAa;IAAE,KAAI,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE,uBAAuB,OAAO,kBAAkB,EAAE,kBAAkB,GAAK,OAAO,CAAC,CAAC,CAAC,CAAA;AAgBhL,oCAAC,CAAC,SAAS,OAAO,WAAW,EAAE,OAAO,QAAQ,QAAQ,aAAa;IAAE,KAAI,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE,YAAY,WAAW,YAAY;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAC,GAAK,OAAO,CAAC,CAAC,CAAC,CAAA;;;;;uBA5FpL,OAAO,iBAAiB,EAAE,QAAQ;;;;;0BAClC,OAAO,yBAAyB,EAAE,OAAO"}
@@ -6,12 +6,15 @@
6
6
  * @typedef {import("../types/viewContext.js").default} ViewContext
7
7
  */
8
8
 
9
- import { checkForDuplicateScaleNames, initializeData } from "./viewUtils.js";
9
+ import { checkForDuplicateScaleNames } from "./viewUtils.js";
10
+ import {
11
+ initializeViewSubtree,
12
+ loadViewSubtreeData,
13
+ } from "../data/flowInit.js";
10
14
  import DataFlow from "../data/dataFlow.js";
11
15
  import { VIEW_ROOT_NAME, ViewFactory } from "./viewFactory.js";
12
16
  import GenomeStore from "../genome/genomeStore.js";
13
17
  import BmFontManager from "../fonts/bmFontManager.js";
14
- import { reconfigureScales } from "./scaleResolution.js";
15
18
  import UnitView from "./unitView.js";
16
19
  import ContainerView from "./containerView.js";
17
20
 
@@ -56,6 +59,15 @@ export function createTestViewContext(viewFactoryOptions = {}) {
56
59
  genomeStore,
57
60
 
58
61
  fontManager: new BmFontManager(),
62
+ animator: /** @type {import("../utils/animator.js").default} */ (
63
+ /** @type {any} */ ({
64
+ requestRender: /** @type {() => void} */ (() => undefined),
65
+ requestTransition:
66
+ /** @type {(callback: () => void) => void} */ (
67
+ (callback) => callback()
68
+ ),
69
+ })
70
+ ),
59
71
 
60
72
  isViewConfiguredVisible: () => true,
61
73
 
@@ -99,7 +111,7 @@ export async function createAndInitialize(spec, viewClass) {
99
111
  });
100
112
  }
101
113
 
102
- await initializeData(view, view.context.dataFlow);
103
- reconfigureScales(view);
114
+ const { dataSources } = initializeViewSubtree(view, view.context.dataFlow);
115
+ await loadViewSubtreeData(view, dataSources);
104
116
  return view;
105
117
  }
@@ -1 +1 @@
1
- {"version":3,"file":"unitView.d.ts","sourceRoot":"","sources":["../../../src/view/unitView.js"],"names":[],"mappings":"AA6BA;;;;GAIG;AACH,wBAHU,MAAM,CAAC,OAAO,iBAAiB,EAAE,QAAQ,EAAE,cAAc,kBAAkB,EAAE,OAAO,CAAC,CAc7F;AAEF;IAeI;;;;;;;;OAQG;IACH,kBAPW,OAAO,iBAAiB,EAAE,QAAQ,WAClC,OAAO,yBAAyB,EAAE,OAAO,gBACzC,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,WAAW,EAAE,OAAO,QAC3B,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAiCzC;IA5BG,yCAAgB;IAIZ,iDAAiD;IACjD,MADW,OAAO,kBAAkB,EAAE,OAAO,CACnB;IA4JlC,2DAIC;IAgBD;;;;;OAKG;IAEH,iEAsHC;IAED;;;;;OAKG;IACH,4IAEC;IAkBD;;OAEG;IACH,uDAEC;IAED;;;;;;;;;;;;;OAaG;IACH,uEAHW,OAAO,oBAAoB,EAAE,IAAI,iDAqB3C;IAED,uBAQC;IAgBD;;;;OAIG;IACH,8BAJW,MAAM,+DAEJ,OAAO,iBAAiB,EAAE,kBAAkB,CAKxD;;CACJ;iBAhdgB,WAAW"}
1
+ {"version":3,"file":"unitView.d.ts","sourceRoot":"","sources":["../../../src/view/unitView.js"],"names":[],"mappings":"AA6BA;;;;GAIG;AACH,wBAHU,MAAM,CAAC,OAAO,iBAAiB,EAAE,QAAQ,EAAE,cAAc,kBAAkB,EAAE,OAAO,CAAC,CAc7F;AAEF;IAeI;;;;;;;;OAQG;IACH,kBAPW,OAAO,iBAAiB,EAAE,QAAQ,WAClC,OAAO,yBAAyB,EAAE,OAAO,gBACzC,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,WAAW,EAAE,OAAO,QAC3B,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAyCzC;IApCG,yCAAgB;IAIZ,iDAAiD;IACjD,MADW,OAAO,kBAAkB,EAAE,OAAO,CACnB;IAoKlC,2DAIC;IAgBD;;;;;OAKG;IAEH,iEAsHC;IAwCD;;;;;OAKG;IACH,4IAMC;IAkBD;;OAEG;IACH,uDAEC;IAED;;;;;;;;;;;;;OAaG;IACH,uEAHW,OAAO,oBAAoB,EAAE,IAAI,iDAqB3C;IAED,uBAQC;IAgBD;;;;OAIG;IACH,8BAJW,MAAM,+DAEJ,OAAO,iBAAiB,EAAE,kBAAkB,CAKxD;;CACJ;iBAlgBgB,WAAW"}
@@ -88,14 +88,22 @@ export default class UnitView extends View {
88
88
  "zoomLevel",
89
89
  1.0
90
90
  );
91
- /** @type {import("../spec/channel.js").ChannelWithScale[]} */ ([
91
+
92
+ for (const channel of /** @type {import("../spec/channel.js").ChannelWithScale[]} */ ([
92
93
  "x",
93
94
  "y",
94
- ]).forEach((channel) =>
95
- this.getScaleResolution(channel)?.addEventListener("domain", () =>
96
- this.#zoomLevelSetter(Math.sqrt(this.getZoomLevel()))
97
- )
98
- );
95
+ ])) {
96
+ const resolution = this.getScaleResolution(channel);
97
+ if (resolution) {
98
+ const listener = () => {
99
+ this.#zoomLevelSetter(Math.sqrt(this.getZoomLevel()));
100
+ };
101
+ resolution.addEventListener("domain", listener);
102
+ this.registerDisposer(() =>
103
+ resolution.removeEventListener("domain", listener)
104
+ );
105
+ }
106
+ }
99
107
 
100
108
  this.needsAxes = { x: true, y: true };
101
109
 
@@ -380,6 +388,44 @@ export default class UnitView extends View {
380
388
  }
381
389
  }
382
390
 
391
+ /**
392
+ * @override
393
+ */
394
+ dispose() {
395
+ super.dispose();
396
+
397
+ this.#unresolve();
398
+ this.mark.dispose();
399
+ }
400
+
401
+ #unresolve() {
402
+ for (const view of this.getDataAncestors()) {
403
+ for (const [channel, resolution] of Object.entries(
404
+ view.resolutions.scale
405
+ )) {
406
+ if (
407
+ resolution &&
408
+ resolution.removeMembersByView(this) &&
409
+ resolution.members.length === 0
410
+ ) {
411
+ delete view.resolutions.scale[channel];
412
+ }
413
+ }
414
+
415
+ for (const [channel, resolution] of Object.entries(
416
+ view.resolutions.axis
417
+ )) {
418
+ if (
419
+ resolution &&
420
+ resolution.removeMembersByView(this) &&
421
+ resolution.members.length === 0
422
+ ) {
423
+ delete view.resolutions.axis[channel];
424
+ }
425
+ }
426
+ }
427
+ }
428
+
383
429
  /**
384
430
  * Returns an accessor that accesses a field or an evaluated expression,
385
431
  * if there is one.
@@ -387,7 +433,11 @@ export default class UnitView extends View {
387
433
  * @param {Channel} channel
388
434
  */
389
435
  getDataAccessor(channel) {
390
- return this.mark.encoders[channel]?.dataAccessor;
436
+ const encoders = this.mark.encoders;
437
+ if (!encoders) {
438
+ return undefined;
439
+ }
440
+ return encoders[channel]?.dataAccessor;
391
441
  }
392
442
 
393
443
  /**
@@ -410,7 +460,7 @@ export default class UnitView extends View {
410
460
  * Returns a collector that is associated with this view.
411
461
  */
412
462
  getCollector() {
413
- return this.context.dataFlow.findCollectorByKey(this);
463
+ return this.flowHandle?.collector;
414
464
  }
415
465
 
416
466
  /**
@@ -90,6 +90,10 @@ export default class View {
90
90
  */
91
91
  layersChildren?: boolean;
92
92
  };
93
+ /**
94
+ * @type {import("../data/flowHandle.js").FlowHandle | undefined}
95
+ */
96
+ flowHandle: import("../data/flowHandle.js").FlowHandle | undefined;
93
97
  /**
94
98
  * Whether GridView or equivalent should draw axis and grid lines for this view.
95
99
  * TODO: Use view options for this.
@@ -210,9 +214,21 @@ export default class View {
210
214
  */
211
215
  visit(visitor: Visitor): VisitResult;
212
216
  /**
213
- * Get all descendants of this view in depth-first order.
217
+ * Get this view and all descendants in depth-first order.
214
218
  */
215
219
  getDescendants(): View[];
220
+ /**
221
+ * Release resources owned by this view.
222
+ */
223
+ dispose(): void;
224
+ /**
225
+ * @param {() => void} disposer
226
+ */
227
+ registerDisposer(disposer: () => void): void;
228
+ /**
229
+ * Dispose this view and all descendants in post-order.
230
+ */
231
+ disposeSubtree(): void;
216
232
  /**
217
233
  * Called after all scales in the view hierarchy have been resolved.
218
234
  */
@@ -1 +1 @@
1
- {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/view/view.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/view/view.js"],"names":[],"mappings":"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"}