jbrowse-plugin-msaview 3.10.0 → 5.0.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/dist/AddHighlightModel/GenomeMouseoverHighlight.js +1 -1
- package/dist/AddHighlightModel/index.js +3 -12
- package/dist/LaunchMsaView/codingFeature.d.ts +0 -12
- package/dist/LaunchMsaView/codingFeature.js +0 -30
- package/dist/LaunchMsaView/codingFeature.test.js +1 -48
- package/dist/LaunchMsaView/components/BlastQuery/BlastAutomaticPanel.js +8 -10
- package/dist/LaunchMsaView/components/BlastQuery/BlastManualPanel.js +9 -11
- package/dist/LaunchMsaView/components/BlastQuery/CachedBlastResults.js +3 -1
- package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js +14 -16
- package/dist/LaunchMsaView/components/OrthologQuery/OrthologPanel.js +16 -18
- package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +17 -19
- package/dist/LaunchMsaView/components/fetchSeq.d.ts +1 -1
- package/dist/LaunchMsaView/components/fetchSeq.js +3 -10
- package/dist/LaunchMsaView/components/launchConnectedView.d.ts +2 -2
- package/dist/LaunchMsaView/components/launchConnectedView.js +4 -8
- package/dist/LaunchMsaView/components/useFeatureSequence.d.ts +1 -1
- package/dist/LaunchMsaView/index.js +4 -13
- package/dist/LaunchMsaView/launchTarget.d.ts +7 -30
- package/dist/LaunchMsaView/launchTarget.js +10 -49
- package/dist/LaunchMsaView/launchTarget.test.js +17 -109
- package/dist/LaunchMsaViewExtensionPoint/index.js +3 -3
- package/dist/LaunchMsaViewExtensionPoint/index.test.js +24 -21
- package/dist/MsaViewPanel/index.js +3 -3
- package/dist/MsaViewPanel/isMsaView.d.ts +4 -0
- package/dist/MsaViewPanel/isMsaView.js +3 -0
- package/dist/MsaViewPanel/model.d.ts +8 -11
- package/dist/MsaViewPanel/model.js +3 -13
- package/dist/MsaViewPanel/resolveConnectedTranscript.js +1 -7
- package/dist/chunks/AboutDialog-WT6GXMXU.js +2 -0
- package/dist/chunks/AboutDialog-WT6GXMXU.js.map +7 -0
- package/dist/chunks/AnnotationFileDialog-34R7LFHB.js +2 -0
- package/dist/chunks/AnnotationFileDialog-34R7LFHB.js.map +7 -0
- package/dist/chunks/BgzipFastaMsaAdapter-ZMUARSUQ.js +4 -0
- package/dist/chunks/BgzipFastaMsaAdapter-ZMUARSUQ.js.map +7 -0
- package/dist/chunks/ExportSVGDialog-NMVUHFGY.js +2 -0
- package/dist/chunks/ExportSVGDialog-NMVUHFGY.js.map +7 -0
- package/dist/chunks/FeatureDialog-XNHIA5PS.js +2 -0
- package/dist/chunks/FeatureDialog-XNHIA5PS.js.map +7 -0
- package/dist/chunks/HelpDialog-DF4Y536X.js +2 -0
- package/dist/chunks/HelpDialog-DF4Y536X.js.map +7 -0
- package/dist/chunks/LaunchMsaViewDialog-LMZOJ7T6.js +5 -0
- package/dist/chunks/LaunchMsaViewDialog-LMZOJ7T6.js.map +7 -0
- package/dist/chunks/MetadataDialog-2WT6EX4M.js +2 -0
- package/dist/chunks/MetadataDialog-2WT6EX4M.js.map +7 -0
- package/dist/chunks/MsaViewPanel-YYP4CYYO.js +2 -0
- package/dist/chunks/MsaViewPanel-YYP4CYYO.js.map +7 -0
- package/dist/chunks/TrackInfoDialog-TYCMLUKG.js +2 -0
- package/dist/chunks/TrackInfoDialog-TYCMLUKG.js.map +7 -0
- package/dist/chunks/TreeNodeInfoDialog-BFF6JRCO.js +2 -0
- package/dist/chunks/TreeNodeInfoDialog-BFF6JRCO.js.map +7 -0
- package/dist/chunks/chunk-2IWD4OO4.js +2 -0
- package/dist/chunks/chunk-2IWD4OO4.js.map +7 -0
- package/dist/chunks/chunk-5ORPTTMR.js +2 -0
- package/dist/chunks/chunk-5ORPTTMR.js.map +7 -0
- package/dist/chunks/chunk-6YFCSBEE.js +2 -0
- package/dist/chunks/chunk-6YFCSBEE.js.map +7 -0
- package/dist/chunks/chunk-73KAPCJ2.js +2 -0
- package/dist/chunks/chunk-73KAPCJ2.js.map +7 -0
- package/dist/chunks/chunk-BX4Z274Q.js +2 -0
- package/dist/chunks/chunk-BX4Z274Q.js.map +7 -0
- package/dist/chunks/chunk-CVLB4VFP.js +2 -0
- package/dist/chunks/chunk-CVLB4VFP.js.map +7 -0
- package/dist/chunks/chunk-DNFD5II2.js +2 -0
- package/dist/chunks/chunk-DNFD5II2.js.map +7 -0
- package/dist/chunks/chunk-ENTWPX2K.js +6 -0
- package/dist/chunks/chunk-ENTWPX2K.js.map +7 -0
- package/dist/chunks/chunk-FCNT6B47.js +2 -0
- package/dist/chunks/chunk-FCNT6B47.js.map +7 -0
- package/dist/chunks/chunk-FCWXYIFC.js +2 -0
- package/dist/chunks/chunk-FCWXYIFC.js.map +7 -0
- package/dist/chunks/chunk-FY3BTKY4.js +2 -0
- package/dist/chunks/chunk-FY3BTKY4.js.map +7 -0
- package/dist/chunks/chunk-IBBQUV2I.js +2 -0
- package/dist/chunks/chunk-IBBQUV2I.js.map +7 -0
- package/dist/chunks/chunk-J6KYLXRD.js +2 -0
- package/dist/chunks/chunk-J6KYLXRD.js.map +7 -0
- package/dist/chunks/chunk-MBI4TMKR.js +2 -0
- package/dist/chunks/chunk-MBI4TMKR.js.map +7 -0
- package/dist/chunks/chunk-MHBTV7BZ.js +3 -0
- package/dist/chunks/chunk-MHBTV7BZ.js.map +7 -0
- package/dist/chunks/chunk-NSASZ5FM.js +2 -0
- package/dist/chunks/chunk-NSASZ5FM.js.map +7 -0
- package/dist/chunks/chunk-O7JNDIKD.js +2 -0
- package/dist/chunks/chunk-O7JNDIKD.js.map +7 -0
- package/dist/chunks/chunk-P77DPK6B.js +2 -0
- package/dist/chunks/chunk-P77DPK6B.js.map +7 -0
- package/dist/chunks/chunk-PJZ3XTMG.js +6 -0
- package/dist/chunks/chunk-PJZ3XTMG.js.map +7 -0
- package/dist/chunks/chunk-QAC6JSDZ.js +5 -0
- package/dist/chunks/chunk-QAC6JSDZ.js.map +7 -0
- package/dist/chunks/chunk-QMLPITS4.js +18 -0
- package/dist/chunks/chunk-QMLPITS4.js.map +7 -0
- package/dist/chunks/chunk-RTKNCGDF.js +8 -0
- package/dist/chunks/chunk-RTKNCGDF.js.map +7 -0
- package/dist/chunks/chunk-TITP6LCV.js +2 -0
- package/dist/chunks/chunk-TITP6LCV.js.map +7 -0
- package/dist/chunks/chunk-VOBS7IVV.js +2 -0
- package/dist/chunks/chunk-VOBS7IVV.js.map +7 -0
- package/dist/chunks/chunk-YUKJI2AH.js +2 -0
- package/dist/chunks/chunk-YUKJI2AH.js.map +7 -0
- package/dist/chunks/chunk-ZTQYZDWK.js +2 -0
- package/dist/chunks/chunk-ZTQYZDWK.js.map +7 -0
- package/dist/chunks/dist-2T65ZS4E.js +2 -0
- package/dist/chunks/dist-2T65ZS4E.js.map +7 -0
- package/dist/chunks/dist-UX5CKLQJ.js +2 -0
- package/dist/chunks/dist-UX5CKLQJ.js.map +7 -0
- package/dist/chunks/model-7VBTOIJX.js +12 -0
- package/dist/chunks/model-7VBTOIJX.js.map +7 -0
- package/dist/chunks/renderToSvg-B7RCHRO3.js +2 -0
- package/dist/chunks/renderToSvg-B7RCHRO3.js.map +7 -0
- package/dist/config.json +1 -1
- package/dist/index.js +5 -2
- package/dist/jbrowse-plugin-msaview.esm.js +3 -0
- package/dist/jbrowse-plugin-msaview.esm.js.map +7 -0
- package/dist/utils/launchMsaView.d.ts +1 -1
- package/dist/utils/launchMsaView.js +5 -2
- package/dist/utils/workspaces.js +6 -25
- package/dist/utils/workspaces.test.js +5 -5
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -5
- package/src/AddHighlightModel/GenomeMouseoverHighlight.tsx +1 -1
- package/src/AddHighlightModel/index.tsx +6 -16
- package/src/LaunchMsaView/codingFeature.test.ts +1 -64
- package/src/LaunchMsaView/codingFeature.ts +0 -38
- package/src/LaunchMsaView/components/BlastQuery/BlastAutomaticPanel.tsx +3 -3
- package/src/LaunchMsaView/components/BlastQuery/BlastManualPanel.tsx +3 -3
- package/src/LaunchMsaView/components/BlastQuery/CachedBlastResults.tsx +3 -1
- package/src/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.tsx +3 -3
- package/src/LaunchMsaView/components/OrthologQuery/OrthologPanel.tsx +3 -3
- package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +3 -3
- package/src/LaunchMsaView/components/fetchSeq.ts +3 -20
- package/src/LaunchMsaView/components/launchConnectedView.ts +5 -8
- package/src/LaunchMsaView/index.ts +8 -13
- package/src/LaunchMsaView/launchTarget.test.ts +20 -133
- package/src/LaunchMsaView/launchTarget.ts +18 -70
- package/src/LaunchMsaViewExtensionPoint/index.test.ts +26 -21
- package/src/LaunchMsaViewExtensionPoint/index.ts +3 -4
- package/src/MsaViewPanel/index.ts +3 -4
- package/src/MsaViewPanel/isMsaView.ts +7 -0
- package/src/MsaViewPanel/model.ts +3 -16
- package/src/MsaViewPanel/resolveConnectedTranscript.ts +1 -7
- package/src/index.ts +5 -2
- package/src/utils/launchMsaView.ts +5 -2
- package/src/utils/useFetch.ts +1 -1
- package/src/utils/workspaces.test.ts +5 -5
- package/src/utils/workspaces.ts +6 -25
- package/src/version.ts +1 -1
- package/dist/jbrowse-plugin-msaview.umd.production.min.js +0 -137
- package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +0 -7
|
@@ -1,132 +1,40 @@
|
|
|
1
1
|
import { SimpleFeature } from '@jbrowse/core/util';
|
|
2
2
|
import { describe, expect, test } from 'vitest';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import { launchTarget } from './launchTarget';
|
|
4
|
+
const host = (type) => ({
|
|
5
|
+
contextMenuItems: () => [],
|
|
6
|
+
contextMenuInfo: { item: { featureId: 'f1', type }, displayedRegionIndex: 0 },
|
|
7
|
+
fetchFullFeature: (featureId) => Promise.resolve(new SimpleFeature({
|
|
8
|
+
uniqueId: featureId,
|
|
7
9
|
refName: 'chr1',
|
|
8
10
|
start: 0,
|
|
9
11
|
end: 100,
|
|
10
|
-
type
|
|
11
|
-
|
|
12
|
-
uniqueId: `${type}-${i}`,
|
|
13
|
-
refName: 'chr1',
|
|
14
|
-
start: 0,
|
|
15
|
-
end: 100,
|
|
16
|
-
type: t,
|
|
17
|
-
})),
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
const modernHost = (type) => ({
|
|
21
|
-
contextMenuItems: () => [],
|
|
22
|
-
contextMenuInfo: { item: { featureId: 'f1', type }, displayedRegionIndex: 0 },
|
|
23
|
-
fetchFullFeature: (featureId) => Promise.resolve(feature(`fetched:${featureId}`)),
|
|
24
|
-
});
|
|
25
|
-
const legacyHost = (feat) => ({
|
|
26
|
-
contextMenuItems: () => [],
|
|
27
|
-
contextMenuFeature: feat,
|
|
28
|
-
});
|
|
29
|
-
async function fetched(target) {
|
|
30
|
-
return target && 'fetchFeature' in target
|
|
31
|
-
? await target.fetchFeature()
|
|
32
|
-
: undefined;
|
|
33
|
-
}
|
|
34
|
-
describe('isGeneLikeType', () => {
|
|
35
|
-
test.each(['gene', 'mRNA', 'transcript', 'lnc_RNA', 'protein_coding_gene'])('accepts %s', type => {
|
|
36
|
-
expect(isGeneLikeType(type)).toBe(true);
|
|
37
|
-
});
|
|
38
|
-
test.each(['CDS', 'exon', 'match', 'SNV', undefined, null, 42])('rejects %s', type => {
|
|
39
|
-
expect(isGeneLikeType(type)).toBe(false);
|
|
40
|
-
});
|
|
12
|
+
type: `fetched:${featureId}`,
|
|
13
|
+
})),
|
|
41
14
|
});
|
|
42
15
|
describe('launchTarget', () => {
|
|
43
16
|
test('resolves the clicked feature through fetchFullFeature', async () => {
|
|
44
|
-
const
|
|
45
|
-
expect(
|
|
46
|
-
expect((await fetched(target))?.get('type')).toBe('fetched:f1');
|
|
17
|
+
const feature = await launchTarget(host('mRNA'))?.fetchFeature();
|
|
18
|
+
expect(feature?.get('type')).toBe('fetched:f1');
|
|
47
19
|
});
|
|
48
20
|
test('offers nothing for a non-gene click', () => {
|
|
49
|
-
expect(launchTarget(
|
|
50
|
-
expect(launchTarget(
|
|
21
|
+
expect(launchTarget(host('CDS'))).toBeUndefined();
|
|
22
|
+
expect(launchTarget(host(undefined))).toBeUndefined();
|
|
51
23
|
});
|
|
52
24
|
test('offers nothing when nothing was clicked', () => {
|
|
53
|
-
expect(launchTarget({
|
|
54
|
-
});
|
|
55
|
-
// v4.3.0 and earlier have contextMenuFeature and nothing else; dropping this
|
|
56
|
-
// fallback once took "Launch MSA view" off every host in the wild.
|
|
57
|
-
test('falls back to a synchronous contextMenuFeature', () => {
|
|
58
|
-
const target = launchTarget(legacyHost(feature('mRNA')));
|
|
59
|
-
expect(target && 'feature' in target && target.feature.get('type')).toBe('mRNA');
|
|
60
|
-
});
|
|
61
|
-
test('applies the same gene test on both host shapes', () => {
|
|
62
|
-
expect(launchTarget(legacyHost(feature('lnc_RNA')))).toBeDefined();
|
|
63
|
-
expect(launchTarget(legacyHost(feature('exon')))).toBeUndefined();
|
|
64
|
-
});
|
|
65
|
-
// gene-like is not enough: an lncRNA translates to nothing, and offering the
|
|
66
|
-
// item opened a dialog whose Submit never left grey
|
|
67
|
-
test('declines a gene-like feature with no CDS below it', () => {
|
|
68
|
-
expect(launchTarget(legacyHost(feature('lnc_RNA', ['exon'])))).toBeUndefined();
|
|
69
|
-
});
|
|
70
|
-
// a legacy host can hand over a bare record whose children are a separate
|
|
71
|
-
// query, and declining it takes the item off an ordinary gene with no word
|
|
72
|
-
test('offers the item for a gene that arrived with no subfeatures', () => {
|
|
73
|
-
expect(launchTarget(legacyHost(feature('gene', [])))).toBeDefined();
|
|
74
|
-
});
|
|
75
|
-
// a click on an isoform should open the dialog on the gene, so every
|
|
76
|
-
// transcript is there to pick from
|
|
77
|
-
test('climbs to the gene from a clicked isoform', () => {
|
|
78
|
-
const gene = new SimpleFeature({
|
|
79
|
-
uniqueId: 'gene',
|
|
80
|
-
refName: 'chr1',
|
|
81
|
-
start: 0,
|
|
82
|
-
end: 100,
|
|
83
|
-
type: 'gene',
|
|
84
|
-
subfeatures: [
|
|
85
|
-
{
|
|
86
|
-
uniqueId: 'mrna',
|
|
87
|
-
refName: 'chr1',
|
|
88
|
-
start: 0,
|
|
89
|
-
end: 100,
|
|
90
|
-
type: 'mRNA',
|
|
91
|
-
subfeatures: [
|
|
92
|
-
{
|
|
93
|
-
uniqueId: 'cds',
|
|
94
|
-
refName: 'chr1',
|
|
95
|
-
start: 0,
|
|
96
|
-
end: 100,
|
|
97
|
-
type: 'CDS',
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
},
|
|
101
|
-
],
|
|
102
|
-
});
|
|
103
|
-
const mrna = gene.get('subfeatures')[0];
|
|
104
|
-
const target = launchTarget(legacyHost(mrna));
|
|
105
|
-
expect(target && 'feature' in target && target.feature).toBe(gene);
|
|
106
|
-
// the gene is what the dialog opens on, but the picker still opens on the
|
|
107
|
-
// isoform the click landed on -- on a v4 host that click is the only place
|
|
108
|
-
// the choice is ever stated
|
|
109
|
-
expect(target?.preferredTranscriptId).toBe(mrna.id());
|
|
25
|
+
expect(launchTarget({ ...host('mRNA'), contextMenuInfo: undefined })).toBeUndefined();
|
|
110
26
|
});
|
|
111
27
|
// the canvas host names the clicked isoform beside the gene it fetches, as
|
|
112
28
|
// its own Collapse introns dialog reads it
|
|
113
|
-
test('carries the isoform a
|
|
114
|
-
const
|
|
29
|
+
test('carries the isoform a click landed on', () => {
|
|
30
|
+
const h = host('gene');
|
|
115
31
|
const target = launchTarget({
|
|
116
|
-
...
|
|
32
|
+
...h,
|
|
117
33
|
contextMenuInfo: {
|
|
118
|
-
...
|
|
34
|
+
...h.contextMenuInfo,
|
|
119
35
|
subfeature: { featureId: 'mrna-2' },
|
|
120
36
|
},
|
|
121
37
|
});
|
|
122
38
|
expect(target?.preferredTranscriptId).toBe('mrna-2');
|
|
123
39
|
});
|
|
124
|
-
// a host that has both shapes must not fall through to the legacy branch and
|
|
125
|
-
// launch on a stale feature when the click was not on a gene
|
|
126
|
-
test('a non-gene click on a host carrying both shapes offers nothing', () => {
|
|
127
|
-
expect(launchTarget({
|
|
128
|
-
...modernHost('CDS'),
|
|
129
|
-
...legacyHost(feature('mRNA')),
|
|
130
|
-
})).toBeUndefined();
|
|
131
|
-
});
|
|
132
40
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { expandSpec } from 'react-msaview';
|
|
2
1
|
import { launchMsaView } from '../utils/launchMsaView';
|
|
3
2
|
/**
|
|
4
3
|
* `msa` and `tree` onto the plugin's own sources, so a url still goes through
|
|
@@ -23,7 +22,7 @@ function withLongSources({ msa, tree, ...args }) {
|
|
|
23
22
|
};
|
|
24
23
|
}
|
|
25
24
|
export default function LaunchMsaViewExtensionPointF(pluginManager) {
|
|
26
|
-
pluginManager.addToExtensionPoint('LaunchView-MsaView', (args) => {
|
|
25
|
+
pluginManager.addToExtensionPoint('LaunchView-MsaView', async (args) => {
|
|
27
26
|
const { session, query, data, msaFileLocation, msaIndexedLocation, msaName, treeFileLocation, querySeqName, searchParams, ...rest } = withLongSources(args);
|
|
28
27
|
// `orthologParams` and `searchParams` name no alignment at all — the
|
|
29
28
|
// view builds one at launch, which is the dialog's Orthologs and BLAST
|
|
@@ -49,7 +48,8 @@ export default function LaunchMsaViewExtensionPointF(pluginManager) {
|
|
|
49
48
|
msaName,
|
|
50
49
|
querySeqName,
|
|
51
50
|
};
|
|
52
|
-
|
|
51
|
+
const { expandSpec } = await import('react-msaview');
|
|
52
|
+
await launchMsaView(session, {
|
|
53
53
|
...expandSpec({ ...rest, query }),
|
|
54
54
|
...(searchParams ? { blastParams: searchParams } : {}),
|
|
55
55
|
data,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { expect, test } from 'vitest';
|
|
2
2
|
import LaunchMsaViewExtensionPointF from './index';
|
|
3
|
-
function launch(args) {
|
|
3
|
+
async function launch(args) {
|
|
4
4
|
let run;
|
|
5
5
|
LaunchMsaViewExtensionPointF({
|
|
6
6
|
addToExtensionPoint(_name, cb) {
|
|
@@ -9,20 +9,20 @@ function launch(args) {
|
|
|
9
9
|
});
|
|
10
10
|
const added = [];
|
|
11
11
|
const session = {
|
|
12
|
-
|
|
12
|
+
async launchView(_type, snapshot) {
|
|
13
13
|
added.push(snapshot);
|
|
14
14
|
return { id: 'view-1' };
|
|
15
15
|
},
|
|
16
16
|
};
|
|
17
|
-
run({ session, ...args });
|
|
17
|
+
await run({ session, ...args });
|
|
18
18
|
return added[0];
|
|
19
19
|
}
|
|
20
|
-
test('inline data carries no init, which the panel would read as a launch in flight', () => {
|
|
21
|
-
const snapshot = launch({ data: { msa: '>a\nMEEP' } });
|
|
20
|
+
test('inline data carries no init, which the panel would read as a launch in flight', async () => {
|
|
21
|
+
const snapshot = await launch({ data: { msa: '>a\nMEEP' } });
|
|
22
22
|
expect('init' in snapshot).toBe(false);
|
|
23
23
|
});
|
|
24
|
-
test('a file location travels through init', () => {
|
|
25
|
-
const snapshot = launch({
|
|
24
|
+
test('a file location travels through init', async () => {
|
|
25
|
+
const snapshot = await launch({
|
|
26
26
|
msaFileLocation: { uri: 'http://example.com/a.fa' },
|
|
27
27
|
});
|
|
28
28
|
expect(snapshot.init).toEqual({
|
|
@@ -32,8 +32,8 @@ test('a file location travels through init', () => {
|
|
|
32
32
|
querySeqName: undefined,
|
|
33
33
|
});
|
|
34
34
|
});
|
|
35
|
-
test('searchParams is a source, stored under the name the dialog uses', () => {
|
|
36
|
-
const snapshot = launch({
|
|
35
|
+
test('searchParams is a source, stored under the name the dialog uses', async () => {
|
|
36
|
+
const snapshot = await launch({
|
|
37
37
|
searchParams: {
|
|
38
38
|
searchProgram: 'phmmer',
|
|
39
39
|
blastDatabase: 'rp15',
|
|
@@ -50,13 +50,13 @@ test('searchParams is a source, stored under the name the dialog uses', () => {
|
|
|
50
50
|
expect('searchParams' in snapshot).toBe(false);
|
|
51
51
|
expect(snapshot.connectedTranscript).toBe('NM_000546.6');
|
|
52
52
|
});
|
|
53
|
-
test('a launch naming no source at all is refused', () => {
|
|
54
|
-
expect(
|
|
53
|
+
test('a launch naming no source at all is refused', async () => {
|
|
54
|
+
await expect(launch({ connectedViewId: 'lgv1' })).rejects.toThrow(/searchParams/);
|
|
55
55
|
});
|
|
56
|
-
test('region and the data-layer keys reach the view as snapshot properties', () => {
|
|
56
|
+
test('region and the data-layer keys reach the view as snapshot properties', async () => {
|
|
57
57
|
const region = { row: 'Human', start: 245, end: 249 };
|
|
58
58
|
const clades = [{ mrca: ['Human', 'Mouse'], tips: 2, mark: 'bracket' }];
|
|
59
|
-
const snapshot = launch({
|
|
59
|
+
const snapshot = await launch({
|
|
60
60
|
data: { msa: '>Human\nMEEP' },
|
|
61
61
|
region,
|
|
62
62
|
clades,
|
|
@@ -68,8 +68,11 @@ test('region and the data-layer keys reach the view as snapshot properties', ()
|
|
|
68
68
|
expect(snapshot.relativeTo).toBe('Human');
|
|
69
69
|
expect(snapshot.gffFilehandle).toEqual({ uri: 'http://example.com/a.gff' });
|
|
70
70
|
});
|
|
71
|
-
test('one field set is enough to need init', () => {
|
|
72
|
-
const snapshot = launch({
|
|
71
|
+
test('one field set is enough to need init', async () => {
|
|
72
|
+
const snapshot = await launch({
|
|
73
|
+
data: { msa: '>a\nMEEP' },
|
|
74
|
+
querySeqName: 'QUERY',
|
|
75
|
+
});
|
|
73
76
|
expect(snapshot.init).toEqual({
|
|
74
77
|
msaUrl: undefined,
|
|
75
78
|
msaIndexedLocation: undefined,
|
|
@@ -77,8 +80,8 @@ test('one field set is enough to need init', () => {
|
|
|
77
80
|
querySeqName: 'QUERY',
|
|
78
81
|
});
|
|
79
82
|
});
|
|
80
|
-
test('msa and tree urls reach the plugin sources, query the query row', () => {
|
|
81
|
-
const snapshot = launch({
|
|
83
|
+
test('msa and tree urls reach the plugin sources, query the query row', async () => {
|
|
84
|
+
const snapshot = await launch({
|
|
82
85
|
msa: 'https://example.com/p53.afa',
|
|
83
86
|
tree: 'https://example.com/p53.nh',
|
|
84
87
|
query: 'Human',
|
|
@@ -94,13 +97,13 @@ test('msa and tree urls reach the plugin sources, query the query row', () => {
|
|
|
94
97
|
expect(snapshot.relativeTo).toBe('Human');
|
|
95
98
|
expect('msa' in snapshot || 'query' in snapshot).toBe(false);
|
|
96
99
|
});
|
|
97
|
-
test('inline msa and newick text become inline data', () => {
|
|
98
|
-
const snapshot = launch({ msa: '>a\nMEEP\n>b\nMEEP', tree: '(a,b);' });
|
|
100
|
+
test('inline msa and newick text become inline data', async () => {
|
|
101
|
+
const snapshot = await launch({ msa: '>a\nMEEP\n>b\nMEEP', tree: '(a,b);' });
|
|
99
102
|
expect(snapshot.data).toEqual({ msa: '>a\nMEEP\n>b\nMEEP', tree: '(a,b);' });
|
|
100
103
|
expect('init' in snapshot).toBe(false);
|
|
101
104
|
});
|
|
102
|
-
test('highlights, region and column tracks expand onto the query row', () => {
|
|
103
|
-
const snapshot = launch({
|
|
105
|
+
test('highlights, region and column tracks expand onto the query row', async () => {
|
|
106
|
+
const snapshot = await launch({
|
|
104
107
|
msa: 'https://example.com/p53.afa',
|
|
105
108
|
query: 'Human',
|
|
106
109
|
highlights: ['102-292 DNA-binding', 175],
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { lazy } from 'react';
|
|
2
2
|
import ViewType from '@jbrowse/core/pluggableElementTypes/ViewType';
|
|
3
|
-
import stateModelFactory from './model';
|
|
4
|
-
// lazies
|
|
5
3
|
const MsaViewPanel = lazy(() => import('./components/MsaViewPanel'));
|
|
6
4
|
export default function MsaViewF(pluginManager) {
|
|
7
5
|
pluginManager.addViewType(() => {
|
|
8
6
|
return new ViewType({
|
|
9
7
|
name: 'MsaView',
|
|
10
|
-
|
|
8
|
+
// a thunk, so react-msaview loads with the first view rather than with
|
|
9
|
+
// the plugin; addView refuses the type until then, hence launchView
|
|
10
|
+
stateModel: () => import('./model').then(m => m.default()),
|
|
11
11
|
ReactComponent: MsaViewPanel,
|
|
12
12
|
});
|
|
13
13
|
});
|
|
@@ -498,16 +498,16 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
498
498
|
clades: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("react-msaview").Clade, import("react-msaview").Clade, import("react-msaview").Clade>>, [undefined]>;
|
|
499
499
|
encodings: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("react-msaview").Encoding, import("react-msaview").Encoding, import("react-msaview").Encoding>>, [undefined]>;
|
|
500
500
|
rowPanels: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("react-msaview").RowPanelSpec, import("react-msaview").RowPanelSpec, import("react-msaview").RowPanelSpec>>, [undefined]>;
|
|
501
|
-
}, "init" | "querySeqName" | "
|
|
501
|
+
}, "init" | "querySeqName" | "launchCompleted" | "connectedViewId" | "connectedFeature" | "connectedTranscript" | "blastParams" | "orthologParams" | "querySeqOffset" | "uniprotId" | "zoomToBaseLevel" | "dataStoreId" | "mafRegion"> & {
|
|
502
502
|
connectedViewId: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
503
503
|
connectedFeature: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
|
|
504
504
|
connectedTranscript: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
505
505
|
blastParams: import("@jbrowse/mobx-state-tree").IType<BlastParams | undefined, BlastParams | undefined, BlastParams | undefined>;
|
|
506
506
|
orthologParams: import("@jbrowse/mobx-state-tree").IType<OrthologParams | undefined, OrthologParams | undefined, OrthologParams | undefined>;
|
|
507
|
-
querySeqName: import("@jbrowse/mobx-state-tree").
|
|
508
|
-
querySeqOffset: import("@jbrowse/mobx-state-tree").
|
|
507
|
+
querySeqName: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
508
|
+
querySeqOffset: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<number>, [undefined]>;
|
|
509
509
|
uniprotId: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
510
|
-
zoomToBaseLevel: import("@jbrowse/mobx-state-tree").
|
|
510
|
+
zoomToBaseLevel: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
511
511
|
init: import("@jbrowse/mobx-state-tree").IType<MsaViewInitState | undefined, MsaViewInitState | undefined, MsaViewInitState | undefined>;
|
|
512
512
|
dataStoreId: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
513
513
|
launchCompleted: import("@jbrowse/mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
@@ -1509,16 +1509,16 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
1509
1509
|
clades: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("react-msaview").Clade, import("react-msaview").Clade, import("react-msaview").Clade>>, [undefined]>;
|
|
1510
1510
|
encodings: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("react-msaview").Encoding, import("react-msaview").Encoding, import("react-msaview").Encoding>>, [undefined]>;
|
|
1511
1511
|
rowPanels: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("react-msaview").RowPanelSpec, import("react-msaview").RowPanelSpec, import("react-msaview").RowPanelSpec>>, [undefined]>;
|
|
1512
|
-
}, "init" | "querySeqName" | "
|
|
1512
|
+
}, "init" | "querySeqName" | "launchCompleted" | "connectedViewId" | "connectedFeature" | "connectedTranscript" | "blastParams" | "orthologParams" | "querySeqOffset" | "uniprotId" | "zoomToBaseLevel" | "dataStoreId" | "mafRegion"> & {
|
|
1513
1513
|
connectedViewId: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
1514
1514
|
connectedFeature: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
|
|
1515
1515
|
connectedTranscript: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
1516
1516
|
blastParams: import("@jbrowse/mobx-state-tree").IType<BlastParams | undefined, BlastParams | undefined, BlastParams | undefined>;
|
|
1517
1517
|
orthologParams: import("@jbrowse/mobx-state-tree").IType<OrthologParams | undefined, OrthologParams | undefined, OrthologParams | undefined>;
|
|
1518
|
-
querySeqName: import("@jbrowse/mobx-state-tree").
|
|
1519
|
-
querySeqOffset: import("@jbrowse/mobx-state-tree").
|
|
1518
|
+
querySeqName: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
1519
|
+
querySeqOffset: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<number>, [undefined]>;
|
|
1520
1520
|
uniprotId: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
1521
|
-
zoomToBaseLevel: import("@jbrowse/mobx-state-tree").
|
|
1521
|
+
zoomToBaseLevel: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
1522
1522
|
init: import("@jbrowse/mobx-state-tree").IType<MsaViewInitState | undefined, MsaViewInitState | undefined, MsaViewInitState | undefined>;
|
|
1523
1523
|
dataStoreId: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
1524
1524
|
launchCompleted: import("@jbrowse/mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
@@ -1803,6 +1803,3 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
1803
1803
|
export type JBrowsePluginMsaViewStateModel = ReturnType<typeof stateModelFactory>;
|
|
1804
1804
|
export type JBrowsePluginMsaViewModel = Instance<JBrowsePluginMsaViewStateModel>;
|
|
1805
1805
|
export { type MafRegion, type MsaViewInitState } from './types';
|
|
1806
|
-
export declare function isMsaView(view: {
|
|
1807
|
-
type: string;
|
|
1808
|
-
}): view is JBrowsePluginMsaViewModel;
|
|
@@ -51,12 +51,7 @@ export default function stateModelFactory() {
|
|
|
51
51
|
/**
|
|
52
52
|
* #property
|
|
53
53
|
*/
|
|
54
|
-
|
|
55
|
-
// mobx-state-tree every released core exposes (present only on main), and
|
|
56
|
-
// the missing function throws while this model is being built, which
|
|
57
|
-
// error-pages the whole app rather than just this view. Restore
|
|
58
|
-
// stripDefault once a release ships it.
|
|
59
|
-
querySeqName: 'QUERY',
|
|
54
|
+
querySeqName: types.stripDefault(types.string, 'QUERY'),
|
|
60
55
|
/**
|
|
61
56
|
* #property
|
|
62
57
|
* transcript residues before the query row's first residue, so a
|
|
@@ -66,8 +61,7 @@ export default function stateModelFactory() {
|
|
|
66
61
|
* transcript's first residue put every click off by the trimmed
|
|
67
62
|
* amount. Negative when the row runs past the transcript's start.
|
|
68
63
|
*/
|
|
69
|
-
|
|
70
|
-
querySeqOffset: 0,
|
|
64
|
+
querySeqOffset: types.stripDefault(types.number, 0),
|
|
71
65
|
/**
|
|
72
66
|
* #property
|
|
73
67
|
*/
|
|
@@ -75,8 +69,7 @@ export default function stateModelFactory() {
|
|
|
75
69
|
/**
|
|
76
70
|
* #property
|
|
77
71
|
*/
|
|
78
|
-
|
|
79
|
-
zoomToBaseLevel: false,
|
|
72
|
+
zoomToBaseLevel: types.stripDefault(types.boolean, false),
|
|
80
73
|
/**
|
|
81
74
|
* #property
|
|
82
75
|
*/
|
|
@@ -513,6 +506,3 @@ export default function stateModelFactory() {
|
|
|
513
506
|
},
|
|
514
507
|
}));
|
|
515
508
|
}
|
|
516
|
-
export function isMsaView(view) {
|
|
517
|
-
return view.type === 'MsaView';
|
|
518
|
-
}
|
|
@@ -50,13 +50,7 @@ async function findTranscript(self, transcriptId) {
|
|
|
50
50
|
const tracks = transcriptTracks(view.tracks);
|
|
51
51
|
for (const regions of searchWindows(view)) {
|
|
52
52
|
for (const track of tracks) {
|
|
53
|
-
|
|
54
|
-
const args = {
|
|
55
|
-
adapterConfig: getConf(track, 'adapter'),
|
|
56
|
-
sessionId,
|
|
57
|
-
regions,
|
|
58
|
-
};
|
|
59
|
-
const feats = await session.rpcManager.call(sessionId, 'CoreGetFeatures', args);
|
|
53
|
+
const feats = await session.rpcManager.call(sessionId, 'CoreGetFeatures', { adapterConfig: getConf(track, 'adapter'), regions });
|
|
60
54
|
for (const feat of feats) {
|
|
61
55
|
const hit = getTranscriptFeatures(feat).find(t => transcriptMatches(t, transcriptId));
|
|
62
56
|
if (hit) {
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as i}from"./chunk-DNFD5II2.js";import{a as m}from"./chunk-BX4Z274Q.js";import{a}from"./chunk-J6KYLXRD.js";import{b as r}from"./chunk-FY3BTKY4.js";var e=r(a(),1),o=r(i(),1),t=r(m(),1);var l="8.4.1";function c({onClose:n}){return e.default.createElement(o.Dialog,{open:!0,title:"About",onClose:()=>{n()}},e.default.createElement(t.DialogContent,null,e.default.createElement(t.Typography,null,"MSAView ",l," (",e.default.createElement(t.Link,{target:"_blank",rel:"noopener",href:"https://github.com/gmod/react-msaview"},"Github"),")"),e.default.createElement("ul",null,e.default.createElement("li",null,e.default.createElement(t.Typography,null,"We use some color schemes from the"," ",e.default.createElement(t.Link,{target:"_blank",rel:"noopener",href:"https://github.com/biotite-dev/biotite"},"biotite")," ","project, and their license is reproduced"," ",e.default.createElement(t.Link,{target:"_blank",rel:"noopener",href:"https://github.com/biotite-dev/biotite/blob/master/LICENSE.rst"},"here"))),e.default.createElement("li",null,e.default.createElement(t.Typography,null,"See this page for some information on jalview colorings"," ",e.default.createElement(t.Link,{target:"_blank",rel:"noopener",href:"https://www.jalview.org/help/html/colourSchemes/"},"here"))),e.default.createElement("li",null,e.default.createElement(t.Typography,null,"See this page for some info on the clustal, cinema, maeditor, and lesk color schemes"," ",e.default.createElement(t.Link,{target:"_blank",rel:"noopener",href:"http://www.bioinformatics.nl/~berndb/aacolour.html"},"here"))),e.default.createElement("li",null,e.default.createElement(t.Typography,null,"See this paper about the flower color scheme"," ",e.default.createElement(t.Link,{target:"_blank",rel:"noopener",href:"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7245768/"},"here"))))))}export{c as default};
|
|
2
|
+
//# sourceMappingURL=AboutDialog-WT6GXMXU.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../node_modules/.pnpm/react-msaview@8.4.1_35cd7d1fa06820f3dff395dec9803110/node_modules/react-msaview/src/components/dialogs/AboutDialog.tsx", "../../node_modules/.pnpm/react-msaview@8.4.1_35cd7d1fa06820f3dff395dec9803110/node_modules/react-msaview/src/version.ts"],
|
|
4
|
+
"sourcesContent": ["import React from 'react'\n\nimport { Dialog } from '@jbrowse/core/ui'\nimport { DialogContent, Link, Typography } from '@mui/material'\n\nimport { version } from '../../version.ts'\n\nexport default function AboutDialog({ onClose }: { onClose: () => void }) {\n return (\n <Dialog\n open\n title=\"About\"\n onClose={() => {\n onClose()\n }}\n >\n <DialogContent>\n <Typography>\n MSAView {version} (\n <Link\n target=\"_blank\"\n rel=\"noopener\"\n href=\"https://github.com/gmod/react-msaview\"\n >\n Github\n </Link>\n )\n </Typography>\n\n <ul>\n <li>\n <Typography>\n We use some color schemes from the{' '}\n <Link\n target=\"_blank\"\n rel=\"noopener\"\n href=\"https://github.com/biotite-dev/biotite\"\n >\n biotite\n </Link>{' '}\n project, and their license is reproduced{' '}\n <Link\n target=\"_blank\"\n rel=\"noopener\"\n href=\"https://github.com/biotite-dev/biotite/blob/master/LICENSE.rst\"\n >\n here\n </Link>\n </Typography>\n </li>\n <li>\n <Typography>\n See this page for some information on jalview colorings{' '}\n <Link\n target=\"_blank\"\n rel=\"noopener\"\n href=\"https://www.jalview.org/help/html/colourSchemes/\"\n >\n here\n </Link>\n </Typography>\n </li>\n <li>\n <Typography>\n See this page for some info on the clustal, cinema, maeditor, and\n lesk color schemes{' '}\n <Link\n target=\"_blank\"\n rel=\"noopener\"\n href=\"http://www.bioinformatics.nl/~berndb/aacolour.html\"\n >\n here\n </Link>\n </Typography>\n </li>\n <li>\n <Typography>\n See this paper about the flower color scheme{' '}\n <Link\n target=\"_blank\"\n rel=\"noopener\"\n href=\"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7245768/\"\n >\n here\n </Link>\n </Typography>\n </li>\n </ul>\n </DialogContent>\n </Dialog>\n )\n}\n", "export const version = '8.4.1'\n"],
|
|
5
|
+
"mappings": "2JAAA,IAAAA,EAAkB,SAElBC,EAAuB,SACvBC,EAAgD,SCHzC,IAAMC,EAAU,QDOT,SAAPC,EAA6B,CAAE,QAAAC,CAAO,EAA2B,CACtE,OACE,EAAAC,QAAA,cAAC,SAAM,CACL,KAAI,GACJ,MAAM,QACN,QAAS,IAAK,CACZD,EAAO,CACT,CAAC,EAED,EAAAC,QAAA,cAAC,gBAAa,KACZ,EAAAA,QAAA,cAAC,aAAU,gBACAC,OACT,EAAAD,QAAA,cAAC,OAAI,CACH,OAAO,SACP,IAAI,WACJ,KAAK,uCAAuC,EAAA,QAAA,OAOhD,EAAAA,QAAA,cAAA,KAAA,KACE,EAAAA,QAAA,cAAA,KAAA,KACE,EAAAA,QAAA,cAAC,aAAU,0CAC0B,IACnC,EAAAA,QAAA,cAAC,OAAI,CACH,OAAO,SACP,IAAI,WACJ,KAAK,wCAAwC,EAAA,SAAA,EAGvC,+CACiC,IACzC,EAAAA,QAAA,cAAC,OAAI,CACH,OAAO,SACP,IAAI,WACJ,KAAK,gEAAgE,EAAA,MAAA,CAGhE,CACI,EAEf,EAAAA,QAAA,cAAA,KAAA,KACE,EAAAA,QAAA,cAAC,aAAU,+DAC+C,IACxD,EAAAA,QAAA,cAAC,OAAI,CACH,OAAO,SACP,IAAI,WACJ,KAAK,kDAAkD,EAAA,MAAA,CAGlD,CACI,EAEf,EAAAA,QAAA,cAAA,KAAA,KACE,EAAAA,QAAA,cAAC,aAAU,4FAEU,IACnB,EAAAA,QAAA,cAAC,OAAI,CACH,OAAO,SACP,IAAI,WACJ,KAAK,oDAAoD,EAAA,MAAA,CAGpD,CACI,EAEf,EAAAA,QAAA,cAAA,KAAA,KACE,EAAAA,QAAA,cAAC,aAAU,oDACoC,IAC7C,EAAAA,QAAA,cAAC,OAAI,CACH,OAAO,SACP,IAAI,WACJ,KAAK,uDAAuD,EAAA,MAAA,CAGvD,CACI,CACV,CACF,CACS,CAGtB",
|
|
6
|
+
"names": ["import_react", "import_ui", "import_material", "version", "AboutDialog", "onClose", "React", "version"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{f as E,i as d}from"./chunk-RTKNCGDF.js";import"./chunk-QAC6JSDZ.js";import"./chunk-73KAPCJ2.js";import{a as x}from"./chunk-CVLB4VFP.js";import{a as w}from"./chunk-DNFD5II2.js";import{a as T}from"./chunk-BX4Z274Q.js";import{a as C}from"./chunk-J6KYLXRD.js";import{b as i}from"./chunk-FY3BTKY4.js";var e=i(C(),1),c=i(w(),1),t=i(T(),1),h=i(x(),1);function b(r){let n=r.trimStart();if(!n.startsWith("{"))return r;let a=JSON.parse(n);return d(E(a))}async function O(r){let n=await fetch(r);if(!n.ok)throw new Error(`HTTP ${n.status} fetching ${r} ${await n.text()}`);return n.text()}var R=(0,h.observer)(function({handleClose:r,model:n}){let[a,g]=(0,e.useState)(),[l,v]=(0,e.useState)("file"),[s,F]=(0,e.useState)(""),[m,u]=(0,e.useState)(),[y,f]=(0,e.useState)(!1);return e.default.createElement(c.Dialog,{maxWidth:"xl",title:"Open annotation file",onClose:()=>{r()},open:!0},e.default.createElement(t.DialogContent,null,m?e.default.createElement(c.ErrorMessage,{error:m}):null,e.default.createElement(t.Typography,null,"Open a GFF3 file of annotations, such as the one `react-msaview-cli interpro` writes, or the JSON an InterProScan run returns."),e.default.createElement("div",{style:{display:"flex",margin:30}},e.default.createElement(t.FormControl,{component:"fieldset"},e.default.createElement(t.RadioGroup,{value:l,onChange:o=>{v(o.target.value)}},e.default.createElement(t.FormControlLabel,{value:"url",control:e.default.createElement(t.Radio,null),label:"URL"}),e.default.createElement(t.FormControlLabel,{value:"file",control:e.default.createElement(t.Radio,null),label:"File"}))),l==="url"?e.default.createElement("div",null,e.default.createElement(t.Typography,null,"Open an annotation file from a URL"),e.default.createElement(t.TextField,{label:"URL",value:s,onChange:o=>{F(o.target.value)}})):e.default.createElement("div",{style:{paddingTop:20}},e.default.createElement(t.Typography,null,"Open an annotation file from your local drive"),e.default.createElement(t.Button,{variant:"outlined",component:"label"},"Choose File",e.default.createElement("input",{type:"file",hidden:!0,onChange:({target:o})=>{let p=o.files?.[0];p&&g(p)}})),a?e.default.createElement(t.Typography,null,a.name):null))),e.default.createElement(t.DialogActions,null,e.default.createElement(t.Button,{variant:"contained",color:"primary",disabled:y||(l==="file"?!a:!s.trim()),onClick:()=>{(async()=>{f(!0),u(void 0);try{let o=await(l==="file"&&a?a.text():O(s));n.setGFF(b(o)),n.setShowDomains(!0),r()}catch(o){console.error(o),u(o)}finally{f(!1)}})()}},"Open annotations"),e.default.createElement(t.Button,{variant:"contained",color:"secondary",onClick:()=>{r()}},"Cancel")))}),D=R;export{D as default};
|
|
2
|
+
//# sourceMappingURL=AnnotationFileDialog-34R7LFHB.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../node_modules/.pnpm/react-msaview@8.4.1_35cd7d1fa06820f3dff395dec9803110/node_modules/react-msaview/src/components/dialogs/AnnotationFileDialog.tsx"],
|
|
4
|
+
"sourcesContent": ["import React, { useState } from 'react'\n\nimport { Dialog, ErrorMessage } from '@jbrowse/core/ui'\nimport {\n Button,\n DialogActions,\n DialogContent,\n FormControl,\n FormControlLabel,\n Radio,\n RadioGroup,\n TextField,\n Typography,\n} from '@mui/material'\nimport { observer } from 'mobx-react'\nimport {\n annotationsToGFF,\n interProScanResponseToAnnotations,\n} from 'msa-parsers'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { InterProScanResponse } from 'msa-parsers'\n\n// GFF3 as the CLI writes it, or the JSON an InterProScan run returns. Both\n// arrive as text and the model keeps GFF, so the JSON is converted on the way\n// in rather than given a second path through the model\nfunction toGFF(text: string) {\n const trimmed = text.trimStart()\n if (!trimmed.startsWith('{')) {\n return text\n }\n const response: InterProScanResponse = JSON.parse(trimmed)\n return annotationsToGFF(interProScanResponseToAnnotations(response))\n}\n\nasync function fetchText(url: string) {\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(\n `HTTP ${response.status} fetching ${url} ${await response.text()}`,\n )\n }\n return response.text()\n}\n\nconst AnnotationFileDialog = observer(function ({\n handleClose,\n model,\n}: {\n handleClose: () => void\n model: MsaViewModel\n}) {\n const [file, setFile] = useState<File>()\n const [choice, setChoice] = useState('file')\n const [url, setUrl] = useState('')\n const [error, setError] = useState<unknown>()\n const [loading, setLoading] = useState(false)\n\n // the error is shown here rather than notified: the standalone app and the\n // MSAViewer component have no jbrowse session to notify, and asking one for\n // its notify() threw out of the success path into the catch, which threw\n // again on the same missing session\n return (\n <Dialog\n maxWidth=\"xl\"\n title=\"Open annotation file\"\n onClose={() => {\n handleClose()\n }}\n open\n >\n <DialogContent>\n {error ? <ErrorMessage error={error} /> : null}\n <Typography>\n Open a GFF3 file of annotations, such as the one `react-msaview-cli\n interpro` writes, or the JSON an InterProScan run returns.\n </Typography>\n\n <div style={{ display: 'flex', margin: 30 }}>\n <FormControl component=\"fieldset\">\n <RadioGroup\n value={choice}\n onChange={event => {\n setChoice(event.target.value)\n }}\n >\n <FormControlLabel value=\"url\" control={<Radio />} label=\"URL\" />\n <FormControlLabel value=\"file\" control={<Radio />} label=\"File\" />\n </RadioGroup>\n </FormControl>\n {choice === 'url' ? (\n <div>\n <Typography>Open an annotation file from a URL</Typography>\n <TextField\n label=\"URL\"\n value={url}\n onChange={event => {\n setUrl(event.target.value)\n }}\n />\n </div>\n ) : (\n <div style={{ paddingTop: 20 }}>\n <Typography>\n Open an annotation file from your local drive\n </Typography>\n <Button variant=\"outlined\" component=\"label\">\n Choose File\n <input\n type=\"file\"\n hidden\n onChange={({ target }) => {\n const chosen = target.files?.[0]\n if (chosen) {\n setFile(chosen)\n }\n }}\n />\n </Button>\n {file ? <Typography>{file.name}</Typography> : null}\n </div>\n )}\n </div>\n </DialogContent>\n <DialogActions>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={loading || (choice === 'file' ? !file : !url.trim())}\n onClick={() => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n ;(async () => {\n setLoading(true)\n setError(undefined)\n try {\n const text = await (choice === 'file' && file\n ? file.text()\n : fetchText(url))\n // through the model's own GFF text, so the annotations travel\n // in the snapshot and the shared URL like every other layer.\n // Setting them straight onto the volatile left a view whose\n // link opened without them\n model.setGFF(toGFF(text))\n model.setShowDomains(true)\n handleClose()\n } catch (e) {\n console.error(e)\n setError(e)\n } finally {\n setLoading(false)\n }\n })()\n }}\n >\n Open annotations\n </Button>\n <Button\n variant=\"contained\"\n color=\"secondary\"\n onClick={() => {\n handleClose()\n }}\n >\n Cancel\n </Button>\n </DialogActions>\n </Dialog>\n )\n})\n\nexport default AnnotationFileDialog\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_react", "import_ui", "import_material", "import_mobx_react", "toGFF", "text", "trimmed", "response", "annotationsToGFF", "interProScanResponseToAnnotations", "fetchText", "url", "AnnotationFileDialog", "handleClose", "model", "file", "setFile", "choice", "setChoice", "setUrl", "error", "setError", "loading", "setLoading", "React", "event", "target", "chosen", "e", "AnnotationFileDialog_default"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{a as or}from"./chunk-2IWD4OO4.js";import{a as tr,b as B}from"./chunk-FY3BTKY4.js";var V=tr((cr,L)=>{L.exports=JBrowseExports["@jbrowse/core/data_adapters/BaseAdapter"]});var Z=B(or()),rr=B(V());var P=function(t,r){return P=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,o){e.__proto__=o}||function(e,o){for(var n in o)Object.prototype.hasOwnProperty.call(o,n)&&(e[n]=o[n])},P(t,r)};function b(t,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");P(t,r);function e(){this.constructor=t}t.prototype=r===null?Object.create(r):(e.prototype=r.prototype,new e)}function T(t){var r=typeof Symbol=="function"&&Symbol.iterator,e=r&&t[r],o=0;if(e)return e.call(t);if(t&&typeof t.length=="number")return{next:function(){return t&&o>=t.length&&(t=void 0),{value:t&&t[o++],done:!t}}};throw new TypeError(r?"Object is not iterable.":"Symbol.iterator is not defined.")}function h(t,r){var e=typeof Symbol=="function"&&t[Symbol.iterator];if(!e)return t;var o=e.call(t),n,i=[],f;try{for(;(r===void 0||r-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(a){f={error:a}}finally{try{n&&!n.done&&(e=o.return)&&e.call(o)}finally{if(f)throw f.error}}return i}function d(t,r,e){if(e||arguments.length===2)for(var o=0,n=r.length,i;o<n;o++)(i||!(o in r))&&(i||(i=Array.prototype.slice.call(r,0,o)),i[o]=r[o]);return t.concat(i||Array.prototype.slice.call(r))}function u(t){return typeof t=="function"}function g(t){var r=function(o){Error.call(o),o.stack=new Error().stack},e=t(r);return e.prototype=Object.create(Error.prototype),e.prototype.constructor=e,e}var _=g(function(t){return function(e){t(this),this.message=e?e.length+` errors occurred during unsubscription:
|
|
2
|
+
`+e.map(function(o,n){return n+1+") "+o.toString()}).join(`
|
|
3
|
+
`):"",this.name="UnsubscriptionError",this.errors=e}});function j(t,r){if(t){var e=t.indexOf(r);0<=e&&t.splice(e,1)}}var E=(function(){function t(r){this.initialTeardown=r,this.closed=!1,this._parentage=null,this._finalizers=null}return t.prototype.unsubscribe=function(){var r,e,o,n,i;if(!this.closed){this.closed=!0;var f=this._parentage;if(f)if(this._parentage=null,Array.isArray(f))try{for(var a=T(f),p=a.next();!p.done;p=a.next()){var c=p.value;c.remove(this)}}catch(s){r={error:s}}finally{try{p&&!p.done&&(e=a.return)&&e.call(a)}finally{if(r)throw r.error}}else f.remove(this);var l=this.initialTeardown;if(u(l))try{l()}catch(s){i=s instanceof _?s.errors:[s]}var v=this._finalizers;if(v){this._finalizers=null;try{for(var w=T(v),y=w.next();!y.done;y=w.next()){var er=y.value;try{k(er)}catch(s){i=i??[],s instanceof _?i=d(d([],h(i)),h(s.errors)):i.push(s)}}}catch(s){o={error:s}}finally{try{y&&!y.done&&(n=w.return)&&n.call(w)}finally{if(o)throw o.error}}}if(i)throw new _(i)}},t.prototype.add=function(r){var e;if(r&&r!==this)if(this.closed)k(r);else{if(r instanceof t){if(r.closed||r._hasParent(this))return;r._addParent(this)}(this._finalizers=(e=this._finalizers)!==null&&e!==void 0?e:[]).push(r)}},t.prototype._hasParent=function(r){var e=this._parentage;return e===r||Array.isArray(e)&&e.includes(r)},t.prototype._addParent=function(r){var e=this._parentage;this._parentage=Array.isArray(e)?(e.push(r),e):e?[e,r]:r},t.prototype._removeParent=function(r){var e=this._parentage;e===r?this._parentage=null:Array.isArray(e)&&j(e,r)},t.prototype.remove=function(r){var e=this._finalizers;e&&j(e,r),r instanceof t&&r._removeParent(this)},t.EMPTY=(function(){var r=new t;return r.closed=!0,r})(),t})();var _r=E.EMPTY;function q(t){return t instanceof E||t&&"closed"in t&&u(t.remove)&&u(t.add)&&u(t.unsubscribe)}function k(t){u(t)?t():t.unsubscribe()}var m={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var x={setTimeout:function(t,r){for(var e=[],o=2;o<arguments.length;o++)e[o-2]=arguments[o];var n=x.delegate;return n?.setTimeout?n.setTimeout.apply(n,d([t,r],h(e))):setTimeout.apply(void 0,d([t,r],h(e)))},clearTimeout:function(t){var r=x.delegate;return(r?.clearTimeout||clearTimeout)(t)},delegate:void 0};function z(t){x.setTimeout(function(){var r=m.onUnhandledError;if(r)r(t);else throw t})}function A(){}var H=(function(){return R("C",void 0,void 0)})();function Y(t){return R("E",void 0,t)}function K(t){return R("N",t,void 0)}function R(t,r,e){return{kind:t,value:r,error:e}}var C=null;function G(t){m.useDeprecatedSynchronousErrorHandling&&C&&(C.errorThrown=!0,C.error=t)}var I=(function(t){b(r,t);function r(e){var o=t.call(this)||this;return o.isStopped=!1,e?(o.destination=e,q(e)&&e.add(o)):o.destination=ar,o}return r.create=function(e,o,n){return new N(e,o,n)},r.prototype.next=function(e){this.isStopped?F(K(e),this):this._next(e)},r.prototype.error=function(e){this.isStopped?F(Y(e),this):(this.isStopped=!0,this._error(e))},r.prototype.complete=function(){this.isStopped?F(H,this):(this.isStopped=!0,this._complete())},r.prototype.unsubscribe=function(){this.closed||(this.isStopped=!0,t.prototype.unsubscribe.call(this),this.destination=null)},r.prototype._next=function(e){this.destination.next(e)},r.prototype._error=function(e){try{this.destination.error(e)}finally{this.unsubscribe()}},r.prototype._complete=function(){try{this.destination.complete()}finally{this.unsubscribe()}},r})(E);var nr=Function.prototype.bind;function M(t,r){return nr.call(t,r)}var ir=(function(){function t(r){this.partialObserver=r}return t.prototype.next=function(r){var e=this.partialObserver;if(e.next)try{e.next(r)}catch(o){S(o)}},t.prototype.error=function(r){var e=this.partialObserver;if(e.error)try{e.error(r)}catch(o){S(o)}else S(r)},t.prototype.complete=function(){var r=this.partialObserver;if(r.complete)try{r.complete()}catch(e){S(e)}},t})(),N=(function(t){b(r,t);function r(e,o,n){var i=t.call(this)||this,f;if(u(e)||!e)f={next:e??void 0,error:o??void 0,complete:n??void 0};else{var a;i&&m.useDeprecatedNextContext?(a=Object.create(e),a.unsubscribe=function(){return i.unsubscribe()},f={next:e.next&&M(e.next,a),error:e.error&&M(e.error,a),complete:e.complete&&M(e.complete,a)}):f=e}return i.destination=new ir(f),i}return r})(I);function S(t){m.useDeprecatedSynchronousErrorHandling?G(t):z(t)}function fr(t){throw t}function F(t,r){var e=m.onStoppedNotification;e&&x.setTimeout(function(){return e(t,r)})}var ar={closed:!0,next:A,error:fr,complete:A};function pr(t){return u(t?.lift)}function O(t){return function(r){if(pr(r))return r.lift(function(e){try{return t(e,this)}catch(o){this.error(o)}});throw new TypeError("Unable to lift unknown Observable type")}}function J(t,r,e,o,n){return new sr(t,r,e,o,n)}var sr=(function(t){b(r,t);function r(e,o,n,i,f,a){var p=t.call(this,e)||this;return p.onFinalize=f,p.shouldUnsubscribe=a,p._next=o?function(c){try{o(c)}catch(l){e.error(l)}}:t.prototype._next,p._error=i?function(c){try{i(c)}catch(l){e.error(l)}finally{this.unsubscribe()}}:t.prototype._error,p._complete=n?function(){try{n()}catch(c){e.error(c)}finally{this.unsubscribe()}}:t.prototype._complete,p}return r.prototype.unsubscribe=function(){var e;if(!this.shouldUnsubscribe||this.shouldUnsubscribe()){var o=this.closed;t.prototype.unsubscribe.call(this),!o&&((e=this.onFinalize)===null||e===void 0||e.call(this))}},r})(I);var $=g(function(t){return function(){t(this),this.name="EmptyError",this.message="no elements in sequence"}});function U(t,r){var e=typeof r=="object";return new Promise(function(o,n){var i=new N({next:function(f){o(f),i.unsubscribe()},error:n,complete:function(){e?o(r.defaultValue):n(new $)}});t.subscribe(i)})}function Q(t,r,e,o,n){return function(i,f){var a=e,p=r,c=0;i.subscribe(J(f,function(l){var v=c++;p=a?t(p,l,v):(a=!0,l),o&&f.next(p)},n&&(function(){a&&f.next(p),f.complete()})))}}function X(t,r){return O(Q(t,r,arguments.length>=2,!1,!0))}var ur=function(t,r){return t.push(r),t};function D(){return O(function(t,r){X(ur,[])(t).subscribe(r)})}var W=class extends rr.BaseAdapter{async configurePre(){let r=this.getSubAdapter;if(r)return(await r({...(0,Z.readConfObject)(this.config),type:"BgzipFastaAdapter"})).dataAdapter;throw new Error("no get subadapter")}configure(){return this.configureP??=this.configurePre().catch(r=>{throw this.configureP=void 0,r}),this.configureP}async getMSARefs(){return this.refNamesP??=this.configure().then(r=>r.getRefNames()).catch(r=>{throw this.refNamesP=void 0,r}),this.refNamesP}getMsaRegex(){return new RegExp(this.getConf("msaRegex"))}refNameToMsaId(r){return r.split(this.getMsaRegex())[0]}async getMSAList(){let r=await this.getMSARefs();return[...new Set(r.map(o=>this.refNameToMsaId(o)))]}async getMSA(r){let e=await this.configure(),n=(await this.getMSARefs()).filter(i=>this.refNameToMsaId(i)===r);return U(e.getFeaturesInMultipleRegions(n.map(i=>({refName:i,start:0,end:1e9,assemblyName:""}))).pipe(D()))}};export{W as default};
|
|
4
|
+
//# sourceMappingURL=BgzipFastaMsaAdapter-ZMUARSUQ.js.map
|