jbrowse-plugin-msaview 2.2.0 → 2.2.2

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 (131) hide show
  1. package/dist/BgzipFastaMsaAdapter/BgzipFastaMsaAdapter.d.ts +10 -0
  2. package/dist/BgzipFastaMsaAdapter/BgzipFastaMsaAdapter.js +64 -0
  3. package/dist/BgzipFastaMsaAdapter/BgzipFastaMsaAdapter.js.map +1 -0
  4. package/dist/BgzipFastaMsaAdapter/configSchema.d.ts +7 -0
  5. package/dist/BgzipFastaMsaAdapter/configSchema.js +13 -0
  6. package/dist/BgzipFastaMsaAdapter/configSchema.js.map +1 -0
  7. package/dist/BgzipFastaMsaAdapter/index.d.ts +2 -0
  8. package/dist/BgzipFastaMsaAdapter/index.js +15 -0
  9. package/dist/BgzipFastaMsaAdapter/index.js.map +1 -0
  10. package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js.map +1 -1
  11. package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.d.ts +1 -1
  12. package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.js +3 -23
  13. package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.js.map +1 -1
  14. package/dist/LaunchMsaView/components/EnsemblGeneTree/util.d.ts +1 -4
  15. package/dist/LaunchMsaView/components/EnsemblGeneTree/util.js +1 -37
  16. package/dist/LaunchMsaView/components/EnsemblGeneTree/util.js.map +1 -1
  17. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.d.ts +1 -1
  18. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js +21 -16
  19. package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js.map +1 -1
  20. package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js +1 -1
  21. package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js.map +1 -1
  22. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js +12 -8
  23. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js.map +1 -1
  24. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js +1 -1
  25. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js.map +1 -1
  26. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.js +8 -7
  27. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.js.map +1 -1
  28. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBISettingsDialog.js +1 -1
  29. package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBISettingsDialog.js.map +1 -1
  30. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +87 -63
  31. package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js.map +1 -1
  32. package/dist/LaunchMsaView/components/PreLoadedMSA/consts.d.ts +7 -0
  33. package/dist/LaunchMsaView/components/PreLoadedMSA/consts.js +8 -0
  34. package/dist/LaunchMsaView/components/PreLoadedMSA/consts.js.map +1 -0
  35. package/dist/LaunchMsaView/components/PreLoadedMSA/fetchMSAData.d.ts +12 -0
  36. package/dist/LaunchMsaView/components/PreLoadedMSA/fetchMSAData.js +12 -0
  37. package/dist/LaunchMsaView/components/PreLoadedMSA/fetchMSAData.js.map +1 -0
  38. package/dist/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.d.ts +5 -0
  39. package/dist/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.js +16 -0
  40. package/dist/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.js.map +1 -0
  41. package/dist/LaunchMsaView/components/PreLoadedMSA/preCalculatedLaunchView.d.ts +6 -3
  42. package/dist/LaunchMsaView/components/PreLoadedMSA/preCalculatedLaunchView.js +3 -20
  43. package/dist/LaunchMsaView/components/PreLoadedMSA/preCalculatedLaunchView.js.map +1 -1
  44. package/dist/LaunchMsaView/components/PreLoadedMSA/types.d.ts +7 -0
  45. package/dist/LaunchMsaView/components/PreLoadedMSA/types.js +2 -0
  46. package/dist/LaunchMsaView/components/PreLoadedMSA/types.js.map +1 -0
  47. package/dist/LaunchMsaView/components/TranscriptSelector.js +2 -2
  48. package/dist/LaunchMsaView/components/TranscriptSelector.js.map +1 -1
  49. package/dist/LaunchMsaView/components/calculateProteinSequence.d.ts +2 -2
  50. package/dist/LaunchMsaView/components/calculateProteinSequence.js +2 -2
  51. package/dist/LaunchMsaView/components/calculateProteinSequence.js.map +1 -1
  52. package/dist/LaunchMsaView/components/types.d.ts +1 -0
  53. package/dist/LaunchMsaView/components/useFeatureSequence.d.ts +3 -7
  54. package/dist/LaunchMsaView/components/useFeatureSequence.js +9 -62
  55. package/dist/LaunchMsaView/components/useFeatureSequence.js.map +1 -1
  56. package/dist/LaunchMsaView/components/useSWRFeatureSequence.d.ts +13 -0
  57. package/dist/LaunchMsaView/components/useSWRFeatureSequence.js +53 -0
  58. package/dist/LaunchMsaView/components/useSWRFeatureSequence.js.map +1 -0
  59. package/dist/LaunchMsaView/index.js +3 -1
  60. package/dist/LaunchMsaView/index.js.map +1 -1
  61. package/dist/MsaViewPanel/components/RIDLink.js +1 -1
  62. package/dist/MsaViewPanel/components/RIDLink.js.map +1 -1
  63. package/dist/MsaViewPanel/genomeToMSA.js +2 -2
  64. package/dist/MsaViewPanel/genomeToMSA.js.map +1 -1
  65. package/dist/MsaViewPanel/model.d.ts +13 -84
  66. package/dist/MsaViewPanel/model.js +6 -2
  67. package/dist/MsaViewPanel/model.js.map +1 -1
  68. package/dist/MsaViewPanel/msaCoordToGenomeCoord.js +39 -14
  69. package/dist/MsaViewPanel/msaCoordToGenomeCoord.js.map +1 -1
  70. package/dist/MsaViewPanel/util.js +2 -2
  71. package/dist/MsaViewPanel/util.js.map +1 -1
  72. package/dist/components/ExternalLink.js.map +1 -0
  73. package/dist/components/ReadOnlyTextField2.js.map +1 -0
  74. package/dist/components/TextField2.js.map +1 -0
  75. package/dist/index.d.ts +9 -5
  76. package/dist/index.js +24 -15
  77. package/dist/index.js.map +1 -1
  78. package/dist/jbrowse-plugin-msaview.umd.production.min.js +46 -33
  79. package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
  80. package/dist/out.js +55367 -0
  81. package/dist/utils/fetch.d.ts +3 -1
  82. package/dist/utils/fetch.js +24 -3
  83. package/dist/utils/fetch.js.map +1 -1
  84. package/package.json +7 -6
  85. package/src/BgzipFastaMsaAdapter/BgzipFastaMsaAdapter.ts +78 -0
  86. package/src/BgzipFastaMsaAdapter/configSchema.ts +18 -0
  87. package/src/BgzipFastaMsaAdapter/index.ts +18 -0
  88. package/src/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.tsx +0 -1
  89. package/src/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.ts +6 -24
  90. package/src/LaunchMsaView/components/EnsemblGeneTree/util.ts +6 -45
  91. package/src/LaunchMsaView/components/LaunchMsaViewDialog.tsx +23 -24
  92. package/src/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.tsx +1 -1
  93. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.tsx +13 -8
  94. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.tsx +1 -1
  95. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastPanel.tsx +20 -29
  96. package/src/LaunchMsaView/components/NCBIBlastQuery/NCBISettingsDialog.tsx +1 -1
  97. package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +154 -68
  98. package/src/LaunchMsaView/components/PreLoadedMSA/consts.ts +7 -0
  99. package/src/LaunchMsaView/components/PreLoadedMSA/fetchMSAData.ts +33 -0
  100. package/src/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.ts +25 -0
  101. package/src/LaunchMsaView/components/PreLoadedMSA/preCalculatedLaunchView.ts +7 -26
  102. package/src/LaunchMsaView/components/PreLoadedMSA/types.ts +8 -0
  103. package/src/LaunchMsaView/components/TranscriptSelector.tsx +2 -2
  104. package/src/LaunchMsaView/components/calculateProteinSequence.ts +3 -3
  105. package/src/LaunchMsaView/components/types.ts +1 -0
  106. package/src/LaunchMsaView/components/useFeatureSequence.ts +10 -71
  107. package/src/LaunchMsaView/components/useSWRFeatureSequence.ts +90 -0
  108. package/src/LaunchMsaView/index.ts +4 -1
  109. package/src/MsaViewPanel/components/RIDLink.tsx +1 -1
  110. package/src/MsaViewPanel/genomeToMSA.ts +2 -2
  111. package/src/MsaViewPanel/model.ts +6 -2
  112. package/src/MsaViewPanel/msaCoordToGenomeCoord.ts +43 -16
  113. package/src/MsaViewPanel/util.ts +2 -2
  114. package/src/index.ts +26 -18
  115. package/src/utils/fetch.ts +31 -3
  116. package/dist/ExternalLink.js.map +0 -1
  117. package/dist/LaunchMsaView/components/PreLoadedMSA/fetchGeneList.d.ts +0 -1
  118. package/dist/LaunchMsaView/components/PreLoadedMSA/fetchGeneList.js +0 -12
  119. package/dist/LaunchMsaView/components/PreLoadedMSA/fetchGeneList.js.map +0 -1
  120. package/dist/ReadOnlyTextField2.js.map +0 -1
  121. package/dist/TextField2.js.map +0 -1
  122. package/src/LaunchMsaView/components/PreLoadedMSA/fetchGeneList.ts +0 -13
  123. /package/dist/{ExternalLink.d.ts → components/ExternalLink.d.ts} +0 -0
  124. /package/dist/{ExternalLink.js → components/ExternalLink.js} +0 -0
  125. /package/dist/{ReadOnlyTextField2.d.ts → components/ReadOnlyTextField2.d.ts} +0 -0
  126. /package/dist/{ReadOnlyTextField2.js → components/ReadOnlyTextField2.js} +0 -0
  127. /package/dist/{TextField2.d.ts → components/TextField2.d.ts} +0 -0
  128. /package/dist/{TextField2.js → components/TextField2.js} +0 -0
  129. /package/src/{ExternalLink.tsx → components/ExternalLink.tsx} +0 -0
  130. /package/src/{ReadOnlyTextField2.tsx → components/ReadOnlyTextField2.tsx} +0 -0
  131. /package/src/{TextField2.tsx → components/TextField2.tsx} +0 -0
