@jbrowse/core 2.1.5 → 2.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/BaseFeatureWidget/BaseFeatureDetail.d.ts +2 -1
  2. package/BaseFeatureWidget/BaseFeatureDetail.js +16 -17
  3. package/BaseFeatureWidget/SequenceBox.d.ts +29 -0
  4. package/BaseFeatureWidget/SequenceBox.js +61 -0
  5. package/BaseFeatureWidget/SequenceFeatureDetails.d.ts +1 -10
  6. package/BaseFeatureWidget/SequenceFeatureDetails.js +100 -152
  7. package/BaseFeatureWidget/SequenceHelpDialog.d.ts +4 -0
  8. package/BaseFeatureWidget/SequenceHelpDialog.js +51 -0
  9. package/BaseFeatureWidget/SequencePanel.d.ts +10 -0
  10. package/BaseFeatureWidget/SequencePanel.js +72 -0
  11. package/BaseFeatureWidget/index.d.ts +7 -0
  12. package/BaseFeatureWidget/index.js +21 -5
  13. package/BaseFeatureWidget/util.d.ts +11 -0
  14. package/BaseFeatureWidget/util.js +13 -1
  15. package/PluginLoader.d.ts +29 -13
  16. package/PluginLoader.js +47 -77
  17. package/PluginManager.d.ts +1 -0
  18. package/PluginManager.js +9 -3
  19. package/assemblyManager/assembly.d.ts +8 -15
  20. package/assemblyManager/assembly.js +14 -17
  21. package/assemblyManager/assemblyManager.d.ts +37 -86
  22. package/configuration/configurationSlot.js +2 -1
  23. package/data_adapters/CytobandAdapter.js +1 -1
  24. package/package.json +3 -3
  25. package/pluggableElementTypes/models/BaseDisplayModel.d.ts +1 -1
  26. package/pluggableElementTypes/models/BaseDisplayModel.js +3 -2
  27. package/pluggableElementTypes/models/BaseTrackModel.d.ts +1 -1
  28. package/pluggableElementTypes/models/BaseTrackModel.js +1 -1
  29. package/pluggableElementTypes/models/baseTrackConfig.js +16 -4
  30. package/rpc/RpcManager.d.ts +1 -1
  31. package/rpc/RpcManager.js +4 -1
  32. package/rpc/WebWorkerRpcDriver.d.ts +2 -0
  33. package/rpc/WebWorkerRpcDriver.js +21 -11
  34. package/rpc/configSchema.js +4 -1
  35. package/tsconfig.build.tsbuildinfo +1 -1
  36. package/ui/AboutDialog.d.ts +6 -0
  37. package/ui/AboutDialog.js +42 -20
  38. package/ui/App.js +2 -2
  39. package/ui/DrawerWidget.js +9 -7
  40. package/ui/FatalErrorDialog.d.ts +6 -22
  41. package/ui/FatalErrorDialog.js +10 -29
  42. package/util/index.d.ts +4 -0
  43. package/util/index.js +5 -1
  44. package/util/stats.js +7 -5
  45. package/util/tracks.d.ts +5 -2
  46. package/util/tracks.js +15 -5
@@ -1,5 +1,11 @@
1
1
  /// <reference types="react" />
2
2
  import { AnyConfigurationModel } from '../configuration';
3
+ export declare function FileInfo({ config }: {
4
+ config: AnyConfigurationModel;
5
+ }): JSX.Element | null;
6
+ export declare function AboutContents({ config }: {
7
+ config: AnyConfigurationModel;
8
+ }): JSX.Element;
3
9
  export default function AboutDialog({ config, handleClose, }: {
4
10
  config: AnyConfigurationModel;
5
11
  handleClose: () => void;
package/ui/AboutDialog.js CHANGED
@@ -26,6 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.AboutContents = exports.FileInfo = void 0;
29
30
  const react_1 = __importStar(require("react"));
30
31
  const copy_to_clipboard_1 = __importDefault(require("copy-to-clipboard"));
31
32
  const material_1 = require("@mui/material");
@@ -33,6 +34,7 @@ const Close_1 = __importDefault(require("@mui/icons-material/Close"));
33
34
  const mui_1 = require("tss-react/mui");
34
35
  const configuration_1 = require("../configuration");
35
36
  const util_1 = require("../util");
37
+ const tracks_1 = require("../util/tracks");
36
38
  const BaseFeatureDetail_1 = require("../BaseFeatureWidget/BaseFeatureDetail");
37
39
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
38
40
  closeButton: {
@@ -45,14 +47,11 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
45
47
  minWidth: 800,
46
48
  },
47
49
  }));
