jbrowse-plugin-msaview 2.8.2 → 2.9.0

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 (87) hide show
  1. package/dist/LaunchMsaView/components/{NCBIBlastQuery/NCBIBlastRIDPanel.d.ts → BlastQuery/BlastAutomaticPanel.d.ts} +2 -3
  2. package/dist/LaunchMsaView/components/{NCBIBlastQuery/NCBIBlastAutomaticPanel.js → BlastQuery/BlastAutomaticPanel.js} +6 -25
  3. package/dist/LaunchMsaView/components/{NCBIBlastQuery/NCBIBlastManualPanel.d.ts → BlastQuery/BlastManualPanel.d.ts} +2 -3
  4. package/dist/LaunchMsaView/components/{NCBIBlastQuery/NCBIBlastManualPanel.js → BlastQuery/BlastManualPanel.js} +7 -4
  5. package/dist/LaunchMsaView/components/{NCBIBlastQuery/NCBIBlastMethodSelector.d.ts → BlastQuery/BlastMethodSelector.d.ts} +2 -2
  6. package/dist/LaunchMsaView/components/{NCBIBlastQuery/NCBIBlastMethodSelector.js → BlastQuery/BlastMethodSelector.js} +1 -2
  7. package/dist/LaunchMsaView/components/{NCBIBlastQuery/NCBIBlastPanel.d.ts → BlastQuery/BlastPanel.d.ts} +3 -12
  8. package/dist/LaunchMsaView/components/{NCBIBlastQuery/NCBIBlastPanel.js → BlastQuery/BlastPanel.js} +14 -16
  9. package/dist/LaunchMsaView/components/BlastQuery/BlastSettingsDialog.d.ts +8 -0
  10. package/dist/LaunchMsaView/components/{NCBIBlastQuery/NCBISettingsDialog.js → BlastQuery/BlastSettingsDialog.js} +13 -9
  11. package/dist/LaunchMsaView/components/{NCBIBlastQuery → BlastQuery}/CachedBlastResults.js +1 -1
  12. package/dist/LaunchMsaView/components/BlastQuery/consts.d.ts +12 -0
  13. package/dist/LaunchMsaView/components/BlastQuery/consts.js +17 -0
  14. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js +3 -3
  15. package/dist/LaunchMsaView/components/OrthologQuery/OrthologPanel.js +1 -1
  16. package/dist/MsaViewPanel/components/JobLink.d.ts +5 -0
  17. package/dist/MsaViewPanel/components/JobLink.js +13 -0
  18. package/dist/MsaViewPanel/components/LoadingBLAST.d.ts +1 -2
  19. package/dist/MsaViewPanel/components/LoadingBLAST.js +8 -15
  20. package/dist/MsaViewPanel/components/MsaViewPanel.js +1 -1
  21. package/dist/MsaViewPanel/doLaunchBlast.js +11 -19
  22. package/dist/MsaViewPanel/doLaunchOrthologs.test.d.ts +1 -0
  23. package/dist/MsaViewPanel/doLaunchOrthologs.test.js +127 -0
  24. package/dist/MsaViewPanel/model.d.ts +1 -4
  25. package/dist/jbrowse-plugin-msaview.umd.production.min.js +30 -30
  26. package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
  27. package/dist/utils/blastCache.d.ts +8 -4
  28. package/dist/utils/blastCache.js +4 -5
  29. package/dist/utils/ebiBlast.d.ts +52 -0
  30. package/dist/utils/ebiBlast.js +63 -0
  31. package/dist/utils/ebiJobDispatcher.d.ts +33 -0
  32. package/dist/utils/ebiJobDispatcher.js +55 -0
  33. package/dist/utils/fetch.js +24 -1
  34. package/dist/utils/msa.d.ts +1 -1
  35. package/dist/utils/msa.js +25 -32
  36. package/dist/utils/types.d.ts +9 -14
  37. package/dist/utils/useLocalStorage.d.ts +1 -0
  38. package/dist/utils/useLocalStorage.js +1 -1
  39. package/dist/version.d.ts +1 -1
  40. package/dist/version.js +1 -1
  41. package/package.json +1 -1
  42. package/src/LaunchMsaView/components/{NCBIBlastQuery/NCBIBlastAutomaticPanel.tsx → BlastQuery/BlastAutomaticPanel.tsx} +13 -59
  43. package/src/LaunchMsaView/components/{NCBIBlastQuery/NCBIBlastManualPanel.tsx → BlastQuery/BlastManualPanel.tsx} +7 -6
  44. package/src/LaunchMsaView/components/{NCBIBlastQuery/NCBIBlastMethodSelector.tsx → BlastQuery/BlastMethodSelector.tsx} +2 -7
  45. package/src/LaunchMsaView/components/{NCBIBlastQuery/NCBIBlastPanel.tsx → BlastQuery/BlastPanel.tsx} +21 -25
  46. package/src/LaunchMsaView/components/{NCBIBlastQuery/NCBISettingsDialog.tsx → BlastQuery/BlastSettingsDialog.tsx} +26 -13
  47. package/src/LaunchMsaView/components/{NCBIBlastQuery → BlastQuery}/CachedBlastResults.tsx +1 -1
  48. package/src/LaunchMsaView/components/BlastQuery/consts.ts +22 -0
  49. package/src/LaunchMsaView/components/LaunchMsaViewDialog.tsx +5 -7
  50. package/src/LaunchMsaView/components/OrthologQuery/OrthologPanel.tsx +2 -2
  51. package/src/MsaViewPanel/components/JobLink.tsx +17 -0
  52. package/src/MsaViewPanel/components/LoadingBLAST.tsx +10 -41
  53. package/src/MsaViewPanel/components/MsaViewPanel.tsx +1 -1
  54. package/src/MsaViewPanel/doLaunchBlast.ts +12 -28
  55. package/src/MsaViewPanel/doLaunchOrthologs.test.ts +159 -0
  56. package/src/MsaViewPanel/model.ts +1 -5
  57. package/src/utils/blastCache.ts +8 -9
  58. package/src/utils/ebiBlast.ts +114 -0
  59. package/src/utils/ebiJobDispatcher.ts +91 -0
  60. package/src/utils/fetch.ts +26 -1
  61. package/src/utils/msa.ts +26 -47
  62. package/src/utils/types.ts +8 -13
  63. package/src/utils/useLocalStorage.ts +1 -1
  64. package/src/version.ts +1 -1
  65. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.d.ts +0 -10
  66. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.js +0 -74
  67. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBISettingsDialog.d.ts +0 -5
  68. package/dist/LaunchMsaView/components/NCBIBlastQuery/consts.d.ts +0 -7
  69. package/dist/LaunchMsaView/components/NCBIBlastQuery/consts.js +0 -4
  70. package/dist/MsaViewPanel/components/RIDLink.d.ts +0 -6
  71. package/dist/MsaViewPanel/components/RIDLink.js +0 -12
  72. package/dist/utils/ncbiBlast.d.ts +0 -30
  73. package/dist/utils/ncbiBlast.js +0 -84
  74. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastRIDPanel.tsx +0 -137
  75. package/src/LaunchMsaView/components/NCBIBlastQuery/consts.ts +0 -10
  76. package/src/MsaViewPanel/components/RIDLink.tsx +0 -19
  77. package/src/utils/ncbiBlast.ts +0 -143
  78. /package/dist/LaunchMsaView/components/{NCBIBlastQuery → BlastQuery}/CachedBlastResults.d.ts +0 -0
  79. /package/dist/LaunchMsaView/components/{NCBIBlastQuery → BlastQuery}/MsaAlgorithmSelect.d.ts +0 -0
  80. /package/dist/LaunchMsaView/components/{NCBIBlastQuery → BlastQuery}/MsaAlgorithmSelect.js +0 -0
  81. /package/dist/LaunchMsaView/components/{NCBIBlastQuery → BlastQuery}/blastLaunchView.d.ts +0 -0
  82. /package/dist/LaunchMsaView/components/{NCBIBlastQuery → BlastQuery}/blastLaunchView.js +0 -0
  83. /package/dist/LaunchMsaView/components/{NCBIBlastQuery → BlastQuery}/useCachedBlastResults.d.ts +0 -0
  84. /package/dist/LaunchMsaView/components/{NCBIBlastQuery → BlastQuery}/useCachedBlastResults.js +0 -0
  85. /package/src/LaunchMsaView/components/{NCBIBlastQuery → BlastQuery}/MsaAlgorithmSelect.tsx +0 -0
  86. /package/src/LaunchMsaView/components/{NCBIBlastQuery → BlastQuery}/blastLaunchView.ts +0 -0
  87. /package/src/LaunchMsaView/components/{NCBIBlastQuery → BlastQuery}/useCachedBlastResults.ts +0 -0
