jbrowse-plugin-msaview 2.5.0 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/LaunchMsaViewExtensionPoint/index.js +2 -1
  2. package/dist/MsaViewPanel/afterCreateAutoruns.d.ts +7 -0
  3. package/dist/MsaViewPanel/afterCreateAutoruns.js +31 -0
  4. package/dist/MsaViewPanel/loadProteinDomains.d.ts +16 -0
  5. package/dist/MsaViewPanel/loadProteinDomains.js +33 -0
  6. package/dist/MsaViewPanel/model.d.ts +189 -158
  7. package/dist/MsaViewPanel/model.js +14 -4
  8. package/dist/jbrowse-plugin-msaview.umd.production.min.js +27 -27
  9. package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
  10. package/dist/utils/domainCache.d.ts +8 -0
  11. package/dist/utils/domainCache.js +28 -0
  12. package/dist/utils/eutils.d.ts +3 -0
  13. package/dist/utils/eutils.js +14 -0
  14. package/dist/utils/msa.js +18 -15
  15. package/dist/utils/ncbiBlast.js +22 -24
  16. package/dist/utils/ncbiDomains.d.ts +39 -0
  17. package/dist/utils/ncbiDomains.js +154 -0
  18. package/dist/utils/poll.d.ts +11 -0
  19. package/dist/utils/poll.js +19 -0
  20. package/dist/utils/taxonomyNames.js +2 -1
  21. package/dist/version.d.ts +1 -1
  22. package/dist/version.js +1 -1
  23. package/package.json +14 -11
  24. package/src/LaunchMsaViewExtensionPoint/index.ts +3 -0
  25. package/src/MsaViewPanel/afterCreateAutoruns.ts +32 -0
  26. package/src/MsaViewPanel/loadProteinDomains.ts +57 -0
  27. package/src/MsaViewPanel/model.ts +19 -3
  28. package/src/utils/domainCache.ts +44 -0
  29. package/src/utils/eutils.ts +16 -0
  30. package/src/utils/msa.ts +18 -16
  31. package/src/utils/ncbiBlast.ts +27 -31
  32. package/src/utils/ncbiDomains.ts +171 -0
  33. package/src/utils/poll.ts +28 -0
  34. package/src/utils/taxonomyNames.ts +3 -1
  35. package/src/version.ts +1 -1
