@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.
- package/BaseFeatureWidget/BaseFeatureDetail.d.ts +2 -1
- package/BaseFeatureWidget/BaseFeatureDetail.js +16 -17
- package/BaseFeatureWidget/SequenceBox.d.ts +29 -0
- package/BaseFeatureWidget/SequenceBox.js +61 -0
- package/BaseFeatureWidget/SequenceFeatureDetails.d.ts +1 -10
- package/BaseFeatureWidget/SequenceFeatureDetails.js +100 -152
- package/BaseFeatureWidget/SequenceHelpDialog.d.ts +4 -0
- package/BaseFeatureWidget/SequenceHelpDialog.js +51 -0
- package/BaseFeatureWidget/SequencePanel.d.ts +10 -0
- package/BaseFeatureWidget/SequencePanel.js +72 -0
- package/BaseFeatureWidget/index.d.ts +7 -0
- package/BaseFeatureWidget/index.js +21 -5
- package/BaseFeatureWidget/util.d.ts +11 -0
- package/BaseFeatureWidget/util.js +13 -1
- package/PluginLoader.d.ts +29 -13
- package/PluginLoader.js +47 -77
- package/PluginManager.d.ts +1 -0
- package/PluginManager.js +9 -3
- package/assemblyManager/assembly.d.ts +8 -15
- package/assemblyManager/assembly.js +14 -17
- package/assemblyManager/assemblyManager.d.ts +37 -86
- package/configuration/configurationSlot.js +2 -1
- package/data_adapters/CytobandAdapter.js +1 -1
- package/package.json +3 -3
- package/pluggableElementTypes/models/BaseDisplayModel.d.ts +1 -1
- package/pluggableElementTypes/models/BaseDisplayModel.js +3 -2
- package/pluggableElementTypes/models/BaseTrackModel.d.ts +1 -1
- package/pluggableElementTypes/models/BaseTrackModel.js +1 -1
- package/pluggableElementTypes/models/baseTrackConfig.js +16 -4
- package/rpc/RpcManager.d.ts +1 -1
- package/rpc/RpcManager.js +4 -1
- package/rpc/WebWorkerRpcDriver.d.ts +2 -0
- package/rpc/WebWorkerRpcDriver.js +21 -11
- package/rpc/configSchema.js +4 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/ui/AboutDialog.d.ts +6 -0
- package/ui/AboutDialog.js +42 -20
- package/ui/App.js +2 -2
- package/ui/DrawerWidget.js +9 -7
- package/ui/FatalErrorDialog.d.ts +6 -22
- package/ui/FatalErrorDialog.js +10 -29
- package/util/index.d.ts +4 -0
- package/util/index.js +5 -1
- package/util/stats.js +7 -5
- package/util/tracks.d.ts +5 -2
- package/util/tracks.js +15 -5
|
@@ -0,0 +1,72 @@
|
|
|
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 util_1 = require("../util");
|
|
8
|
+
const util_2 = require("./util");
|
|
9
|
+
const SequenceBox_1 = require("./SequenceBox");
|
|
10
|
+
const SequencePanel = react_1.default.forwardRef((props, ref) => {
|
|
11
|
+
const { feature, mode, intronBp = 10 } = props;
|
|
12
|
+
let { sequence: { seq, upstream = '', downstream = '' }, } = props;
|
|
13
|
+
const { subfeatures = [] } = feature;
|
|
14
|
+
const children = subfeatures
|
|
15
|
+
.sort((a, b) => a.start - b.start)
|
|
16
|
+
.map(sub => ({
|
|
17
|
+
...sub,
|
|
18
|
+
start: sub.start - feature.start,
|
|
19
|
+
end: sub.end - feature.start,
|
|
20
|
+
}));
|
|
21
|
+
// we filter duplicate entries in cds and exon lists duplicate entries may be
|
|
22
|
+
// rare but was seen in Gencode v36 track NCList, likely a bug on GFF3 or
|
|
23
|
+
// probably worth ignoring here (produces broken protein translations if
|
|
24
|
+
// included)
|
|
25
|
+
//
|
|
26
|
+
// position 1:224,800,006..225,203,064 gene ENSG00000185842.15 first
|
|
27
|
+
// transcript ENST00000445597.6
|
|
28
|
+
//
|
|
29
|
+
// http://localhost:3000/?config=test_data%2Fconfig.json&session=share-FUl7G1isvF&password=HXh5Y
|
|
30
|
+
let cds = (0, util_2.dedupe)(children.filter(sub => sub.type === 'CDS'));
|
|
31
|
+
let utr = (0, util_2.dedupe)(children.filter(sub => sub.type.match(/utr/i)));
|
|
32
|
+
let exons = (0, util_2.dedupe)(children.filter(sub => sub.type === 'exon'));
|
|
33
|
+
if (!utr.length && cds.length && exons.length) {
|
|
34
|
+
utr = (0, util_2.calculateUTRs)(cds, exons);
|
|
35
|
+
}
|
|
36
|
+
if (!utr.length && cds.length && !exons.length) {
|
|
37
|
+
utr = (0, util_2.calculateUTRs2)(cds, {
|
|
38
|
+
start: 0,
|
|
39
|
+
end: feature.end - feature.start,
|
|
40
|
+
type: 'gene',
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (feature.strand === -1) {
|
|
44
|
+
// doing this in a single assignment is needed because downstream and
|
|
45
|
+
// upstream are swapped so this avoids a temp variable
|
|
46
|
+
;
|
|
47
|
+
[seq, upstream, downstream] = [
|
|
48
|
+
(0, util_1.revcom)(seq),
|
|
49
|
+
(0, util_1.revcom)(downstream),
|
|
50
|
+
(0, util_1.revcom)(upstream),
|
|
51
|
+
];
|
|
52
|
+
cds = (0, util_2.revlist)(cds, seq.length);
|
|
53
|
+
exons = (0, util_2.revlist)(exons, seq.length);
|
|
54
|
+
utr = (0, util_2.revlist)(utr, seq.length);
|
|
55
|
+
}
|
|
56
|
+
const codonTable = (0, util_1.generateCodonTable)(util_1.defaultCodonTable);
|
|
57
|
+
return (react_1.default.createElement("div", { ref: ref, "data-testid": "sequence_panel" },
|
|
58
|
+
react_1.default.createElement("div", { style: {
|
|
59
|
+
fontFamily: 'monospace',
|
|
60
|
+
wordWrap: 'break-word',
|
|
61
|
+
overflow: 'auto',
|
|
62
|
+
fontSize: 12,
|
|
63
|
+
maxWidth: 600,
|
|
64
|
+
maxHeight: 500,
|
|
65
|
+
} },
|
|
66
|
+
`>${feature.name ||
|
|
67
|
+
feature.id ||
|
|
68
|
+
feature.refName + ':' + (feature.start + 1) + '-' + feature.end}-${mode}\n`,
|
|
69
|
+
react_1.default.createElement("br", null),
|
|
70
|
+
mode === 'genomic' ? (react_1.default.createElement(SequenceBox_1.Genomic, { sequence: seq })) : mode === 'genomic_sequence_updown' ? (react_1.default.createElement(SequenceBox_1.Genomic, { sequence: seq, upstream: upstream, downstream: downstream })) : mode === 'cds' ? (react_1.default.createElement(SequenceBox_1.GeneCDS, { cds: cds, sequence: seq })) : mode === 'cdna' ? (react_1.default.createElement(SequenceBox_1.GenecDNA, { exons: exons, cds: cds, utr: utr, sequence: seq, intronBp: intronBp })) : mode === 'protein' ? (react_1.default.createElement(SequenceBox_1.GeneProtein, { cds: cds, codonTable: codonTable, sequence: seq })) : mode === 'gene' ? (react_1.default.createElement(SequenceBox_1.GenecDNA, { exons: exons, cds: cds, utr: utr, sequence: seq, includeIntrons: true, intronBp: intronBp })) : mode === 'gene_collapsed_intron' ? (react_1.default.createElement(SequenceBox_1.GenecDNA, { exons: exons, cds: cds, sequence: seq, utr: utr, includeIntrons: true, collapseIntron: true, intronBp: intronBp })) : mode === 'gene_updownstream' ? (react_1.default.createElement(SequenceBox_1.GenecDNA, { exons: exons, cds: cds, sequence: seq, utr: utr, upstream: upstream, downstream: downstream, includeIntrons: true, intronBp: intronBp })) : mode === 'gene_updownstream_collapsed_intron' ? (react_1.default.createElement(SequenceBox_1.GenecDNA, { exons: exons, cds: cds, sequence: seq, utr: utr, upstream: upstream, downstream: downstream, includeIntrons: true, collapseIntron: true, intronBp: intronBp })) : (react_1.default.createElement("div", null, "Unknown type")))));
|
|
71
|
+
});
|
|
72
|
+
exports.default = SequencePanel;
|
|
@@ -8,10 +8,13 @@ export default function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
8
8
|
unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
|
|
9
9
|
view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
10
10
|
track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
11
|
+
trackId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
12
|
+
trackType: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
11
13
|
}, {
|
|
12
14
|
setFeatureData(featureData: Record<string, unknown>): void;
|
|
13
15
|
clearFeatureData(): void;
|
|
14
16
|
setFormattedData(feat: Record<string, unknown>): void;
|
|
17
|
+
setExtra(type?: string, trackId?: string): void;
|
|
15
18
|
} & {
|
|
16
19
|
afterCreate(): void;
|
|
17
20
|
}, import("mobx-state-tree").ModelCreationType<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
|
|
@@ -22,11 +25,15 @@ export default function stateModelFactory(pluginManager: PluginManager): import(
|
|
|
22
25
|
unformattedFeatureData: import("mobx-state-tree").IType<any, any, any>;
|
|
23
26
|
view: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
24
27
|
track: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IReferenceType<import("mobx-state-tree").IAnyType>>;
|
|
28
|
+
trackId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
29
|
+
trackType: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
|
|
25
30
|
}>>, {
|
|
26
31
|
id: string;
|
|
27
32
|
type: "BaseFeatureWidget";
|
|
28
33
|
track: import("mobx-state-tree").ReferenceIdentifier | undefined;
|
|
29
34
|
view: import("mobx-state-tree").ReferenceIdentifier | undefined;
|
|
35
|
+
trackId: string | undefined;
|
|
36
|
+
trackType: string | undefined;
|
|
30
37
|
formattedFields: any;
|
|
31
38
|
finalizedFeatureData: any;
|
|
32
39
|
}>;
|
|
@@ -6,8 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.stateModelFactory = exports.configSchema = void 0;
|
|
7
7
|
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
8
8
|
const mobx_1 = require("mobx");
|
|
9
|
-
const configuration_1 = require("../configuration");
|
|
10
9
|
const clone_1 = __importDefault(require("clone"));
|
|
10
|
+
const configuration_1 = require("../configuration");
|
|
11
|
+
const util_1 = require("../util");
|
|
11
12
|
const mst_1 = require("../util/types/mst");
|
|
12
13
|
const configSchema = (0, configuration_1.ConfigurationSchema)('BaseFeatureWidget', {});
|
|
13
14
|
exports.configSchema = configSchema;
|
|
@@ -32,8 +33,9 @@ function stateModelFactory(pluginManager) {
|
|
|
32
33
|
unformattedFeatureData: mobx_state_tree_1.types.frozen(),
|
|
33
34
|
view: mobx_state_tree_1.types.safeReference(pluginManager.pluggableMstType('view', 'stateModel')),
|
|
34
35
|
track: mobx_state_tree_1.types.safeReference(pluginManager.pluggableMstType('track', 'stateModel')),
|
|
36
|
+
trackId: mobx_state_tree_1.types.maybe(mobx_state_tree_1.types.string),
|
|
37
|
+
trackType: mobx_state_tree_1.types.maybe(mobx_state_tree_1.types.string),
|
|
35
38
|
})
|
|
36
|
-
.volatile(() => ({}))
|
|
37
39
|
.actions(self => ({
|
|
38
40
|
setFeatureData(featureData) {
|
|
39
41
|
self.unformattedFeatureData = featureData;
|
|
@@ -44,20 +46,34 @@ function stateModelFactory(pluginManager) {
|
|
|
44
46
|
setFormattedData(feat) {
|
|
45
47
|
self.featureData = feat;
|
|
46
48
|
},
|
|
49
|
+
setExtra(type, trackId) {
|
|
50
|
+
self.trackId = trackId;
|
|
51
|
+
self.trackType = type;
|
|
52
|
+
},
|
|
47
53
|
}))
|
|
48
54
|
.actions(self => ({
|
|
49
55
|
afterCreate() {
|
|
50
56
|
(0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
|
|
57
|
+
var _a, _b;
|
|
58
|
+
self.setExtra((_a = self.track) === null || _a === void 0 ? void 0 : _a.type, (_b = self.track) === null || _b === void 0 ? void 0 : _b.configuration.trackId);
|
|
51
59
|
const { unformattedFeatureData, track } = self;
|
|
60
|
+
const session = (0, util_1.getSession)(self);
|
|
52
61
|
if (unformattedFeatureData) {
|
|
53
62
|
const feature = (0, clone_1.default)(unformattedFeatureData);
|
|
63
|
+
const f = (obj, arg2) => (0, configuration_1.getConf)(obj, ['formatDetails', arg2], { feature });
|
|
54
64
|
if (track) {
|
|
55
65
|
// eslint-disable-next-line no-underscore-dangle
|
|
56
|
-
feature.__jbrowsefmt =
|
|
66
|
+
feature.__jbrowsefmt = {
|
|
67
|
+
...f(session, 'feature'),
|
|
68
|
+
...f(track, 'feature'),
|
|
69
|
+
};
|
|
57
70
|
const depth = (0, configuration_1.getConf)(track, ['formatDetails', 'depth']);
|
|
58
|
-
formatSubfeatures(feature, depth,
|
|
71
|
+
formatSubfeatures(feature, depth, sub => {
|
|
59
72
|
// eslint-disable-next-line no-underscore-dangle
|
|
60
|
-
|
|
73
|
+
sub.__jbrowsefmt = {
|
|
74
|
+
...f(session, 'subfeature'),
|
|
75
|
+
...f(track, 'subfeature'),
|
|
76
|
+
};
|
|
61
77
|
});
|
|
62
78
|
}
|
|
63
79
|
self.setFormattedData(feature);
|
|
@@ -6,14 +6,20 @@ export interface Feat {
|
|
|
6
6
|
id?: string;
|
|
7
7
|
}
|
|
8
8
|
export interface ParentFeat extends Feat {
|
|
9
|
+
uniqueId: string;
|
|
9
10
|
strand?: number;
|
|
11
|
+
refName: string;
|
|
10
12
|
subfeatures?: Feat[];
|
|
13
|
+
parentId?: string;
|
|
11
14
|
}
|
|
12
15
|
export interface SeqState {
|
|
13
16
|
seq: string;
|
|
14
17
|
upstream?: string;
|
|
15
18
|
downstream?: string;
|
|
16
19
|
}
|
|
20
|
+
export interface ErrorState {
|
|
21
|
+
error: string;
|
|
22
|
+
}
|
|
17
23
|
export declare function stitch(subfeats: Feat[], sequence: string): string;
|
|
18
24
|
export declare function dedupe(list: Feat[]): Feat[];
|
|
19
25
|
export declare function revlist(list: Feat[], seqlen: number): {
|
|
@@ -28,4 +34,9 @@ export declare function calculateUTRs(cds: Feat[], exons: Feat[]): {
|
|
|
28
34
|
start: number;
|
|
29
35
|
end: number;
|
|
30
36
|
}[];
|
|
37
|
+
export declare function calculateUTRs2(cds: Feat[], parentFeat: Feat): {
|
|
38
|
+
type: string;
|
|
39
|
+
start: number;
|
|
40
|
+
end: number;
|
|
41
|
+
}[];
|
|
31
42
|
export declare function ellipses(slug: string): string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ellipses = exports.calculateUTRs = exports.revlist = exports.dedupe = exports.stitch = void 0;
|
|
3
|
+
exports.ellipses = exports.calculateUTRs2 = exports.calculateUTRs = exports.revlist = exports.dedupe = exports.stitch = void 0;
|
|
4
4
|
function stitch(subfeats, sequence) {
|
|
5
5
|
return subfeats.map(sub => sequence.slice(sub.start, sub.end)).join('');
|
|
6
6
|
}
|
|
@@ -43,6 +43,18 @@ function calculateUTRs(cds, exons) {
|
|
|
43
43
|
return [...fiveUTRs, ...threeUTRs];
|
|
44
44
|
}
|
|
45
45
|
exports.calculateUTRs = calculateUTRs;
|
|
46
|
+
// calculates UTRs using impliedUTRs logic, but there are no exon subfeatures
|
|
47
|
+
function calculateUTRs2(cds, parentFeat) {
|
|
48
|
+
const firstCds = cds[0];
|
|
49
|
+
const lastCds = cds[cds.length - 1];
|
|
50
|
+
const fiveUTRs = [{ start: parentFeat.start, end: firstCds.start }].map(elt => ({ ...elt, type: 'five_prime_UTR' }));
|
|
51
|
+
const threeUTRs = [{ start: lastCds.end, end: parentFeat.end }].map(elt => ({
|
|
52
|
+
...elt,
|
|
53
|
+
type: 'three_prime_UTR',
|
|
54
|
+
}));
|
|
55
|
+
return [...fiveUTRs, ...threeUTRs];
|
|
56
|
+
}
|
|
57
|
+
exports.calculateUTRs2 = calculateUTRs2;
|
|
46
58
|
function ellipses(slug) {
|
|
47
59
|
return slug.length > 20 ? `${slug.slice(0, 20)}...` : slug;
|
|
48
60
|
}
|
package/PluginLoader.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { PluginConstructor } from './Plugin';
|
|
2
|
-
export
|
|
3
|
-
|
|
2
|
+
export interface UMDLocPluginDefinition {
|
|
3
|
+
umdLoc: {
|
|
4
|
+
uri: string;
|
|
5
|
+
baseUri?: string;
|
|
6
|
+
};
|
|
7
|
+
name: string;
|
|
8
|
+
}
|
|
9
|
+
export interface UMDUrlPluginDefinition {
|
|
4
10
|
umdUrl: string;
|
|
5
11
|
name: string;
|
|
6
12
|
}
|
|
@@ -8,16 +14,24 @@ export interface LegacyUMDPluginDefinition {
|
|
|
8
14
|
url: string;
|
|
9
15
|
name: string;
|
|
10
16
|
}
|
|
11
|
-
|
|
12
|
-
export
|
|
17
|
+
declare type UMDPluginDefinition = UMDLocPluginDefinition | UMDUrlPluginDefinition;
|
|
18
|
+
export declare function isUMDPluginDefinition(def: PluginDefinition): def is UMDPluginDefinition | LegacyUMDPluginDefinition;
|
|
19
|
+
export interface ESMLocPluginDefinition {
|
|
20
|
+
esmLoc: {
|
|
21
|
+
uri: string;
|
|
22
|
+
baseUri?: string;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export interface ESMUrlPluginDefinition {
|
|
13
26
|
esmUrl: string;
|
|
14
27
|
}
|
|
15
|
-
export declare
|
|
28
|
+
export declare type ESMPluginDefinition = ESMLocPluginDefinition | ESMUrlPluginDefinition;
|
|
29
|
+
export declare function isESMPluginDefinition(def: PluginDefinition): def is ESMPluginDefinition;
|
|
16
30
|
export interface CJSPluginDefinition {
|
|
17
31
|
cjsUrl: string;
|
|
18
32
|
}
|
|
19
|
-
export declare function isCJSPluginDefinition(
|
|
20
|
-
export interface PluginDefinition extends Partial<
|
|
33
|
+
export declare function isCJSPluginDefinition(def: PluginDefinition): def is CJSPluginDefinition;
|
|
34
|
+
export interface PluginDefinition extends Partial<UMDUrlPluginDefinition>, Partial<UMDLocPluginDefinition>, Partial<LegacyUMDPluginDefinition>, Partial<ESMLocPluginDefinition>, Partial<ESMUrlPluginDefinition>, Partial<CJSPluginDefinition> {
|
|
21
35
|
}
|
|
22
36
|
export interface PluginRecord {
|
|
23
37
|
plugin: PluginConstructor;
|
|
@@ -26,24 +40,26 @@ export interface PluginRecord {
|
|
|
26
40
|
export interface LoadedPlugin {
|
|
27
41
|
default: PluginConstructor;
|
|
28
42
|
}
|
|
43
|
+
export declare function getWindowPath(windowHref: string): string;
|
|
29
44
|
export default class PluginLoader {
|
|
30
45
|
definitions: PluginDefinition[];
|
|
31
46
|
fetchESM?: (url: string) => Promise<unknown>;
|
|
32
47
|
fetchCJS?: (url: string) => Promise<LoadedPlugin>;
|
|
33
|
-
constructor(
|
|
48
|
+
constructor(defs?: PluginDefinition[], args?: {
|
|
34
49
|
fetchESM?: (url: string) => Promise<unknown>;
|
|
35
50
|
fetchCJS?: (url: string) => Promise<LoadedPlugin>;
|
|
36
51
|
});
|
|
37
52
|
loadScript(scriptUrl: string): Promise<void>;
|
|
38
|
-
loadCJSPlugin(
|
|
39
|
-
loadESMPlugin(
|
|
40
|
-
loadUMDPlugin(
|
|
53
|
+
loadCJSPlugin(def: CJSPluginDefinition, windowHref: string): Promise<LoadedPlugin>;
|
|
54
|
+
loadESMPlugin(def: ESMPluginDefinition, windowHref: string): Promise<LoadedPlugin>;
|
|
55
|
+
loadUMDPlugin(def: UMDPluginDefinition | LegacyUMDPluginDefinition, windowHref: string): Promise<{
|
|
41
56
|
default: PluginConstructor;
|
|
42
57
|
}>;
|
|
43
|
-
loadPlugin(
|
|
58
|
+
loadPlugin(def: PluginDefinition, windowHref: string): Promise<PluginConstructor>;
|
|
44
59
|
installGlobalReExports(target: WindowOrWorkerGlobalScope): void;
|
|
45
|
-
load(): Promise<{
|
|
60
|
+
load(windowHref?: string): Promise<{
|
|
46
61
|
plugin: PluginConstructor;
|
|
47
62
|
definition: PluginDefinition;
|
|
48
63
|
}[]>;
|
|
49
64
|
}
|
|
65
|
+
export {};
|
package/PluginLoader.js
CHANGED
|
@@ -3,36 +3,30 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.getWindowPath = exports.isCJSPluginDefinition = exports.isESMPluginDefinition = exports.isUMDPluginDefinition = void 0;
|
|
7
7
|
const load_script2_1 = __importDefault(require("load-script2"));
|
|
8
|
-
const configuration_1 = require("./configuration");
|
|
9
8
|
const ReExports_1 = __importDefault(require("./ReExports"));
|
|
10
9
|
const util_1 = require("./util");
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
url: {
|
|
17
|
-
type: 'string',
|
|
18
|
-
defaultValue: '',
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
function isUMDPluginDefinition(pluginDefinition) {
|
|
22
|
-
return ((pluginDefinition.umdUrl !== undefined ||
|
|
23
|
-
pluginDefinition.url !== undefined) &&
|
|
24
|
-
pluginDefinition
|
|
25
|
-
.name !== undefined);
|
|
10
|
+
function isUMDPluginDefinition(def) {
|
|
11
|
+
return ((def.umdUrl !== undefined ||
|
|
12
|
+
def.url !== undefined ||
|
|
13
|
+
def.umdLoc !== undefined) &&
|
|
14
|
+
def.name !== undefined);
|
|
26
15
|
}
|
|
27
16
|
exports.isUMDPluginDefinition = isUMDPluginDefinition;
|
|
28
|
-
function isESMPluginDefinition(
|
|
29
|
-
return
|
|
17
|
+
function isESMPluginDefinition(def) {
|
|
18
|
+
return (def.esmUrl !== undefined ||
|
|
19
|
+
def.esmLoc !== undefined);
|
|
30
20
|
}
|
|
31
21
|
exports.isESMPluginDefinition = isESMPluginDefinition;
|
|
32
|
-
function isCJSPluginDefinition(
|
|
33
|
-
return
|
|
22
|
+
function isCJSPluginDefinition(def) {
|
|
23
|
+
return def.cjsUrl !== undefined;
|
|
34
24
|
}
|
|
35
25
|
exports.isCJSPluginDefinition = isCJSPluginDefinition;
|
|
26
|
+
function getWindowPath(windowHref) {
|
|
27
|
+
return window.location.href + windowHref;
|
|
28
|
+
}
|
|
29
|
+
exports.getWindowPath = getWindowPath;
|
|
36
30
|
function getGlobalObject() {
|
|
37
31
|
// Based on window-or-global
|
|
38
32
|
// https://github.com/purposeindustries/window-or-global/blob/322abc71de0010c9e5d9d0729df40959e1ef8775/lib/index.js
|
|
@@ -47,42 +41,27 @@ function isInWebWorker(globalObject) {
|
|
|
47
41
|
return Boolean('WorkerGlobalScope' in globalObject);
|
|
48
42
|
}
|
|
49
43
|
class PluginLoader {
|
|
50
|
-
constructor(
|
|
44
|
+
constructor(defs = [], args) {
|
|
51
45
|
this.definitions = [];
|
|
52
46
|
this.fetchESM = args === null || args === void 0 ? void 0 : args.fetchESM;
|
|
53
47
|
this.fetchCJS = args === null || args === void 0 ? void 0 : args.fetchCJS;
|
|
54
|
-
this.definitions = JSON.parse(JSON.stringify(
|
|
48
|
+
this.definitions = JSON.parse(JSON.stringify(defs));
|
|
55
49
|
}
|
|
56
|
-
loadScript(scriptUrl) {
|
|
50
|
+
async loadScript(scriptUrl) {
|
|
57
51
|
const globalObject = getGlobalObject();
|
|
58
52
|
if (!isInWebWorker(globalObject)) {
|
|
59
53
|
return (0, load_script2_1.default)(scriptUrl);
|
|
60
54
|
}
|
|
61
55
|
// @ts-ignore
|
|
62
|
-
if (globalObject
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
globalObject.importScripts(scriptUrl);
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
reject(error || new Error(`failed to load ${scriptUrl}`));
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
resolve();
|
|
73
|
-
});
|
|
56
|
+
if (globalObject === null || globalObject === void 0 ? void 0 : globalObject.importScripts) {
|
|
57
|
+
// @ts-ignore
|
|
58
|
+
await globalObject.importScripts(scriptUrl);
|
|
59
|
+
return;
|
|
74
60
|
}
|
|
75
61
|
throw new Error('cannot figure out how to load external JS scripts in this environment');
|
|
76
62
|
}
|
|
77
|
-
async loadCJSPlugin(
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
parsedUrl = new URL(cjsUrl, getGlobalObject().location.href);
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
console.error(error);
|
|
84
|
-
throw new Error(`Error parsing URL: ${cjsUrl}`);
|
|
85
|
-
}
|
|
63
|
+
async loadCJSPlugin(def, windowHref) {
|
|
64
|
+
const parsedUrl = new URL(def.cjsUrl, windowHref);
|
|
86
65
|
if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
|
|
87
66
|
throw new Error(`Cannot load plugins using protocol "${parsedUrl.protocol}"`);
|
|
88
67
|
}
|
|
@@ -91,16 +70,11 @@ class PluginLoader {
|
|
|
91
70
|
}
|
|
92
71
|
return this.fetchCJS(parsedUrl.href);
|
|
93
72
|
}
|
|
94
|
-
async loadESMPlugin(
|
|
73
|
+
async loadESMPlugin(def, windowHref) {
|
|
95
74
|
var _a;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
console.error(error);
|
|
102
|
-
throw new Error(`Error parsing URL: ${pluginDefinition.esmUrl}`);
|
|
103
|
-
}
|
|
75
|
+
const parsedUrl = 'esmUrl' in def
|
|
76
|
+
? new URL(def.esmUrl, windowHref)
|
|
77
|
+
: new URL(def.esmLoc.uri, def.esmLoc.baseUri);
|
|
104
78
|
if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
|
|
105
79
|
throw new Error(`cannot load plugins using protocol "${parsedUrl.protocol}"`);
|
|
106
80
|
}
|
|
@@ -110,21 +84,17 @@ class PluginLoader {
|
|
|
110
84
|
}
|
|
111
85
|
return plugin;
|
|
112
86
|
}
|
|
113
|
-
async loadUMDPlugin(
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
catch (error) {
|
|
120
|
-
console.error(error);
|
|
121
|
-
throw new Error(`Error parsing URL: ${umdUrl}`);
|
|
122
|
-
}
|
|
87
|
+
async loadUMDPlugin(def, windowHref) {
|
|
88
|
+
const parsedUrl = 'url' in def
|
|
89
|
+
? new URL(def.url, windowHref)
|
|
90
|
+
: 'umdUrl' in def
|
|
91
|
+
? new URL(def.umdUrl, windowHref)
|
|
92
|
+
: new URL(def.umdLoc.uri, def.umdLoc.baseUri);
|
|
123
93
|
if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
|
|
124
94
|
throw new Error(`cannot load plugins using protocol "${parsedUrl.protocol}"`);
|
|
125
95
|
}
|
|
126
96
|
await this.loadScript(parsedUrl.href);
|
|
127
|
-
const moduleName =
|
|
97
|
+
const moduleName = def.name;
|
|
128
98
|
const umdName = `JBrowsePlugin${moduleName}`;
|
|
129
99
|
const globalObject = getGlobalObject();
|
|
130
100
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -134,22 +104,22 @@ class PluginLoader {
|
|
|
134
104
|
}
|
|
135
105
|
return plugin;
|
|
136
106
|
}
|
|
137
|
-
async loadPlugin(
|
|
107
|
+
async loadPlugin(def, windowHref) {
|
|
138
108
|
let plugin;
|
|
139
|
-
if (util_1.isElectron && isCJSPluginDefinition(
|
|
140
|
-
plugin = await this.loadCJSPlugin(
|
|
109
|
+
if (util_1.isElectron && isCJSPluginDefinition(def)) {
|
|
110
|
+
plugin = await this.loadCJSPlugin(def, windowHref);
|
|
141
111
|
}
|
|
142
|
-
else if (isESMPluginDefinition(
|
|
143
|
-
plugin = await this.loadESMPlugin(
|
|
112
|
+
else if (isESMPluginDefinition(def)) {
|
|
113
|
+
plugin = await this.loadESMPlugin(def, windowHref);
|
|
144
114
|
}
|
|
145
|
-
else if (isUMDPluginDefinition(
|
|
146
|
-
plugin = await this.loadUMDPlugin(
|
|
115
|
+
else if (isUMDPluginDefinition(def)) {
|
|
116
|
+
plugin = await this.loadUMDPlugin(def, windowHref);
|
|
147
117
|
}
|
|
148
|
-
else if (!util_1.isElectron && isCJSPluginDefinition(
|
|
149
|
-
throw new Error(`
|
|
118
|
+
else if (!util_1.isElectron && isCJSPluginDefinition(def)) {
|
|
119
|
+
throw new Error(`CommonJS plugin found, but not in a NodeJS environment: ${JSON.stringify(def)}`);
|
|
150
120
|
}
|
|
151
121
|
else {
|
|
152
|
-
throw new Error(`Could not determine plugin type: ${JSON.stringify(
|
|
122
|
+
throw new Error(`Could not determine plugin type: ${JSON.stringify(def)}`);
|
|
153
123
|
}
|
|
154
124
|
return plugin.default;
|
|
155
125
|
}
|
|
@@ -159,9 +129,9 @@ class PluginLoader {
|
|
|
159
129
|
return [moduleName, module];
|
|
160
130
|
}));
|
|
161
131
|
}
|
|
162
|
-
async load() {
|
|
132
|
+
async load(windowHref = '') {
|
|
163
133
|
return Promise.all(this.definitions.map(async (definition) => ({
|
|
164
|
-
plugin: await this.loadPlugin(definition),
|
|
134
|
+
plugin: await this.loadPlugin(definition, windowHref),
|
|
165
135
|
definition,
|
|
166
136
|
})));
|
|
167
137
|
}
|
package/PluginManager.d.ts
CHANGED
|
@@ -98,6 +98,7 @@ export default class PluginManager {
|
|
|
98
98
|
addElementType(groupName: PluggableElementTypeGroup, creationCallback: (pluginManager: PluginManager) => PluggableElementType): this;
|
|
99
99
|
getElementType(groupName: PluggableElementTypeGroup, typeName: string): PluggableElementBase;
|
|
100
100
|
getElementTypesInGroup(groupName: PluggableElementTypeGroup): PluggableElementBase[];
|
|
101
|
+
getRpcElements(): RpcMethodType[];
|
|
101
102
|
/** get a MST type for the union of all specified pluggable MST types */
|
|
102
103
|
pluggableMstType(groupName: PluggableElementTypeGroup, fieldName: PluggableElementMember, fallback?: IAnyType): IAnyType;
|
|
103
104
|
/** get a MST type for the union of all specified pluggable config schemas */
|
package/PluginManager.js
CHANGED
|
@@ -16,7 +16,6 @@ const InternetAccountType_1 = __importDefault(require("./pluggableElementTypes/I
|
|
|
16
16
|
const TextSearchAdapterType_1 = __importDefault(require("./pluggableElementTypes/TextSearchAdapterType"));
|
|
17
17
|
const AddTrackWorkflowType_1 = __importDefault(require("./pluggableElementTypes/AddTrackWorkflowType"));
|
|
18
18
|
const configuration_1 = require("./configuration");
|
|
19
|
-
const Plugin_1 = __importDefault(require("./Plugin"));
|
|
20
19
|
const ReExports_1 = __importDefault(require("./ReExports"));
|
|
21
20
|
const CorePlugin_1 = __importDefault(require("./CorePlugin"));
|
|
22
21
|
const jexl_1 = __importDefault(require("./util/jexl"));
|
|
@@ -140,12 +139,17 @@ class PluginManager {
|
|
|
140
139
|
if (this.configured) {
|
|
141
140
|
throw new Error('JBrowse already configured, cannot add plugins');
|
|
142
141
|
}
|
|
143
|
-
|
|
142
|
+
// check for availability of 'install' and 'configure' as a proxy for being
|
|
143
|
+
// an 'instanceof Plugin'
|
|
144
|
+
const [plugin, metadata = {}] = 'install' in load && 'configure' in load
|
|
145
|
+
? [load, {}]
|
|
146
|
+
: [load.plugin, load.metadata];
|
|
144
147
|
if (this.plugins.includes(plugin)) {
|
|
145
148
|
throw new Error('plugin already installed');
|
|
146
149
|
}
|
|
147
150
|
this.pluginMetadata[plugin.name] = metadata;
|
|
148
151
|
if ('definition' in load) {
|
|
152
|
+
// @ts-ignore
|
|
149
153
|
this.runtimePluginDefinitions.push(load.definition);
|
|
150
154
|
}
|
|
151
155
|
plugin.install(this);
|
|
@@ -176,7 +180,6 @@ class PluginManager {
|
|
|
176
180
|
}
|
|
177
181
|
this.plugins.forEach(plugin => plugin.configure(this));
|
|
178
182
|
this.configured = true;
|
|
179
|
-
// console.log(JSON.stringify(getSnapshot(model)))
|
|
180
183
|
return this;
|
|
181
184
|
}
|
|
182
185
|
getElementTypeRecord(groupName) {
|
|
@@ -231,6 +234,9 @@ class PluginManager {
|
|
|
231
234
|
getElementTypesInGroup(groupName) {
|
|
232
235
|
return this.getElementTypeRecord(groupName).all();
|
|
233
236
|
}
|
|
237
|
+
getRpcElements() {
|
|
238
|
+
return this.getElementTypesInGroup('rpc method');
|
|
239
|
+
}
|
|
234
240
|
/** get a MST type for the union of all specified pluggable MST types */
|
|
235
241
|
pluggableMstType(groupName, fieldName, fallback = mobx_state_tree_1.types.maybe(mobx_state_tree_1.types.null)) {
|
|
236
242
|
const pluggableTypes = this.getElementTypeRecord(groupName)
|
|
@@ -7,6 +7,10 @@ export interface BaseOptions {
|
|
|
7
7
|
sessionId: string;
|
|
8
8
|
statusCallback?: Function;
|
|
9
9
|
}
|
|
10
|
+
export interface RefNameMap {
|
|
11
|
+
forwardMap: RefNameAliases;
|
|
12
|
+
reverseMap: RefNameAliases;
|
|
13
|
+
}
|
|
10
14
|
export interface BasicRegion {
|
|
11
15
|
start: number;
|
|
12
16
|
end: number;
|
|
@@ -48,30 +52,19 @@ export default function assemblyFactory(assemblyConfigType: IAnyType, pluginMana
|
|
|
48
52
|
}): void;
|
|
49
53
|
setError(e: Error): void;
|
|
50
54
|
setRegions(regions: Region[]): void;
|
|
51
|
-
setRefNameAliases(
|
|
55
|
+
setRefNameAliases(aliases: RefNameAliases, lowerCase: RefNameAliases): void;
|
|
52
56
|
setCytobands(cytobands: Feature[]): void;
|
|
53
57
|
afterAttach(): void;
|
|
54
58
|
} & {
|
|
55
|
-
getAdapterMapEntry(adapterConf: unknown, options: BaseOptions): Promise<
|
|
56
|
-
forwardMap: {
|
|
57
|
-
[key: string]: string;
|
|
58
|
-
};
|
|
59
|
-
reverseMap: {
|
|
60
|
-
[key: string]: string;
|
|
61
|
-
};
|
|
62
|
-
}>;
|
|
59
|
+
getAdapterMapEntry(adapterConf: unknown, options: BaseOptions): Promise<RefNameMap>;
|
|
63
60
|
/**
|
|
64
61
|
* get Map of `canonical-name -> adapter-specific-name`
|
|
65
62
|
*/
|
|
66
|
-
getRefNameMapForAdapter(adapterConf: unknown, opts: BaseOptions): Promise<
|
|
67
|
-
[key: string]: string;
|
|
68
|
-
}>;
|
|
63
|
+
getRefNameMapForAdapter(adapterConf: unknown, opts: BaseOptions): Promise<RefNameAliases>;
|
|
69
64
|
/**
|
|
70
65
|
* get Map of `adapter-specific-name -> canonical-name`
|
|
71
66
|
*/
|
|
72
|
-
getReverseRefNameMapForAdapter(adapterConf: unknown, opts: BaseOptions): Promise<
|
|
73
|
-
[key: string]: string;
|
|
74
|
-
}>;
|
|
67
|
+
getReverseRefNameMapForAdapter(adapterConf: unknown, opts: BaseOptions): Promise<RefNameAliases>;
|
|
75
68
|
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>;
|
|
76
69
|
export declare type AssemblyModel = ReturnType<typeof assemblyFactory>;
|
|
77
70
|
export declare type Assembly = Instance<AssemblyModel>;
|
|
@@ -186,9 +186,9 @@ function assemblyFactory(assemblyConfigType, pluginManager) {
|
|
|
186
186
|
setRegions(regions) {
|
|
187
187
|
self.regions = regions;
|
|
188
188
|
},
|
|
189
|
-
setRefNameAliases(
|
|
190
|
-
self.refNameAliases =
|
|
191
|
-
self.lowerCaseRefNameAliases =
|
|
189
|
+
setRefNameAliases(aliases, lowerCase) {
|
|
190
|
+
self.refNameAliases = aliases;
|
|
191
|
+
self.lowerCaseRefNameAliases = lowerCase;
|
|
192
192
|
},
|
|
193
193
|
setCytobands(cytobands) {
|
|
194
194
|
self.cytobands = cytobands;
|
|
@@ -292,25 +292,22 @@ async function loadAssemblyReaction(props, signal) {
|
|
|
292
292
|
cytobands,
|
|
293
293
|
};
|
|
294
294
|
}
|
|
295
|
-
async function getRefNameAliases(config,
|
|
296
|
-
|
|
297
|
-
const
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
return adapter.getRefNameAliases({
|
|
301
|
-
signal,
|
|
302
|
-
});
|
|
295
|
+
async function getRefNameAliases(config, pm, signal) {
|
|
296
|
+
const type = pm.getAdapterType(config.type);
|
|
297
|
+
const CLASS = await type.getAdapterClass();
|
|
298
|
+
const adapter = new CLASS(config, undefined, pm);
|
|
299
|
+
return adapter.getRefNameAliases({ signal });
|
|
303
300
|
}
|
|
304
|
-
async function getCytobands(config,
|
|
305
|
-
const type =
|
|
301
|
+
async function getCytobands(config, pm) {
|
|
302
|
+
const type = pm.getAdapterType(config.type);
|
|
306
303
|
const CLASS = await type.getAdapterClass();
|
|
307
|
-
const adapter = new CLASS(config, undefined,
|
|
304
|
+
const adapter = new CLASS(config, undefined, pm);
|
|
308
305
|
// @ts-ignore
|
|
309
306
|
return adapter.getData();
|
|
310
307
|
}
|
|
311
|
-
async function getAssemblyRegions(config,
|
|
312
|
-
const type =
|
|
308
|
+
async function getAssemblyRegions(config, pm, signal) {
|
|
309
|
+
const type = pm.getAdapterType(config.type);
|
|
313
310
|
const CLASS = await type.getAdapterClass();
|
|
314
|
-
const adapter = new CLASS(config, undefined,
|
|
311
|
+
const adapter = new CLASS(config, undefined, pm);
|
|
315
312
|
return adapter.getRegions({ signal });
|
|
316
313
|
}
|