@@ -0,0 +1,127 @@
1
+ import { beforeEach, describe, expect, test, vi } from 'vitest';
2
+ import { doLaunchOrthologs } from './doLaunchOrthologs';
3
+ import { launchMSA } from '../utils/msa';
4
+ import { COMMON_SPECIES, fetchOrthologRows, fetchProteinForGene, resolveGeneId, } from '../utils/ncbiOrthologs';
5
+ // Every network call is mocked and nothing else is. What is under test is the
6
+ // argument shaping either side of those calls -- which taxa get asked for, what
7
+ // becomes the QUERY row, and whether the row earns the Accession that drives the
8
+ // CDD overlay -- so the real COMMON_SPECIES list and the real
9
+ // cleanProteinSequence stay in the picture.
10
+ vi.mock('../utils/ncbiOrthologs', async (importOriginal) => ({
11
+ ...(await importOriginal()),
12
+ resolveGeneId: vi.fn(),
13
+ fetchProteinForGene: vi.fn(),
14
+ fetchOrthologRows: vi.fn(),
15
+ }));
16
+ vi.mock('../utils/msa', () => ({ launchMSA: vi.fn() }));
17
+ const mockResolveGeneId = vi.mocked(resolveGeneId);
18
+ const mockFetchProtein = vi.mocked(fetchProteinForGene);
19
+ const mockFetchRows = vi.mocked(fetchOrthologRows);
20
+ const mockLaunchMSA = vi.mocked(launchMSA);
21
+ const HUMAN = 9606;
22
+ const GENE_ID = '22861';
23
+ const REPRESENTATIVE = { accession: 'NP_127497.1', sequence: 'MAGGAWGRLACY' };
24
+ function makeModel(orthologParams) {
25
+ return {
26
+ orthologParams,
27
+ setProgress: () => { },
28
+ };
29
+ }
30
+ function params(extra = {}) {
31
+ return {
32
+ taxId: HUMAN,
33
+ geneCandidates: ['NLRP1'],
34
+ msaAlgorithm: 'clustalo',
35
+ ...extra,
36
+ };
37
+ }
38
+ // What fetchOrthologRows was asked for, which is the only place the taxa
39
+ // default is observable.
40
+ function taxaAskedFor() {
41
+ return [...mockFetchRows.mock.calls[0][0].taxa].sort((a, b) => a - b);
42
+ }
43
+ // The QUERY row as it went to the aligner, read back out of the FASTA rather
44
+ // than out of an intermediate, since the FASTA is what the alignment is of.
45
+ function queryRowSent() {
46
+ return mockLaunchMSA.mock.calls[0][0].sequence.split('\n')[1];
47
+ }
48
+ function queryMetadata(result) {
49
+ return JSON.parse(result.treeMetadata).QUERY;
50
+ }
51
+ beforeEach(() => {
52
+ vi.clearAllMocks();
53
+ mockResolveGeneId.mockResolvedValue({ geneId: GENE_ID, matched: 'NLRP1' });
54
+ mockFetchProtein.mockResolvedValue(REPRESENTATIVE);
55
+ mockFetchRows.mockResolvedValue([]);
56
+ mockLaunchMSA.mockResolvedValue({ msa: '', tree: '' });
57
+ });
58
+ describe('taxa', () => {
59
+ test('omitted asks for every species the dialog offers, less the query', async () => {
60
+ await doLaunchOrthologs({ self: makeModel(params()) });
61
+ expect(taxaAskedFor()).toEqual(COMMON_SPECIES.map(s => s.taxId)
62
+ .filter(t => t !== HUMAN)
63
+ .sort((a, b) => a - b));
64
+ });
65
+ test('given is taken as written, less the query', async () => {
66
+ await doLaunchOrthologs({
67
+ self: makeModel(params({ taxa: [HUMAN, 10090, 9615] })),
68
+ });
69
+ expect(taxaAskedFor()).toEqual([9615, 10090]);
70
+ });
71
+ test('an empty list is a request for no rows, not a request for all of them', async () => {
72
+ await doLaunchOrthologs({ self: makeModel(params({ taxa: [] })) });
73
+ expect(taxaAskedFor()).toEqual([]);
74
+ });
75
+ });
76
+ describe('the QUERY row', () => {
77
+ test('omitted proteinSequence falls back to the representative protein', async () => {
78
+ await doLaunchOrthologs({ self: makeModel(params()) });
79
+ expect(queryRowSent()).toBe(REPRESENTATIVE.sequence);
80
+ });
81
+ test('a supplied sequence is used, and is cleaned first', async () => {
82
+ await doLaunchOrthologs({
83
+ self: makeModel(params({ proteinSequence: 'MAGG*AWGR&' })),
84
+ });
85
+ expect(queryRowSent()).toBe('MAGGAWGR');
86
+ });
87
+ test('throws when neither a sequence nor a representative is available', async () => {
88
+ mockFetchProtein.mockResolvedValue(undefined);
89
+ await expect(doLaunchOrthologs({ self: makeModel(params()) })).rejects.toThrow(/No query protein/);
90
+ expect(mockLaunchMSA).not.toHaveBeenCalled();
91
+ });
92
+ test('a failed representative lookup does not take down a launch that brought its own sequence', async () => {
93
+ vi.spyOn(console, 'warn').mockImplementation(() => { });
94
+ mockFetchProtein.mockRejectedValue(new Error('429'));
95
+ await doLaunchOrthologs({
96
+ self: makeModel(params({ proteinSequence: REPRESENTATIVE.sequence })),
97
+ });
98
+ expect(queryRowSent()).toBe(REPRESENTATIVE.sequence);
99
+ });
100
+ });
101
+ // The Accession is what afterCreateAutoruns.autoLoadProteinDomains keys the CDD
102
+ // overlay off, and attaching it to a row that is NOT the protein it names draws
103
+ // every domain box at an offset. So the byte-identity guard is the assertion
104
+ // here, in both directions.
105
+ describe('the Accession that drives the domain overlay', () => {
106
+ test('is attached when the query row IS the representative protein', async () => {
107
+ const result = await doLaunchOrthologs({ self: makeModel(params()) });
108
+ expect(queryMetadata(result)).toMatchObject({
109
+ 'Gene ID': GENE_ID,
110
+ Accession: REPRESENTATIVE.accession,
111
+ });
112
+ });
113
+ test('is withheld from a non-representative isoform', async () => {
114
+ const result = await doLaunchOrthologs({
115
+ self: makeModel(params({ proteinSequence: 'MDIFFERENTISOFORM' })),
116
+ });
117
+ expect(queryMetadata(result).Accession).toBeUndefined();
118
+ });
119
+ test('is withheld when the representative lookup failed', async () => {
120
+ vi.spyOn(console, 'warn').mockImplementation(() => { });
121
+ mockFetchProtein.mockRejectedValue(new Error('429'));
122
+ const result = await doLaunchOrthologs({
123
+ self: makeModel(params({ proteinSequence: REPRESENTATIVE.sequence })),
124
+ });
125
+ expect(queryMetadata(result).Accession).toBeUndefined();
126
+ });
127
+ });
@@ -1,6 +1,6 @@
1
1
  export type { MSAFormat } from 'msa-parsers';
2
2
  import type { MafRegion, MsaViewInitState } from './types';
3
- import type { BlastDatabase, BlastProgram, MsaAlgorithm } from '../LaunchMsaView/components/NCBIBlastQuery/consts';
3
+ import type { BlastDatabase, MsaAlgorithm } from '../LaunchMsaView/components/BlastQuery/consts';
4
4
  import type { Feature } from '@jbrowse/core/util';
5
5
  import type { Instance } from '@jbrowse/mobx-state-tree';
6
6
  import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
@@ -12,13 +12,10 @@ export interface IRegion {
12
12
  end: number;
13
13
  }
14
14
  export interface BlastParams {
15
- baseUrl: string;
16
15
  blastDatabase: BlastDatabase;
17
16
  msaAlgorithm: MsaAlgorithm;
18
- blastProgram: BlastProgram;
19
17
  selectedTranscript?: Feature;
20
18
  proteinSequence: string;
21
- rid?: string;
22
19
  }
23
20
  export interface OrthologParams {
24
21
  /** NCBI taxon id of the assembly the query gene came from */