jbrowse-plugin-msaview 2.0.3 → 2.0.5

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 (84) hide show
  1. package/dist/AddHighlightModel/GenomeMouseoverHighlight.js +1 -1
  2. package/dist/AddHighlightModel/GenomeMouseoverHighlight.js.map +1 -1
  3. package/dist/AddHighlightModel/HighlightComponents.js +1 -1
  4. package/dist/AddHighlightModel/HighlightComponents.js.map +1 -1
  5. package/dist/AddHighlightModel/MsaToGenomeHighlight.js +2 -1
  6. package/dist/AddHighlightModel/MsaToGenomeHighlight.js.map +1 -1
  7. package/dist/AddHighlightModel/index.js.map +1 -1
  8. package/dist/AddHighlightModel/util.d.ts +2 -2
  9. package/dist/AddHighlightModel/util.js +1 -1
  10. package/dist/AddHighlightModel/util.js.map +1 -1
  11. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js +8 -3
  12. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js.map +1 -1
  13. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/NcbiBlastPanel.js +17 -9
  14. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/NcbiBlastPanel.js.map +1 -1
  15. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/calculateProteinSequence.js +1 -1
  16. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/calculateProteinSequence.js.map +1 -1
  17. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/ncbiBlastLaunchView.js.map +1 -1
  18. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/useFeatureSequence.js +51 -30
  19. package/dist/LaunchMsaView/components/NewNCBIBlastQuery/useFeatureSequence.js.map +1 -1
  20. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +9 -5
  21. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js.map +1 -1
  22. package/dist/LaunchMsaView/components/TabUtils.d.ts +1 -5
  23. package/dist/LaunchMsaView/components/TabUtils.js +1 -7
  24. package/dist/LaunchMsaView/components/TabUtils.js.map +1 -1
  25. package/dist/LaunchMsaView/components/tabUtil.d.ts +4 -0
  26. package/dist/LaunchMsaView/components/tabUtil.js +7 -0
  27. package/dist/LaunchMsaView/components/tabUtil.js.map +1 -0
  28. package/dist/LaunchMsaView/index.js +4 -5
  29. package/dist/LaunchMsaView/index.js.map +1 -1
  30. package/dist/LaunchMsaView/util.d.ts +1 -1
  31. package/dist/LaunchMsaView/util.js +1 -1
  32. package/dist/LaunchMsaView/util.js.map +1 -1
  33. package/dist/MsaViewPanel/components/LoadingBLAST.js +2 -2
  34. package/dist/MsaViewPanel/components/LoadingBLAST.js.map +1 -1
  35. package/dist/MsaViewPanel/components/MsaViewPanel.js.map +1 -1
  36. package/dist/MsaViewPanel/components/RIDLink.js.map +1 -1
  37. package/dist/MsaViewPanel/doLaunchBlast.js +18 -5
  38. package/dist/MsaViewPanel/doLaunchBlast.js.map +1 -1
  39. package/dist/MsaViewPanel/genomeToMSA.js.map +1 -1
  40. package/dist/MsaViewPanel/index.js.map +1 -1
  41. package/dist/MsaViewPanel/model.d.ts +39 -35
  42. package/dist/MsaViewPanel/model.js +7 -5
  43. package/dist/MsaViewPanel/model.js.map +1 -1
  44. package/dist/MsaViewPanel/msaCoordToGenomeCoord.js +4 -4
  45. package/dist/MsaViewPanel/msaCoordToGenomeCoord.js.map +1 -1
  46. package/dist/OpenInNewIcon.js.map +1 -1
  47. package/dist/TextField2.js.map +1 -1
  48. package/dist/index.js +2 -2
  49. package/dist/index.js.map +1 -1
  50. package/dist/jbrowse-plugin-msaview.umd.production.min.js +84 -30
  51. package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
  52. package/dist/utils/msa.js +4 -0
  53. package/dist/utils/msa.js.map +1 -1
  54. package/dist/utils/ncbiBlast.js +8 -5
  55. package/dist/utils/ncbiBlast.js.map +1 -1
  56. package/package.json +24 -22
  57. package/src/AddHighlightModel/GenomeMouseoverHighlight.tsx +4 -2
  58. package/src/AddHighlightModel/HighlightComponents.tsx +3 -2
  59. package/src/AddHighlightModel/MsaToGenomeHighlight.tsx +9 -6
  60. package/src/AddHighlightModel/index.tsx +1 -0
  61. package/src/AddHighlightModel/util.ts +1 -1
  62. package/src/LaunchMsaView/components/LaunchMsaViewDialog.tsx +13 -4
  63. package/src/LaunchMsaView/components/NewNCBIBlastQuery/NcbiBlastPanel.tsx +22 -13
  64. package/src/LaunchMsaView/components/NewNCBIBlastQuery/calculateProteinSequence.ts +2 -2
  65. package/src/LaunchMsaView/components/NewNCBIBlastQuery/ncbiBlastLaunchView.ts +1 -0
  66. package/src/LaunchMsaView/components/NewNCBIBlastQuery/useFeatureSequence.ts +69 -34
  67. package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +19 -14
  68. package/src/LaunchMsaView/components/TabUtils.tsx +2 -7
  69. package/src/LaunchMsaView/components/tabUtil.ts +6 -0
  70. package/src/LaunchMsaView/index.ts +39 -33
  71. package/src/LaunchMsaView/util.ts +2 -2
  72. package/src/MsaViewPanel/components/LoadingBLAST.tsx +6 -4
  73. package/src/MsaViewPanel/components/MsaViewPanel.tsx +1 -0
  74. package/src/MsaViewPanel/components/RIDLink.tsx +2 -0
  75. package/src/MsaViewPanel/doLaunchBlast.ts +25 -7
  76. package/src/MsaViewPanel/genomeToMSA.ts +2 -1
  77. package/src/MsaViewPanel/index.ts +1 -0
  78. package/src/MsaViewPanel/model.ts +10 -7
  79. package/src/MsaViewPanel/msaCoordToGenomeCoord.ts +4 -4
  80. package/src/OpenInNewIcon.tsx +1 -0
  81. package/src/TextField2.tsx +1 -0
  82. package/src/index.ts +2 -2
  83. package/src/utils/msa.ts +3 -0
  84. package/src/utils/ncbiBlast.ts +22 -10
