jbrowse-plugin-msaview 2.3.8 → 2.4.1

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 (128) hide show
  1. package/dist/AddHighlightModel/GenomeMouseoverHighlight.js +4 -15
  2. package/dist/AddHighlightModel/GenomeMouseoverHighlight.js.map +1 -1
  3. package/dist/AddHighlightModel/MsaToGenomeHighlight.js +11 -13
  4. package/dist/AddHighlightModel/MsaToGenomeHighlight.js.map +1 -1
  5. package/dist/AddHighlightModel/util.d.ts +6 -0
  6. package/dist/AddHighlightModel/util.js +6 -0
  7. package/dist/AddHighlightModel/util.js.map +1 -1
  8. package/dist/BgzipFastaMsaAdapter/BgzipFastaMsaAdapter.d.ts +2 -0
  9. package/dist/BgzipFastaMsaAdapter/BgzipFastaMsaAdapter.js +8 -4
  10. package/dist/BgzipFastaMsaAdapter/BgzipFastaMsaAdapter.js.map +1 -1
  11. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js +3 -8
  12. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js.map +1 -1
  13. package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js +7 -10
  14. package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js.map +1 -1
  15. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js +2 -5
  16. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js.map +1 -1
  17. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js +0 -3
  18. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js.map +1 -1
  19. package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.d.ts +4 -4
  20. package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.js +2 -2
  21. package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.js.map +1 -1
  22. package/dist/LaunchMsaView/components/NCBIBlastQuery/consts.d.ts +4 -0
  23. package/dist/LaunchMsaView/components/NCBIBlastQuery/consts.js +2 -0
  24. package/dist/LaunchMsaView/components/NCBIBlastQuery/consts.js.map +1 -1
  25. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +10 -21
  26. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js.map +1 -1
  27. package/dist/LaunchMsaView/components/PreLoadedMSA/types.d.ts +1 -0
  28. package/dist/LaunchMsaView/components/PreLoadedMSA/types.js +4 -1
  29. package/dist/LaunchMsaView/components/PreLoadedMSA/types.js.map +1 -1
  30. package/dist/LaunchMsaView/components/types.d.ts +0 -3
  31. package/dist/LaunchMsaView/components/useFeatureSequence.d.ts +4 -4
  32. package/dist/LaunchMsaView/components/useFeatureSequence.js +2 -4
  33. package/dist/LaunchMsaView/components/useFeatureSequence.js.map +1 -1
  34. package/dist/LaunchMsaView/components/useSWRFeatureSequence.d.ts +4 -5
  35. package/dist/LaunchMsaView/components/useSWRFeatureSequence.js +11 -30
  36. package/dist/LaunchMsaView/components/useSWRFeatureSequence.js.map +1 -1
  37. package/dist/MsaViewPanel/afterCreateAutoruns.js +13 -17
  38. package/dist/MsaViewPanel/afterCreateAutoruns.js.map +1 -1
  39. package/dist/MsaViewPanel/components/ConnectStructureDialog.js +2 -2
  40. package/dist/MsaViewPanel/components/ConnectStructureDialog.js.map +1 -1
  41. package/dist/MsaViewPanel/components/LoadingBLAST.js +2 -3
  42. package/dist/MsaViewPanel/components/LoadingBLAST.js.map +1 -1
  43. package/dist/MsaViewPanel/model.d.ts +9 -11
  44. package/dist/MsaViewPanel/model.js +22 -23
  45. package/dist/MsaViewPanel/model.js.map +1 -1
  46. package/dist/MsaViewPanel/msaDataStore.d.ts +0 -1
  47. package/dist/MsaViewPanel/msaDataStore.js +0 -9
  48. package/dist/MsaViewPanel/msaDataStore.js.map +1 -1
  49. package/dist/MsaViewPanel/structureConnection.d.ts +6 -4
  50. package/dist/MsaViewPanel/structureConnection.js +6 -6
  51. package/dist/MsaViewPanel/structureConnection.js.map +1 -1
  52. package/dist/MsaViewPanel/structureConnection.test.js +1 -19
  53. package/dist/MsaViewPanel/structureConnection.test.js.map +1 -1
  54. package/dist/MsaViewPanel/util.d.ts +11 -0
  55. package/dist/MsaViewPanel/util.js +11 -3
  56. package/dist/MsaViewPanel/util.js.map +1 -1
  57. package/dist/jbrowse-plugin-msaview.umd.production.min.js +25 -27
  58. package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
  59. package/dist/utils/blastCache.d.ts +7 -13
  60. package/dist/utils/blastCache.js +0 -12
  61. package/dist/utils/blastCache.js.map +1 -1
  62. package/dist/utils/msa.d.ts +2 -1
  63. package/dist/utils/msa.js +0 -3
  64. package/dist/utils/msa.js.map +1 -1
  65. package/dist/utils/ncbiBlast.d.ts +3 -2
  66. package/dist/utils/ncbiBlast.js +7 -7
  67. package/dist/utils/ncbiBlast.js.map +1 -1
  68. package/dist/utils/taxonomyNames.js +9 -7
  69. package/dist/utils/taxonomyNames.js.map +1 -1
  70. package/dist/version.d.ts +1 -1
  71. package/dist/version.js +1 -1
  72. package/package.json +22 -20
  73. package/src/AddHighlightModel/GenomeMouseoverHighlight.tsx +8 -25
  74. package/src/AddHighlightModel/MsaToGenomeHighlight.tsx +16 -16
  75. package/src/AddHighlightModel/util.ts +11 -0
  76. package/src/BgzipFastaMsaAdapter/BgzipFastaMsaAdapter.ts +10 -4
  77. package/src/LaunchMsaView/components/LaunchMsaViewDialog.tsx +3 -16
  78. package/src/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.tsx +8 -12
  79. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.tsx +6 -15
  80. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.tsx +0 -9
  81. package/src/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.ts +6 -6
  82. package/src/LaunchMsaView/components/NCBIBlastQuery/consts.ts +7 -0
  83. package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +12 -27
  84. package/src/LaunchMsaView/components/PreLoadedMSA/types.ts +6 -0
  85. package/src/LaunchMsaView/components/types.ts +0 -3
  86. package/src/LaunchMsaView/components/useFeatureSequence.ts +1 -7
  87. package/src/LaunchMsaView/components/useSWRFeatureSequence.ts +10 -37
  88. package/src/MsaViewPanel/afterCreateAutoruns.ts +15 -17
  89. package/src/MsaViewPanel/components/ConnectStructureDialog.tsx +2 -2
  90. package/src/MsaViewPanel/components/LoadingBLAST.tsx +4 -3
  91. package/src/MsaViewPanel/model.ts +33 -33
  92. package/src/MsaViewPanel/msaDataStore.ts +0 -9
  93. package/src/MsaViewPanel/structureConnection.test.ts +0 -21
  94. package/src/MsaViewPanel/structureConnection.ts +7 -7
  95. package/src/MsaViewPanel/util.ts +27 -2
  96. package/src/utils/blastCache.ts +14 -37
  97. package/src/utils/msa.ts +5 -6
  98. package/src/utils/ncbiBlast.ts +18 -11
  99. package/src/utils/taxonomyNames.ts +13 -6
  100. package/src/version.ts +1 -1
  101. package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.d.ts +0 -8
  102. package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js +0 -70
  103. package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js.map +0 -1
  104. package/dist/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeLaunchView.d.ts +0 -13
  105. package/dist/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeLaunchView.js +0 -12
  106. package/dist/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeLaunchView.js.map +0 -1
  107. package/dist/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeUtils.d.ts +0 -6
  108. package/dist/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeUtils.js +0 -25
  109. package/dist/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeUtils.js.map +0 -1
  110. package/dist/LaunchMsaView/components/EnsemblGeneTree/gatherSequencesFromTree.d.ts +0 -2
  111. package/dist/LaunchMsaView/components/EnsemblGeneTree/gatherSequencesFromTree.js +0 -20
  112. package/dist/LaunchMsaView/components/EnsemblGeneTree/gatherSequencesFromTree.js.map +0 -1
  113. package/dist/LaunchMsaView/components/EnsemblGeneTree/types.d.ts +0 -24
  114. package/dist/LaunchMsaView/components/EnsemblGeneTree/types.js +0 -2
  115. package/dist/LaunchMsaView/components/EnsemblGeneTree/types.js.map +0 -1
  116. package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.d.ts +0 -10
  117. package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.js +0 -11
  118. package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.js.map +0 -1
  119. package/dist/LaunchMsaView/components/EnsemblGeneTree/util.d.ts +0 -1
  120. package/dist/LaunchMsaView/components/EnsemblGeneTree/util.js +0 -2
  121. package/dist/LaunchMsaView/components/EnsemblGeneTree/util.js.map +0 -1
  122. package/src/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.tsx +0 -123
  123. package/src/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeLaunchView.ts +0 -30
  124. package/src/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeUtils.ts +0 -47
  125. package/src/LaunchMsaView/components/EnsemblGeneTree/gatherSequencesFromTree.ts +0 -22
  126. package/src/LaunchMsaView/components/EnsemblGeneTree/types.ts +0 -28
  127. package/src/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.ts +0 -17
  128. package/src/LaunchMsaView/components/EnsemblGeneTree/util.ts +0 -6
