@jbrowse/core 5.0.0-beta.3 → 5.0.0-beta.7

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 (110) hide show
  1. package/README.md +278 -250
  2. package/esm/PluginManager.js +1 -1
  3. package/esm/ReExports/publicUi.d.ts +1 -1
  4. package/esm/ReExports/publicUi.js +1 -1
  5. package/esm/ReExports/publicUtil.d.ts +1 -1
  6. package/esm/ReExports/publicUtil.js +1 -1
  7. package/esm/ReExports/workerNamespaceNames.js +3 -9
  8. package/esm/assemblyManager/assemblyConfigSchema.d.ts +2 -1
  9. package/esm/assemblyManager/assemblyConfigSchema.js +2 -1
  10. package/esm/assemblyManager/expandAssemblyConfigShorthand.d.ts +15 -15
  11. package/esm/assemblyManager/expandAssemblyConfigShorthand.js +34 -18
  12. package/esm/configuration/configurationSchema.d.ts +1 -2
  13. package/esm/configuration/configurationSchema.js +3 -8
  14. package/esm/configuration/configurationSlot.d.ts +0 -47
  15. package/esm/configuration/configurationSlot.js +4 -54
  16. package/esm/configuration/fillLocations.d.ts +14 -0
  17. package/esm/configuration/fillLocations.js +14 -0
  18. package/esm/configuration/fullConfSnapshot.d.ts +0 -15
  19. package/esm/configuration/fullConfSnapshot.js +0 -28
  20. package/esm/configuration/getConf.d.ts +4 -34
  21. package/esm/configuration/getConf.js +3 -38
  22. package/esm/configuration/index.d.ts +3 -4
  23. package/esm/configuration/index.js +3 -2
  24. package/esm/configuration/schemaRegistry.d.ts +1 -2
  25. package/esm/configuration/schemaRegistry.js +1 -2
  26. package/esm/configuration/slotFacade.d.ts +1 -16
  27. package/esm/configuration/slotFacade.js +1 -2
  28. package/esm/configuration/tabixShorthand.js +3 -3
  29. package/esm/configuration/types.d.ts +4 -16
  30. package/esm/data_adapters/CytobandAdapter/configSchema.js +3 -4
  31. package/esm/pluggableElementTypes/DisplayType.d.ts +5 -3
  32. package/esm/pluggableElementTypes/DisplayType.js +3 -1
  33. package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +30 -0
  34. package/esm/pluggableElementTypes/models/BaseTrackModel.js +45 -17
  35. package/esm/rpc/RpcRegistry.d.ts +7 -1
  36. package/esm/rpc/coreRpcMethods.d.ts +1 -0
  37. package/esm/rpc/coreRpcMethods.js +1 -0
  38. package/esm/rpc/methods/CoreEncodeFeatures.d.ts +15 -0
  39. package/esm/rpc/methods/CoreEncodeFeatures.js +62 -0
  40. package/esm/svg/svgId.d.ts +1 -1
  41. package/esm/svg/svgId.js +1 -1
  42. package/esm/ui/LegendSwatchGlyph.js +26 -21
  43. package/esm/ui/MenuTypes.d.ts +5 -52
  44. package/esm/ui/SizeSliderRow.d.ts +1 -3
  45. package/esm/ui/SizeSliderRow.js +4 -6
  46. package/esm/ui/SvgColorLegend.d.ts +9 -3
  47. package/esm/ui/SvgColorLegend.js +74 -33
  48. package/esm/ui/colorScale.d.ts +64 -0
  49. package/esm/ui/colorScale.js +41 -0
  50. package/esm/ui/colors.d.ts +11 -0
  51. package/esm/ui/colors.js +7 -0
  52. package/esm/ui/index.d.ts +5 -7
  53. package/esm/ui/index.js +3 -13
  54. package/esm/ui/legendMenuItem.d.ts +5 -16
  55. package/esm/ui/legendMenuItem.js +3 -14
  56. package/esm/ui/legendSpec.d.ts +11 -5
  57. package/esm/ui/legendSpec.js +8 -11
  58. package/esm/ui/makeSizeMenu.d.ts +0 -6
  59. package/esm/ui/makeSizeMenu.js +6 -30
  60. package/esm/ui/measureLegendText.js +1 -1
  61. package/esm/ui/menuItemAdornment.d.ts +9 -19
  62. package/esm/ui/menuItemAdornment.js +10 -31
  63. package/esm/ui/menuItems.d.ts +2 -6
  64. package/esm/ui/menuItems.js +0 -4
  65. package/esm/ui/palette.js +2 -1
  66. package/esm/ui/toggleMenuItems.d.ts +6 -13
  67. package/esm/ui/toggleMenuItems.js +13 -29
  68. package/esm/util/colorRamp.d.ts +3 -3
  69. package/esm/util/colorRamp.js +2 -2
  70. package/esm/util/featureTransforms.d.ts +15 -0
  71. package/esm/util/featureTransforms.js +342 -0
  72. package/esm/util/freezeDeep.d.ts +8 -10
  73. package/esm/util/freezeDeep.js +8 -10
  74. package/esm/util/glyphNames.d.ts +8 -0
  75. package/esm/util/glyphNames.js +12 -0
  76. package/esm/util/index.d.ts +0 -1
  77. package/esm/util/index.js +0 -1
  78. package/esm/util/markEncoding.d.ts +76 -0
  79. package/esm/util/markEncoding.js +436 -0
  80. package/esm/util/markEncodingTypes.d.ts +331 -0
  81. package/esm/util/markEncodingTypes.js +8 -0
  82. package/esm/util/renderToStaticMarkup.js +1 -1
  83. package/esm/util/starFusion.d.ts +26 -0
  84. package/esm/util/starFusion.js +37 -0
  85. package/esm/util/trackConfigDelta.d.ts +4 -8
  86. package/esm/util/trackConfigDelta.js +2 -4
  87. package/esm/util/tracks.d.ts +7 -1
  88. package/esm/util/tracks.js +72 -7
  89. package/esm/util/types/index.d.ts +12 -4
  90. package/esm/util/whenViewSettled.d.ts +40 -6
  91. package/esm/util/whenViewSettled.js +41 -5
  92. package/package.json +13 -3
  93. package/esm/configuration/promotableDefaults.d.ts +0 -234
  94. package/esm/configuration/promotableDefaults.js +0 -395
  95. package/esm/configuration/promotablePin.d.ts +0 -65
  96. package/esm/configuration/promotablePin.js +0 -1
  97. package/esm/configuration/promotableResolve.d.ts +0 -108
  98. package/esm/configuration/promotableResolve.js +0 -117
  99. package/esm/configuration/promotableSlots.d.ts +0 -12
  100. package/esm/configuration/promotableSlots.js +0 -45
  101. package/esm/configuration/slotShape.d.ts +0 -12
  102. package/esm/configuration/slotShape.js +0 -84
  103. package/esm/ui/PinAdornment.d.ts +0 -5
  104. package/esm/ui/PinAdornment.js +0 -67
  105. package/esm/ui/SvgGradientLegend.d.ts +0 -26
  106. package/esm/ui/SvgGradientLegend.js +0 -26
  107. package/esm/ui/promotablePinCoverage.d.ts +0 -58
  108. package/esm/ui/promotablePinCoverage.js +0 -124
  109. package/esm/util/openDisplays.d.ts +0 -23
  110. package/esm/util/openDisplays.js +0 -79
