jbrowse-plugin-msaview 2.2.7 → 2.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/BgzipFastaMsaAdapter/configSchema.d.ts +2 -2
  2. package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js +1 -1
  3. package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js.map +1 -1
  4. package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js +2 -2
  5. package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js.map +1 -1
  6. package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js +29 -6
  7. package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js.map +1 -1
  8. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js +16 -6
  9. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js.map +1 -1
  10. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js +2 -2
  11. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js.map +1 -1
  12. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastMethodSelector.js +3 -2
  13. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastMethodSelector.js.map +1 -1
  14. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.js +7 -3
  15. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.js.map +1 -1
  16. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.d.ts +10 -0
  17. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.js +77 -0
  18. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.js.map +1 -0
  19. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +1 -1
  20. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js.map +1 -1
  21. package/dist/LaunchMsaView/components/TranscriptSelector.d.ts +2 -1
  22. package/dist/LaunchMsaView/components/TranscriptSelector.js +7 -6
  23. package/dist/LaunchMsaView/components/TranscriptSelector.js.map +1 -1
  24. package/dist/LaunchMsaView/components/useTranscriptSelection.js +13 -7
  25. package/dist/LaunchMsaView/components/useTranscriptSelection.js.map +1 -1
  26. package/dist/LaunchMsaView/util.d.ts +2 -0
  27. package/dist/LaunchMsaView/util.js +18 -2
  28. package/dist/LaunchMsaView/util.js.map +1 -1
  29. package/dist/MsaViewPanel/doLaunchBlast.js +36 -15
  30. package/dist/MsaViewPanel/doLaunchBlast.js.map +1 -1
  31. package/dist/MsaViewPanel/model.d.ts +7 -0
  32. package/dist/MsaViewPanel/model.js.map +1 -1
  33. package/dist/index.d.ts +5 -5
  34. package/dist/index.js +21 -22
  35. package/dist/index.js.map +1 -1
  36. package/dist/jbrowse-plugin-msaview.umd.production.min.js +27 -27
  37. package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
  38. package/dist/utils/blastCache.d.ts +8 -2
  39. package/dist/utils/blastCache.js +19 -6
  40. package/dist/utils/blastCache.js.map +1 -1
  41. package/dist/utils/ncbiBlast.d.ts +13 -0
  42. package/dist/utils/ncbiBlast.js +13 -0
  43. package/dist/utils/ncbiBlast.js.map +1 -1
  44. package/dist/version.d.ts +1 -1
  45. package/dist/version.js +1 -1
  46. package/dist/version.js.map +1 -1
  47. package/package.json +7 -7
  48. package/src/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.tsx +1 -0
  49. package/src/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.tsx +2 -0
  50. package/src/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.tsx +32 -6
  51. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.tsx +19 -4
  52. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.tsx +9 -2
  53. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastMethodSelector.tsx +4 -3
  54. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.tsx +8 -4
  55. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.tsx +187 -0
  56. package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +1 -0
  57. package/src/LaunchMsaView/components/TranscriptSelector.tsx +10 -6
  58. package/src/LaunchMsaView/components/useTranscriptSelection.ts +16 -7
  59. package/src/LaunchMsaView/util.ts +20 -2
  60. package/src/MsaViewPanel/doLaunchBlast.ts +37 -14
  61. package/src/MsaViewPanel/model.ts +1 -0
  62. package/src/index.ts +1 -2
  63. package/src/utils/blastCache.ts +36 -3
  64. package/src/utils/ncbiBlast.ts +24 -0
  65. package/src/version.ts +1 -1
@@ -11,13 +11,16 @@ export interface CachedBlastResult {
11
11
  timestamp: number;
12
12
  geneId?: string;
13
13
  transcriptId?: string;
14
+ transcriptName?: string;
15
+ geneName?: string;
14
16
  }
