@jbrowse/core 2.2.2 → 2.3.1

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 (80) hide show
  1. package/PluginManager.d.ts +4 -0
  2. package/PluginManager.js +12 -0
  3. package/README.md +6 -2
  4. package/package.json +3 -3
  5. package/pluggableElementTypes/AdapterType.d.ts +4 -4
  6. package/pluggableElementTypes/AdapterType.js +0 -1
  7. package/pluggableElementTypes/AddTrackWorkflowType.d.ts +3 -3
  8. package/pluggableElementTypes/ConnectionType.d.ts +0 -1
  9. package/pluggableElementTypes/ConnectionType.js +0 -1
  10. package/pluggableElementTypes/DisplayType.d.ts +9 -0
  11. package/pluggableElementTypes/DisplayType.js +1 -0
  12. package/pluggableElementTypes/PluggableElementBase.d.ts +3 -0
  13. package/pluggableElementTypes/PluggableElementBase.js +4 -0
  14. package/pluggableElementTypes/TextSearchAdapterType.d.ts +1 -0
  15. package/pluggableElementTypes/TrackType.d.ts +2 -1
  16. package/pluggableElementTypes/ViewType.d.ts +4 -3
  17. package/pluggableElementTypes/WidgetType.d.ts +10 -9
  18. package/pluggableElementTypes/models/BaseDisplayModel.js +1 -0
  19. package/pluggableElementTypes/models/BaseTrackModel.d.ts +19 -8
  20. package/pluggableElementTypes/models/BaseTrackModel.js +32 -26
  21. package/pluggableElementTypes/renderers/BoxRendererType.js +1 -14
  22. package/pluggableElementTypes/renderers/CircularChordRendererType.d.ts +9 -0
  23. package/pluggableElementTypes/renderers/CircularChordRendererType.js +23 -0
  24. package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.js +4 -1
  25. package/pluggableElementTypes/renderers/FeatureRendererType.d.ts +4 -4
  26. package/pluggableElementTypes/renderers/FeatureRendererType.js +11 -13
  27. package/pluggableElementTypes/renderers/RendererType.d.ts +1 -0
  28. package/pluggableElementTypes/renderers/RpcRenderedSvgGroup.d.ts +8 -0
  29. package/pluggableElementTypes/renderers/RpcRenderedSvgGroup.js +60 -0
  30. package/pluggableElementTypes/renderers/ServerSideRenderedContent.d.ts +2 -2
  31. package/pluggableElementTypes/renderers/ServerSideRenderedContent.js +6 -6
  32. package/pluggableElementTypes/renderers/ServerSideRendererType.d.ts +4 -4
  33. package/pluggableElementTypes/renderers/ServerSideRendererType.js +13 -12
  34. package/rpc/BaseRpcDriver.d.ts +1 -1
  35. package/rpc/BaseRpcDriver.js +7 -17
  36. package/rpc/coreRpcMethods.d.ts +11 -99
  37. package/rpc/coreRpcMethods.js +17 -241
  38. package/rpc/methods/CoreEstimateRegionStats.d.ts +18 -0
  39. package/rpc/methods/CoreEstimateRegionStats.js +37 -0
  40. package/rpc/methods/CoreFreeResources.d.ts +12 -0
  41. package/rpc/methods/CoreFreeResources.js +35 -0
  42. package/rpc/methods/CoreGetFeatureDetails.d.ts +16 -0
  43. package/rpc/methods/CoreGetFeatureDetails.js +44 -0
  44. package/rpc/methods/CoreGetFeatures.d.ts +17 -0
  45. package/rpc/methods/CoreGetFeatures.js +44 -0
  46. package/rpc/methods/CoreGetFileInfo.d.ts +10 -0
  47. package/rpc/methods/CoreGetFileInfo.js +24 -0
  48. package/rpc/methods/CoreGetMetadata.d.ts +10 -0
  49. package/rpc/methods/CoreGetMetadata.js +24 -0
  50. package/rpc/methods/CoreGetRefNames.d.ts +10 -0
  51. package/rpc/methods/CoreGetRefNames.js +25 -0
  52. package/rpc/methods/CoreRender.d.ts +14 -0
  53. package/rpc/methods/CoreRender.js +57 -0
  54. package/rpc/methods/util.d.ts +14 -0
  55. package/rpc/methods/util.js +21 -0
  56. package/rpc/remoteAbortSignals.d.ts +3 -1
  57. package/rpc/remoteAbortSignals.js +3 -1
  58. package/tsconfig.build.tsbuildinfo +1 -1
  59. package/ui/App.js +9 -77
  60. package/ui/AppLogo.d.ts +8 -0
  61. package/ui/AppLogo.js +22 -0
  62. package/ui/AppToolbar.d.ts +19 -0
  63. package/ui/AppToolbar.js +56 -0
  64. package/ui/AssemblySelector.d.ts +5 -3
  65. package/ui/AssemblySelector.js +4 -4
  66. package/ui/PrerenderedCanvas.d.ts +3 -20
  67. package/ui/PrerenderedCanvas.js +1 -19
  68. package/ui/Snackbar.js +7 -53
  69. package/ui/ViewLauncher.d.ts +18 -0
  70. package/ui/ViewLauncher.js +50 -0
  71. package/ui/index.d.ts +9 -9
  72. package/ui/index.js +19 -19
  73. package/util/Base1DUtils.js +1 -1
  74. package/util/dedupe.d.ts +3 -0
  75. package/util/dedupe.js +18 -0
  76. package/util/index.d.ts +1 -1
  77. package/util/index.js +2 -5
  78. package/util/offscreenCanvasUtils.js +1 -1
  79. package/util/stats.d.ts +7 -3
  80. package/util/stats.js +33 -24