@@ -0,0 +1,342 @@
1
+ import { stringToJexlExpression } from './jexlStrings.js';
2
+ import SimpleFeature, { buildJexlContext } from './simpleFeature.js';
3
+ export const DEFAULT_BIN_AS = ['start', 'end'];
4
+ export const DEFAULT_COVERAGE_AS = 'coverage';
5
+ export const DEFAULT_STACK_AS = 'row';
6
+ export const DEFAULT_STACK_FIELDS = ['start', 'end'];
7
+ /**
8
+ * A feature with fields written over another's: what `formula` and `bin`
9
+ * produce, without copying the base feature's data per step.
10
+ */
11
+ class DerivedFeature {
12
+ base;
13
+ fields;
14
+ constructor(base, fields) {
15
+ this.base = base;
16
+ this.fields = fields;
17
+ }
18
+ get = ((name) => name in this.fields
19
+ ? this.fields[name]
20
+ : this.base.get(name));
21
+ id() {
22
+ return this.base.id();
23
+ }
24
+ parent() {
25
+ return this.base.parent?.();
26
+ }
27
+ children() {
28
+ return this.base.children?.();
29
+ }
30
+ toJSON() {
31
+ return { ...this.base.toJSON(), ...this.fields };
32
+ }
33
+ }
34
+ /**
35
+ * A feature a step made from nothing: what `aggregate` and `coverage` answer,
36
+ * carrying only the fields they wrote. `SimpleFeature`'s constructor costs
37
+ * more than the encode of what it builds, and nothing here needs its checks.
38
+ */
39
+ class MadeFeature {
40
+ data;
41
+ tag;
42
+ constructor(data, tag) {
43
+ this.data = data;
44
+ this.tag = tag;
45
+ }
46
+ get = ((name) => name === 'uniqueId' ? this.id() : this.data[name]);
47
+ id() {
48
+ const { refName, start, end } = this.data;
49
+ return `${String(refName)}:${String(start)}-${String(end)}${this.tag}`;
50
+ }
51
+ toJSON() {
52
+ return { ...this.data, uniqueId: this.id() };
53
+ }
54
+ }
55
+ function expression(expr, jexl) {
56
+ if (!jexl) {
57
+ throw new Error(`a jexl transform needs a jexl instance (${expr})`);
58
+ }
59
+ return stringToJexlExpression(expr, jexl);
60
+ }
61
+ function filter(features, expr, jexl) {
62
+ const compiled = expression(expr, jexl);
63
+ return features.filter(f => compiled.eval(buildJexlContext({ feature: f })));
64
+ }
65
+ function formula(features, expr, as, jexl) {
66
+ const compiled = expression(expr, jexl);
67
+ return features.map(f => new DerivedFeature(f, {
68
+ [as]: compiled.eval(buildJexlContext({ feature: f })),
69
+ }));
70
+ }
71
+ /**
72
+ * One element of a fanned-out array field, reading its own fields over the
73
+ * feature it came from: an exon that still knows its gene's name and strand.
74
+ */
75
+ class FlattenedFeature {
76
+ container;
77
+ item;
78
+ constructor(container, item) {
79
+ this.container = container;
80
+ this.item = item;
81
+ }
82
+ get = ((name) => {
83
+ const v = this.item.get(name);
84
+ return v === undefined ? this.container.get(name) : v;
85
+ });
86
+ id() {
87
+ return this.item.id();
88
+ }
89
+ parent() {
90
+ return this.container;
91
+ }
92
+ children() {
93
+ return this.item.children?.();
94
+ }
95
+ toJSON() {
96
+ return { ...this.container.toJSON(), ...this.item.toJSON() };
97
+ }
98
+ }
99
+ function flatten(features, step) {
100
+ const { field = 'subfeatures', index, keepEmpty } = step;
101
+ const out = [];
102
+ for (const f of features) {
103
+ const items = f.get(field);
104
+ if (!Array.isArray(items) || items.length === 0) {
105
+ if (keepEmpty) {
106
+ out.push(f);
107
+ }
108
+ continue;
109
+ }
110
+ for (const [i, item] of items.entries()) {
111
+ const child = typeof item?.get === 'function'
112
+ ? item
113
+ : new SimpleFeature({
114
+ ...item,
115
+ uniqueId: `${f.id()}#${i}`,
116
+ });
117
+ const flat = new FlattenedFeature(f, child);
118
+ out.push(index ? new DerivedFeature(flat, { [index]: i }) : flat);
119
+ }
120
+ }
121
+ return out;
122
+ }
123
+ function bin(features, step) {
124
+ const { field = 'start', step: size } = step;
125
+ if (!(size > 0)) {
126
+ throw new Error(`a bin step needs a positive size (${size})`);
127
+ }
128
+ const [asStart, asEnd] = step.as ?? DEFAULT_BIN_AS;
129
+ return features.map(f => {
130
+ const v = Number(f.get(field));
131
+ const start = Math.floor(v / size) * size;
132
+ return new DerivedFeature(f, { [asStart]: start, [asEnd]: start + size });
133
+ });
134
+ }
135
+ export function aggregateFieldName({ op, field, as }) {
136
+ return as ?? (op === 'count' || field === undefined ? op : `${op}_${field}`);
137
+ }
138
+ function groupMembers(features, groupby) {
139
+ if (groupby.length === 0) {
140
+ return features.length > 0 ? [[...features]] : [];
141
+ }
142
+ const last = groupby.length - 1;
143
+ const root = new Map();
144
+ const groups = [];
145
+ for (const f of features) {
146
+ let node = root;
147
+ for (let i = 0; i < last; i++) {
148
+ const v = f.get(groupby[i]);
149
+ let next = node.get(v);
150
+ if (!next) {
151
+ next = new Map();
152
+ node.set(v, next);
153
+ }
154
+ node = next;
155
+ }
156
+ const v = f.get(groupby[last]);
157
+ let members = node.get(v);
158
+ if (!members) {
159
+ members = [];
160
+ node.set(v, members);
161
+ groups.push(members);
162
+ }
163
+ members.push(f);
164
+ }
165
+ return groups;
166
+ }
167
+ function aggregate(features, step) {
168
+ const { groupby = [], ops } = step;
169
+ const out = [];
170
+ let serial = 0;
171
+ for (const members of groupMembers(features, groupby)) {
172
+ const first = members[0];
173
+ const refName = first.get('refName');
174
+ let start = Infinity;
175
+ let end = -Infinity;
176
+ for (const m of members) {
177
+ start = Math.min(start, m.get('start'));
178
+ end = Math.max(end, m.get('end'));
179
+ }
180
+ const data = {};
181
+ for (const field of groupby) {
182
+ data[field] = first.get(field);
183
+ }
184
+ for (const agg of ops) {
185
+ data[aggregateFieldName(agg)] = aggregateValue(members, agg);
186
+ }
187
+ out.push(new MadeFeature({ ...data, refName, start, end }, `#${serial++}`));
188
+ }
189
+ return out;
190
+ }
191
+ function aggregateValue(members, { op, field }) {
192
+ if (op === 'count') {
193
+ return members.length;
194
+ }
195
+ if (field === undefined) {
196
+ throw new Error(`an aggregate ${op} needs a field`);
197
+ }
198
+ let sum = 0;
199
+ let n = 0;
200
+ let min = Infinity;
201
+ let max = -Infinity;
202
+ for (const m of members) {
203
+ const v = Number(m.get(field));
204
+ if (!Number.isFinite(v)) {
205
+ continue;
206
+ }
207
+ sum += v;
208
+ n++;
209
+ min = Math.min(min, v);
210
+ max = Math.max(max, v);
211
+ }
212
+ switch (op) {
213
+ case 'sum': {
214
+ return sum;
215
+ }
216
+ case 'mean': {
217
+ return n > 0 ? sum / n : undefined;
218
+ }
219
+ case 'min': {
220
+ return n > 0 ? min : undefined;
221
+ }
222
+ case 'max': {
223
+ return n > 0 ? max : undefined;
224
+ }
225
+ }
226
+ }
227
+ /**
228
+ * The lowest row each feature fits on, greedy first fit in start order: the
229
+ * layout a pileup is, as a step in front of the encoder rather than a packer
230
+ * behind it. `rowEnds[r]` is where row `r` is free again, so the scan is over
231
+ * rows rather than over features.
232
+ */
233
+ function stack(features, step) {
234
+ const as = step.as ?? DEFAULT_STACK_AS;
235
+ const [startField, endField] = step.fields ?? DEFAULT_STACK_FIELDS;
236
+ const padding = step.padding ?? 0;
237
+ const out = [];
238
+ for (const members of groupMembers(features, step.groupby ?? [])) {
239
+ members.sort((a, b) => Number(a.get(startField)) - Number(b.get(startField)));
240
+ const rowEnds = [];
241
+ for (const f of members) {
242
+ const start = Number(f.get(startField));
243
+ const end = Number(f.get(endField));
244
+ let row = 0;
245
+ while (row < rowEnds.length && rowEnds[row] > start) {
246
+ row++;
247
+ }
248
+ rowEnds[row] = (end > start ? end : start) + padding;
249
+ out.push(new DerivedFeature(f, { [as]: row }));
250
+ }
251
+ }
252
+ return out;
253
+ }
254
+ /**
255
+ * Piecewise-constant depth over the features' spans: one feature per run of
256
+ * equal depth, where the depth is not zero. A sweep over the sorted edges,
257
+ * so the input need not be sorted.
258
+ */
259
+ function coverage(features, step) {
260
+ const as = step.as ?? DEFAULT_COVERAGE_AS;
261
+ const n = features.length;
262
+ if (n === 0) {
263
+ return [];
264
+ }
265
+ const starts = new Float64Array(n);
266
+ const ends = new Float64Array(n);
267
+ for (let i = 0; i < n; i++) {
268
+ starts[i] = features[i].get('start');
269
+ ends[i] = features[i].get('end');
270
+ }
271
+ starts.sort();
272
+ ends.sort();
273
+ const refName = features[0].get('refName');
274
+ const out = [];
275
+ let depth = 0;
276
+ let runStart = starts[0];
277
+ let si = 0;
278
+ let ei = 0;
279
+ const emit = (to) => {
280
+ if (depth > 0 && to > runStart) {
281
+ out.push(new MadeFeature({ refName, start: runStart, end: to, [as]: depth }, ''));
282
+ }
283
+ };
284
+ while (si < n || ei < n) {
285
+ const nextStart = si < n ? starts[si] : Infinity;
286
+ const nextEnd = ei < n ? ends[ei] : Infinity;
287
+ const at = Math.min(nextStart, nextEnd);
288
+ emit(at);
289
+ runStart = at;
290
+ while (si < n && starts[si] === at) {
291
+ depth++;
292
+ si++;
293
+ }
294
+ while (ei < n && ends[ei] === at) {
295
+ depth--;
296
+ ei++;
297
+ }
298
+ }
299
+ return out;
300
+ }
301
+ /**
302
+ * #api
303
+ * Run the transform steps over a feature list, in order, in the worker. The
304
+ * list a step answers is what the next one reads, and the last one is what
305
+ * the encoder walks.
306
+ */
307
+ export function runTransforms(features, steps, jexl) {
308
+ let current = features;
309
+ for (const step of steps) {
310
+ switch (step.type) {
311
+ case 'filter': {
312
+ current = filter(current, step.expr, jexl);
313
+ break;
314
+ }
315
+ case 'formula': {
316
+ current = formula(current, step.expr, step.as, jexl);
317
+ break;
318
+ }
319
+ case 'flatten': {
320
+ current = flatten(current, step);
321
+ break;
322
+ }
323
+ case 'bin': {
324
+ current = bin(current, step);
325
+ break;
326
+ }
327
+ case 'aggregate': {
328
+ current = aggregate(current, step);
329
+ break;
330
+ }
331
+ case 'coverage': {
332
+ current = coverage(current, step);
333
+ break;
334
+ }
335
+ case 'stack': {
336
+ current = stack(current, step);
337
+ break;
338
+ }
339
+ }
340
+ }
341
+ return current;
342
+ }
@@ -1,20 +1,18 @@
1
1
  /**
2
2
  * Freeze `value` and everything reachable from it, in place, and return it.
3
3
  *
4
- * For a value handed to consumers **by reference on purpose**: a config slot's
5
- * `promotedBase` (the one literal every track sitting at base resolves to) and a
6
- * stored user preference (a promoted display-type default, read by every
7
- * following display). Sharing the reference is load-bearing in both cases —
8
- * `===` stability is what lets a display's cached MobX computed re-resolve
4
+ * For a value handed to consumers **by reference on purpose**: a stored user
5
+ * preference, read by everything that follows it. Sharing the reference is
6
+ * load-bearing — `===` stability is what lets a cached MobX computed re-derive
9
7
  * without waking anything downstream — so handing out a defensive copy per read
10
8
  * would trade a silent hazard for a real re-render on every read. Freezing keeps
11
9
  * the identity and makes "nothing mutates this" throw rather than quietly
12
- * rewriting a value every other track is reading.
10
+ * rewriting a value every other reader sees.
13
11
  *
14
- * Both callers freeze once, at schema build or at the store write, over a value
15
- * that has to survive `postMessage` anyway — so the recursion is over small JSON
16
- * and costs nothing per read. Cyclic input terminates: each object is frozen
17
- * before its children are visited.
12
+ * The caller freezes once, at the store write, over a value that has to survive
13
+ * `postMessage` anyway — so the recursion is over small JSON and costs nothing
14
+ * per read. Cyclic input terminates: each object is frozen before its children
15
+ * are visited.
18
16
  *
19
17
  * **Unconditional, deliberately unlike MST's own `deepFreeze`** (whose body this
20
18
  * otherwise mirrors), which is gated on `devMode()`. MST gates because it freezes
@@ -6,20 +6,18 @@ function isObjectLike(value) {
6
6
  /**
7
7
  * Freeze `value` and everything reachable from it, in place, and return it.
8
8
  *
9
- * For a value handed to consumers **by reference on purpose**: a config slot's
10
- * `promotedBase` (the one literal every track sitting at base resolves to) and a
11
- * stored user preference (a promoted display-type default, read by every
12
- * following display). Sharing the reference is load-bearing in both cases —
13
- * `===` stability is what lets a display's cached MobX computed re-resolve
9
+ * For a value handed to consumers **by reference on purpose**: a stored user
10
+ * preference, read by everything that follows it. Sharing the reference is
11
+ * load-bearing — `===` stability is what lets a cached MobX computed re-derive
14
12
  * without waking anything downstream — so handing out a defensive copy per read
15
13
  * would trade a silent hazard for a real re-render on every read. Freezing keeps
16
14
  * the identity and makes "nothing mutates this" throw rather than quietly
17
- * rewriting a value every other track is reading.
15
+ * rewriting a value every other reader sees.
18
16
  *
19
- * Both callers freeze once, at schema build or at the store write, over a value
20
- * that has to survive `postMessage` anyway — so the recursion is over small JSON
21
- * and costs nothing per read. Cyclic input terminates: each object is frozen
22
- * before its children are visited.
17
+ * The caller freezes once, at the store write, over a value that has to survive
18
+ * `postMessage` anyway — so the recursion is over small JSON and costs nothing
19
+ * per read. Cyclic input terminates: each object is frozen before its children
20
+ * are visited.
23
21
  *
24
22
  * **Unconditional, deliberately unlike MST's own `deepFreeze`** (whose body this
25
23
  * otherwise mirrors), which is gated on `devMode()`. MST gates because it freezes
@@ -0,0 +1,8 @@
1
+ import type { GlyphName } from './markEncodingTypes.ts';
2
+ /**
3
+ * #api
4
+ * The `point` shape's glyph code for each name an encoding can say.
5
+ */
6
+ export declare const GLYPH_CODES: Record<GlyphName, number>;
7
+ /** The glyph names in range order: what an unlisted `range` hands out. */
8
+ export declare const GLYPH_NAMES: GlyphName[];
@@ -0,0 +1,12 @@
1
+ import { GLYPH_DIAMOND, GLYPH_DISC, GLYPH_TRIANGLE, } from '@jbrowse/render-core/shaders/pointMarkConsts';
2
+ /**
3
+ * #api
4
+ * The `point` shape's glyph code for each name an encoding can say.
5
+ */
6
+ export const GLYPH_CODES = {
7
+ disc: GLYPH_DISC,
8
+ triangle: GLYPH_TRIANGLE,
9
+ diamond: GLYPH_DIAMOND,
10
+ };
11
+ /** The glyph names in range order: what an unlisted `range` hands out. */
12
+ export const GLYPH_NAMES = Object.keys(GLYPH_CODES);
@@ -37,7 +37,6 @@ export { indexedDBAvailable, isElectron, isNode, rIC } from './environment.ts';
37
37
  export { isWebWorker } from './isWebWorker.ts';