@@ -1,4 +1,6 @@
1
- export declare function myfetch(url: string, args?: RequestInit): Promise<Response>;
1
+ export declare function handleFetch(url: string, args?: RequestInit): Promise<Response>;
2
2
  export declare function textfetch(url: string, args?: RequestInit): Promise<string>;
3
3
  export declare function jsonfetch<T>(url: string, args?: RequestInit): Promise<T>;
4
4
  export declare function timeout(time: number): Promise<unknown>;
5
+ export declare function fetchWithLocalStorageCache<T>(key: string, fetchFn: () => Promise<T>): Promise<T>;
6
+ export declare function unzipfetch(url: string, arg?: RequestInit): Promise<string>;
@@ -1,4 +1,5 @@
1
- export async function myfetch(url, args) {
1
+ import { ungzip } from 'pako';
2
+ export async function handleFetch(url, args) {
2
3
  const response = await fetch(url, args);
3
4
  if (!response.ok) {
4
5
  throw new Error(`HTTP ${response.status} fetching ${url} ${await response.text()}`);
@@ -6,14 +7,34 @@ export async function myfetch(url, args) {
6
7
  return response;
7
8
  }
8
9
  export async function textfetch(url, args) {
9
- const response = await myfetch(url, args);
10
+ const response = await handleFetch(url, args);
10
11
  return response.text();
11
12
  }
12
13
  export async function jsonfetch(url, args) {
13
- const response = await myfetch(url, args);
14
+ const response = await handleFetch(url, args);
14
15
  return response.json();
15
16
  }
16
17
  export function timeout(time) {
17
18
  return new Promise(res => setTimeout(res, time));
18
19
  }
20
+ export async function fetchWithLocalStorageCache(key, fetchFn) {
21
+ const cachedData = localStorage.getItem(key);
22
+ if (cachedData) {
23
+ try {
24
+ return JSON.parse(cachedData);
25
+ }
26
+ catch (error) {
27
+ console.error(`Error parsing cached data for ${key}:`, error);
28
+ // Continue to fetch fresh data if parsing fails
29
+ localStorage.removeItem(key);
30
+ }
31
+ }
32
+ const data = await fetchFn();
33
+ localStorage.setItem(key, JSON.stringify(data));
34
+ return data;
35
+ }
36
+ export async function unzipfetch(url, arg) {
37
+ const res = await handleFetch(url, arg);
38
+ return ungzip(await res.arrayBuffer(), { to: 'string' });
39
+ }
19
40
  //# sourceMappingURL=fetch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW,EAAE,IAAkB;IAC3D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAEvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,QAAQ,QAAQ,CAAC,MAAM,aAAa,GAAG,IAAI,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,CACnE,CAAA;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,IAAkB;IAC7D,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACzC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAA;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,GAAW,EAAE,IAAkB;IAChE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACzC,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAA;AACtC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;AAClD,CAAC"}
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAE7B,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,IAAkB;IAC/D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAEvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,QAAQ,QAAQ,CAAC,MAAM,aAAa,GAAG,IAAI,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,CACnE,CAAA;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,IAAkB;IAC7D,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAC7C,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAA;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,GAAW,EAAE,IAAkB;IAChE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAC7C,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAA;AACtC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,GAAW,EACX,OAAyB;IAEzB,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAE5C,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAM,CAAA;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAA;YAC7D,gDAAgD;YAChD,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAA;IAC5B,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;IAC/C,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,GAAiB;IAC7D,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACvC,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAA;AAC1D,CAAC"}
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.2.0",
2
+ "version": "2.2.2",
3
3
  "license": "MIT",
4
4
  "name": "jbrowse-plugin-msaview",
5
5
  "keywords": [
@@ -39,7 +39,8 @@
39
39
  "@emotion/styled": "^11.14.0",
40
40
  "g2p_mapper": "^1.0.4",
41
41
  "pako": "^2.1.0",
42
- "react-msaview": "^4.0.0"
42
+ "react-msaview": "^4.4.1",
43
+ "swr": "^2.3.3"
43
44
  },
44
45
  "devDependencies": {
45
46
  "@emotion/react": "^11.10.4",
@@ -50,18 +51,18 @@
50
51
  "@mui/material": "^7.1.0",
51
52
  "@mui/system": "^7.1.0",
52
53
  "@mui/x-data-grid": "^8.2.0",
53
- "@types/node": "^22.10.7",
54
+ "@types/node": "^24.1.0",
54
55
  "@types/pako": "^2.0.1",
55
56
  "@types/react": "^19.1.6",
56
57
  "@typescript-eslint/eslint-plugin": "^8.0.1",
57
58
  "@typescript-eslint/parser": "^8.0.1",
58
59
  "esbuild": "^0.25.5",
59
- "eslint": "^9.0.0",
60
+ "eslint": "^9.28.0",
60
61
  "eslint-plugin-import": "^2.31.0",
61
62
  "eslint-plugin-react": "^7.20.3",
62
- "eslint-plugin-react-hooks": "^5.0.0",
63
+ "eslint-plugin-react-hooks": "^7.0.0",
63
64
  "eslint-plugin-react-refresh": "^0.4.9",
64
- "eslint-plugin-unicorn": "^59.0.1",
65
+ "eslint-plugin-unicorn": "^61.0.2",
65
66
  "mobx": "^6.10.2",
66
67
  "mobx-react": "^9.0.1",
67
68
  "mobx-state-tree": "^5.3.0",
@@ -0,0 +1,78 @@
1
+ import { readConfObject } from '@jbrowse/core/configuration'
2
+ import {
3
+ BaseAdapter,
4
+ BaseFeatureDataAdapter,
5
+ } from '@jbrowse/core/data_adapters/BaseAdapter'
6
+ import { firstValueFrom, toArray } from 'rxjs'
7
+
8
+ export default class BgzipFastaMsaAdapter extends BaseAdapter {
9
+ configureP: Promise<BaseFeatureDataAdapter> | undefined
10
+
11
+ refNamesP: Promise<string[]> | undefined
12
+
13
+ async configurePre() {
14
+ const getSubAdapter = this.getSubAdapter
15
+ if (getSubAdapter) {
16
+ const adapter = await getSubAdapter({
17
+ ...readConfObject(this.config),
18
+ type: 'BgzipFastaAdapter',
19
+ })
20
+
21
+ return adapter.dataAdapter as BaseFeatureDataAdapter
22
+ } else {
23
+ throw new Error('no get subadapter')
24
+ }
25
+ }
26
+ configure() {
27
+ this.configureP ??= this.configurePre().catch((e: unknown) => {
28
+ this.configureP = undefined
29
+ throw e
30
+ })
31
+ return this.configureP
32
+ }
33
+
34
+ async getMSARefs() {
35
+ this.refNamesP ??= this.configure()
36
+ .then(adapter => adapter.getRefNames())
37
+ .catch((e: unknown) => {
38
+ this.refNamesP = undefined
39
+ throw e
40
+ })
41
+ return this.refNamesP
42
+ }
43
+
44
+ async getMSAList() {
45
+ const refNames = await this.getMSARefs()
46
+ const list = new Set<string>()
47
+ const val = this.getConf('msaRegex')
48
+ const re = new RegExp(val)
49
+ for (let i = 0, l = refNames.length; i < l; i++) {
50
+ list.add(refNames[i]!.split(re)[0]!)
51
+ }
52
+ return [...list]
53
+ }
54
+
55
+ async getMSA(id: string) {
56
+ const adapter = await this.configure()
57
+ const refNames = await adapter.getRefNames()
58
+ const rows = []
59
+ for (let i = 0, l = refNames.length; i < l; i++) {
60
+ const refName = refNames[i]!
61
+ if (refName.startsWith(id)) {
62
+ rows.push(refName)
63
+ }
64
+ }
65
+ return firstValueFrom(
66
+ adapter
67
+ .getFeaturesInMultipleRegions(
68
+ rows.map(refName => ({
69
+ refName,
70
+ start: 0,
71
+ end: 1_000_000_000,
72
+ assemblyName: '',
73
+ })),
74
+ )
75
+ .pipe(toArray()),
76
+ )
77
+ }
78
+ }
@@ -0,0 +1,18 @@
1
+ import PluginManager from '@jbrowse/core/PluginManager'
2
+ import { ConfigurationSchema } from '@jbrowse/core/configuration'
3
+
4
+ export default function configSchemaF(pluginManager: PluginManager) {
5
+ const base = pluginManager.getAdapterType('BgzipFastaAdapter')
6
+ return ConfigurationSchema(
7
+ 'BgzipFastaMsaAdapter',
8
+ {
9
+ msaRegex: {
10
+ type: 'string',
11
+ defaultValue: '_',
12
+ },
13
+ },
14
+ {
15
+ baseConfiguration: base?.configSchema,
16
+ },
17
+ )
18
+ }
@@ -0,0 +1,18 @@
1
+ import PluginManager from '@jbrowse/core/PluginManager'
2
+ import { AdapterType } from '@jbrowse/core/pluggableElementTypes'
3
+
4
+ import configSchemaF from './configSchema'
5
+
6
+ export default function BgzipFastaMsaAdapterF(pluginManager: PluginManager) {
7
+ return pluginManager.addAdapterType(() => {
8
+ return new AdapterType({
9
+ name: 'BgzipFastaMsaAdapter',
10
+ configSchema: configSchemaF(pluginManager),
11
+ adapterMetadata: {
12
+ hiddenFromGUI: true,
13
+ },
14
+ getAdapterClass: () =>
15
+ import('./BgzipFastaMsaAdapter').then(t => t.default),
16
+ })
17
+ })
18
+ }
@@ -19,7 +19,6 @@ import { useFeatureSequence } from '../useFeatureSequence'
19
19
 
20
20
  import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
21
21
 
22
-
23
22
  const useStyles = makeStyles()({
24
23
  dialogContent: {
25
24
  width: '80em',
@@ -1,29 +1,11 @@
1
- import { useEffect, useState } from 'react'
2
-
1
+ import useSWR from 'swr'
3
2
  import { geneTreeFetcher } from './ensemblGeneTreeUtils'
4
3
 
5
- type Ret = Awaited<ReturnType<typeof geneTreeFetcher>>
6
-
7
4
  export function useGeneTree(geneId: string) {
8
- const [treeData, setTreeData] = useState<Ret>()
9
- const [isTreeLoading, setIsTreeLoading] = useState(false)
10
- const [treeError, setTreeError] = useState<unknown>()
11
-
12
- useEffect(() => {
13
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
14
- ;(async () => {
15
- try {
16
- setIsTreeLoading(true)
17
- const result = await geneTreeFetcher(geneId)
18
- setTreeData(result)
19
- } catch (e) {
20
- console.error(e)
21
- setTreeError(e)
22
- } finally {
23
- setIsTreeLoading(false)
24
- }
25
- })()
26
- }, [geneId])
5
+ const { data, error, isLoading } = useSWR(
6
+ () => (geneId ? ['geneTree', geneId] : null),
7
+ ([, geneId]) => geneTreeFetcher(geneId),
8
+ )
27
9
 
28
- return { treeData, isTreeLoading, treeError }
10
+ return { treeData: data, isTreeLoading: isLoading, treeError: error }
29
11
  }
@@ -1,45 +1,6 @@
1
- import { ungzip } from 'pako'
2
-
3
- export async function jsonfetch<T>(url: string, arg?: RequestInit) {
4
- const res = await fetch(url, arg)
5
- if (!res.ok) {
6
- throw new Error(`HTTP ${res.status} from ${url}: ${await res.text()}`)
7
- }
8
- return res.json() as Promise<T>
9
- }
10
-
11
- export async function textfetch(url: string, arg?: RequestInit) {
12
- const res = await fetch(url, arg)
13
- if (!res.ok) {
14
- throw new Error(`HTTP ${res.status} from ${url}`)
15
- }
16
- return res.text()
17
- }
18
-
19
- export async function fetchWithLocalStorageCache<T>(
20
- key: string,
21
- fetchFn: () => Promise<T>,
22
- ): Promise<T> {
23
- const cachedData = localStorage.getItem(key)
24
-
25
- if (cachedData) {
26
- try {
27
- return JSON.parse(cachedData) as T
28
- } catch (error) {
29
- console.error(`Error parsing cached data for ${key}:`, error)
30
- // Continue to fetch fresh data if parsing fails
31
- }
32
- }
33
-
34
- const data = await fetchFn()
35
- localStorage.setItem(key, JSON.stringify(data))
36
- return data
37
- }
38
-
39
- export async function unzipfetch(url: string, arg?: RequestInit) {
40
- const res = await fetch(url, arg)
41
- if (!res.ok) {
42
- throw new Error(`HTTP ${res.status} from ${url}: ${await res.text()}`)
43
- }
44
- return ungzip(await res.arrayBuffer(), { to: 'string' })
45
- }
1
+ export {
2
+ fetchWithLocalStorageCache,
3
+ jsonfetch,
4
+ textfetch,
5
+ unzipfetch,
6
+ } from '../../../utils/fetch'
@@ -10,7 +10,14 @@ import NCBIBlastPanel from './NCBIBlastQuery/NCBIBlastPanel'
10
10
  import PreLoadedMSA from './PreLoadedMSA/PreLoadedMSADataPanel'
11
11
  import TabPanel from './TabPanel'
12
12
 
13
- export default function LaunchProteinViewDialog({
13
+ const TABS = {
14
+ NCBI_BLAST: 0,
15
+ PRELOADED_MSA: 1,
16
+ ENSEMBL_GENETREE: 2,
17
+ MANUAL_MSA: 3,
18
+ }
19
+
20
+ export default function LaunchMsaViewDialog({
14
21
  handleClose,
15
22
  feature,
16
23
  model,
@@ -19,50 +26,42 @@ export default function LaunchProteinViewDialog({
19
26
  feature: Feature
20
27
  model: AbstractTrackModel
21
28
  }) {
22
- const [value, setValue] = useState(0)
29
+ const [value, setValue] = useState(TABS.NCBI_BLAST)
30
+
31
+ const handleChange = (_event: React.SyntheticEvent, newValue: number) => {
32
+ setValue(newValue)
33
+ }
23
34
 
24
35
  return (
25
- <Dialog
26
- maxWidth="xl"
27
- title="Launch MSA view"
28
- open
29
- onClose={() => {
30
- handleClose()
31
- }}
32
- >
33
- <Tabs
34
- value={value}
35
- onChange={(_, val) => {
36
- setValue(val)
37
- }}
38
- >
39
- <Tab label="NCBI BLAST query" value={0} />
40
- <Tab label="UCSC 100-way dataset" value={1} />
41
- <Tab label="Ensembl GeneTree" value={2} />
42
- <Tab label="Manually open MSA/tree" value={3} />
36
+ <Dialog maxWidth="xl" title="Launch MSA view" open onClose={handleClose}>
37
+ <Tabs value={value} onChange={handleChange}>
38
+ <Tab label="NCBI BLAST query" value={TABS.NCBI_BLAST} />
39
+ <Tab label="Pre-loaded MSA datasets" value={TABS.PRELOADED_MSA} />
40
+ <Tab label="Ensembl GeneTree" value={TABS.ENSEMBL_GENETREE} />
41
+ <Tab label="Manually open MSA dataset" value={TABS.MANUAL_MSA} />
43
42
  </Tabs>
44
- <TabPanel value={value} index={0}>
43
+ <TabPanel value={value} index={TABS.NCBI_BLAST}>
45
44
  <NCBIBlastPanel
46
45
  handleClose={handleClose}
47
46
  feature={feature}
48
47
  model={model}
49
48
  />
50
49
  </TabPanel>
51
- <TabPanel value={value} index={1}>
50
+ <TabPanel value={value} index={TABS.PRELOADED_MSA}>
52
51
  <PreLoadedMSA
53
52
  model={model}
54
53
  feature={feature}
55
54
  handleClose={handleClose}
56
55
  />
57
56
  </TabPanel>
58
- <TabPanel value={value} index={2}>
57
+ <TabPanel value={value} index={TABS.ENSEMBL_GENETREE}>
59
58
  <EnsemblGeneTree
60
59
  model={model}
61
60
  feature={feature}
62
61
  handleClose={handleClose}
63
62
  />
64
63
  </TabPanel>
65
- <TabPanel value={value} index={3}>
64
+ <TabPanel value={value} index={TABS.MANUAL_MSA}>
66
65
  <ManualMSALoader
67
66
  model={model}
68
67
  feature={feature}
@@ -22,7 +22,7 @@ import { observer } from 'mobx-react'
22
22
  import { makeStyles } from 'tss-react/mui'
23
23
 
24
24
  import { launchView } from './launchView'
25
- import TextField2 from '../../../TextField2'
25
+ import TextField2 from '../../../components/TextField2'
26
26
  import { getGeneDisplayName, getId, getTranscriptFeatures } from '../../util'
27
27
  import TranscriptSelector from '../TranscriptSelector'
28
28
  import { useFeatureSequence } from '../useFeatureSequence'
@@ -7,6 +7,7 @@ import {
7
7
  getContainingView,
8
8
  } from '@jbrowse/core/util'
9
9
  import {
10
+ Box,
10
11
  Button,
11
12
  DialogActions,
12
13
  DialogContent,
@@ -17,7 +18,7 @@ import { observer } from 'mobx-react'
17
18
  import { makeStyles } from 'tss-react/mui'
18
19
 
19
20
  import { blastLaunchView } from './blastLaunchView'
20
- import TextField2 from '../../../TextField2'
21
+ import TextField2 from '../../../components/TextField2'
21
22
  import {
22
23
  getGeneDisplayName,
23
24
  getId,
@@ -71,11 +72,11 @@ const NCBIBlastAutomaticPanel = observer(function ({
71
72
  getId(options[0]),
72
73
  )
73
74
  const [selectedBlastProgram, setSelectedBlastProgram] =
74
- useState<blastProgramsT>('blastp')
75
+ useState<blastProgramsT>('quick-blastp')
75
76
  const selectedTranscript = options.find(
76
77
  val => getId(val) === selectedTranscriptId,
77
78
  )!
78
- const { error, proteinSequence } = useFeatureSequence({
79
+ const { error: proteinSequenceError, proteinSequence } = useFeatureSequence({
79
80
  view,
80
81
  feature: selectedTranscript,
81
82
  })
@@ -85,7 +86,8 @@ const NCBIBlastAutomaticPanel = observer(function ({
85
86
  setSelectedBlastProgram('blastp')
86
87
  }
87
88
  }, [selectedBlastDatabase])
88
- const e = error ?? launchViewError
89
+ const e = proteinSequenceError ?? launchViewError
90
+ const style = { width: 150 }
89
91
  return (
90
92
  <>
91
93
  <DialogContent className={classes.dialogContent}>
@@ -94,7 +96,7 @@ const NCBIBlastAutomaticPanel = observer(function ({
94
96
  <TextField2
95
97
  variant="outlined"
96
98
  label="BLAST database"
97
- style={{ width: 150 }}
99
+ style={style}
98
100
  select
99
101
  value={selectedBlastDatabase}
100
102
  onChange={event => {
@@ -113,7 +115,7 @@ const NCBIBlastAutomaticPanel = observer(function ({
113
115
  <TextField2
114
116
  variant="outlined"
115
117
  label="MSA Algorithm"
116
- style={{ width: 150 }}
118
+ style={style}
117
119
  select
118
120
  value={selectedMsaAlgorithm}
119
121
  onChange={event => {
@@ -134,7 +136,7 @@ const NCBIBlastAutomaticPanel = observer(function ({
134
136
  variant="outlined"
135
137
  label="BLAST program"
136
138
  disabled={selectedBlastDatabase === 'nr_cluster_seq'}
137
- style={{ width: 150 }}
139
+ style={style}
138
140
  select
139
141
  value={selectedBlastProgram}
140
142
  onChange={event => {
@@ -152,7 +154,10 @@ const NCBIBlastAutomaticPanel = observer(function ({
152
154
  {selectedBlastDatabase === 'nr_cluster_seq' ? (
153
155
  <Typography
154
156
  variant="subtitle2"
155
- style={{ marginLeft: 4, alignContent: 'center' }}
157
+ style={{
158
+ marginLeft: 4,
159
+ alignContent: 'center',
160
+ }}
156
161
  >
157
162
  Can only use blastp on nr_cluster_seq
158
163
  </Typography>
@@ -6,7 +6,7 @@ import { Button, DialogActions, DialogContent, Typography } from '@mui/material'
6
6
  import { observer } from 'mobx-react'
7
7
  import { makeStyles } from 'tss-react/mui'
8
8
 
9
- import ExternalLink from '../../../ExternalLink'
9
+ import ExternalLink from '../../../components/ExternalLink'
10
10
  import { getId, getTranscriptFeatures } from '../../util'
11
11
  import TranscriptSelector from '../TranscriptSelector'
12
12
  import { useFeatureSequence } from '../useFeatureSequence'
@@ -28,6 +28,11 @@ export default function NCBIBlastPanel({
28
28
  )
29
29
  const [settingsOpen, setSettingsOpen] = useState(false)
30
30
 
31
+ const Panel =
32
+ lookupMethod === 'automatic'
33
+ ? NCBIBlastAutomaticPanel
34
+ : NCBIBlastManualPanel
35
+
31
36
  return (
32
37
  <>
33
38
  <IconButton
@@ -40,38 +45,24 @@ export default function NCBIBlastPanel({
40
45
  <SettingsIcon />
41
46
  </IconButton>
42
47
 
43
- {lookupMethod === 'automatic' ? (
44
- <NCBIBlastAutomaticPanel
45
- model={model}
46
- feature={feature}
47
- handleClose={handleClose}
48
- baseUrl={baseUrl}
49
- >
50
- <NCBIBlastMethodSelector
51
- lookupMethod={lookupMethod}
52
- setLookupMethod={setLookupMethod}
53
- />
54
- </NCBIBlastAutomaticPanel>
55
- ) : null}
56
- {lookupMethod === 'manual' ? (
57
- <NCBIBlastManualPanel
58
- model={model}
59
- feature={feature}
60
- handleClose={handleClose}
61
- baseUrl={baseUrl}
62
- >
63
- <NCBIBlastMethodSelector
64
- lookupMethod={lookupMethod}
65
- setLookupMethod={setLookupMethod}
66
- />
67
- </NCBIBlastManualPanel>
68
- ) : null}
48
+ <Panel
49
+ model={model}
50
+ feature={feature}
51
+ handleClose={handleClose}
52
+ baseUrl={baseUrl}
53
+ >
54
+ <NCBIBlastMethodSelector
55
+ lookupMethod={lookupMethod}
56
+ setLookupMethod={setLookupMethod}
57
+ />
58
+ </Panel>
59
+
69
60
  {settingsOpen ? (
70
61
  <NCBISettingsDialog
71
62
  baseUrl={baseUrl}
72
- handleClose={arg => {
73
- if (arg) {
74
- setBaseUrl(arg)
63
+ handleClose={newUrl => {
64
+ if (newUrl) {
65
+ setBaseUrl(newUrl)
75
66
  }
76
67
  setSettingsOpen(false)
77
68
  }}
@@ -9,7 +9,7 @@ import {
9
9
  } from '@mui/material'
10
10
 
11
11
  import { BASE_BLAST_URL } from './consts'
12
- import TextField2 from '../../../TextField2'
12
+ import TextField2 from '../../../components/TextField2'
13
13
 
14
14
  export default function NCBISettingsDialog({
15
15
  handleClose,