jbrowse-plugin-msaview 2.0.3 → 2.0.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.
Files changed (57) hide show
  1. package/dist/AddHighlightModel/MsaToGenomeHighlight.js.map +1 -1
  2. package/dist/AddHighlightModel/util.js +1 -1
  3. package/dist/AddHighlightModel/util.js.map +1 -1
  4. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js +8 -3
  5. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js.map +1 -1
  6. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/NcbiBlastPanel.js +12 -4
  7. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/NcbiBlastPanel.js.map +1 -1
  8. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/calculateProteinSequence.js +1 -1
  9. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/calculateProteinSequence.js.map +1 -1
  10. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/useFeatureSequence.js +50 -29
  11. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/useFeatureSequence.js.map +1 -1
  12. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +6 -2
  13. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js.map +1 -1
  14. package/dist/LaunchMsaView/components/TabUtils.d.ts +1 -5
  15. package/dist/LaunchMsaView/components/TabUtils.js +1 -7
  16. package/dist/LaunchMsaView/components/TabUtils.js.map +1 -1
  17. package/dist/LaunchMsaView/components/tabUtil.d.ts +4 -0
  18. package/dist/LaunchMsaView/components/tabUtil.js +7 -0
  19. package/dist/LaunchMsaView/components/tabUtil.js.map +1 -0
  20. package/dist/LaunchMsaView/index.js +2 -3
  21. package/dist/LaunchMsaView/index.js.map +1 -1
  22. package/dist/LaunchMsaView/util.d.ts +1 -1
  23. package/dist/LaunchMsaView/util.js +1 -1
  24. package/dist/LaunchMsaView/util.js.map +1 -1
  25. package/dist/MsaViewPanel/components/LoadingBLAST.js +1 -1
  26. package/dist/MsaViewPanel/components/LoadingBLAST.js.map +1 -1
  27. package/dist/MsaViewPanel/doLaunchBlast.js +17 -4
  28. package/dist/MsaViewPanel/doLaunchBlast.js.map +1 -1
  29. package/dist/MsaViewPanel/model.d.ts +33 -24
  30. package/dist/MsaViewPanel/model.js +3 -1
  31. package/dist/MsaViewPanel/model.js.map +1 -1
  32. package/dist/MsaViewPanel/msaCoordToGenomeCoord.js +4 -4
  33. package/dist/MsaViewPanel/msaCoordToGenomeCoord.js.map +1 -1
  34. package/dist/jbrowse-plugin-msaview.umd.production.min.js +27 -27
  35. package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
  36. package/dist/utils/msa.js +4 -0
  37. package/dist/utils/msa.js.map +1 -1
  38. package/dist/utils/ncbiBlast.js +8 -5
  39. package/dist/utils/ncbiBlast.js.map +1 -1
  40. package/package.json +8 -8
  41. package/src/AddHighlightModel/MsaToGenomeHighlight.tsx +4 -2
  42. package/src/AddHighlightModel/util.ts +1 -1
  43. package/src/LaunchMsaView/components/LaunchMsaViewDialog.tsx +11 -3
  44. package/src/LaunchMsaView/components/NewNCBIBlastQuery/NcbiBlastPanel.tsx +12 -4
  45. package/src/LaunchMsaView/components/NewNCBIBlastQuery/calculateProteinSequence.ts +2 -2
  46. package/src/LaunchMsaView/components/NewNCBIBlastQuery/useFeatureSequence.ts +69 -34
  47. package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +6 -2
  48. package/src/LaunchMsaView/components/TabUtils.tsx +1 -7
  49. package/src/LaunchMsaView/components/tabUtil.ts +6 -0
  50. package/src/LaunchMsaView/index.ts +36 -31
  51. package/src/LaunchMsaView/util.ts +2 -2
  52. package/src/MsaViewPanel/components/LoadingBLAST.tsx +2 -2
  53. package/src/MsaViewPanel/doLaunchBlast.ts +22 -4
  54. package/src/MsaViewPanel/model.ts +4 -2
  55. package/src/MsaViewPanel/msaCoordToGenomeCoord.ts +4 -4
  56. package/src/utils/msa.ts +3 -0
  57. package/src/utils/ncbiBlast.ts +22 -10
package/dist/utils/msa.js CHANGED
@@ -61,6 +61,7 @@ async function runMafft({ sequence, onProgress, }) {
61
61
  };