38
38
  export { sessionStorageAvailable, sessionStorageGetItem, sessionStorageRemoveItem, sessionStorageSetItem, } from './sessionStorage.ts';
39
39
  export { isObject } from './objectUtils.ts';
40
- export { openPromotableDisplays } from './openDisplays.ts';
41
40
  export { type ReorderDirection, applyOrderWithin, reorder, reorderWithin, } from './reorder.ts';
42
41
  export { getStr } from './getStr.ts';
43
42
  export { downloadPhase, getLocationUri, resolveUri } from './getLocationUri.ts';
package/esm/util/index.js CHANGED
@@ -44,7 +44,6 @@ export { indexedDBAvailable, isElectron, isNode, rIC } from './environment.js';
44
44
  export { isWebWorker } from './isWebWorker.js';
45
45
  export { sessionStorageAvailable, sessionStorageGetItem, sessionStorageRemoveItem, sessionStorageSetItem, } from './sessionStorage.js';
46
46
  export { isObject } from './objectUtils.js';
47
- export { openPromotableDisplays } from './openDisplays.js';
48
47
  export { applyOrderWithin, reorder, reorderWithin, } from './reorder.js';
49
48
  export { getStr } from './getStr.js';
50
49
  export { downloadPhase, getLocationUri, resolveUri } from './getLocationUri.js';