package/ui/App.js CHANGED
@@ -32,18 +32,16 @@ const mui_1 = require("tss-react/mui");
32
32
  const Launch_1 = __importDefault(require("@mui/icons-material/Launch"));
33
33
  const react_error_boundary_1 = require("react-error-boundary");
34
34
  const mobx_react_1 = require("mobx-react");
35
- const mobx_state_tree_1 = require("mobx-state-tree");
36
35
  // locals
37
- const configuration_1 = require("../configuration");
36
+ const util_1 = require("../util");
38
37
  // ui elements
39
38
  const DrawerWidget_1 = __importDefault(require("./DrawerWidget"));
40
- const DropDownMenu_1 = __importDefault(require("./DropDownMenu"));
39
+ const AppToolbar_1 = __importDefault(require("./AppToolbar"));
41
40
  const ErrorMessage_1 = __importDefault(require("./ErrorMessage"));
42
41
  const LoadingEllipses_1 = __importDefault(require("./LoadingEllipses"));
43
- const EditableTypography_1 = __importDefault(require("./EditableTypography"));
44
42
  const Snackbar_1 = __importDefault(require("./Snackbar"));
45
43
  const ViewContainer_1 = __importDefault(require("./ViewContainer"));
46
- const Logo_1 = require("./Logo");
44
+ const ViewLauncher_1 = __importDefault(require("./ViewLauncher"));
47
45
  const useStyles = (0, mui_1.makeStyles)()(theme => ({
48
46
  root: {
49
47
  fontFamily: 'Roboto',
@@ -79,75 +77,9 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
79
77
  appBar: {
80
78
  flexGrow: 1,
81
79
  },
82
- grow: {
83
- flexGrow: 1,
84
- },
85
- inputBase: {
86
- color: theme.palette.primary.contrastText,
87
- },
88
- inputRoot: {
89
- '&:hover': {
90
- backgroundColor: theme.palette.primary.light,
91
- },
92
- },
93
- inputFocused: {
94
- borderColor: theme.palette.secondary.main,
95
- backgroundColor: theme.palette.primary.light,
96
- },
97
- selectPaper: {
98
- padding: theme.spacing(4),
99
- },
100
80
  }));
101
- const Logo = (0, mobx_react_1.observer)(({ session }) => {
102
- const { configuration } = session;
103
- const logoPath = (0, configuration_1.readConfObject)(configuration, 'logoPath');
104
- if (!(logoPath === null || logoPath === void 0 ? void 0 : logoPath.uri)) {
105
- return react_1.default.createElement(Logo_1.LogoFull, { variant: "white" });
106
- }
107
- else {
108
- return react_1.default.createElement("img", { src: logoPath.uri, alt: "Custom logo" });
109
- }
110
- });
111
- const AppToolbar = (0, mobx_react_1.observer)(({ session, HeaderButtons = react_1.default.createElement("div", null), }) => {
112
- const { classes } = useStyles();
113
- const { savedSessionNames, name, menus } = session;
114
- function handleNameChange(newName) {
115
- if (savedSessionNames === null || savedSessionNames === void 0 ? void 0 : savedSessionNames.includes(newName)) {
116
- session.notify(`Cannot rename session to "${newName}", a saved session with that name already exists`, 'warning');
117
- }
118
- else {
119
- session.renameCurrentSession(newName);
120
- }
121
- }
122
- return (react_1.default.createElement(material_1.Toolbar, null,
123
- menus.map(menu => (react_1.default.createElement(DropDownMenu_1.default, { key: menu.label, menuTitle: menu.label, menuItems: menu.menuItems, session: session }))),
124
- react_1.default.createElement("div", { className: classes.grow }),
125
- react_1.default.createElement(material_1.Tooltip, { title: "Rename Session", arrow: true },
126
- react_1.default.createElement(EditableTypography_1.default, { value: name, setValue: handleNameChange, variant: "body1", classes: {
127
- inputBase: classes.inputBase,
128
- inputRoot: classes.inputRoot,
129
- inputFocused: classes.inputFocused,
130
- } })),
131
- HeaderButtons,
132
- react_1.default.createElement("div", { className: classes.grow }),
133
- react_1.default.createElement("div", { style: { width: 150, maxHeight: 48 } },
134
- react_1.default.createElement(Logo, { session: session }))));
135
- });
136
- const ViewLauncher = (0, mobx_react_1.observer)(({ session }) => {
137
- var _a;
138
- const { classes } = useStyles();
139
- const { pluginManager } = (0, mobx_state_tree_1.getEnv)(session);
140
- const viewTypes = pluginManager.getElementTypeRecord('view').all();
141
- const [value, setValue] = (0, react_1.useState)((_a = viewTypes[0]) === null || _a === void 0 ? void 0 : _a.name);
142
- return (react_1.default.createElement(material_1.Paper, { className: classes.selectPaper },
143
- react_1.default.createElement(material_1.Typography, null, "Select a view to launch"),
144
- react_1.default.createElement(material_1.FormControl, { style: { margin: 2 } },
145
- react_1.default.createElement(material_1.Select, { value: value, onChange: event => setValue(event.target.value) }, viewTypes.map(({ name }) => (react_1.default.createElement(material_1.MenuItem, { key: name, value: name }, name))))),
146
- react_1.default.createElement(material_1.FormControl, { style: { margin: 2 } },
147
- react_1.default.createElement(material_1.Button, { onClick: () => session.addView(value, {}), variant: "contained", color: "primary" }, "Launch view"))));
148
- });
149
- const ViewPanel = (0, mobx_react_1.observer)(({ view, session }) => {
150
- const { pluginManager } = (0, mobx_state_tree_1.getEnv)(session);
81
+ const ViewPanel = (0, mobx_react_1.observer)(function ({ view, session, }) {
82
+ const { pluginManager } = (0, util_1.getEnv)(session);
151
83
  const viewType = pluginManager.getViewType(view.type);
152
84
  if (!viewType) {
153
85
  throw new Error(`unknown view type ${view.type}`);
@@ -155,9 +87,9 @@ const ViewPanel = (0, mobx_react_1.observer)(({ view, session }) => {
155
87
  const { ReactComponent } = viewType;
156
88
  return (react_1.default.createElement(ViewContainer_1.default, { view: view, onClose: () => session.removeView(view), onMinimize: () => view.setMinimized(!view.minimized) }, !view.minimized ? (react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { FallbackComponent: ({ error }) => react_1.default.createElement(ErrorMessage_1.default, { error: error }) },
157
89
  react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(LoadingEllipses_1.default, null) },
158
- react_1.default.createElement(ReactComponent, { model: view, session: session, getTrackType: pluginManager.getTrackType })))) : (false)));
90
+ react_1.default.createElement(ReactComponent, { model: view, session: session })))) : (false)));
159
91
  });
