jbrowse-plugin-msaview 2.2.3 → 2.2.4

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 (162) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +229 -0
  3. package/dist/AddHighlightModel/GenomeMouseoverHighlight.js +23 -18
  4. package/dist/AddHighlightModel/GenomeMouseoverHighlight.js.map +1 -1
  5. package/dist/AddHighlightModel/MsaToGenomeHighlight.js +23 -13
  6. package/dist/AddHighlightModel/MsaToGenomeHighlight.js.map +1 -1
  7. package/dist/AddHighlightModel/index.js +8 -1
  8. package/dist/AddHighlightModel/index.js.map +1 -1
  9. package/dist/AddHighlightModel/util.d.ts +2 -2
  10. package/dist/BgzipFastaMsaAdapter/configSchema.d.ts +2 -2
  11. package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js +5 -11
  12. package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js.map +1 -1
  13. package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.js +5 -1
  14. package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.js.map +1 -1
  15. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js +16 -16
  16. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js.map +1 -1
  17. package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js +38 -46
  18. package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js.map +1 -1
  19. package/dist/LaunchMsaView/components/ManualMSALoader/launchView.d.ts +4 -3
  20. package/dist/LaunchMsaView/components/ManualMSALoader/launchView.js +4 -3
  21. package/dist/LaunchMsaView/components/ManualMSALoader/launchView.js.map +1 -1
  22. package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.d.ts +9 -0
  23. package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js +76 -0
  24. package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js.map +1 -0
  25. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js +35 -13
  26. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js.map +1 -1
  27. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js +6 -12
  28. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js.map +1 -1
  29. package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.d.ts +6 -0
  30. package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.js +15 -0
  31. package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.js.map +1 -1
  32. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +12 -34
  33. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js.map +1 -1
  34. package/dist/LaunchMsaView/components/PreLoadedMSA/consts.d.ts +1 -0
  35. package/dist/LaunchMsaView/components/PreLoadedMSA/consts.js +1 -0
  36. package/dist/LaunchMsaView/components/PreLoadedMSA/consts.js.map +1 -1
  37. package/dist/LaunchMsaView/components/TabPanel.d.ts +2 -2
  38. package/dist/LaunchMsaView/components/TranscriptSelector.d.ts +2 -2
  39. package/dist/LaunchMsaView/components/TranscriptSelector.js +3 -6
  40. package/dist/LaunchMsaView/components/TranscriptSelector.js.map +1 -1
  41. package/dist/LaunchMsaView/components/useSWRFeatureSequence.js +6 -4
  42. package/dist/LaunchMsaView/components/useSWRFeatureSequence.js.map +1 -1
  43. package/dist/LaunchMsaView/components/useTranscriptSelection.d.ts +16 -0
  44. package/dist/LaunchMsaView/components/useTranscriptSelection.js +31 -0
  45. package/dist/LaunchMsaView/components/useTranscriptSelection.js.map +1 -0
  46. package/dist/LaunchMsaView/components/util.d.ts +3 -1
  47. package/dist/LaunchMsaView/components/util.js +12 -2
  48. package/dist/LaunchMsaView/components/util.js.map +1 -1
  49. package/dist/LaunchMsaView/util.d.ts +2 -0
  50. package/dist/LaunchMsaView/util.js +16 -4
  51. package/dist/LaunchMsaView/util.js.map +1 -1
  52. package/dist/LaunchMsaViewExtensionPoint/index.d.ts +2 -0
  53. package/dist/LaunchMsaViewExtensionPoint/index.js +31 -0
  54. package/dist/LaunchMsaViewExtensionPoint/index.js.map +1 -0
  55. package/dist/MsaViewPanel/components/ConnectStructureDialog.d.ts +7 -0
  56. package/dist/MsaViewPanel/components/ConnectStructureDialog.js +56 -0
  57. package/dist/MsaViewPanel/components/ConnectStructureDialog.js.map +1 -0
  58. package/dist/MsaViewPanel/components/MsaViewPanel.js +4 -2
  59. package/dist/MsaViewPanel/components/MsaViewPanel.js.map +1 -1
  60. package/dist/MsaViewPanel/doLaunchBlast.d.ts +1 -0
  61. package/dist/MsaViewPanel/doLaunchBlast.js +65 -19
  62. package/dist/MsaViewPanel/doLaunchBlast.js.map +1 -1
  63. package/dist/MsaViewPanel/genomeToMSA.d.ts +6 -0
  64. package/dist/MsaViewPanel/genomeToMSA.js +38 -8
  65. package/dist/MsaViewPanel/genomeToMSA.js.map +1 -1
  66. package/dist/MsaViewPanel/genomeToMSA.test.d.ts +1 -0
  67. package/dist/MsaViewPanel/genomeToMSA.test.js +244 -0
  68. package/dist/MsaViewPanel/genomeToMSA.test.js.map +1 -0
  69. package/dist/MsaViewPanel/model.d.ts +717 -226
  70. package/dist/MsaViewPanel/model.js +467 -39
  71. package/dist/MsaViewPanel/model.js.map +1 -1
  72. package/dist/MsaViewPanel/msaCoordToGenomeCoord.d.ts +7 -2
  73. package/dist/MsaViewPanel/msaCoordToGenomeCoord.js +26 -27
  74. package/dist/MsaViewPanel/msaCoordToGenomeCoord.js.map +1 -1
  75. package/dist/MsaViewPanel/msaCoordToGenomeCoord.test.d.ts +1 -0
  76. package/dist/MsaViewPanel/msaCoordToGenomeCoord.test.js +240 -0
  77. package/dist/MsaViewPanel/msaCoordToGenomeCoord.test.js.map +1 -0
  78. package/dist/MsaViewPanel/msaDataStore.d.ts +14 -0
  79. package/dist/MsaViewPanel/msaDataStore.js +197 -0
  80. package/dist/MsaViewPanel/msaDataStore.js.map +1 -0
  81. package/dist/MsaViewPanel/pairwiseAlignment.d.ts +27 -0
  82. package/dist/MsaViewPanel/pairwiseAlignment.js +776 -0
  83. package/dist/MsaViewPanel/pairwiseAlignment.js.map +1 -0
  84. package/dist/MsaViewPanel/pairwiseAlignment.test.d.ts +1 -0
  85. package/dist/MsaViewPanel/pairwiseAlignment.test.js +112 -0
  86. package/dist/MsaViewPanel/pairwiseAlignment.test.js.map +1 -0
  87. package/dist/MsaViewPanel/structureConnection.d.ts +27 -0
  88. package/dist/MsaViewPanel/structureConnection.js +46 -0
  89. package/dist/MsaViewPanel/structureConnection.js.map +1 -0
  90. package/dist/MsaViewPanel/structureConnection.test.d.ts +1 -0
  91. package/dist/MsaViewPanel/structureConnection.test.js +122 -0
  92. package/dist/MsaViewPanel/structureConnection.test.js.map +1 -0
  93. package/dist/MsaViewPanel/types.d.ts +13 -0
  94. package/dist/MsaViewPanel/types.js +2 -0
  95. package/dist/MsaViewPanel/types.js.map +1 -0
  96. package/dist/MsaViewPanel/util.d.ts +7 -0
  97. package/dist/MsaViewPanel/util.js +10 -0
  98. package/dist/MsaViewPanel/util.js.map +1 -1
  99. package/dist/index.d.ts +5 -5
  100. package/dist/index.js +3 -1
  101. package/dist/index.js.map +1 -1
  102. package/dist/jbrowse-plugin-msaview.umd.production.min.js +39 -90
  103. package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
  104. package/dist/utils/blastCache.d.ts +34 -0
  105. package/dist/utils/blastCache.js +58 -0
  106. package/dist/utils/blastCache.js.map +1 -0
  107. package/dist/utils/fetch.d.ts +1 -1
  108. package/dist/utils/fetch.js +1 -1
  109. package/dist/utils/fetch.js.map +1 -1
  110. package/dist/utils/ncbiBlast.d.ts +1 -5
  111. package/dist/utils/taxonomyNames.d.ts +5 -0
  112. package/dist/utils/taxonomyNames.js +79 -0
  113. package/dist/utils/taxonomyNames.js.map +1 -0
  114. package/dist/utils/types.d.ts +8 -5
  115. package/package.json +50 -54
  116. package/src/AddHighlightModel/GenomeMouseoverHighlight.tsx +37 -21
  117. package/src/AddHighlightModel/MsaToGenomeHighlight.tsx +38 -17
  118. package/src/AddHighlightModel/index.tsx +9 -4
  119. package/src/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.tsx +13 -13
  120. package/src/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.ts +6 -0
  121. package/src/LaunchMsaView/components/LaunchMsaViewDialog.tsx +30 -23
  122. package/src/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.tsx +64 -51
  123. package/src/LaunchMsaView/components/ManualMSALoader/launchView.ts +9 -6
  124. package/src/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.tsx +146 -0
  125. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.tsx +53 -22
  126. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.tsx +8 -13
  127. package/src/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.ts +25 -0
  128. package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +27 -47
  129. package/src/LaunchMsaView/components/PreLoadedMSA/consts.ts +1 -0
  130. package/src/LaunchMsaView/components/TabPanel.tsx +2 -2
  131. package/src/LaunchMsaView/components/TranscriptSelector.tsx +13 -20
  132. package/src/LaunchMsaView/components/useSWRFeatureSequence.ts +5 -5
  133. package/src/LaunchMsaView/components/useTranscriptSelection.ts +48 -0
  134. package/src/LaunchMsaView/components/util.ts +17 -2
  135. package/src/LaunchMsaView/index.ts +1 -1
  136. package/src/LaunchMsaView/util.ts +25 -6
  137. package/src/LaunchMsaViewExtensionPoint/index.ts +74 -0
  138. package/src/MsaViewPanel/components/ConnectStructureDialog.tsx +156 -0
  139. package/src/MsaViewPanel/components/MsaViewPanel.tsx +6 -1
  140. package/src/MsaViewPanel/doLaunchBlast.ts +83 -23
  141. package/src/MsaViewPanel/genomeToMSA.test.ts +281 -0
  142. package/src/MsaViewPanel/genomeToMSA.ts +43 -10
  143. package/src/MsaViewPanel/model.ts +590 -43
  144. package/src/MsaViewPanel/msaCoordToGenomeCoord.test.ts +256 -0
  145. package/src/MsaViewPanel/msaCoordToGenomeCoord.ts +43 -29
  146. package/src/MsaViewPanel/msaDataStore.ts +236 -0
  147. package/src/MsaViewPanel/pairwiseAlignment.test.ts +140 -0
  148. package/src/MsaViewPanel/pairwiseAlignment.ts +818 -0
  149. package/src/MsaViewPanel/structureConnection.test.ts +143 -0
  150. package/src/MsaViewPanel/structureConnection.ts +72 -0
  151. package/src/MsaViewPanel/types.ts +14 -0
  152. package/src/MsaViewPanel/util.ts +11 -0
  153. package/src/index.ts +3 -1
  154. package/src/utils/blastCache.ts +114 -0
  155. package/src/utils/fetch.ts +1 -1
  156. package/src/utils/taxonomyNames.ts +111 -0
  157. package/src/utils/types.ts +9 -1
  158. package/dist/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.d.ts +0 -5
  159. package/dist/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.js +0 -16
  160. package/dist/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.js.map +0 -1
  161. package/dist/out.js +0 -55381
  162. package/src/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.ts +0 -25
