@genome-spy/core 0.30.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 -785
  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 -504
  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 -502
  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 -797
  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,167 +0,0 @@
1
- import clamp from "./clamp";
2
-
3
- const MAX_INTEGER = 2 ** 31 - 1;
4
- const MIN_INTEGER = -(2 ** 31);
5
-
6
- /**
7
- * @callback Lookup
8
- * @param {number} start
9
- * @param {number} end
10
- * @param {[number, number]} [arr] Store the result into this array (and return it)
11
- * @returns {[number, number]}
12
- */
13
-
14
- /**
15
- * A binned index for (overlapping) ranges that are sorted by their start position.
16
- * Each indexed range is associated with respective vertex indices.
17
- *
18
- * @param {number} size Number of bins
19
- * @param {[number, number]} domain Domain of positions
20
- * @param {(datum: T) => number} accessor Accessor for range's start position
21
- * @param {(datum: T) => number} [accessor2] Accessor for range's end position
22
- * @template T
23
- */
24
- export function createBinningRangeIndexer(
25
- size,
26
- domain,
27
- accessor,
28
- accessor2 = accessor
29
- ) {
30
- const startIndices = new Int32Array(size);
31
- startIndices.fill(MAX_INTEGER);
32
-
33
- let lastIndex = MIN_INTEGER;
34
- let unordered = false;
35
-
36
- const endIndices = new Int32Array(size);
37
-
38
- const start = domain[0];
39
- const domainLength = domain[1] - domain[0];
40
- const divisor = domainLength / size;
41
-
42
- /**
43
- * @param {number} pos
44
- * @param {boolean} end
45
- */
46
- const getBin = (pos, end) => {
47
- const unfloored = (pos - start) / divisor;
48
- const floored = Math.floor(unfloored);
49
-
50
- // Special handling for the end coordinate because we are using half-open ranges.
51
- return clamp(
52
- end && floored == unfloored ? floored - 1 : floored,
53
- 0,
54
- size - 1
55
- );
56
- };
57
-
58
- /**
59
- * Indexer for point items. Those have just a single coordinate.
60
- *
61
- * @param {T} datum
62
- * @param {number} startVertexIndex
63
- * @param {number} endVertexIndex
64
- */
65
- function binningIndexer(datum, startVertexIndex, endVertexIndex) {
66
- if (startVertexIndex > lastIndex) {
67
- lastIndex = startVertexIndex;
68
- } else if (!unordered) {
69
- unordered = true;
70
- // TODO: Contextual info like view path
71
- console.debug(
72
- "Items are not ordered properly. Disabling binned index."
73
- );
74
- }
75
-
76
- const value = accessor(datum);
77
- const bin = getBin(value, false);
78
-
79
- if (startIndices[bin] > startVertexIndex) {
80
- startIndices[bin] = startVertexIndex;
81
- }
82
-
83
- if (endIndices[bin] < endVertexIndex) {
84
- endIndices[bin] = endVertexIndex;
85
- }
86
- }
87
-
88
- /**
89
- * Indexer for ranged items. Those have both start and end coordinates.
90
- *
91
- * @param {T} datum
92
- * @param {number} startVertexIndex
93
- * @param {number} endVertexIndex
94
- */
95
- function binningRangeIndexer(datum, startVertexIndex, endVertexIndex) {
96
- if (startVertexIndex > lastIndex) {
97
- lastIndex = startVertexIndex;
98
- } else if (!unordered) {
99
- unordered = true;
100
- // TODO: Contextual info like view path
101
- console.debug(
102
- "Items are not ordered properly. Disabling binned index."
103
- );
104
- }
105
-
106
- const start = accessor(datum);
107
- const end = accessor2(datum);
108
- const startBin = getBin(start, false);
109
- const endBin = getBin(end, true);
110
-
111
- // TODO: This loop could probably be done as a more efficient post processing
112
- // step.
113
- for (let bin = startBin; bin <= endBin; bin++) {
114
- if (startIndices[bin] > startVertexIndex) {
115
- startIndices[bin] = startVertexIndex;
116
- }
117
-
118
- if (endIndices[bin] < endVertexIndex) {
119
- endIndices[bin] = endVertexIndex;
120
- }
121
- }
122
- }
123
-
124
- /**
125
- * @type {Lookup}
126
- */
127
- const lookup = (start, end, arr = [0, 0]) => {
128
- const startBin = getBin(start, false);
129
- const endBin = getBin(end, true);
130
- const startIndex = startIndices[startBin];
131
- const endIndex = Math.max(endIndices[endBin], startIndex);
132
-
133
- arr[0] = startIndex;
134
- arr[1] = endIndex;
135
- return arr;
136
- };
137
-
138
- const getIndex = () => {
139
- for (let i = 1; i < endIndices.length; i++) {
140
- if (endIndices[i] < endIndices[i - 1]) {
141
- endIndices[i] = endIndices[i - 1];
142
- }
143
- }
144
-
145
- let tail = true;
146
-
147
- for (let i = startIndices.length - 1; i > 0; i--) {
148
- if (tail && startIndices[i] == MAX_INTEGER) {
149
- startIndices[i] = endIndices[i];
150
- tail = false;
151
- } else if (startIndices[i - 1] > startIndices[i]) {
152
- startIndices[i - 1] = startIndices[i];
153
- }
154
- }
155
-
156
- return lookup;
157
- };
158
-
159
- binningIndexer.getIndex = getIndex;
160
- binningRangeIndexer.getIndex = getIndex;
161
-
162
- if (unordered) {
163
- return undefined;
164
- } else {
165
- return accessor == accessor2 ? binningIndexer : binningRangeIndexer;
166
- }
167
- }
@@ -1,155 +0,0 @@
1
- import { describe, expect, test } from "vitest";
2
- import { createBinningRangeIndexer } from "./binnedIndex.js";
3
-
4
- describe("Binning Indexer", () => {
5
- test("Single point is binned correctly", () => {
6
- const items = [25];
7
- const indexer = createBinningRangeIndexer(10, [0, 100], (x) => x);
8
-
9
- // Each item uses two vertices
10
- items.forEach((x, i) => indexer(x, i * 2, (i + 1) * 2));
11
-
12
- const index = indexer.getIndex();
13
-
14
- expect(index(1, 4)).toEqual([0, 0]);
15
- expect(index(23, 27)).toEqual([0, 2]);
16
- expect(index(13, 37)).toEqual([0, 2]);
17
- // TODO: MAX_INT could be replaced with the actual maximum vertex number
18
- expect(index(40, 42)).toEqual([2147483647, 2147483647]);
19
- });
20
-
21
- test("Multiple points are binned correctly", () => {
22
- const items = [0, 1, 4, 10, 35, 35, 36, 80];
23
- const indexer = createBinningRangeIndexer(10, [0, 100], (x) => x);
24
-
25
- // Each item uses two vertices
26
- items.forEach((x, i) => indexer(x, i * 2, (i + 1) * 2));
27
-
28
- const index = indexer.getIndex();
29
-
30
- expect(index(0, 0)).toEqual([0, 6]);
31
- expect(index(0, 1)).toEqual([0, 6]);
32
- expect(index(1, 2)).toEqual([0, 6]);
33
- expect(index(1, 15)).toEqual([0, 8]);
34
- expect(index(3, 6)).toEqual([0, 6]);
35
- expect(index(10, 15)).toEqual([6, 8]);
36
- expect(index(11, 38)).toEqual([6, 14]);
37
- expect(index(11, 45)).toEqual([6, 14]);
38
- expect(index(34, 36)).toEqual([8, 14]);
39
- expect(index(35.5, 36.5)).toEqual([8, 14]);
40
- expect(index(40, 50)).toEqual([14, 14]);
41
- expect(index(40, 85)).toEqual([14, 16]);
42
- expect(index(90, 100)).toEqual([16, 16]);
43
-
44
- expect(index(0, 100)).toEqual([0, 16]);
45
- expect(index(-1, 100)).toEqual([0, 16]);
46
- expect(index(0, 101)).toEqual([0, 16]);
47
- });
48
-
49
- test("Non-overlapping ranges are binned correctly", () => {
50
- const items = [
51
- [0, 5],
52
- [25, 48],
53
- [50, 55],
54
- [64, 67],
55
- [72, 75],
56
- [75, 78],
57
- [86, 90],
58
- [90, 93],
59
- ];
60
- const indexer = createBinningRangeIndexer(
61
- 10,
62
- [0, 100],
63
- (x) => x[0],
64
- (x) => x[1]
65
- );
66
-
67
- // Each item uses two vertices
68
- items.forEach((x, i) => indexer(x, i * 2, (i + 1) * 2));
69
-
70
- const index = indexer.getIndex();
71
-
72
- expect(index(0, 1)).toEqual([0, 2]);
73
- expect(index(3, 40)).toEqual([0, 4]);
74
- expect(index(6, 40)).toEqual([0, 4]);
75
- expect(index(15, 30)).toEqual([2, 4]);
76
- expect(index(50, 57)).toEqual([4, 6]);
77
- expect(index(62, 69)).toEqual([6, 8]);
78
- expect(index(69, 71)).toEqual([6, 12]);
79
- expect(index(69, 79)).toEqual([6, 12]);
80
-
81
- expect(index(80, 90)).toEqual([12, 14]);
82
- expect(index(90, 100)).toEqual([14, 16]);
83
-
84
- expect(index(0, 99)).toEqual([0, 16]);
85
- expect(index(0, 100)).toEqual([0, 16]);
86
- });
87
-
88
- test("Overlapping ranges with the same start coordinate are binned correctly", () => {
89
- const items = [
90
- // Increasing lengths
91
- [0, 5],
92
- [0, 64],
93
- [0, 80],
94
- // Decreasing lengths
95
- [100, 191],
96
- [100, 167],
97
- [100, 123],
98
- ];
99
- const indexer = createBinningRangeIndexer(
100
- 100,
101
- [0, 1000],
102
- (x) => x[0],
103
- (x) => x[1]
104
- );
105
-
106
- // Each item uses two vertices
107
- items.forEach((x, i) => indexer(x, i * 2, (i + 1) * 2));
108
-
109
- const index = indexer.getIndex();
110
-
111
- expect(index(0, 1)).toEqual([0, 6]);
112
- expect(index(3, 40)).toEqual([0, 6]);
113
- expect(index(0, 100)).toEqual([0, 6]);
114
- expect(index(77, 78)).toEqual([4, 6]);
115
-
116
- expect(index(90, 205)).toEqual([6, 12]);
117
- expect(index(111, 115)).toEqual([6, 12]);
118
- // Not optimal. Should be [6, 8], but [6, 12] is not wrong
119
- expect(index(180, 190)).toEqual([6, 12]);
120
- });
121
-
122
- test("Overlapping ranges are binned correctly", () => {
123
- const items = [
124
- [10, 30],
125
- [25, 50],
126
-
127
- [102, 129],
128
- [112, 139],
129
- [121, 149],
130
- ];
131
- const indexer = createBinningRangeIndexer(
132
- 100,
133
- [0, 1000],
134
- (x) => x[0],
135
- (x) => x[1]
136
- );
137
-
138
- items.forEach((x, i) => indexer(x, i * 2, (i + 1) * 2));
139
-
140
- const index = indexer.getIndex();
141
-
142
- // TODO: More tests
143
-
144
- expect(index(0, 5)).toEqual([0, 0]);
145
- expect(index(0, 15)).toEqual([0, 2]);
146
- expect(index(27, 40)).toEqual([0, 4]);
147
- expect(index(40, 50)).toEqual([2, 4]);
148
- expect(index(40, 80)).toEqual([2, 4]);
149
- expect(index(10, 29)).toEqual([0, 4]);
150
-
151
- expect(index(90, 160)).toEqual([4, 10]);
152
- expect(index(115, 116)).toEqual([4, 8]);
153
- expect(index(135, 145)).toEqual([6, 10]);
154
- });
155
- });
@@ -1,8 +0,0 @@
1
- /**
2
- * @param {number} value
3
- * @param {number} [min]
4
- * @param {number} [max]
5
- */
6
- export default function clamp(value, min = 0, max = 1) {
7
- return Math.max(min, Math.min(max, value));
8
- }
@@ -1,34 +0,0 @@
1
- /**
2
- * Creates a shallow-cloner function that ensures (hopefully) that the properties
3
- * end up into the in-object storage. Offers better performance than Object.assign
4
- * and saves memory.
5
- *
6
- * Read more at:
7
- * https://mrale.ph/blog/2014/07/30/constructor-vs-objectcreate.html
8
- *
9
- * @param {T} template The template object that
10
- * @returns {(function(T):T) & { properties: string[] }}
11
- * @template T
12
- */
13
- export default function createCloner(template) {
14
- // TODO: Check that only properties, not methods get cloned
15
- const properties = /** @type {string[]} */ (
16
- Object.keys(template).filter((k) => typeof k == "string")
17
- );
18
-
19
- const cloner = /** @type {(function(T):T) & { properties: string[] }} */ (
20
- new Function(
21
- "source",
22
- "return { " +
23
- properties
24
- .map((prop) => JSON.stringify(prop))
25
- .map((prop) => `${prop}: source[${prop}]`)
26
- .join(",\n") +
27
- " };"
28
- )
29
- );
30
-
31
- cloner.properties = properties;
32
-
33
- return cloner;
34
- }
@@ -1,24 +0,0 @@
1
- import { expect, test } from "vitest";
2
- import createCloner from "./cloner";
3
-
4
- const template = {
5
- a: 1,
6
- b: "xyzzy",
7
- 3: "iddqd",
8
- };
9
-
10
- test("Cloner clones object properly", () => {
11
- const makeClone = createCloner(template);
12
-
13
- expect(makeClone(template)).toEqual(template);
14
- expect(makeClone(template)).not.toBe(template);
15
-
16
- const another = {
17
- a: 2,
18
- b: "idkfa",
19
- 3: "hello",
20
- };
21
-
22
- expect(makeClone(another)).toEqual(another);
23
- expect(makeClone(another)).not.toBe(another);
24
- });
@@ -1,11 +0,0 @@
1
- /**
2
- *
3
- * @param {any[]} candidates
4
- */
5
- export default function coalesce(...candidates) {
6
- for (const candidate of candidates) {
7
- if (candidate !== undefined) {
8
- return candidate;
9
- }
10
- }
11
- }
@@ -1,16 +0,0 @@
1
- import { expect, test } from "vitest";
2
- import coalesce from "./coalesce";
3
-
4
- test("Coalesce returns first defined value", () => {
5
- expect(coalesce(0, 1, 2, 3)).toEqual(0);
6
- expect(coalesce(undefined, 1, 2, 3)).toEqual(1);
7
- expect(coalesce(undefined, undefined, 2, 3)).toEqual(2);
8
- });
9
-
10
- test("Coalesce returns undefined if input is all-undefined", () => {
11
- expect(coalesce(undefined, undefined)).toBeUndefined();
12
- });
13
-
14
- test("Coalesce returns undefined on empty input", () => {
15
- expect(coalesce()).toBeUndefined();
16
- });
@@ -1,26 +0,0 @@
1
- /**
2
- * @param {...Iterable<T>} iterables
3
- * @template T
4
- */
5
- export default function concatIterables(...iterables) {
6
- if (iterables.length <= 0) {
7
- return {
8
- *[Symbol.iterator]() {
9
- //
10
- },
11
- };
12
- }
13
-
14
- let currentIterable = iterables.shift();
15
-
16
- return {
17
- *[Symbol.iterator]() {
18
- do {
19
- for (const value of currentIterable) {
20
- yield value;
21
- }
22
- currentIterable = iterables.shift();
23
- } while (currentIterable);
24
- },
25
- };
26
- }
@@ -1,8 +0,0 @@
1
- import { expect, test } from "vitest";
2
- import concatIterables from "./concatIterables";
3
-
4
- test("ConcatIterables yields all elements in the correct order", () => {
5
- expect([...concatIterables([1, 2], [3, 4], [5, 6, 7], [-1000])]).toEqual([
6
- 1, 2, 3, 4, 5, 6, 7, -1000,
7
- ]);
8
- });
@@ -1,37 +0,0 @@
1
- /**
2
- * @param {(...args:T) => R} func
3
- * @param {number} wait
4
- * @template {any[]} T
5
- * @template R
6
- */
7
- export function debounce(func, wait, rejectOnDebounce = true) {
8
- /** @type {number} */
9
- let timeout;
10
-
11
- /** @type {(reason?: any) => void} */
12
- let rejectPrevious = (_) => undefined;
13
-
14
- /**
15
- * @param {T} args
16
- * @return {Promise<R>} */
17
- const debouncer = function debouncer(...args) {
18
- return new Promise((resolve, reject) => {
19
- const later = () => {
20
- clearTimeout(timeout);
21
- rejectPrevious = (_) => undefined;
22
-
23
- resolve(func(...args));
24
- };
25
-
26
- if (rejectOnDebounce) {
27
- rejectPrevious("debounced");
28
- }
29
- clearTimeout(timeout);
30
-
31
- rejectPrevious = reject;
32
- timeout = setTimeout(later, wait);
33
- });
34
- };
35
-
36
- return debouncer;
37
- }