@jbrowse/core 5.0.0-beta.2 → 5.0.0-beta.4
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 +70 -40
- 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/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/PluginManager.d.ts +30 -1
- package/esm/PluginManager.js +107 -70
- 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 +28 -56
- 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 +1 -1
- package/esm/ReExports/sharedModules.js +8 -1
- package/esm/ReExports/uiStub.d.ts +1 -0
- package/esm/ReExports/uiStub.js +6 -8
- package/esm/ReExports/workerModules.js +9 -4
- package/esm/ReExports/workerNamespaceNames.d.ts +11 -0
- package/esm/ReExports/workerNamespaceNames.js +281 -0
- package/esm/configuration/configurationSchema.js +11 -0
- 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 +108 -45
- 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.js +4 -12
- package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +12 -0
- package/esm/data_adapters/BaseAdapter/featureDensity.js +15 -0
- package/esm/data_adapters/BaseAdapter/index.d.ts +2 -2
- package/esm/data_adapters/BaseAdapter/index.js +1 -1
- package/esm/data_adapters/BaseAdapter/types.d.ts +2 -8
- package/esm/pluggableElementTypes/AdapterType.d.ts +2 -1
- package/esm/pluggableElementTypes/AdapterType.js +1 -1
- package/esm/pluggableElementTypes/DisplayType.d.ts +3 -10
- package/esm/pluggableElementTypes/DisplayType.js +3 -45
- package/esm/pluggableElementTypes/LazyStateModelElement.d.ts +27 -0
- package/esm/pluggableElementTypes/LazyStateModelElement.js +71 -0
- package/esm/pluggableElementTypes/ViewType.d.ts +3 -10
- package/esm/pluggableElementTypes/ViewType.js +6 -51
- package/esm/pluggableElementTypes/extendElementType.d.ts +1 -2
- package/esm/pluggableElementTypes/extendElementType.js +1 -2
- package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +3 -3
- package/esm/pluggableElementTypes/models/BaseDisplayModel.js +1 -1
- package/esm/pluggableElementTypes/models/BaseTrackModel.js +1 -4
- package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +34 -34
- package/esm/pluggableElementTypes/models/BaseViewModel.js +19 -30
- package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +4 -3
- package/esm/pluggableElementTypes/models/assertDisplayContract.js +2 -2
- package/esm/pluggableElementTypes/models/baseTrackConfig.js +7 -1
- package/esm/ui/BaseExportSvgDialog.d.ts +1 -1
- package/esm/ui/ErrorMessageStackTraceDialog.js +5 -6
- package/esm/ui/ExportSvgDialog.d.ts +1 -1
- package/esm/ui/MenuTypes.d.ts +3 -3
- package/esm/ui/PinAdornment.js +22 -40
- 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 +2 -2
- package/esm/ui/index.js +3 -3
- package/esm/ui/legendMenuItem.d.ts +9 -15
- package/esm/ui/legendMenuItem.js +8 -19
- package/esm/ui/menuItemAdornment.d.ts +2 -3
- package/esm/ui/menuItemAdornment.js +2 -3
- package/esm/ui/menuItems.d.ts +1 -2
- package/esm/ui/menuItems.js +0 -1
- 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 +38 -2
- package/esm/ui/theme.js +5 -0
- package/esm/ui/toggleMenuItems.d.ts +13 -6
- 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/analytics.js +4 -5
- 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 +8 -7
- package/esm/util/featureTypes.d.ts +24 -0
- package/esm/util/featureTypes.js +35 -0
- package/esm/util/fetchPhases.d.ts +1 -1
- package/esm/util/index.d.ts +4 -2
- package/esm/util/index.js +3 -1
- package/esm/util/installFetch.d.ts +29 -18
- package/esm/util/installFetch.js +17 -17
- package/esm/util/installInitAutorun.d.ts +6 -5
- package/esm/util/installInitAutorun.js +2 -2
- package/esm/util/installPrerequisiteFetch.d.ts +86 -0
- package/esm/util/installPrerequisiteFetch.js +73 -0
- 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/renderToStaticMarkup.js +10 -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/trackConfigDelta.d.ts +6 -6
- package/esm/util/trackConfigDelta.js +3 -3
- package/esm/util/types/index.d.ts +25 -20
- 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/wheelZoom.d.ts +3 -1
- package/esm/util/wheelZoom.js +39 -14
- package/esm/util/whenViewSettled.d.ts +31 -6
- package/esm/util/whenViewSettled.js +33 -5
- package/esm/util/withLaunchInput.d.ts +47 -2
- package/esm/util/withLaunchInput.js +56 -11
- package/package.json +10 -5
- package/esm/ui/promotableMenuItems.d.ts +0 -19
- package/esm/ui/promotableMenuItems.js +0 -91
package/README.md
CHANGED
|
@@ -149,12 +149,11 @@ default" action, which passes the slots it actually listed
|
|
|
149
149
|
|
|
150
150
|
**`slots` is required, and an all-slots default is not the convenience it looks
|
|
151
151
|
like.** It reaches further than any list a dialog can have shown: a promoted
|
|
152
|
-
default the track _customized_ over
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
defaults" is where it lives (`clearPreferenceOverrides`).
|
|
152
|
+
default the track _customized_ over is `inherited: false` and so appears in no
|
|
153
|
+
row, yet still governs sibling tracks — so clearing it from a dialog that never
|
|
154
|
+
showed it moves tracks other than the one whose badge was clicked. Clearing
|
|
155
|
+
every promoted default at once is a preferences-scope action, and Preferences →
|
|
156
|
+
"Reset to defaults" is where it lives (`clearPreferenceOverrides`).
|
|
158
157
|
|
|
159
158
|
```js
|
|
160
159
|
// type signature
|
|
@@ -423,10 +422,10 @@ default" predicate for a promotable slot: comparing the resolved value to the
|
|
|
423
422
|
base instead reads as at-default for a track merely _following_ a non-base
|
|
424
423
|
promoted default, so the reset control lights up on a no-op.
|
|
425
424
|
|
|
426
|
-
`SLOT` is constrained the way `getConf`'s is
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
425
|
+
`SLOT` is constrained the way `getConf`'s is, and a widened `self` switches the
|
|
426
|
+
check off (`HostChecksSlotNames`). A slot name the schema does not declare
|
|
427
|
+
throws at the first read (`getSlotDefinition`), and a declared but
|
|
428
|
+
non-promotable one throws in `resolveSlotIn`.
|
|
430
429
|
|
|
431
430
|
```js
|
|
432
431
|
// type signature
|
|
@@ -449,20 +448,22 @@ synchronous `addOrReplaceView` requires it loaded already.
|
|
|
449
448
|
|
|
450
449
|
### makePin
|
|
451
450
|
|
|
452
|
-
The pin
|
|
451
|
+
The pin on a radio or slider row: "apply this value to every open track of this
|
|
453
452
|
display type", and — via the snackbar it raises — "keep it as the default for
|
|
454
453
|
the ones opened later".
|
|
455
454
|
|
|
456
455
|
`value` chooses between the subsystem's two meanings, which are otherwise
|
|
457
456
|
identical:
|
|
458
457
|
|
|
459
|
-
- **Give it** for a per-value pin — "make
|
|
460
|
-
what the track currently shows. Use on an always-visible pin so it can
|
|
461
|
-
promote a meaningless value, and so two rows sharing one slot (
|
|
462
|
-
|
|
458
|
+
- **Give it** for a per-value pin — "make _compact_ the default" — independent
|
|
459
|
+
of what the track currently shows. Use on an always-visible pin so it can
|
|
460
|
+
never promote a meaningless value, and so two rows sharing one slot (sashimi
|
|
461
|
+
`'down'` vs `'auto'`) stay independent.
|
|
463
462
|
- **Omit it** for "whatever I'm showing", resolved through the cascade. Use for
|
|
464
|
-
a
|
|
465
|
-
|
|
463
|
+
a continuous setting where no fixed on-value makes sense (wiggle point size,
|
|
464
|
+
arc line width).
|
|
465
|
+
|
|
466
|
+
A checkbox row takes neither: makeTogglePin.
|
|
466
467
|
|
|
467
468
|
One function with an optional argument, rather than the two exported builders it
|
|
468
469
|
replaces — a per-value one and a `…CurrentValue…` one, the second of which was
|
|
@@ -472,7 +473,32 @@ argument now says what the longer name said.
|
|
|
472
473
|
|
|
473
474
|
```js
|
|
474
475
|
// type signature
|
|
475
|
-
<CONFMODEL extends AnyConfigurationModel, SLOT extends ConfigurationSlotName<…>>(self: ResolvableDisplay<CONFMODEL>, slot: SLOT, ...value: [] | [...]) =>
|
|
476
|
+
<CONFMODEL extends AnyConfigurationModel, SLOT extends ConfigurationSlotName<…>>(self: ResolvableDisplay<CONFMODEL>, slot: SLOT, ...value: [] | [...]) => ValuePin
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
[Source code](https://github.com/GMOD/jbrowse-components/blob/main/packages/core/src/configuration/promotableDefaults.ts)
|
|
480
|
+
|
|
481
|
+
### makeTogglePin
|
|
482
|
+
|
|
483
|
+
The pin on a checkbox row: the row's own checkbox, acting on every open track of
|
|
484
|
+
the display type. `active` mirrors the row, so the pin draws filled exactly when
|
|
485
|
+
the box is ticked; a click flips the row's state on every open track and offers
|
|
486
|
+
the new state as the display type's default. It never clears a default the way
|
|
487
|
+
makePin's filled pin does — flipping back and taking the offer promotes the
|
|
488
|
+
other value, and promoting the base value clears the default
|
|
489
|
+
(`applyAndOfferDefault`).
|
|
490
|
+
|
|
491
|
+
Replaces a symmetric `makePin(self, slot)` on these rows, which carried the
|
|
492
|
+
row's current state: beside an unchecked box that applied _off_ everywhere and
|
|
493
|
+
visibly did nothing. It also replaces the per-value `makePin` a checkbox row
|
|
494
|
+
over a shared enum slot used to carry, which gave two checkbox rows in one
|
|
495
|
+
submenu two different pins: one filled when its value was promoted and clearing
|
|
496
|
+
on a second click, the other filled when the box was ticked and flipping. With
|
|
497
|
+
`states`, a checkbox row is always the toggle kind.
|
|
498
|
+
|
|
499
|
+
```js
|
|
500
|
+
// type signature
|
|
501
|
+
<…>(self: ResolvableDisplay<CONFMODEL>, slot: SLOT, ...states: ConfigurationSlotValueResolved<...> extends boolean ? [] | [...] : [...]) => TogglePin
|
|
476
502
|
```
|
|
477
503
|
|
|
478
504
|
[Source code](https://github.com/GMOD/jbrowse-components/blob/main/packages/core/src/configuration/promotableDefaults.ts)
|
|
@@ -505,28 +531,12 @@ each display whether it has anything to promote.
|
|
|
505
531
|
### Pin
|
|
506
532
|
|
|
507
533
|
The "apply this to every open track of this type" affordance on a menu row — the
|
|
508
|
-
trailing `PushPin`, bundled so the row consumes it as one prop.
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
display type's default; on an already-promoted value it clears that default
|
|
515
|
-
instead, touching no track (see `applyPinClick`).
|
|
516
|
-
|
|
517
|
-
**`toggle` rather than an `apply`/`clear` pair**, which was tried and dropped:
|
|
518
|
-
the sole renderer is a MUI `ToggleButton` whose `onChange` means exactly "flip",
|
|
519
|
-
so splitting it adds a member _and_ a branch at the one call site that never
|
|
520
|
-
needed one. `active` is already public for a caller that wants to state a
|
|
521
|
-
direction. (The house preference for explicit setters over toggles is about MST
|
|
522
|
-
actions, where a toggle destroys the ability to set a known state; nothing here
|
|
523
|
-
stores a value.)
|
|
524
|
-
|
|
525
|
-
Lives here, alone and with no imports, rather than beside `makePin` in
|
|
526
|
-
`promotableDefaults.ts`: the menu types describe a pin without building one, and
|
|
527
|
-
`MenuTypes.ts` taking this one interface from that module gave a React-free type
|
|
528
|
-
file a type closure of 374 files. See
|
|
529
|
-
`agent-docs/ideas/barrels-block-extraction.md` and `scripts/moduleClosure.ts`.
|
|
534
|
+
trailing `PushPin`, bundled so the row consumes it as one prop.
|
|
535
|
+
|
|
536
|
+
`kind` is what the adornment words itself from and what the row builders check:
|
|
537
|
+
a checkbox row takes a TogglePin, a radio or slider row a ValuePin. The two used
|
|
538
|
+
to be told apart by `typeof onValue === 'boolean'`, which let a value pin over a
|
|
539
|
+
boolean slot compile and read as a toggle while clearing on its second click.
|
|
530
540
|
|
|
531
541
|
[Source code](https://github.com/GMOD/jbrowse-components/blob/main/packages/core/src/configuration/promotablePin.ts)
|
|
532
542
|
|
|
@@ -796,6 +806,16 @@ never baked into the color string.
|
|
|
796
806
|
|
|
797
807
|
[Source code](https://github.com/GMOD/jbrowse-components/blob/main/packages/core/src/util/colorRamp.ts)
|
|
798
808
|
|
|
809
|
+
### TogglePin
|
|
810
|
+
|
|
811
|
+
The pin on a checkbox row, built by makeTogglePin: the row's own checkbox over
|
|
812
|
+
every open track of the display type. `active` mirrors the row, `onValue` is the
|
|
813
|
+
state a click applies (the row's opposite), and `toggle` applies it everywhere
|
|
814
|
+
and offers it as the default. It never clears a default on its own — promoting
|
|
815
|
+
the slot's base value is what clears one.
|
|
816
|
+
|
|
817
|
+
[Source code](https://github.com/GMOD/jbrowse-components/blob/main/packages/core/src/configuration/promotablePin.ts)
|
|
818
|
+
|
|
799
819
|
### TrackConfigWithPromotables
|
|
800
820
|
|
|
801
821
|
A track config snapshot with every display's `promotable` slots resolved, plus
|
|
@@ -827,6 +847,16 @@ reader has promoted in their own browser. Pinned by
|
|
|
827
847
|
|
|
828
848
|
[Source code](https://github.com/GMOD/jbrowse-components/blob/main/packages/core/src/configuration/promotableDefaults.ts)
|
|
829
849
|
|
|
850
|
+
### ValuePin
|
|
851
|
+
|
|
852
|
+
The pin on a radio or slider row, built by makePin: `onValue` is the row's own
|
|
853
|
+
value, `active` means that value is the display type's promoted default, and
|
|
854
|
+
`toggle` on an outline pin applies the value to every open track and offers it
|
|
855
|
+
as the default, while on a filled pin it clears that default and touches no
|
|
856
|
+
track (`applyAndOfferDefault` / `clearDefault`).
|
|
857
|
+
|
|
858
|
+
[Source code](https://github.com/GMOD/jbrowse-components/blob/main/packages/core/src/configuration/promotablePin.ts)
|
|
859
|
+
|
|
830
860
|
### VIRIDIS_STOPS
|
|
831
861
|
|
|
832
862
|
The 256 viridis stops, fully opaque. Feed them to buildColorRampLut for the
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { SimpleFeatureSerialized } from '../../util/index.ts';
|
|
2
|
-
import type { Descriptors, FeatureFormatter } from '../types.tsx';
|
|
3
|
-
import type { IAnyStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
2
|
+
import type { Descriptors, FeatureDetailsModel, FeatureFormatter } from '../types.tsx';
|
|
4
3
|
interface FeatureDetailsProps {
|
|
5
|
-
model:
|
|
4
|
+
model: FeatureDetailsModel;
|
|
6
5
|
feature: SimpleFeatureSerialized;
|
|
7
6
|
depth?: number;
|
|
8
7
|
omit?: string[];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Typography } from '@mui/material';
|
|
3
|
+
import { makeStyles } from '../../util/tss-react/index.js';
|
|
4
|
+
const useStyles = makeStyles()(theme => ({
|
|
5
|
+
line: {
|
|
6
|
+
padding: theme.spacing(0.5, 1, 0),
|
|
7
|
+
},
|
|
8
|
+
}));
|
|
9
|
+
// Which gene a transcript came out of, above the card naming the transcript.
|
|
10
|
+
// The panel is opened on the exact isoform the click resolved to, and that
|
|
11
|
+
// isoform's own record is regularly the only place its accession appears --
|
|
12
|
+
// nothing in `NM_004006.2 - mRNA` says DMD.
|
|
13
|
+
export default function ParentFeatureLine({ parentFeature, }) {
|
|
14
|
+
const { classes } = useStyles();
|
|
15
|
+
const { name, type } = parentFeature;
|
|
16
|
+
return (_jsxs(Typography, { variant: "body2", color: "textSecondary", className: classes.line, "data-testid": "parent-feature-line", children: ["in ", type ? `${type} ` : '', name] }));
|
|
17
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { observer } from 'mobx-react';
|
|
3
3
|
import { ErrorBanner } from '../../ui/index.js';
|
|
4
4
|
import FeatureDetails from './FeatureDetails.js';
|
|
5
5
|
import FeatureWash from './FeatureWash.js';
|
|
6
|
+
import ParentFeatureLine from './ParentFeatureLine.js';
|
|
6
7
|
import { isEmpty } from './util.js';
|
|
7
8
|
const BaseFeatureDetail = observer(function BaseFeatureDetail({ model, }) {
|
|
8
|
-
const { error, featureData } = model;
|
|
9
|
+
const { error, featureData, parentFeature } = model;
|
|
9
10
|
// annotated to shed the MST node brand types.frozen() carries on the instance
|
|
10
11
|
const descriptions = model.descriptions;
|
|
11
12
|
// A field is hidden by a formatDetails callback returning undefined (jexl
|
|
@@ -19,7 +20,7 @@ const BaseFeatureDetail = observer(function BaseFeatureDetail({ model, }) {
|
|
|
19
20
|
return null;
|
|
20
21
|
}
|
|
21
22
|
else {
|
|
22
|
-
return (
|
|
23
|
+
return (_jsxs(FeatureWash, { uniqueId: featureData.uniqueId, children: [parentFeature ? (_jsx(ParentFeatureLine, { parentFeature: parentFeature })) : null, _jsx(FeatureDetails, { model: model, feature: featureData, descriptions: descriptions })] }));
|
|
23
24
|
}
|
|
24
25
|
});
|
|
25
26
|
export default BaseFeatureDetail;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SimpleFeatureSerialized } from '../../util/index.ts';
|
|
2
|
-
import type {
|
|
2
|
+
import type { FeatureDetailsModel } from '../types.tsx';
|
|
3
3
|
declare const SequenceFeaturePanel: ({ model, feature, }: {
|
|
4
|
-
model:
|
|
4
|
+
model: FeatureDetailsModel;
|
|
5
5
|
feature: SimpleFeatureSerialized;
|
|
6
6
|
}) => import("react").JSX.Element;
|
|
7
7
|
export default SequenceFeaturePanel;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { configSchema } from './configSchema.ts';
|
|
2
|
-
export type { Descriptors, MaybeSerializedFeat } from './types.tsx';
|
|
2
|
+
export type { Descriptors, FeatureDetailsModel, MaybeSerializedFeat, } from './types.tsx';
|
|
3
3
|
export type { SequenceHoverPosition, ShowCoordinatesMode, } from './SequenceFeatureDetails/model.ts';
|
|
4
4
|
export { stateModelFactory } from './stateModelFactory.ts';
|
|
5
5
|
export type { BaseFeatureWidgetModel, BaseFeatureWidgetStateModel, } from './stateModelFactory.ts';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type PluginManager from '../PluginManager.ts';
|
|
2
|
-
import type { SimpleFeatureSerialized } from '../util/index.ts';
|
|
2
|
+
import type { ParentFeatureSummary, SimpleFeatureSerialized } from '../util/index.ts';
|
|
3
3
|
import type { SequenceHoverPosition } from './SequenceFeatureDetails/model.ts';
|
|
4
4
|
import type { Descriptors, MaybeSerializedFeat } from './types.tsx';
|
|
5
5
|
import type { Instance } from '@jbrowse/mobx-state-tree';
|
|
@@ -69,6 +69,12 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
69
69
|
* #property
|
|
70
70
|
*/
|
|
71
71
|
descriptions: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IType<Descriptors | undefined, Descriptors | undefined, Descriptors | undefined>, [undefined]>;
|
|
72
|
+
/**
|
|
73
|
+
* #property
|
|
74
|
+
* names the feature this one was reached through, when it was reached
|
|
75
|
+
* through one -- a transcript clicked inside its gene
|
|
76
|
+
*/
|
|
77
|
+
parentFeature: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IType<ParentFeatureSummary | undefined, ParentFeatureSummary | undefined, ParentFeatureSummary | undefined>, [undefined]>;
|
|
72
78
|
}, {
|
|
73
79
|
error: unknown;
|
|
74
80
|
sequenceHoverPosition: SequenceHoverPosition | undefined;
|
|
@@ -113,6 +119,7 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
113
119
|
maxDepth: number | undefined;
|
|
114
120
|
sequenceFeatureDetails: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{}>;
|
|
115
121
|
descriptions: Descriptors | undefined;
|
|
122
|
+
parentFeature: ParentFeatureSummary | undefined;
|
|
116
123
|
finalizedFeatureData: any;
|
|
117
124
|
}>;
|
|
118
125
|
export type BaseFeatureWidgetStateModel = ReturnType<typeof stateModelFactory>;
|
|
@@ -59,6 +59,12 @@ export function stateModelFactory(pluginManager) {
|
|
|
59
59
|
* #property
|
|
60
60
|
*/
|
|
61
61
|
descriptions: types.optional(types.frozen(), undefined),
|
|
62
|
+
/**
|
|
63
|
+
* #property
|
|
64
|
+
* names the feature this one was reached through, when it was reached
|
|
65
|
+
* through one -- a transcript clicked inside its gene
|
|
66
|
+
*/
|
|
67
|
+
parentFeature: types.optional(types.frozen(), undefined),
|
|
62
68
|
})
|
|
63
69
|
.volatile(() => ({
|
|
64
70
|
/**
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import type { SimpleFeatureSerialized } from '../util/simpleFeature.ts';
|
|
2
|
-
import type {
|
|
2
|
+
import type { SequenceFeatureDetailsModel, SequenceHoverTarget } from './SequenceFeatureDetails/model.ts';
|
|
3
|
+
import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
3
4
|
import type React from 'react';
|
|
5
|
+
export interface FeatureDetailsModel extends IStateTreeNode, SequenceHoverTarget {
|
|
6
|
+
maxDepth: number | undefined;
|
|
7
|
+
sequenceFeatureDetails: SequenceFeatureDetailsModel;
|
|
8
|
+
view: {
|
|
9
|
+
assemblyNames: string[];
|
|
10
|
+
} | undefined;
|
|
11
|
+
}
|
|
4
12
|
export interface Descriptors {
|
|
5
13
|
[key: string]: React.ReactNode | Descriptors;
|
|
6
14
|
}
|
|
@@ -9,7 +17,7 @@ export interface BaseProps extends BaseCardProps {
|
|
|
9
17
|
feature: SimpleFeatureSerialized;
|
|
10
18
|
formatter?: FeatureFormatter;
|
|
11
19
|
descriptions?: Descriptors;
|
|
12
|
-
model?:
|
|
20
|
+
model?: FeatureDetailsModel;
|
|
13
21
|
}
|
|
14
22
|
export interface BaseCardProps {
|
|
15
23
|
title?: string;
|
package/esm/PluginManager.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import PhasedScheduler from './PhasedScheduler.ts';
|
|
2
2
|
import './util/tracks.ts';
|
|
3
3
|
import type Plugin from './Plugin.ts';
|
|
4
|
+
import type { PluginConstructor } from './Plugin.ts';
|
|
4
5
|
import type AdapterType from './pluggableElementTypes/AdapterType.ts';
|
|
5
6
|
import type AddTrackWorkflowType from './pluggableElementTypes/AddTrackWorkflowType.ts';
|
|
6
7
|
import type ConnectionType from './pluggableElementTypes/ConnectionType.ts';
|
|
@@ -290,6 +291,15 @@ export interface PluginLoadRecord {
|
|
|
290
291
|
metadata?: PluginMetadata;
|
|
291
292
|
plugin: Plugin;
|
|
292
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* Instantiate an application's bundled plugin list as `isCore` load records —
|
|
296
|
+
* what tells the plugin store these came with the bundle rather than being
|
|
297
|
+
* installed by the user, so `InstalledPluginsList` filters them out and the
|
|
298
|
+
* About widget lists them. Every product and every test harness builds its
|
|
299
|
+
* manager from one of these lists, and a harness that passed bare instances
|
|
300
|
+
* silently disagreed with the app it was testing.
|
|
301
|
+
*/
|
|
302
|
+
export declare function corePluginRecords(plugins: PluginConstructor[]): PluginLoadRecord[];
|
|
293
303
|
export interface RuntimePluginLoadRecord extends PluginLoadRecord {
|
|
294
304
|
definition: PluginDefinition;
|
|
295
305
|
}
|
|
@@ -367,6 +377,14 @@ export default class PluginManager {
|
|
|
367
377
|
pluggableMstType(groupName: PluggableElementTypeGroup, fieldName: string, fallback?: IAnyType): IAnyType;
|
|
368
378
|
/** get a MST type for the union of all specified pluggable config schemas */
|
|
369
379
|
pluggableConfigSchemaType(typeGroup: PluggableElementTypeGroup, fieldName?: string): IAnyType;
|
|
380
|
+
/**
|
|
381
|
+
* An adapter union dispatches on `type`, so a config still spelling an
|
|
382
|
+
* adapter's old name has to be rewritten to the name it registers under
|
|
383
|
+
* before the union sees it. Here rather than in each schema holding an
|
|
384
|
+
* adapter slot, so a track, an assembly's sequence and a connection all take
|
|
385
|
+
* it.
|
|
386
|
+
*/
|
|
387
|
+
private canonicalizeAdapterSnapshot;
|
|
370
388
|
jbrequireCache: Map<any, any>;
|
|
371
389
|
get lib(): Record<string, unknown>;
|
|
372
390
|
load: <FTYPE extends AnyFunction>(lib: FTYPE) => ReturnType<FTYPE>;
|
|
@@ -380,6 +398,12 @@ export default class PluginManager {
|
|
|
380
398
|
default: AnyFunction;
|
|
381
399
|
}) => any;
|
|
382
400
|
getAdapterType(typeName: string): AdapterType;
|
|
401
|
+
/**
|
|
402
|
+
* The name an adapter `type` registers under: itself, or the adapter that
|
|
403
|
+
* declares it in `aliases`. A name nothing answers to comes back as written,
|
|
404
|
+
* so the registered-names error still names what the config said.
|
|
405
|
+
*/
|
|
406
|
+
canonicalAdapterTypeName(typeName: string): string;
|
|
383
407
|
/**
|
|
384
408
|
* Whether an adapter type is registered, for a caller walking a config where
|
|
385
409
|
* `type` names a track, a display and an adapter alike — `getAdapterType`
|
|
@@ -394,7 +418,12 @@ export default class PluginManager {
|
|
|
394
418
|
stateModel: ViewTypeRegistry[N];
|
|
395
419
|
};
|
|
396
420
|
getViewType(typeName: string): ViewType;
|
|
397
|
-
|
|
421
|
+
/**
|
|
422
|
+
* The registered view and display types a snapshot names, from every `type`
|
|
423
|
+
* string anywhere in it — `heldForMissingPlugins` included. Over-collection
|
|
424
|
+
* is harmless: a name that resolves to neither is dropped here.
|
|
425
|
+
*/
|
|
426
|
+
private sessionElementTypes;
|
|
398
427
|
/**
|
|
399
428
|
* Every async code path that hands a snapshot to a synchronous session
|
|
400
429
|
* instantiation (`setSession`, `cast`) must await this first.
|
package/esm/PluginManager.js
CHANGED
|
@@ -3,6 +3,7 @@ import CorePlugin from './CorePlugin.js';
|
|
|
3
3
|
import PhasedScheduler from './PhasedScheduler.js';
|
|
4
4
|
import { getReExportRegistry } from './ReExports/registry.js';
|
|
5
5
|
import { ConfigurationSchema, isBareConfigurationSchemaType, } from './configuration/index.js';
|
|
6
|
+
import LazyStateModelElement from './pluggableElementTypes/LazyStateModelElement.js';
|
|
6
7
|
import createJexlInstance from './util/jexl.js';
|
|
7
8
|
import { expandLooseTrackConfig } from './util/tracks.js';
|
|
8
9
|
/**
|
|
@@ -24,6 +25,9 @@ export const pluggableElementTypeGroups = [
|
|
|
24
25
|
'internet account',
|
|
25
26
|
'add track workflow',
|
|
26
27
|
];
|
|
28
|
+
function isUnloadedLazyElement(element) {
|
|
29
|
+
return element instanceof LazyStateModelElement && !element.isStateModelLoaded;
|
|
30
|
+
}
|
|
27
31
|
/** internal class that holds the info for a certain element type */
|
|
28
32
|
class TypeRecord {
|
|
29
33
|
registeredTypes = {};
|
|
@@ -90,6 +94,17 @@ function nextAccumulator(name, accumulator, result) {
|
|
|
90
94
|
function logCallbackError(name, error) {
|
|
91
95
|
console.error(`error in a ${name} extension point callback`, error);
|
|
92
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Instantiate an application's bundled plugin list as `isCore` load records —
|
|
99
|
+
* what tells the plugin store these came with the bundle rather than being
|
|
100
|
+
* installed by the user, so `InstalledPluginsList` filters them out and the
|
|
101
|
+
* About widget lists them. Every product and every test harness builds its
|
|
102
|
+
* manager from one of these lists, and a harness that passed bare instances
|
|
103
|
+
* silently disagreed with the app it was testing.
|
|
104
|
+
*/
|
|
105
|
+
export function corePluginRecords(plugins) {
|
|
106
|
+
return plugins.map(P => ({ plugin: new P(), metadata: { isCore: true } }));
|
|
107
|
+
}
|
|
93
108
|
export default class PluginManager {
|
|
94
109
|
plugins = [];
|
|
95
110
|
jexl = createJexlInstance();
|
|
@@ -307,9 +322,28 @@ export default class PluginManager {
|
|
|
307
322
|
console.warn(`${groupName} ${newElement.name} already registered, cannot register it again`);
|
|
308
323
|
}
|
|
309
324
|
else {
|
|
310
|
-
|
|
325
|
+
const extend = () => this.evaluateExtensionPoint(
|
|
311
326
|
/** #extensionPoint Core-extendPluggableElement | sync | Mutate any pluggable element after it is created */
|
|
312
|
-
'Core-extendPluggableElement', newElement, { group: groupName })
|
|
327
|
+
'Core-extendPluggableElement', newElement, { group: groupName });
|
|
328
|
+
// A lazily registered state model is not there for a callback to
|
|
329
|
+
// extend yet, so the point fires when the loader resolves instead.
|
|
330
|
+
// agent-docs/reference/EAGER_BUNDLE.md
|
|
331
|
+
if (isUnloadedLazyElement(newElement)) {
|
|
332
|
+
newElement.onStateModelLoaded = () => {
|
|
333
|
+
const extended = extend();
|
|
334
|
+
if (extended !== newElement) {
|
|
335
|
+
typeRecord.add(newElement.name, extended);
|
|
336
|
+
if (extended instanceof LazyStateModelElement &&
|
|
337
|
+
extended.isStateModelLoaded) {
|
|
338
|
+
newElement.stateModel = extended.stateModel;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
typeRecord.add(newElement.name, newElement);
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
typeRecord.add(newElement.name, extend());
|
|
346
|
+
}
|
|
313
347
|
}
|
|
314
348
|
});
|
|
315
349
|
return this;
|
|
@@ -348,18 +382,20 @@ export default class PluginManager {
|
|
|
348
382
|
*/
|
|
349
383
|
pluggableMstType(groupName, fieldName, fallback = types.maybe(types.null)) {
|
|
350
384
|
const record = this.getElementTypeRecord(groupName);
|
|
385
|
+
const fieldOf = (t) => isUnloadedLazyElement(t)
|
|
386
|
+
? undefined
|
|
387
|
+
: t[fieldName];
|
|
351
388
|
const anyMember = record.all().some(t => {
|
|
352
|
-
const
|
|
353
|
-
const field = element[fieldName];
|
|
389
|
+
const field = fieldOf(t);
|
|
354
390
|
return ((isType(field) && isModelType(field)) ||
|
|
355
|
-
typeof
|
|
391
|
+
typeof t[`${fieldName}Loader`] === 'function');
|
|
356
392
|
});
|
|
357
393
|
if (!anyMember) {
|
|
358
394
|
return fallback;
|
|
359
395
|
}
|
|
360
396
|
const modelsOf = () => record
|
|
361
397
|
.all()
|
|
362
|
-
.map(t => t
|
|
398
|
+
.map(t => fieldOf(t))
|
|
363
399
|
.filter(t => isType(t) && isModelType(t));
|
|
364
400
|
let members = modelsOf();
|
|
365
401
|
return types.union({
|
|
@@ -395,7 +431,28 @@ export default class PluginManager {
|
|
|
395
431
|
? types.snapshotProcessor(union, {
|
|
396
432
|
preProcessor: (snap) => expandLooseTrackConfig(snap, this),
|
|
397
433
|
})
|
|
398
|
-
:
|
|
434
|
+
: typeGroup === 'adapter'
|
|
435
|
+
? types.snapshotProcessor(union, {
|
|
436
|
+
preProcessor: (snap) => this.canonicalizeAdapterSnapshot(snap),
|
|
437
|
+
})
|
|
438
|
+
: union;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* An adapter union dispatches on `type`, so a config still spelling an
|
|
442
|
+
* adapter's old name has to be rewritten to the name it registers under
|
|
443
|
+
* before the union sees it. Here rather than in each schema holding an
|
|
444
|
+
* adapter slot, so a track, an assembly's sequence and a connection all take
|
|
445
|
+
* it.
|
|
446
|
+
*/
|
|
447
|
+
canonicalizeAdapterSnapshot(snap) {
|
|
448
|
+
if (typeof snap === 'object' &&
|
|
449
|
+
snap !== null &&
|
|
450
|
+
'type' in snap &&
|
|
451
|
+
typeof snap.type === 'string') {
|
|
452
|
+
const canonical = this.canonicalAdapterTypeName(snap.type);
|
|
453
|
+
return canonical === snap.type ? snap : { ...snap, type: canonical };
|
|
454
|
+
}
|
|
455
|
+
return snap;
|
|
399
456
|
}
|
|
400
457
|
jbrequireCache = new Map();
|
|
401
458
|
// populated by PluginLoader once a runtime plugin is actually being loaded,
|
|
@@ -434,7 +491,18 @@ export default class PluginManager {
|
|
|
434
491
|
throw new TypeError('lib passed to jbrequire must be either a string or a function');
|
|
435
492
|
};
|
|
436
493
|
getAdapterType(typeName) {
|
|
437
|
-
return this.adapterTypes.get(typeName);
|
|
494
|
+
return this.adapterTypes.get(this.canonicalAdapterTypeName(typeName));
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* The name an adapter `type` registers under: itself, or the adapter that
|
|
498
|
+
* declares it in `aliases`. A name nothing answers to comes back as written,
|
|
499
|
+
* so the registered-names error still names what the config said.
|
|
500
|
+
*/
|
|
501
|
+
canonicalAdapterTypeName(typeName) {
|
|
502
|
+
return this.adapterTypes.has(typeName)
|
|
503
|
+
? typeName
|
|
504
|
+
: (this.adapterTypes.all().find(t => t.aliases?.includes(typeName))
|
|
505
|
+
?.name ?? typeName);
|
|
438
506
|
}
|
|
439
507
|
/**
|
|
440
508
|
* Whether an adapter type is registered, for a caller walking a config where
|
|
@@ -443,7 +511,7 @@ export default class PluginManager {
|
|
|
443
511
|
* claims to be an adapter and wrong when you are asking whether it is one.
|
|
444
512
|
*/
|
|
445
513
|
hasAdapterType(typeName) {
|
|
446
|
-
return this.adapterTypes.has(typeName);
|
|
514
|
+
return this.adapterTypes.has(this.canonicalAdapterTypeName(typeName));
|
|
447
515
|
}
|
|
448
516
|
getTextSearchAdapterType(typeName) {
|
|
449
517
|
return this.textSearchAdapterTypes.get(typeName);
|
|
@@ -457,81 +525,50 @@ export default class PluginManager {
|
|
|
457
525
|
getViewType(typeName) {
|
|
458
526
|
return this.viewTypes.get(typeName);
|
|
459
527
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
const type = display && typeof display === 'object'
|
|
472
|
-
? display.type
|
|
473
|
-
: undefined;
|
|
474
|
-
if (typeof type === 'string') {
|
|
475
|
-
displayNames.add(type);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
}
|
|
528
|
+
/**
|
|
529
|
+
* The registered view and display types a snapshot names, from every `type`
|
|
530
|
+
* string anywhere in it — `heldForMissingPlugins` included. Over-collection
|
|
531
|
+
* is harmless: a name that resolves to neither is dropped here.
|
|
532
|
+
*/
|
|
533
|
+
sessionElementTypes(sessionSnapshot) {
|
|
534
|
+
const names = new Set();
|
|
535
|
+
const walk = (node) => {
|
|
536
|
+
if (Array.isArray(node)) {
|
|
537
|
+
for (const item of node) {
|
|
538
|
+
walk(item);
|
|
479
539
|
}
|
|
480
540
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
viewNames.add(type);
|
|
489
|
-
}
|
|
490
|
-
collectViews(children);
|
|
491
|
-
collectTracks(tracks);
|
|
492
|
-
if (Array.isArray(levels)) {
|
|
493
|
-
for (const level of levels) {
|
|
494
|
-
collectTracks(level && typeof level === 'object'
|
|
495
|
-
? level.tracks
|
|
496
|
-
: undefined);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
541
|
+
else if (node && typeof node === 'object') {
|
|
542
|
+
for (const [key, value] of Object.entries(node)) {
|
|
543
|
+
if (key === 'type' && typeof value === 'string') {
|
|
544
|
+
names.add(value);
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
walk(value);
|
|
499
548
|
}
|
|
500
549
|
}
|
|
501
550
|
}
|
|
502
551
|
};
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
552
|
+
walk(sessionSnapshot);
|
|
553
|
+
return [...names].flatMap(name => {
|
|
554
|
+
const display = this.resolveDisplayTypeRecord(name);
|
|
555
|
+
return [
|
|
556
|
+
...(this.viewTypes.has(name) ? [this.getViewType(name)] : []),
|
|
557
|
+
...(display ? [display] : []),
|
|
558
|
+
];
|
|
559
|
+
});
|
|
509
560
|
}
|
|
510
561
|
/**
|
|
511
562
|
* Every async code path that hands a snapshot to a synchronous session
|
|
512
563
|
* instantiation (`setSession`, `cast`) must await this first.
|
|
513
564
|
*/
|
|
514
565
|
async preloadSessionTypes(sessionSnapshot) {
|
|
515
|
-
|
|
516
|
-
await Promise.all([
|
|
517
|
-
...[...viewNames]
|
|
518
|
-
.filter(name => this.viewTypes.has(name))
|
|
519
|
-
.map(name => this.getViewType(name).loadStateModel()),
|
|
520
|
-
...[...displayNames]
|
|
521
|
-
.map(name => this.resolveDisplayTypeRecord(name))
|
|
522
|
-
.flatMap(display => (display ? [display.loadStateModel()] : [])),
|
|
523
|
-
]);
|
|
566
|
+
await Promise.all(this.sessionElementTypes(sessionSnapshot).map(t => t.loadStateModel()));
|
|
524
567
|
}
|
|
525
568
|
unloadedSessionTypes(sessionSnapshot) {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
!this.getViewType(name).isStateModelLoaded),
|
|
530
|
-
...[...displayNames].filter(name => {
|
|
531
|
-
const display = this.resolveDisplayTypeRecord(name);
|
|
532
|
-
return display !== undefined && !display.isStateModelLoaded;
|
|
533
|
-
}),
|
|
534
|
-
];
|
|
569
|
+
return this.sessionElementTypes(sessionSnapshot)
|
|
570
|
+
.filter(t => !t.isStateModelLoaded)
|
|
571
|
+
.map(t => t.name);
|
|
535
572
|
}
|
|
536
573
|
/**
|
|
537
574
|
* Without this, a snapshot naming an unloaded lazy type fails inside MST as
|
|
@@ -7,4 +7,4 @@ export const BaseFeatureDetail = lazyMap({
|
|
|
7
7
|
BaseCard: lazy(() => import('../BaseFeatureWidget/BaseFeatureDetail/BaseCard.js')),
|
|
8
8
|
BaseAttributes: lazy(() => import('../BaseFeatureWidget/BaseFeatureDetail/BaseAttributes.js')),
|
|
9
9
|
BaseCoreDetails: lazy(() => import('../BaseFeatureWidget/BaseFeatureDetail/BaseCoreDetails.js')),
|
|
10
|
-
}
|
|
10
|
+
});
|