62
62
  }
63
63
  async function wait({ onProgress, jobId, algorithm, }) {
64
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
64
65
  while (true) {
65
66
  for (let i = 0; i < 10; i++) {
66
67
  await timeout(1000);
@@ -70,6 +71,9 @@ async function wait({ onProgress, jobId, algorithm, }) {
70
71
  if (result === 'FINISHED') {
71
72
  break;
72
73
  }
74
+ else if (result.includes('FAILURE')) {
75
+ throw new Error(`Failed to run: jobId ${jobId}`);
76
+ }
73
77
  }
74
78
  }
75
79
  export async function launchMSA({ algorithm, sequence, onProgress, }) {
@@ -1 +1 @@
1
- {"version":3,"file":"msa.js","sourceRoot":"","sources":["../../src/utils/msa.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"msa.js","sourceRoot":"","sources":["../../src/utils/msa.ts"],"names":[],"mappings":"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"}
@@ -9,9 +9,11 @@ export async function queryBlast({ query, blastDatabase, blastProgram, onProgres
9
9
  });
10
10
  onRid(rid);
11
11
  await waitForRid({ rid, onProgress });
12
- const ret = await jsonfetch(`${BLAST_URL}?CMD=Get&RID=${rid}&FORMAT_TYPE=JSON2_S&FORMAT_OBJECT=Alignment`);
13
- const hits = ret.BlastOutput2[0].report.results.search.hits;
14
- return { rid, hits };
12
+ const ret = (await jsonfetch(`${BLAST_URL}?CMD=Get&RID=${rid}&FORMAT_TYPE=JSON2_S&FORMAT_OBJECT=Alignment`));
13
+ return {
14
+ rid,
15
+ hits: ret.BlastOutput2[0]?.report.results.search.hits ?? [],
16
+ };
15
17
  }
16
18
  async function initialQuery({ query, blastProgram, blastDatabase, }) {
17
19
  const res = await textfetch(BLAST_URL, {
@@ -32,14 +34,15 @@ async function initialQuery({ query, blastProgram, blastDatabase, }) {
32
34
  // the initial submission/query to the BLAST "REST API" does not return JSON
33
35
  // as a response (e.g. FORMAT_TYPE=JSON does not work), so the RID is
34
36
  // literally parsed from the text of the HTML that is returned
35
- const rid = /^ RID = (.*$)/m.exec(res)?.[1];
36
- const rtoe = /^ RTOE = (.*$)/m.exec(res)?.[1];
37
+ const rid = /^ {4}RID = (.*$)/m.exec(res)?.[1];
38
+ const rtoe = /^ {4}RTOE = (.*$)/m.exec(res)?.[1];
37
39
  if (!rid) {
38
40
  throw new Error('Failed to get RID from BLAST request');
39
41
  }
40
42
  return { rid, rtoe };
41
43
  }
42
44
  async function waitForRid({ rid, onProgress, }) {
45
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
43
46
  while (true) {
44
47
  const iter = 20;
45
48
  for (let i = 0; i < iter; i++) {
@@ -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/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.0.3",
2
+ "version": "2.0.4",
3
3
  "license": "MIT",
4
4
  "name": "jbrowse-plugin-msaview",
5
5
  "keywords": [
@@ -25,9 +25,10 @@
25
25
  "scripts": {
26
26
  "clean": "rimraf dist",
27
27
  "start": "node esbuild.mjs",
28
+ "format": "prettier --write .",
28
29
  "build": "tsc && NODE_ENV=production node esbuild.mjs",
29
30
  "prebuild": "npm run clean",
30
- "lint": "eslint --report-unused-disable-directives --max-warnings 0 src/",
31
+ "lint": "eslint --report-unused-disable-directives --max-warnings 0",
31
32
  "prepack": "npm run build",
32
33
  "postversion": "git push --follow-tags"
33
34
  },
@@ -41,14 +42,13 @@
41
42
  },
42
43
  "devDependencies": {
43
44
  "@emotion/react": "^11.10.4",
44
- "@eslint/compat": "^1.1.0",
45
45
  "@fal-works/esbuild-plugin-global-externals": "^2.1.2",
46
46
  "@jbrowse/core": "^2.10.1",
47
47
  "@jbrowse/plugin-linear-genome-view": "^2.7.0",
48
48
  "@mui/icons-material": "^5.15.6",
49
49
  "@mui/material": "^5.14.12",
50
50
  "@mui/system": "^5.14.12",
51
- "@mui/x-data-grid": "^7.3.0",
51
+ "@mui/x-data-grid": "^7.13.0",
52
52
  "@types/node": "^20.8.6",
53
53
  "@types/pako": "^2.0.1",
54
54
  "@types/react": "^18.2.28",
@@ -56,10 +56,9 @@
56
56
  "@typescript-eslint/parser": "^8.0.1",
57
57
  "esbuild": "^0.23.0",
58
58
  "eslint": "^9.0.0",
59
- "eslint-config-prettier": "^9.1.0",
60
- "eslint-plugin-prettier": "^5.1.0",
61
59
  "eslint-plugin-react": "^7.20.3",
62
- "eslint-plugin-react-hooks": "^4.6.0",
60
+ "eslint-plugin-react-hooks": "next",
61
+ "eslint-plugin-react-refresh": "^0.4.9",
63
62
  "eslint-plugin-unicorn": "^55.0.0",
64
63
  "mobx": "^6.10.2",
65
64
  "mobx-react": "^9.0.1",
@@ -71,6 +70,7 @@
71
70
  "rimraf": "^6.0.0",
72
71
  "rxjs": "^7.8.1",
73
72
  "tss-react": "^4.9.2",
74
- "typescript": "^5.2.2"
73
+ "typescript": "^5.2.2",
74
+ "typescript-eslint": "^8.1.0"
75
75
  }
76
76
  }
@@ -22,8 +22,10 @@ const MsaToGenomeHighlight = observer(function MsaToGenomeHighlight2({
22
22
  }) {
23
23
  const { classes } = useStyles()
24
24
  const { assemblyManager, views } = getSession(model)
25
- const p = views.find(f => f.type === 'MsaView') as JBrowsePluginMsaViewModel
26
- const assembly = assemblyManager.get(model.assemblyNames[0])
25
+ const p = views.find(f => f.type === 'MsaView') as
26
+ | JBrowsePluginMsaViewModel
27
+ | undefined
28
+ const assembly = assemblyManager.get(model.assemblyNames[0]!)
27
29
  return assembly ? (
28
30
  <>
29
31
  {p?.connectedHighlights.map((r, idx) => {
@@ -6,7 +6,7 @@ export const useStyles = makeStyles()({
6
6
  background: 'rgba(255,255,0,0.2)',
7
7
  border: '1px solid rgba(50,50,0,0.2)',
8
8
  position: 'absolute',
9
- zIndex: 1000,
9
+ zIndex: 99,
10
10
  textAlign: 'center',
11
11
  pointerEvents: 'none',
12
12
  overflow: 'hidden',
@@ -5,9 +5,10 @@ import { AbstractTrackModel, Feature } from '@jbrowse/core/util'
5
5
 
6
6
  // locals
7
7
 
8
- import { CustomTabPanel, a11yProps } from './TabUtils'
8
+ import CustomTabPanel from './TabUtils'
9
9
  import NewNcbiBlastQueryPanel from './NewNCBIBlastQuery'
10
10
  import PreLoadedMSA from './PreLoadedMSA/PreLoadedMSADataPanel'
11
+ import { a11yProps } from './tabUtil'
11
12
 
12
13
  export default function LaunchProteinViewDialog({
13
14
  handleClose,
@@ -24,11 +25,18 @@ export default function LaunchProteinViewDialog({
24
25
  <Dialog
25
26
  maxWidth="xl"
26
27
  title="Launch MSA view"
27
- onClose={() => handleClose()}
28
+ onClose={() => {
29
+ handleClose()
30
+ }}
28
31
  open
29
32
  >
30
33
  <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
31
- <Tabs value={value} onChange={(_, val) => setValue(val)}>
34
+ <Tabs
35
+ value={value}
36
+ onChange={(_, val) => {
37
+ setValue(val)
38
+ }}
39
+ >
32
40
  <Tab label="NCBI BLAST query" {...a11yProps(0)} />
33
41
  <Tab label="UCSC 100-way dataset" {...a11yProps(1)} />
34
42
  </Tabs>
@@ -67,7 +67,9 @@ const NcbiBlastPanel = observer(function NcbiBlastPanel2({
67
67
  {error ? <ErrorMessage error={error} /> : null}
68
68
  <TextField2
69
69
  value={blastDatabase}
70
- onChange={event => setBlastDatabase(event.target.value)}
70
+ onChange={event => {
71
+ setBlastDatabase(event.target.value)
72
+ }}
71
73
  label="BLAST blastDatabase"
72
74
  select
73
75
  >
@@ -80,7 +82,9 @@ const NcbiBlastPanel = observer(function NcbiBlastPanel2({
80
82
 
81
83
  <TextField2
82
84
  value={msaAlgorithm}
83
- onChange={event => setMsaAlgorithm(event.target.value)}
85
+ onChange={event => {
86
+ setMsaAlgorithm(event.target.value)
87
+ }}
84
88
  label="MSA Algorithm"
85
89
  select
86
90
  >
@@ -93,7 +97,9 @@ const NcbiBlastPanel = observer(function NcbiBlastPanel2({
93
97
 
94
98
  <TextField2
95
99
  value={userSelection}
96
- onChange={event => setUserSelection(event.target.value)}
100
+ onChange={event => {
101
+ setUserSelection(event.target.value)
102
+ }}
97
103
  label="Choose isoform to BLAST"
98
104
  select
99
105
  >
@@ -148,7 +154,9 @@ const NcbiBlastPanel = observer(function NcbiBlastPanel2({
148
154
  <Button
149
155
  color="secondary"
150
156
  variant="contained"
151
- onClick={() => handleClose()}
157
+ onClick={() => {
158
+ handleClose()
159
+ }}
152
160
  >
153
161
  Cancel
154
162
  </Button>
@@ -28,7 +28,7 @@ export function calculateProteinSequence({
28
28
  let protein = ''
29
29
  for (let i = 0; i < str.length; i += 3) {
30
30
  // use & symbol for undefined codon, or partial slice
31
- protein += codonTable[str.slice(i, i + 3)] || '&'
31
+ protein += codonTable[str.slice(i, i + 3)] ?? '&'
32
32
  }
33
33
  return protein
34
34
  }
@@ -54,7 +54,7 @@ function getItemId(feat: Feat) {
54
54
  // filters if successive elements share same start/end
55
55
  export function dedupe(list: Feat[]) {
56
56
  return list.filter(
57
- (item, pos, ary) => !pos || getItemId(item) !== getItemId(ary[pos - 1]),
57
+ (item, pos, ary) => !pos || getItemId(item) !== getItemId(ary[pos - 1]!),
58
58
  )
59
59
  }
60
60
 
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useState } from 'react'
2
2
 
3
- import { Feature, getSession } from '@jbrowse/core/util'
3
+ import { AbstractSessionModel, Feature, getSession } from '@jbrowse/core/util'
4
4
  import { getConf } from '@jbrowse/core/configuration'
5
5
 
6
6
  export interface SeqState {
@@ -14,6 +14,40 @@ export interface ErrorState {
14
14
  }
15
15
  const BPLIMIT = 500_000
16
16
 
17
+ async function fetchSeq({
18
+ start,
19
+ end,
20
+ refName,
21
+ session,
22
+ assemblyName,
23
+ }: {
24
+ start: number
25
+ end: number
26
+ refName: string
27
+ assemblyName: string
28
+ session: AbstractSessionModel
29
+ }) {
30
+ const { assemblyManager, rpcManager } = session
31
+ const assembly = await assemblyManager.waitForAssembly(assemblyName)
32
+ if (!assembly) {
33
+ throw new Error('assembly not found')
34
+ }
35
+ const sessionId = 'getSequence'
36
+ const feats = (await rpcManager.call(sessionId, 'CoreGetFeatures', {
37
+ adapterConfig: getConf(assembly, ['sequence', 'adapter']),
38
+ sessionId,
39
+ regions: [
40
+ {
41
+ start,
42
+ end,
43
+ refName: assembly.getCanonicalRefName(refName),
44
+ assemblyName,
45
+ },
46
+ ],
47
+ })) as Feature[]
48
+ return (feats[0]?.get('seq') as string | undefined) ?? ''
49
+ }
50
+
17
51
  export function useFeatureSequence({
18
52
  view,
19
53
  feature,
@@ -27,41 +61,23 @@ export function useFeatureSequence({
27
61
  }) {
28
62
  const [sequence, setSequence] = useState<SeqState | ErrorState>()
29
63
  const [error, setError] = useState<unknown>()
64
+ const assemblyName = view?.assemblyNames?.[0]
30
65
  useEffect(() => {
31
66
  if (view) {
32
- const { assemblyManager, rpcManager } = getSession(view)
33
- const [assemblyName] = view?.assemblyNames || []
34
- async function fetchSeq(start: number, end: number, refName: string) {
35
- const assembly = await assemblyManager.waitForAssembly(assemblyName)
36
- if (!assembly) {
37
- throw new Error('assembly not found')
38
- }
39
- const sessionId = 'getSequence'
40
- const feats = await rpcManager.call(sessionId, 'CoreGetFeatures', {
41
- adapterConfig: getConf(assembly, ['sequence', 'adapter']),
42
- sessionId,
43
- regions: [
44
- {
45
- start,
46
- end,
47
- refName: assembly.getCanonicalRefName(refName),
48
- assemblyName,
49
- },
50
- ],
51
- })
52
-
53
- const [feat] = feats as Feature[]
54
- return (feat?.get('seq') as string | undefined) || ''
55
- }
56
-
57
67
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
58
68
  ;(async () => {
59
69
  try {
60
70
  setError(undefined)
61
71
  setSequence(undefined)
62
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
- const { start, end, refName } = feature.toJSON() as any
64
-
72
+ const session = getSession(view)
73
+ const { start, end, refName } = feature.toJSON() as {
74
+ start: number
75
+ end: number
76
+ refName: string
77
+ }
78
+ if (!assemblyName) {
79
+ throw new Error('No assembly found')
80
+ }
65
81
  if (!forceLoad && end - start > BPLIMIT) {
66
82
  setSequence({
67
83
  error: `Genomic sequence larger than ${BPLIMIT}bp, use "force load" button to display`,
@@ -69,10 +85,29 @@ export function useFeatureSequence({
69
85
  } else {
70
86
  const b = start - upDownBp
71
87
  const e = end + upDownBp
72
- const seq = await fetchSeq(start, end, refName)
73
- const up = await fetchSeq(Math.max(0, b), start, refName)
74
- const down = await fetchSeq(end, e, refName)
75
- setSequence({ seq, upstream: up, downstream: down })
88
+ setSequence({
89
+ seq: await fetchSeq({
90
+ start,
91
+ end,
92
+ refName,
93
+ assemblyName,
94
+ session,
95
+ }),
96
+ upstream: await fetchSeq({
97
+ start: Math.max(0, b),
98
+ end: start,
99
+ refName,
100
+ assemblyName,
101
+ session,
102
+ }),
103
+ downstream: await fetchSeq({
104
+ start: end,
105
+ end: e,
106
+ refName,
107
+ assemblyName,
108
+ session,
109
+ }),
110
+ })
76
111
  }
77
112
  } catch (e) {
78
113
  console.error(e)
@@ -80,6 +115,6 @@ export function useFeatureSequence({
80
115
  }
81
116
  })()
82
117
  }
83
- }, [feature, view, upDownBp, forceLoad])
118
+ }, [feature, view, upDownBp, assemblyName, forceLoad])
84
119
  return { sequence, error }
85
120
  }
@@ -86,7 +86,9 @@ const PreLoadedMSA = observer(function PreLoadedMSA2({
86
86
  ) : null}
87
87
  <TextField
88
88
  value={userSelection}
89
- onChange={event => setUserSelection(event.target.value)}
89
+ onChange={event => {
90
+ setUserSelection(event.target.value)
91
+ }}
90
92
  label="Choose isoform to view MSA for"
91
93
  select
92
94
  >
@@ -138,7 +140,9 @@ const PreLoadedMSA = observer(function PreLoadedMSA2({
138
140
  <Button
139
141
  color="secondary"
140
142
  variant="contained"
141
- onClick={() => handleClose()}
143
+ onClick={() => {
144
+ handleClose()
145
+ }}
142
146
  >
143
147
  Cancel
144
148
  </Button>
@@ -7,7 +7,7 @@ interface TabPanelProps {
7
7
  value: number
8
8
  }
9
9
 
10
- export function CustomTabPanel(props: TabPanelProps) {
10
+ export default function CustomTabPanel(props: TabPanelProps) {
11
11
  const { children, value, index, ...other } = props
12
12
 
13
13
  return (
@@ -22,9 +22,3 @@ export function CustomTabPanel(props: TabPanelProps) {
22
22
  </div>
23
23
  )
24
24
  }
25
- export function a11yProps(index: number) {
26
- return {
27
- id: `gtab-${index}`,
28
- 'aria-controls': `gtabpanel-${index}`,
29
- }
30
- }
@@ -0,0 +1,6 @@
1
+ export function a11yProps(index: number) {
2
+ return {
3
+ id: `gtab-${index}`,
4
+ 'aria-controls': `gtabpanel-${index}`,
5
+ }
6
+ }
@@ -2,50 +2,55 @@ import PluginManager from '@jbrowse/core/PluginManager'
2
2
  import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'
3
3
  import { PluggableElementType } from '@jbrowse/core/pluggableElementTypes'
4
4
  import { IAnyModelType } from 'mobx-state-tree'
5
- import { getSession, getContainingTrack } from '@jbrowse/core/util'
5
+ import { getSession, getContainingTrack, Feature } from '@jbrowse/core/util'
6
6
 
7
7
  // icons
8
8
  import AddIcon from '@mui/icons-material/Add'
9
9
 
10
10
  // locals
11
11
  import LaunchMsaViewDialog from './components/LaunchMsaViewDialog'
12
+ import { MenuItem } from '@jbrowse/core/ui'
12
13
 
13
14
  function isDisplay(elt: { name: string }): elt is DisplayType {
14
15
  return elt.name === 'LinearBasicDisplay'
15
16
  }
16
17
 
17
18
  function extendStateModel(stateModel: IAnyModelType) {
18
- return stateModel.views(self => {
19
- const superContextMenuItems = self.contextMenuItems
20
- return {
21
- contextMenuItems() {
22
- const feature = self.contextMenuFeature
23
- const track = getContainingTrack(self)
24
- return [
25
- ...superContextMenuItems(),
26
- ...(feature
27
- ? [
28
- {
29
- label: 'Launch MSA view',
30
- icon: AddIcon,
31
- onClick: () => {
32
- const session = getSession(track)
33
- session.queueDialog(handleClose => [
34
- LaunchMsaViewDialog,
35
- {
36
- model: track,
37
- handleClose,
38
- feature,
39
- },
40
- ])
19
+ return stateModel.views(
20
+ (self: {
21
+ contextMenuItems: () => MenuItem[]
22
+ contextMenuFeature?: Feature
23
+ }) => {
24
+ const superContextMenuItems = self.contextMenuItems
25
+ return {
26
+ contextMenuItems() {
27
+ const feature = self.contextMenuFeature
28
+ const track = getContainingTrack(self)
29
+ return [
30
+ ...superContextMenuItems(),
31
+ ...(feature
32
+ ? [
33
+ {
34
+ label: 'Launch MSA view',
35
+ icon: AddIcon,
36
+ onClick: () => {
37
+ getSession(track).queueDialog(handleClose => [
38
+ LaunchMsaViewDialog,
39
+ {
40
+ model: track,
41
+ handleClose,
42
+ feature,
43
+ },
44
+ ])
45
+ },
41
46
  },
42
- },
43
- ]
44
- : []),
45
- ]
46
- },
47
- }
48
- })
47
+ ]
48
+ : []),
49
+ ]
50
+ },
51
+ }
52
+ },
53
+ )
49
54
  }
50
55
 
51
56
  export default function LaunchMsaViewF(pluginManager: PluginManager) {
@@ -11,8 +11,8 @@ export function getTranscriptFeatures(feature: Feature) {
11
11
  f.get('subfeatures')?.some(f => f.get('type') === 'CDS'),
12
12
  )
13
13
  }
14
- export function getId(val?: Feature) {
15
- return val === undefined ? '' : val.get('name') || val.get('id')
14
+ export function getId(val?: Feature): string {
15
+ return val?.get('name') || val?.get('id') || ''
16
16
  }
17
17
 
18
18
  export function getTranscriptDisplayName(val?: Feature) {
@@ -48,9 +48,9 @@ const LoadingBLAST = observer(function LoadingBLAST2({
48
48
  <LoadingEllipses message="Running NCBI BLAST" variant="h5" />
49
49
  {error ? (
50
50
  <RIDError rid={rid} error={error} />
51
- ) : rid ? (
51
+ ) : (rid ? (
52
52
  <RIDProgress rid={rid} progress={progress} />
53
- ) : null}
53
+ ) : null)}
54
54
  <Typography>{processing || 'Initializing BLAST query'}</Typography>
55
55
  </div>
56
56
  )
@@ -18,21 +18,39 @@ export async function doLaunchBlast({
18
18
  query,
19
19
  blastDatabase,
20
20
  blastProgram,
21
- onProgress: arg => self.setProgress(arg),
22
- onRid: rid => self.setRid(rid),
21
+ onProgress: arg => {
22
+ self.setProgress(arg)
23
+ },
24
+ onRid: rid => {
25
+ self.setRid(rid)
26
+ },
23
27
  })
24
28
 
25
29
  const sequence = [
26
30
  `>QUERY\n${query}`,
27
31
  ...hits
28
- .map(h => [makeId(h.description[0]), strip(h.hsps[0].hseq)] as const)
32
+ .map(
33
+ h =>
34
+ [
35
+ makeId(
36
+ h.description[0] ?? {
37
+ accession: 'unknown',
38
+ id: 'unknown',
39
+ sciname: 'unknown',
40
+ },
41
+ ),
42
+ strip(h.hsps[0]?.hseq ?? ''),
43
+ ] as const,
44
+ )
29
45
  .map(([id, seq]) => `>${id}\n${seq}`),
30
46
  ].join('\n')
31
47
 
32
48
  const data = await launchMSA({
33
49
  algorithm: msaAlgorithm,
34
50
  sequence,
35
- onProgress: arg => self.setProgress(arg),
51
+ onProgress: arg => {
52
+ self.setProgress(arg)
53
+ },
36
54
  })
37
55
  return data
38
56
  }
@@ -199,7 +199,9 @@ export default function stateModelFactory() {
199
199
  label: 'Zoom to base level on click?',
200
200
  checked: self.zoomToBaseLevel,
201
201
  type: 'checkbox',
202
- onClick: () => self.setZoomToBaseLevel(!self.zoomToBaseLevel),
202
+ onClick: () => {
203
+ self.setZoomToBaseLevel(!self.zoomToBaseLevel)
204
+ },
203
205
  },
204
206
  ]
205
207
  },
@@ -280,7 +282,7 @@ export default function stateModelFactory() {
280
282
  } else {
281
283
  const r =
282
284
  assemblyManager
283
- .get(connectedView.assemblyNames[0])
285
+ .get(connectedView.assemblyNames[0]!)
284
286
  ?.getCanonicalRefName(r2.refName) ?? r2.refName
285
287
  connectedView.centerAt(r2.start, r)
286
288
  }
@@ -9,13 +9,13 @@ export function msaCoordToGenomeCoord({
9
9
  coord: number
10
10
  }) {
11
11
  const { transcriptToMsaMap } = model
12
- if (mouseCol === undefined || transcriptToMsaMap === undefined) {
12
+ if (transcriptToMsaMap === undefined) {
13
13
  return
14
14
  }
15
15
 
16
- const c = mouseCol - 1
17
- const k1 = model.globalCoordToRowSpecificSeqCoord('QUERY', c) || 0
18
- const k2 = model.globalCoordToRowSpecificSeqCoord('QUERY', c + 1) || 0
16
+ const c = mouseCol
17
+ const k1 = model.seqCoordToRowSpecificGlobalCoord('QUERY', c) || 0
18
+ const k2 = model.seqCoordToRowSpecificGlobalCoord('QUERY', c + 1) || 0
19
19
  const { refName, p2g } = transcriptToMsaMap
20
20
  const s = p2g[k1]
21
21
  const e = p2g[k2]
package/src/utils/msa.ts CHANGED
@@ -98,6 +98,7 @@ async function wait({
98
98
  algorithm: string
99
99
  onProgress: (arg: string) => void
100
100
  }) {
101
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
101
102
  while (true) {
102
103
  for (let i = 0; i < 10; i++) {
103
104
  await timeout(1000)
@@ -107,6 +108,8 @@ async function wait({
107
108
 
108
109
  if (result === 'FINISHED') {
109
110
  break
111
+ } else if (result.includes('FAILURE')) {
112
+ throw new Error(`Failed to run: jobId ${jobId}`)
110
113
  }
111
114
  }
112
115
  }