@genome-spy/core 0.29.0 → 0.30.2

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 (234) hide show
  1. package/dist/index.es.js +16373 -0
  2. package/dist/index.js +43 -43
  3. package/package.json +10 -7
  4. package/src/data/collector.js +0 -183
  5. package/src/data/collector.test.js +0 -84
  6. package/src/data/dataFlow.js +0 -148
  7. package/src/data/dataFlow.test.js +0 -5
  8. package/src/data/facetNode.js +0 -17
  9. package/src/data/flow.test.js +0 -72
  10. package/src/data/flowBatch.d.ts +0 -40
  11. package/src/data/flowNode.js +0 -283
  12. package/src/data/flowNode.test.js +0 -50
  13. package/src/data/flowOptimizer.js +0 -123
  14. package/src/data/flowOptimizer.test.js +0 -193
  15. package/src/data/flowTestUtils.js +0 -63
  16. package/src/data/formats/fasta.js +0 -32
  17. package/src/data/formats/fasta.test.js +0 -27
  18. package/src/data/sources/dataSource.js +0 -22
  19. package/src/data/sources/dataSourceFactory.js +0 -24
  20. package/src/data/sources/dataUtils.js +0 -78
  21. package/src/data/sources/dynamicCallbackSource.js +0 -57
  22. package/src/data/sources/dynamicSource.js +0 -37
  23. package/src/data/sources/inlineSource.js +0 -67
  24. package/src/data/sources/inlineSource.test.js +0 -56
  25. package/src/data/sources/namedSource.js +0 -79
  26. package/src/data/sources/sequenceSource.js +0 -46
  27. package/src/data/sources/sequenceSource.test.js +0 -46
  28. package/src/data/sources/urlSource.js +0 -74
  29. package/src/data/transforms/aggregate.js +0 -70
  30. package/src/data/transforms/clone.js +0 -40
  31. package/src/data/transforms/clone.test.js +0 -11
  32. package/src/data/transforms/coverage.js +0 -187
  33. package/src/data/transforms/coverage.test.js +0 -123
  34. package/src/data/transforms/filter.js +0 -37
  35. package/src/data/transforms/filter.test.js +0 -18
  36. package/src/data/transforms/filterScoredLabels.js +0 -134
  37. package/src/data/transforms/flattenCompressedExons.js +0 -57
  38. package/src/data/transforms/flattenDelimited.js +0 -74
  39. package/src/data/transforms/flattenDelimited.test.js +0 -87
  40. package/src/data/transforms/flattenSequence.js +0 -39
  41. package/src/data/transforms/flattenSequence.test.js +0 -34
  42. package/src/data/transforms/formula.js +0 -39
  43. package/src/data/transforms/formula.test.js +0 -19
  44. package/src/data/transforms/identifier.js +0 -108
  45. package/src/data/transforms/identifier.test.js +0 -83
  46. package/src/data/transforms/linearizeGenomicCoordinate.js +0 -101
  47. package/src/data/transforms/measureText.js +0 -44
  48. package/src/data/transforms/pileup.js +0 -128
  49. package/src/data/transforms/pileup.test.js +0 -70
  50. package/src/data/transforms/project.js +0 -41
  51. package/src/data/transforms/project.test.js +0 -32
  52. package/src/data/transforms/regexExtract.js +0 -61
  53. package/src/data/transforms/regexExtract.test.js +0 -67
  54. package/src/data/transforms/regexFold.js +0 -141
  55. package/src/data/transforms/regexFold.test.js +0 -160
  56. package/src/data/transforms/sample.js +0 -101
  57. package/src/data/transforms/sample.test.js +0 -38
  58. package/src/data/transforms/stack.js +0 -137
  59. package/src/data/transforms/stack.test.js +0 -91
  60. package/src/data/transforms/transformFactory.js +0 -60
  61. package/src/embedApi.d.ts +0 -67
  62. package/src/encoder/accessor.js +0 -82
  63. package/src/encoder/accessor.test.js +0 -47
  64. package/src/encoder/encoder.js +0 -394
  65. package/src/encoder/encoder.test.js +0 -98
  66. package/src/fonts/Lato-Regular.json +0 -1267
  67. package/src/fonts/Lato-Regular.png +0 -0
  68. package/src/fonts/OFL.txt +0 -93
  69. package/src/fonts/README.md +0 -3
  70. package/src/fonts/bmFont.d.ts +0 -58
  71. package/src/fonts/bmFontManager.js +0 -357
  72. package/src/fonts/bmFontMetrics.js +0 -108
  73. package/src/genome/genome.js +0 -317
  74. package/src/genome/genome.test.js +0 -188
  75. package/src/genome/genomeStore.js +0 -54
  76. package/src/genome/locusFormat.js +0 -31
  77. package/src/genome/scaleIndex.d.ts +0 -38
  78. package/src/genome/scaleIndex.js +0 -166
  79. package/src/genome/scaleIndex.test.js +0 -78
  80. package/src/genome/scaleLocus.d.ts +0 -11
  81. package/src/genome/scaleLocus.js +0 -108
  82. package/src/genome/scaleLocus.test.js +0 -4
  83. package/src/genomeSpy.js +0 -784
  84. package/src/gl/arrayBuilder.js +0 -199
  85. package/src/gl/dataToVertices.js +0 -636
  86. package/src/gl/includes/common.glsl +0 -63
  87. package/src/gl/includes/picking.fragment.glsl +0 -1
  88. package/src/gl/includes/picking.vertex.glsl +0 -27
  89. package/src/gl/includes/sampleFacet.glsl +0 -107
  90. package/src/gl/includes/scales.glsl +0 -112
  91. package/src/gl/link.fragment.glsl +0 -18
  92. package/src/gl/link.vertex.glsl +0 -111
  93. package/src/gl/point.fragment.glsl +0 -123
  94. package/src/gl/point.vertex.glsl +0 -129
  95. package/src/gl/rect.fragment.glsl +0 -51
  96. package/src/gl/rect.vertex.glsl +0 -114
  97. package/src/gl/rule.fragment.glsl +0 -52
  98. package/src/gl/rule.vertex.glsl +0 -89
  99. package/src/gl/text.fragment.glsl +0 -31
  100. package/src/gl/text.vertex.glsl +0 -246
  101. package/src/gl/webGLHelper.js +0 -489
  102. package/src/img/bowtie.svg +0 -1
  103. package/src/img/genomespy-favicon.svg +0 -34
  104. package/src/index.html +0 -11
  105. package/src/index.js +0 -128
  106. package/src/marks/link.js +0 -175
  107. package/src/marks/mark.js +0 -975
  108. package/src/marks/markUtils.js +0 -125
  109. package/src/marks/pointMark.js +0 -251
  110. package/src/marks/rectMark.js +0 -241
  111. package/src/marks/rule.js +0 -250
  112. package/src/marks/text.js +0 -278
  113. package/src/node_modules/.vitest/results.json +0 -1
  114. package/src/scale/colorUtils.js +0 -184
  115. package/src/scale/glslScaleGenerator.js +0 -488
  116. package/src/scale/scale.js +0 -451
  117. package/src/scale/scale.test.js +0 -324
  118. package/src/scale/ticks.js +0 -203
  119. package/src/scale/ticks.test.js +0 -40
  120. package/src/singlePageApp.js +0 -13
  121. package/src/spec/axis.d.ts +0 -296
  122. package/src/spec/channel.d.ts +0 -430
  123. package/src/spec/data.d.ts +0 -196
  124. package/src/spec/font.d.ts +0 -15
  125. package/src/spec/genome.d.ts +0 -35
  126. package/src/spec/mark.d.ts +0 -429
  127. package/src/spec/root.d.ts +0 -17
  128. package/src/spec/sampleView.d.ts +0 -180
  129. package/src/spec/scale.d.ts +0 -273
  130. package/src/spec/title.d.ts +0 -102
  131. package/src/spec/tooltip.d.ts +0 -9
  132. package/src/spec/transform.d.ts +0 -479
  133. package/src/spec/view.d.ts +0 -201
  134. package/src/styles/genome-spy.scss +0 -153
  135. package/src/tooltip/dataTooltipHandler.js +0 -64
  136. package/src/tooltip/refseqGeneTooltipHandler.js +0 -78
  137. package/src/tooltip/tooltipHandler.ts +0 -12
  138. package/src/types/filetypes.d.ts +0 -14
  139. package/src/types/flatqueue.d.ts +0 -53
  140. package/src/types/glsl.d.ts +0 -4
  141. package/src/types/internmap.d.ts +0 -22
  142. package/src/types/object.d.ts +0 -21
  143. package/src/types/vega-loader.d.ts +0 -1
  144. package/src/types/vega-scale.d.ts +0 -60
  145. package/src/utils/addBaseUrl.js +0 -19
  146. package/src/utils/addBaseUrl.test.js +0 -22
  147. package/src/utils/animator.js +0 -83
  148. package/src/utils/arrayUtils.js +0 -61
  149. package/src/utils/binnedIndex.js +0 -167
  150. package/src/utils/binnedIndex.test.js +0 -155
  151. package/src/utils/clamp.js +0 -8
  152. package/src/utils/cloner.js +0 -34
  153. package/src/utils/cloner.test.js +0 -24
  154. package/src/utils/coalesce.js +0 -11
  155. package/src/utils/coalesce.test.js +0 -16
  156. package/src/utils/concatIterables.js +0 -26
  157. package/src/utils/concatIterables.test.js +0 -8
  158. package/src/utils/debounce.js +0 -37
  159. package/src/utils/domainArray.js +0 -216
  160. package/src/utils/domainArray.test.js +0 -130
  161. package/src/utils/eerp.js +0 -13
  162. package/src/utils/expression.js +0 -32
  163. package/src/utils/field.js +0 -28
  164. package/src/utils/formatObject.js +0 -31
  165. package/src/utils/indexer.js +0 -43
  166. package/src/utils/indexer.test.js +0 -47
  167. package/src/utils/inertia.js +0 -124
  168. package/src/utils/interactionEvent.js +0 -33
  169. package/src/utils/iterateNestedMaps.js +0 -21
  170. package/src/utils/iterateNestedMaps.test.js +0 -33
  171. package/src/utils/kWayMerge.js +0 -42
  172. package/src/utils/kWayMerge.test.js +0 -26
  173. package/src/utils/layout/flexLayout.js +0 -368
  174. package/src/utils/layout/flexLayout.test.js +0 -311
  175. package/src/utils/layout/grid.js +0 -95
  176. package/src/utils/layout/grid.test.js +0 -71
  177. package/src/utils/layout/padding.js +0 -120
  178. package/src/utils/layout/point.js +0 -23
  179. package/src/utils/layout/rectangle.js +0 -288
  180. package/src/utils/layout/rectangle.test.js +0 -172
  181. package/src/utils/mergeObjects.js +0 -99
  182. package/src/utils/mergeObjects.test.js +0 -42
  183. package/src/utils/numberExtractor.js +0 -24
  184. package/src/utils/numberExtractor.test.js +0 -6
  185. package/src/utils/point.js +0 -14
  186. package/src/utils/propertyCacher.js +0 -70
  187. package/src/utils/propertyCacher.test.js +0 -85
  188. package/src/utils/propertyCoalescer.js +0 -42
  189. package/src/utils/propertyCoalescer.test.js +0 -22
  190. package/src/utils/reservationMap.js +0 -103
  191. package/src/utils/reservationMap.test.js +0 -20
  192. package/src/utils/scaleNull.js +0 -19
  193. package/src/utils/setOperations.js +0 -75
  194. package/src/utils/smoothstep.js +0 -10
  195. package/src/utils/throttle.js +0 -34
  196. package/src/utils/topK.js +0 -76
  197. package/src/utils/topK.test.js +0 -64
  198. package/src/utils/transition.js +0 -74
  199. package/src/utils/ui/tooltip.js +0 -189
  200. package/src/utils/url.js +0 -22
  201. package/src/utils/variableTools.js +0 -24
  202. package/src/utils/variableTools.test.js +0 -13
  203. package/src/view/axisResolution.js +0 -140
  204. package/src/view/axisResolution.test.js +0 -201
  205. package/src/view/axisView.js +0 -747
  206. package/src/view/concatView.js +0 -45
  207. package/src/view/containerView.js +0 -159
  208. package/src/view/facetView.js +0 -491
  209. package/src/view/flowBuilder.js +0 -367
  210. package/src/view/flowBuilder.test.js +0 -125
  211. package/src/view/gridView.js +0 -786
  212. package/src/view/implicitRootView.js +0 -14
  213. package/src/view/importView.js +0 -19
  214. package/src/view/layerView.js +0 -74
  215. package/src/view/rendering.d.ts +0 -44
  216. package/src/view/renderingContext/compositeViewRenderingContext.js +0 -51
  217. package/src/view/renderingContext/deferredViewRenderingContext.js +0 -176
  218. package/src/view/renderingContext/layoutRecorderViewRenderingContext.js +0 -128
  219. package/src/view/renderingContext/simpleViewRenderingContext.js +0 -64
  220. package/src/view/renderingContext/svgViewRenderingContext.js +0 -125
  221. package/src/view/renderingContext/viewRenderingContext.js +0 -41
  222. package/src/view/scaleResolution.js +0 -791
  223. package/src/view/scaleResolution.test.js +0 -572
  224. package/src/view/scaleResolutionApi.d.ts +0 -40
  225. package/src/view/testUtils.js +0 -51
  226. package/src/view/title.js +0 -165
  227. package/src/view/unitView.js +0 -382
  228. package/src/view/view.js +0 -612
  229. package/src/view/view.test.js +0 -214
  230. package/src/view/viewContext.d.ts +0 -62
  231. package/src/view/viewFactory.js +0 -181
  232. package/src/view/viewFactory.test.js +0 -17
  233. package/src/view/viewUtils.js +0 -327
  234. package/src/view/zoom.js +0 -89