48
- function AboutDialog({ config, handleClose, }) {
49
- const { classes } = useStyles();
50
- const [info, setInfo] = (0, react_1.useState)();
50
+ function FileInfo({ config }) {
51
51
  const [error, setError] = (0, react_1.useState)();
52
- const [copied, setCopied] = (0, react_1.useState)(false);
52
+ const [info, setInfo] = (0, react_1.useState)();
53
53
  const session = (0, util_1.getSession)(config);
54
54
  const { rpcManager } = session;
55
- const conf = (0, configuration_1.readConfObject)(config);
56
55
  (0, react_1.useEffect)(() => {
57
56
  const aborter = new AbortController();
58
57
  const { signal } = aborter;
@@ -80,13 +79,6 @@ function AboutDialog({ config, handleClose, }) {
80
79
  cancelled = true;
81
80
  };
82
81
  }, [config, rpcManager]);
83
- let trackName = (0, configuration_1.readConfObject)(config, 'name');
84
- if ((0, configuration_1.readConfObject)(config, 'type') === 'ReferenceSequenceTrack') {
85
- const asm = session.assemblies.find(a => a.sequence === config.configuration);
86
- trackName = asm
87
- ? `Reference Sequence (${(0, configuration_1.readConfObject)(asm, 'displayName') || (0, configuration_1.readConfObject)(asm, 'name')})`
88
- : 'Reference Sequence';
89
- }
90
82
  const details = typeof info === 'string'
91
83
  ? {
92
84
  header: `<pre>${info
@@ -94,19 +86,49 @@ function AboutDialog({ config, handleClose, }) {
94
86
  .replace(/>/g, '&gt;')}</pre>`,
95
87
  }
96
88
  : info || {};
89
+ return info !== null ? (react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { title: "File info" }, error ? (react_1.default.createElement(material_1.Typography, { color: "error" }, `${error}`)) : info === undefined ? ('Loading file data...') : (react_1.default.createElement(BaseFeatureDetail_1.Attributes, { attributes: details })))) : null;
90
+ }
91
+ exports.FileInfo = FileInfo;
92
+ function AboutContents({ config }) {
93
+ const [copied, setCopied] = (0, react_1.useState)(false);
94
+ const conf = (0, configuration_1.readConfObject)(config);
95
+ const session = (0, util_1.getSession)(config);
96
+ const hideUris = (0, configuration_1.getConf)(session, ['formatAbout', 'hideUris']) ||
97
+ (0, configuration_1.readConfObject)(config, ['formatAbout', 'hideUris']);
98
+ const { pluginManager } = (0, util_1.getEnv)(session);
99
+ const confPostExt = pluginManager.evaluateExtensionPoint('Core-customizeAbout', {
100
+ config: {
101
+ ...conf,
102
+ ...(0, configuration_1.getConf)(session, ['formatAbout', 'config'], { config: conf }),
103
+ ...(0, configuration_1.readConfObject)(config, ['formatAbout', 'config'], { config: conf }),
104
+ },
105
+ }, { session, config });
106
+ const ExtraPanel = pluginManager.evaluateExtensionPoint('Core-extraAboutPanel', null, { session, config });
107
+ return (react_1.default.createElement(react_1.default.Fragment, null,
108
+ react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { title: "Configuration" },
109
+ !hideUris ? (react_1.default.createElement(material_1.Button, { variant: "contained", style: { float: 'right' }, onClick: () => {
110
+ (0, copy_to_clipboard_1.default)(JSON.stringify(conf, null, 2));
111
+ setCopied(true);
112
+ setTimeout(() => setCopied(false), 1000);
113
+ } }, copied ? 'Copied to clipboard!' : 'Copy config')) : null,
114
+ react_1.default.createElement(BaseFeatureDetail_1.Attributes, { attributes: confPostExt, omit: ['displays', 'baseUri', 'refNames', 'formatAbout'], hideUris: hideUris })),
115
+ ExtraPanel ? (react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { title: ExtraPanel.name },
116
+ react_1.default.createElement(ExtraPanel.Component, { config: config }))) : null,
117
+ react_1.default.createElement(FileInfo, { config: config })));
118
+ }
119
+ exports.AboutContents = AboutContents;
120
+ function AboutDialog({ config, handleClose, }) {
121
+ const { classes } = useStyles();
122
+ const session = (0, util_1.getSession)(config);
123
+ const trackName = (0, tracks_1.getTrackName)(config, session);
124
+ const { pluginManager } = (0, util_1.getEnv)(session);
125
+ const AboutComponent = pluginManager.evaluateExtensionPoint('Core-replaceAbout', AboutContents, { session, config });
97
126
  return (react_1.default.createElement(material_1.Dialog, { open: true, onClose: handleClose, maxWidth: "xl" },
98
127
  react_1.default.createElement(material_1.DialogTitle, null,
99
128
  trackName,
100
129
  react_1.default.createElement(material_1.IconButton, { className: classes.closeButton, onClick: () => handleClose(), size: "large" },
101
130
  react_1.default.createElement(Close_1.default, null))),
102
131
  react_1.default.createElement(material_1.DialogContent, { className: classes.content },
103
- react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { title: "Configuration" },
104
- react_1.default.createElement(material_1.Button, { variant: "contained", style: { float: 'right' }, onClick: () => {
105
- (0, copy_to_clipboard_1.default)(JSON.stringify(conf, null, 2));
106
- setCopied(true);
107
- setTimeout(() => setCopied(false), 1000);
108
- } }, copied ? 'Copied to clipboard!' : 'Copy config'),
109
- react_1.default.createElement(BaseFeatureDetail_1.Attributes, { attributes: conf, omit: ['displays', 'baseUri', 'refNames'] })),
110
- info !== null ? (react_1.default.createElement(BaseFeatureDetail_1.BaseCard, { title: "File info" }, error ? (react_1.default.createElement(material_1.Typography, { color: "error" }, `${error}`)) : info === undefined ? ('Loading file data...') : (react_1.default.createElement(BaseFeatureDetail_1.Attributes, { attributes: details })))) : null)));
132
+ react_1.default.createElement(AboutComponent, { config: config }))));
111
133
  }
