@jbrowse/core 5.0.0-beta.1 → 5.0.0-beta.3
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.
- package/README.md +112 -43
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts +2 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.d.ts +4 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.js +17 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/index.js +4 -3
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.d.ts +2 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.d.ts +2 -2
- package/esm/BaseFeatureWidget/index.d.ts +1 -1
- package/esm/BaseFeatureWidget/stateModelFactory.d.ts +8 -1
- package/esm/BaseFeatureWidget/stateModelFactory.js +6 -0
- package/esm/BaseFeatureWidget/types.d.ts +10 -2
- package/esm/PluginLoader.d.ts +1 -0
- package/esm/PluginLoader.js +52 -8
- package/esm/PluginManager.d.ts +99 -17
- package/esm/PluginManager.js +194 -26
- package/esm/ReExports/BaseFeatureDetails.js +1 -1
- package/esm/ReExports/MuiDataGridReExports.d.ts +1 -0
- package/esm/ReExports/MuiDataGridReExports.js +2 -2
- package/esm/ReExports/barrelOnlyNames.d.ts +5 -0
- package/esm/ReExports/barrelOnlyNames.js +63 -0
- package/esm/ReExports/modules.js +31 -109
- package/esm/ReExports/publicTracks.d.ts +1 -0
- package/esm/ReExports/publicTracks.js +14 -0
- package/esm/ReExports/publicUi.d.ts +4 -0
- package/esm/ReExports/publicUi.js +33 -0
- package/esm/ReExports/publicUtil.d.ts +1 -1
- package/esm/ReExports/publicUtil.js +8 -4
- package/esm/ReExports/sharedModules.d.ts +96 -0
- package/esm/ReExports/sharedModules.js +66 -0
- package/esm/ReExports/uiStub.d.ts +2 -0
- package/esm/ReExports/uiStub.js +11 -0
- package/esm/ReExports/workerModules.d.ts +2 -0
- package/esm/ReExports/workerModules.js +15 -0
- package/esm/ReExports/workerNamespaceNames.d.ts +11 -0
- package/esm/ReExports/workerNamespaceNames.js +281 -0
- package/esm/configuration/configurationSchema.d.ts +5 -38
- package/esm/configuration/configurationSchema.js +64 -40
- package/esm/configuration/index.d.ts +2 -2
- package/esm/configuration/index.js +1 -1
- package/esm/configuration/promotableDefaults.d.ts +54 -19
- package/esm/configuration/promotableDefaults.js +117 -48
- package/esm/configuration/promotablePin.d.ts +50 -40
- package/esm/configuration/promotableResolve.d.ts +1 -1
- package/esm/configuration/promotableResolve.js +1 -1
- package/esm/configuration/tabixIndexFields.d.ts +2 -2
- package/esm/configuration/tabixIndexFields.js +2 -2
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +12 -0
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +35 -4
- package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +41 -0
- package/esm/data_adapters/BaseAdapter/featureDensity.js +32 -0
- package/esm/data_adapters/BaseAdapter/index.d.ts +2 -1
- package/esm/data_adapters/BaseAdapter/index.js +1 -0
- package/esm/data_adapters/BaseAdapter/stats.d.ts +33 -1
- package/esm/data_adapters/BaseAdapter/stats.js +52 -13
- package/esm/data_adapters/BaseAdapter/types.d.ts +3 -8
- package/esm/pluggableElementTypes/AdapterType.d.ts +2 -1
- package/esm/pluggableElementTypes/AdapterType.js +1 -1
- package/esm/pluggableElementTypes/DisplayType.d.ts +4 -12
- package/esm/pluggableElementTypes/DisplayType.js +3 -10
- package/esm/pluggableElementTypes/LazyStateModelElement.d.ts +27 -0
- package/esm/pluggableElementTypes/LazyStateModelElement.js +71 -0
- package/esm/pluggableElementTypes/ViewType.d.ts +20 -4
- package/esm/pluggableElementTypes/ViewType.js +32 -4
- package/esm/pluggableElementTypes/extendElementType.d.ts +1 -2
- package/esm/pluggableElementTypes/extendElementType.js +9 -5
- package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +44 -3
- package/esm/pluggableElementTypes/models/BaseDisplayModel.js +75 -2
- package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +21 -0
- package/esm/pluggableElementTypes/models/BaseTrackModel.js +34 -2
- package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +49 -0
- package/esm/pluggableElementTypes/models/BaseViewModel.js +28 -0
- package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +14 -10
- package/esm/pluggableElementTypes/models/assertDisplayContract.js +25 -32
- package/esm/pluggableElementTypes/models/baseTrackConfig.js +7 -1
- package/esm/rpc/RpcRegistry.d.ts +10 -0
- package/esm/rpc/byteBudget.d.ts +9 -0
- package/esm/rpc/coreRpcMethods.d.ts +1 -0
- package/esm/rpc/coreRpcMethods.js +1 -0
- package/esm/rpc/methods/CoreGetFeatureDensity.d.ts +11 -0
- package/esm/rpc/methods/CoreGetFeatureDensity.js +22 -0
- package/esm/svg/svgReady.d.ts +1 -0
- package/esm/ui/BaseExportSvgDialog.d.ts +1 -1
- package/esm/ui/CascadingMenu.js +30 -8
- package/esm/ui/ErrorMessageStackTraceDialog.js +5 -6
- package/esm/ui/ExportSvgDialog.d.ts +1 -1
- package/esm/ui/LoadingOverlay.d.ts +14 -0
- package/esm/ui/LoadingOverlay.js +1 -1
- package/esm/ui/MenuTypes.d.ts +14 -5
- package/esm/ui/MenuTypes.js +3 -0
- package/esm/ui/PaletteContext.d.ts +11 -4
- package/esm/ui/PaletteContext.js +34 -5
- package/esm/ui/PinAdornment.js +31 -43
- package/esm/ui/ScrollChrome.d.ts +16 -0
- package/esm/ui/ScrollChrome.js +12 -0
- package/esm/ui/ScrollZoomToggle.d.ts +4 -3
- package/esm/ui/ScrollZoomToggle.js +4 -3
- package/esm/ui/SizeSliderRow.js +1 -1
- package/esm/ui/index.d.ts +3 -3
- package/esm/ui/index.js +4 -4
- package/esm/ui/launchViewMenu.js +7 -1
- package/esm/ui/legendMenuItem.d.ts +10 -16
- package/esm/ui/legendMenuItem.js +9 -20
- package/esm/ui/makeSizeMenu.js +1 -1
- package/esm/ui/menuItemAdornment.d.ts +2 -3
- package/esm/ui/menuItemAdornment.js +2 -3
- package/esm/ui/menuItems.d.ts +2 -3
- package/esm/ui/menuItems.js +1 -2
- package/esm/ui/palette.d.ts +11 -11
- package/esm/ui/palette.js +11 -11
- package/esm/ui/promotablePinCoverage.d.ts +16 -2
- package/esm/ui/promotablePinCoverage.js +40 -3
- package/esm/ui/theme.js +5 -0
- package/esm/ui/toggleMenuItems.d.ts +14 -9
- package/esm/ui/toggleMenuItems.js +32 -15
- package/esm/util/Base1DUtils.d.ts +4 -2
- package/esm/util/Base1DUtils.js +12 -4
- package/esm/util/SvgCanvas.js +4 -3
- package/esm/util/adapterConfigKey.d.ts +12 -0
- package/esm/util/adapterConfigKey.js +14 -0
- package/esm/util/adapterMetadata.js +2 -1
- package/esm/util/addAndShowTrack.d.ts +1 -1
- package/esm/util/addAndShowTrack.js +5 -1
- package/esm/util/addTrackFromWidget.js +2 -2
- package/esm/util/analytics.js +4 -5
- package/esm/util/cacheBudgets.d.ts +22 -19
- package/esm/util/cacheBudgets.js +22 -19
- package/esm/util/clampToContig.d.ts +17 -0
- package/esm/util/clampToContig.js +19 -0
- package/esm/util/colorBits.d.ts +2 -1
- package/esm/util/colorBits.js +2 -5
- package/esm/util/createStopTokenRotation.d.ts +9 -7
- package/esm/util/createStopTokenRotation.js +7 -27
- package/esm/util/featureTypes.d.ts +24 -0
- package/esm/util/featureTypes.js +35 -0
- package/esm/util/fetchContext.d.ts +2 -2
- package/esm/util/fetchContext.js +2 -2
- package/esm/util/fetchPhases.d.ts +10 -10
- package/esm/util/hooks.d.ts +8 -0
- package/esm/util/hooks.js +27 -0
- package/esm/util/index.d.ts +6 -5
- package/esm/util/index.js +5 -4
- package/esm/util/installFetch.d.ts +71 -34
- package/esm/util/installFetch.js +57 -29
- package/esm/util/installInitAutorun.d.ts +14 -13
- package/esm/util/installInitAutorun.js +17 -17
- package/esm/util/installPrerequisiteFetch.d.ts +86 -0
- package/esm/util/installPrerequisiteFetch.js +73 -0
- package/esm/util/lazyAfterAttach.d.ts +13 -0
- package/esm/util/lazyAfterAttach.js +31 -0
- package/esm/util/legendCandidates.d.ts +50 -0
- package/esm/util/legendCandidates.js +87 -0
- package/esm/util/mstUtils.d.ts +12 -1
- package/esm/util/mstUtils.js +20 -2
- package/esm/util/openFeatureWidget.d.ts +5 -0
- package/esm/util/openFeatureWidget.js +1 -0
- package/esm/util/openViews.d.ts +16 -0
- package/esm/util/openViews.js +22 -0
- package/esm/util/parentWalk.d.ts +1 -1
- package/esm/util/parentWalk.js +1 -1
- package/esm/util/pluginStore.d.ts +1 -0
- package/esm/util/pluginStore.js +8 -1
- package/esm/util/range.d.ts +13 -9
- package/esm/util/range.js +17 -8
- package/esm/util/renderToStaticMarkup.js +10 -0
- package/esm/util/rxjs.d.ts +16 -0
- package/esm/util/rxjs.js +49 -0
- package/esm/util/scheduleDetachedDestroy.d.ts +18 -0
- package/esm/util/scheduleDetachedDestroy.js +24 -0
- package/esm/util/scrollLatch.d.ts +1 -0
- package/esm/util/scrollLatch.js +8 -0
- package/esm/util/stopToken.d.ts +6 -5
- package/esm/util/tabix.d.ts +10 -4
- package/esm/util/tabix.js +11 -5
- package/esm/util/trackConfigDelta.d.ts +6 -6
- package/esm/util/trackConfigDelta.js +3 -3
- package/esm/util/tracks.d.ts +48 -0
- package/esm/util/tracks.js +192 -66
- package/esm/util/types/index.d.ts +58 -10
- package/esm/util/types/index.js +3 -0
- package/esm/util/unknownSnapshotKeys.d.ts +36 -0
- package/esm/util/unknownSnapshotKeys.js +69 -0
- package/esm/util/usePanelVirtualScroll.d.ts +6 -2
- package/esm/util/usePanelVirtualScroll.js +6 -2
- package/esm/util/useRowVirtualScroll.d.ts +1 -1
- package/esm/util/useRowVirtualScroll.js +1 -1
- package/esm/util/useVirtualScrollWheel.js +11 -1
- package/esm/util/viewStatus.d.ts +23 -0
- package/esm/util/viewStatus.js +17 -0
- package/esm/util/wheelZoom.d.ts +3 -1
- package/esm/util/wheelZoom.js +39 -14
- package/esm/util/whenViewSettled.d.ts +17 -4
- package/esm/util/whenViewSettled.js +19 -6
- package/esm/util/withLaunchInput.d.ts +168 -0
- package/esm/util/withLaunchInput.js +273 -0
- package/package.json +19 -11
- package/esm/ui/promotableMenuItems.d.ts +0 -19
- package/esm/ui/promotableMenuItems.js +0 -89
- package/esm/util/applyInitSettings.d.ts +0 -79
- package/esm/util/applyInitSettings.js +0 -91
package/esm/ui/palette.js
CHANGED
|
@@ -231,16 +231,16 @@ const darkNeutrals = {
|
|
|
231
231
|
export const colorFwdStrand = '#EC8B8B';
|
|
232
232
|
/** #color alignments-strand | Reverse strand | Read maps to the reverse strand */
|
|
233
233
|
export const colorRevStrand = '#8F8FD8';
|
|
234
|
-
/** #color alignments-pair-orientation | LR (→
|
|
234
|
+
/** #color alignments-pair-orientation | LR (→ ←) | Normal proper pair */
|
|
235
235
|
export const colorPairLR = '#d3d3d3';
|
|
236
236
|
// Dimmer grey for dark mode: the light #d3d3d3 reads as near-white glaring
|
|
237
237
|
// blocks against a dark track background. Wired into the dark alignmentFill.
|
|
238
238
|
export const colorPairLRDark = '#8a8a8a';
|
|
239
|
-
/** #color alignments-pair-orientation | RL (←
|
|
239
|
+
/** #color alignments-pair-orientation | RL (← →) | Mates point away from each other */
|
|
240
240
|
export const colorPairRL = '#0099bb';
|
|
241
|
-
/** #color alignments-pair-orientation | LL (→
|
|
241
|
+
/** #color alignments-pair-orientation | LL (→ →) | Both mates on the forward strand */
|
|
242
242
|
export const colorPairLL = '#4d9a4d';
|
|
243
|
-
/** #color alignments-pair-orientation | RR (←
|
|
243
|
+
/** #color alignments-pair-orientation | RR (← ←) | Both mates on the reverse strand */
|
|
244
244
|
export const colorPairRR = '#5555bb';
|
|
245
245
|
// Was `colorNostrand`, which named the one thing it essentially never paints. A
|
|
246
246
|
// SAM record's strand is DEFINED from the reverse flag inside the adapter's
|
|
@@ -266,8 +266,8 @@ export const colorPairRR = '#5555bb';
|
|
|
266
266
|
// settle it, and the dark-mode half is `agent-docs/TODO.md`.
|
|
267
267
|
export const colorNeutralRead = '#c8c8c8';
|
|
268
268
|
/**
|
|
269
|
-
* #color alignments-pair-orientation | Inter-chromosomal | Mate
|
|
270
|
-
* #color alignments-insert-size | Mate on
|
|
269
|
+
* #color alignments-pair-orientation | Inter-chromosomal | Mate on another chromosome
|
|
270
|
+
* #color alignments-insert-size | Inter-chromosomal | Mate on another chromosome
|
|
271
271
|
*/
|
|
272
272
|
// THIS SLOT AND `colorUnmappedMate` WERE CHOSEN TOGETHER, and reading either one
|
|
273
273
|
// alone is how the previous pair got stuck. Both are warm, both belong to all
|
|
@@ -299,9 +299,9 @@ export const colorNeutralRead = '#c8c8c8';
|
|
|
299
299
|
// neighbour that must not be confusable: red means "insert too long", and a
|
|
300
300
|
// second red would read as a second statement about insert size.
|
|
301
301
|
export const colorInterchrom = '#af4d19';
|
|
302
|
-
/** #color alignments-insert-size | Insert larger than expected |
|
|
302
|
+
/** #color alignments-insert-size | Insert larger than expected | Deletion between the mates */
|
|
303
303
|
export const colorLongInsert = '#ff0000';
|
|
304
|
-
/** #color alignments-insert-size | Insert smaller than expected |
|
|
304
|
+
/** #color alignments-insert-size | Insert smaller than expected | Insertion between the mates */
|
|
305
305
|
// This slot has TWO neighbours it must stay clear of, and every past value has
|
|
306
306
|
// solved one by walking into the other. They sit at opposite ends of the
|
|
307
307
|
// lightness axis, which is what makes it a balance rather than a direction:
|
|
@@ -349,8 +349,8 @@ export const colorLongInsert = '#ff0000';
|
|
|
349
349
|
// them.
|
|
350
350
|
export const colorShortInsert = '#f582c0';
|
|
351
351
|
/**
|
|
352
|
-
* #color alignments-pair-orientation | Mate unmapped |
|
|
353
|
-
* #color alignments-insert-size | Mate unmapped |
|
|
352
|
+
* #color alignments-pair-orientation | Mate unmapped | Mate aligned nowhere
|
|
353
|
+
* #color alignments-insert-size | Mate unmapped | Mate aligned nowhere
|
|
354
354
|
*/
|
|
355
355
|
// A NON-COLOUR, at the dark end of the neutral scale on BOTH themes. It takes
|
|
356
356
|
// the first half of the `readOverlap` pattern and not the second, and that split
|
|
@@ -421,7 +421,7 @@ export const colorUnmappedMate = '#000000';
|
|
|
421
421
|
// the least that still reads as a read rather than as a hole.
|
|
422
422
|
export const colorUnmappedMateDark = '#4a4a4a';
|
|
423
423
|
export const colorLongreadInv = '#7755bb';
|
|
424
|
-
/** #color alignments-pair-orientation | Split
|
|
424
|
+
/** #color alignments-pair-orientation | Split read (inverted) | Supplementary segment on the opposite strand to its primary */
|
|
425
425
|
export const colorSplitReadInversion = '#9b30b0';
|
|
426
426
|
export const colorSupplementary = '#f0b878';
|
|
427
427
|
// Qualitative palette for coloring reads by an arbitrary tag value (e.g. the HP
|
|
@@ -26,10 +26,24 @@ export declare function displayTypesWithPromotableSlots(displayTypes: readonly {
|
|
|
26
26
|
* Reads `pin.control.slot` and nothing else. A raw `endAdornment` is
|
|
27
27
|
* deliberately not counted: it is an arbitrary element (synteny's colour
|
|
28
28
|
* swatch), so it cannot say which slot it promotes, and a pin built by hand
|
|
29
|
-
* rather than through `
|
|
30
|
-
*
|
|
29
|
+
* rather than through `makePin`/`makeTogglePin` is a thing to find, not to
|
|
30
|
+
* accept.
|
|
31
31
|
*/
|
|
32
32
|
export declare function pinnedSlots(items: MenuItem[]): Set<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Rows whose pin is the wrong kind for the row, submenus included: a checkbox
|
|
35
|
+
* row carrying a value pin, or a radio row carrying a toggle pin. Empty is the
|
|
36
|
+
* healthy answer.
|
|
37
|
+
*
|
|
38
|
+
* The row builders type the option so this cannot happen through them; this
|
|
39
|
+
* is for a `pin` written by hand as a literal, which the type system lets
|
|
40
|
+
* through as the union. A checkbox row's pin has to be the toggle kind because
|
|
41
|
+
* that is what a click beside a checkbox is read as — "turn this on for all" —
|
|
42
|
+
* and a value pin there applies the row's *current* state instead, which
|
|
43
|
+
* beside an unchecked box is a visible no-op. That shipped once (2026-09-07)
|
|
44
|
+
* and was caught in a live session, not by a test; this is the test.
|
|
45
|
+
*/
|
|
46
|
+
export declare function misKindedPins(items: MenuItem[]): string[];
|
|
33
47
|
/**
|
|
34
48
|
* A display's promotable slots that its own track menu offers no pin for,
|
|
35
49
|
* sorted. Empty is the healthy answer.
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* result against a baseline.
|
|
24
24
|
*/
|
|
25
25
|
import { promotableSlotNames } from '../configuration/promotableSlots.js';
|
|
26
|
+
import { resolveSubMenu } from './MenuTypes.js';
|
|
26
27
|
/**
|
|
27
28
|
* The registered display types whose config schema declares a promotable slot,
|
|
28
29
|
* sorted — the set a pin-coverage check has to reach, answered off the
|
|
@@ -50,8 +51,8 @@ export function displayTypesWithPromotableSlots(displayTypes) {
|
|
|
50
51
|
* Reads `pin.control.slot` and nothing else. A raw `endAdornment` is
|
|
51
52
|
* deliberately not counted: it is an arbitrary element (synteny's colour
|
|
52
53
|
* swatch), so it cannot say which slot it promotes, and a pin built by hand
|
|
53
|
-
* rather than through `
|
|
54
|
-
*
|
|
54
|
+
* rather than through `makePin`/`makeTogglePin` is a thing to find, not to
|
|
55
|
+
* accept.
|
|
55
56
|
*/
|
|
56
57
|
export function pinnedSlots(items) {
|
|
57
58
|
const found = new Set();
|
|
@@ -61,7 +62,43 @@ export function pinnedSlots(items) {
|
|
|
61
62
|
found.add(item.pin.control.slot);
|
|
62
63
|
}
|
|
63
64
|
if ('subMenu' in item) {
|
|
64
|
-
walk(item
|
|
65
|
+
walk(resolveSubMenu(item));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
walk(items);
|
|
70
|
+
return found;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Rows whose pin is the wrong kind for the row, submenus included: a checkbox
|
|
74
|
+
* row carrying a value pin, or a radio row carrying a toggle pin. Empty is the
|
|
75
|
+
* healthy answer.
|
|
76
|
+
*
|
|
77
|
+
* The row builders type the option so this cannot happen through them; this
|
|
78
|
+
* is for a `pin` written by hand as a literal, which the type system lets
|
|
79
|
+
* through as the union. A checkbox row's pin has to be the toggle kind because
|
|
80
|
+
* that is what a click beside a checkbox is read as — "turn this on for all" —
|
|
81
|
+
* and a value pin there applies the row's *current* state instead, which
|
|
82
|
+
* beside an unchecked box is a visible no-op. That shipped once (2026-09-07)
|
|
83
|
+
* and was caught in a live session, not by a test; this is the test.
|
|
84
|
+
*/
|
|
85
|
+
export function misKindedPins(items) {
|
|
86
|
+
const found = [];
|
|
87
|
+
const walk = (list) => {
|
|
88
|
+
for (const item of list) {
|
|
89
|
+
if ('pin' in item && item.pin && 'type' in item) {
|
|
90
|
+
const { kind } = item.pin.control;
|
|
91
|
+
const wanted = item.type === 'checkbox'
|
|
92
|
+
? 'toggle'
|
|
93
|
+
: item.type === 'radio'
|
|
94
|
+
? 'value'
|
|
95
|
+
: undefined;
|
|
96
|
+
if (wanted && kind !== wanted) {
|
|
97
|
+
found.push(`${item.pin.label}: ${kind} pin on a ${item.type} row`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if ('subMenu' in item) {
|
|
101
|
+
walk(resolveSubMenu(item));
|
|
65
102
|
}
|
|
66
103
|
}
|
|
67
104
|
};
|
package/esm/ui/theme.js
CHANGED
|
@@ -209,6 +209,11 @@ const baseThemeOptions = {
|
|
|
209
209
|
MuiFormLabel: {
|
|
210
210
|
styleOverrides: darkModeContrastOverride(['&.Mui-focused']),
|
|
211
211
|
},
|
|
212
|
+
// the rail, track and thumb are all `currentColor` off the root, so a
|
|
213
|
+
// midnight root paints the whole control dark-on-dark
|
|
214
|
+
MuiSlider: {
|
|
215
|
+
styleOverrides: darkModeContrastOverride(),
|
|
216
|
+
},
|
|
212
217
|
MuiAccordionSummary: {
|
|
213
218
|
styleOverrides: {
|
|
214
219
|
root: ({ theme: t }) => ({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TogglePin, ValuePin } from '../configuration/promotablePin.ts';
|
|
1
2
|
import type { CheckboxMenuItem, MenuItem, RadioMenuItem } from './MenuTypes.ts';
|
|
2
3
|
export interface SettingRowOptions {
|
|
3
4
|
helpText?: string;
|
|
@@ -5,8 +6,14 @@ export interface SettingRowOptions {
|
|
|
5
6
|
disabledHelpText?: string;
|
|
6
7
|
keepMenuOpen?: boolean;
|
|
7
8
|
}
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
export interface CheckboxRowOptions extends SettingRowOptions {
|
|
10
|
+
pin?: TogglePin;
|
|
11
|
+
}
|
|
12
|
+
export interface RadioRowOptions extends SettingRowOptions {
|
|
13
|
+
pin?: ValuePin;
|
|
14
|
+
}
|
|
15
|
+
/** #menuBuilder checkboxItem | one checkbox setting row, with a toggle pin when the setting is promotable */
|
|
16
|
+
export declare function checkboxItem(label: string, checked: boolean, onToggle: () => void, opts?: CheckboxRowOptions): CheckboxMenuItem;
|
|
10
17
|
/**
|
|
11
18
|
* #menuBuilder toggleItem | a checkbox row whose setter takes the new value
|
|
12
19
|
*
|
|
@@ -23,17 +30,15 @@ export declare function checkboxItem(label: string, checked: boolean, onToggle:
|
|
|
23
30
|
* `SettingRowOptions` to a hand-narrowed one-field bag — the exact drift the
|
|
24
31
|
* comment on that interface warns about.
|
|
25
32
|
*/
|
|
26
|
-
export declare function toggleItem(label: string, value: boolean, setValue: (value: boolean) => void, opts?:
|
|
33
|
+
export declare function toggleItem(label: string, value: boolean, setValue: (value: boolean) => void, opts?: CheckboxRowOptions): CheckboxMenuItem;
|
|
27
34
|
/** #menuBuilder radioItem | one radio setting row; the singular of `radioItems` */
|
|
28
|
-
export declare function radioItem(label: string, checked: boolean, onClick: () => void, opts?:
|
|
29
|
-
export interface RadioOption<T extends string> {
|
|
35
|
+
export declare function radioItem(label: string, checked: boolean, onClick: () => void, opts?: RadioRowOptions): RadioMenuItem;
|
|
36
|
+
export interface RadioOption<T extends string> extends SettingRowOptions {
|
|
30
37
|
value: T;
|
|
31
38
|
label: string;
|
|
32
|
-
helpText?: string;
|
|
33
|
-
keepMenuOpen?: boolean;
|
|
34
39
|
}
|
|
35
|
-
/** #menuBuilder radioItems | a radio group, one row per option */
|
|
36
|
-
export declare function radioItems<T extends string>(options: readonly RadioOption<T>[], current: T | undefined, setMode: (m: T) => void): RadioMenuItem[];
|
|
40
|
+
/** #menuBuilder radioItems | a radio group, one row per option, with a value pin per option when the setting is promotable */
|
|
41
|
+
export declare function radioItems<T extends string>(options: readonly RadioOption<T>[], current: T | undefined, setMode: (m: T) => void, pin?: (value: T) => ValuePin): RadioMenuItem[];
|
|
37
42
|
/**
|
|
38
43
|
* #menuBuilder withSubHeader | a section heading, present only if the section is
|
|
39
44
|
*
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
function withPin(row, pin) {
|
|
2
|
+
return pin ? { ...row, pin: { control: pin, label: row.label } } : row;
|
|
3
|
+
}
|
|
4
|
+
/** #menuBuilder checkboxItem | one checkbox setting row, with a toggle pin when the setting is promotable */
|
|
5
|
+
export function checkboxItem(label, checked, onToggle, opts = {}) {
|
|
6
|
+
const { pin, ...rest } = opts;
|
|
7
|
+
return withPin({
|
|
4
8
|
label,
|
|
5
9
|
type: 'checkbox',
|
|
6
10
|
checked,
|
|
7
11
|
onClick: onToggle,
|
|
8
|
-
...
|
|
9
|
-
};
|
|
12
|
+
...rest,
|
|
13
|
+
}, pin);
|
|
10
14
|
}
|
|
11
15
|
/**
|
|
12
16
|
* #menuBuilder toggleItem | a checkbox row whose setter takes the new value
|
|
@@ -29,24 +33,37 @@ export function toggleItem(label, value, setValue, opts) {
|
|
|
29
33
|
setValue(!value);
|
|
30
34
|
}, opts);
|
|
31
35
|
}
|
|
32
|
-
// One radio row. The singular of `radioItems`,
|
|
33
|
-
//
|
|
34
|
-
//
|
|
36
|
+
// One radio row. The singular of `radioItems`, for a group the plural form
|
|
37
|
+
// can't express: a row with no single value to promote yet (the colorBy
|
|
38
|
+
// "Tag..." row before a tag is picked), a display whose slot isn't promotable
|
|
39
|
+
// at all (the shared colorBy menu on gwas/variants), or a group gated row by
|
|
40
|
+
// row and mixing in a non-promotable peer (the alignments size presets and
|
|
41
|
+
// their "Custom..." row). **Reach for `radioItems` first**: every option in a
|
|
42
|
+
// group has to get a pin, and hand-naming the rows is what leaves one without.
|
|
35
43
|
/** #menuBuilder radioItem | one radio setting row; the singular of `radioItems` */
|
|
36
|
-
export function radioItem(label, checked, onClick, opts) {
|
|
37
|
-
|
|
44
|
+
export function radioItem(label, checked, onClick, opts = {}) {
|
|
45
|
+
const { pin, ...rest } = opts;
|
|
46
|
+
return withPin({
|
|
38
47
|
label,
|
|
39
48
|
type: 'radio',
|
|
40
49
|
checked,
|
|
41
50
|
onClick,
|
|
42
|
-
...
|
|
43
|
-
};
|
|
51
|
+
...rest,
|
|
52
|
+
}, pin);
|
|
44
53
|
}
|
|
45
|
-
|
|
46
|
-
|
|
54
|
+
// `pin` is a factory rather than a per-option field so a promotable group can't
|
|
55
|
+
// be a row short. **Every option in a group gets a pin, the `promotedBase`
|
|
56
|
+
// value included**: once a non-base value is promoted, taking the base row's
|
|
57
|
+
// offer is the per-value way to undo it, and a radio group with one row silently
|
|
58
|
+
// missing its trailing control reads as a bug. `sashimiArcsMode`'s base looked
|
|
59
|
+
// unpinnable precisely because each row had been named by hand. Pass
|
|
60
|
+
// `value => makePin(self, slot, value)`, or a model member of that shape where
|
|
61
|
+
// the menu module is handed a duck-typed model (alignments).
|
|
62
|
+
/** #menuBuilder radioItems | a radio group, one row per option, with a value pin per option when the setting is promotable */
|
|
63
|
+
export function radioItems(options, current, setMode, pin) {
|
|
47
64
|
return options.map(({ value, label, ...opts }) => radioItem(label, current === value, () => {
|
|
48
65
|
setMode(value);
|
|
49
|
-
}, opts));
|
|
66
|
+
}, { ...opts, pin: pin?.(value) }));
|
|
50
67
|
}
|
|
51
68
|
/**
|
|
52
69
|
* #menuBuilder withSubHeader | a section heading, present only if the section is
|
|
@@ -121,7 +121,7 @@ export declare function bpToPx({ refName, coord, displayedRegionIndex, self, }:
|
|
|
121
121
|
* Undefined when no displayed region holds the coord, same as `bpToPx`; a
|
|
122
122
|
* caller that means "as far as the region goes" clamps before asking.
|
|
123
123
|
*/
|
|
124
|
-
export declare function bpToOffset({ refName, coord, displayedRegions, }: {
|
|
124
|
+
export declare function bpToOffset({ refName, coord, displayedRegions, displayedRegionIndex, }: {
|
|
125
125
|
refName: string;
|
|
126
126
|
coord: number;
|
|
127
127
|
displayedRegions: {
|
|
@@ -130,6 +130,7 @@ export declare function bpToOffset({ refName, coord, displayedRegions, }: {
|
|
|
130
130
|
end: number;
|
|
131
131
|
reversed?: boolean;
|
|
132
132
|
}[];
|
|
133
|
+
displayedRegionIndex?: number;
|
|
133
134
|
}): BpOffset | undefined;
|
|
134
135
|
/**
|
|
135
136
|
* Where a 0-based genomic coord sits in the LINEARIZED bp space — the
|
|
@@ -145,7 +146,7 @@ export declare function bpToOffset({ refName, coord, displayedRegions, }: {
|
|
|
145
146
|
* `undefined` when no displayed region holds the coord, exactly as `bpToPx`
|
|
146
147
|
* answers: a refName the view is not showing has no place on its screen.
|
|
147
148
|
*/
|
|
148
|
-
export declare function bpToLinearBp({ refName, coord, displayedRegions, }: {
|
|
149
|
+
export declare function bpToLinearBp({ refName, coord, displayedRegions, displayedRegionIndex, }: {
|
|
149
150
|
refName: string;
|
|
150
151
|
coord: number;
|
|
151
152
|
displayedRegions: {
|
|
@@ -154,6 +155,7 @@ export declare function bpToLinearBp({ refName, coord, displayedRegions, }: {
|
|
|
154
155
|
end: number;
|
|
155
156
|
reversed?: boolean;
|
|
156
157
|
}[];
|
|
158
|
+
displayedRegionIndex?: number;
|
|
157
159
|
}): number | undefined;
|
|
158
160
|
/**
|
|
159
161
|
* Screen order of two {@link BpOffset}s: negative when `a` is to the left of
|
package/esm/util/Base1DUtils.js
CHANGED
|
@@ -187,9 +187,12 @@ export function bpToPx({ refName, coord, displayedRegionIndex, self, }) {
|
|
|
187
187
|
* Undefined when no displayed region holds the coord, same as `bpToPx`; a
|
|
188
188
|
* caller that means "as far as the region goes" clamps before asking.
|
|
189
189
|
*/
|
|
190
|
-
export function bpToOffset({ refName, coord, displayedRegions, }) {
|
|
190
|
+
export function bpToOffset({ refName, coord, displayedRegions, displayedRegionIndex, }) {
|
|
191
191
|
for (const [index, r] of displayedRegions.entries()) {
|
|
192
|
-
if (refName === r.refName &&
|
|
192
|
+
if (refName === r.refName &&
|
|
193
|
+
coord >= r.start &&
|
|
194
|
+
coord <= r.end &&
|
|
195
|
+
(displayedRegionIndex === undefined || displayedRegionIndex === index)) {
|
|
193
196
|
return { refName, index, offset: bpOffsetInRegion(r, coord) };
|
|
194
197
|
}
|
|
195
198
|
}
|
|
@@ -209,8 +212,13 @@ export function bpToOffset({ refName, coord, displayedRegions, }) {
|
|
|
209
212
|
* `undefined` when no displayed region holds the coord, exactly as `bpToPx`
|
|
210
213
|
* answers: a refName the view is not showing has no place on its screen.
|
|
211
214
|
*/
|
|
212
|
-
export function bpToLinearBp({ refName, coord, displayedRegions, }) {
|
|
213
|
-
const at = bpToOffset({
|
|
215
|
+
export function bpToLinearBp({ refName, coord, displayedRegions, displayedRegionIndex, }) {
|
|
216
|
+
const at = bpToOffset({
|
|
217
|
+
refName,
|
|
218
|
+
coord,
|
|
219
|
+
displayedRegions,
|
|
220
|
+
displayedRegionIndex,
|
|
221
|
+
});
|
|
214
222
|
return at ? cumulativeBp(displayedRegions, at.index, at.offset) : undefined;
|
|
215
223
|
}
|
|
216
224
|
/**
|
package/esm/util/SvgCanvas.js
CHANGED
|
@@ -479,9 +479,10 @@ export class SvgCanvas {
|
|
|
479
479
|
// The family goes through, not just the size: `measureText` switches to the
|
|
480
480
|
// fixed monospace advance on seeing one, so dropping it measured a monospace
|
|
481
481
|
// string against the proportional table — the same string, laid out one way on
|
|
482
|
-
// a real canvas and another in the export, with nothing to show which.
|
|
483
|
-
//
|
|
484
|
-
//
|
|
482
|
+
// a real canvas and another in the export, with nothing to show which. An
|
|
483
|
+
// estimate all the same: a draw whose layout turns on a width (synteny's
|
|
484
|
+
// off-screen mate labels) measures through a real canvas and passes the
|
|
485
|
+
// result in, so the figure names what the screen named.
|
|
485
486
|
measureText(text) {
|
|
486
487
|
const { size, family } = parseFont(this.font);
|
|
487
488
|
return { width: measureTextWidth(text, Number(size), family) };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The adapter-config axis of a fetch key: the config a fetch was issued
|
|
3
|
+
* against, as one string. Every fetch that refetches on an adapter edit folds
|
|
4
|
+
* this in — the comparative displays, the prerequisite reads, the density
|
|
5
|
+
* tier, the global family's signature — so the axis is spelled once and cannot
|
|
6
|
+
* drift between them.
|
|
7
|
+
*
|
|
8
|
+
* Not `adapterConfigCacheKey`: that one short-circuits on `adapterId`, which is
|
|
9
|
+
* right for sharing one adapter instance and wrong for freshness, where an
|
|
10
|
+
* edit to a config carrying an id still has to read as a different fetch.
|
|
11
|
+
*/
|
|
12
|
+
export declare function adapterConfigKey(adapterConfig: Record<string, unknown>): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The adapter-config axis of a fetch key: the config a fetch was issued
|
|
3
|
+
* against, as one string. Every fetch that refetches on an adapter edit folds
|
|
4
|
+
* this in — the comparative displays, the prerequisite reads, the density
|
|
5
|
+
* tier, the global family's signature — so the axis is spelled once and cannot
|
|
6
|
+
* drift between them.
|
|
7
|
+
*
|
|
8
|
+
* Not `adapterConfigCacheKey`: that one short-circuits on `adapterId`, which is
|
|
9
|
+
* right for sharing one adapter instance and wrong for freshness, where an
|
|
10
|
+
* edit to a config carrying an id still has to read as a different fetch.
|
|
11
|
+
*/
|
|
12
|
+
export function adapterConfigKey(adapterConfig) {
|
|
13
|
+
return JSON.stringify(adapterConfig);
|
|
14
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { adapterConfigKey } from './adapterConfigKey.js';
|
|
1
2
|
import { getRpcSessionId } from './parentWalk.js';
|
|
2
3
|
import { getRpcHost } from './sessionServices.js';
|
|
3
4
|
/**
|
|
@@ -19,7 +20,7 @@ import { getRpcHost } from './sessionServices.js';
|
|
|
19
20
|
export function createAdapterMetadataFetch(self) {
|
|
20
21
|
let cached;
|
|
21
22
|
return () => {
|
|
22
|
-
const key =
|
|
23
|
+
const key = adapterConfigKey(self.adapterConfig);
|
|
23
24
|
if (cached?.key !== key) {
|
|
24
25
|
const promise = getRpcHost(self)
|
|
25
26
|
// eslint-disable-next-line no-restricted-syntax -- nothing to narrate, nothing a cancel could save
|
|
@@ -15,7 +15,7 @@ import type { SessionWithAddSessionTrack } from './types/index.ts';
|
|
|
15
15
|
export declare function addAndShowTrack(session: SessionWithAddSessionTrack, conf: Parameters<SessionWithAddSessionTrack['addSessionTrackConf']>[0] & {
|
|
16
16
|
trackId: string;
|
|
17
17
|
}, view?: {
|
|
18
|
-
|
|
18
|
+
launchTrack: (trackId: string) => Promise<unknown>;
|
|
19
19
|
}): (import("@jbrowse/mobx-state-tree").ModelInstanceTypeProps<Record<string, any>> & {
|
|
20
20
|
setSubschema(slotName: string, data: Record<string, unknown>): any;
|
|
21
21
|
setSlot(slotName: string, value: unknown): void;
|
|
@@ -16,8 +16,12 @@ export function addAndShowTrack(session, conf, view) {
|
|
|
16
16
|
// addSessionTrackConf already notified on an invalid conf; showing a trackId
|
|
17
17
|
// that was never added would only add a second "Could not resolve identifier"
|
|
18
18
|
// snackbar
|
|
19
|
+
//
|
|
20
|
+
// `launchTrack`, voided: the display's state model may still be a dynamic
|
|
21
|
+
// import away, and every caller here is a menu item or a dialog button whose
|
|
22
|
+
// return value is the added config rather than the opened track
|
|
19
23
|
if (added) {
|
|
20
|
-
view?.
|
|
24
|
+
void view?.launchTrack(conf.trackId);
|
|
21
25
|
}
|
|
22
26
|
return added;
|
|
23
27
|
}
|
|
@@ -68,7 +68,7 @@ export function addTrackFromWidget({ model, session, conf, }) {
|
|
|
68
68
|
session.notify(`Could not add "${conf.name ?? conf.trackId}": the view it was being added to has closed, and it uses an assembly that only that view had.`, 'warning');
|
|
69
69
|
return undefined;
|
|
70
70
|
}
|
|
71
|
-
trackContainer.
|
|
71
|
+
void trackContainer.launchTrack(conf.trackId, {}, {}, conf);
|
|
72
72
|
finishAddTrack(model, session);
|
|
73
73
|
return conf;
|
|
74
74
|
}
|
|
@@ -77,7 +77,7 @@ export function addTrackFromWidget({ model, session, conf, }) {
|
|
|
77
77
|
return undefined;
|
|
78
78
|
}
|
|
79
79
|
if (containerDisplaysAssembly(trackContainer, conf.assemblyNames, session.assemblyManager)) {
|
|
80
|
-
trackContainer?.
|
|
80
|
+
void trackContainer?.launchTrack(conf.trackId);
|
|
81
81
|
}
|
|
82
82
|
else {
|
|
83
83
|
const assemblies = conf.assemblyNames?.filter(a => !!a) ?? [];
|
package/esm/util/analytics.js
CHANGED
|
@@ -9,11 +9,10 @@ export async function writeAWSAnalytics(rootModel, initialTimestamp, sessionQuer
|
|
|
9
9
|
try {
|
|
10
10
|
const url = 'https://analytics.jbrowse.org/api/v1';
|
|
11
11
|
const multiAssemblyTracks = rootModel.jbrowse.tracks.filter(track => readConfObject(track, 'assemblyNames').length > 1).length;
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
// Canvas2D is counted as Canvas2D rather than as
|
|
15
|
-
//
|
|
16
|
-
// users end up on Canvas2D" unanswerable.
|
|
12
|
+
// The rung createGpuHal built where a display has built one by idle time,
|
|
13
|
+
// else the ladder's prediction with any page-wide pin applied — so a
|
|
14
|
+
// session that fell back to Canvas2D is counted as Canvas2D rather than as
|
|
15
|
+
// what the hardware could have done.
|
|
17
16
|
const capabilities = await getGraphicsCapabilities();
|
|
18
17
|
const renderer = effectiveRenderer(capabilities);
|
|
19
18
|
// The coarse bit only. `glRenderer` names the exact driver and stays local
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { SharedBudget } from '@gmod/shared-read-cache';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* in this JS context — so one per RPC worker, plus one on the main
|
|
5
|
-
* which is the scope that actually runs out of memory.
|
|
3
|
+
* The ceiling on what the indexed-format libraries retain, shared by every
|
|
4
|
+
* adapter in this JS context — so one per RPC worker, plus one on the main
|
|
5
|
+
* thread, which is the scope that actually runs out of memory.
|
|
6
6
|
*
|
|
7
|
-
* ## Why
|
|
7
|
+
* ## Why this is not per file
|
|
8
8
|
*
|
|
9
9
|
* `@gmod/bam`, `@gmod/tabix` and `@gmod/cram` each take a per-file budget,
|
|
10
10
|
* sized so that a single track panning never falls off the cliff where a cache
|
|
@@ -29,24 +29,27 @@ import { SharedBudget } from '@gmod/shared-read-cache';
|
|
|
29
29
|
* at hand their space to the one being panned, so the active track keeps a
|
|
30
30
|
* whole working set however many are open.
|
|
31
31
|
*
|
|
32
|
-
* ## The
|
|
32
|
+
* ## The number is not new
|
|
33
33
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
34
|
+
* 1 GB is the libraries' own per-file default (`DEFAULT_MAX_CACHE_BYTES` in
|
|
35
|
+
* both `@gmod/bam` and `@gmod/cram`), moved from per-file to per-context. That
|
|
36
|
+
* makes this a strict tightening — retention can only fall — and avoids
|
|
37
|
+
* inventing a number that would need its own justification. With one file open
|
|
38
|
+
* the two ceilings coincide; from the second file on, this one is the one that
|
|
39
|
+
* binds. The budget still has to clear one query's working set or the cliff
|
|
40
|
+
* returns, and on that workload 512 MB shared across three tracks already cost
|
|
41
|
+
* 43 refills where 1 GB cost 4.
|
|
40
42
|
*
|
|
41
|
-
* ##
|
|
43
|
+
* ## One budget, because every member weighs bytes
|
|
42
44
|
*
|
|
43
45
|
* `SharedBudget.total` is a sum over its members, so they must all weigh in the
|
|
44
|
-
* same unit
|
|
45
|
-
* `@gmod/
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
46
|
+
* same unit, and `sizeOf` is opaque, so nothing could catch a mismatch at
|
|
47
|
+
* runtime. `@gmod/bam` and `@gmod/tabix` weigh decompressed bytes, and since 14
|
|
48
|
+
* `@gmod/cram` weighs a decoded slice by `DecodedSlice.byteLength` — its typed
|
|
49
|
+
* columns exactly and its strings by estimate, within 1–8% of the measured heap
|
|
50
|
+
* (its ADR 0013). Before that a CRAM slice weighed its record count, which is
|
|
51
|
+
* why this used to be two budgets named for their units: a million records
|
|
52
|
+
* could not be added to bytes, and never bound long-read data either, where a
|
|
53
|
+
* 6 MB slice counted as 37.
|
|
49
54
|
*/
|
|
50
55
|
export declare const decompressedBytesBudget: SharedBudget;
|
|
51
|
-
/** See {@link decompressedBytesBudget}. Records, not bytes — CRAM only. */
|
|
52
|
-
export declare const decodedRecordsBudget: SharedBudget;
|
package/esm/util/cacheBudgets.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { SharedBudget } from '@gmod/shared-read-cache';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* in this JS context — so one per RPC worker, plus one on the main
|
|
5
|
-
* which is the scope that actually runs out of memory.
|
|
3
|
+
* The ceiling on what the indexed-format libraries retain, shared by every
|
|
4
|
+
* adapter in this JS context — so one per RPC worker, plus one on the main
|
|
5
|
+
* thread, which is the scope that actually runs out of memory.
|
|
6
6
|
*
|
|
7
|
-
* ## Why
|
|
7
|
+
* ## Why this is not per file
|
|
8
8
|
*
|
|
9
9
|
* `@gmod/bam`, `@gmod/tabix` and `@gmod/cram` each take a per-file budget,
|
|
10
10
|
* sized so that a single track panning never falls off the cliff where a cache
|
|
@@ -29,24 +29,27 @@ import { SharedBudget } from '@gmod/shared-read-cache';
|
|
|
29
29
|
* at hand their space to the one being panned, so the active track keeps a
|
|
30
30
|
* whole working set however many are open.
|
|
31
31
|
*
|
|
32
|
-
* ## The
|
|
32
|
+
* ## The number is not new
|
|
33
33
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
34
|
+
* 1 GB is the libraries' own per-file default (`DEFAULT_MAX_CACHE_BYTES` in
|
|
35
|
+
* both `@gmod/bam` and `@gmod/cram`), moved from per-file to per-context. That
|
|
36
|
+
* makes this a strict tightening — retention can only fall — and avoids
|
|
37
|
+
* inventing a number that would need its own justification. With one file open
|
|
38
|
+
* the two ceilings coincide; from the second file on, this one is the one that
|
|
39
|
+
* binds. The budget still has to clear one query's working set or the cliff
|
|
40
|
+
* returns, and on that workload 512 MB shared across three tracks already cost
|
|
41
|
+
* 43 refills where 1 GB cost 4.
|
|
40
42
|
*
|
|
41
|
-
* ##
|
|
43
|
+
* ## One budget, because every member weighs bytes
|
|
42
44
|
*
|
|
43
45
|
* `SharedBudget.total` is a sum over its members, so they must all weigh in the
|
|
44
|
-
* same unit
|
|
45
|
-
* `@gmod/
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
46
|
+
* same unit, and `sizeOf` is opaque, so nothing could catch a mismatch at
|
|
47
|
+
* runtime. `@gmod/bam` and `@gmod/tabix` weigh decompressed bytes, and since 14
|
|
48
|
+
* `@gmod/cram` weighs a decoded slice by `DecodedSlice.byteLength` — its typed
|
|
49
|
+
* columns exactly and its strings by estimate, within 1–8% of the measured heap
|
|
50
|
+
* (its ADR 0013). Before that a CRAM slice weighed its record count, which is
|
|
51
|
+
* why this used to be two budgets named for their units: a million records
|
|
52
|
+
* could not be added to bytes, and never bound long-read data either, where a
|
|
53
|
+
* 6 MB slice counted as 37.
|
|
49
54
|
*/
|
|
50
55
|
export const decompressedBytesBudget = new SharedBudget(1024 * 2 ** 20);
|
|
51
|
-
/** See {@link decompressedBytesBudget}. Records, not bytes — CRAM only. */
|
|
52
|
-
export const decodedRecordsBudget = new SharedBudget(1_000_000);
|
|
@@ -24,3 +24,20 @@ export declare function clampToContig(assembly: Assembly, region: {
|
|
|
24
24
|
start: number;
|
|
25
25
|
end: number;
|
|
26
26
|
}): Region | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* `clampToContig` for a refName that may not be on the assembly at all, which
|
|
29
|
+
* is the shape a location nobody requested arrives in — a BAM's `nextRef`, an
|
|
30
|
+
* SA record's contig (REFNAME_NAMESPACES.md). `clampToContig` alone passes an
|
|
31
|
+
* unknown name through with nothing to clamp against, so it cannot tell "past
|
|
32
|
+
* the end of a contig we have" from "a contig we do not have", and both callers
|
|
33
|
+
* need that apart to say which happened.
|
|
34
|
+
*/
|
|
35
|
+
export declare function clampToListedContig(assembly: Assembly, region: {
|
|
36
|
+
refName: string;
|
|
37
|
+
start: number;
|
|
38
|
+
end: number;
|
|
39
|
+
}): {
|
|
40
|
+
refName: string;
|
|
41
|
+
onAssembly: boolean;
|
|
42
|
+
region: Region | undefined;
|
|
43
|
+
};
|