@@ -1,51 +1,57 @@
1
1
  import PluginManager from '@jbrowse/core/PluginManager'
2
- import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'
3
2
  import { PluggableElementType } from '@jbrowse/core/pluggableElementTypes'
3
+ import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'
4
+ import { MenuItem } from '@jbrowse/core/ui'
5
+ import { Feature, getContainingTrack, getSession } from '@jbrowse/core/util'
6
+ import AddIcon from '@mui/icons-material/Add'
4
7
  import { IAnyModelType } from 'mobx-state-tree'
5
- import { getSession, getContainingTrack } from '@jbrowse/core/util'
6
8
 
7
9
  // icons
8
- import AddIcon from '@mui/icons-material/Add'
9
10
 
10
11
  // locals
11
12
  import LaunchMsaViewDialog from './components/LaunchMsaViewDialog'
12
13
 
14
+
13
15
  function isDisplay(elt: { name: string }): elt is DisplayType {
14
16
  return elt.name === 'LinearBasicDisplay'
15
17
  }
16
18
 
17
19
  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
- ])
20
+ return stateModel.views(
21
+ (self: {
22
+ contextMenuItems: () => MenuItem[]
23
+ contextMenuFeature?: Feature
24
+ }) => {
25
+ const superContextMenuItems = self.contextMenuItems
26
+ return {
27
+ contextMenuItems() {
28
+ const feature = self.contextMenuFeature
29
+ const track = getContainingTrack(self)
30
+ return [
31
+ ...superContextMenuItems(),
32
+ ...(feature
33
+ ? [
34
+ {
35
+ label: 'Launch MSA view',
36
+ icon: AddIcon,
37
+ onClick: () => {
38
+ getSession(track).queueDialog(handleClose => [
39
+ LaunchMsaViewDialog,
40
+ {
41
+ model: track,
42
+ handleClose,
43
+ feature,
44
+ },
45
+ ])
46
+ },
41
47
  },
42
- },
43
- ]
44
- : []),
45
- ]
46
- },
47
- }
48
- })
48
+ ]
49
+ : []),
50
+ ]
51
+ },
52
+ }
53
+ },
54
+ )
49
55
  }
50
56
 
