jbrowse-plugin-msaview 2.2.3 → 2.2.4
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/CHANGELOG.md +1 -1
- package/README.md +229 -0
- package/dist/AddHighlightModel/GenomeMouseoverHighlight.js +23 -18
- package/dist/AddHighlightModel/GenomeMouseoverHighlight.js.map +1 -1
- package/dist/AddHighlightModel/MsaToGenomeHighlight.js +23 -13
- package/dist/AddHighlightModel/MsaToGenomeHighlight.js.map +1 -1
- package/dist/AddHighlightModel/index.js +8 -1
- package/dist/AddHighlightModel/index.js.map +1 -1
- package/dist/AddHighlightModel/util.d.ts +2 -2
- package/dist/BgzipFastaMsaAdapter/configSchema.d.ts +2 -2
- package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js +5 -11
- package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js.map +1 -1
- package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.js +5 -1
- package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.js.map +1 -1
- package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js +16 -16
- package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js.map +1 -1
- package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js +38 -46
- package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js.map +1 -1
- package/dist/LaunchMsaView/components/ManualMSALoader/launchView.d.ts +4 -3
- package/dist/LaunchMsaView/components/ManualMSALoader/launchView.js +4 -3
- package/dist/LaunchMsaView/components/ManualMSALoader/launchView.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.d.ts +9 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js +76 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js.map +1 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js +35 -13
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js +6 -12
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.d.ts +6 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.js +15 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.js.map +1 -1
- package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +12 -34
- package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/PreLoadedMSA/consts.d.ts +1 -0
- package/dist/LaunchMsaView/components/PreLoadedMSA/consts.js +1 -0
- package/dist/LaunchMsaView/components/PreLoadedMSA/consts.js.map +1 -1
- package/dist/LaunchMsaView/components/TabPanel.d.ts +2 -2
- package/dist/LaunchMsaView/components/TranscriptSelector.d.ts +2 -2
- package/dist/LaunchMsaView/components/TranscriptSelector.js +3 -6
- package/dist/LaunchMsaView/components/TranscriptSelector.js.map +1 -1
- package/dist/LaunchMsaView/components/useSWRFeatureSequence.js +6 -4
- package/dist/LaunchMsaView/components/useSWRFeatureSequence.js.map +1 -1
- package/dist/LaunchMsaView/components/useTranscriptSelection.d.ts +16 -0
- package/dist/LaunchMsaView/components/useTranscriptSelection.js +31 -0
- package/dist/LaunchMsaView/components/useTranscriptSelection.js.map +1 -0
- package/dist/LaunchMsaView/components/util.d.ts +3 -1
- package/dist/LaunchMsaView/components/util.js +12 -2
- package/dist/LaunchMsaView/components/util.js.map +1 -1
- package/dist/LaunchMsaView/util.d.ts +2 -0
- package/dist/LaunchMsaView/util.js +16 -4
- package/dist/LaunchMsaView/util.js.map +1 -1
- package/dist/LaunchMsaViewExtensionPoint/index.d.ts +2 -0
- package/dist/LaunchMsaViewExtensionPoint/index.js +31 -0
- package/dist/LaunchMsaViewExtensionPoint/index.js.map +1 -0
- package/dist/MsaViewPanel/components/ConnectStructureDialog.d.ts +7 -0
- package/dist/MsaViewPanel/components/ConnectStructureDialog.js +56 -0
- package/dist/MsaViewPanel/components/ConnectStructureDialog.js.map +1 -0
- package/dist/MsaViewPanel/components/MsaViewPanel.js +4 -2
- package/dist/MsaViewPanel/components/MsaViewPanel.js.map +1 -1
- package/dist/MsaViewPanel/doLaunchBlast.d.ts +1 -0
- package/dist/MsaViewPanel/doLaunchBlast.js +65 -19
- package/dist/MsaViewPanel/doLaunchBlast.js.map +1 -1
- package/dist/MsaViewPanel/genomeToMSA.d.ts +6 -0
- package/dist/MsaViewPanel/genomeToMSA.js +38 -8
- package/dist/MsaViewPanel/genomeToMSA.js.map +1 -1
- package/dist/MsaViewPanel/genomeToMSA.test.d.ts +1 -0
- package/dist/MsaViewPanel/genomeToMSA.test.js +244 -0
- package/dist/MsaViewPanel/genomeToMSA.test.js.map +1 -0
- package/dist/MsaViewPanel/model.d.ts +717 -226
- package/dist/MsaViewPanel/model.js +467 -39
- package/dist/MsaViewPanel/model.js.map +1 -1
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.d.ts +7 -2
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.js +26 -27
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.js.map +1 -1
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.test.d.ts +1 -0
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.test.js +240 -0
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.test.js.map +1 -0
- package/dist/MsaViewPanel/msaDataStore.d.ts +14 -0
- package/dist/MsaViewPanel/msaDataStore.js +197 -0
- package/dist/MsaViewPanel/msaDataStore.js.map +1 -0
- package/dist/MsaViewPanel/pairwiseAlignment.d.ts +27 -0
- package/dist/MsaViewPanel/pairwiseAlignment.js +776 -0
- package/dist/MsaViewPanel/pairwiseAlignment.js.map +1 -0
- package/dist/MsaViewPanel/pairwiseAlignment.test.d.ts +1 -0
- package/dist/MsaViewPanel/pairwiseAlignment.test.js +112 -0
- package/dist/MsaViewPanel/pairwiseAlignment.test.js.map +1 -0
- package/dist/MsaViewPanel/structureConnection.d.ts +27 -0
- package/dist/MsaViewPanel/structureConnection.js +46 -0
- package/dist/MsaViewPanel/structureConnection.js.map +1 -0
- package/dist/MsaViewPanel/structureConnection.test.d.ts +1 -0
- package/dist/MsaViewPanel/structureConnection.test.js +122 -0
- package/dist/MsaViewPanel/structureConnection.test.js.map +1 -0
- package/dist/MsaViewPanel/types.d.ts +13 -0
- package/dist/MsaViewPanel/types.js +2 -0
- package/dist/MsaViewPanel/types.js.map +1 -0
- package/dist/MsaViewPanel/util.d.ts +7 -0
- package/dist/MsaViewPanel/util.js +10 -0
- package/dist/MsaViewPanel/util.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/jbrowse-plugin-msaview.umd.production.min.js +39 -90
- package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
- package/dist/utils/blastCache.d.ts +34 -0
- package/dist/utils/blastCache.js +58 -0
- package/dist/utils/blastCache.js.map +1 -0
- package/dist/utils/fetch.d.ts +1 -1
- package/dist/utils/fetch.js +1 -1
- package/dist/utils/fetch.js.map +1 -1
- package/dist/utils/ncbiBlast.d.ts +1 -5
- package/dist/utils/taxonomyNames.d.ts +5 -0
- package/dist/utils/taxonomyNames.js +79 -0
- package/dist/utils/taxonomyNames.js.map +1 -0
- package/dist/utils/types.d.ts +8 -5
- package/package.json +50 -54
- package/src/AddHighlightModel/GenomeMouseoverHighlight.tsx +37 -21
- package/src/AddHighlightModel/MsaToGenomeHighlight.tsx +38 -17
- package/src/AddHighlightModel/index.tsx +9 -4
- package/src/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.tsx +13 -13
- package/src/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.ts +6 -0
- package/src/LaunchMsaView/components/LaunchMsaViewDialog.tsx +30 -23
- package/src/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.tsx +64 -51
- package/src/LaunchMsaView/components/ManualMSALoader/launchView.ts +9 -6
- package/src/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.tsx +146 -0
- package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.tsx +53 -22
- package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.tsx +8 -13
- package/src/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.ts +25 -0
- package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +27 -47
- package/src/LaunchMsaView/components/PreLoadedMSA/consts.ts +1 -0
- package/src/LaunchMsaView/components/TabPanel.tsx +2 -2
- package/src/LaunchMsaView/components/TranscriptSelector.tsx +13 -20
- package/src/LaunchMsaView/components/useSWRFeatureSequence.ts +5 -5
- package/src/LaunchMsaView/components/useTranscriptSelection.ts +48 -0
- package/src/LaunchMsaView/components/util.ts +17 -2
- package/src/LaunchMsaView/index.ts +1 -1
- package/src/LaunchMsaView/util.ts +25 -6
- package/src/LaunchMsaViewExtensionPoint/index.ts +74 -0
- package/src/MsaViewPanel/components/ConnectStructureDialog.tsx +156 -0
- package/src/MsaViewPanel/components/MsaViewPanel.tsx +6 -1
- package/src/MsaViewPanel/doLaunchBlast.ts +83 -23
- package/src/MsaViewPanel/genomeToMSA.test.ts +281 -0
- package/src/MsaViewPanel/genomeToMSA.ts +43 -10
- package/src/MsaViewPanel/model.ts +590 -43
- package/src/MsaViewPanel/msaCoordToGenomeCoord.test.ts +256 -0
- package/src/MsaViewPanel/msaCoordToGenomeCoord.ts +43 -29
- package/src/MsaViewPanel/msaDataStore.ts +236 -0
- package/src/MsaViewPanel/pairwiseAlignment.test.ts +140 -0
- package/src/MsaViewPanel/pairwiseAlignment.ts +818 -0
- package/src/MsaViewPanel/structureConnection.test.ts +143 -0
- package/src/MsaViewPanel/structureConnection.ts +72 -0
- package/src/MsaViewPanel/types.ts +14 -0
- package/src/MsaViewPanel/util.ts +11 -0
- package/src/index.ts +3 -1
- package/src/utils/blastCache.ts +114 -0
- package/src/utils/fetch.ts +1 -1
- package/src/utils/taxonomyNames.ts +111 -0
- package/src/utils/types.ts +9 -1
- package/dist/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.d.ts +0 -5
- package/dist/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.js +0 -16
- package/dist/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.js.map +0 -1
- package/dist/out.js +0 -55381
- package/src/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.ts +0 -25
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface CachedBlastResult {
|
|
2
|
+
id: string;
|
|
3
|
+
proteinSequence: string;
|
|
4
|
+
blastDatabase: string;
|
|
5
|
+
blastProgram: string;
|
|
6
|
+
msaAlgorithm: string;
|
|
7
|
+
msa: string;
|
|
8
|
+
tree: string;
|
|
9
|
+
treeMetadata: string;
|
|
10
|
+
rid: string;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
geneId?: string;
|
|
13
|
+
transcriptId?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function getCachedBlastResult({ proteinSequence, blastDatabase, blastProgram, }: {
|
|
16
|
+
proteinSequence: string;
|
|
17
|
+
blastDatabase: string;
|
|
18
|
+
blastProgram: string;
|
|
19
|
+
}): Promise<any>;
|
|
20
|
+
export declare function saveBlastResult({ proteinSequence, blastDatabase, blastProgram, msaAlgorithm, msa, tree, treeMetadata, rid, geneId, transcriptId, }: {
|
|
21
|
+
proteinSequence: string;
|
|
22
|
+
blastDatabase: string;
|
|
23
|
+
blastProgram: string;
|
|
24
|
+
msaAlgorithm: string;
|
|
25
|
+
msa: string;
|
|
26
|
+
tree: string;
|
|
27
|
+
treeMetadata: string;
|
|
28
|
+
rid: string;
|
|
29
|
+
geneId?: string;
|
|
30
|
+
transcriptId?: string;
|
|
31
|
+
}): Promise<CachedBlastResult>;
|
|
32
|
+
export declare function getAllCachedResults(): Promise<any[]>;
|
|
33
|
+
export declare function deleteCachedResult(id: string): Promise<void>;
|
|
34
|
+
export declare function clearAllCachedResults(): Promise<void>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { openDB } from 'idb';
|
|
2
|
+
const DB_NAME = 'jbrowse-msaview-blast-cache';
|
|
3
|
+
const STORE_NAME = 'blast-results';
|
|
4
|
+
const DB_VERSION = 2;
|
|
5
|
+
async function getDB() {
|
|
6
|
+
return openDB(DB_NAME, DB_VERSION, {
|
|
7
|
+
upgrade(db, oldVersion) {
|
|
8
|
+
if (oldVersion < 2 && db.objectStoreNames.contains(STORE_NAME)) {
|
|
9
|
+
db.deleteObjectStore(STORE_NAME);
|
|
10
|
+
}
|
|
11
|
+
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
|
12
|
+
db.createObjectStore(STORE_NAME, { keyPath: 'id' });
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function createCacheKey(proteinSequence, blastDatabase, blastProgram) {
|
|
18
|
+
return `${blastDatabase}:${blastProgram}:${proteinSequence.slice(0, 100)}`;
|
|
19
|
+
}
|
|
20
|
+
export async function getCachedBlastResult({ proteinSequence, blastDatabase, blastProgram, }) {
|
|
21
|
+
const db = await getDB();
|
|
22
|
+
const id = createCacheKey(proteinSequence, blastDatabase, blastProgram);
|
|
23
|
+
return db.get(STORE_NAME, id);
|
|
24
|
+
}
|
|
25
|
+
export async function saveBlastResult({ proteinSequence, blastDatabase, blastProgram, msaAlgorithm, msa, tree, treeMetadata, rid, geneId, transcriptId, }) {
|
|
26
|
+
const db = await getDB();
|
|
27
|
+
const id = createCacheKey(proteinSequence, blastDatabase, blastProgram);
|
|
28
|
+
const entry = {
|
|
29
|
+
id,
|
|
30
|
+
proteinSequence,
|
|
31
|
+
blastDatabase,
|
|
32
|
+
blastProgram,
|
|
33
|
+
msaAlgorithm,
|
|
34
|
+
msa,
|
|
35
|
+
tree,
|
|
36
|
+
treeMetadata,
|
|
37
|
+
rid,
|
|
38
|
+
timestamp: Date.now(),
|
|
39
|
+
geneId,
|
|
40
|
+
transcriptId,
|
|
41
|
+
};
|
|
42
|
+
await db.put(STORE_NAME, entry);
|
|
43
|
+
return entry;
|
|
44
|
+
}
|
|
45
|
+
export async function getAllCachedResults() {
|
|
46
|
+
const db = await getDB();
|
|
47
|
+
const results = await db.getAll(STORE_NAME);
|
|
48
|
+
return results.toSorted((a, b) => b.timestamp - a.timestamp);
|
|
49
|
+
}
|
|
50
|
+
export async function deleteCachedResult(id) {
|
|
51
|
+
const db = await getDB();
|
|
52
|
+
await db.delete(STORE_NAME, id);
|
|
53
|
+
}
|
|
54
|
+
export async function clearAllCachedResults() {
|
|
55
|
+
const db = await getDB();
|
|
56
|
+
await db.clear(STORE_NAME);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=blastCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blastCache.js","sourceRoot":"","sources":["../../src/utils/blastCache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AAE5B,MAAM,OAAO,GAAG,6BAA6B,CAAA;AAC7C,MAAM,UAAU,GAAG,eAAe,CAAA;AAClC,MAAM,UAAU,GAAG,CAAC,CAAA;AAiBpB,KAAK,UAAU,KAAK;IAClB,OAAO,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE;QACjC,OAAO,CAAC,EAAE,EAAE,UAAU;YACpB,IAAI,UAAU,GAAG,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/D,EAAE,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAA;YAClC,CAAC;YACD,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC9C,EAAE,CAAC,iBAAiB,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;YACrD,CAAC;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,cAAc,CACrB,eAAuB,EACvB,aAAqB,EACrB,YAAoB;IAEpB,OAAO,GAAG,aAAa,IAAI,YAAY,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAA;AAC5E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,EACzC,eAAe,EACf,aAAa,EACb,YAAY,GAKb;IACC,MAAM,EAAE,GAAG,MAAM,KAAK,EAAE,CAAA;IACxB,MAAM,EAAE,GAAG,cAAc,CAAC,eAAe,EAAE,aAAa,EAAE,YAAY,CAAC,CAAA;IACvE,OAAO,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EACpC,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,GAAG,EACH,IAAI,EACJ,YAAY,EACZ,GAAG,EACH,MAAM,EACN,YAAY,GAYb;IACC,MAAM,EAAE,GAAG,MAAM,KAAK,EAAE,CAAA;IACxB,MAAM,EAAE,GAAG,cAAc,CAAC,eAAe,EAAE,aAAa,EAAE,YAAY,CAAC,CAAA;IACvE,MAAM,KAAK,GAAsB;QAC/B,EAAE;QACF,eAAe;QACf,aAAa;QACb,YAAY;QACZ,YAAY;QACZ,GAAG;QACH,IAAI;QACJ,YAAY;QACZ,GAAG;QACH,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,MAAM;QACN,YAAY;KACb,CAAA;IACD,MAAM,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;IAC/B,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,EAAE,GAAG,MAAM,KAAK,EAAE,CAAA;IACxB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAC3C,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAU;IACjD,MAAM,EAAE,GAAG,MAAM,KAAK,EAAE,CAAA;IACxB,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,EAAE,GAAG,MAAM,KAAK,EAAE,CAAA;IACxB,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;AAC5B,CAAC"}
|
package/dist/utils/fetch.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ export declare function textfetch(url: string, args?: RequestInit): Promise<stri
|
|
|
3
3
|
export declare function jsonfetch<T>(url: string, args?: RequestInit): Promise<T>;
|
|
4
4
|
export declare function timeout(time: number): Promise<unknown>;
|
|
5
5
|
export declare function fetchWithLocalStorageCache<T>(key: string, fetchFn: () => Promise<T>): Promise<T>;
|
|
6
|
-
export declare function unzipfetch(url: string, arg?: RequestInit): Promise<
|
|
6
|
+
export declare function unzipfetch(url: string, arg?: RequestInit): Promise<any>;
|
package/dist/utils/fetch.js
CHANGED
package/dist/utils/fetch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAElC,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,IAAkB;IAC/D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAEvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,QAAQ,QAAQ,CAAC,MAAM,aAAa,GAAG,IAAI,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,CACnE,CAAA;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,IAAkB;IAC7D,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAC7C,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAA;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,GAAW,EAAE,IAAkB;IAChE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAC7C,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAA;AACtC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,GAAW,EACX,OAAyB;IAEzB,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAE5C,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAM,CAAA;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAA;YAC7D,gDAAgD;YAChD,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAA;IAC5B,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;IAC/C,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,GAAiB;IAC7D,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACvC,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAA;AAC1D,CAAC"}
|
|
@@ -8,11 +8,7 @@ export declare function queryBlast({ query, blastDatabase, blastProgram, baseUrl
|
|
|
8
8
|
}): Promise<{
|
|
9
9
|
rid: string;
|
|
10
10
|
hits: {
|
|
11
|
-
description:
|
|
12
|
-
accession: string;
|
|
13
|
-
id: string;
|
|
14
|
-
sciname: string;
|
|
15
|
-
}[];
|
|
11
|
+
description: import("./types").BlastHitDescription[];
|
|
16
12
|
hsps: {
|
|
17
13
|
hseq: string;
|
|
18
14
|
}[];
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { openDB } from 'idb';
|
|
2
|
+
const DB_NAME = 'jbrowse-msaview-taxonomy-cache';
|
|
3
|
+
const STORE_NAME = 'common-names';
|
|
4
|
+
const DB_VERSION = 1;
|
|
5
|
+
async function getDB() {
|
|
6
|
+
return openDB(DB_NAME, DB_VERSION, {
|
|
7
|
+
upgrade(db) {
|
|
8
|
+
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
|
9
|
+
db.createObjectStore(STORE_NAME, { keyPath: 'taxid' });
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
async function getCachedCommonName(taxid) {
|
|
15
|
+
const db = await getDB();
|
|
16
|
+
return db.get(STORE_NAME, taxid);
|
|
17
|
+
}
|
|
18
|
+
async function saveTaxonomyCache(entries) {
|
|
19
|
+
const db = await getDB();
|
|
20
|
+
const tx = db.transaction(STORE_NAME, 'readwrite');
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
await tx.store.put(entry);
|
|
23
|
+
}
|
|
24
|
+
await tx.done;
|
|
25
|
+
}
|
|
26
|
+
export async function fetchTaxonomyInfo(taxids) {
|
|
27
|
+
const result = new Map();
|
|
28
|
+
const uncachedTaxids = [];
|
|
29
|
+
for (const taxid of taxids) {
|
|
30
|
+
const cached = await getCachedCommonName(taxid);
|
|
31
|
+
if (cached) {
|
|
32
|
+
result.set(taxid, {
|
|
33
|
+
sciname: cached.sciname,
|
|
34
|
+
commonName: cached.commonName,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
uncachedTaxids.push(taxid);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (uncachedTaxids.length === 0) {
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
const batchSize = 100;
|
|
45
|
+
const toCache = [];
|
|
46
|
+
for (let i = 0; i < uncachedTaxids.length; i += batchSize) {
|
|
47
|
+
const batch = uncachedTaxids.slice(i, i + batchSize);
|
|
48
|
+
const idsParam = batch.join(',');
|
|
49
|
+
try {
|
|
50
|
+
const response = await fetch(`https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=taxonomy&id=${idsParam}&retmode=xml`);
|
|
51
|
+
const text = await response.text();
|
|
52
|
+
for (const taxid of batch) {
|
|
53
|
+
const taxonRegex = new RegExp(`<Taxon>.*?<TaxId>${taxid}</TaxId>.*?</Taxon>`, 's');
|
|
54
|
+
const taxonMatch = taxonRegex.exec(text);
|
|
55
|
+
if (taxonMatch) {
|
|
56
|
+
const taxonXml = taxonMatch[0];
|
|
57
|
+
const genbankCommon = /<GenbankCommonName>(.*?)<\/GenbankCommonName>/.exec(taxonXml);
|
|
58
|
+
const commonName = /<CommonName>(.*?)<\/CommonName>/.exec(taxonXml);
|
|
59
|
+
const sciName = /<ScientificName>(.*?)<\/ScientificName>/.exec(taxonXml);
|
|
60
|
+
const name = genbankCommon?.[1] ?? commonName?.[1];
|
|
61
|
+
const sci = sciName?.[1] ?? '';
|
|
62
|
+
result.set(taxid, { sciname: sci, commonName: name });
|
|
63
|
+
toCache.push({ taxid, sciname: sci, commonName: name });
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
toCache.push({ taxid, sciname: '', commonName: undefined });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
console.error('Failed to fetch taxonomy data:', error);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (toCache.length > 0) {
|
|
75
|
+
await saveTaxonomyCache(toCache);
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=taxonomyNames.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taxonomyNames.js","sourceRoot":"","sources":["../../src/utils/taxonomyNames.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
export interface BlastHitDescription {
|
|
2
|
+
accession: string;
|
|
3
|
+
id: string;
|
|
4
|
+
sciname: string;
|
|
5
|
+
taxid?: number;
|
|
6
|
+
title?: string;
|
|
7
|
+
}
|
|
1
8
|
export interface BlastResults {
|
|
2
9
|
BlastOutput2: {
|
|
3
10
|
report: {
|
|
4
11
|
results: {
|
|
5
12
|
search: {
|
|
6
13
|
hits: {
|
|
7
|
-
description:
|
|
8
|
-
accession: string;
|
|
9
|
-
id: string;
|
|
10
|
-
sciname: string;
|
|
11
|
-
}[];
|
|
14
|
+
description: BlastHitDescription[];
|
|
12
15
|
hsps: {
|
|
13
16
|
hseq: string;
|
|
14
17
|
}[];
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.2.
|
|
2
|
+
"version": "2.2.4",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"name": "jbrowse-plugin-msaview",
|
|
5
5
|
"keywords": [
|
|
@@ -11,69 +11,65 @@
|
|
|
11
11
|
"dist",
|
|
12
12
|
"src"
|
|
13
13
|
],
|
|
14
|
-
"config": {
|
|
15
|
-
"port": 9000,
|
|
16
|
-
"browse": {
|
|
17
|
-
"port": 8999
|
|
18
|
-
},
|
|
19
|
-
"jbrowse": {
|
|
20
|
-
"plugin": {
|
|
21
|
-
"name": "MsaView"
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
14
|
"scripts": {
|
|
26
15
|
"clean": "rimraf dist",
|
|
27
|
-
"start": "node esbuild
|
|
16
|
+
"start": "node esbuild.mjs --watch",
|
|
28
17
|
"format": "prettier --write .",
|
|
29
18
|
"build": "tsc && NODE_ENV=production node esbuild.mjs && cp distconfig.json dist/config.json",
|
|
30
|
-
"prebuild": "
|
|
19
|
+
"prebuild": "yarn clean",
|
|
31
20
|
"lint": "eslint --report-unused-disable-directives --max-warnings 0",
|
|
32
|
-
"
|
|
21
|
+
"pretest": "rm -rf .test-jbrowse && npx @jbrowse/cli create .test-jbrowse --nightly",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"test:watch": "vitest",
|
|
24
|
+
"test:setup": "node scripts/test-versions.mjs setup",
|
|
25
|
+
"test:setup:version": "node scripts/test-versions.mjs setup",
|
|
26
|
+
"test:versions": "node scripts/test-versions.mjs run",
|
|
27
|
+
"test:version": "node scripts/test-versions.mjs run",
|
|
28
|
+
"prepack": "yarn build",
|
|
33
29
|
"postversion": "git push --follow-tags"
|
|
34
30
|
},
|
|
35
|
-
"jbrowse-plugin": {
|
|
36
|
-
"name": "MsaView"
|
|
37
|
-
},
|
|
38
31
|
"dependencies": {
|
|
39
|
-
"@emotion/styled": "^11.14.
|
|
40
|
-
"g2p_mapper": "^
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
32
|
+
"@emotion/styled": "^11.14.1",
|
|
33
|
+
"g2p_mapper": "^2.0.0",
|
|
34
|
+
"idb": "^8.0.3",
|
|
35
|
+
"pako-esm2": "^2.0.0",
|
|
36
|
+
"react-msaview": "^5.0.5",
|
|
37
|
+
"swr": "^2.3.8"
|
|
44
38
|
},
|
|
45
39
|
"devDependencies": {
|
|
46
|
-
"@emotion/react": "^11.
|
|
40
|
+
"@emotion/react": "^11.14.0",
|
|
41
|
+
"@eslint/js": "^9.39.2",
|
|
47
42
|
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
|
|
48
|
-
"@jbrowse/core": "^
|
|
49
|
-
"@jbrowse/
|
|
50
|
-
"@
|
|
51
|
-
"@mui/material": "^7.
|
|
52
|
-
"@mui/
|
|
53
|
-
"@mui/
|
|
54
|
-
"@
|
|
55
|
-
"@types/
|
|
56
|
-
"@types/
|
|
57
|
-
"@
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"eslint": "^
|
|
61
|
-
"eslint-plugin-
|
|
62
|
-
"eslint-plugin-react": "^7.
|
|
63
|
-
"eslint-plugin-react-
|
|
64
|
-
"eslint-plugin-
|
|
65
|
-
"
|
|
66
|
-
"mobx": "^
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"react": "^19.
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"tss-react": "^4.9.
|
|
76
|
-
"typescript": "^5.
|
|
77
|
-
"typescript-eslint": "^8.
|
|
43
|
+
"@jbrowse/core": "^4.1.1",
|
|
44
|
+
"@jbrowse/mobx-state-tree": "^5.4.2",
|
|
45
|
+
"@jbrowse/plugin-linear-genome-view": "^4.1.1",
|
|
46
|
+
"@mui/icons-material": "^7.3.7",
|
|
47
|
+
"@mui/material": "^7.3.7",
|
|
48
|
+
"@mui/system": "^7.3.7",
|
|
49
|
+
"@mui/x-data-grid": "^8.24.0",
|
|
50
|
+
"@types/node": "^24.10.4",
|
|
51
|
+
"@types/pako": "^2.0.4",
|
|
52
|
+
"@types/react": "^19.2.7",
|
|
53
|
+
"esbuild": "^0.27.2",
|
|
54
|
+
"eslint": "^9.39.2",
|
|
55
|
+
"eslint-plugin-import": "^2.32.0",
|
|
56
|
+
"eslint-plugin-react": "^7.37.5",
|
|
57
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
58
|
+
"eslint-plugin-react-refresh": "^0.4.26",
|
|
59
|
+
"eslint-plugin-unicorn": "^62.0.0",
|
|
60
|
+
"mobx": "^6.15.0",
|
|
61
|
+
"mobx-react": "^9.2.1",
|
|
62
|
+
"prettier": "^3.7.4",
|
|
63
|
+
"pretty-bytes": "^7.1.0",
|
|
64
|
+
"puppeteer": "^24.34.0",
|
|
65
|
+
"react": "^19.2.3",
|
|
66
|
+
"react-dom": "^19.2.3",
|
|
67
|
+
"rimraf": "^6.1.2",
|
|
68
|
+
"rxjs": "^7.8.2",
|
|
69
|
+
"serve": "^14.2.5",
|
|
70
|
+
"tss-react": "^4.9.20",
|
|
71
|
+
"typescript": "^5.9.3",
|
|
72
|
+
"typescript-eslint": "^8.52.0",
|
|
73
|
+
"vitest": "^4.0.16"
|
|
78
74
|
}
|
|
79
75
|
}
|
|
@@ -12,35 +12,51 @@ const GenomeMouseoverHighlight = observer(function ({
|
|
|
12
12
|
}: {
|
|
13
13
|
model: LinearGenomeViewModel
|
|
14
14
|
}) {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
)
|
|
15
|
+
const session = getSession(model)
|
|
16
|
+
const { hovered, views } = session
|
|
17
|
+
|
|
18
|
+
// Early return if no MSA view exists
|
|
19
|
+
const hasMsaView = views.some(s => s.type === 'MsaView')
|
|
20
|
+
if (!hasMsaView) {
|
|
21
|
+
return null
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Early return if no hover position
|
|
25
|
+
if (
|
|
26
|
+
!hovered ||
|
|
27
|
+
typeof hovered !== 'object' ||
|
|
28
|
+
!('hoverPosition' in hovered)
|
|
29
|
+
) {
|
|
30
|
+
return null
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return <GenomeMouseoverHighlightRenderer model={model} hovered={hovered} />
|
|
21
34
|
})
|
|
22
35
|
|
|
23
|
-
const
|
|
36
|
+
const GenomeMouseoverHighlightRenderer = observer(function ({
|
|
24
37
|
model,
|
|
38
|
+
hovered,
|
|
25
39
|
}: {
|
|
26
40
|
model: LinearGenomeViewModel
|
|
41
|
+
|
|
42
|
+
hovered: any
|
|
27
43
|
}) {
|
|
28
44
|
const { classes } = useStyles()
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
45
|
+
const { offsetPx } = model
|
|
46
|
+
const { coord, refName } = hovered.hoverPosition as {
|
|
47
|
+
coord: number
|
|
48
|
+
refName: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const s = model.bpToPx({ refName, coord: coord - 1 })
|
|
52
|
+
const e = model.bpToPx({ refName, coord: coord })
|
|
53
|
+
|
|
54
|
+
if (s && e) {
|
|
55
|
+
const width = Math.max(Math.abs(e.offsetPx - s.offsetPx), 4)
|
|
56
|
+
const left = Math.min(s.offsetPx, e.offsetPx) - offsetPx
|
|
57
|
+
return <div className={classes.highlight} style={{ left, width }} />
|
|
43
58
|
}
|
|
59
|
+
|
|
44
60
|
return null
|
|
45
61
|
})
|
|
46
62
|
|
|
@@ -1,53 +1,74 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
|
|
3
|
-
import { Assembly } from '@jbrowse/core/assemblyManager/assembly'
|
|
4
3
|
import { getSession } from '@jbrowse/core/util'
|
|
5
4
|
import { observer } from 'mobx-react'
|
|
6
5
|
|
|
7
6
|
import { useStyles } from './util'
|
|
8
|
-
import { JBrowsePluginMsaViewModel } from '../MsaViewPanel/model'
|
|
9
7
|
|
|
8
|
+
import type { JBrowsePluginMsaViewModel } from '../MsaViewPanel/model'
|
|
10
9
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
11
10
|
|
|
12
11
|
type LGV = LinearGenomeViewModel
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
return assembly.getCanonicalRefName(s) ?? s
|
|
16
|
-
}
|
|
17
|
-
|
|
13
|
+
// Outer component: only re-renders when MSA view or highlights change
|
|
18
14
|
const MsaToGenomeHighlight = observer(function MsaToGenomeHighlight2({
|
|
19
15
|
model,
|
|
20
16
|
}: {
|
|
21
17
|
model: LGV
|
|
22
18
|
}) {
|
|
23
|
-
const {
|
|
24
|
-
const
|
|
25
|
-
const p = views.find(f => f.type === 'MsaView') as
|
|
19
|
+
const { views } = getSession(model)
|
|
20
|
+
const msaView = views.find(f => f.type === 'MsaView') as
|
|
26
21
|
| JBrowsePluginMsaViewModel
|
|
27
22
|
| undefined
|
|
23
|
+
|
|
24
|
+
const highlights = msaView?.connectedHighlights
|
|
25
|
+
|
|
26
|
+
// Early return if no highlights - avoid all other work
|
|
27
|
+
if (!highlights || highlights.length === 0) {
|
|
28
|
+
return null
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return <MsaToGenomeHighlightRenderer model={model} highlights={highlights} />
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
// Inner component: handles the scroll-dependent rendering
|
|
35
|
+
const MsaToGenomeHighlightRenderer = observer(function ({
|
|
36
|
+
model,
|
|
37
|
+
highlights,
|
|
38
|
+
}: {
|
|
39
|
+
model: LGV
|
|
40
|
+
highlights: { refName: string; start: number; end: number }[]
|
|
41
|
+
}) {
|
|
42
|
+
const { classes } = useStyles()
|
|
43
|
+
const { assemblyManager } = getSession(model)
|
|
28
44
|
const assembly = assemblyManager.get(model.assemblyNames[0]!)
|
|
29
|
-
|
|
45
|
+
const { offsetPx } = model
|
|
46
|
+
|
|
47
|
+
if (!assembly) {
|
|
48
|
+
return null
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return (
|
|
30
52
|
<>
|
|
31
|
-
{
|
|
32
|
-
const refName =
|
|
53
|
+
{highlights.map((r, idx) => {
|
|
54
|
+
const refName = assembly.getCanonicalRefName(r.refName) ?? r.refName
|
|
33
55
|
const s = model.bpToPx({ refName, coord: r.start })
|
|
34
56
|
const e = model.bpToPx({ refName, coord: r.end })
|
|
35
57
|
if (s && e) {
|
|
36
58
|
const width = Math.max(Math.abs(e.offsetPx - s.offsetPx), 4)
|
|
37
|
-
const left = Math.min(s.offsetPx, e.offsetPx) -
|
|
59
|
+
const left = Math.min(s.offsetPx, e.offsetPx) - offsetPx
|
|
38
60
|
return (
|
|
39
61
|
<div
|
|
40
|
-
key={`${
|
|
62
|
+
key={`${r.refName}-${r.start}-${r.end}-${idx}`}
|
|
41
63
|
className={classes.highlight}
|
|
42
64
|
style={{ left, width }}
|
|
43
65
|
/>
|
|
44
66
|
)
|
|
45
|
-
} else {
|
|
46
|
-
return null
|
|
47
67
|
}
|
|
68
|
+
return null
|
|
48
69
|
})}
|
|
49
70
|
</>
|
|
50
|
-
)
|
|
71
|
+
)
|
|
51
72
|
})
|
|
52
73
|
|
|
53
74
|
export default MsaToGenomeHighlight
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
|
|
3
3
|
import PluginManager from '@jbrowse/core/PluginManager'
|
|
4
|
+
import { getSession } from '@jbrowse/core/util'
|
|
4
5
|
|
|
5
6
|
import HighlightComponents from './HighlightComponents'
|
|
6
7
|
|
|
@@ -12,10 +13,14 @@ export default function AddHighlightComponentsModelF(
|
|
|
12
13
|
pluginManager.addToExtensionPoint(
|
|
13
14
|
'LinearGenomeView-TracksContainerComponent',
|
|
14
15
|
// @ts-expect-error
|
|
15
|
-
(
|
|
16
|
-
|
|
17
|
-
{
|
|
18
|
-
|
|
16
|
+
(rest: React.ReactNode[], { model }: { model: LinearGenomeViewModel }) => {
|
|
17
|
+
// Quick check: don't add any components if no MSA view exists
|
|
18
|
+
const { views } = getSession(model)
|
|
19
|
+
const hasMsaView = views.some(v => v.type === 'MsaView')
|
|
20
|
+
if (!hasMsaView) {
|
|
21
|
+
return rest
|
|
22
|
+
}
|
|
23
|
+
|
|
19
24
|
return [
|
|
20
25
|
...rest,
|
|
21
26
|
<HighlightComponents
|
|
@@ -13,9 +13,9 @@ import { makeStyles } from 'tss-react/mui'
|
|
|
13
13
|
|
|
14
14
|
import { ensemblGeneTreeLaunchView } from './ensemblGeneTreeLaunchView'
|
|
15
15
|
import { useGeneTree } from './useGeneTree'
|
|
16
|
-
import { getGeneDisplayName
|
|
16
|
+
import { getGeneDisplayName } from '../../util'
|
|
17
17
|
import TranscriptSelector from '../TranscriptSelector'
|
|
18
|
-
import {
|
|
18
|
+
import { useTranscriptSelection } from '../useTranscriptSelection'
|
|
19
19
|
|
|
20
20
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
21
21
|
|
|
@@ -41,15 +41,15 @@ const EnsemblGeneTree = observer(function ({
|
|
|
41
41
|
const view = getContainingView(model) as LinearGenomeViewModel
|
|
42
42
|
const { classes } = useStyles()
|
|
43
43
|
const [launchViewError, setLaunchViewError] = useState<unknown>()
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
})
|
|
44
|
+
const {
|
|
45
|
+
options,
|
|
46
|
+
selectedId,
|
|
47
|
+
setSelectedId,
|
|
48
|
+
selectedTranscript,
|
|
49
|
+
proteinSequence,
|
|
50
|
+
error: featureSequenceError,
|
|
51
|
+
} = useTranscriptSelection({ feature, view })
|
|
52
|
+
const { treeData, isTreeLoading, treeError } = useGeneTree(selectedId)
|
|
53
53
|
|
|
54
54
|
const loadingMessage = isTreeLoading
|
|
55
55
|
? 'Loading tree data from Ensembl GeneTree'
|
|
@@ -76,8 +76,8 @@ const EnsemblGeneTree = observer(function ({
|
|
|
76
76
|
<TranscriptSelector
|
|
77
77
|
feature={feature}
|
|
78
78
|
options={options}
|
|
79
|
-
|
|
80
|
-
onTranscriptChange={
|
|
79
|
+
selectedTranscript={selectedTranscript}
|
|
80
|
+
onTranscriptChange={setSelectedId}
|
|
81
81
|
proteinSequence={proteinSequence}
|
|
82
82
|
/>
|
|
83
83
|
</DialogContent>
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import useSWR from 'swr'
|
|
2
|
+
|
|
2
3
|
import { geneTreeFetcher } from './ensemblGeneTreeUtils'
|
|
3
4
|
|
|
4
5
|
export function useGeneTree(geneId: string) {
|
|
5
6
|
const { data, error, isLoading } = useSWR(
|
|
6
7
|
() => (geneId ? ['geneTree', geneId] : null),
|
|
7
8
|
([, geneId]) => geneTreeFetcher(geneId),
|
|
9
|
+
{
|
|
10
|
+
revalidateOnFocus: false,
|
|
11
|
+
revalidateOnReconnect: false,
|
|
12
|
+
revalidateIfStale: false,
|
|
13
|
+
},
|
|
8
14
|
)
|
|
9
15
|
|
|
10
16
|
return { treeData: data, isTreeLoading: isLoading, treeError: error }
|