15
- export declare function getCachedBlastResult({ proteinSequence, blastDatabase, blastProgram, }: {
17
+ export declare function getCachedBlastResult({ proteinSequence, blastDatabase, blastProgram, transcriptId, }: {
16
18
  proteinSequence: string;
17
19
  blastDatabase: string;
18
20
  blastProgram: string;
21
+ transcriptId?: string;
19
22
  }): Promise<any>;
20
- export declare function saveBlastResult({ proteinSequence, blastDatabase, blastProgram, msaAlgorithm, msa, tree, treeMetadata, rid, geneId, transcriptId, }: {
23
+ export declare function saveBlastResult({ proteinSequence, blastDatabase, blastProgram, msaAlgorithm, msa, tree, treeMetadata, rid, geneId, transcriptId, transcriptName, geneName, }: {
21
24
  proteinSequence: string;
22
25
  blastDatabase: string;
23
26
  blastProgram: string;
@@ -28,7 +31,10 @@ export declare function saveBlastResult({ proteinSequence, blastDatabase, blastP
28
31
  rid: string;
29
32
  geneId?: string;
30
33
  transcriptId?: string;
34
+ transcriptName?: string;
35
+ geneName?: string;
31
36
  }): Promise<CachedBlastResult>;
32
37
  export declare function getAllCachedResults(): Promise<any[]>;
38
+ export declare function getCachedResultsByGeneId(geneId: string): Promise<any[]>;
33
39
  export declare function deleteCachedResult(id: string): Promise<void>;
34
40
  export declare function clearAllCachedResults(): Promise<void>;
@@ -14,17 +14,21 @@ async function getDB() {
14
14
  },
15
15
  });
16
16
  }
17
- function createCacheKey(proteinSequence, blastDatabase, blastProgram) {
18
- return `${blastDatabase}:${blastProgram}:${proteinSequence.slice(0, 100)}`;
17
+ function createCacheKey(proteinSequence, blastDatabase, blastProgram, transcriptId) {
18
+ const seqKey = proteinSequence.slice(0, 100);
19
+ if (transcriptId) {
20
+ return `${blastDatabase}:${blastProgram}:${transcriptId}:${seqKey}`;
21
+ }
22
+ return `${blastDatabase}:${blastProgram}:${seqKey}`;
19
23
  }
20
- export async function getCachedBlastResult({ proteinSequence, blastDatabase, blastProgram, }) {
24
+ export async function getCachedBlastResult({ proteinSequence, blastDatabase, blastProgram, transcriptId, }) {
21
25
  const db = await getDB();
22
- const id = createCacheKey(proteinSequence, blastDatabase, blastProgram);
26
+ const id = createCacheKey(proteinSequence, blastDatabase, blastProgram, transcriptId);
23
27
  return db.get(STORE_NAME, id);
24
28
  }
25
- export async function saveBlastResult({ proteinSequence, blastDatabase, blastProgram, msaAlgorithm, msa, tree, treeMetadata, rid, geneId, transcriptId, }) {
29
+ export async function saveBlastResult({ proteinSequence, blastDatabase, blastProgram, msaAlgorithm, msa, tree, treeMetadata, rid, geneId, transcriptId, transcriptName, geneName, }) {
26
30
  const db = await getDB();
27
- const id = createCacheKey(proteinSequence, blastDatabase, blastProgram);
31
+ const id = createCacheKey(proteinSequence, blastDatabase, blastProgram, transcriptId);
28
32
  const entry = {
29
33
  id,
30
34
  proteinSequence,
@@ -38,6 +42,8 @@ export async function saveBlastResult({ proteinSequence, blastDatabase, blastPro
38
42
  timestamp: Date.now(),
39
43
  geneId,
40
44
  transcriptId,
45
+ transcriptName,
46
+ geneName,
41
47
  };
42
48
  await db.put(STORE_NAME, entry);
43
49
  return entry;
@@ -47,6 +53,13 @@ export async function getAllCachedResults() {
47
53
  const results = await db.getAll(STORE_NAME);
48
54
  return results.toSorted((a, b) => b.timestamp - a.timestamp);
49
55
  }
56
+ export async function getCachedResultsByGeneId(geneId) {
57
+ const db = await getDB();
58
+ const results = await db.getAll(STORE_NAME);
59
+ return results
60
+ .filter(r => r.geneId === geneId)
61
+ .toSorted((a, b) => b.timestamp - a.timestamp);
62
+ }
50
63
  export async function deleteCachedResult(id) {
51
64
  const db = await getDB();
52
65
  await db.delete(STORE_NAME, id);
@@ -1 +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"}
1
+ {"version":3,"file":"blastCache.js","sourceRoot":"","sources":["../../src/utils/blastCache.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,16 @@
1
+ export declare function queryBlastFromRid({ rid, baseUrl, onProgress, }: {
2
+ rid: string;
3
+ baseUrl: string;
4
+ onProgress: (arg: string) => void;
5
+ }): Promise<{
6
+ rid: string;
7
+ hits: {
8
+ description: import("./types").BlastHitDescription[];
9
+ hsps: {
10
+ hseq: string;
11
+ }[];
12
+ }[];
13
+ }>;
1
14
  export declare function queryBlast({ query, blastDatabase, blastProgram, baseUrl, onProgress, onRid, }: {
2
15
  query: string;
3
16
  blastDatabase: string;
@@ -1,4 +1,17 @@
1
1
  import { jsonfetch, textfetch, timeout } from './fetch';
2
+ export async function queryBlastFromRid({ rid, baseUrl, onProgress, }) {
3
+ onProgress(`Checking BLAST status for RID: ${rid}...`);
4
+ await waitForRid({
5
+ rid,
6
+ onProgress,
7
+ baseUrl,
8
+ });
9
+ const ret = await jsonfetch(`${baseUrl}?CMD=Get&RID=${rid}&FORMAT_TYPE=JSON2_S&FORMAT_OBJECT=Alignment`);
10
+ return {
11
+ rid,
12
+ hits: ret.BlastOutput2[0]?.report.results.search.hits ?? [],
13
+ };
14
+ }
2
15
  export async function queryBlast({ query, blastDatabase, blastProgram, baseUrl, onProgress, onRid, }) {
3
16
  onProgress('Submitting to NCBI BLAST...');
4
17
  const { rid } = await initialQuery({
@@ -1 +1 @@
1
- {"version":3,"file":"ncbiBlast.js","sourceRoot":"","sources":["../../src/utils/ncbiBlast.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ncbiBlast.js","sourceRoot":"","sources":["../../src/utils/ncbiBlast.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.2.7";
1
+ export declare const version = "2.2.11";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '2.2.7';
1
+ export const version = '2.2.11';
2
2
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAA"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAA"}
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.2.7",
2
+ "version": "2.2.11",
3
3
  "license": "MIT",
4
4
  "name": "jbrowse-plugin-msaview",
5
5
  "keywords": [
@@ -35,7 +35,7 @@
35
35
  "g2p_mapper": "^2.0.0",
36
36
  "idb": "^8.0.3",
37
37
  "pako-esm2": "^2.0.0",
38
- "react-msaview": "^5.0.6",
38
+ "react-msaview": "^5.0.7",
39
39
  "swr": "^2.3.8"
40
40
  },
41
41
  "devDependencies": {
@@ -56,8 +56,8 @@
56
56
  "eslint-plugin-import": "^2.32.0",
57
57
  "eslint-plugin-react": "^7.37.5",
58
58
  "eslint-plugin-react-hooks": "^7.0.1",
59
- "eslint-plugin-react-refresh": "^0.4.26",
60
- "eslint-plugin-unicorn": "^62.0.0",
59
+ "eslint-plugin-react-refresh": "^0.5.2",
60
+ "eslint-plugin-unicorn": "^63.0.0",
61
61
  "mobx": "^6.15.0",
62
62
  "mobx-react": "^9.2.1",
63
63
  "prettier": "^3.7.4",
@@ -69,8 +69,8 @@
69
69
  "rxjs": "^7.8.2",
70
70
  "serve": "^14.2.5",
71
71
  "tss-react": "^4.9.20",
72
- "typescript": "^5.9.3",
73
- "typescript-eslint": "^8.54.0",
74
- "vitest": "^4.0.16"
72
+ "typescript": "^6.0.2",
73
+ "typescript-eslint": "^8.57.2",
74
+ "vitest": "^4.1.1"
75
75
  }
76
76
  }
@@ -76,6 +76,7 @@ const EnsemblGeneTree = observer(function ({
76
76
  <TranscriptSelector
77
77
  feature={feature}
78
78
  options={options}
79
+ selectedId={selectedId}
79
80
  selectedTranscript={selectedTranscript}
80
81
  onTranscriptChange={setSelectedId}
81
82
  proteinSequence={proteinSequence}
@@ -59,6 +59,7 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
59
59
  const [querySeqName, setQuerySeqName] = useState('')
60
60
  const {
61
61
  options,
62
+ selectedId,
62
63
  setSelectedId,
63
64
  selectedTranscript,
64
65
  proteinSequence,
@@ -143,6 +144,7 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
143
144
  <TranscriptSelector
144
145
  feature={feature}
145
146
  options={options}
147
+ selectedId={selectedId}
146
148
  selectedTranscript={selectedTranscript}
147
149
  onTranscriptChange={setSelectedId}
148
150
  proteinSequence={proteinSequence}
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react'
1
+ import React, { useEffect, useMemo, useState } from 'react'
2
2
 
3
3
  import { Feature, getContainingView } from '@jbrowse/core/util'
4
4
  import DeleteIcon from '@mui/icons-material/Delete'
@@ -24,6 +24,31 @@ import type { CachedBlastResult } from '../../../utils/blastCache'
24
24
  import type { AbstractTrackModel } from '@jbrowse/core/util'
25
25
  import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
26
26
 
27
+ function getGeneIdentifiers(feature: Feature): string[] {
28
+ const ids = [
29
+ feature.id(),
30
+ feature.get('id'),
31
+ feature.get('name'),
32
+ feature.get('gene_id'),
33
+ feature.get('gene_name'),
34
+ ].filter((id): id is string => !!id)
35
+ return [...new Set(ids)]
36
+ }
37
+
38
+ function getResultDisplayName(result: CachedBlastResult): string {
39
+ const parts = []
40
+ if (result.geneName) {
41
+ parts.push(result.geneName)
42
+ }
43
+ if (result.transcriptName && result.transcriptName !== result.geneName) {
44
+ parts.push(result.transcriptName)
45
+ }
46
+ if (parts.length === 0) {
47
+ parts.push(result.geneId ?? result.transcriptId ?? 'Unknown')
48
+ }
49
+ return parts.join(' - ')
50
+ }
51
+
27
52
  const CachedBlastResults = observer(function ({
28
53
  model,
29
54
  handleClose,
@@ -37,19 +62,20 @@ const CachedBlastResults = observer(function ({
37
62
  const [loading, setLoading] = useState(true)
38
63
  const view = getContainingView(model) as LinearGenomeViewModel
39
64
 
40
- const geneId = feature.get('id')
65
+ const geneIds = useMemo(() => getGeneIdentifiers(feature), [feature])
66
+
41
67
  useEffect(() => {
42
68
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
43
69
  ;(async () => {
44
70
  try {
45
71
  const cached = await getAllCachedResults()
46
- setResults(cached.filter(r => r.geneId === geneId))
72
+ setResults(cached.filter(r => r.geneId && geneIds.includes(r.geneId)))
47
73
  setLoading(false)
48
74
  } catch (e) {
49
75
  console.error(e)
50
76
  }
51
77
  })()
52
- }, [geneId])
78
+ }, [geneIds])
53
79
 
54
80
  const handleDelete = async (id: string) => {
55
81
  await deleteCachedResult(id)
@@ -65,7 +91,7 @@ const CachedBlastResults = observer(function ({
65
91
  blastLaunchViewFromCache({
66
92
  view,
67
93
  cached,
68
- newViewTitle: `BLAST - ${cached.geneId ?? cached.transcriptId ?? 'Unknown gene'}`,
94
+ newViewTitle: `BLAST - ${getResultDisplayName(cached)}`,
69
95
  })
70
96
  handleClose()
71
97
  }
@@ -132,7 +158,7 @@ const CachedBlastResults = observer(function ({
132
158
  }}
133
159
  >
134
160
  <ListItemText
135
- primary={`${result.geneId ?? result.transcriptId ?? 'Unknown'} - ${result.blastDatabase}/${result.blastProgram} (${result.msaAlgorithm})`}
161
+ primary={`${getResultDisplayName(result)} - ${result.blastDatabase}/${result.blastProgram} (${result.msaAlgorithm})`}
136
162
  secondary={`${new Date(result.timestamp).toLocaleString()} - Seq: ${result.proteinSequence.slice(0, 30)}...`}
137
163
  />
138
164
  </ListItemButton>
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react'
1
+ import React, { useEffect, useMemo, useState } from 'react'
2
2
 
3
3
  import { ErrorMessage } from '@jbrowse/core/ui'
4
4
  import {
@@ -30,6 +30,17 @@ import { useTranscriptSelection } from '../useTranscriptSelection'
30
30
 
31
31
  import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
32
32
 
33
+ function getGeneIdentifiers(feature: Feature): string[] {
34
+ const ids = [
35
+ feature.id(),
36
+ feature.get('id'),
37
+ feature.get('name'),
38
+ feature.get('gene_id'),
39
+ feature.get('gene_name'),
40
+ ].filter((id): id is string => !!id)
41
+ return [...new Set(ids)]
42
+ }
43
+
33
44
  const useStyles = makeStyles()({
34
45
  dialogContent: {
35
46
  width: '80em',
@@ -72,22 +83,25 @@ const NCBIBlastAutomaticPanel = observer(function ({
72
83
  const [hasCachedResults, setHasCachedResults] = useState(false)
73
84
  const [error, setError] = useState<unknown>()
74
85
 
75
- const geneId = feature.get('id')
86
+ const geneIds = useMemo(() => getGeneIdentifiers(feature), [feature])
76
87
  useEffect(() => {
77
88
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
78
89
  ;(async () => {
79
90
  try {
80
91
  const results = await getAllCachedResults()
81
- setHasCachedResults(results.some(r => r.geneId === geneId))
92
+ setHasCachedResults(
93
+ results.some(r => r.geneId && geneIds.includes(r.geneId)),
94
+ )
82
95
  } catch (e) {
83
96
  console.error(e)
84
97
  setError(e)
85
98
  }
86
99
  })()
87
- }, [geneId])
100
+ }, [geneIds])
88
101
 
89
102
  const {
90
103
  options,
104
+ selectedId,
91
105
  setSelectedId,
92
106
  selectedTranscript,
93
107
  proteinSequence,
@@ -180,6 +194,7 @@ const NCBIBlastAutomaticPanel = observer(function ({
180
194
  <TranscriptSelector
181
195
  feature={feature}
182
196
  options={options}
197
+ selectedId={selectedId}
183
198
  selectedTranscript={selectedTranscript}
184
199
  onTranscriptChange={setSelectedId}
185
200
  proteinSequence={proteinSequence}
@@ -43,8 +43,14 @@ const NCBIBlastManualPanel = observer(function ({
43
43
  }) {
44
44
  const { classes } = useStyles()
45
45
  const view = getContainingView(model) as LinearGenomeViewModel
46
- const { options, setSelectedId, selectedTranscript, proteinSequence, error } =
47
- useTranscriptSelection({ feature, view })
46
+ const {
47
+ options,
48
+ selectedId,
49
+ setSelectedId,
50
+ selectedTranscript,
51
+ proteinSequence,
52
+ error,
53
+ } = useTranscriptSelection({ feature, view })
48
54
 
49
55
  const s2 = cleanProteinSequence(proteinSequence)
50
56
  const link = `${baseUrl}?PAGE_TYPE=BlastSearch&PAGE=Proteins&PROGRAM=blastp&QUERY=${s2}`
@@ -59,6 +65,7 @@ const NCBIBlastManualPanel = observer(function ({
59
65
  <TranscriptSelector
60
66
  feature={feature}
61
67
  options={options}
68
+ selectedId={selectedId}
62
69
  selectedTranscript={selectedTranscript}
63
70
  onTranscriptChange={setSelectedId}
64
71
  proteinSequence={proteinSequence}
@@ -21,13 +21,14 @@ export default function NCBIBlastMethodSelector({
21
21
  <FormControlLabel
22
22
  value="automatic"
23
23
  control={<Radio />}
24
- label="Run NCBI BLAST and load results automatically"
24
+ label="Automatic"
25
25
  />
26
26
  <FormControlLabel
27
- value="manual"
27
+ value="rid"
28
28
  control={<Radio />}
29
- label="Link to NCBI BLAST and import results manually"
29
+ label="Load from RID"
30
30
  />
31
+ <FormControlLabel value="manual" control={<Radio />} label="Manual" />
31
32
  </RadioGroup>
32
33
  </FormControl>
33
34
  )
@@ -7,11 +7,18 @@ import { IconButton } from '@mui/material'
7
7
  import NCBIBlastAutomaticPanel from './NCBIBlastAutomaticPanel'
8
8
  import NCBIBlastManualPanel from './NCBIBlastManualPanel'
9
9
  import NCBIBlastMethodSelector from './NCBIBlastMethodSelector'
10
+ import NCBIBlastRIDPanel from './NCBIBlastRIDPanel'
10
11
  import NCBISettingsDialog from './NCBISettingsDialog'
11
12
  import { BASE_BLAST_URL } from './consts'
12
13
 
13
14
  import type { AbstractTrackModel, Feature } from '@jbrowse/core/util'
14
15
 
16
+ const panelMap = {
17
+ automatic: NCBIBlastAutomaticPanel,
18
+ rid: NCBIBlastRIDPanel,
19
+ manual: NCBIBlastManualPanel,
20
+ } as const
21
+
15
22
  export default function NCBIBlastPanel({
16
23
  handleClose,
17
24
  model,
@@ -28,10 +35,7 @@ export default function NCBIBlastPanel({
28
35
  )
29
36
  const [settingsOpen, setSettingsOpen] = useState(false)
30
37
 
31
- const Panel =
32
- lookupMethod === 'automatic'
33
- ? NCBIBlastAutomaticPanel
34
- : NCBIBlastManualPanel
38
+ const Panel = panelMap[lookupMethod as keyof typeof panelMap]
35
39
 
36
40
  return (
37
41
  <>
@@ -0,0 +1,187 @@
1
+ import React, { useState } from 'react'
2
+
3
+ import { ErrorMessage } from '@jbrowse/core/ui'
4
+ import {
5
+ AbstractTrackModel,
6
+ Feature,
7
+ getContainingView,
8
+ } from '@jbrowse/core/util'
9
+ import {
10
+ Button,
11
+ DialogActions,
12
+ DialogContent,
13
+ MenuItem,
14
+ Typography,
15
+ } from '@mui/material'
16
+ import { observer } from 'mobx-react'
17
+ import { makeStyles } from 'tss-react/mui'
18
+
19
+ import { blastLaunchView } from './blastLaunchView'
20
+ import ExternalLink from '../../../components/ExternalLink'
21
+ import TextField2 from '../../../components/TextField2'
22
+ import { getGeneDisplayName, getTranscriptDisplayName } from '../../util'
23
+ import TranscriptSelector from '../TranscriptSelector'
24
+ import { useTranscriptSelection } from '../useTranscriptSelection'
25
+
26
+ import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
27
+
28
+ const useStyles = makeStyles()({
29
+ dialogContent: {
30
+ width: '80em',
31
+ },
32
+ })
33
+
34
+ const msaAlgorithms = ['clustalo', 'muscle', 'kalign', 'mafft'] as const
35
+
36
+ type msaAlgorithmsT = (typeof msaAlgorithms)[number]
37
+
38
+ const NCBIBlastRIDPanel = observer(function ({
39
+ handleClose,
40
+ feature,
41
+ model,
42
+ children,
43
+ baseUrl,
44
+ }: {
45
+ model: AbstractTrackModel
46
+ feature: Feature
47
+ baseUrl: string
48
+ handleClose: () => void
49
+ children: React.ReactNode
50
+ }) {
51
+ const { classes } = useStyles()
52
+ const view = getContainingView(model) as LinearGenomeViewModel
53
+ const [launchViewError, setLaunchViewError] = useState<unknown>()
54
+ const [rid, setRid] = useState('')
55
+ const [selectedMsaAlgorithm, setSelectedMsaAlgorithm] =
56
+ useState<msaAlgorithmsT>('clustalo')
57
+
58
+ const {
59
+ options,
60
+ selectedId,
61
+ setSelectedId,
62
+ selectedTranscript,
63
+ proteinSequence,
64
+ error: proteinSequenceError,
65
+ } = useTranscriptSelection({ feature, view })
66
+
67
+ const e = proteinSequenceError ?? launchViewError
68
+ const style = { width: 150 }
69
+ const trimmedRid = rid.trim()
70
+
71
+ return (
72
+ <>
73
+ <DialogContent className={classes.dialogContent}>
74
+ {children}
75
+ {e ? <ErrorMessage error={e} /> : null}
76
+
77
+ <Typography variant="body2" style={{ marginBottom: 16 }}>
78
+ Enter the RID (Request ID) from a previously submitted NCBI BLAST
79
+ query. You can find the RID in the BLAST results page URL or at the
80
+ top of the results page. RIDs are typically valid for 24-36 hours
81
+ after submission.
82
+ </Typography>
83
+
84
+ <TextField2
85
+ variant="outlined"
86
+ label="BLAST RID"
87
+ placeholder="e.g., ABC12345"
88
+ fullWidth
89
+ style={{ marginBottom: 16 }}
90
+ value={rid}
91
+ onChange={event => {
92
+ setRid(event.target.value)
93
+ }}
94
+ />
95
+
96
+ {trimmedRid ? (
97
+ <Typography variant="body2" style={{ marginBottom: 16 }}>
98
+ <ExternalLink href={`${baseUrl}?CMD=Get&RID=${trimmedRid}`}>
99
+ View BLAST results on NCBI
100
+ </ExternalLink>
101
+ </Typography>
102
+ ) : null}
103
+
104
+ <TextField2
105
+ variant="outlined"
106
+ label="MSA Algorithm"
107
+ style={style}
108
+ select
109
+ value={selectedMsaAlgorithm}
110
+ onChange={event => {
111
+ setSelectedMsaAlgorithm(
112
+ event.target.value as (typeof msaAlgorithms)[number],
113
+ )
114
+ }}
115
+ >
116
+ {msaAlgorithms.map(val => (
117
+ <MenuItem value={val} key={val}>
118
+ {val}
119
+ </MenuItem>
120
+ ))}
121
+ </TextField2>
122
+
123
+ <TranscriptSelector
124
+ feature={feature}
125
+ options={options}
126
+ selectedId={selectedId}
127
+ selectedTranscript={selectedTranscript}
128
+ onTranscriptChange={setSelectedId}
129
+ proteinSequence={proteinSequence}
130
+ />
131
+
132
+ <Typography style={{ marginTop: 20 }}>
133
+ This will fetch the BLAST results for the provided RID and run them
134
+ through a multiple sequence alignment. The protein sequence from the
135
+ selected transcript will be added as the query sequence in the MSA.
136
+ </Typography>
137
+ </DialogContent>
138
+ <DialogActions>
139
+ <Button
140
+ color="primary"
141
+ variant="contained"
142
+ onClick={() => {
143
+ try {
144
+ if (!selectedTranscript || !trimmedRid) {
145
+ return
146
+ }
147
+ setLaunchViewError(undefined)
148
+ blastLaunchView({
149
+ feature: selectedTranscript,
150
+ view,
151
+ newViewTitle: `BLAST - ${getGeneDisplayName(feature)} - ${getTranscriptDisplayName(selectedTranscript)}`,
152
+ blastParams: {
153
+ baseUrl,
154
+ blastProgram: 'blastp',
155
+ blastDatabase: 'nr',
156
+ msaAlgorithm: selectedMsaAlgorithm,
157
+ selectedTranscript,
158
+ proteinSequence,
159
+ rid: trimmedRid,
160
+ },
161
+ })
162
+ } catch (e) {
163
+ console.error(e)
164
+ setLaunchViewError(e)
165
+ }
166
+
167
+ handleClose()
168
+ }}
169
+ disabled={!proteinSequence || !trimmedRid}
170
+ >
171
+ Submit
172
+ </Button>
173
+ <Button
174
+ color="secondary"
175
+ variant="contained"
176
+ onClick={() => {
177
+ handleClose()
178
+ }}
179
+ >
180
+ Cancel
181
+ </Button>
182
+ </DialogActions>
183
+ </>
184
+ )
185
+ })
186
+
187
+ export default NCBIBlastRIDPanel
@@ -146,6 +146,7 @@ const PreLoadedMSA = observer(function PreLoadedMSA2({
146
146
  <TranscriptSelector
147
147
  feature={feature}
148
148
  options={transcripts}
149
+ selectedId={selectedId}
149
150
  selectedTranscript={selectedTranscript}
150
151
  onTranscriptChange={setSelectedId}
151
152
  proteinSequence={proteinSequence}