51
57
  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) {
@@ -1,9 +1,11 @@
1
1
  import React from 'react'
2
- import { JBrowsePluginMsaViewModel } from '../model'
2
+
3
+ import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui'
3
4
  import { Typography } from '@mui/material'
4
5
  import { observer } from 'mobx-react'
5
6
  import { makeStyles } from 'tss-react/mui'
6
- import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui'
7
+
8
+ import { JBrowsePluginMsaViewModel } from '../model'
7
9
 
8
10
  // locals
9
11
  import RIDLink from './RIDLink'
@@ -48,9 +50,9 @@ const LoadingBLAST = observer(function LoadingBLAST2({
48
50
  <LoadingEllipses message="Running NCBI BLAST" variant="h5" />
49
51
  {error ? (
50
52
  <RIDError rid={rid} error={error} />
51
- ) : rid ? (
53
+ ) : (rid ? (
52
54
  <RIDProgress rid={rid} progress={progress} />
53
- ) : null}
55
+ ) : null)}
54
56
  <Typography>{processing || 'Initializing BLAST query'}</Typography>
55
57
  </div>
56
58
  )
@@ -1,4 +1,5 @@
1
1
  import React from 'react'
2
+
2
3
  import { observer } from 'mobx-react'
3
4
  import { MSAView } from 'react-msaview'
4
5
 
@@ -1,5 +1,7 @@
1
1
  import React from 'react'
2
+
2
3
  import { Link, Typography } from '@mui/material'
4
+
3
5
  // locals
4
6
  import OpenInNewIcon from '../../OpenInNewIcon'
5
7
  import { BLAST_URL } from '../../utils/ncbiBlast'
@@ -1,10 +1,10 @@
1
- import { launchMSA } from '../utils/msa'
2
- import { queryBlast } from '../utils/ncbiBlast'
1
+ import { JBrowsePluginMsaViewModel } from './model'
3
2
  import {
4
3
  makeId,
5
4
  strip,
6
5
  } from '../LaunchMsaView/components/NewNCBIBlastQuery/util'
7
- import { JBrowsePluginMsaViewModel } from './model'
6
+ import { launchMSA } from '../utils/msa'
7
+ import { queryBlast } from '../utils/ncbiBlast'
8
8
 
9
9
  export async function doLaunchBlast({
10
10
  self,
@@ -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
  }
@@ -1,6 +1,7 @@
1
1
  import { getSession } from '@jbrowse/core/util'
2
- import { checkHovered } from './util'
2
+
3
3
  import { JBrowsePluginMsaViewModel } from './model'
4
+ import { checkHovered } from './util'
4
5
 
5
6
  export function genomeToMSA({ model }: { model: JBrowsePluginMsaViewModel }) {
6
7
  const { hovered } = getSession(model)
@@ -1,4 +1,5 @@
1
1
  import { lazy } from 'react'
2
+
2
3
  import PluginManager from '@jbrowse/core/PluginManager'
3
4
  import ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'
4
5
 
@@ -1,15 +1,16 @@
1
- import { Instance, addDisposer, cast, types } from 'mobx-state-tree'
2
- import { autorun } from 'mobx'
3
- import { MSAModelF } from 'react-msaview'
1
+ import { BaseViewModel } from '@jbrowse/core/pluggableElementTypes'
4
2
  import { Feature, getSession } from '@jbrowse/core/util'
5
3
  import { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
6
- import { BaseViewModel } from '@jbrowse/core/pluggableElementTypes'
4
+ import { genomeToTranscriptSeqMapping } from 'g2p_mapper'
5
+ import { autorun } from 'mobx'
6
+ import { Instance, addDisposer, cast, types } from 'mobx-state-tree'
7
+ import { MSAModelF } from 'react-msaview'
7
8
 
8
9
  // locals
9
10
  import { doLaunchBlast } from './doLaunchBlast'
10
11
  import { genomeToMSA } from './genomeToMSA'
11
12
  import { msaCoordToGenomeCoord } from './msaCoordToGenomeCoord'
12
- import { genomeToTranscriptSeqMapping } from 'g2p_mapper'
13
+
13
14
 
14
15
  type LGV = LinearGenomeViewModel
15
16
 
@@ -199,7 +200,9 @@ export default function stateModelFactory() {
199
200
  label: 'Zoom to base level on click?',
200
201
  checked: self.zoomToBaseLevel,
201
202
  type: 'checkbox',
202
- onClick: () => self.setZoomToBaseLevel(!self.zoomToBaseLevel),
203
+ onClick: () => {
204
+ self.setZoomToBaseLevel(!self.zoomToBaseLevel)
205
+ },
203
206
  },
204
207
  ]
205
208
  },
@@ -280,7 +283,7 @@ export default function stateModelFactory() {
280
283
  } else {
281
284
  const r =
282
285
  assemblyManager
283
- .get(connectedView.assemblyNames[0])
286
+ .get(connectedView.assemblyNames[0]!)
284
287
  ?.getCanonicalRefName(r2.refName) ?? r2.refName
285
288
  connectedView.centerAt(r2.start, r)
286
289
  }
@@ -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]
@@ -1,4 +1,5 @@
1
1
  import React from 'react'
2
+
2
3
  import { SvgIcon, SvgIconProps } from '@mui/material'
3
4
 
4
5
  export default function OpenInNewIcon(props: SvgIconProps) {
@@ -1,4 +1,5 @@
1
1
  import React from 'react'
2
+
2
3
  import { TextField, TextFieldProps } from '@mui/material'
3
4
 
4
5
  function TextField2({ children, ...rest }: TextFieldProps) {
package/src/index.ts CHANGED
@@ -7,9 +7,9 @@ import GridOn from '@mui/icons-material/GridOn'
7
7
 
8
8
  // locals
9
9
  import { version } from '../package.json'
10
- import MsaViewF from './MsaViewPanel'
11
- import LaunchMsaViewF from './LaunchMsaView'
12
10
  import AddHighlightModelF from './AddHighlightModel'
11
+ import LaunchMsaViewF from './LaunchMsaView'
12
+ import MsaViewF from './MsaViewPanel'
13
13
 
14
14
  export default class MsaViewPlugin extends Plugin {
15
15
  name = 'MsaViewPlugin'
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
  }
@@ -23,15 +23,26 @@ export async function queryBlast({
23
23
  })
24
24
  onRid(rid)
25
25
  await waitForRid({ rid, onProgress })
26
- const ret = await jsonfetch(
26
+ const ret = (await jsonfetch(
27
27
  `${BLAST_URL}?CMD=Get&RID=${rid}&FORMAT_TYPE=JSON2_S&FORMAT_OBJECT=Alignment`,
28
- )
29
- const hits = ret.BlastOutput2[0].report.results.search.hits as {
30
- description: { accession: string; id: string; sciname: string }[]
31
- hsps: { hseq: string }[]
32
- }[]
33
-
34
- return { rid, hits }
28
+ )) as {
29
+ BlastOutput2: {
30
+ report: {
31
+ results: {
32
+ search: {
33
+ hits: {
34
+ description: { accession: string; id: string; sciname: string }[]
35
+ hsps: { hseq: string }[]
36
+ }[]
37
+ }
38
+ }
39
+ }
40
+ }[]
41
+ }
42
+ return {
43
+ rid,
44
+ hits: ret.BlastOutput2[0]?.report.results.search.hits ?? [],
45
+ }
35
46
  }
36
47
 
37
48
  async function initialQuery({
@@ -62,8 +73,8 @@ async function initialQuery({
62
73
  // the initial submission/query to the BLAST "REST API" does not return JSON
63
74
  // as a response (e.g. FORMAT_TYPE=JSON does not work), so the RID is
64
75
  // literally parsed from the text of the HTML that is returned
65
- const rid = /^ RID = (.*$)/m.exec(res)?.[1]
66
- const rtoe = /^ RTOE = (.*$)/m.exec(res)?.[1]
76
+ const rid = /^ {4}RID = (.*$)/m.exec(res)?.[1]
77
+ const rtoe = /^ {4}RTOE = (.*$)/m.exec(res)?.[1]
67
78
 
68
79
  if (!rid) {
69
80
  throw new Error('Failed to get RID from BLAST request')
@@ -78,6 +89,7 @@ async function waitForRid({
78
89
  rid: string
79
90
  onProgress: (arg: string) => void
80
91
  }) {
92
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
81
93
  while (true) {
82
94
  const iter = 20
83
95
  for (let i = 0; i < iter; i++) {