jbrowse-plugin-protein3d 0.4.10 → 0.4.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LaunchProteinView/components/AlphaFoldDBSearch.d.ts +5 -3
- package/dist/LaunchProteinView/components/AlphaFoldDBSearch.js +1 -4
- package/dist/LaunchProteinView/components/AlphaFoldDBSearchStatus.js +8 -13
- package/dist/LaunchProteinView/components/FoldseekSearch.d.ts +5 -3
- package/dist/LaunchProteinView/components/FoldseekSearch.js +7 -15
- package/dist/LaunchProteinView/components/IsoformSequencesToggle.d.ts +10 -0
- package/dist/LaunchProteinView/components/IsoformSequencesToggle.js +13 -0
- package/dist/LaunchProteinView/components/LaunchProteinViewDialog.js +6 -3
- package/dist/LaunchProteinView/components/StructureSourcePicker.d.ts +1 -2
- package/dist/LaunchProteinView/components/StructureSourcePicker.js +1 -1
- package/dist/LaunchProteinView/components/UserProvidedStructure.d.ts +6 -3
- package/dist/LaunchProteinView/components/UserProvidedStructure.js +10 -35
- package/dist/LaunchProteinView/hooks/swrOptions.d.ts +5 -0
- package/dist/LaunchProteinView/hooks/swrOptions.js +8 -0
- package/dist/LaunchProteinView/hooks/useAlphaFoldDBSearch.js +17 -15
- package/dist/LaunchProteinView/hooks/useAlphaFoldData.d.ts +1 -0
- package/dist/LaunchProteinView/hooks/useAlphaFoldData.js +3 -4
- package/dist/LaunchProteinView/hooks/useAlphaFoldSequenceSearch.d.ts +1 -0
- package/dist/LaunchProteinView/hooks/useAlphaFoldSequenceSearch.js +4 -4
- package/dist/LaunchProteinView/hooks/useFoldseekSearch.js +47 -12
- package/dist/LaunchProteinView/hooks/useIsoformProteinSequences.js +8 -4
- package/dist/LaunchProteinView/hooks/useStructureFileSequence.d.ts +9 -0
- package/dist/LaunchProteinView/hooks/useStructureFileSequence.js +50 -0
- package/dist/LaunchProteinView/hooks/useTranscriptIsoformSelection.d.ts +24 -0
- package/dist/LaunchProteinView/hooks/useTranscriptIsoformSelection.js +33 -0
- package/dist/LaunchProteinView/hooks/useUniProtSearch.js +2 -3
- package/dist/LaunchProteinView/services/foldseekApi.d.ts +23 -5
- package/dist/LaunchProteinView/services/foldseekApi.js +21 -13
- package/dist/LaunchProteinView/utils/calculateProteinSequence.d.ts +4 -5
- package/dist/LaunchProteinView/utils/calculateProteinSequence.js +2 -4
- package/dist/LaunchProteinView/utils/util.d.ts +0 -1
- package/dist/LaunchProteinView/utils/util.js +0 -3
- package/dist/LaunchProteinViewExtensionPoint/index.js +44 -7
- package/dist/LaunchProteinViewExtensionPoint/resolveShortLaunch.d.ts +26 -0
- package/dist/LaunchProteinViewExtensionPoint/resolveShortLaunch.js +91 -0
- package/dist/ProteinView/applyColorTheme.d.ts +1 -1
- package/dist/ProteinView/components/FeatureBar.js +2 -2
- package/dist/ProteinView/components/FeatureTypeLabel.js +2 -2
- package/dist/ProteinView/components/HeaderStructureInfo.d.ts +1 -1
- package/dist/ProteinView/components/HeaderStructureInfo.js +12 -6
- package/dist/ProteinView/components/ProteinAlignment.js +5 -5
- package/dist/ProteinView/components/ProteinFeatureTrack.js +3 -3
- package/dist/ProteinView/components/ProteinView.js +7 -2
- package/dist/ProteinView/components/ProteinViewHeader.js +69 -18
- package/dist/ProteinView/components/ResidueValueTrack.js +4 -4
- package/dist/ProteinView/constants.d.ts +4 -2
- package/dist/ProteinView/constants.js +4 -2
- package/dist/ProteinView/loadStructureData.d.ts +18 -0
- package/dist/ProteinView/loadStructureData.js +22 -0
- package/dist/ProteinView/model.d.ts +25 -11
- package/dist/ProteinView/model.js +18 -36
- package/dist/ProteinView/structureLoader.d.ts +30 -0
- package/dist/ProteinView/structureLoader.js +58 -0
- package/dist/ProteinView/structureModel.d.ts +26 -1
- package/dist/ProteinView/structureModel.js +53 -8
- package/dist/ProteinView/useProteinView.js +43 -8
- package/dist/config.json +1 -1
- package/dist/fetchUtils.d.ts +1 -1
- package/dist/fetchUtils.js +18 -2
- package/dist/jbrowse-plugin-protein3d.umd.production.min.js +16 -16
- package/dist/jbrowse-plugin-protein3d.umd.production.min.js.map +4 -4
- package/dist/molstar-chunk.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -2
- package/src/LaunchProteinView/components/AlphaFoldDBSearch.tsx +5 -6
- package/src/LaunchProteinView/components/AlphaFoldDBSearchStatus.tsx +12 -27
- package/src/LaunchProteinView/components/FoldseekSearch.tsx +17 -24
- package/src/LaunchProteinView/components/IsoformSequencesToggle.tsx +41 -0
- package/src/LaunchProteinView/components/LaunchProteinViewDialog.tsx +10 -3
- package/src/LaunchProteinView/components/StructureSourcePicker.tsx +0 -2
- package/src/LaunchProteinView/components/UserProvidedStructure.tsx +24 -53
- package/src/LaunchProteinView/hooks/swrOptions.ts +8 -0
- package/src/LaunchProteinView/hooks/useAlphaFoldDBSearch.ts +30 -29
- package/src/LaunchProteinView/hooks/useAlphaFoldData.ts +4 -4
- package/src/LaunchProteinView/hooks/useAlphaFoldSequenceSearch.ts +13 -12
- package/src/LaunchProteinView/hooks/useFoldseekSearch.ts +49 -12
- package/src/LaunchProteinView/hooks/useIsoformProteinSequences.ts +8 -4
- package/src/LaunchProteinView/hooks/useStructureFileSequence.ts +67 -0
- package/src/LaunchProteinView/hooks/useTranscriptIsoformSelection.ts +47 -0
- package/src/LaunchProteinView/hooks/useUniProtSearch.ts +2 -3
- package/src/LaunchProteinView/services/foldseekApi.ts +57 -23
- package/src/LaunchProteinView/utils/calculateProteinSequence.ts +5 -6
- package/src/LaunchProteinView/utils/util.ts +0 -4
- package/src/LaunchProteinViewExtensionPoint/index.ts +54 -6
- package/src/LaunchProteinViewExtensionPoint/resolveShortLaunch.ts +143 -0
- package/src/ProteinView/components/FeatureBar.tsx +2 -7
- package/src/ProteinView/components/FeatureTypeLabel.tsx +2 -2
- package/src/ProteinView/components/HeaderStructureInfo.tsx +21 -10
- package/src/ProteinView/components/ProteinAlignment.tsx +13 -9
- package/src/ProteinView/components/ProteinFeatureTrack.tsx +3 -3
- package/src/ProteinView/components/ProteinView.tsx +11 -2
- package/src/ProteinView/components/ProteinViewHeader.tsx +104 -43
- package/src/ProteinView/components/ResidueValueTrack.tsx +4 -4
- package/src/ProteinView/constants.ts +4 -2
- package/src/ProteinView/loadStructureData.ts +36 -0
- package/src/ProteinView/model.ts +18 -47
- package/src/ProteinView/structureLoader.test.ts +102 -0
- package/src/ProteinView/structureLoader.ts +74 -0
- package/src/ProteinView/structureModel.ts +63 -8
- package/src/ProteinView/useProteinView.ts +49 -8
- package/src/fetchUtils.test.ts +27 -0
- package/src/fetchUtils.ts +22 -2
- package/src/version.ts +1 -1
- package/dist/LaunchProteinView/hooks/useLocalStructureFileSequence.d.ts +0 -7
- package/dist/LaunchProteinView/hooks/useLocalStructureFileSequence.js +0 -39
- package/dist/LaunchProteinView/hooks/useRemoteStructureFileSequence.d.ts +0 -7
- package/dist/LaunchProteinView/hooks/useRemoteStructureFileSequence.js +0 -28
- package/src/LaunchProteinView/hooks/useLocalStructureFileSequence.ts +0 -60
- package/src/LaunchProteinView/hooks/useRemoteStructureFileSequence.ts +0 -41
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { AlignmentAlgorithm } from '../../ProteinView/types';
|
|
3
|
-
import type {
|
|
4
|
-
|
|
3
|
+
import type { AbstractSessionModel, Feature } from '@jbrowse/core/util';
|
|
4
|
+
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
5
|
+
declare const AlphaFoldDBSearch: ({ feature, session, view, handleClose, alignmentAlgorithm, onAlignmentAlgorithmChange, }: {
|
|
5
6
|
feature: Feature;
|
|
6
|
-
|
|
7
|
+
session: AbstractSessionModel;
|
|
8
|
+
view: LinearGenomeViewModel;
|
|
7
9
|
handleClose: () => void;
|
|
8
10
|
alignmentAlgorithm: AlignmentAlgorithm;
|
|
9
11
|
onAlignmentAlgorithmChange: (algorithm: AlignmentAlgorithm) => void;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
3
|
-
import { getContainingView, getSession } from '@jbrowse/core/util';
|
|
4
3
|
import { DialogActions, DialogContent, Typography } from '@mui/material';
|
|
5
4
|
import { observer } from 'mobx-react';
|
|
6
5
|
import { makeStyles } from 'tss-react/mui';
|
|
@@ -30,10 +29,8 @@ const useStyles = makeStyles()({
|
|
|
30
29
|
alignItems: 'flex-start',
|
|
31
30
|
},
|
|
32
31
|
});
|
|
33
|
-
const AlphaFoldDBSearch = observer(function AlphaFoldDBSearch({ feature,
|
|
32
|
+
const AlphaFoldDBSearch = observer(function AlphaFoldDBSearch({ feature, session, view, handleClose, alignmentAlgorithm, onAlignmentAlgorithmChange, }) {
|
|
34
33
|
const { classes } = useStyles();
|
|
35
|
-
const session = getSession(model);
|
|
36
|
-
const view = getContainingView(model);
|
|
37
34
|
const state = useAlphaFoldDBSearch({ feature, view });
|
|
38
35
|
return (React.createElement(React.Fragment, null,
|
|
39
36
|
React.createElement(DialogContent, { className: classes.dialogContent },
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Typography } from '@mui/material';
|
|
3
|
+
import IsoformSequencesToggle from './IsoformSequencesToggle';
|
|
4
4
|
import ExternalLink from '../../components/ExternalLink';
|
|
5
|
-
import {
|
|
5
|
+
import { getTranscriptDisplayName } from '../utils/util';
|
|
6
6
|
function NotFound({ uniprotId }) {
|
|
7
7
|
return (React.createElement(Typography, null,
|
|
8
8
|
"No structure found for this UniProtID in AlphaFoldDB",
|
|
@@ -10,7 +10,6 @@ function NotFound({ uniprotId }) {
|
|
|
10
10
|
React.createElement(ExternalLink, { href: `https://alphafold.ebi.ac.uk/search/text/${uniprotId}` }, "(search for results)")));
|
|
11
11
|
}
|
|
12
12
|
export default function AlphaFoldDBSearchStatus({ uniprotId, selectedTranscript, structureSequence, isoformSequences, url, }) {
|
|
13
|
-
const [showAllProteinSequences, setShowAllProteinSequences] = useState(false);
|
|
14
13
|
return uniprotId ? (React.createElement(React.Fragment, null,
|
|
15
14
|
React.createElement("div", null,
|
|
16
15
|
React.createElement(Typography, null,
|
|
@@ -20,16 +19,12 @@ export default function AlphaFoldDBSearchStatus({ uniprotId, selectedTranscript,
|
|
|
20
19
|
React.createElement(Typography, null,
|
|
21
20
|
"AlphaFoldDB link: ",
|
|
22
21
|
React.createElement(ExternalLink, { href: url }, url))),
|
|
23
|
-
structureSequence ? (React.createElement(
|
|
24
|
-
React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
|
|
25
|
-
setShowAllProteinSequences(!showAllProteinSequences);
|
|
26
|
-
} }, showAllProteinSequences
|
|
27
|
-
? 'Hide all isoform protein sequences'
|
|
28
|
-
: 'Show all isoform protein sequences'),
|
|
29
|
-
showAllProteinSequences ? (React.createElement(MSATable, { structureSequence: structureSequence, structureName: uniprotId, isoformSequences: isoformSequences })) : null)) : (React.createElement(NotFound, { uniprotId: uniprotId })))) : (React.createElement(Typography, null,
|
|
22
|
+
structureSequence ? (React.createElement(IsoformSequencesToggle, { structureSequence: structureSequence, structureName: uniprotId, isoformSequences: isoformSequences })) : (React.createElement(NotFound, { uniprotId: uniprotId })))) : (React.createElement(Typography, null,
|
|
30
23
|
"Searching",
|
|
31
24
|
' ',
|
|
32
|
-
selectedTranscript
|
|
25
|
+
selectedTranscript
|
|
26
|
+
? getTranscriptDisplayName(selectedTranscript)
|
|
27
|
+
: 'transcript',
|
|
33
28
|
' ',
|
|
34
29
|
"for UniProt ID"));
|
|
35
30
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
3
|
-
|
|
2
|
+
import type { AbstractSessionModel, Feature } from '@jbrowse/core/util';
|
|
3
|
+
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
4
|
+
declare const FoldseekSearch: ({ feature, session, view, handleClose, }: {
|
|
4
5
|
feature: Feature;
|
|
5
|
-
|
|
6
|
+
session: AbstractSessionModel;
|
|
7
|
+
view: LinearGenomeViewModel;
|
|
6
8
|
handleClose: () => void;
|
|
7
9
|
}) => React.JSX.Element;
|
|
8
10
|
export default FoldseekSearch;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
3
|
-
import { getContainingView, getSession } from '@jbrowse/core/util';
|
|
4
3
|
import { Button, DialogActions, DialogContent, TextField, Typography, } from '@mui/material';
|
|
5
4
|
import { observer } from 'mobx-react';
|
|
6
5
|
import { makeStyles } from 'tss-react/mui';
|
|
@@ -8,10 +7,9 @@ import FoldseekDatabaseSelector from './FoldseekDatabaseSelector';
|
|
|
8
7
|
import FoldseekResultsTable from './FoldseekResultsTable';
|
|
9
8
|
import TranscriptSelector from './TranscriptSelector';
|
|
10
9
|
import useFoldseekSearch from '../hooks/useFoldseekSearch';
|
|
11
|
-
import
|
|
12
|
-
import useTranscriptSelection from '../hooks/useTranscriptSelection';
|
|
10
|
+
import useTranscriptIsoformSelection from '../hooks/useTranscriptIsoformSelection';
|
|
13
11
|
import { DEFAULT_DATABASES } from '../services/foldseekApi';
|
|
14
|
-
import {
|
|
12
|
+
import { stripStopCodon } from '../utils/util';
|
|
15
13
|
const useStyles = makeStyles()({
|
|
16
14
|
dialogContent: {
|
|
17
15
|
width: '80em',
|
|
@@ -28,21 +26,15 @@ const useStyles = makeStyles()({
|
|
|
28
26
|
gap: 8,
|
|
29
27
|
},
|
|
30
28
|
});
|
|
31
|
-
const FoldseekSearch = observer(function FoldseekSearch({ feature,
|
|
29
|
+
const FoldseekSearch = observer(function FoldseekSearch({ feature, session, view, handleClose, }) {
|
|
32
30
|
const { classes } = useStyles();
|
|
33
|
-
const session = getSession(model);
|
|
34
|
-
const view = getContainingView(model);
|
|
35
31
|
const [userEditedSequence, setUserEditedSequence] = useState();
|
|
36
32
|
const [selectedDatabases, setSelectedDatabases] = useState(DEFAULT_DATABASES);
|
|
37
33
|
const { results, cleanedAaSequence, di3Sequence, isLoading, isPredicting, error, statusMessage, predictStructure, search, reset, } = useFoldseekSearch();
|
|
38
|
-
const transcripts =
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const selectedIsoformData = effectiveSelectedTranscriptId
|
|
43
|
-
? isoformSequences?.[effectiveSelectedTranscriptId]
|
|
44
|
-
: undefined;
|
|
45
|
-
const cleanedSequence = selectedIsoformData?.seq.replace(/\*/g, '') ?? '';
|
|
34
|
+
const { transcripts, isoformSequences, isLoading: isLoadingIsoforms, error: isoformError, selectedTranscriptId: effectiveSelectedTranscriptId, setSelectedTranscriptId: setUserSelection, selectedTranscript, selectedIsoform: selectedIsoformData, } = useTranscriptIsoformSelection({ feature, view });
|
|
35
|
+
const cleanedSequence = selectedIsoformData
|
|
36
|
+
? stripStopCodon(selectedIsoformData.seq)
|
|
37
|
+
: '';
|
|
46
38
|
const sequence = userEditedSequence ?? cleanedSequence;
|
|
47
39
|
const setUserSelectionWithReset = (id) => {
|
|
48
40
|
setUserSelection(id);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Feature } from '@jbrowse/core/util';
|
|
3
|
+
export default function IsoformSequencesToggle({ structureSequence, structureName, isoformSequences, }: {
|
|
4
|
+
structureSequence: string;
|
|
5
|
+
structureName: string;
|
|
6
|
+
isoformSequences: Record<string, {
|
|
7
|
+
feature: Feature;
|
|
8
|
+
seq: string;
|
|
9
|
+
}>;
|
|
10
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Button } from '@mui/material';
|
|
3
|
+
import MSATable from './MSATable';
|
|
4
|
+
export default function IsoformSequencesToggle({ structureSequence, structureName, isoformSequences, }) {
|
|
5
|
+
const [show, setShow] = useState(false);
|
|
6
|
+
return (React.createElement("div", { style: { margin: 10 } },
|
|
7
|
+
React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
|
|
8
|
+
setShow(!show);
|
|
9
|
+
} }, show
|
|
10
|
+
? 'Hide all isoform protein sequences'
|
|
11
|
+
: 'Show all isoform protein sequences'),
|
|
12
|
+
show ? (React.createElement(MSATable, { structureSequence: structureSequence, structureName: structureName, isoformSequences: isoformSequences })) : null));
|
|
13
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { Dialog } from '@jbrowse/core/ui';
|
|
3
|
+
import { getContainingView, getSession } from '@jbrowse/core/util';
|
|
3
4
|
import { Tab, Tabs } from '@mui/material';
|
|
4
5
|
import AlphaFoldDBSearch from './AlphaFoldDBSearch';
|
|
5
6
|
import FoldseekSearch from './FoldseekSearch';
|
|
@@ -11,6 +12,8 @@ import { useLocalStorage } from '../hooks/useLocalStorage';
|
|
|
11
12
|
export default function LaunchProteinViewDialog({ handleClose, feature, model, }) {
|
|
12
13
|
const [choice, setChoice] = useState(0);
|
|
13
14
|
const [alignmentAlgorithm, setAlignmentAlgorithm] = useLocalStorage('jbrowse-protein3d-alignment-algorithm', DEFAULT_ALIGNMENT_ALGORITHM);
|
|
15
|
+
const session = getSession(model);
|
|
16
|
+
const view = getContainingView(model);
|
|
14
17
|
return (React.createElement(Dialog, { maxWidth: "xl", title: "Launch protein view", titleNode: React.createElement(React.Fragment, null,
|
|
15
18
|
"Launch protein view ",
|
|
16
19
|
React.createElement(HelpButton, null)), open: true, onClose: handleClose },
|
|
@@ -21,9 +24,9 @@ export default function LaunchProteinViewDialog({ handleClose, feature, model, }
|
|
|
21
24
|
React.createElement(Tab, { value: 1, label: "Foldseek search" }),
|
|
22
25
|
React.createElement(Tab, { value: 2, label: "Open file manually" })),
|
|
23
26
|
React.createElement(TabPanel, { value: choice, index: 0 },
|
|
24
|
-
React.createElement(AlphaFoldDBSearch, {
|
|
27
|
+
React.createElement(AlphaFoldDBSearch, { session: session, view: view, feature: feature, handleClose: handleClose, alignmentAlgorithm: alignmentAlgorithm, onAlignmentAlgorithmChange: setAlignmentAlgorithm })),
|
|
25
28
|
React.createElement(TabPanel, { value: choice, index: 1 },
|
|
26
|
-
React.createElement(FoldseekSearch, {
|
|
29
|
+
React.createElement(FoldseekSearch, { session: session, view: view, feature: feature, handleClose: handleClose })),
|
|
27
30
|
React.createElement(TabPanel, { value: choice, index: 2 },
|
|
28
|
-
React.createElement(UserProvidedStructure, {
|
|
31
|
+
React.createElement(UserProvidedStructure, { session: session, view: view, feature: feature, handleClose: handleClose, alignmentAlgorithm: alignmentAlgorithm, onAlignmentAlgorithmChange: setAlignmentAlgorithm }))));
|
|
29
32
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
export default function StructureSourcePicker({ choice, setChoice, structureURL, setStructureURL,
|
|
2
|
+
export default function StructureSourcePicker({ choice, setChoice, structureURL, setStructureURL, setFile, pdbId, setPdbId, }: {
|
|
3
3
|
choice: string;
|
|
4
4
|
setChoice: (c: string) => void;
|
|
5
5
|
structureURL: string;
|
|
6
6
|
setStructureURL: (url: string) => void;
|
|
7
|
-
file: File | undefined;
|
|
8
7
|
setFile: (f: File) => void;
|
|
9
8
|
pdbId: string;
|
|
10
9
|
setPdbId: (id: string) => void;
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { Button, FormControl, FormControlLabel, Radio, RadioGroup, TextField, Typography, } from '@mui/material';
|
|
3
3
|
import HelpButton from './HelpButton';
|
|
4
4
|
import { getPdbStructureUrl } from '../utils/launchViewUtils';
|
|
5
|
-
export default function StructureSourcePicker({ choice, setChoice, structureURL, setStructureURL,
|
|
5
|
+
export default function StructureSourcePicker({ choice, setChoice, structureURL, setStructureURL, setFile, pdbId, setPdbId, }) {
|
|
6
6
|
return (React.createElement("div", { style: { display: 'flex', margin: 30 } },
|
|
7
7
|
React.createElement(Typography, null,
|
|
8
8
|
"Open your structure file ",
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { AlignmentAlgorithm } from '../../ProteinView/types';
|
|
3
|
-
import type {
|
|
4
|
-
|
|
3
|
+
import type { AbstractSessionModel, Feature } from '@jbrowse/core/util';
|
|
4
|
+
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
5
|
+
type LGV = LinearGenomeViewModel;
|
|
6
|
+
declare const UserProvidedStructure: ({ feature, session, view, handleClose, alignmentAlgorithm, onAlignmentAlgorithmChange, }: {
|
|
5
7
|
feature: Feature;
|
|
6
|
-
|
|
8
|
+
session: AbstractSessionModel;
|
|
9
|
+
view: LGV;
|
|
7
10
|
handleClose: () => void;
|
|
8
11
|
alignmentAlgorithm: AlignmentAlgorithm;
|
|
9
12
|
onAlignmentAlgorithmChange: (algorithm: AlignmentAlgorithm) => void;
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
3
|
-
import { getContainingView, getSession } from '@jbrowse/core/util';
|
|
4
3
|
import { Button, DialogActions, DialogContent } from '@mui/material';
|
|
5
4
|
import { observer } from 'mobx-react';
|
|
6
5
|
import { makeStyles } from 'tss-react/mui';
|
|
7
|
-
import
|
|
6
|
+
import IsoformSequencesToggle from './IsoformSequencesToggle';
|
|
8
7
|
import SequenceMismatchNotice from './SequenceMismatchNotice';
|
|
9
8
|
import StructureSourcePicker from './StructureSourcePicker';
|
|
10
9
|
import TranscriptSelector from './TranscriptSelector';
|
|
11
10
|
import ExternalLink from '../../components/ExternalLink';
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import useRemoteStructureFileSequence from '../hooks/useRemoteStructureFileSequence';
|
|
15
|
-
import useTranscriptSelection from '../hooks/useTranscriptSelection';
|
|
11
|
+
import useStructureFileSequence from '../hooks/useStructureFileSequence';
|
|
12
|
+
import useTranscriptIsoformSelection from '../hooks/useTranscriptIsoformSelection';
|
|
16
13
|
import { launch3DProteinView } from '../utils/launchViewUtils';
|
|
17
|
-
import { getGeneDisplayName,
|
|
14
|
+
import { getGeneDisplayName, getTranscriptDisplayName, stripStopCodon, } from '../utils/util';
|
|
18
15
|
const useStyles = makeStyles()(theme => ({
|
|
19
16
|
dialogContent: {
|
|
20
17
|
marginTop: theme.spacing(6),
|
|
@@ -31,36 +28,20 @@ function HelpText() {
|
|
|
31
28
|
React.createElement(ExternalLink, { href: "https://github.com/sokrypton/ColabFold" }, "ColabFold"),
|
|
32
29
|
". This plugin will align the protein sequence calculated from the genome to the protein sequence embedded in the structure file which allows for slight differences in these two representations."));
|
|
33
30
|
}
|
|
34
|
-
const UserProvidedStructure = observer(function UserProvidedStructure({ feature,
|
|
31
|
+
const UserProvidedStructure = observer(function UserProvidedStructure({ feature, session, view, handleClose, alignmentAlgorithm, onAlignmentAlgorithmChange, }) {
|
|
35
32
|
const { classes } = useStyles();
|
|
36
|
-
const session = getSession(model);
|
|
37
33
|
const [file, setFile] = useState();
|
|
38
34
|
const [pdbId, setPdbId] = useState('');
|
|
39
35
|
const [choice, setChoice] = useState('file');
|
|
40
36
|
const [submitError, setSubmitError] = useState();
|
|
41
37
|
const [structureURL, setStructureURL] = useState('');
|
|
42
|
-
const [showAllProteinSequences, setShowAllProteinSequences] = useState(false);
|
|
43
38
|
const activeFile = choice === 'file' ? file : undefined;
|
|
44
39
|
const activeURL = choice === 'file' ? '' : structureURL;
|
|
45
|
-
const
|
|
46
|
-
const view = getContainingView(model);
|
|
47
|
-
const { isoformSequences, error: isoformError } = useIsoformProteinSequences({
|
|
48
|
-
feature,
|
|
49
|
-
view,
|
|
50
|
-
});
|
|
51
|
-
const { sequences: localSequences, error: localFileError } = useLocalStructureFileSequence({ file: activeFile });
|
|
52
|
-
const { sequences: remoteSequences, error: remoteFileError } = useRemoteStructureFileSequence({ url: activeURL });
|
|
40
|
+
const { sequences: structureSequences, error: fileError } = useStructureFileSequence({ file: activeFile, url: activeURL });
|
|
53
41
|
const structureName = activeFile?.name ?? activeURL.slice(activeURL.lastIndexOf('/') + 1);
|
|
54
|
-
const structureSequences = activeFile ? localSequences : remoteSequences;
|
|
55
42
|
const structureSequence = structureSequences?.[0];
|
|
56
|
-
const { userSelection, setUserSelection } =
|
|
57
|
-
|
|
58
|
-
isoformSequences,
|
|
59
|
-
structureSequence,
|
|
60
|
-
});
|
|
61
|
-
const selectedTranscript = options.find(val => getId(val) === userSelection);
|
|
62
|
-
const protein = userSelection ? isoformSequences?.[userSelection] : undefined;
|
|
63
|
-
const error = isoformError ?? submitError ?? localFileError ?? remoteFileError;
|
|
43
|
+
const { transcripts: options, isoformSequences, selectedTranscriptId: userSelection, setSelectedTranscriptId: setUserSelection, selectedTranscript, selectedIsoform: protein, error: isoformError, } = useTranscriptIsoformSelection({ feature, view, structureSequence });
|
|
44
|
+
const error = isoformError ?? submitError ?? fileError;
|
|
64
45
|
const canLaunch = !!(activeURL || activeFile) && !!protein && !!selectedTranscript;
|
|
65
46
|
const sequencesDiffer = !!protein?.seq &&
|
|
66
47
|
!!structureSequence &&
|
|
@@ -94,16 +75,10 @@ const UserProvidedStructure = observer(function UserProvidedStructure({ feature,
|
|
|
94
75
|
React.createElement(DialogContent, { className: classes.dialogContent },
|
|
95
76
|
error ? React.createElement(ErrorMessage, { error: error }) : null,
|
|
96
77
|
React.createElement(HelpText, null),
|
|
97
|
-
React.createElement(StructureSourcePicker, { choice: choice, setChoice: setChoice, structureURL: structureURL, setStructureURL: setStructureURL,
|
|
78
|
+
React.createElement(StructureSourcePicker, { choice: choice, setChoice: setChoice, structureURL: structureURL, setStructureURL: setStructureURL, setFile: setFile, pdbId: pdbId, setPdbId: setPdbId }),
|
|
98
79
|
React.createElement("div", { style: { margin: 20 } }, isoformSequences ? (structureSequence ? (React.createElement(React.Fragment, null,
|
|
99
80
|
React.createElement(TranscriptSelector, { val: userSelection, setVal: setUserSelection, structureSequence: structureSequence, isoforms: options, feature: feature, isoformSequences: isoformSequences }),
|
|
100
|
-
React.createElement(
|
|
101
|
-
React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
|
|
102
|
-
setShowAllProteinSequences(!showAllProteinSequences);
|
|
103
|
-
} }, showAllProteinSequences
|
|
104
|
-
? 'Hide all isoform protein sequences'
|
|
105
|
-
: 'Show all isoform protein sequences'),
|
|
106
|
-
showAllProteinSequences ? (React.createElement(MSATable, { structureSequence: structureSequence, structureName: structureName, isoformSequences: isoformSequences })) : null))) : null) : (React.createElement(LoadingEllipses, { title: "Loading protein sequences", variant: "h6" })))),
|
|
81
|
+
React.createElement(IsoformSequencesToggle, { structureSequence: structureSequence, structureName: structureName, isoformSequences: isoformSequences }))) : null) : (React.createElement(LoadingEllipses, { title: "Loading protein sequences", variant: "h6" })))),
|
|
107
82
|
React.createElement(DialogActions, null,
|
|
108
83
|
sequencesDiffer ? (React.createElement(SequenceMismatchNotice, { alignmentAlgorithm: alignmentAlgorithm, onAlignmentAlgorithmChange: onAlignmentAlgorithmChange })) : null,
|
|
109
84
|
React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Shared SWR config for one-shot fetches that should never auto-revalidate
|
|
2
|
+
// (structure files, computed protein sequences). keepPreviousData is opt-in
|
|
3
|
+
// per-hook since it avoids result flicker when the key changes.
|
|
4
|
+
export const STATIC_SWR_OPTIONS = {
|
|
5
|
+
revalidateOnFocus: false,
|
|
6
|
+
revalidateOnReconnect: false,
|
|
7
|
+
revalidateIfStale: false,
|
|
8
|
+
};
|
|
@@ -2,11 +2,10 @@ import { useState } from 'react';
|
|
|
2
2
|
import useAlphaFoldData from './useAlphaFoldData';
|
|
3
3
|
import useAlphaFoldSequenceSearch from './useAlphaFoldSequenceSearch';
|
|
4
4
|
import useDebouncedValue from './useDebouncedValue';
|
|
5
|
-
import
|
|
6
|
-
import useTranscriptSelection from './useTranscriptSelection';
|
|
5
|
+
import useTranscriptIsoformSelection from './useTranscriptIsoformSelection';
|
|
7
6
|
import useUniProtSearch from './useUniProtSearch';
|
|
8
7
|
import getSearchDescription from '../utils/getSearchDescription';
|
|
9
|
-
import { extractFeatureIdentifiers,
|
|
8
|
+
import { extractFeatureIdentifiers, stripStopCodon } from '../utils/util';
|
|
10
9
|
export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
11
10
|
const [lookupMode, setLookupMode] = useState('auto');
|
|
12
11
|
const [manualUniprotId, setManualUniprotId] = useState('');
|
|
@@ -14,12 +13,10 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
14
13
|
const [selectedQueryId, setSelectedQueryId] = useState('auto');
|
|
15
14
|
const [sequenceSearchType, setSequenceSearchType] = useState('md5');
|
|
16
15
|
const [selectedUniprotId, setSelectedUniprotId] = useState();
|
|
17
|
-
const transcriptOptions = getTranscriptFeatures(feature);
|
|
18
16
|
const featureUniprotId = geneIds.uniprotId;
|
|
19
17
|
const effectiveLookupMode = lookupMode === 'auto' && featureUniprotId ? 'feature' : lookupMode;
|
|
20
18
|
const isSequenceMode = effectiveLookupMode === 'sequence';
|
|
21
19
|
const isAutoMode = effectiveLookupMode === 'auto';
|
|
22
|
-
const { isoformSequences, isLoading: isIsoformLoading, error: isoformError, } = useIsoformProteinSequences({ feature, view });
|
|
23
20
|
const { entries: uniprotEntries, isLoading: isLookupLoading, error: lookupError, } = useUniProtSearch({
|
|
24
21
|
recognizedIds: geneIds.recognizedIds,
|
|
25
22
|
geneId: geneIds.geneId,
|
|
@@ -38,20 +35,16 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
38
35
|
: effectiveLookupMode === 'manual'
|
|
39
36
|
? debouncedManualUniprotId
|
|
40
37
|
: undefined;
|
|
41
|
-
const { isLoading: isAlphaFoldLoading, error: alphaFoldError, url: alphaFoldUrl, confidenceUrl: alphaFoldConfidenceUrl, structureSequence: alphaFoldStructureSequence, } = useAlphaFoldData({
|
|
38
|
+
const { isLoading: isAlphaFoldLoading, isValidating: isAlphaFoldValidating, error: alphaFoldError, url: alphaFoldUrl, confidenceUrl: alphaFoldConfidenceUrl, structureSequence: alphaFoldStructureSequence, } = useAlphaFoldData({
|
|
42
39
|
uniprotId: isSequenceMode ? undefined : uniprotId,
|
|
43
40
|
});
|
|
44
|
-
const {
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
const { transcripts: transcriptOptions, isoformSequences, isLoading: isIsoformLoading, error: isoformError, selectedTranscriptId: effectiveTranscriptId, setSelectedTranscriptId: setUserSelection, selectedTranscript, selectedIsoform: userSelectedProteinSequence, } = useTranscriptIsoformSelection({
|
|
42
|
+
feature,
|
|
43
|
+
view,
|
|
47
44
|
structureSequence: alphaFoldStructureSequence,
|
|
48
45
|
resetKey: uniprotId,
|
|
49
46
|
});
|
|
50
|
-
const
|
|
51
|
-
const userSelectedProteinSequence = effectiveTranscriptId
|
|
52
|
-
? isoformSequences?.[effectiveTranscriptId]
|
|
53
|
-
: undefined;
|
|
54
|
-
const { uniprotId: seqSearchUniprotId, cifUrl: seqSearchUrl, plddtDocUrl: seqSearchConfidenceUrl, structureSequence: seqSearchStructureSequence, isLoading: isSequenceSearchLoading, error: sequenceSearchError, } = useAlphaFoldSequenceSearch({
|
|
47
|
+
const { uniprotId: seqSearchUniprotId, cifUrl: seqSearchUrl, plddtDocUrl: seqSearchConfidenceUrl, structureSequence: seqSearchStructureSequence, isLoading: isSequenceSearchLoading, isValidating: isSequenceSearchValidating, error: sequenceSearchError, } = useAlphaFoldSequenceSearch({
|
|
55
48
|
sequence: userSelectedProteinSequence?.seq,
|
|
56
49
|
searchType: sequenceSearchType,
|
|
57
50
|
enabled: isSequenceMode,
|
|
@@ -65,6 +58,13 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
65
58
|
? seqSearchStructureSequence
|
|
66
59
|
: alphaFoldStructureSequence;
|
|
67
60
|
const finalUniprotId = isSequenceMode ? seqSearchUniprotId : uniprotId;
|
|
61
|
+
// While a structure fetch is in flight, finalStructureSequence may still be
|
|
62
|
+
// the previous selection's sequence (keepPreviousData). Comparing that stale
|
|
63
|
+
// sequence to the freshly-selected transcript would give a wrong match, so
|
|
64
|
+
// the match is treated as unknown until the fetch settles.
|
|
65
|
+
const isStructureValidating = isSequenceMode
|
|
66
|
+
? isSequenceSearchValidating
|
|
67
|
+
: isAlphaFoldValidating;
|
|
68
68
|
const loadingStatuses = [
|
|
69
69
|
isLookupLoading && 'Looking up UniProt ID',
|
|
70
70
|
isIsoformLoading && 'Loading protein sequences from transcript isoforms',
|
|
@@ -111,7 +111,9 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
111
111
|
showStructureSelectors: !!isoformSequences &&
|
|
112
112
|
!!selectedTranscript &&
|
|
113
113
|
(isSequenceMode || !!(finalStructureSequence && finalUniprotId)),
|
|
114
|
-
sequencesMatch:
|
|
114
|
+
sequencesMatch: !isStructureValidating &&
|
|
115
|
+
userSelectedProteinSequence?.seq &&
|
|
116
|
+
finalStructureSequence
|
|
115
117
|
? stripStopCodon(userSelectedProteinSequence.seq) ===
|
|
116
118
|
finalStructureSequence
|
|
117
119
|
: undefined,
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import useStructureFileSequence from './useStructureFileSequence';
|
|
2
2
|
import { getAlphaFoldConfidenceUrl, getAlphaFoldStructureUrl, } from '../utils/launchViewUtils';
|
|
3
3
|
export default function useAlphaFoldData({ uniprotId, }) {
|
|
4
4
|
const url = uniprotId ? getAlphaFoldStructureUrl(uniprotId) : undefined;
|
|
5
5
|
const confidenceUrl = uniprotId
|
|
6
6
|
? getAlphaFoldConfidenceUrl(uniprotId)
|
|
7
7
|
: undefined;
|
|
8
|
-
const { sequences, isLoading, error } =
|
|
9
|
-
url,
|
|
10
|
-
});
|
|
8
|
+
const { sequences, isLoading, isValidating, error } = useStructureFileSequence({ url });
|
|
11
9
|
return {
|
|
12
10
|
isLoading,
|
|
11
|
+
isValidating,
|
|
13
12
|
error,
|
|
14
13
|
url,
|
|
15
14
|
confidenceUrl,
|
|
@@ -19,6 +19,7 @@ export default function useAlphaFoldSequenceSearch({ sequence, searchType, enabl
|
|
|
19
19
|
enabled?: boolean;
|
|
20
20
|
}): {
|
|
21
21
|
isLoading: boolean;
|
|
22
|
+
isValidating: boolean;
|
|
22
23
|
result: SequenceSummaryResponse | undefined;
|
|
23
24
|
uniprotId: string | undefined;
|
|
24
25
|
cifUrl: string | undefined;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import useSWR from 'swr';
|
|
3
|
+
import { STATIC_SWR_OPTIONS } from './swrOptions';
|
|
3
4
|
import { jsonfetch } from '../../fetchUtils';
|
|
4
5
|
import { md5 } from '../utils/md5';
|
|
5
6
|
import { stripStopCodon } from '../utils/util';
|
|
@@ -11,16 +12,15 @@ export default function useAlphaFoldSequenceSearch({ sequence, searchType, enabl
|
|
|
11
12
|
const cleanSeq = stripStopCodon(sequence.toUpperCase());
|
|
12
13
|
return searchType === 'md5' ? md5(cleanSeq) : cleanSeq;
|
|
13
14
|
}, [sequence, searchType]);
|
|
14
|
-
const { data, error, isLoading } = useSWR(enabled && searchValue
|
|
15
|
+
const { data, error, isLoading, isValidating } = useSWR(enabled && searchValue
|
|
15
16
|
? `https://alphafold.ebi.ac.uk/api/sequence/summary?id=${encodeURIComponent(searchValue)}&type=${searchType}`
|
|
16
17
|
: null, jsonfetch, {
|
|
17
|
-
|
|
18
|
-
revalidateOnReconnect: false,
|
|
19
|
-
revalidateIfStale: false,
|
|
18
|
+
...STATIC_SWR_OPTIONS,
|
|
20
19
|
keepPreviousData: true,
|
|
21
20
|
});
|
|
22
21
|
return {
|
|
23
22
|
isLoading,
|
|
23
|
+
isValidating,
|
|
24
24
|
result: data,
|
|
25
25
|
uniprotId: data?.uniprotAccession,
|
|
26
26
|
cifUrl: data?.cifUrl,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { DEFAULT_DATABASES, predict3Di, submitFoldseekSearch, waitForFoldseekResults, } from '../services/foldseekApi';
|
|
3
3
|
export default function useFoldseekSearch() {
|
|
4
4
|
const [results, setResults] = useState();
|
|
@@ -7,46 +7,81 @@ export default function useFoldseekSearch() {
|
|
|
7
7
|
const [isPredicting, setIsPredicting] = useState(false);
|
|
8
8
|
const [error, setError] = useState();
|
|
9
9
|
const [statusMessage, setStatusMessage] = useState('');
|
|
10
|
+
// Aborts the in-flight request (3Di prediction or the up-to-3-minute Foldseek
|
|
11
|
+
// poll) when the dialog closes/unmounts, so it stops hitting the external API
|
|
12
|
+
// and stops updating dead state.
|
|
13
|
+
const abortRef = useRef(null);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
return () => {
|
|
16
|
+
abortRef.current?.abort();
|
|
17
|
+
};
|
|
18
|
+
}, []);
|
|
19
|
+
const startOperation = () => {
|
|
20
|
+
abortRef.current?.abort();
|
|
21
|
+
const controller = new AbortController();
|
|
22
|
+
abortRef.current = controller;
|
|
23
|
+
return controller.signal;
|
|
24
|
+
};
|
|
10
25
|
const predictStructure = async (aaSequence) => {
|
|
26
|
+
const signal = startOperation();
|
|
11
27
|
setIsPredicting(true);
|
|
12
28
|
setError(undefined);
|
|
13
29
|
setStatusMessage('Predicting 3Di structure...');
|
|
14
30
|
try {
|
|
15
|
-
const result = await predict3Di(aaSequence);
|
|
31
|
+
const result = await predict3Di({ aaSequence, signal });
|
|
16
32
|
setPredictData(result);
|
|
17
33
|
return result;
|
|
18
34
|
}
|
|
19
35
|
catch (e) {
|
|
20
|
-
|
|
21
|
-
|
|
36
|
+
if (!signal.aborted) {
|
|
37
|
+
console.error(e);
|
|
38
|
+
setError(e);
|
|
39
|
+
}
|
|
22
40
|
return undefined;
|
|
23
41
|
}
|
|
24
42
|
finally {
|
|
25
|
-
|
|
26
|
-
|
|
43
|
+
if (!signal.aborted) {
|
|
44
|
+
setIsPredicting(false);
|
|
45
|
+
setStatusMessage('');
|
|
46
|
+
}
|
|
27
47
|
}
|
|
28
48
|
};
|
|
29
49
|
const search = async (aaSeq, di3Seq, databases = DEFAULT_DATABASES) => {
|
|
50
|
+
const signal = startOperation();
|
|
30
51
|
setIsLoading(true);
|
|
31
52
|
setError(undefined);
|
|
32
53
|
setStatusMessage('Submitting search...');
|
|
33
54
|
try {
|
|
34
|
-
const ticket = await submitFoldseekSearch(
|
|
35
|
-
|
|
55
|
+
const ticket = await submitFoldseekSearch({
|
|
56
|
+
aaSequence: aaSeq,
|
|
57
|
+
di3Sequence: di3Seq,
|
|
58
|
+
databases,
|
|
59
|
+
signal,
|
|
60
|
+
});
|
|
61
|
+
const result = await waitForFoldseekResults({
|
|
62
|
+
ticketId: ticket.id,
|
|
63
|
+
onStatusChange: setStatusMessage,
|
|
64
|
+
signal,
|
|
65
|
+
});
|
|
36
66
|
setResults(result);
|
|
37
67
|
return result;
|
|
38
68
|
}
|
|
39
69
|
catch (e) {
|
|
40
|
-
|
|
41
|
-
|
|
70
|
+
if (!signal.aborted) {
|
|
71
|
+
console.error(e);
|
|
72
|
+
setError(e);
|
|
73
|
+
}
|
|
42
74
|
return undefined;
|
|
43
75
|
}
|
|
44
76
|
finally {
|
|
45
|
-
|
|
46
|
-
|
|
77
|
+
if (!signal.aborted) {
|
|
78
|
+
setIsLoading(false);
|
|
79
|
+
setStatusMessage('');
|
|
80
|
+
}
|
|
47
81
|
}
|
|
48
82
|
};
|
|
49
83
|
const reset = () => {
|
|
84
|
+
abortRef.current?.abort();
|
|
50
85
|
setResults(undefined);
|
|
51
86
|
setPredictData(undefined);
|
|
52
87
|
setError(undefined);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { getSession } from '@jbrowse/core/util';
|
|
1
2
|
import useSWR from 'swr';
|
|
3
|
+
import { STATIC_SWR_OPTIONS } from './swrOptions';
|
|
2
4
|
import { fetchProteinSeq } from '../utils/calculateProteinSequence';
|
|
3
5
|
import { getTranscriptFeatures } from '../utils/util';
|
|
4
6
|
export default function useIsoformProteinSequences({ feature, view, }) {
|
|
@@ -7,7 +9,11 @@ export default function useIsoformProteinSequences({ feature, view, }) {
|
|
|
7
9
|
const errors = [];
|
|
8
10
|
const results = await Promise.all(transcripts.map(async (f) => {
|
|
9
11
|
try {
|
|
10
|
-
const seq = await fetchProteinSeq({
|
|
12
|
+
const seq = await fetchProteinSeq({
|
|
13
|
+
session: getSession(view),
|
|
14
|
+
assemblyName: view?.assemblyNames?.[0],
|
|
15
|
+
feature: f,
|
|
16
|
+
});
|
|
11
17
|
return seq ? [f.id(), { feature: f, seq }] : undefined;
|
|
12
18
|
}
|
|
13
19
|
catch (e) {
|
|
@@ -27,9 +33,7 @@ export default function useIsoformProteinSequences({ feature, view, }) {
|
|
|
27
33
|
}
|
|
28
34
|
return Object.fromEntries(entries);
|
|
29
35
|
}, {
|
|
30
|
-
|
|
31
|
-
revalidateOnReconnect: false,
|
|
32
|
-
revalidateIfStale: false,
|
|
36
|
+
...STATIC_SWR_OPTIONS,
|
|
33
37
|
keepPreviousData: true,
|
|
34
38
|
});
|
|
35
39
|
return { isLoading, isoformSequences: data, error };
|