@@ -1,35 +1,33 @@
1
- /**
2
- * Convert gapped MSA column coordinate to ungapped sequence coordinate
3
- * This is the inverse of ungappedCoordMap
4
- */
5
- function gappedToUngappedCoord(seq, gappedPos) {
6
- let ungappedPos = 0;
7
- for (let i = 0; i < gappedPos && i < seq.length; i++) {
8
- if (seq[i] !== '-') {
9
- ungappedPos++;
10
- }
11
- }
12
- return ungappedPos;
13
- }
1
+ import { gappedToUngappedPosition } from './structureConnection';
14
2
  export function msaCoordToGenomeCoord({ model, coord: mouseCol, }) {
15
- const { querySeqName, transcriptToMsaMap } = model;
16
- if (transcriptToMsaMap === undefined) {
3
+ const { querySeqName, transcriptToMsaMap, mafRegion } = model;
4
+ // Get the query sequence
5
+ const queryRow = model.rows.find(f => f[0] === querySeqName);
6
+ const querySeq = queryRow?.[1];
7
+ if (!querySeq) {
17
8
  return undefined;
18
9
  }
19
- else {
20
- // Get the query sequence
21
- const queryRow = model.rows.find(f => f[0] === querySeqName);
22
- const querySeq = queryRow?.[1];
23
- if (!querySeq) {
24
- return undefined;
25
- }
26
- // Check if the position in the query sequence is a gap
27
- if (querySeq[mouseCol] === '-') {
10
+ // Convert gapped MSA column to ungapped sequence coordinate
11
+ // Returns undefined if the position is a gap
12
+ const ungappedPos = gappedToUngappedPosition(querySeq, mouseCol);
13
+ if (ungappedPos === undefined) {
14
+ return undefined;
15
+ }
16
+ // Handle MAF region mapping
17
+ if (mafRegion) {
18
+ const genomePos = mafRegion.start + ungappedPos;
19
+ // Check if position is within the region
20
+ if (genomePos >= mafRegion.end) {
28
21
  return undefined;
29
22
  }
30
- // Convert gapped MSA column to ungapped sequence coordinate
31
- const ungappedPos = gappedToUngappedCoord(querySeq, mouseCol);
32
- // Use the ungapped position to look up in the p2g map
23
+ return {
24
+ refName: mafRegion.refName,
25
+ start: genomePos,
26
+ end: genomePos + 1,
27
+ };
28
+ }
29
+ // Handle transcript mapping (original behavior)
30
+ if (transcriptToMsaMap) {
33
31
  const { refName, p2g } = transcriptToMsaMap;
34
32
  const s = p2g[ungappedPos];
35
33
  const e = p2g[ungappedPos + 1];
@@ -41,5 +39,6 @@ export function msaCoordToGenomeCoord({ model, coord: mouseCol, }) {
41
39
  }
42
40
  : undefined;
43
41
  }
42
+ return undefined;
44
43
  }
45
44
  //# sourceMappingURL=msaCoordToGenomeCoord.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"msaCoordToGenomeCoord.js","sourceRoot":"","sources":["../../src/MsaViewPanel/msaCoordToGenomeCoord.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,SAAS,qBAAqB,CAAC,GAAW,EAAE,SAAiB;IAC3D,IAAI,WAAW,GAAG,CAAC,CAAA;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrD,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACnB,WAAW,EAAE,CAAA;QACf,CAAC;IACH,CAAC;IACD,OAAO,WAAW,CAAA;AACpB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EACpC,KAAK,EACL,KAAK,EAAE,QAAQ,GAIhB;IACC,MAAM,EAAE,YAAY,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAA;IAClD,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,SAAS,CAAA;IAClB,CAAC;SAAM,CAAC;QACN,yBAAyB;QACzB,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,CAAA;QAC5D,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAA;QAC9B,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,uDAAuD;QACvD,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,GAAG,EAAE,CAAC;YAC/B,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,4DAA4D;QAC5D,MAAM,WAAW,GAAG,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QAE7D,sDAAsD;QACtD,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,kBAAkB,CAAA;QAC3C,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAA;QAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,CAAA;QAC9B,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS;YACvC,CAAC,CAAC;gBACE,OAAO;gBACP,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;gBACrB,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;aACpB;YACH,CAAC,CAAC,SAAS,CAAA;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"msaCoordToGenomeCoord.js","sourceRoot":"","sources":["../../src/MsaViewPanel/msaCoordToGenomeCoord.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAIhE,MAAM,UAAU,qBAAqB,CAAC,EACpC,KAAK,EACL,KAAK,EAAE,QAAQ,GAchB;IACC,MAAM,EAAE,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IAE7D,yBAAyB;IACzB,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,CAAA;IAC5D,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAA;IAC9B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,4DAA4D;IAC5D,6CAA6C;IAC7C,MAAM,WAAW,GAAG,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAChE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,4BAA4B;IAC5B,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,GAAG,WAAW,CAAA;QAC/C,yCAAyC;QACzC,IAAI,SAAS,IAAI,SAAS,CAAC,GAAG,EAAE,CAAC;YAC/B,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,OAAO;YACL,OAAO,EAAE,SAAS,CAAC,OAAO;YAC1B,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,SAAS,GAAG,CAAC;SACnB,CAAA;IACH,CAAC;IAED,gDAAgD;IAChD,IAAI,kBAAkB,EAAE,CAAC;QACvB,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,kBAAkB,CAAA;QAC3C,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAA;QAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,CAAA;QAC9B,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS;YACvC,CAAC,CAAC;gBACE,OAAO;gBACP,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;gBACrB,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;aACpB;YACH,CAAC,CAAC,SAAS,CAAA;IACf,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,240 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { msaCoordToGenomeCoord } from './msaCoordToGenomeCoord';
3
+ describe('msaCoordToGenomeCoord', () => {
4
+ test('returns undefined when neither transcriptToMsaMap nor mafRegion is defined', () => {
5
+ const model = {
6
+ querySeqName: 'QUERY',
7
+ transcriptToMsaMap: undefined,
8
+ mafRegion: undefined,
9
+ rows: [['QUERY', 'MKAA']],
10
+ };
11
+ const result = msaCoordToGenomeCoord({ model, coord: 0 });
12
+ expect(result).toBeUndefined();
13
+ });
14
+ test('returns undefined when query row is not found', () => {
15
+ const model = {
16
+ querySeqName: 'QUERY',
17
+ transcriptToMsaMap: {
18
+ refName: 'chr1',
19
+ p2g: { 0: 100, 1: 103 },
20
+ },
21
+ rows: [['OTHER', 'MKAA']],
22
+ };
23
+ const result = msaCoordToGenomeCoord({ model, coord: 0 });
24
+ expect(result).toBeUndefined();
25
+ });
26
+ test('returns undefined when coord is a gap', () => {
27
+ const model = {
28
+ querySeqName: 'QUERY',
29
+ transcriptToMsaMap: {
30
+ refName: 'chr1',
31
+ p2g: { 0: 100, 1: 103 },
32
+ },
33
+ rows: [['QUERY', 'M-KA']],
34
+ };
35
+ // Position 1 is a gap
36
+ const result = msaCoordToGenomeCoord({ model, coord: 1 });
37
+ expect(result).toBeUndefined();
38
+ });
39
+ test('returns genome region for valid non-gap position', () => {
40
+ const model = {
41
+ querySeqName: 'QUERY',
42
+ transcriptToMsaMap: {
43
+ refName: 'chr1',
44
+ p2g: { 0: 100, 1: 103, 2: 106, 3: 109 },
45
+ },
46
+ rows: [['QUERY', 'MKAA']],
47
+ };
48
+ // Position 0 (M) should map to ungapped 0, genome 100-103
49
+ const result = msaCoordToGenomeCoord({ model, coord: 0 });
50
+ expect(result).toEqual({
51
+ refName: 'chr1',
52
+ start: 100,
53
+ end: 103,
54
+ });
55
+ });
56
+ test('handles gapped sequence correctly', () => {
57
+ const model = {
58
+ querySeqName: 'QUERY',
59
+ transcriptToMsaMap: {
60
+ refName: 'chr1',
61
+ p2g: { 0: 100, 1: 103, 2: 106, 3: 109 },
62
+ },
63
+ rows: [['QUERY', 'M-K-AA']],
64
+ // 012345 gapped positions
65
+ // 0 1 23 ungapped positions
66
+ };
67
+ // Gapped position 2 (K) = ungapped 1
68
+ const result = msaCoordToGenomeCoord({ model, coord: 2 });
69
+ expect(result).toEqual({
70
+ refName: 'chr1',
71
+ start: 103,
72
+ end: 106,
73
+ });
74
+ // Gapped position 4 (first A) = ungapped 2
75
+ const result2 = msaCoordToGenomeCoord({ model, coord: 4 });
76
+ expect(result2).toEqual({
77
+ refName: 'chr1',
78
+ start: 106,
79
+ end: 109,
80
+ });
81
+ });
82
+ test('returns undefined when p2g mapping is incomplete', () => {
83
+ const model = {
84
+ querySeqName: 'QUERY',
85
+ transcriptToMsaMap: {
86
+ refName: 'chr1',
87
+ p2g: { 0: 100 }, // Missing entry for position 1
88
+ },
89
+ rows: [['QUERY', 'MKAA']],
90
+ };
91
+ // Position 0 needs p2g[0] and p2g[1], but p2g[1] is missing
92
+ const result = msaCoordToGenomeCoord({ model, coord: 0 });
93
+ expect(result).toBeUndefined();
94
+ });
95
+ test('handles reverse strand (start > end in p2g)', () => {
96
+ const model = {
97
+ querySeqName: 'QUERY',
98
+ transcriptToMsaMap: {
99
+ refName: 'chr1',
100
+ p2g: { 0: 109, 1: 106, 2: 103, 3: 100 }, // Reverse strand
101
+ },
102
+ rows: [['QUERY', 'MKAA']],
103
+ };
104
+ // Should return min/max correctly
105
+ const result = msaCoordToGenomeCoord({ model, coord: 0 });
106
+ expect(result).toEqual({
107
+ refName: 'chr1',
108
+ start: 106, // min(109, 106)
109
+ end: 109, // max(109, 106)
110
+ });
111
+ });
112
+ test('returns undefined for out of bounds coord', () => {
113
+ const model = {
114
+ querySeqName: 'QUERY',
115
+ transcriptToMsaMap: {
116
+ refName: 'chr1',
117
+ p2g: { 0: 100, 1: 103 },
118
+ },
119
+ rows: [['QUERY', 'MK']],
120
+ };
121
+ // Position 10 is out of bounds
122
+ const result = msaCoordToGenomeCoord({ model, coord: 10 });
123
+ expect(result).toBeUndefined();
124
+ });
125
+ test('works with multiple rows, uses querySeqName', () => {
126
+ const model = {
127
+ querySeqName: 'SEQ2',
128
+ transcriptToMsaMap: {
129
+ refName: 'chr1',
130
+ p2g: { 0: 200, 1: 203 },
131
+ },
132
+ rows: [
133
+ ['SEQ1', 'AAAA'],
134
+ ['SEQ2', 'MKAA'],
135
+ ['SEQ3', 'LLLL'],
136
+ ],
137
+ };
138
+ const result = msaCoordToGenomeCoord({ model, coord: 0 });
139
+ expect(result).toEqual({
140
+ refName: 'chr1',
141
+ start: 200,
142
+ end: 203,
143
+ });
144
+ });
145
+ // MAF region tests
146
+ describe('mafRegion', () => {
147
+ test('returns genome position for mafRegion mapping', () => {
148
+ const model = {
149
+ querySeqName: 'hg38.chr1',
150
+ transcriptToMsaMap: undefined,
151
+ mafRegion: {
152
+ refName: 'chr1',
153
+ start: 1000,
154
+ end: 1010,
155
+ assemblyName: 'hg38',
156
+ },
157
+ rows: [['hg38.chr1', 'ACGTACGTAC']],
158
+ };
159
+ // Position 0 should map to genome 1000
160
+ const result = msaCoordToGenomeCoord({ model, coord: 0 });
161
+ expect(result).toEqual({
162
+ refName: 'chr1',
163
+ start: 1000,
164
+ end: 1001,
165
+ });
166
+ // Position 5 should map to genome 1005
167
+ const result2 = msaCoordToGenomeCoord({ model, coord: 5 });
168
+ expect(result2).toEqual({
169
+ refName: 'chr1',
170
+ start: 1005,
171
+ end: 1006,
172
+ });
173
+ });
174
+ test('handles gaps in mafRegion sequence', () => {
175
+ const model = {
176
+ querySeqName: 'hg38.chr1',
177
+ transcriptToMsaMap: undefined,
178
+ mafRegion: {
179
+ refName: 'chr1',
180
+ start: 1000,
181
+ end: 1008,
182
+ assemblyName: 'hg38',
183
+ },
184
+ rows: [['hg38.chr1', 'AC--GTAC']],
185
+ // Gapped positions: 0 1 2 3 4 5 6 7
186
+ // Ungapped: 0 1 2 3 4 5
187
+ };
188
+ // Position 2 is a gap, should return undefined
189
+ const result = msaCoordToGenomeCoord({ model, coord: 2 });
190
+ expect(result).toBeUndefined();
191
+ // Position 4 (G) = ungapped 2 = genome 1002
192
+ const result2 = msaCoordToGenomeCoord({ model, coord: 4 });
193
+ expect(result2).toEqual({
194
+ refName: 'chr1',
195
+ start: 1002,
196
+ end: 1003,
197
+ });
198
+ });
199
+ test('returns undefined when position exceeds mafRegion end', () => {
200
+ const model = {
201
+ querySeqName: 'hg38.chr1',
202
+ transcriptToMsaMap: undefined,
203
+ mafRegion: {
204
+ refName: 'chr1',
205
+ start: 1000,
206
+ end: 1005,
207
+ assemblyName: 'hg38',
208
+ },
209
+ rows: [['hg38.chr1', 'ACGTACGTAC']], // 10 chars but region is only 5bp
210
+ };
211
+ // Position 8 would be ungapped 8 = genome 1008, but region ends at 1005
212
+ const result = msaCoordToGenomeCoord({ model, coord: 8 });
213
+ expect(result).toBeUndefined();
214
+ });
215
+ test('mafRegion takes precedence over transcriptToMsaMap', () => {
216
+ const model = {
217
+ querySeqName: 'hg38.chr1',
218
+ transcriptToMsaMap: {
219
+ refName: 'chr2',
220
+ p2g: { 0: 5000, 1: 5003 },
221
+ },
222
+ mafRegion: {
223
+ refName: 'chr1',
224
+ start: 1000,
225
+ end: 1010,
226
+ assemblyName: 'hg38',
227
+ },
228
+ rows: [['hg38.chr1', 'ACGTACGTAC']],
229
+ };
230
+ // Should use mafRegion, not transcriptToMsaMap
231
+ const result = msaCoordToGenomeCoord({ model, coord: 0 });
232
+ expect(result).toEqual({
233
+ refName: 'chr1',
234
+ start: 1000,
235
+ end: 1001,
236
+ });
237
+ });
238
+ });
239
+ });
240
+ //# sourceMappingURL=msaCoordToGenomeCoord.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"msaCoordToGenomeCoord.test.js","sourceRoot":"","sources":["../../src/MsaViewPanel/msaCoordToGenomeCoord.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export declare function generateDataStoreId(): string;
2
+ export declare function storeMsaData(id: string, data: {
3
+ msa?: string;
4
+ tree?: string;
5
+ treeMetadata?: string;
6
+ }): Promise<boolean>;
7
+ export declare function retrieveMsaData(id: string): Promise<{
8
+ msa?: string;
9
+ tree?: string;
10
+ treeMetadata?: string;
11
+ } | undefined>;
12
+ export declare function deleteMsaData(id: string): Promise<void>;
13
+ export declare function cleanupOldData(maxAgeMs?: number): Promise<number>;
14
+ export declare function isIndexedDBAvailable(): boolean;
@@ -0,0 +1,197 @@
1
+ const DB_NAME = 'jbrowse-msaview-data';
2
+ const DB_VERSION = 1;
3
+ const STORE_NAME = 'msa-data';
4
+ let dbPromise;
5
+ let indexedDBAvailable;
6
+ function checkIndexedDBAvailable() {
7
+ if (indexedDBAvailable !== undefined) {
8
+ return indexedDBAvailable;
9
+ }
10
+ try {
11
+ // Check if indexedDB exists and is accessible
12
+ if (typeof indexedDB === 'undefined') {
13
+ indexedDBAvailable = false;
14
+ return false;
15
+ }
16
+ // Try to open a test database to verify IndexedDB is working
17
+ // This can fail in private browsing mode in some browsers
18
+ indexedDBAvailable = true;
19
+ return true;
20
+ }
21
+ catch {
22
+ indexedDBAvailable = false;
23
+ return false;
24
+ }
25
+ }
26
+ async function openDB() {
27
+ if (!checkIndexedDBAvailable()) {
28
+ return undefined;
29
+ }
30
+ if (dbPromise) {
31
+ return dbPromise;
32
+ }
33
+ dbPromise = new Promise(resolve => {
34
+ try {
35
+ const request = indexedDB.open(DB_NAME, DB_VERSION);
36
+ request.addEventListener('error', () => {
37
+ // IndexedDB may be blocked in private browsing mode
38
+ console.warn('IndexedDB unavailable - MSA data will not persist across page refreshes');
39
+ indexedDBAvailable = false;
40
+ resolve(undefined);
41
+ });
42
+ request.onsuccess = () => {
43
+ resolve(request.result);
44
+ };
45
+ request.onupgradeneeded = event => {
46
+ const db = event.target.result;
47
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
48
+ const store = db.createObjectStore(STORE_NAME, { keyPath: 'id' });
49
+ store.createIndex('timestamp', 'timestamp', { unique: false });
50
+ }
51
+ };
52
+ }
53
+ catch (e) {
54
+ console.warn('Failed to open IndexedDB:', e);
55
+ indexedDBAvailable = false;
56
+ resolve(undefined);
57
+ }
58
+ });
59
+ return dbPromise;
60
+ }
61
+ export function generateDataStoreId() {
62
+ return `msa-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
63
+ }
64
+ export async function storeMsaData(id, data) {
65
+ const db = await openDB();
66
+ if (!db) {
67
+ // IndexedDB not available, silently skip storage
68
+ return false;
69
+ }
70
+ return new Promise(resolve => {
71
+ try {
72
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
73
+ const store = transaction.objectStore(STORE_NAME);
74
+ const storedData = {
75
+ id,
76
+ msa: data.msa,
77
+ tree: data.tree,
78
+ treeMetadata: data.treeMetadata,
79
+ timestamp: Date.now(),
80
+ };
81
+ const request = store.put(storedData);
82
+ request.addEventListener('error', () => {
83
+ // Log but don't fail - storage is best-effort
84
+ console.warn('Failed to store MSA data:', request.error);
85
+ resolve(false);
86
+ });
87
+ request.onsuccess = () => {
88
+ resolve(true);
89
+ };
90
+ }
91
+ catch (e) {
92
+ console.warn('Failed to store MSA data:', e);
93
+ resolve(false);
94
+ }
95
+ });
96
+ }
97
+ export async function retrieveMsaData(id) {
98
+ const db = await openDB();
99
+ if (!db) {
100
+ return undefined;
101
+ }
102
+ return new Promise(resolve => {
103
+ try {
104
+ const transaction = db.transaction(STORE_NAME, 'readonly');
105
+ const store = transaction.objectStore(STORE_NAME);
106
+ const request = store.get(id);
107
+ request.addEventListener('error', () => {
108
+ console.warn('Failed to retrieve MSA data:', request.error);
109
+ resolve(undefined);
110
+ });
111
+ request.onsuccess = () => {
112
+ const result = request.result;
113
+ if (result) {
114
+ resolve({
115
+ msa: result.msa,
116
+ tree: result.tree,
117
+ treeMetadata: result.treeMetadata,
118
+ });
119
+ }
120
+ else {
121
+ resolve(undefined);
122
+ }
123
+ };
124
+ }
125
+ catch (e) {
126
+ console.warn('Failed to retrieve MSA data:', e);
127
+ resolve(undefined);
128
+ }
129
+ });
130
+ }
131
+ export async function deleteMsaData(id) {
132
+ const db = await openDB();
133
+ if (!db) {
134
+ return;
135
+ }
136
+ return new Promise(resolve => {
137
+ try {
138
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
139
+ const store = transaction.objectStore(STORE_NAME);
140
+ const request = store.delete(id);
141
+ request.addEventListener('error', () => {
142
+ console.warn('Failed to delete MSA data:', request.error);
143
+ resolve();
144
+ });
145
+ request.onsuccess = () => {
146
+ resolve();
147
+ };
148
+ }
149
+ catch (e) {
150
+ console.warn('Failed to delete MSA data:', e);
151
+ resolve();
152
+ }
153
+ });
154
+ }
155
+ // Clean up entries older than the specified age (default 7 days)
156
+ export async function cleanupOldData(maxAgeMs = 7 * 24 * 60 * 60 * 1000) {
157
+ const db = await openDB();
158
+ if (!db) {
159
+ return 0;
160
+ }
161
+ const cutoffTime = Date.now() - maxAgeMs;
162
+ return new Promise(resolve => {
163
+ try {
164
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
165
+ const store = transaction.objectStore(STORE_NAME);
166
+ const index = store.index('timestamp');
167
+ const range = IDBKeyRange.upperBound(cutoffTime);
168
+ const request = index.openCursor(range);
169
+ let deletedCount = 0;
170
+ request.addEventListener('error', () => {
171
+ console.warn('Failed to cleanup old MSA data:', request.error);
172
+ resolve(deletedCount);
173
+ });
174
+ request.onsuccess = event => {
175
+ const cursor = event.target
176
+ .result;
177
+ if (cursor) {
178
+ cursor.delete();
179
+ deletedCount++;
180
+ cursor.continue();
181
+ }
182
+ else {
183
+ resolve(deletedCount);
184
+ }
185
+ };
186
+ }
187
+ catch (e) {
188
+ console.warn('Failed to cleanup old MSA data:', e);
189
+ resolve(0);
190
+ }
191
+ });
192
+ }
193
+ // Check if IndexedDB storage is available
194
+ export function isIndexedDBAvailable() {
195
+ return checkIndexedDBAvailable();
196
+ }
197
+ //# sourceMappingURL=msaDataStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"msaDataStore.js","sourceRoot":"","sources":["../../src/MsaViewPanel/msaDataStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ interface AlignmentResult {
2
+ alignedSeq1: string;
3
+ alignedSeq2: string;
4
+ score: number;
5
+ }
6
+ export interface AlignmentRow {
7
+ id: string;
8
+ seq: string;
9
+ }
10
+ export interface PairwiseAlignment {
11
+ consensus: string;
12
+ alns: readonly [AlignmentRow, AlignmentRow];
13
+ }
14
+ /**
15
+ * Needleman-Wunsch global alignment algorithm
16
+ */
17
+ export declare function needlemanWunsch(seq1: string, seq2: string, gapOpen?: number, gapExtend?: number): AlignmentResult;
18
+ export declare function runPairwiseAlignment(seq1: string, seq2: string): PairwiseAlignment;
19
+ /**
20
+ * Build coordinate mappings from a pairwise alignment
21
+ * Maps between ungapped positions in seq1 and seq2
22
+ */
23
+ export declare function buildAlignmentMaps(pairwiseAlignment: PairwiseAlignment): {
24
+ seq1ToSeq2: Map<number, number>;
25
+ seq2ToSeq1: Map<number, number>;
26
+ };
27
+ export {};