112
134
  exports.default = AboutDialog;
package/ui/App.js CHANGED
@@ -106,7 +106,7 @@ const Logo = (0, mobx_react_1.observer)(({ session }) => {
106
106
  return react_1.default.createElement("img", { src: logoPath.uri, alt: "Custom logo" });
107
107
  }
108
108
  });
109
- const AppToolbar = ({ session, HeaderButtons = react_1.default.createElement("div", null), }) => {
109
+ const AppToolbar = (0, mobx_react_1.observer)(({ session, HeaderButtons = react_1.default.createElement("div", null), }) => {
110
110
  const { classes } = useStyles();
111
111
  const { savedSessionNames, name, menus } = session;
112
112
  function handleNameChange(newName) {
@@ -130,7 +130,7 @@ const AppToolbar = ({ session, HeaderButtons = react_1.default.createElement("di
130
130
  react_1.default.createElement("div", { className: classes.grow }),
131
131
  react_1.default.createElement("div", { style: { width: 150, maxHeight: 48 } },
132
132
  react_1.default.createElement(Logo, { session: session }))));
133
- };
133
+ });
134
134
  const ViewLauncher = (0, mobx_react_1.observer)(({ session }) => {
135
135
  var _a;
136
136
  const { classes } = useStyles();
@@ -31,7 +31,7 @@ const react_error_boundary_1 = require("react-error-boundary");
31
31
  const material_1 = require("@mui/material");
32
32
  const mui_1 = require("tss-react/mui");
33
33
  const mobx_react_1 = require("mobx-react");
34
- const mobx_state_tree_1 = require("mobx-state-tree");
34
+ const util_1 = require("../util");
35
35
  // icons
36
36
  const Delete_1 = __importDefault(require("@mui/icons-material/Delete"));
37
37
  const Close_1 = __importDefault(require("@mui/icons-material/Close"));
@@ -59,10 +59,10 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
59
59
  },
60
60
  }));
