@jbrowse/core 2.13.1 → 2.14.0
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/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.js +2 -2
- package/BaseFeatureWidget/BaseFeatureDetail/BasicValue.js +1 -1
- package/BaseFeatureWidget/BaseFeatureDetail/DataGridDetails.js +3 -1
- package/BaseFeatureWidget/BaseFeatureDetail/index.js +28 -25
- package/BaseFeatureWidget/BaseFeatureDetail/util.js +1 -1
- package/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeatureDetails.js +11 -5
- package/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.d.ts +1 -1
- package/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.js +11 -7
- package/BaseFeatureWidget/SequenceFeatureDetails/SequencePanel.js +1 -1
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/HelpDialog.js +6 -2
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceDialog.js +11 -5
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceFeatureMenu.js +15 -5
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceTypeSelector.js +4 -2
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SettingsDialog.js +15 -5
- package/BaseFeatureWidget/SequenceFeatureDetails/hooks.js +2 -2
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/CDNASequence.js +2 -2
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/SequenceDisplay.js +5 -3
- package/BaseFeatureWidget/stateModelFactory.js +0 -2
- package/PluginLoader.d.ts +1 -2
- package/PluginLoader.js +16 -6
- package/PluginManager.d.ts +13 -13
- package/PluginManager.js +7 -2
- package/ReExports/modules.js +2 -11
- package/assemblyManager/assembly.d.ts +18 -12
- package/assemblyManager/assembly.js +75 -52
- package/assemblyManager/assemblyConfigSchema.d.ts +9 -7
- package/assemblyManager/assemblyConfigSchema.js +15 -16
- package/assemblyManager/assemblyManager.d.ts +109 -81
- package/assemblyManager/assemblyManager.js +3 -6
- package/configuration/configurationSchema.d.ts +1 -1
- package/configuration/configurationSchema.js +1 -2
- package/configuration/configurationSlot.js +7 -8
- package/configuration/util.js +0 -7
- package/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +6 -6
- package/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +6 -6
- package/data_adapters/BaseAdapter/BaseRefNameAliasAdapter.d.ts +1 -0
- package/data_adapters/CytobandAdapter/CytobandAdapter.d.ts +0 -1
- package/data_adapters/CytobandAdapter/CytobandAdapter.js +4 -8
- package/data_adapters/dataAdapterCache.d.ts +9 -6
- package/data_adapters/dataAdapterCache.js +16 -22
- package/package.json +3 -3
- package/pluggableElementTypes/AddTrackWorkflowType.js +0 -6
- package/pluggableElementTypes/ConnectionType.js +0 -6
- package/pluggableElementTypes/DisplayType.js +0 -20
- package/pluggableElementTypes/InternetAccountType.js +0 -11
- package/pluggableElementTypes/RpcMethodType.d.ts +1 -1
- package/pluggableElementTypes/TextSearchAdapterType.js +0 -3
- package/pluggableElementTypes/TrackType.js +0 -11
- package/pluggableElementTypes/ViewType.js +0 -6
- package/pluggableElementTypes/WidgetType.js +0 -6
- package/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +4 -3
- package/pluggableElementTypes/models/BaseConnectionModelFactory.js +1 -3
- package/pluggableElementTypes/models/BaseDisplayModel.d.ts +4 -5
- package/pluggableElementTypes/models/BaseDisplayModel.js +6 -14
- package/pluggableElementTypes/models/BaseTrackModel.js +8 -5
- package/pluggableElementTypes/models/InternetAccountModel.d.ts +1 -1
- package/pluggableElementTypes/models/InternetAccountModel.js +19 -13
- package/pluggableElementTypes/models/baseTrackConfig.js +2 -5
- package/pluggableElementTypes/renderers/BoxRendererType.d.ts +10 -4
- package/pluggableElementTypes/renderers/BoxRendererType.js +10 -26
- package/pluggableElementTypes/renderers/CircularChordRendererType.d.ts +1 -1
- package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.d.ts +9 -12
- package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.js +12 -19
- package/pluggableElementTypes/renderers/FeatureRendererType.d.ts +5 -5
- package/pluggableElementTypes/renderers/FeatureRendererType.js +6 -13
- package/pluggableElementTypes/renderers/RendererType.js +0 -10
- package/pluggableElementTypes/renderers/RpcRenderedSvgGroup.d.ts +1 -1
- package/pluggableElementTypes/renderers/RpcRenderedSvgGroup.js +8 -9
- package/pluggableElementTypes/renderers/ServerSideRenderedContent.js +11 -14
- package/pluggableElementTypes/renderers/ServerSideRendererType.d.ts +4 -4
- package/pluggableElementTypes/renderers/ServerSideRendererType.js +7 -5
- package/pluggableElementTypes/renderers/util/serializableFilterChain.js +0 -1
- package/rpc/BaseRpcDriver.d.ts +1 -1
- package/rpc/BaseRpcDriver.js +12 -11
- package/rpc/MainThreadRpcDriver.d.ts +2 -2
- package/rpc/MainThreadRpcDriver.js +3 -0
- package/rpc/RpcManager.d.ts +1 -1
- package/rpc/RpcManager.js +11 -8
- package/rpc/configSchema.js +0 -1
- package/rpc/methods/CoreFreeResources.d.ts +2 -2
- package/rpc/methods/CoreGetFeatureDensityStats.d.ts +2 -2
- package/rpc/methods/CoreGetFeatureDetails.d.ts +1 -1
- package/rpc/methods/CoreGetFeatureDetails.js +3 -3
- package/rpc/methods/CoreGetFeatures.d.ts +1 -1
- package/rpc/methods/CoreGetFileInfo.d.ts +1 -1
- package/rpc/methods/CoreGetMetadata.d.ts +1 -1
- package/rpc/methods/CoreGetRefNames.d.ts +1 -1
- package/rpc/methods/util.d.ts +2 -2
- package/rpc/methods/util.js +0 -3
- package/tsconfig.build.tsbuildinfo +1 -1
- package/ui/AssemblySelector.js +3 -1
- package/ui/CascadingMenu.js +2 -1
- package/ui/CascadingMenuButton.js +3 -1
- package/ui/ColorPicker.js +14 -4
- package/ui/DropDownMenu.js +3 -1
- package/ui/EditableTypography.js +6 -2
- package/ui/ErrorMessage.d.ts +2 -2
- package/ui/ErrorMessage.js +37 -20
- package/ui/ErrorMessageStackTraceDialog.js +11 -9
- package/ui/FactoryResetDialog.d.ts +1 -1
- package/ui/FactoryResetDialog.js +9 -3
- package/ui/FatalErrorDialog.js +9 -3
- package/ui/FileSelector/FileSelector.js +8 -4
- package/ui/FileSelector/LocalFileChooser.js +7 -6
- package/ui/LoadingEllipses.js +1 -1
- package/ui/Menu.d.ts +4 -4
- package/ui/Menu.js +6 -9
- package/ui/MenuButton.js +6 -2
- package/ui/PrerenderedCanvas.js +8 -5
- package/ui/RedErrorMessageBox.js +13 -8
- package/ui/ResizeHandle.d.ts +1 -1
- package/ui/ReturnToImportFormDialog.js +3 -1
- package/ui/SanitizedHTML.js +1 -3
- package/ui/SnackbarModel.d.ts +12 -1
- package/ui/SnackbarModel.js +19 -3
- package/ui/theme.js +5 -5
- package/util/Base1DViewModel.js +3 -1
- package/util/QuickLRU.js +8 -8
- package/util/TimeTraveller.js +12 -4
- package/util/analytics.js +0 -1
- package/util/blockTypes.js +5 -9
- package/util/calculateStaticBlocks.d.ts +1 -1
- package/util/compositeMap.js +2 -2
- package/util/idMaker.js +0 -1
- package/util/index.d.ts +9 -8
- package/util/index.js +91 -51
- package/util/io/RemoteFileWithRangeCache.js +1 -3
- package/util/io/index.js +3 -5
- package/util/jexlStrings.js +5 -8
- package/util/layouts/GranularRectLayout.js +1 -4
- package/util/layouts/SceneGraph.d.ts +1 -1
- package/util/layouts/SceneGraph.js +2 -6
- package/util/map-obj.js +15 -7
- package/util/mst-reflection.js +1 -2
- package/util/nanoid.js +9 -8
- package/util/offscreenCanvasPonyfill.d.ts +1 -1
- package/util/offscreenCanvasPonyfill.js +7 -10
- package/util/offscreenCanvasUtils.d.ts +1 -1
- package/util/offscreenCanvasUtils.js +1 -3
- package/util/rxjs.js +4 -2
- package/util/simpleFeature.d.ts +2 -3
- package/util/simpleFeature.js +9 -12
- package/util/stats.js +3 -1
- package/util/tracks.d.ts +4 -2
- package/util/tracks.js +10 -11
- package/util/types/index.d.ts +5 -5
- package/util/types/index.js +8 -1
- package/util/types/mst.js +1 -0
- package/util/when.js +7 -2
|
@@ -33,12 +33,12 @@ function ArrayValue({ name, value, description, prefix = [], }) {
|
|
|
33
33
|
react_1.default.createElement(BasicValue_1.default, { value: value[0] })));
|
|
34
34
|
}
|
|
35
35
|
else if (value.every(val => (0, is_object_1.default)(val))) {
|
|
36
|
-
return (react_1.default.createElement(react_1.default.Fragment, null, value.map((val, i) => (react_1.default.createElement(Attributes_1.default, { key: JSON.stringify(val)
|
|
36
|
+
return (react_1.default.createElement(react_1.default.Fragment, null, value.map((val, i) => (react_1.default.createElement(Attributes_1.default, { key: `${JSON.stringify(val)}-${i}`, attributes: val, prefix: [...prefix, `${name}-${i}`] })))));
|
|
37
37
|
}
|
|
38
38
|
else {
|
|
39
39
|
return (react_1.default.createElement("div", { className: classes.field },
|
|
40
40
|
react_1.default.createElement(FieldName_1.default, { prefix: prefix, description: description, name: name }),
|
|
41
|
-
value.map((val, i) => (react_1.default.createElement("div", { key: JSON.stringify(val)
|
|
41
|
+
value.map((val, i) => (react_1.default.createElement("div", { key: `${JSON.stringify(val)}-${i}`, className: classes.fieldSubvalue },
|
|
42
42
|
react_1.default.createElement(BasicValue_1.default, { value: val }))))));
|
|
43
43
|
}
|
|
44
44
|
}
|
|
@@ -21,6 +21,6 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
21
21
|
}));
|
|
22
22
|
function BasicValue({ value }) {
|
|
23
23
|
const { classes } = useStyles();
|
|
24
|
-
const isLink = `${value}
|
|
24
|
+
const isLink = /^https?:\/\//.exec(`${value}`);
|
|
25
25
|
return (react_1.default.createElement("div", { className: classes.fieldValue }, react_1.default.isValidElement(value) ? (value) : isLink ? (react_1.default.createElement(material_1.Link, { href: `${value}` }, `${value}`)) : (react_1.default.createElement(ui_1.SanitizedHTML, { html: (0, is_object_1.default)(value) ? JSON.stringify(value) : String(value) }))));
|
|
26
26
|
}
|
|
@@ -78,7 +78,9 @@ function DataGridDetails({ value, prefix, name, }) {
|
|
|
78
78
|
if (unionKeys.size < keys.length + 5) {
|
|
79
79
|
return (react_1.default.createElement("div", { className: classes.margin },
|
|
80
80
|
react_1.default.createElement(FieldName_1.default, { prefix: prefix, name: name }),
|
|
81
|
-
react_1.default.createElement(material_1.FormControlLabel, { control: react_1.default.createElement(material_1.Checkbox, { checked: checked, onChange: event =>
|
|
81
|
+
react_1.default.createElement(material_1.FormControlLabel, { control: react_1.default.createElement(material_1.Checkbox, { checked: checked, onChange: event => {
|
|
82
|
+
setChecked(event.target.checked);
|
|
83
|
+
} }), label: react_1.default.createElement(material_1.Typography, { variant: "body2" }, "Show options") }),
|
|
82
84
|
react_1.default.createElement(x_data_grid_1.DataGrid, { autoHeight: true, disableRowSelectionOnClick: true, rows: rows, rowHeight: 20, columnHeaderHeight: 35, hideFooter: rows.length < 25, slots: {
|
|
83
85
|
toolbar: checked ? x_data_grid_1.GridToolbar : null,
|
|
84
86
|
}, slotProps: {
|
|
@@ -29,7 +29,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports.Attributes = exports.BaseAttributes = exports.BaseCoreDetails = void 0;
|
|
30
30
|
exports.BaseCard = BaseCard;
|
|
31
31
|
exports.FeatureDetails = FeatureDetails;
|
|
32
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
33
32
|
const react_1 = __importStar(require("react"));
|
|
34
33
|
const react_error_boundary_1 = require("react-error-boundary");
|
|
35
34
|
const material_1 = require("@mui/material");
|
|
@@ -54,22 +53,26 @@ const coreDetails = [
|
|
|
54
53
|
'description',
|
|
55
54
|
'type',
|
|
56
55
|
];
|
|
57
|
-
const useStyles = (0, mui_1.makeStyles)()(theme => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
},
|
|
67
|
-
});
|
|
68
|
-
});
|
|
56
|
+
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
57
|
+
expansionPanelDetails: {
|
|
58
|
+
display: 'block',
|
|
59
|
+
padding: theme.spacing(1),
|
|
60
|
+
},
|
|
61
|
+
expandIcon: {
|
|
62
|
+
color: theme.palette.tertiary.contrastText || '#fff',
|
|
63
|
+
},
|
|
64
|
+
}));
|
|
69
65
|
function BaseCard({ children, title, defaultExpanded = true, }) {
|
|
70
66
|
const { classes } = useStyles();
|
|
71
67
|
const [expanded, setExpanded] = (0, react_1.useState)(defaultExpanded);
|
|
72
|
-
return (react_1.default.createElement(material_1.Accordion, { expanded: expanded, onChange: () =>
|
|
68
|
+
return (react_1.default.createElement(material_1.Accordion, { expanded: expanded, onChange: () => {
|
|
69
|
+
setExpanded(s => !s);
|
|
70
|
+
}, slotProps: {
|
|
71
|
+
transition: {
|
|
72
|
+
unmountOnExit: true,
|
|
73
|
+
timeout: 150,
|
|
74
|
+
},
|
|
75
|
+
} },
|
|
73
76
|
react_1.default.createElement(material_1.AccordionSummary, { expandIcon: react_1.default.createElement(ExpandMore_1.default, { className: classes.expandIcon }) },
|
|
74
77
|
react_1.default.createElement(material_1.Typography, { variant: "button" }, title)),
|
|
75
78
|
react_1.default.createElement(material_1.AccordionDetails, { className: classes.expansionPanelDetails }, children)));
|
|
@@ -89,7 +92,6 @@ function Position(props) {
|
|
|
89
92
|
function CoreDetails(props) {
|
|
90
93
|
const { feature } = props;
|
|
91
94
|
const obj = feature;
|
|
92
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
93
95
|
const formattedFeat = { ...obj, ...obj.__jbrowsefmt };
|
|
94
96
|
const { start, end } = formattedFeat;
|
|
95
97
|
const displayedDetails = {
|
|
@@ -132,21 +134,19 @@ function FeatureDetails(props) {
|
|
|
132
134
|
feature,
|
|
133
135
|
model,
|
|
134
136
|
});
|
|
137
|
+
const m = mate;
|
|
135
138
|
return (react_1.default.createElement(BaseCard, { title: (0, util_2.generateTitle)(name, id, type) },
|
|
136
139
|
react_1.default.createElement(material_1.Typography, null, "Core details"),
|
|
137
140
|
react_1.default.createElement(CoreDetails, { ...props }),
|
|
138
|
-
|
|
141
|
+
m ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
139
142
|
react_1.default.createElement(material_1.Divider, null),
|
|
140
143
|
react_1.default.createElement(material_1.Typography, null, "Mate details"),
|
|
141
144
|
react_1.default.createElement(CoreDetails, { ...props, feature: {
|
|
142
|
-
...
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
// @ts-expect-error
|
|
148
|
-
refName: mate.refName,
|
|
149
|
-
uniqueId: uniqueId + '-mate',
|
|
145
|
+
...m,
|
|
146
|
+
start: m.start,
|
|
147
|
+
end: m.end,
|
|
148
|
+
refName: m.refName,
|
|
149
|
+
uniqueId: `${uniqueId}-mate`,
|
|
150
150
|
} }))) : null,
|
|
151
151
|
react_1.default.createElement(material_1.Divider, null),
|
|
152
152
|
react_1.default.createElement(material_1.Typography, null, "Attributes"),
|
|
@@ -157,7 +157,10 @@ function FeatureDetails(props) {
|
|
|
157
157
|
react_1.default.createElement(material_1.Divider, null),
|
|
158
158
|
react_1.default.createElement(BaseCard, { title: ExtraPanel.name },
|
|
159
159
|
react_1.default.createElement(ExtraPanel.Component, { ...props })))) : null,
|
|
160
|
-
depth < maxDepth && (subfeatures === null || subfeatures === void 0 ? void 0 : subfeatures.length) ? (react_1.default.createElement(BaseCard, { title: "Subfeatures", defaultExpanded: depth < 1 }, subfeatures.map((sub, idx) => (react_1.default.createElement(FeatureDetails, { key: JSON.stringify(sub), feature: {
|
|
160
|
+
depth < maxDepth && (subfeatures === null || subfeatures === void 0 ? void 0 : subfeatures.length) ? (react_1.default.createElement(BaseCard, { title: "Subfeatures", defaultExpanded: depth < 1 }, subfeatures.map((sub, idx) => (react_1.default.createElement(FeatureDetails, { key: JSON.stringify(sub), feature: {
|
|
161
|
+
...sub,
|
|
162
|
+
uniqueId: `${uniqueId}_${idx}`,
|
|
163
|
+
}, model: model, depth: depth + 1 }))))) : null));
|
|
161
164
|
}
|
|
162
165
|
const BaseFeatureDetail = (0, mobx_react_1.observer)(function ({ model }) {
|
|
163
166
|
const { error, featureData } = model;
|
|
@@ -35,7 +35,7 @@ function accessNested(arr, obj = {}) {
|
|
|
35
35
|
});
|
|
36
36
|
return typeof obj2 === 'string'
|
|
37
37
|
? obj2
|
|
38
|
-
: (0, is_object_1.default)(obj2) && typeof
|
|
38
|
+
: (0, is_object_1.default)(obj2) && typeof obj2.Description === 'string'
|
|
39
39
|
? obj2.Description
|
|
40
40
|
: undefined;
|
|
41
41
|
}
|
|
@@ -59,18 +59,24 @@ const SequenceFeatureDetails = (0, mobx_react_1.observer)(function ({ model, fea
|
|
|
59
59
|
onClick: () => {
|
|
60
60
|
// this is given a setTimeout because it allows the menu to
|
|
61
61
|
// close before dialog opens
|
|
62
|
-
setTimeout(() =>
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
setOpenInDialog(true);
|
|
64
|
+
}, 1);
|
|
63
65
|
},
|
|
64
66
|
},
|
|
65
67
|
] })),
|
|
66
68
|
openInDialog ? (react_1.default.createElement("div", null,
|
|
67
69
|
"Open in dialog...",
|
|
68
70
|
react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(ui_1.LoadingEllipses, null) },
|
|
69
|
-
react_1.default.createElement(SequenceDialog, { model: model, feature: feature, handleClose: () =>
|
|
71
|
+
react_1.default.createElement(SequenceDialog, { model: model, feature: feature, handleClose: () => {
|
|
72
|
+
setOpenInDialog(false);
|
|
73
|
+
} })))) : (react_1.default.createElement("div", null,
|
|
70
74
|
feature.type === 'gene' ? (react_1.default.createElement(material_1.Typography, null, "Note: inspect subfeature sequences for protein/CDS computations")) : null,
|
|
71
|
-
error ? (react_1.default.createElement(ui_1.ErrorMessage, { error: error })) : !sequence ? (react_1.default.createElement(ui_1.LoadingEllipses, null)) :
|
|
75
|
+
error ? (react_1.default.createElement(ui_1.ErrorMessage, { error: error })) : !sequence ? (react_1.default.createElement(ui_1.LoadingEllipses, null)) : 'error' in sequence ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
72
76
|
react_1.default.createElement(material_1.Typography, { color: "error" }, sequence.error),
|
|
73
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "inherit", onClick: () =>
|
|
74
|
-
|
|
77
|
+
react_1.default.createElement(material_1.Button, { variant: "contained", color: "inherit", onClick: () => {
|
|
78
|
+
setForce(true);
|
|
79
|
+
} }, "Force load"))) : (react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(ui_1.LoadingEllipses, null) },
|
|
80
|
+
react_1.default.createElement(SequencePanel, { ref: seqPanelRef, feature: feature, sequence: sequence, model: sequenceFeatureDetails })))))));
|
|
75
81
|
});
|
|
76
82
|
exports.default = SequenceFeatureDetails;
|
|
@@ -4,5 +4,5 @@ import { SimpleFeatureSerialized } from '../../util';
|
|
|
4
4
|
declare const SequenceFeaturePanel: ({ model, feature, }: {
|
|
5
5
|
model: BaseFeatureWidgetModel;
|
|
6
6
|
feature: SimpleFeatureSerialized;
|
|
7
|
-
}) => React.JSX.Element
|
|
7
|
+
}) => React.JSX.Element;
|
|
8
8
|
export default SequenceFeaturePanel;
|
|
@@ -53,15 +53,19 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
53
53
|
const SequenceFeaturePanel = (0, mobx_react_1.observer)(function ({ model, feature, }) {
|
|
54
54
|
const { classes } = useStyles();
|
|
55
55
|
const [shown, setShown] = (0, react_1.useState)(false);
|
|
56
|
-
return
|
|
56
|
+
return (react_1.default.createElement("div", { className: classes.container },
|
|
57
57
|
react_1.default.createElement(material_1.FormControl, { className: classes.formControl },
|
|
58
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", onClick: () =>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
react_1.default.createElement(material_1.Button, { variant: "contained", onClick: () => {
|
|
59
|
+
setShown(!shown);
|
|
60
|
+
} }, shown ? 'Hide feature sequence' : 'Show feature sequence')),
|
|
61
|
+
react_1.default.createElement(material_1.IconButton, { onClick: () => {
|
|
62
|
+
(0, util_1.getSession)(model).queueDialog(handleClose => [
|
|
63
|
+
HelpDialog,
|
|
64
|
+
{ handleClose },
|
|
65
|
+
]);
|
|
66
|
+
} },
|
|
63
67
|
react_1.default.createElement(Help_1.default, null)),
|
|
64
68
|
shown ? (react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(ui_1.LoadingEllipses, null) },
|
|
65
|
-
react_1.default.createElement(SequenceFeatureDetails, { key: feature.uniqueId, model: model, feature: feature }))) : null))
|
|
69
|
+
react_1.default.createElement(SequenceFeatureDetails, { key: feature.uniqueId, model: model, feature: feature }))) : null));
|
|
66
70
|
});
|
|
67
71
|
exports.default = SequenceFeaturePanel;
|
|
@@ -95,7 +95,7 @@ const SequencePanel = (0, mobx_react_1.observer)(react_1.default.forwardRef(func
|
|
|
95
95
|
return (react_1.default.createElement("div", { "data-testid": "sequence_panel", ref: ref, style: { maxHeight: 300, overflow: 'auto' } },
|
|
96
96
|
react_1.default.createElement(Container, null,
|
|
97
97
|
react_1.default.createElement("div", { style: { background: 'white' } }, `>${[
|
|
98
|
-
|
|
98
|
+
`${feature.name || feature.id}-${mode}`,
|
|
99
99
|
`${feature.refName}:${(0, util_1.toLocale)(feature.start + 1)}-${(0, util_1.toLocale)(feature.end)}${getStrand(feature.strand)}`,
|
|
100
100
|
mode.endsWith('updownstream')
|
|
101
101
|
? `+/- ${(0, util_1.toLocale)(model.upDownBp)} up/downstream bp`
|
|
@@ -10,7 +10,9 @@ const ui_1 = require("@jbrowse/core/ui");
|
|
|
10
10
|
// icons
|
|
11
11
|
const Settings_1 = __importDefault(require("@mui/icons-material/Settings"));
|
|
12
12
|
function HelpDialog({ handleClose, }) {
|
|
13
|
-
return (react_1.default.createElement(ui_1.Dialog, { maxWidth: "xl", open: true, onClose: () =>
|
|
13
|
+
return (react_1.default.createElement(ui_1.Dialog, { maxWidth: "xl", open: true, onClose: () => {
|
|
14
|
+
handleClose();
|
|
15
|
+
}, title: "Feature sequence panel help" },
|
|
14
16
|
react_1.default.createElement(material_1.DialogContent, null,
|
|
15
17
|
react_1.default.createElement(material_1.Typography, { paragraph: true }, "The \"Feature sequence\" panel shows the underlying genomic sequence for a given feature, fetched from the reference genome."),
|
|
16
18
|
react_1.default.createElement(material_1.Typography, null, "For gene features, this panel does special calculations to e.g. stitch together the coding sequence, the options are:"),
|
|
@@ -28,5 +30,7 @@ function HelpDialog({ handleClose, }) {
|
|
|
28
30
|
" to edit the number of bp displayed up/downstream and in the intron region"),
|
|
29
31
|
react_1.default.createElement(material_1.Typography, null, "Note 2: The 'Copy HTML' function retains the colors from the sequence panel but cannot be pasted into some programs like notepad that only expect plain text.")),
|
|
30
32
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
31
|
-
react_1.default.createElement(material_1.Button, { onClick: () =>
|
|
33
|
+
react_1.default.createElement(material_1.Button, { onClick: () => {
|
|
34
|
+
handleClose();
|
|
35
|
+
}, autoFocus: true, variant: "contained" }, "Close"))));
|
|
32
36
|
}
|
|
@@ -52,18 +52,24 @@ const SequenceDialog = (0, mobx_react_1.observer)(function ({ handleClose, model
|
|
|
52
52
|
const seqPanelRef = (0, react_1.useRef)(null);
|
|
53
53
|
const [force, setForce] = (0, react_1.useState)(false);
|
|
54
54
|
const { sequence, error } = (0, hooks_1.useFeatureSequence)(model, feature, upDownBp, force);
|
|
55
|
-
return (react_1.default.createElement(ui_1.Dialog, { maxWidth: "xl", open: true, onClose: () =>
|
|
55
|
+
return (react_1.default.createElement(ui_1.Dialog, { maxWidth: "xl", open: true, onClose: () => {
|
|
56
|
+
handleClose();
|
|
57
|
+
}, title: "Sequence view" },
|
|
56
58
|
react_1.default.createElement(material_1.DialogContent, { className: classes.dialogContent },
|
|
57
59
|
react_1.default.createElement("div", null,
|
|
58
60
|
react_1.default.createElement(SequenceTypeSelector_1.default, { model: sequenceFeatureDetails }),
|
|
59
61
|
react_1.default.createElement(SequenceFeatureMenu_1.default, { ref: seqPanelRef, model: sequenceFeatureDetails })),
|
|
60
62
|
react_1.default.createElement("div", null,
|
|
61
63
|
feature.type === 'gene' ? (react_1.default.createElement(material_1.Typography, null, "Note: inspect subfeature sequences for protein/CDS computations")) : null,
|
|
62
|
-
error ? (react_1.default.createElement(ui_1.ErrorMessage, { error: error })) : !sequence ? (react_1.default.createElement(ui_1.LoadingEllipses, null)) :
|
|
64
|
+
error ? (react_1.default.createElement(ui_1.ErrorMessage, { error: error })) : !sequence ? (react_1.default.createElement(ui_1.LoadingEllipses, null)) : 'error' in sequence ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
63
65
|
react_1.default.createElement(material_1.Typography, { color: "error" }, sequence.error),
|
|
64
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "inherit", onClick: () =>
|
|
65
|
-
|
|
66
|
+
react_1.default.createElement(material_1.Button, { variant: "contained", color: "inherit", onClick: () => {
|
|
67
|
+
setForce(true);
|
|
68
|
+
} }, "Force load"))) : (react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(ui_1.LoadingEllipses, null) },
|
|
69
|
+
react_1.default.createElement(SequencePanel_1.default, { ref: seqPanelRef, feature: feature, sequence: sequence, model: sequenceFeatureDetails }))))),
|
|
66
70
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
67
|
-
react_1.default.createElement(material_1.Button, { onClick: () =>
|
|
71
|
+
react_1.default.createElement(material_1.Button, { onClick: () => {
|
|
72
|
+
handleClose();
|
|
73
|
+
}, variant: "contained" }, "Close"))));
|
|
68
74
|
});
|
|
69
75
|
exports.default = SequenceDialog;
|
|
@@ -94,13 +94,17 @@ const SequenceFeatureMenu = (0, mobx_react_1.observer)(react_1.default.forwardRe
|
|
|
94
94
|
label: 'No coordinates',
|
|
95
95
|
type: 'radio',
|
|
96
96
|
checked: showCoordinatesSetting === 'none',
|
|
97
|
-
onClick: () =>
|
|
97
|
+
onClick: () => {
|
|
98
|
+
model.setShowCoordinates('none');
|
|
99
|
+
},
|
|
98
100
|
},
|
|
99
101
|
{
|
|
100
102
|
label: 'Coordinates relative to feature start',
|
|
101
103
|
type: 'radio',
|
|
102
104
|
checked: showCoordinatesSetting === 'relative',
|
|
103
|
-
onClick: () =>
|
|
105
|
+
onClick: () => {
|
|
106
|
+
model.setShowCoordinates('relative');
|
|
107
|
+
},
|
|
104
108
|
},
|
|
105
109
|
...(showGenomicCoordsOption
|
|
106
110
|
? [
|
|
@@ -108,7 +112,9 @@ const SequenceFeatureMenu = (0, mobx_react_1.observer)(react_1.default.forwardRe
|
|
|
108
112
|
label: 'Coordinates relative to genome (only available for continuous genome based sequence types)',
|
|
109
113
|
type: 'radio',
|
|
110
114
|
checked: showCoordinatesSetting === 'genomic',
|
|
111
|
-
onClick: () =>
|
|
115
|
+
onClick: () => {
|
|
116
|
+
model.setShowCoordinates('genomic');
|
|
117
|
+
},
|
|
112
118
|
},
|
|
113
119
|
]
|
|
114
120
|
: []),
|
|
@@ -117,10 +123,14 @@ const SequenceFeatureMenu = (0, mobx_react_1.observer)(react_1.default.forwardRe
|
|
|
117
123
|
{
|
|
118
124
|
label: 'Settings',
|
|
119
125
|
icon: Settings_1.default,
|
|
120
|
-
onClick: () =>
|
|
126
|
+
onClick: () => {
|
|
127
|
+
setShowSettings(true);
|
|
128
|
+
},
|
|
121
129
|
},
|
|
122
130
|
] },
|
|
123
131
|
react_1.default.createElement(MoreVert_1.default, null)),
|
|
124
|
-
showSettings ? (react_1.default.createElement(SequenceFeatureSettingsDialog, { model: model, handleClose: () =>
|
|
132
|
+
showSettings ? (react_1.default.createElement(SequenceFeatureSettingsDialog, { model: model, handleClose: () => {
|
|
133
|
+
setShowSettings(false);
|
|
134
|
+
} })) : null));
|
|
125
135
|
}));
|
|
126
136
|
exports.default = SequenceFeatureMenu;
|
|
@@ -17,7 +17,9 @@ const SequenceTypeSelector = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
|
17
17
|
const { classes } = useStyles();
|
|
18
18
|
const { intronBp, upDownBp, mode, hasCDS, hasExonOrCDS } = model;
|
|
19
19
|
return (react_1.default.createElement(material_1.FormControl, { className: classes.formControl },
|
|
20
|
-
react_1.default.createElement(material_1.Select, { size: "small", value: mode, onChange: event =>
|
|
20
|
+
react_1.default.createElement(material_1.Select, { size: "small", value: mode, onChange: event => {
|
|
21
|
+
model.setMode(event.target.value);
|
|
22
|
+
} }, Object.entries({
|
|
21
23
|
...(hasCDS
|
|
22
24
|
? {
|
|
23
25
|
cds: 'CDS',
|
|
@@ -35,7 +37,7 @@ const SequenceTypeSelector = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
|
35
37
|
: {}),
|
|
36
38
|
...(hasExonOrCDS
|
|
37
39
|
? {
|
|
38
|
-
gene:
|
|
40
|
+
gene: 'Genomic w/ full introns',
|
|
39
41
|
}
|
|
40
42
|
: {}),
|
|
41
43
|
...(hasExonOrCDS
|
|
@@ -55,13 +55,21 @@ const SequenceFeatureSettingsDialog = (0, mobx_react_1.observer)(function ({ han
|
|
|
55
55
|
const [upDownBp, setUpDownBp] = (0, react_1.useState)(`${model.upDownBp}`);
|
|
56
56
|
const intronBpValid = !Number.isNaN(+intronBp);
|
|
57
57
|
const upDownBpValid = !Number.isNaN(+upDownBp);
|
|
58
|
-
return (react_1.default.createElement(ui_1.Dialog, { maxWidth: "xl", open: true, onClose: () =>
|
|
58
|
+
return (react_1.default.createElement(ui_1.Dialog, { maxWidth: "xl", open: true, onClose: () => {
|
|
59
|
+
handleClose();
|
|
60
|
+
}, title: "Feature sequence settings" },
|
|
59
61
|
react_1.default.createElement(material_1.DialogContent, { className: classes.dialogContent },
|
|
60
|
-
react_1.default.createElement(TextField2, { label: "Number of intronic bases around splice site to display", className: classes.formElt, value: intronBp, helperText: !intronBpValid ? 'Not a number' : '', error: !intronBpValid, onChange: event =>
|
|
61
|
-
|
|
62
|
+
react_1.default.createElement(TextField2, { label: "Number of intronic bases around splice site to display", className: classes.formElt, value: intronBp, helperText: !intronBpValid ? 'Not a number' : '', error: !intronBpValid, onChange: event => {
|
|
63
|
+
setIntronBp(event.target.value);
|
|
64
|
+
} }),
|
|
65
|
+
react_1.default.createElement(TextField2, { label: "Number of bases up/down stream of feature to display", className: classes.formElt, value: upDownBp, helperText: !upDownBpValid ? 'Not a number' : '', error: !upDownBpValid, onChange: event => {
|
|
66
|
+
setUpDownBp(event.target.value);
|
|
67
|
+
} }),
|
|
62
68
|
react_1.default.createElement(FormControl2, null,
|
|
63
69
|
react_1.default.createElement(material_1.FormLabel, null, "Sequence capitalization"),
|
|
64
|
-
react_1.default.createElement(material_1.RadioGroup, { value: upperCaseCDS ? 'cds' : 'unchanged', onChange: e =>
|
|
70
|
+
react_1.default.createElement(material_1.RadioGroup, { value: upperCaseCDS ? 'cds' : 'unchanged', onChange: e => {
|
|
71
|
+
model.setUpperCaseCDS(e.target.value === 'cds');
|
|
72
|
+
} },
|
|
65
73
|
react_1.default.createElement(material_1.FormControlLabel, { value: "cds", control: react_1.default.createElement(material_1.Radio, { className: classes.root, size: "small" }), label: "Capitalize CDS and lower case everything else" }),
|
|
66
74
|
react_1.default.createElement(material_1.FormControlLabel, { value: "unchanged", control: react_1.default.createElement(material_1.Radio, { className: classes.root, size: "small" }), label: "Capitalization from reference genome sequence" })))),
|
|
67
75
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
@@ -70,6 +78,8 @@ const SequenceFeatureSettingsDialog = (0, mobx_react_1.observer)(function ({ han
|
|
|
70
78
|
model.setUpDownBp(+upDownBp);
|
|
71
79
|
handleClose();
|
|
72
80
|
}, disabled: !intronBpValid || !upDownBpValid, color: "primary", variant: "contained" }, "Submit"),
|
|
73
|
-
react_1.default.createElement(material_1.Button, { onClick: () =>
|
|
81
|
+
react_1.default.createElement(material_1.Button, { onClick: () => {
|
|
82
|
+
handleClose();
|
|
83
|
+
}, color: "secondary", autoFocus: true, variant: "contained" }, "Cancel"))));
|
|
74
84
|
});
|
|
75
85
|
exports.default = SequenceFeatureSettingsDialog;
|
|
@@ -9,12 +9,12 @@ function useFeatureSequence(model, feature, upDownBp, forceLoad) {
|
|
|
9
9
|
const [sequence, setSequence] = (0, react_1.useState)();
|
|
10
10
|
const [error, setError] = (0, react_1.useState)();
|
|
11
11
|
(0, react_1.useEffect)(() => {
|
|
12
|
-
var _a;
|
|
12
|
+
var _a, _b;
|
|
13
13
|
if (!model) {
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
16
|
const { assemblyManager, rpcManager } = (0, util_1.getSession)(model);
|
|
17
|
-
const
|
|
17
|
+
const assemblyName = ((_b = (_a = model.view) === null || _a === void 0 ? void 0 : _a.assemblyNames) === null || _b === void 0 ? void 0 : _b[0]) || '';
|
|
18
18
|
async function fetchSeq(start, end, refName) {
|
|
19
19
|
const assembly = await assemblyManager.waitForAssembly(assemblyName);
|
|
20
20
|
if (!assembly) {
|
|
@@ -51,7 +51,7 @@ const CDNASequence = (0, mobx_react_1.observer)(function ({ utr, cds, exons, seq
|
|
|
51
51
|
currRemainder,
|
|
52
52
|
showCoordinates,
|
|
53
53
|
});
|
|
54
|
-
middleChunks.push(react_1.default.createElement(SequenceDisplay_1.default, { key: JSON.stringify(chunk)
|
|
54
|
+
middleChunks.push(react_1.default.createElement(SequenceDisplay_1.default, { key: `${JSON.stringify(chunk)}-mid`, model: model, color: chunk.type === 'CDS' ? util_1.cdsColor : util_1.utrColor, strand: mult, start: currStart, coordStart: coordStart, chunks: segments }));
|
|
55
55
|
currRemainder = remainder;
|
|
56
56
|
currStart = currStart + s.length * mult;
|
|
57
57
|
coordStart = coordStart + s.length * mult;
|
|
@@ -66,7 +66,7 @@ const CDNASequence = (0, mobx_react_1.observer)(function ({ utr, cds, exons, seq
|
|
|
66
66
|
showCoordinates,
|
|
67
67
|
});
|
|
68
68
|
if (segments.length) {
|
|
69
|
-
middleChunks.push(react_1.default.createElement(SequenceDisplay_1.default, { key: JSON.stringify(chunk)
|
|
69
|
+
middleChunks.push(react_1.default.createElement(SequenceDisplay_1.default, { key: `${JSON.stringify(chunk)}-intron`, model: model, strand: mult, coordStart: coordStart, start: currStart, chunks: segments }));
|
|
70
70
|
currRemainder = remainder;
|
|
71
71
|
currStart = currStart + str.length * mult;
|
|
72
72
|
coordStart = coordStart + str.length * mult;
|
|
@@ -10,8 +10,8 @@ const SequenceDisplay = (0, mobx_react_1.observer)(function ({ chunks, start, co
|
|
|
10
10
|
return chunks.map((chunk, idx) => {
|
|
11
11
|
var _a;
|
|
12
12
|
const f = coordStart - (start % charactersPerRow);
|
|
13
|
-
const prefix = (idx
|
|
14
|
-
? `${f + idx * strand * charactersPerRow}`.padStart(4)
|
|
13
|
+
const prefix = (idx === 0 && start % charactersPerRow === 0) || idx > 0
|
|
14
|
+
? `${`${f + idx * strand * charactersPerRow}`.padStart(4)} `
|
|
15
15
|
: '';
|
|
16
16
|
const postfix = idx === chunks.length - 1 &&
|
|
17
17
|
(((_a = chunks.at(-1)) === null || _a === void 0 ? void 0 : _a.replaceAll(' ', '').length) || 0) +
|
|
@@ -21,7 +21,9 @@ const SequenceDisplay = (0, mobx_react_1.observer)(function ({ chunks, start, co
|
|
|
21
21
|
: showCoordinates
|
|
22
22
|
? ' \n'
|
|
23
23
|
: '';
|
|
24
|
-
return (
|
|
24
|
+
return (
|
|
25
|
+
/* biome-ignore lint/suspicious/noArrayIndexKey: */
|
|
26
|
+
react_1.default.createElement(react_1.default.Fragment, { key: `${chunk}-${idx}` },
|
|
25
27
|
showCoordinates ? prefix : null,
|
|
26
28
|
react_1.default.createElement("span", { style: { background: color } }, chunk),
|
|
27
29
|
postfix));
|
|
@@ -129,10 +129,8 @@ function stateModelFactory(pluginManager) {
|
|
|
129
129
|
...(0, configuration_1.getConf)(track, ['formatDetails', arg2], { feature }),
|
|
130
130
|
});
|
|
131
131
|
if (track) {
|
|
132
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
133
132
|
feature.__jbrowsefmt = combine('feature', feature);
|
|
134
133
|
formatSubfeatures(feature, (0, configuration_1.getConf)(track, ['formatDetails', 'depth']), sub => {
|
|
135
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
136
134
|
sub.__jbrowsefmt = combine('subfeatures', sub);
|
|
137
135
|
});
|
|
138
136
|
}
|
package/PluginLoader.d.ts
CHANGED
|
@@ -31,8 +31,7 @@ export interface CJSPluginDefinition {
|
|
|
31
31
|
cjsUrl: string;
|
|
32
32
|
}
|
|
33
33
|
export declare function isCJSPluginDefinition(def: PluginDefinition): def is CJSPluginDefinition;
|
|
34
|
-
export
|
|
35
|
-
}
|
|
34
|
+
export type PluginDefinition = UMDUrlPluginDefinition | UMDLocPluginDefinition | LegacyUMDPluginDefinition | ESMLocPluginDefinition | ESMUrlPluginDefinition | CJSPluginDefinition;
|
|
36
35
|
export interface PluginRecord {
|
|
37
36
|
plugin: PluginConstructor;
|
|
38
37
|
definition: PluginDefinition;
|
package/PluginLoader.js
CHANGED
|
@@ -13,13 +13,21 @@ const Plugin_1 = __importDefault(require("./Plugin"));
|
|
|
13
13
|
const ReExports_1 = __importDefault(require("./ReExports"));
|
|
14
14
|
const util_1 = require("./util");
|
|
15
15
|
function isUMDPluginDefinition(def) {
|
|
16
|
-
return (
|
|
16
|
+
return (
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18
|
+
(def.umdUrl !== undefined ||
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
17
20
|
def.url !== undefined ||
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18
22
|
def.umdLoc !== undefined) &&
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
19
24
|
def.name !== undefined);
|
|
20
25
|
}
|
|
21
26
|
function isESMPluginDefinition(def) {
|
|
22
|
-
return (
|
|
27
|
+
return (
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
29
|
+
def.esmUrl !== undefined ||
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
23
31
|
def.esmLoc !== undefined);
|
|
24
32
|
}
|
|
25
33
|
function promisifiedLoadScript(src) {
|
|
@@ -39,7 +47,7 @@ async function loadScript(scriptUrl) {
|
|
|
39
47
|
return promisifiedLoadScript(scriptUrl);
|
|
40
48
|
}
|
|
41
49
|
// @ts-expect-error
|
|
42
|
-
if (globalThis
|
|
50
|
+
if (globalThis.importScripts) {
|
|
43
51
|
// @ts-expect-error
|
|
44
52
|
await globalThis.importScripts(scriptUrl);
|
|
45
53
|
return;
|
|
@@ -47,16 +55,16 @@ async function loadScript(scriptUrl) {
|
|
|
47
55
|
throw new Error('cannot figure out how to load external JS scripts in this environment');
|
|
48
56
|
}
|
|
49
57
|
function isCJSPluginDefinition(def) {
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
50
59
|
return def.cjsUrl !== undefined;
|
|
51
60
|
}
|
|
52
61
|
function pluginDescriptionString(pluginDefinition) {
|
|
53
|
-
var _a;
|
|
54
62
|
if (isUMDPluginDefinition(pluginDefinition)) {
|
|
55
63
|
return `UMD plugin ${pluginDefinition.name}`;
|
|
56
64
|
}
|
|
57
65
|
if (isESMPluginDefinition(pluginDefinition)) {
|
|
58
66
|
return `ESM plugin ${pluginDefinition.esmUrl ||
|
|
59
|
-
|
|
67
|
+
pluginDefinition.esmLoc.uri}`;
|
|
60
68
|
}
|
|
61
69
|
if (isCJSPluginDefinition(pluginDefinition)) {
|
|
62
70
|
return `CJS plugin ${pluginDefinition.cjsUrl}`;
|
|
@@ -91,9 +99,10 @@ class PluginLoader {
|
|
|
91
99
|
throw new Error(`cannot load plugins using protocol "${parsedUrl.protocol}"`);
|
|
92
100
|
}
|
|
93
101
|
if (!this.fetchESM) {
|
|
94
|
-
throw new Error(
|
|
102
|
+
throw new Error('No ESM fetcher installed');
|
|
95
103
|
}
|
|
96
104
|
const plugin = await this.fetchESM(parsedUrl.href);
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
97
106
|
if (!plugin) {
|
|
98
107
|
throw new Error(`Could not load ESM plugin: ${parsedUrl}`);
|
|
99
108
|
}
|
|
@@ -141,6 +150,7 @@ class PluginLoader {
|
|
|
141
150
|
else {
|
|
142
151
|
throw new Error(`Could not determine plugin type: ${JSON.stringify(def)}`);
|
|
143
152
|
}
|
|
153
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
144
154
|
if (!plugin.default) {
|
|
145
155
|
throw new Error(`${pluginDescriptionString(def)} does not have a default export, cannot load`);
|
|
146
156
|
}
|
package/PluginManager.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ declare class TypeRecord<ElementClass extends PluggableElementBase> {
|
|
|
36
36
|
}));
|
|
37
37
|
add(name: string, t: ElementClass): void;
|
|
38
38
|
has(name: string): boolean;
|
|
39
|
-
get(name: string): ElementClass;
|
|
39
|
+
get(name: string): ElementClass | undefined;
|
|
40
40
|
all(): ElementClass[];
|
|
41
41
|
}
|
|
42
42
|
type AnyFunction = (...args: any) => any;
|
|
@@ -104,7 +104,7 @@ export default class PluginManager {
|
|
|
104
104
|
configure(): this;
|
|
105
105
|
getElementTypeRecord(groupName: PluggableElementTypeGroup): TypeRecord<PluggableElementBase>;
|
|
106
106
|
addElementType(groupName: PluggableElementTypeGroup, creationCallback: (pluginManager: PluginManager) => PluggableElementType): this;
|
|
107
|
-
getElementType(groupName: PluggableElementTypeGroup, typeName: string): PluggableElementBase;
|
|
107
|
+
getElementType(groupName: PluggableElementTypeGroup, typeName: string): PluggableElementBase | undefined;
|
|
108
108
|
getElementTypesInGroup(groupName: PluggableElementTypeGroup): PluggableElementBase[];
|
|
109
109
|
getTrackElements(): TrackType[];
|
|
110
110
|
getConnectionElements(): ConnectionType[];
|
|
@@ -266,18 +266,18 @@ export default class PluginManager {
|
|
|
266
266
|
jbrequire: (lib: keyof typeof ReExports | AnyFunction | {
|
|
267
267
|
default: AnyFunction;
|
|
268
268
|
}) => any;
|
|
269
|
-
getRendererType(typeName: string): RendererType;
|
|
269
|
+
getRendererType(typeName: string): RendererType | undefined;
|
|
270
270
|
getRendererTypes(): RendererType[];
|
|
271
|
-
getAdapterType(typeName: string): AdapterType;
|
|
272
|
-
getTextSearchAdapterType(typeName: string): TextSearchAdapterType;
|
|
273
|
-
getTrackType(typeName: string): TrackType;
|
|
274
|
-
getDisplayType(typeName: string): DisplayType;
|
|
275
|
-
getViewType(typeName: string): ViewType;
|
|
276
|
-
getAddTrackWorkflow(typeName: string): AddTrackWorkflowType;
|
|
277
|
-
getWidgetType(typeName: string): WidgetType;
|
|
278
|
-
getConnectionType(typeName: string): ConnectionType;
|
|
279
|
-
getRpcMethodType(methodName: string): RpcMethodType;
|
|
280
|
-
getInternetAccountType(name: string): InternetAccountType;
|
|
271
|
+
getAdapterType(typeName: string): AdapterType | undefined;
|
|
272
|
+
getTextSearchAdapterType(typeName: string): TextSearchAdapterType | undefined;
|
|
273
|
+
getTrackType(typeName: string): TrackType | undefined;
|
|
274
|
+
getDisplayType(typeName: string): DisplayType | undefined;
|
|
275
|
+
getViewType(typeName: string): ViewType | undefined;
|
|
276
|
+
getAddTrackWorkflow(typeName: string): AddTrackWorkflowType | undefined;
|
|
277
|
+
getWidgetType(typeName: string): WidgetType | undefined;
|
|
278
|
+
getConnectionType(typeName: string): ConnectionType | undefined;
|
|
279
|
+
getRpcMethodType(methodName: string): RpcMethodType | undefined;
|
|
280
|
+
getInternetAccountType(name: string): InternetAccountType | undefined;
|
|
281
281
|
addRendererType(cb: (pm: PluginManager) => RendererType): this;
|
|
282
282
|
addAdapterType(cb: (pm: PluginManager) => AdapterType): this;
|
|
283
283
|
addTextSearchAdapterType(cb: (pm: PluginManager) => TextSearchAdapterType): this;
|