@@ -18,7 +18,7 @@ import { makeStyles } from 'tss-react/mui'
18
18
 
19
19
  import CachedBlastResults from './CachedBlastResults'
20
20
  import { blastLaunchView } from './blastLaunchView'
21
- import { msaAlgorithms } from './consts'
21
+ import { blastDatabaseOptions, blastPrograms, msaAlgorithms } from './consts'
22
22
  import { useCachedBlastResults } from './useCachedBlastResults'
23
23
  import TextField2 from '../../../components/TextField2'
24
24
  import {
@@ -29,7 +29,7 @@ import {
29
29
  import TranscriptSelector from '../TranscriptSelector'
30
30
  import { useTranscriptSelection } from '../useTranscriptSelection'
31
31
 
32
- import type { MsaAlgorithm } from './consts'
32
+ import type { BlastDatabase, BlastProgram, MsaAlgorithm } from './consts'
33
33
  import type { AbstractTrackModel, Feature } from '@jbrowse/core/util'
34
34
  import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
35
35
 
@@ -55,12 +55,6 @@ const useStyles = makeStyles()({
55
55
  },
56
56
  })
57
57
 
58
- const blastDatabaseOptions = ['nr', 'nr_cluster_seq'] as const
59
- const blastPrograms = ['blastp', 'quick-blastp'] as const
60
-
61
- type blastDatabaseOptionsT = (typeof blastDatabaseOptions)[number]
62
- type blastProgramsT = (typeof blastPrograms)[number]
63
-
64
58
  const NCBIBlastAutomaticPanel = observer(function ({
65
59
  handleClose,
66
60
  feature,
@@ -78,11 +72,11 @@ const NCBIBlastAutomaticPanel = observer(function ({
78
72
  const view = getContainingView(model) as LinearGenomeViewModel
79
73
  const [launchViewError, setLaunchViewError] = useState<unknown>()
80
74
  const [selectedBlastDatabase, setSelectedBlastDatabase] =
81
- useState<blastDatabaseOptionsT>('nr')
75
+ useState<BlastDatabase>('nr')
82
76
  const [selectedMsaAlgorithm, setSelectedMsaAlgorithm] =
83
77
  useState<MsaAlgorithm>('clustalo')
84
78
  const [selectedBlastProgram, setSelectedBlastProgram] =
85
- useState<blastProgramsT>('quick-blastp')
79
+ useState<BlastProgram>('quick-blastp')
86
80
 
87
81
  const geneIds = useMemo(() => getGeneIdentifiers(feature), [feature])
88
82
  const { results: cachedResults, error: cachedResultsError } =
@@ -109,8 +103,7 @@ const NCBIBlastAutomaticPanel = observer(function ({
109
103
  select
110
104
  value={selectedBlastDatabase}
111
105
  onChange={event => {
112
- const newDb = event.target
113
- .value as (typeof blastDatabaseOptions)[number]
106
+ const newDb = event.target.value as BlastDatabase
114
107
  setSelectedBlastDatabase(newDb)
115
108
  if (newDb === 'nr_cluster_seq') {
116
109
  setSelectedBlastProgram('blastp')
@@ -150,9 +143,7 @@ const NCBIBlastAutomaticPanel = observer(function ({
150
143
  select
151
144
  value={selectedBlastProgram}
152
145
  onChange={event => {
153
- setSelectedBlastProgram(
154
- event.target.value as (typeof blastPrograms)[number],
155
- )
146
+ setSelectedBlastProgram(event.target.value as BlastProgram)
156
147
  }}
157
148
  >
158
149
  {blastPrograms.map(val => (
@@ -96,15 +96,6 @@ const NCBIBlastManualPanel = observer(function ({
96
96
  onClick={() => {
97
97
  handleClose()
98
98
  }}
99
- >
100
- Submit
101
- </Button>
102
- <Button
103
- color="secondary"
104
- variant="contained"
105
- onClick={() => {
106
- handleClose()
107
- }}
108
99
  >
109
100
  Close
110
101
  </Button>
@@ -1,6 +1,6 @@
1
1
  import { getSession } from '@jbrowse/core/util'
2
2
 
3
- import type { JBrowsePluginMsaViewModel } from '../../../MsaViewPanel/model'
3
+ import type { BlastParams } from '../../../MsaViewPanel/model'
4
4
  import type { CachedBlastResult } from '../../../utils/blastCache'
5
5
  import type { Feature } from '@jbrowse/core/util'
6
6
  import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
@@ -14,9 +14,9 @@ export function blastLaunchView({
14
14
  newViewTitle: string
15
15
  view: LinearGenomeViewModel
16
16
  feature: Feature
17
- blastParams: Record<string, unknown>
17
+ blastParams: BlastParams
18
18
  }) {
19
- return getSession(view).addView('MsaView', {
19
+ getSession(view).addView('MsaView', {
20
20
  type: 'MsaView',
21
21
  displayName: newViewTitle,
22
22
  connectedViewId: view.id,
@@ -25,7 +25,7 @@ export function blastLaunchView({
25
25
  colWidth: 10,
26
26
  rowHeight: 12,
27
27
  blastParams,
28
- }) as JBrowsePluginMsaViewModel
28
+ })
29
29
  }
30
30
 
31
31
  export function blastLaunchViewFromCache({
@@ -37,7 +37,7 @@ export function blastLaunchViewFromCache({
37
37
  view: LinearGenomeViewModel
38
38
  cached: CachedBlastResult
39
39
  }) {
40
- return getSession(view).addView('MsaView', {
40
+ getSession(view).addView('MsaView', {
41
41
  type: 'MsaView',
42
42
  displayName: newViewTitle,
43
43
  connectedViewId: view.id,
@@ -49,5 +49,5 @@ export function blastLaunchViewFromCache({
49
49
  tree: cached.tree,
50
50
  treeMetadata: cached.treeMetadata,
51
51
  },
52
- }) as JBrowsePluginMsaViewModel
52
+ })
53
53
  }
@@ -1,3 +1,10 @@
1
1
  export const BASE_BLAST_URL = 'https://blast.ncbi.nlm.nih.gov/Blast.cgi'
2
+
2
3
  export const msaAlgorithms = ['clustalo', 'muscle', 'kalign', 'mafft'] as const
3
4
  export type MsaAlgorithm = (typeof msaAlgorithms)[number]
5
+
6
+ export const blastDatabaseOptions = ['nr', 'nr_cluster_seq'] as const
7
+ export type BlastDatabase = (typeof blastDatabaseOptions)[number]
8
+
9
+ export const blastPrograms = ['blastp', 'quick-blastp'] as const
10
+ export type BlastProgram = (typeof blastPrograms)[number]
@@ -1,6 +1,5 @@
1
1
  import React, { useState } from 'react'
2
2
 
3
- import { readConfObject } from '@jbrowse/core/configuration'
4
3
  import { ErrorMessage, LoadingEllipses, SanitizedHTML } from '@jbrowse/core/ui'
5
4
  import { getContainingView, getEnv, getSession } from '@jbrowse/core/util'
6
5
  import { Button, DialogActions, DialogContent, MenuItem } from '@mui/material'
@@ -15,8 +14,8 @@ import { useTranscriptSelection } from '../useTranscriptSelection'
15
14
  import { swrFlags } from './consts'
16
15
  import { fetchMSA, fetchMSAList } from './fetchMSAData'
17
16
  import { preCalculatedLaunchView } from './preCalculatedLaunchView'
17
+ import { readMsaDatasets } from './types'
18
18
 
19
- import type { Dataset } from './types'
20
19
  import type { AbstractTrackModel, Feature } from '@jbrowse/core/util'
21
20
  import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
22
21
 
@@ -45,10 +44,7 @@ const PreLoadedMSA = observer(function ({
45
44
  const { assemblyNames } = view
46
45
  const [viewError, setViewError] = useState<unknown>()
47
46
 
48
- const { jbrowse } = session
49
- const datasets = readConfObject(jbrowse, ['msa', 'datasets']) as
50
- | Dataset[]
51
- | undefined
47
+ const datasets = readMsaDatasets(session.jbrowse)
52
48
  const [selectedDatasetId, setSelectedDatasetId] = useState(
53
49
  datasets?.[0]?.datasetId,
54
50
  )
@@ -58,14 +54,8 @@ const PreLoadedMSA = observer(function ({
58
54
  isLoading: msaListLoading,
59
55
  error: msaListFetchError,
60
56
  } = useSWR(
61
- selectedDatasetId ? `${selectedDatasetId}-msa-list` : 'none-msa-list',
62
- () =>
63
- selectedDataset
64
- ? fetchMSAList({
65
- config: selectedDataset.adapter,
66
- pluginManager,
67
- })
68
- : undefined,
57
+ selectedDataset ? `${selectedDataset.datasetId}-msa-list` : null,
58
+ () => fetchMSAList({ config: selectedDataset!.adapter, pluginManager }),
69
59
  swrFlags,
70
60
  )
71
61
 
@@ -83,25 +73,20 @@ const PreLoadedMSA = observer(function ({
83
73
  isLoading: msaDataLoading,
84
74
  error: msaDataFetchError,
85
75
  } = useSWR(
86
- selectedId && selectedDatasetId
87
- ? `${selectedDatasetId}-${selectedId}-${msaList?.length}-msa`
88
- : 'none-msa',
76
+ selectedId && selectedDataset && msaList
77
+ ? `${selectedDataset.datasetId}-${selectedId}-${msaList.length}-msa`
78
+ : null,
89
79
  () =>
90
- selectedId && selectedDataset && msaList
91
- ? fetchMSA({
92
- msaId: selectedId,
93
- config: selectedDataset.adapter,
94
- pluginManager,
95
- })
96
- : undefined,
80
+ fetchMSA({
81
+ msaId: selectedId,
82
+ config: selectedDataset!.adapter,
83
+ pluginManager,
84
+ }),
97
85
  swrFlags,
98
86
  )
99
87
 
100
88
  const e =
101
89
  msaListFetchError ?? msaDataFetchError ?? proteinSequenceError ?? viewError
102
- if (e) {
103
- console.error(e)
104
- }
105
90
  return (
106
91
  <>
107
92
  <DialogContent className={classes.dialogContent}>
@@ -1,3 +1,5 @@
1
+ import { readConfObject } from '@jbrowse/core/configuration'
2
+
1
3
  import type { AnyConfigurationModel } from '@jbrowse/core/configuration'
2
4
 
3
5
  export interface Dataset {
@@ -6,3 +8,7 @@ export interface Dataset {
6
8
  description?: string
7
9
  adapter: AnyConfigurationModel
8
10
  }
11
+
12
+ export function readMsaDatasets(jbrowse: AnyConfigurationModel) {
13
+ return readConfObject(jbrowse, ['msa', 'datasets']) as Dataset[] | undefined
14
+ }
@@ -6,7 +6,4 @@ export interface Feat {
6
6
 
7
7
  export interface SeqState {
8
8
  seq: string
9
- upstream?: string
10
- downstream?: string
11
- error?: unknown
12
9
  }
@@ -6,23 +6,17 @@ import type { Feature } from '@jbrowse/core/util'
6
6
  export function useFeatureSequence({
7
7
  view,
8
8
  feature,
9
- upDownBp = 0,
10
- forceLoad = true,
11
9
  }: {
12
10
  view: { assemblyNames?: string[] } | undefined
13
11
  feature?: Feature
14
- upDownBp?: number
15
- forceLoad?: boolean
16
12
  }) {
17
13
  const { sequence, error } = useSWRFeatureSequence({
18
14
  view,
19
15
  feature,
20
- upDownBp,
21
- forceLoad,
22
16
  })
23
17
 
24
18
  const proteinSequence =
25
- sequence && !('error' in sequence) && feature
19
+ sequence && feature
26
20
  ? getProteinSequenceFromFeature({
27
21
  seq: sequence.seq,
28
22
  feature,
@@ -3,77 +3,50 @@ import useSWR from 'swr'
3
3
 
4
4
  import { fetchSeq } from './fetchSeq'
5
5
 
6
- import type { SeqState } from './types'
7
6
  import type { Feature } from '@jbrowse/core/util'
8
7
 
9
8
  async function featureSequenceFetcher({
10
9
  feature,
11
10
  assemblyName,
12
- upDownBp,
13
11
  view,
14
12
  }: {
15
13
  feature: Feature
16
14
  assemblyName: string
17
- upDownBp: number
18
15
  view: { assemblyNames?: string[] }
19
- }): Promise<SeqState | undefined> {
16
+ }) {
20
17
  const session = getSession(view)
21
18
  const { start, end, refName } = feature.toJSON() as {
22
19
  start: number
23
20
  end: number
24
21
  refName: string
25
22
  }
26
-
27
- const b = start - upDownBp
28
- const e = end + upDownBp
29
- const [seq, upstream, downstream] = await Promise.all([
30
- fetchSeq({
31
- start,
32
- end,
33
- refName,
34
- assemblyName,
35
- session,
36
- }),
37
- fetchSeq({
38
- start: Math.max(0, b),
39
- end: start,
40
- refName,
41
- assemblyName,
42
- session,
43
- }),
44
- fetchSeq({
45
- start: end,
46
- end: e,
47
- refName,
48
- assemblyName,
49
- session,
50
- }),
51
- ])
52
- return { seq, upstream, downstream }
23
+ const seq = await fetchSeq({
24
+ start,
25
+ end,
26
+ refName,
27
+ assemblyName,
28
+ session,
29
+ })
30
+ return { seq }
53
31
  }
54
32
 
55
33
  export function useSWRFeatureSequence({
56
34
  view,
57
35
  feature,
58
- upDownBp = 0,
59
- forceLoad = true,
60
36
  }: {
61
37
  view: { assemblyNames?: string[] } | undefined
62
38
  feature?: Feature
63
- upDownBp?: number
64
- forceLoad?: boolean
65
39
  }) {
66
40
  const assemblyName = view?.assemblyNames?.[0]
67
41
  const { data, error } = useSWR(
68
42
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
69
43
  feature && assemblyName && view
70
- ? [feature.id(), assemblyName, upDownBp, forceLoad, 'feature-sequence']
44
+ ? [feature.id(), assemblyName, 'feature-sequence']
71
45
  : null,
72
46
  () =>
73
47
  featureSequenceFetcher({
74
48
  feature: feature!,
75
49
  assemblyName: assemblyName!,
76
- upDownBp,
77
50
  view: view!,
78
51
  }),
79
52
  {
@@ -8,7 +8,10 @@ import {
8
8
  retrieveMsaData,
9
9
  storeMsaData,
10
10
  } from './msaDataStore'
11
- import { gappedToUngappedPosition, isProteinView } from './structureConnection'
11
+ import {
12
+ gappedToUngappedPosition,
13
+ getProteinViews,
14
+ } from './structureConnection'
12
15
  import { getUniprotIdFromAlphaFoldUrl } from './util'
13
16
 
14
17
  import type { JBrowsePluginMsaViewModel } from './model'
@@ -39,10 +42,9 @@ export function loadStoredData(self: JBrowsePluginMsaViewModel) {
39
42
  }
40
43
 
41
44
  export function storeDataToIndexedDB(self: JBrowsePluginMsaViewModel) {
42
- const { rows, dataStoreId } = self
43
- if (rows.length > 0 && !dataStoreId) {
44
- const hasFilehandle = !!(self.msaFilehandle ?? self.treeFilehandle)
45
- if (hasFilehandle) {
45
+ const { rows, dataStoreId, isStoringData } = self
46
+ if (rows.length > 0 && !dataStoreId && !isStoringData) {
47
+ if (self.msaFilehandle || self.treeFilehandle) {
46
48
  return
47
49
  }
48
50
 
@@ -50,6 +52,10 @@ export function storeDataToIndexedDB(self: JBrowsePluginMsaViewModel) {
50
52
  const treeData = self.data.tree
51
53
 
52
54
  if (msaData || treeData) {
55
+ // mark as storing synchronously so re-runs of this autorun (e.g. when
56
+ // data observables change while the write is pending) don't kick off a
57
+ // duplicate write and leave an orphan IndexedDB entry
58
+ self.setIsStoringData(true)
53
59
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
54
60
  ;(async () => {
55
61
  try {
@@ -64,6 +70,8 @@ export function storeDataToIndexedDB(self: JBrowsePluginMsaViewModel) {
64
70
  }
65
71
  } catch (e) {
66
72
  console.error('Failed to store MSA data to IndexedDB:', e)
73
+ } finally {
74
+ self.setIsStoringData(false)
67
75
  }
68
76
  })()
69
77
  }
@@ -194,18 +202,13 @@ export function highlightConnectedStructures(self: JBrowsePluginMsaViewModel) {
194
202
  }
195
203
 
196
204
  export function autoConnectStructures(self: JBrowsePluginMsaViewModel) {
197
- const views = getSession(self).views as unknown[]
198
205
  const { connectedViewId, uniprotId, rows, connectedStructures } = self
199
206
 
200
207
  if (!uniprotId || rows.length === 0) {
201
208
  return
202
209
  }
203
210
 
204
- for (const view of views) {
205
- if (!isProteinView(view)) {
206
- continue
207
- }
208
-
211
+ for (const view of getProteinViews(getSession(self).views)) {
209
212
  for (
210
213
  let structureIdx = 0;
211
214
  structureIdx < view.structures.length;
@@ -245,7 +248,6 @@ export function autoConnectStructures(self: JBrowsePluginMsaViewModel) {
245
248
  }
246
249
 
247
250
  export function observeProteinHighlights(self: JBrowsePluginMsaViewModel) {
248
- const views = getSession(self).views as unknown[]
249
251
  const { connectedViewId, transcriptToMsaMap, querySeqName } = self
250
252
 
251
253
  if (!connectedViewId || !transcriptToMsaMap) {
@@ -254,11 +256,7 @@ export function observeProteinHighlights(self: JBrowsePluginMsaViewModel) {
254
256
 
255
257
  const columns = new Set<number>()
256
258
 
257
- for (const view of views) {
258
- if (!isProteinView(view)) {
259
- continue
260
- }
261
-
259
+ for (const view of getProteinViews(getSession(self).views)) {
262
260
  for (const structure of view.structures) {
263
261
  if (structure.connectedViewId !== connectedViewId) {
264
262
  continue
@@ -15,7 +15,7 @@ import {
15
15
  import { observer } from 'mobx-react'
16
16
  import { makeStyles } from 'tss-react/mui'
17
17
 
18
- import { isProteinView } from '../structureConnection'
18
+ import { getProteinViews } from '../structureConnection'
19
19
 
20
20
  import type { JBrowsePluginMsaViewModel } from '../model'
21
21
 
@@ -39,7 +39,7 @@ const ConnectStructureDialog = observer(function ConnectStructureDialog({
39
39
  const [selectedMsaRow, setSelectedMsaRow] = useState(model.querySeqName)
40
40
  const [error, setError] = useState<string>()
41
41
 
42
- const proteinViews = (session.views as unknown[]).filter(isProteinView)
42
+ const proteinViews = getProteinViews(session.views)
43
43
 
44
44
  const selectedView = proteinViews.find(v => v.id === selectedViewId)
45
45
  const structures = selectedView?.structures ?? []
@@ -60,7 +60,7 @@ const LoadingBLAST = observer(function LoadingBLAST2({
60
60
  model: JBrowsePluginMsaViewModel
61
61
  baseUrl: string
62
62
  }) {
63
- const { progress, rid, error, processing } = model
63
+ const { progress, rid, error } = model
64
64
  const { classes } = useStyles()
65
65
  return (
66
66
  <div className={classes.margin}>
@@ -69,8 +69,9 @@ const LoadingBLAST = observer(function LoadingBLAST2({
69
69
  <RIDError baseUrl={baseUrl} rid={rid} error={error} />
70
70
  ) : rid ? (
71
71
  <RIDProgress baseUrl={baseUrl} rid={rid} progress={progress} />
72
- ) : null}
73
- <Typography>{processing || 'Initializing BLAST query'}</Typography>
72
+ ) : (
73
+ <Typography>{progress || 'Initializing BLAST query'}</Typography>
74
+ )}
74
75
  </div>
75
76
  )
76
77
  })
@@ -22,13 +22,18 @@ import { genomeToMSA } from './genomeToMSA'
22
22
  import { msaCoordToGenomeCoord } from './msaCoordToGenomeCoord'
23
23
  import { buildAlignmentMaps, runPairwiseAlignment } from './pairwiseAlignment'
24
24
  import {
25
- isProteinView,
26
- mapToRecord,
25
+ getProteinViews,
27
26
  ungappedToGappedPosition,
28
27
  } from './structureConnection'
28
+ import { getCanonicalRefName } from './util'
29
29
 
30
30
  import type { ProteinView, StructureConnection } from './structureConnection'
31
31
  import type { MafRegion, MsaViewInitState } from './types'
32
+ import type {
33
+ BlastDatabase,
34
+ BlastProgram,
35
+ MsaAlgorithm,
36
+ } from '../LaunchMsaView/components/NCBIBlastQuery/consts'
32
37
  import type { Feature } from '@jbrowse/core/util'
33
38
  import type { Instance } from '@jbrowse/mobx-state-tree'
34
39
  import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
@@ -49,9 +54,9 @@ export interface IRegion {
49
54
 
50
55
  export interface BlastParams {
51
56
  baseUrl: string
52
- blastDatabase: string
53
- msaAlgorithm: string
54
- blastProgram: string
57
+ blastDatabase: BlastDatabase
58
+ msaAlgorithm: MsaAlgorithm
59
+ blastProgram: BlastProgram
55
60
  selectedTranscript?: Feature
56
61
  proteinSequence: string
57
62
  rid?: string
@@ -133,6 +138,7 @@ export default function stateModelFactory() {
133
138
  progress: string
134
139
  error: unknown
135
140
  loadingStoredData: boolean
141
+ isStoringData: boolean
136
142
  } => ({
137
143
  /**
138
144
  * #volatile
@@ -150,6 +156,10 @@ export default function stateModelFactory() {
150
156
  * #volatile
151
157
  */
152
158
  loadingStoredData: false,
159
+ /**
160
+ * #volatile
161
+ */
162
+ isStoringData: false,
153
163
  }),
154
164
  )
155
165
 
@@ -179,13 +189,6 @@ export default function stateModelFactory() {
179
189
  : undefined
180
190
  },
181
191
 
182
- /**
183
- * #getter
184
- */
185
- get processing() {
186
- return !!self.progress
187
- },
188
-
189
192
  /**
190
193
  * #getter
191
194
  */
@@ -198,14 +201,12 @@ export default function stateModelFactory() {
198
201
  * #getter
199
202
  */
200
203
  get connectedProteinViews() {
201
- const { views } = getSession(self)
202
- const unknownViews = views as unknown[]
204
+ const proteinViews = getProteinViews(getSession(self).views)
203
205
  const result: (StructureConnection & { proteinView: ProteinView })[] =
204
206
  []
205
207
  for (const conn of self.connectedStructures) {
206
- const proteinView = unknownViews.find(
207
- (v): v is ProteinView =>
208
- isProteinView(v) && v.id === conn.proteinViewId,
208
+ const proteinView = proteinViews.find(
209
+ v => v.id === conn.proteinViewId,
209
210
  )
210
211
  if (proteinView) {
211
212
  result.push({ ...conn, proteinView })
@@ -251,12 +252,6 @@ export default function stateModelFactory() {
251
252
  }
252
253
  return genomeToMSA({ model: self as JBrowsePluginMsaViewModel })
253
254
  },
254
- /**
255
- * #getter
256
- */
257
- get clickCol2() {
258
- return undefined
259
- },
260
255
  }))
261
256
 
262
257
  .actions(self => ({
@@ -344,6 +339,12 @@ export default function stateModelFactory() {
344
339
  setLoadingStoredData(arg: boolean) {
345
340
  self.loadingStoredData = arg
346
341
  },
342
+ /**
343
+ * #action
344
+ */
345
+ setIsStoringData(arg: boolean) {
346
+ self.isStoringData = arg
347
+ },
347
348
  /**
348
349
  * #action
349
350
  */
@@ -359,10 +360,11 @@ export default function stateModelFactory() {
359
360
  if (zoomToBaseLevel) {
360
361
  connectedView.navTo(r2)
361
362
  } else {
362
- const r =
363
- assemblyManager
364
- .get(connectedView.assemblyNames[0]!)
365
- ?.getCanonicalRefName(r2.refName) ?? r2.refName
363
+ const r = getCanonicalRefName({
364
+ assemblyManager,
365
+ assemblyNames: connectedView.assemblyNames,
366
+ refName: r2.refName,
367
+ })
366
368
  connectedView.centerAt(r2.start, r)
367
369
  }
368
370
  },
@@ -383,10 +385,8 @@ export default function stateModelFactory() {
383
385
 
384
386
  const ungappedMsaSequence = msaSequence.replaceAll('-', '')
385
387
 
386
- const { views } = getSession(self)
387
-
388
- const proteinView = (views as unknown[]).find(
389
- (v): v is ProteinView => isProteinView(v) && v.id === proteinViewId,
388
+ const proteinView = getProteinViews(getSession(self).views).find(
389
+ v => v.id === proteinViewId,
390
390
  )
391
391
  if (!proteinView) {
392
392
  throw new Error(`ProteinView "${proteinViewId}" not found`)
@@ -412,8 +412,8 @@ export default function stateModelFactory() {
412
412
  proteinViewId,
413
413
  structureIdx,
414
414
  msaRowName: rowName,
415
- msaToStructure: mapToRecord(seq1ToSeq2),
416
- structureToMsa: mapToRecord(seq2ToSeq1),
415
+ msaToStructure: Object.fromEntries(seq1ToSeq2),
416
+ structureToMsa: Object.fromEntries(seq2ToSeq1),
417
417
  }
418
418
 
419
419
  self.connectedStructures.push(connection)
@@ -66,15 +66,6 @@ export async function retrieveMsaData(id: string) {
66
66
  }
67
67
  }
68
68
 
69
- export async function deleteMsaData(id: string) {
70
- try {
71
- const db = await getDB()
72
- await db.delete(STORE_NAME, id)
73
- } catch (e) {
74
- console.warn('Failed to delete MSA data:', e)
75
- }
76
- }
77
-
78
69
  export async function cleanupOldData(maxAgeMs = 7 * 24 * 60 * 60 * 1000) {
79
70
  try {
80
71
  const db = await getDB()
@@ -2,7 +2,6 @@ import { describe, expect, test } from 'vitest'
2
2
 
3
3
  import {
4
4
  gappedToUngappedPosition,
5
- mapToRecord,
6
5
  ungappedToGappedPosition,
7
6
  } from './structureConnection'
8
7
 
@@ -121,23 +120,3 @@ describe('gappedToUngappedPosition and ungappedToGappedPosition are inverses', (
121
120
  }
122
121
  })
123
122
  })
124
-
125
- describe('mapToRecord', () => {
126
- test('converts Map to Record', () => {
127
- const map = new Map<number, number>([
128
- [0, 5],
129
- [1, 10],
130
- [2, 15],
131
- ])
132
- const record = mapToRecord(map)
133
- expect(record[0]).toBe(5)
134
- expect(record[1]).toBe(10)
135
- expect(record[2]).toBe(15)
136
- })
137
-
138
- test('handles empty Map', () => {
139
- const map = new Map<number, number>()
140
- const record = mapToRecord(map)
141
- expect(Object.keys(record)).toHaveLength(0)
142
- })
143
- })