61
61
  const DrawerHeader = (0, mobx_react_1.observer)(({ session, setToolbarHeight, }) => {
62
- const { pluginManager } = (0, mobx_state_tree_1.getEnv)(session);
62
+ const { pluginManager } = (0, util_1.getEnv)(session);
63
63
  const { visibleWidget, activeWidgets, drawerPosition } = session;
64
64
  const { classes } = useStyles();
65
- const [anchorEl, setAnchorEl] = react_1.default.useState(null);
65
+ const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
66
66
  return (react_1.default.createElement(material_1.AppBar, { position: "sticky", className: classes.header, ref: ref => setToolbarHeight((ref === null || ref === void 0 ? void 0 : ref.getBoundingClientRect().height) || 0) },
67
67
  react_1.default.createElement(material_1.Toolbar, { disableGutters: true },
68
68
  react_1.default.createElement(material_1.FormControl, { className: classes.formControl },
@@ -110,9 +110,12 @@ const DrawerHeader = (0, mobx_react_1.observer)(({ session, setToolbarHeight, })
110
110
  });
111
111
  const DrawerWidget = (0, mobx_react_1.observer)(({ session }) => {
112
112
  const { visibleWidget } = session;
113
- const { pluginManager } = (0, mobx_state_tree_1.getEnv)(session);
113
+ const { pluginManager } = (0, util_1.getEnv)(session);
114
114
  const DrawerComponent = visibleWidget
115
- ? pluginManager.getWidgetType(visibleWidget.type).ReactComponent
115
+ ? pluginManager.evaluateExtensionPoint('Core-replaceWidget', pluginManager.getWidgetType(visibleWidget.type).ReactComponent, {
116
+ session,
117
+ model: visibleWidget,
118
+ })
116
119
  : null;
117
120
  // we track the toolbar height because components that use virtualized
118
121
  // height want to be able to fill the contained, minus the toolbar height
@@ -121,7 +124,6 @@ const DrawerWidget = (0, mobx_react_1.observer)(({ session }) => {
121
124
  return (react_1.default.createElement(Drawer_1.default, { session: session },
122
125
  react_1.default.createElement(DrawerHeader, { session: session, setToolbarHeight: setToolbarHeight }),
123
126
  react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement("div", null, "Loading...") },
124
- react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { FallbackComponent: ({ error }) => react_1.default.createElement(ErrorMessage_1.default, { error: error }) },
125
- react_1.default.createElement(DrawerComponent, { model: visibleWidget, session: session, toolbarHeight: toolbarHeight })))));
127
+ react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { FallbackComponent: ({ error }) => react_1.default.createElement(ErrorMessage_1.default, { error: error }) }, DrawerComponent ? (react_1.default.createElement(DrawerComponent, { model: visibleWidget, session: session, toolbarHeight: toolbarHeight })) : null))));
126
128
  });
127
129
  exports.default = DrawerWidget;
@@ -1,24 +1,8 @@
1
1
  /// <reference types="react" />
2
- import PropTypes from 'prop-types';
3
- declare const FatalErrorDialog: {
4
- ({ componentStack, error, onFactoryReset, resetButtonText, }: {
5
- componentStack: string;
6
- error: Error;
7
- onFactoryReset: Function;
8
- resetButtonText: string;
9
- }): JSX.Element;
10
- propTypes: {
11
- componentStack: PropTypes.Requireable<string>;
12
- error: PropTypes.Requireable<PropTypes.InferProps<{}>>;
13
- onFactoryReset: PropTypes.Validator<(...args: any[]) => any>;
14
- resetButtonText: PropTypes.Requireable<string>;
15
- };
16
- defaultProps: {
17
- error: {
18
- message: string;
19
- };
20
- componentStack: string;
21
- resetButtonText: string;
22
- };
23
- };
2
+ declare const FatalErrorDialog: ({ componentStack, error, onFactoryReset, resetButtonText, }: {
3
+ componentStack?: string | undefined;
4
+ error?: unknown;
5
+ onFactoryReset: Function;
6
+ resetButtonText?: string | undefined;
7
+ }) => JSX.Element;
24
8
  export default FatalErrorDialog;