160
- const App = (0, mobx_react_1.observer)((props) => {
92
+ const App = (0, mobx_react_1.observer)(function (props) {
161
93
  const { session } = props;
162
94
  const { classes } = useStyles();
163
95
  const { minimized, visibleWidget, drawerWidth, activeWidgets, views, drawerPosition, } = session;
@@ -184,9 +116,9 @@ const App = (0, mobx_react_1.observer)((props) => {
184
116
  react_1.default.createElement("div", { className: classes.menuBarAndComponents },
185
117
  react_1.default.createElement("div", { className: classes.menuBar },
186
118
  react_1.default.createElement(material_1.AppBar, { className: classes.appBar, position: "static" },
187
- react_1.default.createElement(AppToolbar, { ...props }))),
119
+ react_1.default.createElement(AppToolbar_1.default, { ...props }))),
188
120
  react_1.default.createElement("div", { className: classes.components },
189
- views.length ? (views.map(view => (react_1.default.createElement(ViewPanel, { key: `view-${view.id}`, view: view, session: session })))) : (react_1.default.createElement(ViewLauncher, { ...props })),
121
+ views.length ? (views.map(view => (react_1.default.createElement(ViewPanel, { key: `view-${view.id}`, view: view, session: session })))) : (react_1.default.createElement(ViewLauncher_1.default, { ...props })),
190
122
  react_1.default.createElement("div", { style: { height: 300 } }))),
191
123
  activeWidgets.size > 0 && minimized ? (react_1.default.createElement(material_1.Tooltip, { title: "Open drawer widget" },
192
124
  react_1.default.createElement(material_1.Fab, { className: drawerPosition === 'right' ? classes.fabRight : classes.fabLeft, color: "primary", "data-testid": "drawer-maximize", onClick: () => session.showWidgetDrawer() },
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ import { AnyConfigurationModel } from '../configuration';
3
+ declare const Logo: ({ session, }: {
4
+ session: {
5
+ configuration: AnyConfigurationModel;
6
+ };
7
+ }) => JSX.Element;
8
+ export default Logo;
package/ui/AppLogo.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const mobx_react_1 = require("mobx-react");
8
+ // locals
9
+ const configuration_1 = require("../configuration");
10
+ // ui elements
11
+ const Logo_1 = require("./Logo");
12
+ const Logo = (0, mobx_react_1.observer)(function ({ session, }) {
13
+ const { configuration } = session;
14
+ const logoPath = (0, configuration_1.readConfObject)(configuration, 'logoPath');
15
+ if (!(logoPath === null || logoPath === void 0 ? void 0 : logoPath.uri)) {
16
+ return react_1.default.createElement(Logo_1.LogoFull, { variant: "white" });
17
+ }
18
+ else {
19
+ return react_1.default.createElement("img", { src: logoPath.uri, alt: "Custom logo" });
20
+ }
21
+ });
22
+ exports.default = Logo;
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { NotificationLevel, SessionWithDrawerWidgets, SnackAction } from '../util';
3
+ import { MenuItem as JBMenuItem } from './Menu';
4
+ type SnackbarMessage = [string, NotificationLevel, SnackAction];
5
+ type AppSession = SessionWithDrawerWidgets & {
6
+ savedSessionNames: string[];
7
+ menus: {
8
+ label: string;
9
+ menuItems: JBMenuItem[];
10
+ }[];
11
+ renameCurrentSession: (arg: string) => void;
12
+ snackbarMessages: SnackbarMessage[];
13
+ popSnackbarMessage: () => unknown;
14
+ };
15
+ declare const AppToolbar: ({ session, HeaderButtons, }: {
16
+ HeaderButtons?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
17
+ session: AppSession;
18
+ }) => JSX.Element;
19
+ export default AppToolbar;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const material_1 = require("@mui/material");
8
+ const mui_1 = require("tss-react/mui");
9
+ const mobx_react_1 = require("mobx-react");
10
+ // ui elements
11
+ const DropDownMenu_1 = __importDefault(require("./DropDownMenu"));
12
+ const EditableTypography_1 = __importDefault(require("./EditableTypography"));
13
+ const AppLogo_1 = __importDefault(require("./AppLogo"));
14
+ const useStyles = (0, mui_1.makeStyles)()(theme => ({
15
+ grow: {
16
+ flexGrow: 1,
17
+ },
18
+ inputBase: {
19
+ color: theme.palette.primary.contrastText,
20
+ },
21
+ inputRoot: {
22
+ '&:hover': {
23
+ backgroundColor: theme.palette.primary.light,
24
+ },
25
+ },
26
+ inputFocused: {
27
+ borderColor: theme.palette.secondary.main,
28
+ backgroundColor: theme.palette.primary.light,
29
+ },
30
+ }));
31
+ const AppToolbar = (0, mobx_react_1.observer)(function ({ session, HeaderButtons = react_1.default.createElement("div", null), }) {
32
+ const { classes } = useStyles();
33
+ const { savedSessionNames, name, menus } = session;
34
+ function handleNameChange(newName) {
35
+ if (savedSessionNames === null || savedSessionNames === void 0 ? void 0 : savedSessionNames.includes(newName)) {
36
+ session.notify(`Cannot rename session to "${newName}", a saved session with that name already exists`, 'warning');
37
+ }
38
+ else {
39
+ session.renameCurrentSession(newName);
40
+ }
41
+ }
42
+ return (react_1.default.createElement(material_1.Toolbar, null,
43
+ menus.map(menu => (react_1.default.createElement(DropDownMenu_1.default, { key: menu.label, menuTitle: menu.label, menuItems: menu.menuItems, session: session }))),
44
+ react_1.default.createElement("div", { className: classes.grow }),
45
+ react_1.default.createElement(material_1.Tooltip, { title: "Rename Session", arrow: true },
46
+ react_1.default.createElement(EditableTypography_1.default, { value: name, setValue: handleNameChange, variant: "body1", classes: {
47
+ inputBase: classes.inputBase,
48
+ inputRoot: classes.inputRoot,
49
+ inputFocused: classes.inputFocused,
50
+ } })),
51
+ HeaderButtons,
52
+ react_1.default.createElement("div", { className: classes.grow }),
53
+ react_1.default.createElement("div", { style: { width: 150, maxHeight: 48 } },
54
+ react_1.default.createElement(AppLogo_1.default, { session: session }))));
55
+ });
56
+ exports.default = AppToolbar;
@@ -1,11 +1,13 @@
1
1
  /// <reference types="react" />
2
- import { InputProps as IIP } from '@mui/material';
2
+ import { InputProps as IIP, TextFieldProps as TFP } from '@mui/material';
3
3
  import { AbstractSessionModel } from '../util';
4
- declare const AssemblySelector: ({ session, onChange, selected, InputProps, extra, }: {
4
+ declare const AssemblySelector: ({ session, onChange, selected, InputProps, TextFieldProps, localStorageKey, helperText, }: {
5
5
  session: AbstractSessionModel;
6
+ helperText?: string | undefined;
6
7
  onChange: (arg: string) => void;
7
8
  selected?: string | undefined;
9
+ localStorageKey?: string | undefined;
8
10
  InputProps?: IIP | undefined;
9
- extra?: unknown;
11
+ TextFieldProps?: TFP | undefined;
10
12
  }) => JSX.Element;
11
13
  export default AssemblySelector;
@@ -35,17 +35,17 @@ const useStyles = (0, mui_1.makeStyles)()({
35
35
  minWidth: 180,
36
36
  },
37
37
  });
38
- const AssemblySelector = (0, mobx_react_1.observer)(({ session, onChange, selected, InputProps, extra = 0, }) => {
38
+ const AssemblySelector = (0, mobx_react_1.observer)(({ session, onChange, selected, InputProps, TextFieldProps, localStorageKey, helperText = 'Select assembly to view', }) => {
39
39
  const { classes } = useStyles();
40
40
  const { assemblyNames, assemblyManager } = session;
41
41
  // constructs a localstorage key based on host/path/config to help
42
42
  // remember. non-config assists usage with e.g. embedded apps
43
43
  const config = new URLSearchParams(window.location.search).get('config');
44
- const [lastSelected, setLastSelected] = typeof jest === 'undefined'
44
+ const [lastSelected, setLastSelected] = typeof jest === 'undefined' && localStorageKey
45
45
  ? (0, util_1.useLocalStorage)(`lastAssembly-${[
46
46
  window.location.host + window.location.pathname,
47
47
  config,
48
- extra,
48
+ localStorageKey,
49
49
  ].join('-')}`, selected)
50
50
  : (0, react_1.useState)(selected);
51
51
  const selection = assemblyNames.includes(lastSelected || '')
@@ -57,7 +57,7 @@ const AssemblySelector = (0, mobx_react_1.observer)(({ session, onChange, select
57
57
  }
58
58
  }, [selection, onChange, selected]);
59
59
  const error = assemblyNames.length ? '' : 'No configured assemblies';
60
- return (react_1.default.createElement(material_1.TextField, { select: true, label: "Assembly", variant: "outlined", helperText: error || 'Select assembly to view', value: selection || '', inputProps: { 'data-testid': 'assembly-selector' }, onChange: event => setLastSelected(event.target.value), error: !!error, InputProps: InputProps, disabled: !!error, className: classes.importFormEntry }, assemblyNames.map(name => {
60
+ return (react_1.default.createElement(material_1.TextField, { select: true, label: "Assembly", variant: "outlined", helperText: error || helperText, value: selection || '', inputProps: { 'data-testid': 'assembly-selector' }, onChange: event => setLastSelected(event.target.value), error: !!error, InputProps: InputProps, disabled: !!error, className: classes.importFormEntry, ...TextFieldProps }, assemblyNames.map(name => {
61
61
  const assembly = assemblyManager.get(name);
62
62
  const displayName = assembly ? (0, configuration_1.getConf)(assembly, 'displayName') : '';
63
63
  return (react_1.default.createElement(material_1.MenuItem, { key: name, value: name }, displayName || name));
@@ -1,28 +1,11 @@
1
1
  /// <reference types="react" />
2
- import ReactPropTypes from 'prop-types';
3
2
  declare function PrerenderedCanvas(props: {
4
3
  width: number;
5
4
  height: number;
6
- highResolutionScaling: number;
7
- style: any;
8
- imageData: any;
5
+ highResolutionScaling?: number;
6
+ style?: any;
7
+ imageData?: any;
9
8
  showSoftClip?: boolean;
10
9
  blockKey?: string;
11
10
  }): JSX.Element;
12
- declare namespace PrerenderedCanvas {
13
- var propTypes: {
14
- height: ReactPropTypes.Validator<number>;
15
- width: ReactPropTypes.Validator<number>;
16
- highResolutionScaling: ReactPropTypes.Requireable<number>;
17
- style: ReactPropTypes.Requireable<{
18
- [x: string]: any;
19
- }>;
20
- imageData: ReactPropTypes.Requireable<any>;
21
- };
22
- var defaultProps: {
23
- imageData: undefined;
24
- highResolutionScaling: number;
25
- style: {};
26
- };
27
- }
28
11
  export default PrerenderedCanvas;
@@ -22,16 +22,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
25
  Object.defineProperty(exports, "__esModule", { value: true });
29
26
  /* eslint-disable @typescript-eslint/no-explicit-any */
30
- const prop_types_1 = __importDefault(require("prop-types"));
31
27
  const react_1 = __importStar(require("react"));
32
28
  const offscreenCanvasPonyfill_1 = require("../util/offscreenCanvasPonyfill");
33
29
  function PrerenderedCanvas(props) {
34
- const { width, height, highResolutionScaling, style, imageData, blockKey, showSoftClip, } = props;
30
+ const { width, height, highResolutionScaling = 1, style = {}, imageData, blockKey, showSoftClip, } = props;
35
31
  const [done, setDone] = (0, react_1.useState)(false);
36
32
  const featureCanvas = (0, react_1.useRef)(null);
37
33
  (0, react_1.useEffect)(() => {
@@ -54,18 +50,4 @@ function PrerenderedCanvas(props) {
54
50
  const testId = `prerendered_canvas${softClipString}${blockKeyStr}${done ? '_done' : ''}`;
55
51
  return (react_1.default.createElement("canvas", { "data-testid": testId, ref: featureCanvas, width: width * highResolutionScaling, height: height * highResolutionScaling, style: { width, height, ...style } }));
56
52
  }
57
- PrerenderedCanvas.propTypes = {
58
- height: prop_types_1.default.number.isRequired,
59
- width: prop_types_1.default.number.isRequired,
60
- highResolutionScaling: prop_types_1.default.number,
61
- style: prop_types_1.default.objectOf(prop_types_1.default.any),
62
- imageData: prop_types_1.default.any,
63
- // config: ReactPropTypes.objectOf(ReactPropTypes.any),
64
- };
65
- PrerenderedCanvas.defaultProps = {
66
- imageData: undefined,
67
- highResolutionScaling: 1,
68
- style: {},
69
- // config: {},
70
- };
71
53
  exports.default = PrerenderedCanvas;
package/ui/Snackbar.js CHANGED
@@ -1,79 +1,33 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
5
  Object.defineProperty(exports, "__esModule", { value: true });
29
- const react_1 = __importStar(require("react"));
6
+ const react_1 = __importDefault(require("react"));
30
7
  const material_1 = require("@mui/material");
31
- const Close_1 = __importDefault(require("@mui/icons-material/Close"));
32
8
  const mobx_react_1 = require("mobx-react");
9
+ // icons
10
+ const Close_1 = __importDefault(require("@mui/icons-material/Close"));
33
11
  function MessageSnackbar({ session, }) {
34
- const [open, setOpen] = (0, react_1.useState)(false);
35
- const [snackbarMessage, setSnackbarMessage] = (0, react_1.useState)();
36
12
  const { popSnackbarMessage, snackbarMessages } = session;
37
13
  const latestMessage = snackbarMessages.length
38
14
  ? snackbarMessages[snackbarMessages.length - 1]
39
15
  : null;
40
- (0, react_1.useEffect)(() => {
41
- let timeoutId;
42
- if (snackbarMessage) {
43
- if (!latestMessage) {
44
- setSnackbarMessage(undefined);
45
- }
46
- else if (snackbarMessage[0] !== latestMessage[0]) {
47
- setOpen(false);
48
- timeoutId = setTimeout(() => {
49
- setSnackbarMessage(latestMessage);
50
- setOpen(true);
51
- }, 100);
52
- }
53
- }
54
- else if (latestMessage) {
55
- setSnackbarMessage(latestMessage);
56
- setOpen(true);
57
- }
58
- return () => {
59
- clearTimeout(timeoutId);
60
- };
61
- }, [latestMessage, snackbarMessage]);
62
16
  const handleClose = (_event, reason) => {
63
17
  if (reason === 'clickaway') {
64
18
  return;
65
19
  }
66
20
  popSnackbarMessage();
67
- setOpen(false);
68
21
  };
69
- const [message, level, action] = snackbarMessage || [];
70
- return (react_1.default.createElement(material_1.Snackbar, { open: open && !!message, onClose: handleClose, anchorOrigin: { vertical: 'bottom', horizontal: 'center' } },
22
+ const open = !!latestMessage;
23
+ const [message, level, action] = latestMessage || [];
24
+ return (react_1.default.createElement(material_1.Snackbar, { open: open, onClose: handleClose, anchorOrigin: { vertical: 'bottom', horizontal: 'center' } },
71
25
  react_1.default.createElement(material_1.Alert, { onClose: handleClose, action: action ? (react_1.default.createElement(react_1.default.Fragment, null,
72
26
  react_1.default.createElement(material_1.Button, { color: "inherit", onClick: e => {
73
27
  action.onClick();
74
28
  handleClose(e);
75
29
  } }, action.name),
76
- react_1.default.createElement(material_1.IconButton, { "aria-label": "close", color: "inherit", onClick: handleClose },
30
+ react_1.default.createElement(material_1.IconButton, { color: "inherit", onClick: handleClose },
77
31
  react_1.default.createElement(Close_1.default, null)))) : null, severity: level || 'warning' }, message)));
78
32
  }
79
33
  exports.default = (0, mobx_react_1.observer)(MessageSnackbar);
@@ -0,0 +1,18 @@
1
+ /// <reference types="react" />
2
+ import { NotificationLevel, SnackAction, SessionWithDrawerWidgets } from '../util';
3
+ import { MenuItem as JBMenuItem } from './Menu';
4
+ type SnackbarMessage = [string, NotificationLevel, SnackAction];
5
+ type AppSession = SessionWithDrawerWidgets & {
6
+ savedSessionNames: string[];
7
+ menus: {
8
+ label: string;
9
+ menuItems: JBMenuItem[];
10
+ }[];
11
+ renameCurrentSession: (arg: string) => void;
12
+ snackbarMessages: SnackbarMessage[];
13
+ popSnackbarMessage: () => unknown;
14
+ };
15
+ declare const ViewLauncher: ({ session }: {
16
+ session: AppSession;
17
+ }) => JSX.Element;
18
+ export default ViewLauncher;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const react_1 = __importStar(require("react"));
27
+ const material_1 = require("@mui/material");
28
+ const mobx_react_1 = require("mobx-react");
29
+ const mui_1 = require("tss-react/mui");
30
+ // locals
31
+ const util_1 = require("../util");
32
+ const useStyles = (0, mui_1.makeStyles)()(theme => ({
33
+ selectPaper: {
34
+ padding: theme.spacing(4),
35
+ },
36
+ }));
37
+ const ViewLauncher = (0, mobx_react_1.observer)(({ session }) => {
38
+ var _a;
39
+ const { classes } = useStyles();
40
+ const { pluginManager } = (0, util_1.getEnv)(session);
41
+ const viewTypes = pluginManager.getElementTypeRecord('view').all();
42
+ const [value, setValue] = (0, react_1.useState)((_a = viewTypes[0]) === null || _a === void 0 ? void 0 : _a.name);
43
+ return (react_1.default.createElement(material_1.Paper, { className: classes.selectPaper },
44
+ react_1.default.createElement(material_1.Typography, null, "Select a view to launch"),
45
+ react_1.default.createElement(material_1.FormControl, { style: { margin: 2 } },
46
+ react_1.default.createElement(material_1.Select, { value: value, onChange: event => setValue(event.target.value) }, viewTypes.map(({ displayName, name }) => (react_1.default.createElement(material_1.MenuItem, { key: name, value: name }, displayName))))),
47
+ react_1.default.createElement(material_1.FormControl, { style: { margin: 2 } },
48
+ react_1.default.createElement(material_1.Button, { onClick: () => session.addView(value, {}), variant: "contained", color: "primary" }, "Launch view"))));
49
+ });
50
+ exports.default = ViewLauncher;
package/ui/index.d.ts CHANGED
@@ -1,19 +1,19 @@
1
1
  export * from './theme';
2
2
  export { LogoFull, Logomark } from './Logo';
3
- export { default as Dialog } from './Dialog';
4
3
  export { default as App } from './App';
5
- export { default as ReturnToImportFormDialog } from './ReturnToImportFormDialog';
6
- export { default as ErrorMessage } from './ErrorMessage';
7
4
  export { default as AssemblySelector } from './AssemblySelector';
8
- export { default as FileSelector } from './FileSelector';
9
- export { default as PrerenderedCanvas } from './PrerenderedCanvas';
10
- export { default as ResizeHandle } from './ResizeHandle';
5
+ export { default as CascadingMenu } from './CascadingMenu';
6
+ export { default as Dialog } from './Dialog';
11
7
  export { default as EditableTypography } from './EditableTypography';
8
+ export { default as ErrorMessage } from './ErrorMessage';
12
9
  export { default as FactoryResetDialog } from './FactoryResetDialog';
13
- export { default as Tooltip } from './Tooltip';
14
10
  export { default as FatalErrorDialog } from './FatalErrorDialog';
11
+ export { default as FileSelector } from './FileSelector';
12
+ export { default as LoadingEllipses } from './LoadingEllipses';
15
13
  export { default as Menu } from './Menu';
16
- export { default as CascadingMenu } from './CascadingMenu';
14
+ export { default as PrerenderedCanvas } from './PrerenderedCanvas';
15
+ export { default as Tooltip } from './Tooltip';
16
+ export { default as ReturnToImportFormDialog } from './ReturnToImportFormDialog';
17
+ export { default as ResizeHandle } from './ResizeHandle';
17
18
  export { default as SanitizedHTML } from './SanitizedHTML';
18
- export { default as LoadingEllipses } from './LoadingEllipses';
19
19
  export * from './Menu';
package/ui/index.js CHANGED
@@ -17,41 +17,41 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.LoadingEllipses = exports.SanitizedHTML = exports.CascadingMenu = exports.Menu = exports.FatalErrorDialog = exports.Tooltip = exports.FactoryResetDialog = exports.EditableTypography = exports.ResizeHandle = exports.PrerenderedCanvas = exports.FileSelector = exports.AssemblySelector = exports.ErrorMessage = exports.ReturnToImportFormDialog = exports.App = exports.Dialog = exports.Logomark = exports.LogoFull = void 0;
20
+ exports.SanitizedHTML = exports.ResizeHandle = exports.ReturnToImportFormDialog = exports.Tooltip = exports.PrerenderedCanvas = exports.Menu = exports.LoadingEllipses = exports.FileSelector = exports.FatalErrorDialog = exports.FactoryResetDialog = exports.ErrorMessage = exports.EditableTypography = exports.Dialog = exports.CascadingMenu = exports.AssemblySelector = exports.App = exports.Logomark = exports.LogoFull = void 0;
21
21
  __exportStar(require("./theme"), exports);
22
22
  var Logo_1 = require("./Logo");
23
23
  Object.defineProperty(exports, "LogoFull", { enumerable: true, get: function () { return Logo_1.LogoFull; } });
24
24
  Object.defineProperty(exports, "Logomark", { enumerable: true, get: function () { return Logo_1.Logomark; } });
25
- var Dialog_1 = require("./Dialog");
26
- Object.defineProperty(exports, "Dialog", { enumerable: true, get: function () { return __importDefault(Dialog_1).default; } });
27
25
  var App_1 = require("./App");
28
26
  Object.defineProperty(exports, "App", { enumerable: true, get: function () { return __importDefault(App_1).default; } });
29
- var ReturnToImportFormDialog_1 = require("./ReturnToImportFormDialog");
30
- Object.defineProperty(exports, "ReturnToImportFormDialog", { enumerable: true, get: function () { return __importDefault(ReturnToImportFormDialog_1).default; } });
31
- var ErrorMessage_1 = require("./ErrorMessage");
32
- Object.defineProperty(exports, "ErrorMessage", { enumerable: true, get: function () { return __importDefault(ErrorMessage_1).default; } });
33
27
  var AssemblySelector_1 = require("./AssemblySelector");
34
28
  Object.defineProperty(exports, "AssemblySelector", { enumerable: true, get: function () { return __importDefault(AssemblySelector_1).default; } });
35
- var FileSelector_1 = require("./FileSelector");
36
- Object.defineProperty(exports, "FileSelector", { enumerable: true, get: function () { return __importDefault(FileSelector_1).default; } });
37
- var PrerenderedCanvas_1 = require("./PrerenderedCanvas");
38
- Object.defineProperty(exports, "PrerenderedCanvas", { enumerable: true, get: function () { return __importDefault(PrerenderedCanvas_1).default; } });
39
- var ResizeHandle_1 = require("./ResizeHandle");
40
- Object.defineProperty(exports, "ResizeHandle", { enumerable: true, get: function () { return __importDefault(ResizeHandle_1).default; } });
29
+ var CascadingMenu_1 = require("./CascadingMenu");
30
+ Object.defineProperty(exports, "CascadingMenu", { enumerable: true, get: function () { return __importDefault(CascadingMenu_1).default; } });
31
+ var Dialog_1 = require("./Dialog");
32
+ Object.defineProperty(exports, "Dialog", { enumerable: true, get: function () { return __importDefault(Dialog_1).default; } });
41
33
  var EditableTypography_1 = require("./EditableTypography");
42
34
  Object.defineProperty(exports, "EditableTypography", { enumerable: true, get: function () { return __importDefault(EditableTypography_1).default; } });
35
+ var ErrorMessage_1 = require("./ErrorMessage");
36
+ Object.defineProperty(exports, "ErrorMessage", { enumerable: true, get: function () { return __importDefault(ErrorMessage_1).default; } });
43
37
  var FactoryResetDialog_1 = require("./FactoryResetDialog");
44
38
  Object.defineProperty(exports, "FactoryResetDialog", { enumerable: true, get: function () { return __importDefault(FactoryResetDialog_1).default; } });
45
- var Tooltip_1 = require("./Tooltip");
46
- Object.defineProperty(exports, "Tooltip", { enumerable: true, get: function () { return __importDefault(Tooltip_1).default; } });
47
39
  var FatalErrorDialog_1 = require("./FatalErrorDialog");
48
40
  Object.defineProperty(exports, "FatalErrorDialog", { enumerable: true, get: function () { return __importDefault(FatalErrorDialog_1).default; } });
41
+ var FileSelector_1 = require("./FileSelector");
42
+ Object.defineProperty(exports, "FileSelector", { enumerable: true, get: function () { return __importDefault(FileSelector_1).default; } });
43
+ var LoadingEllipses_1 = require("./LoadingEllipses");
44
+ Object.defineProperty(exports, "LoadingEllipses", { enumerable: true, get: function () { return __importDefault(LoadingEllipses_1).default; } });
49
45
  var Menu_1 = require("./Menu");
50
46
  Object.defineProperty(exports, "Menu", { enumerable: true, get: function () { return __importDefault(Menu_1).default; } });
51
- var CascadingMenu_1 = require("./CascadingMenu");
52
- Object.defineProperty(exports, "CascadingMenu", { enumerable: true, get: function () { return __importDefault(CascadingMenu_1).default; } });
47
+ var PrerenderedCanvas_1 = require("./PrerenderedCanvas");
48
+ Object.defineProperty(exports, "PrerenderedCanvas", { enumerable: true, get: function () { return __importDefault(PrerenderedCanvas_1).default; } });
49
+ var Tooltip_1 = require("./Tooltip");
50
+ Object.defineProperty(exports, "Tooltip", { enumerable: true, get: function () { return __importDefault(Tooltip_1).default; } });
51
+ var ReturnToImportFormDialog_1 = require("./ReturnToImportFormDialog");
52
+ Object.defineProperty(exports, "ReturnToImportFormDialog", { enumerable: true, get: function () { return __importDefault(ReturnToImportFormDialog_1).default; } });
53
+ var ResizeHandle_1 = require("./ResizeHandle");
54
+ Object.defineProperty(exports, "ResizeHandle", { enumerable: true, get: function () { return __importDefault(ResizeHandle_1).default; } });
53
55
  var SanitizedHTML_1 = require("./SanitizedHTML");
54
56
  Object.defineProperty(exports, "SanitizedHTML", { enumerable: true, get: function () { return __importDefault(SanitizedHTML_1).default; } });
55
- var LoadingEllipses_1 = require("./LoadingEllipses");
56
- Object.defineProperty(exports, "LoadingEllipses", { enumerable: true, get: function () { return __importDefault(LoadingEllipses_1).default; } });
57
57
  __exportStar(require("./Menu"), exports);
@@ -109,7 +109,7 @@ function pxToBp(self, px) {
109
109
  bpSoFar += len;
110
110
  }
111
111
  }
112
- if (bp >= bpSoFar) {
112
+ if (bp >= bpSoFar && displayedRegions.length) {
113
113
  const region = displayedRegions[displayedRegions.length - 1];
114
114
  const len = region.end - region.start;
115
115
  const offset = bp - bpSoFar + len;
@@ -0,0 +1,3 @@
1
+ type Hasher<T> = (input: T) => string;
2
+ export declare function dedupe<T>(list: T[], hasher?: Hasher<T>): T[];
3
+ export {};
package/util/dedupe.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dedupe = void 0;
4
+ // from https://github.com/seriousManual/dedupe/blob/master/LICENSE
5
+ function dedupe(list, hasher = JSON.stringify) {
6
+ const clone = [];
7
+ const lookup = new Set();
8
+ for (let i = 0; i < list.length; i++) {
9
+ const entry = list[i];
10
+ const hashed = hasher(entry);
11
+ if (!lookup.has(hashed)) {
12
+ clone.push(entry);
13
+ lookup.add(hashed);
14
+ }
15
+ }
16
+ return clone;
17
+ }
18
+ exports.dedupe = dedupe;