@@ -1,7 +1,7 @@
1
1
  export default function LaunchMsaViewExtensionPointF(pluginManager) {
2
2
  pluginManager.addToExtensionPoint('LaunchView-MsaView',
3
3
  // @ts-expect-error
4
- ({ session, data, msaFileLocation, treeFileLocation, connectedViewId, connectedFeature, displayName, colorSchemeName, colWidth, rowHeight, treeAreaWidth, treeWidth, drawNodeBubbles, labelsAlignRight, showBranchLen, querySeqName, }) => {
4
+ ({ session, data, msaFileLocation, treeFileLocation, connectedViewId, connectedFeature, displayName, colorSchemeName, colWidth, rowHeight, treeAreaWidth, treeWidth, drawNodeBubbles, labelsAlignRight, showBranchLen, querySeqName, highlightColumns, }) => {
5
5
  if (!data && !msaFileLocation) {
6
6
  throw new Error('No MSA data or file location provided when launching MSA view');
7
7
  }
@@ -18,6 +18,7 @@ export default function LaunchMsaViewExtensionPointF(pluginManager) {
18
18
  drawNodeBubbles,
19
19
  labelsAlignRight,
20
20
  showBranchLen,
21
+ highlightColumns,
21
22
  init: {
22
23
  msaData: data?.msa,
23
24
  treeData: data?.tree,
@@ -2,6 +2,13 @@ import type { JBrowsePluginMsaViewModel } from './model';
2
2
  export declare function loadStoredData(self: JBrowsePluginMsaViewModel): void;
3
3
  export declare function storeDataToIndexedDB(self: JBrowsePluginMsaViewModel): void;
4
4
  export declare function launchBlastIfNeeded(self: JBrowsePluginMsaViewModel): void;
5
+ /**
6
+ * Once an accession-bearing alignment is present (fresh from BLAST or restored
7
+ * from cache), fetch NCBI CDD domains for those accessions and overlay them.
8
+ * Runs once per view; the domainsRequested guard prevents refiring when NCBI
9
+ * returns no domains (which leaves interProAnnotations undefined).
10
+ */
11
+ export declare function autoLoadProteinDomains(self: JBrowsePluginMsaViewModel): void;
5
12
  export declare function processInit(self: JBrowsePluginMsaViewModel): void;
6
13
  /**
7
14
  * Mirror the connected genome view's hover position onto the MSA's hovered
@@ -1,6 +1,7 @@
1
1
  import { getSession } from '@jbrowse/core/util';
2
2
  import { doLaunchBlast } from './doLaunchBlast';
3
3
  import { genomeToMSA } from './genomeToMSA';
4
+ import { loadProteinDomains } from './loadProteinDomains';
4
5
  import { cleanupOldData, generateDataStoreId, retrieveMsaData, storeMsaData, } from './msaDataStore';
5
6
  import { gappedToUngappedPosition, getProteinViews, } from './structureConnection';
6
7
  import { getUniprotIdFromAlphaFoldUrl } from './util';
@@ -18,6 +19,9 @@ export function loadStoredData(self) {
18
19
  if (storedData.tree) {
19
20
  self.setTree(storedData.tree);
20
21
  }
22
+ if (storedData.treeMetadata) {
23
+ self.setTreeMetadata(storedData.treeMetadata);
24
+ }
21
25
  }
22
26
  }
23
27
  catch (e) {
@@ -84,6 +88,33 @@ export function launchBlastIfNeeded(self) {
84
88
  })();
85
89
  }
86
90
  }
91
+ /**
92
+ * Once an accession-bearing alignment is present (fresh from BLAST or restored
93
+ * from cache), fetch NCBI CDD domains for those accessions and overlay them.
94
+ * Runs once per view; the domainsRequested guard prevents refiring when NCBI
95
+ * returns no domains (which leaves interProAnnotations undefined).
96
+ */
97
+ export function autoLoadProteinDomains(self) {
98
+ const { rows, domainsRequested, interProAnnotations } = self;
99
+ const hasAccessions = self.data.treeMetadata?.includes('"Accession"') ?? false;
100
+ if (rows.length > 0 &&
101
+ hasAccessions &&
102
+ !interProAnnotations &&
103
+ !domainsRequested) {
104
+ self.setDomainsRequested(true);
105
+ void (async () => {
106
+ try {
107
+ await loadProteinDomains(self);
108
+ }
109
+ catch (e) {
110
+ console.error('[msaview-domains] auto-load failed:', e);
111
+ }
112
+ finally {
113
+ self.setProgress('');
114
+ }
115
+ })();
116
+ }
117
+ }
87
118
  export function processInit(self) {
88
119
  const { init } = self;
89
120
  if (init) {
@@ -0,0 +1,16 @@
1
+ import type { InterProScanResults } from 'react-msaview';
2
+ interface DomainModel {
3
+ data: {
4
+ treeMetadata?: string;
5
+ };
6
+ setProgress: (arg: string) => void;
7
+ setDomains: (data: Record<string, InterProScanResults>) => void;
8
+ }
9
+ /**
10
+ * Overlay protein domains on the alignment using NCBI's pre-computed CDD
11
+ * annotations. The BLAST workflow stores each hit's accession in treeMetadata,
12
+ * so we look those up via efetch and key the results by MSA row name (which is
13
+ * what react-msaview matches domains against).
14
+ */
15
+ export declare function loadProteinDomains(self: DomainModel): Promise<void>;
16
+ export {};
@@ -0,0 +1,33 @@
1
+ import { fetchProteinDomains } from '../utils/ncbiDomains';
2
+ /**
3
+ * Overlay protein domains on the alignment using NCBI's pre-computed CDD
4
+ * annotations. The BLAST workflow stores each hit's accession in treeMetadata,
5
+ * so we look those up via efetch and key the results by MSA row name (which is
6
+ * what react-msaview matches domains against).
7
+ */
8
+ export async function loadProteinDomains(self) {
9
+ const metadataJson = self.data.treeMetadata;
10
+ if (!metadataJson) {
11
+ throw new Error('No sequence metadata available to look up domains');
12
+ }
13
+ const metadata = JSON.parse(metadataJson);
14
+ const rowAccessions = Object.entries(metadata)
15
+ .map(([rowName, meta]) => ({ rowName, accession: meta.Accession }))
16
+ .filter((r) => !!r.accession);
17
+ if (rowAccessions.length === 0) {
18
+ throw new Error('No NCBI accessions found in alignment rows');
19
+ }
20
+ self.setProgress(`Fetching protein domains from NCBI for ${rowAccessions.length} sequences...`);
21
+ const byAccession = await fetchProteinDomains(rowAccessions.map(r => r.accession));
22
+ const annotations = {};
23
+ for (const { rowName, accession } of rowAccessions) {
24
+ const matches = byAccession.get(accession);
25
+ if (matches && matches.length > 0) {
26
+ annotations[rowName] = { matches, xref: [{ id: rowName }] };
27
+ }
28
+ }
29
+ if (Object.keys(annotations).length === 0) {
30
+ throw new Error('No CDD domain annotations found for these proteins');
31
+ }
32
+ self.setDomains(annotations);
33
+ }