@@ -0,0 +1,76 @@
1
+ import type { JexlInstance } from './jexlStrings.ts';
2
+ import type { ColorEncoding, Encoded, EncodedChannels, FieldRef, GlyphEncoding, LaneName, ValueEncoding } from './markEncodingTypes.ts';
3
+ import type { ProgressReporter } from './progress.ts';
4
+ import type { Feature } from './simpleFeature.ts';
5
+ export type { AggregateOp, AggregateStep, BinStep, CategoricalRef, ColorEncoding, CoverageStep, ColorScaleTable, CoreEncodeFeaturesArgs, Encoded, EncodedChannels, EncodedFeaturesResult, FieldRef, FilterStep, FormulaStep, GlyphEncoding, GlyphName, GlyphScaleTable, LaneName, LayerRequest, MarkEncoding, RampRef, ScaleTable, TransformStep, ValueEncoding, } from './markEncodingTypes.ts';
6
+ export declare const DEFAULT_MARK_COLOR = "#0068d1";
7
+ /**
8
+ * #api
9
+ * The key row a feature with nothing in a categorical field lands on, so the
10
+ * legend says why a mark is grey, or a disc, rather than listing a blank
11
+ * value.
12
+ */
13
+ export declare const NO_VALUE_LABEL = "(no value)";
14
+ /**
15
+ * #api
16
+ * A channel read per feature: the compiled form of a {@link FieldRef}, and
17
+ * what a display's own worker method hands the encoder for a channel no
18
+ * field name can say — a join against a second adapter, a lookup table, a
19
+ * rule over two fields.
20
+ */
21
+ export type ChannelReader<T = unknown> = (feature: Feature) => T;
22
+ /**
23
+ * #api
24
+ * What `encodeFeatures` takes: a {@link MarkEncoding}, any channel of which
25
+ * may be a {@link ChannelReader} in place of its declared form. The declared
26
+ * form is what crosses the wire; a reader is built in the worker.
27
+ */
28
+ export interface MarkEncodingInput {
29
+ x?: FieldRef | ChannelReader;
30
+ x2?: FieldRef | ChannelReader;
31
+ y?: ValueEncoding | ChannelReader;
32
+ row?: FieldRef | ChannelReader;
33
+ color?: ColorEncoding | ChannelReader<number>;
34
+ glyph?: GlyphEncoding | ChannelReader<number>;
35
+ }
36
+ /**
37
+ * #api
38
+ * What surrounds an encode: the jexl instance a `jexl:` channel compiles
39
+ * against — a caller whose channels are all readers or field names passes
40
+ * none — and a progress reporter.
41
+ */
42
+ export interface EncodeContext {
43
+ jexl?: JexlInstance;
44
+ report?: ProgressReporter;
45
+ }
46
+ /**
47
+ * #api
48
+ * The field a `y` declaration reads, whichever of its two forms it is
49
+ * written in.
50
+ */
51
+ export declare function valueField(y: ValueEncoding): FieldRef;
52
+ /**
53
+ * #api
54
+ * Evaluate one encoding over a feature list into dense channel arrays for
55
+ * the lanes named, the scale table each scaled channel came from, the `y`
56
+ * extremes and — when `index` is among the lanes — a hit index.
57
+ *
58
+ * A feature whose `x`, `x2` or (declared and asked-for) `y` is not finite is
59
+ * skipped and counted in `skipped`, so every array stays index-aligned with
60
+ * the Flatbush. Pure: the RPC around it owns the adapter, the filters and the
61
+ * transferables.
62
+ */
63
+ export declare function encodeFeatures<L extends LaneName>(features: readonly Feature[], encoding: MarkEncodingInput, lanes: readonly L[], ctx?: EncodeContext): Encoded<L>;
64
+ /**
65
+ * #api
66
+ * A CSS colour or `jexl:` colour expression as a per-feature packed ABGR —
67
+ * the unscaled arm of {@link ColorEncoding}, on its own for a display that
68
+ * carries a plain `color` slot.
69
+ */
70
+ export declare function colorEvaluator(color: string, jexl: JexlInstance | undefined): (feature: Feature) => number;
71
+ /**
72
+ * #api
73
+ * The buffers an {@link EncodedChannels} owns, for `rpcResult`'s transfer
74
+ * list.
75
+ */
76
+ export declare function encodedChannelTransferables(c: EncodedChannels): ArrayBufferLike[];