@@ -1,32 +0,0 @@
1
- /**
2
- * A bare-bones FASTA-parser
3
- *
4
- * @typedef {object} SequenceEntry
5
- * @prop {string} identifier
6
- * @prop {string} sequence
7
- *
8
- * @param {string} data
9
- * @param {any} options
10
- * @returns {SequenceEntry[]}
11
- */
12
- export default function fasta(data, options) {
13
- /** @type {SequenceEntry[]} */
14
- const sequences = [];
15
-
16
- /** @type {SequenceEntry} */
17
- let currentEntry;
18
-
19
- for (const line of data.split("\n")) {
20
- if (line.startsWith(">")) {
21
- const identifier = line.match(/>(\S+)/)[1];
22
- currentEntry = { identifier, sequence: "" };
23
- sequences.push(currentEntry);
24
- } else if (currentEntry) {
25
- currentEntry.sequence += line.trim();
26
- } else {
27
- throw new Error("Invalid fasta file!");
28
- }
29
- }
30
-
31
- return sequences;
32
- }
@@ -1,27 +0,0 @@
1
- import { expect, test } from "vitest";
2
- import fasta from "./fasta";
3
-
4
- test("fasta", () => {
5
- const fileContent = `>A stuff
6
- --------------------------AGAGTTTGATCCTGGCTCAGGGTGAACGCTGGCG
7
- GCGTGC----TTAAGACATGCAAGTCGAACGG-CCT------TCTTCG-G-AAGGC-AGT
8
- ---------------------------------
9
- >B other stuff
10
- --------------------------AGAGTTTGATCATGGCTCAGGGTGAACGCTGGCG
11
- GCGTGC----TTAAGACATGCAAGTCGGACGA-TCG------GCTTCG---GCCGGTAGT
12
- ---------------------------------
13
- `;
14
-
15
- expect(fasta(fileContent)).toEqual([
16
- {
17
- identifier: "A",
18
- sequence:
19
- "--------------------------AGAGTTTGATCCTGGCTCAGGGTGAACGCTGGCGGCGTGC----TTAAGACATGCAAGTCGAACGG-CCT------TCTTCG-G-AAGGC-AGT---------------------------------",
20
- },
21
- {
22
- identifier: "B",
23
- sequence:
24
- "--------------------------AGAGTTTGATCATGGCTCAGGGTGAACGCTGGCGGCGTGC----TTAAGACATGCAAGTCGGACGA-TCG------GCTTCG---GCCGGTAGT---------------------------------",
25
- },
26
- ]);
27
- });
@@ -1,22 +0,0 @@
1
- import FlowNode from "../flowNode";
2
-
3
- export default class DataSource extends FlowNode {
4
- /**
5
- * @return {string}
6
- */
7
- get identifier() {
8
- return undefined;
9
- }
10
-
11
- /**
12
- *
13
- * @param {import("../flowNode").Datum} datum
14
- */
15
- handle(datum) {
16
- throw new Error("Source does not handle incoming data!");
17
- }
18
-
19
- async load() {
20
- // override
21
- }
22
- }
@@ -1,24 +0,0 @@
1
- import InlineSource, { isInlineData } from "./inlineSource";
2
- import UrlSource, { isUrlData } from "./urlSource";
3
- import SequenceSource, { isSequenceGenerator } from "./sequenceSource";
4
- import DynamicSource, { isDynamicData } from "./dynamicSource";
5
-
6
- /**
7
- * @param {Partial<import("../../spec/data").Data>} params
8
- * @param {string} [baseUrl]
9
- */
10
- export default function createDataSource(params, baseUrl) {
11
- if (isInlineData(params)) {
12
- return new InlineSource(params);
13
- } else if (isUrlData(params)) {
14
- return new UrlSource(params, baseUrl);
15
- } else if (isSequenceGenerator(params)) {
16
- return new SequenceSource(params);
17
- } else if (isDynamicData(params)) {
18
- return new DynamicSource();
19
- }
20
-
21
- throw new Error(
22
- "Cannot figure out the data source type: " + JSON.stringify(params)
23
- );
24
- }
@@ -1,78 +0,0 @@
1
- /**
2
- * Validates data source params, infers format if not specified explicitly,
3
- * returns a complete DataSource params object.
4
- *
5
- * @param {import("../../spec/data").DataSource} params
6
- * DataSource parameters
7
- */
8
- export function getFormat(params) {
9
- const format = { ...params.format };
10
-
11
- format.type ??= isUrlData(params) && extractTypeFromUrl(params.url);
12
- // @ts-expect-error
13
- format.parse ??= "auto";
14
-
15
- if (!format.type) {
16
- throw new Error(
17
- "Format for the data source was not defined and it could not be inferred: " +
18
- JSON.stringify(params)
19
- );
20
- }
21
-
22
- return format;
23
- }
24
-
25
- /**
26
- * @param {string | string[]} url
27
- */
28
- export function extractTypeFromUrl(url) {
29
- if (Array.isArray(url)) {
30
- url = url[0];
31
- }
32
-
33
- if (url) {
34
- return url.match(/\.(csv|tsv|json)/)?.[1];
35
- }
36
- }
37
-
38
- export const makeWrapper = (/** @type {any} */ d) =>
39
- typeof d != "object" ? scalarWrapper : nopWrapper;
40
-
41
- const scalarWrapper = (
42
- /** @type {import("@genome-spy/core/spec/channel").Scalar} */ x
43
- ) => ({ data: x });
44
-
45
- const nopWrapper = (/** @type {import("../flowNode").Datum} */ x) => x;
46
-
47
- /**
48
- * @param {import("../../spec/data").DataFormat} dataFormat
49
- * @return {dataFormat is import("../../spec/data").CsvDataFormat}
50
- */
51
- export function isCsvDataFormat(dataFormat) {
52
- return dataFormat.type == "csv" || dataFormat.type == "tsv";
53
- }
54
-
55
- /**
56
- * @param {import("../../spec/data").DataFormat} dataFormat
57
- * @return {dataFormat is import("../../spec/data").DsvDataFormat}
58
- */
59
- export function isDsvDataFormat(dataFormat) {
60
- return dataFormat.type == "dsv";
61
- }
62
-
63
- /**
64
- * @param {import("../../spec/data").DataFormat} dataFormat
65
- * @return {dataFormat is import("../../spec/data").JsonDataFormat}
66
- */
67
- export function isJsonDataFormat(dataFormat) {
68
- return dataFormat.type == "json";
69
- }
70
-
71
- /**
72
- *
73
- * @param {import("../../spec/data").DataSource} dataSource
74
- * @return {dataSource is import("../../spec/data").UrlData}
75
- */
76
- export function isUrlData(dataSource) {
77
- return "url" in dataSource;
78
- }
@@ -1,57 +0,0 @@
1
- import DataSource from "./dataSource";
2
- import { makeWrapper } from "./dataUtils";
3
-
4
- /**
5
- * @param {Partial<import("../../spec/data").Data>} data
6
- * @returns {data is import("../../spec/data").DynamicCallbackData}
7
- */
8
- export function isDynamicCallbackData(data) {
9
- return "dynamicCallbackSource" in data;
10
- }
11
-
12
- /**
13
- * A data source that retrieves the data from a callback that returns an iterable.
14
- */
15
- export default class DynamicCallbackSource extends DataSource {
16
- /**
17
- * @param {function():Iterable<any>} [callback] Function that provides the data
18
- */
19
- constructor(callback) {
20
- super();
21
-
22
- this.callback = callback;
23
- }
24
-
25
- loadSynchronously() {
26
- if (!this.callback) {
27
- return;
28
- }
29
-
30
- const iterable = this.callback();
31
-
32
- if (!iterable || typeof iterable[Symbol.iterator] !== "function") {
33
- throw new Error(
34
- "Dynamic data callback didn't return iterable data!"
35
- );
36
- }
37
-
38
- this.reset();
39
- this.beginBatch({ type: "file" });
40
-
41
- let wrap;
42
-
43
- for (const d of iterable) {
44
- if (!wrap) {
45
- wrap = makeWrapper(d);
46
- }
47
-
48
- this._propagate(wrap(d));
49
- }
50
-
51
- this.complete();
52
- }
53
-
54
- async load() {
55
- this.loadSynchronously();
56
- }
57
- }
@@ -1,37 +0,0 @@
1
- import DataSource from "./dataSource";
2
- import { makeWrapper } from "./dataUtils";
3
-
4
- /**
5
- * @param {Partial<import("../../spec/data").Data>} data
6
- * @returns {data is import("../../spec/data").DynamicData}
7
- */
8
- export function isDynamicData(data) {
9
- return "dynamicSource" in data;
10
- }
11
-
12
- export default class DynamicSource extends DataSource {
13
- /**
14
- *
15
- * @param {Iterable<any>} iterable
16
- */
17
- publishData(iterable) {
18
- this.reset();
19
- this.beginBatch({ type: "file" });
20
-
21
- let wrap;
22
-
23
- for (const d of iterable) {
24
- if (!wrap) {
25
- wrap = makeWrapper(d);
26
- }
27
-
28
- this._propagate(wrap(d));
29
- }
30
-
31
- this.complete();
32
- }
33
-
34
- async load() {
35
- // nop
36
- }
37
- }
@@ -1,67 +0,0 @@
1
- import { read } from "vega-loader";
2
- import { getFormat, makeWrapper } from "./dataUtils";
3
- import DataSource from "./dataSource";
4
-
5
- /**
6
- * @param {Partial<import("../../spec/data").Data>} data
7
- * @returns {data is import("../../spec/data").InlineData}
8
- */
9
- export function isInlineData(data) {
10
- return "values" in data;
11
- }
12
-
13
- export default class InlineSource extends DataSource {
14
- /**
15
- * @param {import("../../spec/data").InlineData} params
16
- */
17
- constructor(params) {
18
- super();
19
-
20
- this.params = params;
21
-
22
- if (typeof params.values == "string" && !params?.format?.type) {
23
- throw new Error(
24
- "Data format type (csv, dsv, ...) must be specified if a string is provided!"
25
- );
26
- }
27
- }
28
-
29
- loadSynchronously() {
30
- const values = this.params.values;
31
-
32
- let data = [];
33
-
34
- /** @type {(x: any) => import("../flowNode").Datum} */
35
- let wrap = (x) => x;
36
-
37
- if (Array.isArray(values)) {
38
- if (values.length > 0) {
39
- data = values;
40
- // TODO: Should check the whole array and abort if types are heterogeneous
41
- wrap = makeWrapper(values[0]);
42
- }
43
- } else if (typeof values == "object") {
44
- data = [values];
45
- } else if (typeof values == "string") {
46
- // It's a string that needs to be parsed
47
- data = read(values, getFormat(this.params));
48
- } else {
49
- throw new Error(
50
- '"values" in data configuration is not an array, object, or a string!'
51
- );
52
- }
53
-
54
- this.reset();
55
- this.beginBatch({ type: "file" });
56
-
57
- for (const d of data) {
58
- this._propagate(wrap(d));
59
- }
60
-
61
- this.complete();
62
- }
63
-
64
- async load() {
65
- this.loadSynchronously();
66
- }
67
- }
@@ -1,56 +0,0 @@
1
- import { expect, test } from "vitest";
2
- import Collector from "../collector";
3
- import InlineSource from "./inlineSource";
4
-
5
- /**
6
- * @param {InlineSource} source
7
- */
8
- async function collectSource(source) {
9
- const collector = new Collector();
10
- source.addChild(collector);
11
-
12
- await source.load();
13
-
14
- return [...collector.getData()];
15
- }
16
-
17
- test("InlineSource propagates an object", async () => {
18
- expect(await collectSource(new InlineSource({ values: { x: 1 } }))).toEqual(
19
- [{ x: 1 }]
20
- );
21
- });
22
-
23
- test("InlineSource propagates an array of objects", async () => {
24
- expect(
25
- await collectSource(new InlineSource({ values: [{ x: 1 }, { x: 2 }] }))
26
- ).toEqual([{ x: 1 }, { x: 2 }]);
27
- });
28
-
29
- test("InlineSource wraps scalars to objects", async () => {
30
- expect(await collectSource(new InlineSource({ values: [1, 2] }))).toEqual([
31
- { data: 1 },
32
- { data: 2 },
33
- ]);
34
- });
35
-
36
- test("InlineSource parses a string", async () => {
37
- expect(
38
- await collectSource(
39
- new InlineSource({
40
- values: "a\n1\n2\n3",
41
- format: {
42
- type: "csv",
43
- },
44
- })
45
- )
46
- ).toEqual([{ a: 1 }, { a: 2 }, { a: 3 }]);
47
- });
48
-
49
- test("InlineSource throws on a string and a missing format specifier", () => {
50
- expect(
51
- () =>
52
- new InlineSource({
53
- values: "a\n1\n2\n3",
54
- })
55
- ).toThrow();
56
- });
@@ -1,79 +0,0 @@
1
- import DataSource from "./dataSource";
2
- import { makeWrapper } from "./dataUtils";
3
-
4
- /**
5
- * @param {Partial<import("../../spec/data").Data>} data
6
- * @returns {data is import("../../spec/data").NamedData}
7
- */
8
- export function isNamedData(data) {
9
- return "name" in data;
10
- }
11
-
12
- export default class NamedSource extends DataSource {
13
- /**
14
- * Data that has been provided explicitly using the updateDynamicData method
15
- * @type {any[]}
16
- */
17
- #explicitData;
18
-
19
- /**
20
- * @param {import("../../spec/data").NamedData} params
21
- * @param {function(string):any[]} provider Function that retrieves a dataset using a name
22
- */
23
- constructor(params, provider) {
24
- super();
25
-
26
- this.provider = provider;
27
- this.params = params;
28
- }
29
-
30
- /**
31
- * @return {string}
32
- */
33
- get identifier() {
34
- return this.params.name;
35
- }
36
-
37
- /**
38
- * Update the named data. If data is omitted, a data provider is used instead.
39
- *
40
- * @param {import("../flowNode").Datum[]} [data]
41
- */
42
- updateDynamicData(data) {
43
- // TODO: Throw is data is undefined and the provider is unable to provide any data
44
- this.#explicitData = data;
45
- this.loadSynchronously();
46
- }
47
-
48
- loadSynchronously() {
49
- const data =
50
- this.#explicitData ?? this.provider(this.params.name) ?? [];
51
-
52
- /** @type {(x: any) => import("../flowNode").Datum} */
53
- let wrap = (x) => x;
54
-
55
- if (Array.isArray(data)) {
56
- if (data.length > 0) {
57
- // TODO: Should check the whole array and abort if types are heterogeneous
58
- wrap = makeWrapper(data[0]);
59
- }
60
- } else {
61
- throw new Error(
62
- `Named data "${this.params.name}" is not an array!`
63
- );
64
- }
65
-
66
- this.reset();
67
- this.beginBatch({ type: "file" });
68
-
69
- for (const d of data) {
70
- this._propagate(wrap(d));
71
- }
72
-
73
- this.complete();
74
- }
75
-
76
- async load() {
77
- this.loadSynchronously();
78
- }
79
- }
@@ -1,46 +0,0 @@
1
- import DataSource from "./dataSource";
2
-
3
- /**
4
- * @param {Partial<import("../../spec/data").Data>} data
5
- * @returns {data is import("../../spec/data").SequenceGenerator}
6
- */
7
- export function isSequenceGenerator(data) {
8
- return "sequence" in data;
9
- }
10
-
11
- export default class SequenceSource extends DataSource {
12
- /**
13
- *
14
- * @param {import("../../spec/data").SequenceGenerator} params
15
- */
16
- constructor(params) {
17
- super();
18
- this.sequence = params.sequence;
19
-
20
- if (!("start" in this.sequence)) {
21
- throw new Error("'start' is missing from sequence parameters!");
22
- }
23
- if (!("stop" in this.sequence)) {
24
- throw new Error("'stop' is missing from sequence parameters!");
25
- }
26
- }
27
-
28
- loadSynchronously() {
29
- const as = this.sequence.as || "data";
30
- const step = this.sequence.step || 1;
31
- const stop = this.sequence.stop;
32
-
33
- this.reset();
34
- this.beginBatch({ type: "file" });
35
-
36
- for (let x = this.sequence.start; x < stop; x += step) {
37
- this._propagate({ [as]: x });
38
- }
39
-
40
- this.complete();
41
- }
42
-
43
- async load() {
44
- this.loadSynchronously();
45
- }
46
- }
@@ -1,46 +0,0 @@
1
- import { expect, test } from "vitest";
2
- import Collector from "../collector";
3
- import SequenceSource from "./sequenceSource";
4
-
5
- /**
6
- * @param {SequenceSource} source
7
- */
8
- async function collectSource(source) {
9
- const collector = new Collector();
10
- source.addChild(collector);
11
-
12
- await source.load();
13
-
14
- return [...collector.getData()];
15
- }
16
-
17
- test("SequenceSource generates a sequence", async () => {
18
- expect(
19
- await collectSource(
20
- new SequenceSource({ sequence: { start: 0, stop: 3 } })
21
- )
22
- ).toEqual([{ data: 0 }, { data: 1 }, { data: 2 }]);
23
- });
24
-
25
- test("SequenceSource generates a sequence with a custom step", async () => {
26
- expect(
27
- await collectSource(
28
- new SequenceSource({ sequence: { start: 0, stop: 5, step: 2 } })
29
- )
30
- ).toEqual([{ data: 0 }, { data: 2 }, { data: 4 }]);
31
- });
32
-
33
- test("SequenceSource generates a sequence with a custom field name", async () => {
34
- expect(
35
- await collectSource(
36
- new SequenceSource({ sequence: { start: 0, stop: 3, as: "x" } })
37
- )
38
- ).toEqual([{ x: 0 }, { x: 1 }, { x: 2 }]);
39
- });
40
-
41
- test("SequenceSource throws on missing 'start' parameter", () => {
42
- expect(() => new SequenceSource({ sequence: { stop: 3 } })).toThrow();
43
- });
44
- test("SequenceSource throws on missing 'stop' parameter", () => {
45
- expect(() => new SequenceSource({ sequence: { start: 0 } })).toThrow();
46
- });
@@ -1,74 +0,0 @@
1
- import { loader as vegaLoader, read } from "vega-loader";
2
- import { getFormat } from "./dataUtils";
3
- import DataSource from "./dataSource";
4
-
5
- /**
6
- * @param {Partial<import("../../spec/data").Data>} data
7
- * @returns {data is import("../../spec/data").UrlData}
8
- */
9
- export function isUrlData(data) {
10
- return "url" in data;
11
- }
12
-
13
- export default class UrlSource extends DataSource {
14
- /**
15
- * @param {import("../../spec/data").UrlData} params
16
- * @param {string} [baseUrl]
17
- */
18
- constructor(params, baseUrl) {
19
- super();
20
-
21
- this.params = params;
22
- this.baseUrl = baseUrl;
23
- }
24
-
25
- get identifier() {
26
- return JSON.stringify({ params: this.params, baseUrl: this.baseUrl });
27
- }
28
-
29
- async load() {
30
- const url = this.params.url;
31
-
32
- /** @type {string[]} */
33
- const urls = Array.isArray(url) ? url : [url];
34
-
35
- /** @param {string} url */
36
- const load = async (url) =>
37
- // TODO: Support chunked loading
38
- /** @type {string} */ (
39
- vegaLoader({
40
- baseURL: this.baseUrl,
41
- })
42
- .load(url)
43
- .catch((/** @type {Error} */ e) => {
44
- // TODO: Include baseurl in the error message. Should be normalized, however.
45
- throw new Error(
46
- `Cannot fetch: ${this.baseUrl}${url}: ${e.message}`
47
- );
48
- })
49
- );
50
-
51
- /**
52
- * @param {string} text
53
- * @param {string} [url]
54
- */
55
- const readAndParse = (text, url) => {
56
- try {
57
- /** @type {any[]} */
58
- const data = read(text, getFormat(this.params));
59
- this.beginBatch({ type: "file", url: url });
60
- for (const d of data) {
61
- this._propagate(d);
62
- }
63
- } catch (e) {
64
- throw new Error(`Cannot parse: ${url}: ${e.message}`);
65
- }
66
- };
67
-
68
- this.reset();
69
-
70
- await Promise.all(urls.map((url) => load(url).then(readAndParse)));
71
-
72
- this.complete();
73
- }
74
- }