jbrowse-plugin-msaview 3.3.0 → 3.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.
- package/dist/AddHighlightModel/GenomeMouseoverHighlight.js +1 -1
- package/dist/AddHighlightModel/MsaToGenomeHighlight.js +1 -1
- package/dist/AddHighlightModel/index.js +1 -1
- package/dist/LaunchMsaView/components/BlastQuery/BlastAutomaticPanel.js +60 -18
- package/dist/LaunchMsaView/components/BlastQuery/BlastManualPanel.js +1 -1
- package/dist/LaunchMsaView/components/BlastQuery/BlastPanel.js +2 -2
- package/dist/LaunchMsaView/components/BlastQuery/CachedBlastResults.d.ts +12 -0
- package/dist/LaunchMsaView/components/BlastQuery/CachedBlastResults.js +21 -2
- package/dist/LaunchMsaView/components/BlastQuery/CachedBlastResults.test.d.ts +1 -0
- package/dist/LaunchMsaView/components/BlastQuery/CachedBlastResults.test.js +29 -0
- package/dist/LaunchMsaView/components/BlastQuery/MsaAlgorithmSelect.js +1 -1
- package/dist/LaunchMsaView/components/BlastQuery/consts.d.ts +28 -0
- package/dist/LaunchMsaView/components/BlastQuery/consts.js +21 -0
- package/dist/LaunchMsaView/components/BlastQuery/searchChoiceStorage.d.ts +7 -0
- package/dist/LaunchMsaView/components/BlastQuery/searchChoiceStorage.js +42 -0
- package/dist/LaunchMsaView/components/BlastQuery/searchChoiceStorage.test.d.ts +1 -0
- package/dist/LaunchMsaView/components/BlastQuery/searchChoiceStorage.test.js +32 -0
- package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js +1 -1
- package/dist/LaunchMsaView/components/OrthologQuery/OrthologPanel.js +5 -4
- package/dist/LaunchMsaView/components/SubmitCancelActions.test.js +1 -1
- package/dist/LaunchMsaView/components/useFeatureSequence.js +1 -1
- package/dist/LaunchMsaView/detectQueryRow.d.ts +15 -2
- package/dist/LaunchMsaView/detectQueryRow.js +20 -21
- package/dist/LaunchMsaView/detectQueryRow.test.js +15 -15
- package/dist/LaunchMsaView/useQueryRowName.js +5 -8
- package/dist/LaunchMsaViewExtensionPoint/index.js +11 -6
- package/dist/LaunchMsaViewExtensionPoint/index.test.d.ts +1 -0
- package/dist/LaunchMsaViewExtensionPoint/index.test.js +43 -0
- package/dist/MsaViewPanel/afterCreateAutoruns.d.ts +15 -0
- package/dist/MsaViewPanel/afterCreateAutoruns.js +95 -72
- package/dist/MsaViewPanel/components/ErrorBoundary.d.ts +2 -2
- package/dist/MsaViewPanel/components/JobLink.js +7 -1
- package/dist/MsaViewPanel/components/LaunchProgress.d.ts +17 -0
- package/dist/MsaViewPanel/components/LaunchProgress.js +50 -0
- package/dist/MsaViewPanel/components/MsaViewPanel.js +6 -3
- package/dist/MsaViewPanel/components/MsaViewPanel.test.d.ts +1 -0
- package/dist/MsaViewPanel/components/MsaViewPanel.test.js +87 -0
- package/dist/MsaViewPanel/doLaunchBlast.d.ts +4 -2
- package/dist/MsaViewPanel/doLaunchBlast.js +86 -56
- package/dist/MsaViewPanel/doLaunchOrthologs.d.ts +3 -1
- package/dist/MsaViewPanel/doLaunchOrthologs.js +6 -5
- package/dist/MsaViewPanel/doLaunchOrthologs.test.js +39 -25
- package/dist/MsaViewPanel/genomeToMSA.js +4 -2
- package/dist/MsaViewPanel/genomeToMSA.test.js +34 -0
- package/dist/MsaViewPanel/model.d.ts +190 -19
- package/dist/MsaViewPanel/model.js +51 -1
- package/dist/MsaViewPanel/msaDataStore.d.ts +5 -3
- package/dist/MsaViewPanel/msaDataStore.js +16 -7
- package/dist/MsaViewPanel/msaDataStore.test.d.ts +1 -0
- package/dist/MsaViewPanel/msaDataStore.test.js +44 -0
- package/dist/MsaViewPanel/observeProteinHighlights.test.js +11 -0
- package/dist/MsaViewPanel/runLaunch.d.ts +38 -0
- package/dist/MsaViewPanel/runLaunch.js +65 -0
- package/dist/MsaViewPanel/runLaunch.test.d.ts +1 -0
- package/dist/MsaViewPanel/runLaunch.test.js +129 -0
- package/dist/MsaViewPanel/storedData.test.d.ts +1 -0
- package/dist/MsaViewPanel/storedData.test.js +160 -0
- package/dist/MsaViewPanel/syncGenomeHoverToMsaColumn.test.js +1 -0
- package/dist/MsaViewPanel/util.d.ts +18 -0
- package/dist/MsaViewPanel/util.js +17 -0
- package/dist/jbrowse-plugin-msaview.umd.production.min.js +47 -35
- package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
- package/dist/utils/blastCache.d.ts +10 -6
- package/dist/utils/blastCache.js +47 -3
- package/dist/utils/blastCache.test.d.ts +1 -0
- package/dist/utils/blastCache.test.js +72 -0
- package/dist/utils/ebiBlast.d.ts +5 -3
- package/dist/utils/ebiBlast.js +6 -4
- package/dist/utils/ebiJobDispatcher.d.ts +6 -3
- package/dist/utils/ebiJobDispatcher.js +13 -6
- package/dist/utils/fetch.d.ts +8 -1
- package/dist/utils/fetch.js +28 -2
- package/dist/utils/msa.d.ts +15 -1
- package/dist/utils/msa.js +40 -13
- package/dist/utils/msaRows.d.ts +31 -0
- package/dist/utils/msaRows.js +67 -0
- package/dist/utils/ncbiDomains.d.ts +2 -2
- package/dist/utils/ncbiOrthologs.d.ts +11 -1
- package/dist/utils/ncbiOrthologs.js +26 -7
- package/dist/utils/ncbiOrthologs.test.js +23 -1
- package/dist/utils/pantherOrthologs.js +2 -10
- package/dist/utils/phmmer.d.ts +54 -0
- package/dist/utils/phmmer.js +120 -0
- package/dist/utils/poll.d.ts +6 -1
- package/dist/utils/poll.js +7 -2
- package/dist/utils/taxonomyNames.d.ts +1 -1
- package/dist/utils/taxonomyNames.js +6 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +30 -24
- package/src/AddHighlightModel/GenomeMouseoverHighlight.tsx +1 -1
- package/src/AddHighlightModel/MsaToGenomeHighlight.tsx +1 -1
- package/src/AddHighlightModel/index.tsx +1 -1
- package/src/LaunchMsaView/components/BlastQuery/BlastAutomaticPanel.tsx +85 -31
- package/src/LaunchMsaView/components/BlastQuery/BlastManualPanel.tsx +1 -1
- package/src/LaunchMsaView/components/BlastQuery/BlastPanel.tsx +4 -4
- package/src/LaunchMsaView/components/BlastQuery/CachedBlastResults.test.ts +50 -0
- package/src/LaunchMsaView/components/BlastQuery/CachedBlastResults.tsx +23 -3
- package/src/LaunchMsaView/components/BlastQuery/MsaAlgorithmSelect.tsx +1 -1
- package/src/LaunchMsaView/components/BlastQuery/consts.ts +40 -0
- package/src/LaunchMsaView/components/BlastQuery/searchChoiceStorage.test.ts +43 -0
- package/src/LaunchMsaView/components/BlastQuery/searchChoiceStorage.ts +64 -0
- package/src/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.tsx +1 -1
- package/src/LaunchMsaView/components/OrthologQuery/OrthologPanel.tsx +7 -7
- package/src/LaunchMsaView/components/SubmitCancelActions.test.tsx +1 -1
- package/src/LaunchMsaView/components/useFeatureSequence.ts +1 -1
- package/src/LaunchMsaView/detectQueryRow.test.ts +17 -15
- package/src/LaunchMsaView/detectQueryRow.ts +34 -23
- package/src/LaunchMsaView/useQueryRowName.ts +6 -9
- package/src/LaunchMsaViewExtensionPoint/index.test.ts +51 -0
- package/src/LaunchMsaViewExtensionPoint/index.ts +21 -6
- package/src/MsaViewPanel/afterCreateAutoruns.ts +102 -68
- package/src/MsaViewPanel/components/ErrorBoundary.tsx +2 -1
- package/src/MsaViewPanel/components/JobLink.tsx +7 -2
- package/src/MsaViewPanel/components/LaunchProgress.tsx +80 -0
- package/src/MsaViewPanel/components/MsaViewPanel.test.tsx +104 -0
- package/src/MsaViewPanel/components/MsaViewPanel.tsx +7 -4
- package/src/MsaViewPanel/doLaunchBlast.ts +134 -72
- package/src/MsaViewPanel/doLaunchOrthologs.test.ts +43 -28
- package/src/MsaViewPanel/doLaunchOrthologs.ts +9 -5
- package/src/MsaViewPanel/genomeToMSA.test.ts +37 -0
- package/src/MsaViewPanel/genomeToMSA.ts +6 -2
- package/src/MsaViewPanel/model.ts +82 -6
- package/src/MsaViewPanel/msaDataStore.test.ts +54 -0
- package/src/MsaViewPanel/msaDataStore.ts +22 -13
- package/src/MsaViewPanel/observeProteinHighlights.test.ts +13 -0
- package/src/MsaViewPanel/runLaunch.test.ts +154 -0
- package/src/MsaViewPanel/runLaunch.ts +102 -0
- package/src/MsaViewPanel/storedData.test.ts +196 -0
- package/src/MsaViewPanel/syncGenomeHoverToMsaColumn.test.ts +1 -0
- package/src/MsaViewPanel/util.ts +18 -0
- package/src/utils/blastCache.test.ts +86 -0
- package/src/utils/blastCache.ts +67 -13
- package/src/utils/ebiBlast.ts +9 -3
- package/src/utils/ebiJobDispatcher.ts +18 -3
- package/src/utils/fetch.ts +29 -2
- package/src/utils/msa.ts +51 -12
- package/src/utils/msaRows.ts +95 -0
- package/src/utils/ncbiDomains.ts +4 -2
- package/src/utils/ncbiOrthologs.test.ts +25 -0
- package/src/utils/ncbiOrthologs.ts +27 -7
- package/src/utils/pantherOrthologs.ts +6 -11
- package/src/utils/phmmer.ts +178 -0
- package/src/utils/poll.ts +8 -1
- package/src/utils/taxonomyNames.ts +6 -1
- package/src/version.ts +1 -1
- package/dist/MsaViewPanel/components/LoadingBLAST.d.ts +0 -6
- package/dist/MsaViewPanel/components/LoadingBLAST.js +0 -26
- package/src/MsaViewPanel/components/LoadingBLAST.tsx +0 -48
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type { MSAFormat } from 'msa-parsers';
|
|
2
|
+
import type { BlastDatabase, MsaAlgorithm, PhmmerDatabase } from '../LaunchMsaView/components/BlastQuery/consts';
|
|
3
|
+
import type { MsaDataPayload } from './msaDataStore';
|
|
2
4
|
import type { MafRegion, MsaViewInitState } from './types';
|
|
3
|
-
import type { BlastDatabase, MsaAlgorithm } from '../LaunchMsaView/components/BlastQuery/consts';
|
|
4
5
|
import type { Feature } from '@jbrowse/core/util';
|
|
5
6
|
import type { Instance } from '@jbrowse/mobx-state-tree';
|
|
6
7
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
@@ -11,12 +12,31 @@ export interface IRegion {
|
|
|
11
12
|
start: number;
|
|
12
13
|
end: number;
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* A search to run, discriminated by the program that runs it: the two arms
|
|
17
|
+
* differ in which databases they name and in whether an aligner runs at all, so
|
|
18
|
+
* splitting them is what lets doLaunchBlast read the database without asserting
|
|
19
|
+
* whose it is.
|
|
20
|
+
*
|
|
21
|
+
* The field is still `blastDatabase` rather than `database`: it is persisted in
|
|
22
|
+
* session snapshots and in the IndexedDB result cache, so renaming it would
|
|
23
|
+
* orphan every row already written.
|
|
24
|
+
*/
|
|
25
|
+
export type BlastParams = {
|
|
17
26
|
selectedTranscript?: Feature;
|
|
18
27
|
proteinSequence: string;
|
|
19
|
-
}
|
|
28
|
+
} & ({
|
|
29
|
+
/** absent on params written before phmmer existed, which were all blastp */
|
|
30
|
+
searchProgram?: 'blastp';
|
|
31
|
+
blastDatabase: BlastDatabase;
|
|
32
|
+
msaAlgorithm: MsaAlgorithm;
|
|
33
|
+
} | {
|
|
34
|
+
searchProgram: 'phmmer';
|
|
35
|
+
/** phmmer names its databases its own way: `swissprot`, not `uniprotkb_swissprot` */
|
|
36
|
+
blastDatabase: PhmmerDatabase;
|
|
37
|
+
/** phmmer aligns as it searches, so there is no aligner to choose */
|
|
38
|
+
msaAlgorithm?: undefined;
|
|
39
|
+
});
|
|
20
40
|
/**
|
|
21
41
|
* Where the ortholog set comes from. NCBI's sets cover vertebrates and
|
|
22
42
|
* insects; PANTHER's span its 144 reference proteomes, human to yeast to
|
|
@@ -66,7 +86,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
66
86
|
id: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
67
87
|
displayName: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
68
88
|
minimized: import("@jbrowse/mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
69
|
-
}, "
|
|
89
|
+
}, "id" | "type" | "autoTreeAreaWidth" | "drawLabels" | "drawNodeBubbles" | "drawTree" | "labelsAlignRight" | "showBranchLen" | "treeAreaWidth" | "treeWidth" | "bgColor" | "colorSchemeName" | "msaFormat" | "showColumnStats" | "allowedGappyness" | "colWidth" | "collapsed" | "columnTracks" | "currentAlignment" | "data" | "drawMsaLetters" | "featureFilters" | "gffFilehandle" | "height" | "hideGaps" | "highlightColumns" | "highlights" | "msaFilehandle" | "relativeTo" | "rowHeight" | "scrollX" | "scrollY" | "scrollZoom" | "showDomainLegend" | "showDomains" | "showOnly" | "subFeatureRows" | "treeFilehandle" | "treeMetadataFilehandle" | "turnedOffTracks"> & Omit<Omit<Omit<{}, "autoTreeAreaWidth" | "drawLabels" | "drawNodeBubbles" | "drawTree" | "labelsAlignRight" | "showBranchLen" | "treeAreaWidth" | "treeWidth"> & {
|
|
70
90
|
drawLabels: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
71
91
|
labelsAlignRight: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
72
92
|
treeAreaWidth: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<number>, [undefined]>;
|
|
@@ -80,7 +100,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
80
100
|
colorSchemeName: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
81
101
|
showColumnStats: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
82
102
|
msaFormat: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<import("msa-parsers").MSAFormat>>;
|
|
83
|
-
}, "
|
|
103
|
+
}, "id" | "type" | "allowedGappyness" | "colWidth" | "collapsed" | "columnTracks" | "currentAlignment" | "data" | "drawMsaLetters" | "featureFilters" | "gffFilehandle" | "height" | "hideGaps" | "highlightColumns" | "highlights" | "msaFilehandle" | "relativeTo" | "rowHeight" | "scrollX" | "scrollY" | "scrollZoom" | "showDomainLegend" | "showDomains" | "showOnly" | "subFeatureRows" | "treeFilehandle" | "treeMetadataFilehandle" | "turnedOffTracks"> & {
|
|
84
104
|
id: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
85
105
|
showDomains: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
86
106
|
showDomainLegend: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
@@ -475,6 +495,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
475
495
|
collapsed: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").ISimpleType<string>>, [undefined]>;
|
|
476
496
|
showOnly: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
477
497
|
turnedOffTracks: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IMapType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>>, [undefined]>;
|
|
498
|
+
columnTracks: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("react-msaview").ColumnTrackSpec, import("react-msaview").ColumnTrackSpec, import("react-msaview").ColumnTrackSpec>>, [undefined]>;
|
|
478
499
|
data: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IModelType<{
|
|
479
500
|
tree: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
480
501
|
msa: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
@@ -486,14 +507,12 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
486
507
|
setTreeMetadata(treeMetadata?: string): void;
|
|
487
508
|
setGFF(gff?: string): void;
|
|
488
509
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, {
|
|
489
|
-
|
|
490
|
-
msa: string | undefined;
|
|
491
|
-
treeMetadata: string | undefined;
|
|
492
|
-
gff: string | undefined;
|
|
510
|
+
[k: string]: string | undefined;
|
|
493
511
|
}>, [undefined]>;
|
|
494
512
|
featureFilters: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IMapType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>>, [undefined]>;
|
|
495
513
|
relativeTo: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
496
514
|
highlightColumns: import("@jbrowse/mobx-state-tree").IType<number[] | undefined, number[] | undefined, number[] | undefined>;
|
|
515
|
+
highlights: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("react-msaview").Highlight, import("react-msaview").Highlight, import("react-msaview").Highlight>>, [undefined]>;
|
|
497
516
|
}, "init" | "querySeqName" | "zoomToBaseLevel" | "connectedViewId" | "connectedFeature" | "blastParams" | "orthologParams" | "uniprotId" | "dataStoreId" | "mafRegion"> & {
|
|
498
517
|
connectedViewId: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
499
518
|
connectedFeature: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
|
|
@@ -559,6 +578,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
559
578
|
highlightedColumns: number[] | undefined;
|
|
560
579
|
minimapHeight: number;
|
|
561
580
|
conservationTrackHeight: number;
|
|
581
|
+
sequenceLogoTrackHeight: number;
|
|
562
582
|
marginLeft: number;
|
|
563
583
|
error: unknown;
|
|
564
584
|
annotations: import("msa-parsers").Annotation[];
|
|
@@ -574,6 +594,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
574
594
|
setError(error?: unknown): void;
|
|
575
595
|
setMousePos(col?: number, row?: number): void;
|
|
576
596
|
setHighlightedColumns(columns?: number[]): void;
|
|
597
|
+
setHighlights(highlights: import("react-msaview").Highlight[]): void;
|
|
577
598
|
setShowDomains(arg: boolean): void;
|
|
578
599
|
setShowDomainLegend(arg: boolean): void;
|
|
579
600
|
setSubFeatureRows(arg: boolean): void;
|
|
@@ -591,6 +612,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
591
612
|
}): void;
|
|
592
613
|
setMSAFilehandle(msaFilehandle?: import("@jbrowse/core/util").FileLocation): void;
|
|
593
614
|
setTreeFilehandle(treeFilehandle?: import("@jbrowse/core/util").FileLocation): void;
|
|
615
|
+
setTreeMetadataFilehandle(treeMetadataFilehandle?: import("@jbrowse/core/util").FileLocation): void;
|
|
594
616
|
setGFFFilehandle(gffFilehandle?: import("@jbrowse/core/util").FileLocation): void;
|
|
595
617
|
setMSA(result: string): void;
|
|
596
618
|
setTree(result: string): void;
|
|
@@ -655,6 +677,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
655
677
|
}[];
|
|
656
678
|
readonly colClustalX: Record<string, string>[];
|
|
657
679
|
readonly conservation: number[];
|
|
680
|
+
readonly alphabetMaxBits: number;
|
|
658
681
|
readonly propertyConservation: number[];
|
|
659
682
|
readonly hierarchy: import("react-msaview").HierarchyNode<import("react-msaview").NodeWithIdsAndLength>;
|
|
660
683
|
readonly totalHeight: number;
|
|
@@ -669,6 +692,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
669
692
|
readonly dataInitialized: boolean;
|
|
670
693
|
readonly blocksX: number[];
|
|
671
694
|
readonly blocksY: number[];
|
|
695
|
+
readonly visibleMsaHeight: number;
|
|
672
696
|
} & {
|
|
673
697
|
readonly blocks2d: (readonly [number, number])[];
|
|
674
698
|
readonly isLoading: boolean;
|
|
@@ -696,6 +720,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
696
720
|
applyGFFText(gffText: string): void;
|
|
697
721
|
doScrollX(deltaX: number): void;
|
|
698
722
|
setScrollX(n: number): void;
|
|
723
|
+
setColumnTracks(tracks: import("react-msaview").ColumnTrackSpec[]): void;
|
|
699
724
|
toggleTrack(id: string): void;
|
|
700
725
|
setStatus(status?: {
|
|
701
726
|
msg: string;
|
|
@@ -704,10 +729,16 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
704
729
|
}): void;
|
|
705
730
|
} & {
|
|
706
731
|
readonly labelWidthMap: Map<string, number>;
|
|
732
|
+
readonly labelWidthScale: number;
|
|
707
733
|
readonly labelsWidth: number;
|
|
708
734
|
readonly secondaryStructureConsensus: string | undefined;
|
|
709
735
|
readonly seqConsensus: string | undefined;
|
|
710
736
|
readonly adapterTrackModels: import("react-msaview").BasicTrack[];
|
|
737
|
+
readonly columnTrackContent: Map<string, {
|
|
738
|
+
values?: number[];
|
|
739
|
+
data?: string;
|
|
740
|
+
}>;
|
|
741
|
+
readonly columnTrackModels: import("react-msaview").BasicTrack[];
|
|
711
742
|
readonly tracks: import("react-msaview").BasicTrack[];
|
|
712
743
|
readonly turnedOnTracks: import("react-msaview").BasicTrack[];
|
|
713
744
|
readonly showHorizontalScrollbar: boolean;
|
|
@@ -747,6 +778,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
747
778
|
start: number;
|
|
748
779
|
end: number;
|
|
749
780
|
}[];
|
|
781
|
+
readonly resolvedHighlights: import("react-msaview").ResolvedHighlight[];
|
|
750
782
|
readonly mouseOverColumnStats: {
|
|
751
783
|
col: number;
|
|
752
784
|
total: number;
|
|
@@ -770,13 +802,9 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
770
802
|
} & {
|
|
771
803
|
setHeaderHeight(arg: number): void;
|
|
772
804
|
setConservationTrackHeight(arg: number): void;
|
|
805
|
+
setSequenceLogoTrackHeight(arg: number): void;
|
|
773
806
|
reset(): void;
|
|
774
|
-
exportSVG(opts:
|
|
775
|
-
theme: import("@mui/material").Theme;
|
|
776
|
-
includeMinimap?: boolean;
|
|
777
|
-
includeTracks?: boolean;
|
|
778
|
-
exportType: "entire" | "viewport";
|
|
779
|
-
}): Promise<void>;
|
|
807
|
+
exportSVG(opts: import("react-msaview").ExportSvgOptions): Promise<void>;
|
|
780
808
|
initFilter(arg: string): void;
|
|
781
809
|
setFilter(arg: string, flag: boolean): void;
|
|
782
810
|
fit(): void;
|
|
@@ -789,6 +817,8 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
789
817
|
error: unknown;
|
|
790
818
|
loadingStoredData: boolean;
|
|
791
819
|
isStoringData: boolean;
|
|
820
|
+
lastStoredData: MsaDataPayload | undefined;
|
|
821
|
+
launchController: AbortController | undefined;
|
|
792
822
|
domainsRequested: boolean;
|
|
793
823
|
} & {
|
|
794
824
|
/**
|
|
@@ -887,6 +917,23 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
887
917
|
* #action
|
|
888
918
|
*/
|
|
889
919
|
setIsStoringData(arg: boolean): void;
|
|
920
|
+
/**
|
|
921
|
+
* #action
|
|
922
|
+
*/
|
|
923
|
+
setLastStoredData(arg?: MsaDataPayload): void;
|
|
924
|
+
/**
|
|
925
|
+
* #action
|
|
926
|
+
*/
|
|
927
|
+
setLaunchController(arg?: AbortController): void;
|
|
928
|
+
/**
|
|
929
|
+
* #action
|
|
930
|
+
* Abandon the launch in flight. The EBI job keeps running on their side —
|
|
931
|
+
* nothing here can recall it, and its JobLink stays valid — so this only
|
|
932
|
+
* stops the polling and the writes it would make. Dropping the params is
|
|
933
|
+
* what keeps the request from refiring; the view falls back to the import
|
|
934
|
+
* form, which is where react-msaview's own cancel leaves it too.
|
|
935
|
+
*/
|
|
936
|
+
cancelLaunch(): void;
|
|
890
937
|
/**
|
|
891
938
|
* #action
|
|
892
939
|
*/
|
|
@@ -916,7 +963,129 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
916
963
|
id: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
917
964
|
displayName: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
918
965
|
minimized: import("@jbrowse/mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
919
|
-
}> & {
|
|
966
|
+
}> & (({
|
|
967
|
+
bgColor: boolean;
|
|
968
|
+
colorSchemeName: string;
|
|
969
|
+
showColumnStats: boolean;
|
|
970
|
+
msaFormat: import("msa-parsers").MSAFormat | undefined;
|
|
971
|
+
drawLabels: boolean;
|
|
972
|
+
labelsAlignRight: boolean;
|
|
973
|
+
treeAreaWidth: number;
|
|
974
|
+
treeWidth: number;
|
|
975
|
+
showBranchLen: boolean;
|
|
976
|
+
drawTree: boolean;
|
|
977
|
+
drawNodeBubbles: boolean;
|
|
978
|
+
autoTreeAreaWidth: boolean;
|
|
979
|
+
columnTracks: import("react-msaview").ColumnTrackSpec[];
|
|
980
|
+
id: string;
|
|
981
|
+
showDomains: boolean;
|
|
982
|
+
showDomainLegend: boolean;
|
|
983
|
+
hideGaps: boolean;
|
|
984
|
+
allowedGappyness: number;
|
|
985
|
+
subFeatureRows: boolean;
|
|
986
|
+
type: "MsaView";
|
|
987
|
+
drawMsaLetters: boolean;
|
|
988
|
+
scrollZoom: boolean;
|
|
989
|
+
height: number;
|
|
990
|
+
rowHeight: number;
|
|
991
|
+
scrollY: number;
|
|
992
|
+
scrollX: number;
|
|
993
|
+
colWidth: number;
|
|
994
|
+
treeFilehandle: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
995
|
+
locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"LocalPathLocation">;
|
|
996
|
+
localPath: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
997
|
+
}> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
998
|
+
locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"BlobLocation">;
|
|
999
|
+
name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1000
|
+
blobId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1001
|
+
}> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1002
|
+
locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"FileHandleLocation">;
|
|
1003
|
+
name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1004
|
+
handleId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1005
|
+
}> | {
|
|
1006
|
+
locationType: "UriLocation";
|
|
1007
|
+
uri: string;
|
|
1008
|
+
internetAccountId: string | undefined;
|
|
1009
|
+
internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1010
|
+
internetAccountType: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1011
|
+
authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
|
|
1012
|
+
}> | undefined;
|
|
1013
|
+
} | undefined;
|
|
1014
|
+
msaFilehandle: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1015
|
+
locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"LocalPathLocation">;
|
|
1016
|
+
localPath: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1017
|
+
}> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1018
|
+
locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"BlobLocation">;
|
|
1019
|
+
name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1020
|
+
blobId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1021
|
+
}> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1022
|
+
locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"FileHandleLocation">;
|
|
1023
|
+
name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1024
|
+
handleId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1025
|
+
}> | {
|
|
1026
|
+
locationType: "UriLocation";
|
|
1027
|
+
uri: string;
|
|
1028
|
+
internetAccountId: string | undefined;
|
|
1029
|
+
internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1030
|
+
internetAccountType: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1031
|
+
authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
|
|
1032
|
+
}> | undefined;
|
|
1033
|
+
} | undefined;
|
|
1034
|
+
treeMetadataFilehandle: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1035
|
+
locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"LocalPathLocation">;
|
|
1036
|
+
localPath: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1037
|
+
}> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1038
|
+
locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"BlobLocation">;
|
|
1039
|
+
name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1040
|
+
blobId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1041
|
+
}> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1042
|
+
locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"FileHandleLocation">;
|
|
1043
|
+
name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1044
|
+
handleId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1045
|
+
}> | {
|
|
1046
|
+
locationType: "UriLocation";
|
|
1047
|
+
uri: string;
|
|
1048
|
+
internetAccountId: string | undefined;
|
|
1049
|
+
internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1050
|
+
internetAccountType: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1051
|
+
authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
|
|
1052
|
+
}> | undefined;
|
|
1053
|
+
} | undefined;
|
|
1054
|
+
gffFilehandle: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1055
|
+
locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"LocalPathLocation">;
|
|
1056
|
+
localPath: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1057
|
+
}> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1058
|
+
locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"BlobLocation">;
|
|
1059
|
+
name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1060
|
+
blobId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1061
|
+
}> | import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1062
|
+
locationType: import("@jbrowse/mobx-state-tree").ISimpleType<"FileHandleLocation">;
|
|
1063
|
+
name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1064
|
+
handleId: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1065
|
+
}> | {
|
|
1066
|
+
locationType: "UriLocation";
|
|
1067
|
+
uri: string;
|
|
1068
|
+
internetAccountId: string | undefined;
|
|
1069
|
+
internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{
|
|
1070
|
+
internetAccountType: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1071
|
+
authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
|
|
1072
|
+
}> | undefined;
|
|
1073
|
+
} | undefined;
|
|
1074
|
+
currentAlignment: number;
|
|
1075
|
+
collapsed: string[];
|
|
1076
|
+
showOnly: string | undefined;
|
|
1077
|
+
turnedOffTracks: import("mobx").IKeyValueMap<boolean>;
|
|
1078
|
+
featureFilters: import("mobx").IKeyValueMap<boolean>;
|
|
1079
|
+
relativeTo: string | undefined;
|
|
1080
|
+
highlightColumns: number[] | undefined;
|
|
1081
|
+
highlights: import("react-msaview").Highlight[];
|
|
1082
|
+
data: {
|
|
1083
|
+
tree?: string | undefined;
|
|
1084
|
+
msa?: string | undefined;
|
|
1085
|
+
treeMetadata?: string | undefined;
|
|
1086
|
+
gff?: string | undefined;
|
|
1087
|
+
};
|
|
1088
|
+
} & import("@jbrowse/mobx-state-tree")._NotCustomized) | ({
|
|
920
1089
|
bgColor: boolean;
|
|
921
1090
|
colorSchemeName: string;
|
|
922
1091
|
showColumnStats: boolean;
|
|
@@ -929,6 +1098,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
929
1098
|
drawTree: boolean;
|
|
930
1099
|
drawNodeBubbles: boolean;
|
|
931
1100
|
autoTreeAreaWidth: boolean;
|
|
1101
|
+
columnTracks?: undefined;
|
|
932
1102
|
id: string;
|
|
933
1103
|
showDomains: boolean;
|
|
934
1104
|
showDomainLegend: boolean;
|
|
@@ -1030,13 +1200,14 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
1030
1200
|
featureFilters: import("mobx").IKeyValueMap<boolean>;
|
|
1031
1201
|
relativeTo: string | undefined;
|
|
1032
1202
|
highlightColumns: number[] | undefined;
|
|
1203
|
+
highlights: import("react-msaview").Highlight[];
|
|
1033
1204
|
data: {
|
|
1034
1205
|
tree?: string | undefined;
|
|
1035
1206
|
msa?: string | undefined;
|
|
1036
1207
|
treeMetadata?: string | undefined;
|
|
1037
1208
|
gff?: string | undefined;
|
|
1038
1209
|
};
|
|
1039
|
-
} & import("@jbrowse/mobx-state-tree")._NotCustomized>;
|
|
1210
|
+
} & import("@jbrowse/mobx-state-tree")._NotCustomized))>;
|
|
1040
1211
|
export type JBrowsePluginMsaViewStateModel = ReturnType<typeof stateModelFactory>;
|
|
1041
1212
|
export type JBrowsePluginMsaViewModel = Instance<JBrowsePluginMsaViewStateModel>;
|
|
1042
1213
|
export { type MafRegion, type MsaViewInitState } from './types';
|
|
@@ -88,6 +88,21 @@ export default function stateModelFactory() {
|
|
|
88
88
|
* #volatile
|
|
89
89
|
*/
|
|
90
90
|
isStoringData: false,
|
|
91
|
+
/**
|
|
92
|
+
* #volatile
|
|
93
|
+
* what IndexedDB was last known to hold for this view, so an edit made
|
|
94
|
+
* after the first write (react-msaview replacing data.tree with a
|
|
95
|
+
* neighbor-joining tree, say) is recognized as needing a new one
|
|
96
|
+
*/
|
|
97
|
+
lastStoredData: undefined,
|
|
98
|
+
/**
|
|
99
|
+
* #volatile
|
|
100
|
+
* aborts the launch currently in flight -- from the Cancel button, and
|
|
101
|
+
* from the disposer afterCreate registers, so a closed view stops
|
|
102
|
+
* polling EBI instead of running to completion and writing to a node
|
|
103
|
+
* that is gone
|
|
104
|
+
*/
|
|
105
|
+
launchController: undefined,
|
|
91
106
|
/**
|
|
92
107
|
* #volatile
|
|
93
108
|
* guards the one-shot auto-fetch of protein domains so it doesn't refire
|
|
@@ -106,7 +121,7 @@ export default function stateModelFactory() {
|
|
|
106
121
|
* #method
|
|
107
122
|
*/
|
|
108
123
|
getSequenceByRowName(rowName) {
|
|
109
|
-
return
|
|
124
|
+
return this.getRowByName(rowName)?.[1];
|
|
110
125
|
},
|
|
111
126
|
}))
|
|
112
127
|
.views(self => ({
|
|
@@ -241,6 +256,35 @@ export default function stateModelFactory() {
|
|
|
241
256
|
setIsStoringData(arg) {
|
|
242
257
|
self.isStoringData = arg;
|
|
243
258
|
},
|
|
259
|
+
/**
|
|
260
|
+
* #action
|
|
261
|
+
*/
|
|
262
|
+
setLastStoredData(arg) {
|
|
263
|
+
self.lastStoredData = arg;
|
|
264
|
+
},
|
|
265
|
+
/**
|
|
266
|
+
* #action
|
|
267
|
+
*/
|
|
268
|
+
setLaunchController(arg) {
|
|
269
|
+
self.launchController = arg;
|
|
270
|
+
},
|
|
271
|
+
/**
|
|
272
|
+
* #action
|
|
273
|
+
* Abandon the launch in flight. The EBI job keeps running on their side —
|
|
274
|
+
* nothing here can recall it, and its JobLink stays valid — so this only
|
|
275
|
+
* stops the polling and the writes it would make. Dropping the params is
|
|
276
|
+
* what keeps the request from refiring; the view falls back to the import
|
|
277
|
+
* form, which is where react-msaview's own cancel leaves it too.
|
|
278
|
+
*/
|
|
279
|
+
cancelLaunch() {
|
|
280
|
+
self.launchController?.abort();
|
|
281
|
+
self.launchController = undefined;
|
|
282
|
+
self.blastParams = undefined;
|
|
283
|
+
self.orthologParams = undefined;
|
|
284
|
+
self.progress = '';
|
|
285
|
+
self.rid = undefined;
|
|
286
|
+
self.error = undefined;
|
|
287
|
+
},
|
|
244
288
|
/**
|
|
245
289
|
* #action
|
|
246
290
|
*/
|
|
@@ -301,6 +345,12 @@ export default function stateModelFactory() {
|
|
|
301
345
|
.actions(self => ({
|
|
302
346
|
afterCreate() {
|
|
303
347
|
runCleanup();
|
|
348
|
+
// ties the launch to the view: closing one mid-BLAST used to leave the
|
|
349
|
+
// poller running for the job's lifetime and then call actions on a
|
|
350
|
+
// destroyed node, which surfaced as an unhandled rejection
|
|
351
|
+
addDisposer(self, () => {
|
|
352
|
+
self.launchController?.abort();
|
|
353
|
+
});
|
|
304
354
|
for (const fn of [
|
|
305
355
|
loadStoredData,
|
|
306
356
|
storeDataToIndexedDB,
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
/** the documents a view keeps in IndexedDB rather than in its session snapshot */
|
|
2
|
+
export interface MsaDataPayload {
|
|
3
3
|
msa?: string;
|
|
4
4
|
tree?: string;
|
|
5
5
|
treeMetadata?: string;
|
|
6
|
-
}
|
|
6
|
+
}
|
|
7
|
+
export declare function generateDataStoreId(): string;
|
|
8
|
+
export declare function storeMsaData(id: string, data: MsaDataPayload): Promise<boolean>;
|
|
7
9
|
export declare function retrieveMsaData(id: string): Promise<{
|
|
8
10
|
msa: string | undefined;
|
|
9
11
|
tree: string | undefined;
|
|
@@ -33,14 +33,23 @@ export async function retrieveMsaData(id) {
|
|
|
33
33
|
try {
|
|
34
34
|
const db = await getDB();
|
|
35
35
|
const result = await db.get(STORE_NAME, id);
|
|
36
|
-
if (result) {
|
|
37
|
-
return
|
|
38
|
-
msa: result.msa,
|
|
39
|
-
tree: result.tree,
|
|
40
|
-
treeMetadata: result.treeMetadata,
|
|
41
|
-
};
|
|
36
|
+
if (!result) {
|
|
37
|
+
return undefined;
|
|
42
38
|
}
|
|
43
|
-
|
|
39
|
+
// reading counts as use, which is what makes cleanupOldData's policy
|
|
40
|
+
// "unused for 7 days" rather than "written 7 days ago" -- a session opened
|
|
41
|
+
// every day used to lose its alignment on the eighth
|
|
42
|
+
try {
|
|
43
|
+
await db.put(STORE_NAME, { ...result, timestamp: Date.now() });
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
console.warn('Failed to refresh MSA data timestamp:', e);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
msa: result.msa,
|
|
50
|
+
tree: result.tree,
|
|
51
|
+
treeMetadata: result.treeMetadata,
|
|
52
|
+
};
|
|
44
53
|
}
|
|
45
54
|
catch (e) {
|
|
46
55
|
console.warn('Failed to retrieve MSA data:', e);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { beforeEach, expect, test, vi } from 'vitest';
|
|
2
|
+
import { retrieveMsaData } from './msaDataStore';
|
|
3
|
+
// An in-memory stand-in for the one object store this module opens, with a
|
|
4
|
+
// switch for the write half so a browser that refuses writes can be played back.
|
|
5
|
+
const { rows, state } = vi.hoisted(() => ({
|
|
6
|
+
rows: new Map(),
|
|
7
|
+
state: { putFails: false },
|
|
8
|
+
}));
|
|
9
|
+
vi.mock('../utils/idb', () => ({
|
|
10
|
+
createDbOpener: () => () => Promise.resolve({
|
|
11
|
+
get: (_store, id) => Promise.resolve(rows.get(id)),
|
|
12
|
+
put: (_store, value) => {
|
|
13
|
+
if (state.putFails) {
|
|
14
|
+
return Promise.reject(new Error('QuotaExceededError'));
|
|
15
|
+
}
|
|
16
|
+
rows.set(value.id, value);
|
|
17
|
+
return Promise.resolve(value.id);
|
|
18
|
+
},
|
|
19
|
+
}),
|
|
20
|
+
}));
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
rows.clear();
|
|
23
|
+
state.putFails = false;
|
|
24
|
+
});
|
|
25
|
+
// cleanupOldData deletes by timestamp, so without this a session opened every
|
|
26
|
+
// single day still lost its alignment on the eighth
|
|
27
|
+
test('reading a row refreshes its timestamp, making the expiry "unused for 7 days"', async () => {
|
|
28
|
+
rows.set('msa-1', { id: 'msa-1', msa: '>a\nMK', timestamp: 1000 });
|
|
29
|
+
const before = Date.now();
|
|
30
|
+
expect((await retrieveMsaData('msa-1'))?.msa).toBe('>a\nMK');
|
|
31
|
+
expect(rows.get('msa-1').timestamp).toBeGreaterThanOrEqual(before);
|
|
32
|
+
});
|
|
33
|
+
test('a row that is no longer there reads as undefined and writes nothing', async () => {
|
|
34
|
+
expect(await retrieveMsaData('msa-gone')).toBeUndefined();
|
|
35
|
+
expect(rows.size).toBe(0);
|
|
36
|
+
});
|
|
37
|
+
// the refresh is housekeeping; failing it must not turn a readable alignment
|
|
38
|
+
// into a missing one, which is what the caller reports as expired
|
|
39
|
+
test('a refresh that fails still hands back the data it read', async () => {
|
|
40
|
+
vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
41
|
+
rows.set('msa-1', { id: 'msa-1', msa: '>a\nMK', timestamp: 1000 });
|
|
42
|
+
state.putFails = true;
|
|
43
|
+
expect((await retrieveMsaData('msa-1'))?.msa).toBe('>a\nMK');
|
|
44
|
+
});
|
|
@@ -18,6 +18,7 @@ function makeModel({ highlightColumns } = {}) {
|
|
|
18
18
|
const calls = [];
|
|
19
19
|
const model = {
|
|
20
20
|
querySeqName: 'query',
|
|
21
|
+
rows: [['query', 'MKVLTAEEK']],
|
|
21
22
|
connectedViewId: CONNECTED,
|
|
22
23
|
// g2p is indexed by genome coord; identity keeps the arithmetic out of the way
|
|
23
24
|
transcriptToMsaMap: {
|
|
@@ -195,6 +196,16 @@ describe('scope and redundant writes', () => {
|
|
|
195
196
|
run();
|
|
196
197
|
expect(calls).toEqual([]);
|
|
197
198
|
});
|
|
199
|
+
// seqPosToGlobalCol answers 0 for a row name it does not know, so without a
|
|
200
|
+
// guard a structure hover would light column 0 of whatever row is first
|
|
201
|
+
test('a query row this alignment does not have contributes no column', () => {
|
|
202
|
+
const { model, calls } = makeModel();
|
|
203
|
+
Object.assign(model, { rows: [['some_other_row', 'MKVLTAEEK']] });
|
|
204
|
+
const run = observeProteinHighlights(model);
|
|
205
|
+
session({ hover: [{ start: 10, end: 12 }] });
|
|
206
|
+
run();
|
|
207
|
+
expect(calls).toEqual([]);
|
|
208
|
+
});
|
|
198
209
|
test('nothing happens until the view is connected and mapped', () => {
|
|
199
210
|
const { calls } = makeModel();
|
|
200
211
|
const bare = {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { JBrowsePluginMsaViewModel } from './model';
|
|
2
|
+
/**
|
|
3
|
+
* What a launch is allowed to do to the model and to the network while it runs.
|
|
4
|
+
*
|
|
5
|
+
* Every write a launch makes goes through `act`, so "nothing touches the model
|
|
6
|
+
* once the launch has been abandoned" is one rule in one place. Spreading that
|
|
7
|
+
* guard across the call sites only takes one omission to undo: an abandoned
|
|
8
|
+
* launch keeps running until its next network hop rejects, and an action on a
|
|
9
|
+
* destroyed mobx-state-tree node throws where nothing is catching.
|
|
10
|
+
*/
|
|
11
|
+
export interface LaunchScope {
|
|
12
|
+
/** aborts when the user cancels, and when the view is destroyed */
|
|
13
|
+
signal: AbortSignal;
|
|
14
|
+
act: (fn: () => void) => void;
|
|
15
|
+
onProgress: (arg: string) => void;
|
|
16
|
+
/** the EBI job id, published before the first poll so the view can link out */
|
|
17
|
+
onRid: (arg: string) => void;
|
|
18
|
+
}
|
|
19
|
+
interface LaunchedData {
|
|
20
|
+
msa: string;
|
|
21
|
+
tree: string;
|
|
22
|
+
treeMetadata: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Run one launch attempt, owning the AbortController that ties it to the view.
|
|
26
|
+
*
|
|
27
|
+
* The controller lives on the model because two things end a launch and neither
|
|
28
|
+
* is here: the Cancel button, and the disposer `afterCreate` registers. Before
|
|
29
|
+
* it existed, closing a view mid-BLAST left the poller checking EBI for the
|
|
30
|
+
* job's lifetime and then writing to a node that was gone.
|
|
31
|
+
*/
|
|
32
|
+
export declare function runLaunch({ self, message, launch, onLaunched, }: {
|
|
33
|
+
self: JBrowsePluginMsaViewModel;
|
|
34
|
+
message: string;
|
|
35
|
+
launch: (scope: LaunchScope) => Promise<LaunchedData>;
|
|
36
|
+
onLaunched: () => void;
|
|
37
|
+
}): void;
|
|
38
|
+
export {};
|