@@ -26,44 +26,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- const Button_1 = __importDefault(require("@mui/material/Button"));
30
- const Dialog_1 = __importDefault(require("@mui/material/Dialog"));
31
- const DialogActions_1 = __importDefault(require("@mui/material/DialogActions"));
32
- const DialogContent_1 = __importDefault(require("@mui/material/DialogContent"));
33
- const DialogTitle_1 = __importDefault(require("@mui/material/DialogTitle"));
34
- const prop_types_1 = __importDefault(require("prop-types"));
35
29
  const react_1 = __importStar(require("react"));
30
+ const material_1 = require("@mui/material");
36
31
  const FactoryResetDialog_1 = __importDefault(require("./FactoryResetDialog"));
37
32
  const ResetComponent = ({ onFactoryReset, resetButtonText, }) => {
38
33
  const [dialogOpen, setDialogOpen] = (0, react_1.useState)(false);
39
34
  return (react_1.default.createElement(react_1.default.Fragment, null,
40
- react_1.default.createElement(Button_1.default, { "data-testid": "fatal-error", color: "primary", variant: "contained", onClick: () => setDialogOpen(true) }, resetButtonText),
35
+ react_1.default.createElement(material_1.Button, { "data-testid": "fatal-error", color: "primary", variant: "contained", onClick: () => setDialogOpen(true) }, resetButtonText),
41
36
  react_1.default.createElement(FactoryResetDialog_1.default, { onClose: () => setDialogOpen(false), open: dialogOpen, onFactoryReset: onFactoryReset })));
42
37
  };
