@jbrowse/core 2.1.7 → 2.2.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.d.ts +2 -2
- package/BaseFeatureWidget/SequenceFeatureDetails.js +2 -1
- package/PluginManager.d.ts +3 -3
- package/ReExports/modules.d.ts +3 -3
- package/assemblyManager/assembly.d.ts +20 -14
- package/assemblyManager/assembly.js +74 -75
- package/assemblyManager/assemblyConfigSchema.d.ts +6 -2
- package/assemblyManager/assemblyConfigSchema.js +39 -2
- package/assemblyManager/assemblyManager.d.ts +76 -214
- package/assemblyManager/assemblyManager.js +17 -39
- package/data_adapters/CytobandAdapter.js +7 -0
- package/package.json +2 -2
- package/pluggableElementTypes/models/BaseDisplayModel.d.ts +60 -1
- package/pluggableElementTypes/models/BaseDisplayModel.js +138 -92
- package/pluggableElementTypes/models/baseConnectionConfig.js +17 -1
- package/pluggableElementTypes/models/baseInternetAccountConfig.js +27 -1
- package/pluggableElementTypes/models/baseTrackConfig.d.ts +3 -0
- package/pluggableElementTypes/models/baseTrackConfig.js +43 -1
- package/pluggableElementTypes/renderers/BoxRendererType.d.ts +1 -1
- package/pluggableElementTypes/renderers/BoxRendererType.js +2 -0
- package/rpc/MainThreadRpcDriver.d.ts +1 -1
- package/rpc/MainThreadRpcDriver.js +2 -2
- package/rpc/WebWorkerRpcDriver.d.ts +5 -4
- package/rpc/WebWorkerRpcDriver.js +2 -2
- package/rpc/baseRpcConfig.d.ts +2 -0
- package/rpc/baseRpcConfig.js +18 -0
- package/rpc/configSchema.js +16 -10
- package/rpc/coreRpcMethods.d.ts +14 -14
- package/rpc/coreRpcMethods.js +60 -63
- package/rpc/mainThreadRpcConfig.d.ts +2 -0
- package/rpc/mainThreadRpcConfig.js +19 -0
- package/rpc/webWorkerRpcConfig.d.ts +2 -0
- package/rpc/webWorkerRpcConfig.js +19 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/ui/AboutDialog.js +2 -1
- package/ui/App.js +8 -5
- package/ui/AssemblySelector.js +1 -1
- package/ui/DrawerWidget.js +2 -1
- package/ui/LoadingEllipses.d.ts +7 -0
- package/ui/LoadingEllipses.js +38 -0
- package/ui/index.d.ts +1 -0
- package/ui/index.js +3 -1
- package/util/Base1DUtils.js +9 -3
- package/util/calculateDynamicBlocks.js +1 -1
- package/util/calculateStaticBlocks.js +1 -1
- package/util/index.d.ts +1 -0
- package/util/index.js +13 -9
- package/util/io/RemoteFileWithRangeCache.d.ts +1 -2
- package/util/layouts/GranularRectLayout.d.ts +7 -2
- package/util/layouts/GranularRectLayout.js +29 -45
- package/util/layouts/MultiLayout.d.ts +2 -2
- package/util/layouts/MultiLayout.js +4 -6
- package/util/simpleFeature.d.ts +3 -0
- package/util/stats.d.ts +26 -0
- package/util/stats.js +9 -9
package/ui/AboutDialog.js
CHANGED
|
@@ -33,6 +33,7 @@ const material_1 = require("@mui/material");
|
|
|
33
33
|
const Close_1 = __importDefault(require("@mui/icons-material/Close"));
|
|
34
34
|
const mui_1 = require("tss-react/mui");
|
|
35
35
|
const configuration_1 = require("../configuration");
|
|
36
|
+
const LoadingEllipses_1 = __importDefault(require("./LoadingEllipses"));
|
|
36
37
|
const util_1 = require("../util");
|
|
37
38
|
const tracks_1 = require("../util/tracks");
|
|
38
39
|
const BaseFeatureDetail_1 = require("../BaseFeatureWidget/BaseFeatureDetail");
|
|
@@ -86,7 +87,7 @@ function FileInfo({ config }) {
|
|
|
86
87
|
.replace(/>/g, '>')}</pre>`,
|
|
87
88
|
}
|
|
88
89
|
: 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 ? (
|
|
90
|
+
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 ? (react_1.default.createElement(LoadingEllipses_1.default, { message: "Loading file data" })) : (react_1.default.createElement(BaseFeatureDetail_1.Attributes, { attributes: details })))) : null;
|
|
90
91
|
}
|
|
91
92
|
exports.FileInfo = FileInfo;
|
|
92
93
|
function AboutContents({ config }) {
|
package/ui/App.js
CHANGED
|
@@ -38,6 +38,7 @@ const configuration_1 = require("../configuration");
|
|
|
38
38
|
const DrawerWidget_1 = __importDefault(require("./DrawerWidget"));
|
|
39
39
|
const DropDownMenu_1 = __importDefault(require("./DropDownMenu"));
|
|
40
40
|
const ErrorMessage_1 = __importDefault(require("./ErrorMessage"));
|
|
41
|
+
const LoadingEllipses_1 = __importDefault(require("./LoadingEllipses"));
|
|
41
42
|
const EditableTypography_1 = __importDefault(require("./EditableTypography"));
|
|
42
43
|
const Logo_1 = require("./Logo");
|
|
43
44
|
const Snackbar_1 = __importDefault(require("./Snackbar"));
|
|
@@ -139,10 +140,12 @@ const ViewLauncher = (0, mobx_react_1.observer)(({ session }) => {
|
|
|
139
140
|
const [value, setValue] = (0, react_1.useState)((_a = viewTypes[0]) === null || _a === void 0 ? void 0 : _a.name);
|
|
140
141
|
return (react_1.default.createElement(material_1.Paper, { className: classes.selectPaper },
|
|
141
142
|
react_1.default.createElement(material_1.Typography, null, "Select a view to launch"),
|
|
142
|
-
react_1.default.createElement(material_1.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
react_1.default.createElement(material_1.FormControl, { style: { margin: 2 } },
|
|
144
|
+
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))))),
|
|
145
|
+
react_1.default.createElement(material_1.FormControl, { style: { margin: 2 } },
|
|
146
|
+
react_1.default.createElement(material_1.Button, { onClick: () => {
|
|
147
|
+
session.addView(value, {});
|
|
148
|
+
}, variant: "contained", color: "primary" }, "Launch view"))));
|
|
146
149
|
});
|
|
147
150
|
const ViewPanel = (0, mobx_react_1.observer)(({ view, session }) => {
|
|
148
151
|
const { pluginManager } = (0, mobx_state_tree_1.getEnv)(session);
|
|
@@ -152,7 +155,7 @@ const ViewPanel = (0, mobx_react_1.observer)(({ view, session }) => {
|
|
|
152
155
|
}
|
|
153
156
|
const { ReactComponent } = viewType;
|
|
154
157
|
return (react_1.default.createElement(ViewContainer_1.default, { view: view, onClose: () => session.removeView(view) },
|
|
155
|
-
react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(
|
|
158
|
+
react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(LoadingEllipses_1.default, null) },
|
|
156
159
|
react_1.default.createElement(ReactComponent, { model: view, session: session, getTrackType: pluginManager.getTrackType }))));
|
|
157
160
|
});
|
|
158
161
|
const App = (0, mobx_react_1.observer)((props) => {
|
package/ui/AssemblySelector.js
CHANGED
|
@@ -55,7 +55,7 @@ const AssemblySelector = (0, mobx_react_1.observer)(({ session, onChange, select
|
|
|
55
55
|
}
|
|
56
56
|
}, [selection, onChange, selected]);
|
|
57
57
|
const error = assemblyNames.length ? '' : 'No configured assemblies';
|
|
58
|
-
return (react_1.default.createElement(material_1.TextField, { select: true, label: "Assembly", variant: "outlined", helperText: error || 'Select assembly to view', value:
|
|
58
|
+
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 => {
|
|
59
59
|
const assembly = assemblyManager.get(name);
|
|
60
60
|
const displayName = assembly ? (0, configuration_1.getConf)(assembly, 'displayName') : '';
|
|
61
61
|
return (react_1.default.createElement(material_1.MenuItem, { key: name, value: name }, displayName || name));
|
package/ui/DrawerWidget.js
CHANGED
|
@@ -32,6 +32,7 @@ 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
34
|
const util_1 = require("../util");
|
|
35
|
+
const LoadingEllipses_1 = __importDefault(require("./LoadingEllipses"));
|
|
35
36
|
// icons
|
|
36
37
|
const Delete_1 = __importDefault(require("@mui/icons-material/Delete"));
|
|
37
38
|
const Close_1 = __importDefault(require("@mui/icons-material/Close"));
|
|
@@ -123,7 +124,7 @@ const DrawerWidget = (0, mobx_react_1.observer)(({ session }) => {
|
|
|
123
124
|
const [toolbarHeight, setToolbarHeight] = (0, react_1.useState)(0);
|
|
124
125
|
return (react_1.default.createElement(Drawer_1.default, { session: session },
|
|
125
126
|
react_1.default.createElement(DrawerHeader, { session: session, setToolbarHeight: setToolbarHeight }),
|
|
126
|
-
react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(
|
|
127
|
+
react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(LoadingEllipses_1.default, null) },
|
|
127
128
|
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))));
|
|
128
129
|
});
|
|
129
130
|
exports.default = DrawerWidget;
|
|
@@ -0,0 +1,38 @@
|
|
|
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 tss_react_1 = require("tss-react");
|
|
10
|
+
const useStyles = (0, mui_1.makeStyles)()({
|
|
11
|
+
dots: {
|
|
12
|
+
'&::after': {
|
|
13
|
+
display: 'inline-block',
|
|
14
|
+
content: '""',
|
|
15
|
+
width: '1em',
|
|
16
|
+
textAlign: 'left',
|
|
17
|
+
animation: `${(0, tss_react_1.keyframes) `
|
|
18
|
+
0% {
|
|
19
|
+
content: '';
|
|
20
|
+
}
|
|
21
|
+
25% {
|
|
22
|
+
content: '.';
|
|
23
|
+
}
|
|
24
|
+
50% {
|
|
25
|
+
content: '..';
|
|
26
|
+
}
|
|
27
|
+
75% {
|
|
28
|
+
content: '...';
|
|
29
|
+
}
|
|
30
|
+
`} 1.4s infinite ease-in-out`,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
function LoadingEllipses({ message = 'Loading', variant = 'body2', ...rest }) {
|
|
35
|
+
const { classes } = useStyles();
|
|
36
|
+
return (react_1.default.createElement(material_1.Typography, { className: classes.dots, ...rest, variant: variant }, `${message || 'Loading'}`));
|
|
37
|
+
}
|
|
38
|
+
exports.default = LoadingEllipses;
|
package/ui/index.d.ts
CHANGED
|
@@ -14,4 +14,5 @@ export { default as FatalErrorDialog } from './FatalErrorDialog';
|
|
|
14
14
|
export { default as Menu } from './Menu';
|
|
15
15
|
export { default as CascadingMenu } from './CascadingMenu';
|
|
16
16
|
export { default as SanitizedHTML } from './SanitizedHTML';
|
|
17
|
+
export { default as LoadingEllipses } from './LoadingEllipses';
|
|
17
18
|
export * from './Menu';
|
package/ui/index.js
CHANGED
|
@@ -17,7 +17,7 @@ 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.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.Logomark = exports.LogoFull = void 0;
|
|
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.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; } });
|
|
@@ -50,4 +50,6 @@ var CascadingMenu_1 = require("./CascadingMenu");
|
|
|
50
50
|
Object.defineProperty(exports, "CascadingMenu", { enumerable: true, get: function () { return __importDefault(CascadingMenu_1).default; } });
|
|
51
51
|
var SanitizedHTML_1 = require("./SanitizedHTML");
|
|
52
52
|
Object.defineProperty(exports, "SanitizedHTML", { enumerable: true, get: function () { return __importDefault(SanitizedHTML_1).default; } });
|
|
53
|
+
var LoadingEllipses_1 = require("./LoadingEllipses");
|
|
54
|
+
Object.defineProperty(exports, "LoadingEllipses", { enumerable: true, get: function () { return __importDefault(LoadingEllipses_1).default; } });
|
|
53
55
|
__exportStar(require("./Menu"), exports);
|
package/util/Base1DUtils.js
CHANGED
|
@@ -26,10 +26,16 @@ function moveTo(self, start, end) {
|
|
|
26
26
|
if (!start || !end) {
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
|
-
const { width, interRegionPaddingWidth } = self;
|
|
29
|
+
const { width, interRegionPaddingWidth, displayedRegions, bpPerPx, minimumBlockWidth, } = self;
|
|
30
30
|
const len = lengthBetween(self, start, end);
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
let numBlocksWideEnough = 0;
|
|
32
|
+
for (let i = start.index; i < end.index; i++) {
|
|
33
|
+
const r = displayedRegions[i];
|
|
34
|
+
if ((r.end - r.start) / bpPerPx > minimumBlockWidth) {
|
|
35
|
+
numBlocksWideEnough++;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const targetBpPerPx = len / (width - interRegionPaddingWidth * numBlocksWideEnough);
|
|
33
39
|
const newBpPerPx = self.zoomTo(targetBpPerPx);
|
|
34
40
|
// If our target bpPerPx was smaller than the allowed minBpPerPx, adjust
|
|
35
41
|
// the scroll so the requested range is in the middle of the screen
|
|
@@ -75,7 +75,7 @@ function calculateDynamicBlocks(model, padding = true, elision = true) {
|
|
|
75
75
|
isRightEndOfDisplayedRegion,
|
|
76
76
|
key: '',
|
|
77
77
|
};
|
|
78
|
-
blockData.key = `${(0, _1.
|
|
78
|
+
blockData.key = `${(0, _1.assembleLocStringFast)(blockData)}-${regionNumber}${reversed ? '-reversed' : ''}`;
|
|
79
79
|
if (padding && blocks.length === 0 && isLeftEndOfDisplayedRegion) {
|
|
80
80
|
blocks.push(new blockTypes_1.InterRegionPaddingBlock({
|
|
81
81
|
key: `${blockData.key}-beforeFirstRegion`,
|
|
@@ -59,7 +59,7 @@ function calculateStaticBlocks(model, padding = true, elision = true, extra = 0,
|
|
|
59
59
|
isRightEndOfDisplayedRegion,
|
|
60
60
|
key: '',
|
|
61
61
|
};
|
|
62
|
-
blockData.key = `${(0, _1.
|
|
62
|
+
blockData.key = `${(0, _1.assembleLocStringFast)(blockData)}-${regionNumber}${reversed ? '-reversed' : ''}`;
|
|
63
63
|
if (padding && regionNumber === 0 && blockNum === 0) {
|
|
64
64
|
blocks.push(new blockTypes_1.InterRegionPaddingBlock({
|
|
65
65
|
key: `${blockData.key}-beforeFirstRegion`,
|
package/util/index.d.ts
CHANGED
|
@@ -63,6 +63,7 @@ export declare function getContainingDisplay(node: IAnyStateTreeNode): import(".
|
|
|
63
63
|
* ```
|
|
64
64
|
*/
|
|
65
65
|
export declare function assembleLocString(region: ParsedLocString): string;
|
|
66
|
+
export declare function assembleLocStringFast(region: ParsedLocString, cb?: (n: number) => string | number): string;
|
|
66
67
|
export interface ParsedLocString {
|
|
67
68
|
assemblyName?: string;
|
|
68
69
|
refName: string;
|
package/util/index.js
CHANGED
|
@@ -29,8 +29,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
29
29
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
30
30
|
};
|
|
31
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
-
exports.
|
|
33
|
-
exports.getEnv = exports.measureGridWidth = exports.getStr = exports.getUriLink = exports.useLocalStorage = exports.getLayoutId = exports.getViewParams = exports.getTickDisplayStr = exports.toLocale = void 0;
|
|
32
|
+
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.assembleLocStringFast = 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.getEnv = exports.measureGridWidth = exports.getStr = exports.getUriLink = exports.useLocalStorage = exports.getLayoutId = exports.getViewParams = exports.getTickDisplayStr = exports.toLocale = exports.getBpDisplayStr = 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"));
|
|
@@ -237,11 +237,18 @@ exports.getContainingDisplay = getContainingDisplay;
|
|
|
237
237
|
* ```
|
|
238
238
|
*/
|
|
239
239
|
function assembleLocString(region) {
|
|
240
|
+
return assembleLocStringFast(region, toLocale);
|
|
241
|
+
}
|
|
242
|
+
exports.assembleLocString = assembleLocString;
|
|
243
|
+
// same as assembleLocString above, but does not perform toLocaleString which
|
|
244
|
+
// can slow down the speed of block calculations which use assembleLocString
|
|
245
|
+
// for block.key
|
|
246
|
+
function assembleLocStringFast(region, cb = (n) => n) {
|
|
240
247
|
const { assemblyName, refName, start, end, reversed } = region;
|
|
241
248
|
const assemblyNameString = assemblyName ? `{${assemblyName}}` : '';
|
|
242
249
|
let startString;
|
|
243
250
|
if (start !== undefined) {
|
|
244
|
-
startString = `:${(start + 1)
|
|
251
|
+
startString = `:${cb(start + 1)}`;
|
|
245
252
|
}
|
|
246
253
|
else if (end !== undefined) {
|
|
247
254
|
startString = ':1';
|
|
@@ -251,10 +258,7 @@ function assembleLocString(region) {
|
|
|
251
258
|
}
|
|
252
259
|
let endString;
|
|
253
260
|
if (end !== undefined) {
|
|
254
|
-
endString =
|
|
255
|
-
start !== undefined && start + 1 === end
|
|
256
|
-
? ''
|
|
257
|
-
: `..${end.toLocaleString('en-US')}`;
|
|
261
|
+
endString = start !== undefined && start + 1 === end ? '' : `..${cb(end)}`;
|
|
258
262
|
}
|
|
259
263
|
else {
|
|
260
264
|
endString = start !== undefined ? '..' : '';
|
|
@@ -265,7 +269,7 @@ function assembleLocString(region) {
|
|
|
265
269
|
}
|
|
266
270
|
return `${assemblyNameString}${refName}${startString}${endString}${rev}`;
|
|
267
271
|
}
|
|
268
|
-
exports.
|
|
272
|
+
exports.assembleLocStringFast = assembleLocStringFast;
|
|
269
273
|
function parseLocStringOneBased(locString, isValidRefName) {
|
|
270
274
|
if (!locString) {
|
|
271
275
|
throw new Error('no location string provided, could not parse');
|
|
@@ -649,7 +653,7 @@ function minmax(a, b) {
|
|
|
649
653
|
exports.minmax = minmax;
|
|
650
654
|
function stringify({ refName, coord, oob, }) {
|
|
651
655
|
return refName
|
|
652
|
-
? `${refName}:${coord
|
|
656
|
+
? `${refName}:${toLocale(coord)}${oob ? ' (out of bounds)' : ''}`
|
|
653
657
|
: '';
|
|
654
658
|
}
|
|
655
659
|
exports.stringify = stringify;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { RemoteFile, PolyfilledResponse } from 'generic-filehandle';
|
|
3
|
-
interface BinaryRangeResponse {
|
|
3
|
+
export interface BinaryRangeResponse {
|
|
4
4
|
headers: Record<string, string>;
|
|
5
5
|
requestDate: Date;
|
|
6
6
|
responseDate: Date;
|
|
@@ -14,4 +14,3 @@ export declare class RemoteFileWithRangeCache extends RemoteFile {
|
|
|
14
14
|
signal?: AbortSignal;
|
|
15
15
|
}): Promise<BinaryRangeResponse>;
|
|
16
16
|
}
|
|
17
|
-
export {};
|
|
@@ -9,6 +9,11 @@ export default class GranularRectLayout<T> implements BaseLayout<T> {
|
|
|
9
9
|
private maxHeight;
|
|
10
10
|
private displayMode;
|
|
11
11
|
private pTotalHeight;
|
|
12
|
+
/**
|
|
13
|
+
* pitchX - layout grid pitch in the X direction
|
|
14
|
+
* pitchY - layout grid pitch in the Y direction
|
|
15
|
+
* maxHeight - maximum layout height, default Infinity (no max)
|
|
16
|
+
*/
|
|
12
17
|
constructor({ pitchX, pitchY, maxHeight, hardRowLimit, displayMode, }?: {
|
|
13
18
|
pitchX?: number;
|
|
14
19
|
pitchY?: number;
|
|
@@ -33,9 +38,9 @@ export default class GranularRectLayout<T> implements BaseLayout<T> {
|
|
|
33
38
|
*/
|
|
34
39
|
discardRange(left: number, right: number): void;
|
|
35
40
|
hasSeen(id: string): boolean;
|
|
36
|
-
getByCoord(x: number, y: number): Record<string, T> |
|
|
41
|
+
getByCoord(x: number, y: number): string | Record<string, T> | undefined;
|
|
37
42
|
getByID(id: string): RectTuple | undefined;
|
|
38
|
-
getDataByID(id: string):
|
|
43
|
+
getDataByID(id: string): T | undefined;
|
|
39
44
|
cleanup(): void;
|
|
40
45
|
getTotalHeight(): number;
|
|
41
46
|
get totalHeight(): number;
|
|
@@ -18,66 +18,47 @@ class LayoutRow {
|
|
|
18
18
|
constructor() {
|
|
19
19
|
this.padding = 1;
|
|
20
20
|
this.widthLimit = 1000000;
|
|
21
|
-
// this.rowState.offset is the offset of the bits array relative to the genomic coordinates
|
|
22
|
-
// (modified by pitchX, but we don't know that in this class)
|
|
23
|
-
// this.rowState.bits is the array of items in the layout row, indexed by (x - this.offset)
|
|
24
|
-
// this.rowState.min is the leftmost edge of all the rectangles we have in the layout
|
|
25
|
-
// this.rowState.max is the rightmost edge of all the rectangles we have in the layout
|
|
26
21
|
}
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
22
|
+
// this.rowState.bits is the array of items in the layout row, indexed by (x - this.offset)
|
|
23
|
+
// this.rowState.min is the leftmost edge of all the rectangles we have in the layout
|
|
24
|
+
// this.rowState.max is the rightmost edge of all the rectangles we have in the layout
|
|
25
|
+
// this.rowState.offset is the offset of the bits array relative to the genomic coordinates
|
|
26
|
+
// (modified by pitchX, but we don't know that in this class)
|
|
32
27
|
setAllFilled(data) {
|
|
33
28
|
this.allFilled = data;
|
|
34
29
|
}
|
|
35
30
|
getItemAt(x) {
|
|
31
|
+
var _a;
|
|
36
32
|
if (this.allFilled) {
|
|
37
33
|
return this.allFilled;
|
|
38
34
|
}
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (this.rowState.min === undefined) {
|
|
35
|
+
if (((_a = this.rowState) === null || _a === void 0 ? void 0 : _a.min) === undefined ||
|
|
36
|
+
x < this.rowState.min ||
|
|
37
|
+
x >= this.rowState.max) {
|
|
43
38
|
return undefined;
|
|
44
39
|
}
|
|
45
|
-
|
|
46
|
-
return undefined;
|
|
47
|
-
}
|
|
48
|
-
if (x >= this.rowState.max) {
|
|
49
|
-
return undefined;
|
|
50
|
-
}
|
|
51
|
-
const offset = x - this.rowState.offset;
|
|
52
|
-
// if (offset < 0)
|
|
53
|
-
// debugger
|
|
54
|
-
// if (offset >= this.rowState.bits.length)
|
|
55
|
-
// debugger
|
|
56
|
-
return this.rowState.bits[offset];
|
|
40
|
+
return this.rowState.bits[x - this.rowState.offset];
|
|
57
41
|
}
|
|
58
42
|
isRangeClear(left, right) {
|
|
59
43
|
if (this.allFilled) {
|
|
60
44
|
return false;
|
|
61
45
|
}
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const { min, max } = this.rowState;
|
|
66
|
-
if (right <= min || left >= max) {
|
|
46
|
+
if (this.rowState === undefined ||
|
|
47
|
+
right <= this.rowState.min ||
|
|
48
|
+
left >= this.rowState.max) {
|
|
67
49
|
return true;
|
|
68
50
|
}
|
|
69
|
-
|
|
70
|
-
const maxX = Math.min(max, right);
|
|
71
|
-
let
|
|
72
|
-
for (
|
|
73
|
-
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
51
|
+
const { min, max, offset, bits } = this.rowState;
|
|
52
|
+
const maxX = Math.min(max, right) - offset;
|
|
53
|
+
let flag = true;
|
|
54
|
+
for (let x = Math.max(min, left) - offset; x < maxX && flag; x++) {
|
|
55
|
+
flag = bits[x] === undefined;
|
|
76
56
|
}
|
|
77
|
-
return
|
|
57
|
+
return flag;
|
|
78
58
|
}
|
|
59
|
+
// NOTE: this.rowState.min, this.rowState.max, and this.rowState.offset are
|
|
60
|
+
// interbase coordinates
|
|
79
61
|
initialize(left, right) {
|
|
80
|
-
// NOTE: this.rowState.min, this.rowState.max, and this.rowState.offset are interbase coordinates
|
|
81
62
|
const rectWidth = right - left;
|
|
82
63
|
return {
|
|
83
64
|
offset: left - rectWidth,
|
|
@@ -85,7 +66,6 @@ class LayoutRow {
|
|
|
85
66
|
max: right,
|
|
86
67
|
bits: new Array(3 * rectWidth),
|
|
87
68
|
};
|
|
88
|
-
// this.log(`initialize ${this.rowState.min} - ${this.rowState.max} (${this.rowState.bits.length})`)
|
|
89
69
|
}
|
|
90
70
|
addRect(rect, data) {
|
|
91
71
|
const left = rect.l;
|
|
@@ -220,8 +200,7 @@ class LayoutRow {
|
|
|
220
200
|
}
|
|
221
201
|
}
|
|
222
202
|
class GranularRectLayout {
|
|
223
|
-
|
|
224
|
-
*
|
|
203
|
+
/**
|
|
225
204
|
* pitchX - layout grid pitch in the X direction
|
|
226
205
|
* pitchY - layout grid pitch in the Y direction
|
|
227
206
|
* maxHeight - maximum layout height, default Infinity (no max)
|
|
@@ -296,7 +275,7 @@ class GranularRectLayout {
|
|
|
296
275
|
const maxY = top + rect.h;
|
|
297
276
|
for (let y = top; y < maxY; y += 1) {
|
|
298
277
|
const row = bitmap[y];
|
|
299
|
-
if (row && !row.isRangeClear(rect.l, rect.r)) {
|
|
278
|
+
if (row !== undefined && !row.isRangeClear(rect.l, rect.r)) {
|
|
300
279
|
return true;
|
|
301
280
|
}
|
|
302
281
|
}
|
|
@@ -370,7 +349,12 @@ class GranularRectLayout {
|
|
|
370
349
|
const r = this.rectangles.get(id);
|
|
371
350
|
if (r) {
|
|
372
351
|
const t = r.top * this.pitchY;
|
|
373
|
-
return [
|
|
352
|
+
return [
|
|
353
|
+
r.l * this.pitchX,
|
|
354
|
+
t,
|
|
355
|
+
r.r * this.pitchX,
|
|
356
|
+
t + r.originalHeight,
|
|
357
|
+
];
|
|
374
358
|
}
|
|
375
359
|
return undefined;
|
|
376
360
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { BaseLayout, SerializedLayout } from './BaseLayout';
|
|
2
2
|
export default class MultiLayout<SUB_LAYOUT_CLASS extends BaseLayout<T>, T> {
|
|
3
3
|
SubLayoutClass: new (...args: any[]) => SUB_LAYOUT_CLASS;
|
|
4
|
-
subLayouts: Map<string, SUB_LAYOUT_CLASS>;
|
|
5
4
|
subLayoutConstructorArgs: Record<string, any>;
|
|
5
|
+
subLayouts: Map<string, SUB_LAYOUT_CLASS>;
|
|
6
6
|
/**
|
|
7
7
|
* layout class that just keeps a number of named sub-layouts.
|
|
8
8
|
* basically just a fancier
|
|
9
9
|
* `{ layout1: new GranularRectLayout(), layout2: new GranularRectLayout() ...}`
|
|
10
10
|
*/
|
|
11
|
-
constructor(SubLayoutClass: new (...args: any[]) => SUB_LAYOUT_CLASS,
|
|
11
|
+
constructor(SubLayoutClass: new (...args: any[]) => SUB_LAYOUT_CLASS, subLayoutConstructorArgs?: Record<string, any>);
|
|
12
12
|
getDataByID(id: string): unknown;
|
|
13
13
|
getSublayout(layoutName: string): SUB_LAYOUT_CLASS;
|
|
14
14
|
addRect(layoutName: string, id: string, left: number, right: number, height: number, data?: Record<string, T>): number | null;
|
|
@@ -6,12 +6,10 @@ class MultiLayout {
|
|
|
6
6
|
* basically just a fancier
|
|
7
7
|
* `{ layout1: new GranularRectLayout(), layout2: new GranularRectLayout() ...}`
|
|
8
8
|
*/
|
|
9
|
-
constructor(SubLayoutClass,
|
|
9
|
+
constructor(SubLayoutClass, subLayoutConstructorArgs = {}) {
|
|
10
10
|
this.SubLayoutClass = SubLayoutClass;
|
|
11
|
+
this.subLayoutConstructorArgs = subLayoutConstructorArgs;
|
|
11
12
|
this.subLayouts = new Map();
|
|
12
|
-
this.subLayoutConstructorArgs = {};
|
|
13
|
-
this.subLayouts = new Map();
|
|
14
|
-
this.subLayoutConstructorArgs = layoutArgs;
|
|
15
13
|
}
|
|
16
14
|
getDataByID(id) {
|
|
17
15
|
for (const layout of this.subLayouts.values()) {
|
|
@@ -36,8 +34,8 @@ class MultiLayout {
|
|
|
36
34
|
return this.getSublayout(layoutName).addRect(id, left, right, height, data);
|
|
37
35
|
}
|
|
38
36
|
discardRange(layoutName, left, right) {
|
|
39
|
-
|
|
40
|
-
return
|
|
37
|
+
var _a;
|
|
38
|
+
return (_a = this.subLayouts.get(layoutName)) === null || _a === void 0 ? void 0 : _a.discardRange(left, right);
|
|
41
39
|
}
|
|
42
40
|
toJSON() {
|
|
43
41
|
const data = {};
|
package/util/simpleFeature.d.ts
CHANGED
|
@@ -31,6 +31,9 @@ export interface Feature {
|
|
|
31
31
|
* Get an array of child features, or undefined if none.
|
|
32
32
|
*/
|
|
33
33
|
children(): Feature[] | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Convert to JSON
|
|
36
|
+
*/
|
|
34
37
|
toJSON(): SimpleFeatureSerialized;
|
|
35
38
|
}
|
|
36
39
|
export declare function isFeature(thing: unknown): thing is Feature;
|
package/util/stats.d.ts
CHANGED
|
@@ -14,8 +14,34 @@ export interface FeatureStats extends UnrectifiedFeatureStats {
|
|
|
14
14
|
scoreMean: number;
|
|
15
15
|
scoreStdDev: number;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* calculate standard deviation using the 'shortcut method' that accepts
|
|
19
|
+
* the sum and the sum squares of the elements
|
|
20
|
+
*
|
|
21
|
+
* @param sum - sum(i, 1..n)
|
|
22
|
+
* @param sumSquares - sum(i^2, 1..n)
|
|
23
|
+
* @param n - number of elements
|
|
24
|
+
* @param population - boolean: use population instead of sample correction
|
|
25
|
+
* @returns - the estimated std deviation
|
|
26
|
+
*/
|
|
17
27
|
export declare function calcStdFromSums(sum: number, sumSquares: number, n: number, population?: boolean): number;
|
|
28
|
+
/**
|
|
29
|
+
* @param stats - a summary stats object with scoreSum, featureCount, scoreSumSquares, and basesCovered
|
|
30
|
+
* @returns - a summary stats object with scoreMean, scoreStdDev, and featureDensity added
|
|
31
|
+
*/
|
|
18
32
|
export declare function rectifyStats(s: UnrectifiedFeatureStats): FeatureStats;
|
|
33
|
+
/**
|
|
34
|
+
* calculates per-base scores for variable width features over a region
|
|
35
|
+
* @param region - object contains start, end
|
|
36
|
+
* @param features - list of features with start, end, score
|
|
37
|
+
* @returns array of numeric scores
|
|
38
|
+
*/
|
|
19
39
|
export declare function calcPerBaseStats(region: NoAssemblyRegion, features: Feature[]): number[];
|
|
40
|
+
/**
|
|
41
|
+
* transform a list of scores to summary statistics
|
|
42
|
+
* @param region - object with start, end
|
|
43
|
+
* @param features - array of features which are possibly summary features
|
|
44
|
+
* @returns - object with scoreMax, scoreMin, scoreSum, scoreSumSquares, etc
|
|
45
|
+
*/
|
|
20
46
|
export declare function scoresToStats(region: NoAssemblyRegion, features: Observable<Feature>): Promise<FeatureStats>;
|
|
21
47
|
export declare function blankStats(): FeatureStats;
|
package/util/stats.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.blankStats = exports.scoresToStats = exports.calcPerBaseStats = exports.rectifyStats = exports.calcStdFromSums = void 0;
|
|
4
4
|
const operators_1 = require("rxjs/operators");
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
6
|
* calculate standard deviation using the 'shortcut method' that accepts
|
|
7
7
|
* the sum and the sum squares of the elements
|
|
8
8
|
*
|
|
@@ -10,7 +10,7 @@ const operators_1 = require("rxjs/operators");
|
|
|
10
10
|
* @param sumSquares - sum(i^2, 1..n)
|
|
11
11
|
* @param n - number of elements
|
|
12
12
|
* @param population - boolean: use population instead of sample correction
|
|
13
|
-
* @
|
|
13
|
+
* @returns - the estimated std deviation
|
|
14
14
|
*/
|
|
15
15
|
function calcStdFromSums(sum, sumSquares, n, population = false) {
|
|
16
16
|
if (n === 0) {
|
|
@@ -30,9 +30,9 @@ function calcStdFromSums(sum, sumSquares, n, population = false) {
|
|
|
30
30
|
return variance < 0 ? 0 : Math.sqrt(variance);
|
|
31
31
|
}
|
|
32
32
|
exports.calcStdFromSums = calcStdFromSums;
|
|
33
|
-
|
|
33
|
+
/**
|
|
34
34
|
* @param stats - a summary stats object with scoreSum, featureCount, scoreSumSquares, and basesCovered
|
|
35
|
-
* @
|
|
35
|
+
* @returns - a summary stats object with scoreMean, scoreStdDev, and featureDensity added
|
|
36
36
|
*/
|
|
37
37
|
function rectifyStats(s) {
|
|
38
38
|
return {
|
|
@@ -43,11 +43,11 @@ function rectifyStats(s) {
|
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
exports.rectifyStats = rectifyStats;
|
|
46
|
-
|
|
46
|
+
/**
|
|
47
47
|
* calculates per-base scores for variable width features over a region
|
|
48
48
|
* @param region - object contains start, end
|
|
49
49
|
* @param features - list of features with start, end, score
|
|
50
|
-
* @
|
|
50
|
+
* @returns array of numeric scores
|
|
51
51
|
*/
|
|
52
52
|
function calcPerBaseStats(region, features) {
|
|
53
53
|
const { start, end } = region;
|
|
@@ -76,11 +76,11 @@ function calcPerBaseStats(region, features) {
|
|
|
76
76
|
return scores;
|
|
77
77
|
}
|
|
78
78
|
exports.calcPerBaseStats = calcPerBaseStats;
|
|
79
|
-
|
|
79
|
+
/**
|
|
80
80
|
* transform a list of scores to summary statistics
|
|
81
81
|
* @param region - object with start, end
|
|
82
|
-
* @param
|
|
83
|
-
* @
|
|
82
|
+
* @param features - array of features which are possibly summary features
|
|
83
|
+
* @returns - object with scoreMax, scoreMin, scoreSum, scoreSumSquares, etc
|
|
84
84
|
*/
|
|
85
85
|
async function scoresToStats(region, features) {
|
|
86
86
|
const { start, end } = region;
|