43
- ResetComponent.propTypes = {
44
- onFactoryReset: prop_types_1.default.func.isRequired,
45
- resetButtonText: prop_types_1.default.string.isRequired,
46
- };
47
- const FatalErrorDialog = ({ componentStack, error, onFactoryReset, resetButtonText, }) => {
48
- return (react_1.default.createElement(Dialog_1.default, { open: true },
49
- react_1.default.createElement(DialogTitle_1.default, { style: { backgroundColor: '#e88' } }, "Fatal error"),
50
- react_1.default.createElement(DialogContent_1.default, null,
38
+ const FatalErrorDialog = ({ componentStack, error = 'No error message provided', onFactoryReset, resetButtonText = 'Factory Reset', }) => {
39
+ console.error(error);
40
+ return (react_1.default.createElement(material_1.Dialog, { open: true },
41
+ react_1.default.createElement(material_1.DialogTitle, { style: { background: '#e88' } }, "Fatal error"),
42
+ react_1.default.createElement(material_1.DialogContent, null,
51
43
  react_1.default.createElement("pre", null,
52
- error.toString(),
44
+ `${error}`,
53
45
  componentStack)),
54
- react_1.default.createElement(DialogActions_1.default, null,
55
- react_1.default.createElement(Button_1.default, { color: "secondary", variant: "contained", onClick: () => window.location.reload() }, "Refresh"),
46
+ react_1.default.createElement(material_1.DialogActions, null,
47
+ react_1.default.createElement(material_1.Button, { color: "secondary", variant: "contained", onClick: () => window.location.reload() }, "Refresh"),
56
48
  react_1.default.createElement(ResetComponent, { onFactoryReset: onFactoryReset, resetButtonText: resetButtonText }))));
57
49
  };
58
- FatalErrorDialog.propTypes = {
59
- componentStack: prop_types_1.default.string,
60
- error: prop_types_1.default.shape({}),
61
- onFactoryReset: prop_types_1.default.func.isRequired,
62
- resetButtonText: prop_types_1.default.string,
63
- };
64
- FatalErrorDialog.defaultProps = {
65
- error: { message: 'No error message provided' },
66
- componentStack: '',
67
- resetButtonText: 'Factory Reset',
68
- };
69
50
  exports.default = FatalErrorDialog;
package/util/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import PluginManager from '../PluginManager';
1
2
  import { IAnyStateTreeNode, IStateTreeNode } from 'mobx-state-tree';
2
3
  import { IReactionPublic, IReactionOptions } from 'mobx';
3
4
  import SimpleFeature, { Feature, isFeature } from './simpleFeature';
@@ -334,3 +335,6 @@ export declare function getUriLink(value: {
334
335
  }): string;
335
336
  export declare function getStr(obj: unknown): string;
336
337
  export declare function measureGridWidth(elements: string[]): number;
338
+ export declare function getEnv(obj: any): {
339
+ pluginManager: PluginManager;
340
+ };
package/util/index.js CHANGED
@@ -30,7 +30,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
30
30
  };
31
31
  Object.defineProperty(exports, "__esModule", { value: true });
32
32
  exports.getBpDisplayStr = exports.supportedIndexingAdapters = exports.bytesForRegions = exports.objectHash = exports.hashCode = exports.updateStatus = exports.generateCodonTable = exports.defaultCodonTable = exports.defaultStops = exports.defaultStarts = exports.measureText = exports.rIC = exports.blobToDataURL = exports.complement = exports.reverse = exports.revcom = exports.isElectron = exports.stringify = exports.minmax = exports.renameRegionsIfNeeded = exports.renameRegionIfNeeded = exports.makeAbortableReaction = exports.findLastIndex = exports.iterMap = exports.bpSpanPx = exports.featureSpanPx = exports.cartesianToPolar = exports.polarToCartesian = exports.degToRad = exports.radToDeg = exports.bpToPx = exports.clamp = exports.compareLocStrings = exports.compareLocs = exports.parseLocString = exports.parseLocStringOneBased = exports.assembleLocString = exports.getContainingDisplay = exports.getContainingTrack = exports.getContainingView = exports.getSession = exports.findParentThatIs = exports.springAnimate = exports.findParentThat = exports.useDebouncedCallback = exports.useDebounce = exports.inProduction = exports.inDevelopment = exports.isFeature = exports.SimpleFeature = void 0;
33
- exports.measureGridWidth = exports.getStr = exports.getUriLink = exports.useLocalStorage = exports.getLayoutId = exports.getViewParams = exports.getTickDisplayStr = exports.toLocale = void 0;
33
+ exports.getEnv = exports.measureGridWidth = exports.getStr = exports.getUriLink = exports.useLocalStorage = exports.getLayoutId = exports.getViewParams = exports.getTickDisplayStr = exports.toLocale = void 0;
34
34
  /* eslint-disable @typescript-eslint/no-explicit-any */
35
35
  const react_1 = require("react");
36
36
  const is_object_1 = __importDefault(require("is-object"));
@@ -996,3 +996,7 @@ function measureGridWidth(elements) {
996
996
  return Math.max(...elements.map(element => Math.min(Math.max(measureText(getStr(element), 14) + 50, 80), 1000)));
997
997
  }
998
998
  exports.measureGridWidth = measureGridWidth;
999
+ function getEnv(obj) {
1000
+ return (0, mobx_state_tree_1.getEnv)(obj);
1001
+ }
1002
+ exports.getEnv = getEnv;
package/util/stats.js CHANGED
@@ -86,11 +86,13 @@ async function scoresToStats(region, features) {
86
86
  const { start, end } = region;
87
87
  const { scoreMin, scoreMax, scoreSum, scoreSumSquares, featureCount } = await features
88
88
  .pipe((0, operators_1.reduce)((seed, f) => {
89
- const score = f.get('score');
90
- seed.scoreMax = Math.max(seed.scoreMax, f.get('summary') ? f.get('maxScore') : score);
91
- seed.scoreMin = Math.min(seed.scoreMin, f.get('summary') ? f.get('minScore') : score);
92
- seed.scoreSum += score;
93
- seed.scoreSumSquares += score * score;
89
+ const s = f.get('score');
90
+ const summary = f.get('summary');
91
+ const { scoreMax, scoreMin } = seed;
92
+ seed.scoreMax = Math.max(scoreMax, summary ? f.get('maxScore') : s);
93
+ seed.scoreMin = Math.min(scoreMin, summary ? f.get('minScore') : s);
94
+ seed.scoreSum += s;
95
+ seed.scoreSumSquares += s * s;
94
96
  seed.featureCount += 1;
95
97
  return seed;
96
98
  }, {
package/util/tracks.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { IAnyStateTreeNode } from 'mobx-state-tree';
2
2
  import { PreFileLocation, FileLocation } from './types';
3
- import { AnyConfigurationModel } from '../configuration/configurationSchema';
3
+ import { AnyConfigurationModel } from '../configuration';
4
4
  export declare function getTrackAssemblyNames(track: IAnyStateTreeNode & {
5
5
  configuration: AnyConfigurationModel;
6
- }): any[];
6
+ }): string[];
7
7
  /** return the rpcSessionId of the highest parent node in the tree that has an rpcSessionId */
8
8
  export declare function getRpcSessionId(thisNode: IAnyStateTreeNode): string;
9
9
  /**
@@ -73,3 +73,6 @@ export declare function generateUnknownTrackConf(trackName: string, trackUrl: st
73
73
  category: string[] | undefined;
74
74
  trackId: string;
75
75
  };
76
+ export declare function getTrackName(conf: AnyConfigurationModel, session: {
77
+ assemblies: AnyConfigurationModel[];
78
+ }): any;
package/util/tracks.js CHANGED
@@ -1,13 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateUnknownTrackConf = exports.generateUnsupportedTrackConf = exports.guessTrackType = exports.guessAdapter = exports.getFileName = exports.makeIndexType = exports.makeIndex = exports.storeBlobLocation = exports.setBlobMap = exports.getBlobMap = exports.getBlob = exports.UNSUPPORTED = exports.UNKNOWN = exports.getParentRenderProps = exports.getRpcSessionId = exports.getTrackAssemblyNames = void 0;
3
+ exports.getTrackName = exports.generateUnknownTrackConf = exports.generateUnsupportedTrackConf = exports.guessTrackType = exports.guessAdapter = exports.getFileName = exports.makeIndexType = exports.makeIndex = exports.storeBlobLocation = exports.setBlobMap = exports.getBlobMap = exports.getBlob = exports.UNSUPPORTED = exports.UNKNOWN = exports.getParentRenderProps = exports.getRpcSessionId = exports.getTrackAssemblyNames = void 0;
4
4
  const mobx_state_tree_1 = require("mobx-state-tree");
5
5
  const index_1 = require("./index");
6
6
  const configuration_1 = require("../configuration");
7
7
  /* utility functions for use by track models and so forth */
8
8
  function getTrackAssemblyNames(track) {
9
- const trackConf = track.configuration;
10
- const trackAssemblyNames = (0, configuration_1.readConfObject)(trackConf, 'assemblyNames');
9
+ const trackAssemblyNames = (0, configuration_1.getConf)(track, 'assemblyNames');
11
10
  if (!trackAssemblyNames) {
12
11
  // Check if it's an assembly sequence track
13
12
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -126,7 +125,7 @@ function getFileName(track) {
126
125
  exports.getFileName = getFileName;
127
126
  function guessAdapter(file, index, adapterHint, model) {
128
127
  if (model) {
129
- const { pluginManager } = (0, mobx_state_tree_1.getEnv)(model);
128
+ const { pluginManager } = (0, index_1.getEnv)(model);
130
129
  const adapterGuesser = pluginManager.evaluateExtensionPoint('Core-guessAdapterForLocation', (_file, _index, _adapterHint) => {
131
130
  return undefined;
132
131
  });
@@ -144,7 +143,7 @@ function guessTrackType(adapterType, model) {
144
143
  if (model) {
145
144
  // @ts-ignore
146
145
  const session = (0, index_1.getSession)(model);
147
- const trackTypeGuesser = (0, mobx_state_tree_1.getEnv)(session).pluginManager.evaluateExtensionPoint('Core-guessTrackTypeForLocation', (_adapterName) => {
146
+ const trackTypeGuesser = (0, index_1.getEnv)(session).pluginManager.evaluateExtensionPoint('Core-guessTrackTypeForLocation', (_adapterName) => {
148
147
  return undefined;
149
148
  });
150
149
  const trackType = trackTypeGuesser(adapterType);
@@ -179,3 +178,14 @@ function generateUnknownTrackConf(trackName, trackUrl, categories) {
179
178
  return conf;
180
179
  }
181
180
  exports.generateUnknownTrackConf = generateUnknownTrackConf;
181
+ function getTrackName(conf, session) {
182
+ const trackName = (0, configuration_1.readConfObject)(conf, 'name');
183
+ if (!trackName && (0, configuration_1.readConfObject)(conf, 'type') === 'ReferenceSequenceTrack') {
184
+ const asm = session.assemblies.find(a => a.sequence === conf);
185
+ return asm
186
+ ? `Reference sequence (${(0, configuration_1.readConfObject)(asm, 'displayName') || (0, configuration_1.readConfObject)(asm, 'name')})`
187
+ : 'Reference sequence';
188
+ }
189
+ return trackName;
190
+ }
191
+ exports.getTrackName = getTrackName;