@jbrowse/core 1.7.11 → 2.1.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 (204) hide show
  1. package/BaseFeatureWidget/BaseFeatureDetail.d.ts +20 -4
  2. package/BaseFeatureWidget/BaseFeatureDetail.js +313 -558
  3. package/BaseFeatureWidget/SequenceFeatureDetails.js +213 -473
  4. package/BaseFeatureWidget/index.d.ts +2 -2
  5. package/BaseFeatureWidget/index.js +88 -124
  6. package/BaseFeatureWidget/types.d.ts +1 -0
  7. package/BaseFeatureWidget/types.js +1 -4
  8. package/BaseFeatureWidget/util.js +40 -75
  9. package/CorePlugin.js +55 -94
  10. package/Plugin.js +9 -34
  11. package/PluginLoader.js +153 -422
  12. package/PluginManager.d.ts +84 -117
  13. package/PluginManager.js +377 -666
  14. package/ReExports/Attributes.d.ts +2 -0
  15. package/ReExports/Attributes.js +5 -0
  16. package/ReExports/BaseCard.d.ts +2 -0
  17. package/ReExports/BaseCard.js +5 -0
  18. package/ReExports/DataGrid.d.ts +2 -0
  19. package/ReExports/DataGrid.js +6 -0
  20. package/ReExports/FeatureDetails.d.ts +2 -0
  21. package/ReExports/FeatureDetails.js +5 -0
  22. package/ReExports/index.js +6 -12
  23. package/ReExports/list.d.ts +5 -0
  24. package/ReExports/list.js +271 -7
  25. package/ReExports/material-ui-colors.d.ts +1 -19
  26. package/ReExports/material-ui-colors.js +16 -158
  27. package/ReExports/modules.d.ts +68 -109
  28. package/ReExports/modules.js +455 -244
  29. package/TextSearch/BaseResults.js +51 -123
  30. package/TextSearch/TextSearchManager.d.ts +3 -1
  31. package/TextSearch/TextSearchManager.js +66 -144
  32. package/assemblyManager/assembly.js +280 -554
  33. package/assemblyManager/assemblyConfigSchema.js +47 -64
  34. package/assemblyManager/assemblyManager.d.ts +12 -10
  35. package/assemblyManager/assemblyManager.js +126 -270
  36. package/assemblyManager/index.js +9 -22
  37. package/configuration/configurationSchema.js +167 -203
  38. package/configuration/configurationSlot.js +248 -326
  39. package/configuration/index.js +19 -35
  40. package/configuration/util.d.ts +1 -1
  41. package/configuration/util.js +131 -173
  42. package/data_adapters/BaseAdapter.d.ts +2 -2
  43. package/data_adapters/BaseAdapter.js +132 -521
  44. package/data_adapters/CytobandAdapter.js +40 -126
  45. package/data_adapters/dataAdapterCache.js +77 -158
  46. package/package.json +16 -18
  47. package/pluggableElementTypes/AdapterType.js +24 -79
  48. package/pluggableElementTypes/AddTrackWorkflowType.d.ts +17 -0
  49. package/pluggableElementTypes/AddTrackWorkflowType.js +20 -0
  50. package/pluggableElementTypes/ConnectionType.js +22 -65
  51. package/pluggableElementTypes/DisplayType.js +35 -82
  52. package/pluggableElementTypes/InternetAccountType.js +23 -64
  53. package/pluggableElementTypes/PluggableElementBase.js +8 -20
  54. package/pluggableElementTypes/RpcMethodType.js +85 -427
  55. package/pluggableElementTypes/TextSearchAdapterType.js +16 -55
  56. package/pluggableElementTypes/TrackType.js +26 -70
  57. package/pluggableElementTypes/ViewType.js +21 -63
  58. package/pluggableElementTypes/WidgetType.js +21 -64
  59. package/pluggableElementTypes/index.d.ts +4 -3
  60. package/pluggableElementTypes/index.js +42 -125
  61. package/pluggableElementTypes/models/BaseConnectionModelFactory.js +28 -43
  62. package/pluggableElementTypes/models/BaseDisplayModel.d.ts +10 -10
  63. package/pluggableElementTypes/models/BaseDisplayModel.js +58 -95
  64. package/pluggableElementTypes/models/BaseTrackModel.d.ts +1 -1
  65. package/pluggableElementTypes/models/BaseTrackModel.js +139 -200
  66. package/pluggableElementTypes/models/BaseViewModel.js +24 -40
  67. package/pluggableElementTypes/models/InternetAccountModel.js +116 -263
  68. package/pluggableElementTypes/models/baseConnectionConfig.js +14 -25
  69. package/pluggableElementTypes/models/baseInternetAccountConfig.js +29 -38
  70. package/pluggableElementTypes/models/baseTrackConfig.js +106 -133
  71. package/pluggableElementTypes/models/index.js +21 -70
  72. package/pluggableElementTypes/renderers/BoxRendererType.js +132 -291
  73. package/pluggableElementTypes/renderers/CircularChordRendererType.js +8 -38
  74. package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.js +60 -192
  75. package/pluggableElementTypes/renderers/FeatureRendererType.d.ts +0 -2
  76. package/pluggableElementTypes/renderers/FeatureRendererType.js +89 -255
  77. package/pluggableElementTypes/renderers/RendererType.js +31 -105
  78. package/pluggableElementTypes/renderers/ServerSideRenderedContent.js +61 -72
  79. package/pluggableElementTypes/renderers/ServerSideRendererType.d.ts +2 -2
  80. package/pluggableElementTypes/renderers/ServerSideRendererType.js +112 -265
  81. package/pluggableElementTypes/renderers/index.js +19 -62
  82. package/pluggableElementTypes/renderers/util/serializableFilterChain.js +27 -65
  83. package/rpc/BaseRpcDriver.js +169 -405
  84. package/rpc/MainThreadRpcDriver.js +27 -150
  85. package/rpc/RpcManager.js +58 -159
  86. package/rpc/WebWorkerRpcDriver.js +54 -171
  87. package/rpc/configSchema.js +25 -49
  88. package/rpc/coreRpcMethods.d.ts +1 -3
  89. package/rpc/coreRpcMethods.js +221 -959
  90. package/rpc/remoteAbortSignals.js +46 -70
  91. package/tsconfig.build.tsbuildinfo +1 -1
  92. package/ui/AboutDialog.js +107 -158
  93. package/ui/App.js +157 -261
  94. package/ui/AssemblySelector.d.ts +1 -1
  95. package/ui/AssemblySelector.js +59 -115
  96. package/ui/CascadingMenu.js +100 -199
  97. package/ui/ColorPicker.d.ts +16 -0
  98. package/ui/ColorPicker.js +97 -0
  99. package/ui/Drawer.js +28 -58
  100. package/ui/DrawerWidget.js +109 -209
  101. package/ui/DropDownMenu.d.ts +0 -8
  102. package/ui/DropDownMenu.js +60 -97
  103. package/ui/EditableTypography.d.ts +1 -1
  104. package/ui/EditableTypography.js +87 -155
  105. package/ui/ErrorMessage.js +41 -66
  106. package/ui/FactoryResetDialog.js +24 -57
  107. package/ui/FatalErrorDialog.js +59 -91
  108. package/ui/FileSelector/FileSelector.js +123 -189
  109. package/ui/FileSelector/LocalFileChooser.js +44 -71
  110. package/ui/FileSelector/UrlChooser.js +17 -38
  111. package/ui/FileSelector/index.js +6 -12
  112. package/ui/Icons.d.ts +1 -1
  113. package/ui/Icons.js +45 -69
  114. package/ui/Logo.js +57 -110
  115. package/ui/Menu.d.ts +1 -1
  116. package/ui/Menu.js +232 -355
  117. package/ui/PrerenderedCanvas.js +63 -78
  118. package/ui/ResizeHandle.js +87 -114
  119. package/ui/ReturnToImportFormDialog.js +32 -59
  120. package/ui/SanitizedHTML.js +63 -52
  121. package/ui/Snackbar.js +74 -99
  122. package/ui/SnackbarModel.js +37 -51
  123. package/ui/Tooltip.d.ts +3 -1
  124. package/ui/Tooltip.js +49 -74
  125. package/ui/ViewContainer.js +113 -183
  126. package/ui/colors.d.ts +10 -0
  127. package/ui/colors.js +78 -0
  128. package/ui/index.js +51 -181
  129. package/ui/react-colorful.d.ts +17 -0
  130. package/ui/react-colorful.js +455 -0
  131. package/ui/theme.d.ts +279 -131
  132. package/ui/theme.js +197 -225
  133. package/util/Base1DUtils.d.ts +32 -0
  134. package/util/Base1DUtils.js +174 -0
  135. package/util/Base1DViewModel.d.ts +16 -37
  136. package/util/Base1DViewModel.js +116 -295
  137. package/util/QuickLRU.js +84 -332
  138. package/util/TimeTraveller.d.ts +19 -0
  139. package/util/TimeTraveller.js +86 -0
  140. package/util/aborting.js +49 -127
  141. package/util/analytics.js +91 -154
  142. package/util/blockTypes.js +106 -240
  143. package/util/calculateDynamicBlocks.js +98 -128
  144. package/util/calculateStaticBlocks.js +105 -125
  145. package/util/color/cssColorsLevel4.js +156 -160
  146. package/util/color/index.js +33 -55
  147. package/util/compositeMap.js +49 -333
  148. package/util/formatFastaStrings.js +9 -14
  149. package/util/idMaker.js +18 -31
  150. package/util/index.d.ts +18 -39
  151. package/util/index.js +743 -1236
  152. package/util/io/RemoteFileWithRangeCache.js +88 -257
  153. package/util/io/index.js +95 -169
  154. package/util/jexl.js +60 -115
  155. package/util/jexlStrings.js +24 -29
  156. package/util/layouts/BaseLayout.js +1 -4
  157. package/util/layouts/GranularRectLayout.js +388 -557
  158. package/util/layouts/MultiLayout.js +41 -109
  159. package/util/layouts/PrecomputedLayout.js +56 -114
  160. package/util/layouts/PrecomputedMultiLayout.js +22 -59
  161. package/util/layouts/SceneGraph.js +127 -197
  162. package/util/layouts/index.js +29 -66
  163. package/util/mst-reflection.js +55 -71
  164. package/util/offscreenCanvasPonyfill.js +66 -134
  165. package/util/offscreenCanvasUtils.d.ts +2 -7
  166. package/util/offscreenCanvasUtils.js +49 -146
  167. package/util/range.js +29 -40
  168. package/util/rxjs.js +20 -27
  169. package/util/simpleFeature.js +88 -152
  170. package/util/stats.js +91 -151
  171. package/util/tracks.js +130 -171
  172. package/util/types/index.d.ts +3 -3
  173. package/util/types/index.js +110 -179
  174. package/util/types/mst.d.ts +3 -3
  175. package/util/types/mst.js +91 -142
  176. package/util/types/util.js +1 -4
  177. package/util/when.js +54 -101
  178. package/BaseFeatureWidget/SequenceFeatureDetails.test.js +0 -122
  179. package/BaseFeatureWidget/index.test.js +0 -51
  180. package/TextSearch/BaseResults.test.js +0 -42
  181. package/configuration/configurationSchema.test.js +0 -266
  182. package/configuration/configurationSlot.test.js +0 -69
  183. package/configuration/util.test.js +0 -39
  184. package/data_adapters/BaseAdapter.test.js +0 -200
  185. package/declare.d.js +0 -1
  186. package/pluggableElementTypes/RpcMethodType.test.js +0 -118
  187. package/pluggableElementTypes/renderers/declare.d.js +0 -1
  188. package/pluggableElementTypes/renderers/util/serializableFilterChain.test.js +0 -20
  189. package/rpc/BaseRpcDriver.test.js +0 -540
  190. package/rpc/declaration.d.js +0 -1
  191. package/ui/FatalErrorDialog.test.js +0 -82
  192. package/ui/SanitizedHTML.test.js +0 -36
  193. package/ui/theme.test.js +0 -111
  194. package/util/Base1DViewModel.test.js +0 -130
  195. package/util/calculateDynamicBlocks.test.js +0 -74
  196. package/util/calculateStaticBlocks.test.js +0 -297
  197. package/util/declare.d.js +0 -1
  198. package/util/formatFastaStrings.test.js +0 -40
  199. package/util/index.test.js +0 -213
  200. package/util/jexlStrings.test.js +0 -48
  201. package/util/layouts/GranularRectLayout.test.js +0 -99
  202. package/util/range.test.js +0 -64
  203. package/util/simpleFeature.test.js +0 -34
  204. package/util/stats.test.js +0 -172
@@ -1,489 +1,229 @@
1
1
  "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- var _typeof = require("@babel/runtime/helpers/typeof");
6
-
7
- Object.defineProperty(exports, "__esModule", {
8
- value: true
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
9
17
  });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
10
29
  exports.SequencePanel = void 0;
11
- exports.default = SequenceFeatureDetails;
12
-
13
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
14
-
15
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
16
-
17
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
18
-
19
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
20
-
21
- var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
22
-
23
- var _react = _interopRequireWildcard(require("react"));
24
-
25
- var _core = require("@material-ui/core");
26
-
27
- var _reactIntersectionObserver = require("react-intersection-observer");
28
-
29
- var _copyToClipboard = _interopRequireDefault(require("copy-to-clipboard"));
30
-
31
- var _util = require("../util");
32
-
33
- var _configuration = require("../configuration");
34
-
35
- var _util2 = require("./util");
36
-
37
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
38
-
39
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
40
-
41
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
42
-
43
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
44
-
45
- var useStyles = (0, _core.makeStyles)(function (theme) {
46
- return {
30
+ const react_1 = __importStar(require("react"));
31
+ const material_1 = require("@mui/material");
32
+ const mui_1 = require("tss-react/mui");
33
+ const react_intersection_observer_1 = require("react-intersection-observer");
34
+ const copy_to_clipboard_1 = __importDefault(require("copy-to-clipboard"));
35
+ const util_1 = require("../util");
36
+ const configuration_1 = require("../configuration");
37
+ const util_2 = require("./util");
38
+ const useStyles = (0, mui_1.makeStyles)()(theme => ({
47
39
  button: {
48
- margin: theme.spacing(1)
49
- }
50
- };
51
- }); // note that these are currently put into the style section instead of being
40
+ margin: theme.spacing(1),
41
+ },
42
+ }));
43
+ // note that these are currently put into the style section instead of being
52
44
  // defined in classes to aid copy and paste to an external document e.g. word
53
-
54
- var proteinColor = 'rgb(220,160,220)';
55
- var intronColor = undefined;
56
- var cdsColor = 'rgb(220,220,180)';
57
- var updownstreamColor = 'rgba(250,200,200)';
58
- var utrColor = 'rgb(200,240,240)';
59
-
60
- function GeneCDS(_ref) {
61
- var cds = _ref.cds,
62
- sequence = _ref.sequence;
63
- return /*#__PURE__*/_react.default.createElement("span", {
64
- style: {
65
- background: cdsColor
66
- }
67
- }, (0, _util2.stitch)(cds, sequence));
45
+ const proteinColor = 'rgb(220,160,220)';
46
+ const intronColor = undefined;
47
+ const cdsColor = 'rgb(220,220,180)';
48
+ const updownstreamColor = 'rgba(250,200,200)';
49
+ const utrColor = 'rgb(200,240,240)';
50
+ function GeneCDS({ cds, sequence }) {
51
+ return react_1.default.createElement("span", { style: { background: cdsColor } }, (0, util_2.stitch)(cds, sequence));
68
52
  }
69
-
70
- function GeneProtein(_ref2) {
71
- var cds = _ref2.cds,
72
- sequence = _ref2.sequence,
73
- codonTable = _ref2.codonTable;
74
- var str = (0, _util2.stitch)(cds, sequence);
75
- var protein = '';
76
-
77
- for (var i = 0; i < str.length; i += 3) {
78
- // use & symbol for undefined codon, or partial slice
79
- protein += codonTable[str.slice(i, i + 3)] || '&';
80
- }
81
-
82
- return /*#__PURE__*/_react.default.createElement("span", {
83
- style: {
84
- background: proteinColor
53
+ function GeneProtein({ cds, sequence, codonTable, }) {
54
+ const str = (0, util_2.stitch)(cds, sequence);
55
+ let protein = '';
56
+ for (let i = 0; i < str.length; i += 3) {
57
+ // use & symbol for undefined codon, or partial slice
58
+ protein += codonTable[str.slice(i, i + 3)] || '&';
85
59
  }
86
- }, protein);
60
+ return react_1.default.createElement("span", { style: { background: proteinColor } }, protein);
61
+ }
62
+ function GenecDNA({ utr, cds, exons, sequence, upstream, downstream, includeIntrons, collapseIntron, }) {
63
+ const chunks = cds.length
64
+ ? [...cds, ...utr].sort((a, b) => a.start - b.start)
65
+ : exons;
66
+ return (react_1.default.createElement(react_1.default.Fragment, null,
67
+ upstream ? (react_1.default.createElement("span", { style: { background: updownstreamColor } }, upstream)) : null,
68
+ chunks
69
+ .filter(f => f.start !== f.end)
70
+ .map((chunk, index) => {
71
+ var _a;
72
+ const intron = sequence.slice(chunk.end, (_a = chunks[index + 1]) === null || _a === void 0 ? void 0 : _a.start);
73
+ return (react_1.default.createElement(react_1.default.Fragment, { key: JSON.stringify(chunk) },
74
+ react_1.default.createElement("span", { style: {
75
+ background: chunk.type === 'CDS' ? cdsColor : utrColor,
76
+ } }, sequence.slice(chunk.start, chunk.end)),
77
+ includeIntrons && index < chunks.length - 1 ? (react_1.default.createElement("span", { style: { background: intronColor } }, collapseIntron && intron.length > 20
78
+ ? `${intron.slice(0, 10)}...${intron.slice(-10)}`
79
+ : intron)) : null));
80
+ }),
81
+ downstream ? (react_1.default.createElement("span", { style: { background: updownstreamColor } }, downstream)) : null));
87
82
  }
88
-
89
- function GenecDNA(_ref3) {
90
- var utr = _ref3.utr,
91
- cds = _ref3.cds,
92
- exons = _ref3.exons,
93
- sequence = _ref3.sequence,
94
- upstream = _ref3.upstream,
95
- downstream = _ref3.downstream,
96
- includeIntrons = _ref3.includeIntrons,
97
- collapseIntron = _ref3.collapseIntron;
98
- var chunks = cds.length ? [].concat((0, _toConsumableArray2.default)(cds), (0, _toConsumableArray2.default)(utr)).sort(function (a, b) {
99
- return a.start - b.start;
100
- }) : exons;
101
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, upstream ? /*#__PURE__*/_react.default.createElement("span", {
102
- style: {
103
- background: updownstreamColor
83
+ exports.SequencePanel = react_1.default.forwardRef(({ feature, mode, sequence: { seq: sequence, upstream = '', downstream = '' }, }, ref) => {
84
+ const { subfeatures } = feature;
85
+ const codonTable = (0, util_1.generateCodonTable)(util_1.defaultCodonTable);
86
+ if (!subfeatures) {
87
+ return null;
104
88
  }
105
- }, upstream) : null, chunks.filter(function (f) {
106
- return f.start !== f.end;
107
- }).map(function (chunk, index) {
108
- var _chunks;
109
-
110
- var intron = sequence.slice(chunk.end, (_chunks = chunks[index + 1]) === null || _chunks === void 0 ? void 0 : _chunks.start);
111
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, {
112
- key: JSON.stringify(chunk)
113
- }, /*#__PURE__*/_react.default.createElement("span", {
114
- style: {
115
- background: chunk.type === 'CDS' ? cdsColor : utrColor
116
- }
117
- }, sequence.slice(chunk.start, chunk.end)), includeIntrons && index < chunks.length - 1 ? /*#__PURE__*/_react.default.createElement("span", {
118
- style: {
119
- background: intronColor
120
- }
121
- }, collapseIntron && intron.length > 20 ? "".concat(intron.slice(0, 10), "...").concat(intron.slice(-10)) : intron) : null);
122
- }), downstream ? /*#__PURE__*/_react.default.createElement("span", {
123
- style: {
124
- background: updownstreamColor
89
+ const children = subfeatures
90
+ .sort((a, b) => a.start - b.start)
91
+ .map(sub => ({
92
+ ...sub,
93
+ start: sub.start - feature.start,
94
+ end: sub.end - feature.start,
95
+ }));
96
+ // we filter duplicate entries in cds and exon lists duplicate entries may be
97
+ // rare but was seen in Gencode v36 track NCList, likely a bug on GFF3 or
98
+ // probably worth ignoring here (produces broken protein translations if
99
+ // included)
100
+ //
101
+ // position 1:224,800,006..225,203,064 gene ENSG00000185842.15 first
102
+ // transcript ENST00000445597.6
103
+ //
104
+ // http://localhost:3000/?config=test_data%2Fconfig.json&session=share-FUl7G1isvF&password=HXh5Y
105
+ let cds = (0, util_2.dedupe)(children.filter(sub => sub.type === 'CDS'));
106
+ let utr = (0, util_2.dedupe)(children.filter(sub => sub.type.match(/utr/i)));
107
+ let exons = (0, util_2.dedupe)(children.filter(sub => sub.type === 'exon'));
108
+ if (!utr.length && cds.length && exons.length) {
109
+ utr = (0, util_2.calculateUTRs)(cds, exons);
125
110
  }
126
- }, downstream) : null);
127
- }
128
-
129
- var SequencePanel = /*#__PURE__*/_react.default.forwardRef(function (_ref4, ref) {
130
- var feature = _ref4.feature,
131
- mode = _ref4.mode,
132
- _ref4$sequence = _ref4.sequence,
133
- sequence = _ref4$sequence.seq,
134
- _ref4$sequence$upstre = _ref4$sequence.upstream,
135
- upstream = _ref4$sequence$upstre === void 0 ? '' : _ref4$sequence$upstre,
136
- _ref4$sequence$downst = _ref4$sequence.downstream,
137
- downstream = _ref4$sequence$downst === void 0 ? '' : _ref4$sequence$downst;
138
- var subfeatures = feature.subfeatures;
139
- var codonTable = (0, _util.generateCodonTable)(_util.defaultCodonTable);
140
-
141
- if (!subfeatures) {
142
- return null;
143
- }
144
-
145
- var children = subfeatures.sort(function (a, b) {
146
- return a.start - b.start;
147
- }).map(function (sub) {
148
- return _objectSpread(_objectSpread({}, sub), {}, {
149
- start: sub.start - feature.start,
150
- end: sub.end - feature.start
151
- });
152
- }); // we filter duplicate entries in cds and exon lists duplicate entries may be
153
- // rare but was seen in Gencode v36 track NCList, likely a bug on GFF3 or
154
- // probably worth ignoring here (produces broken protein translations if
155
- // included)
156
- //
157
- // position 1:224,800,006..225,203,064 gene ENSG00000185842.15 first
158
- // transcript ENST00000445597.6
159
- //
160
- // http://localhost:3000/?config=test_data%2Fconfig.json&session=share-FUl7G1isvF&password=HXh5Y
161
-
162
- var cds = (0, _util2.dedupe)(children.filter(function (sub) {
163
- return sub.type === 'CDS';
164
- }));
165
- var utr = (0, _util2.dedupe)(children.filter(function (sub) {
166
- return sub.type.match(/utr/i);
167
- }));
168
- var exons = (0, _util2.dedupe)(children.filter(function (sub) {
169
- return sub.type === 'exon';
170
- }));
171
-
172
- if (!utr.length && cds.length && exons.length) {
173
- utr = (0, _util2.calculateUTRs)(cds, exons);
174
- }
175
-
176
- if (feature.strand === -1) {
177
- // doing this in a single assignment is needed because downstream and
178
- // upstream are swapped so this avoids a temp variable
179
- ;
180
- var _ref5 = [(0, _util.revcom)(sequence), (0, _util.revcom)(downstream), (0, _util.revcom)(upstream)];
181
- sequence = _ref5[0];
182
- upstream = _ref5[1];
183
- downstream = _ref5[2];
184
- cds = (0, _util2.revlist)(cds, sequence.length);
185
- exons = (0, _util2.revlist)(exons, sequence.length);
186
- utr = (0, _util2.revlist)(utr, sequence.length);
187
- }
188
-
189
- return /*#__PURE__*/_react.default.createElement("div", {
190
- ref: ref,
191
- "data-testid": "sequence_panel"
192
- }, /*#__PURE__*/_react.default.createElement("div", {
193
- style: {
194
- fontFamily: 'monospace',
195
- wordWrap: 'break-word',
196
- maxWidth: 600
111
+ if (feature.strand === -1) {
112
+ // doing this in a single assignment is needed because downstream and
113
+ // upstream are swapped so this avoids a temp variable
114
+ ;
115
+ [sequence, upstream, downstream] = [
116
+ (0, util_1.revcom)(sequence),
117
+ (0, util_1.revcom)(downstream),
118
+ (0, util_1.revcom)(upstream),
119
+ ];
120
+ cds = (0, util_2.revlist)(cds, sequence.length);
121
+ exons = (0, util_2.revlist)(exons, sequence.length);
122
+ utr = (0, util_2.revlist)(utr, sequence.length);
197
123
  }
198
- }, ">".concat(feature.name || feature.id || 'unknown', "-").concat(mode, "\n"), mode === 'cds' ? /*#__PURE__*/_react.default.createElement(GeneCDS, {
199
- cds: cds,
200
- sequence: sequence
201
- }) : mode === 'cdna' ? /*#__PURE__*/_react.default.createElement(GenecDNA, {
202
- exons: exons,
203
- cds: cds,
204
- utr: utr,
205
- sequence: sequence
206
- }) : mode === 'protein' ? /*#__PURE__*/_react.default.createElement(GeneProtein, {
207
- cds: cds,
208
- codonTable: codonTable,
209
- sequence: sequence
210
- }) : mode === 'gene' ? /*#__PURE__*/_react.default.createElement(GenecDNA, {
211
- exons: exons,
212
- cds: cds,
213
- utr: utr,
214
- sequence: sequence,
215
- includeIntrons: true
216
- }) : mode === 'gene_collapsed_intron' ? /*#__PURE__*/_react.default.createElement(GenecDNA, {
217
- exons: exons,
218
- cds: cds,
219
- sequence: sequence,
220
- utr: utr,
221
- includeIntrons: true,
222
- collapseIntron: true
223
- }) : mode === 'gene_updownstream' ? /*#__PURE__*/_react.default.createElement(GenecDNA, {
224
- exons: exons,
225
- cds: cds,
226
- sequence: sequence,
227
- utr: utr,
228
- upstream: upstream,
229
- downstream: downstream,
230
- includeIntrons: true
231
- }) : mode === 'gene_updownstream_collapsed_intron' ? /*#__PURE__*/_react.default.createElement(GenecDNA, {
232
- exons: exons,
233
- cds: cds,
234
- sequence: sequence,
235
- utr: utr,
236
- upstream: upstream,
237
- downstream: downstream,
238
- includeIntrons: true,
239
- collapseIntron: true
240
- }) : /*#__PURE__*/_react.default.createElement("div", null, "Unknown type")));
241
- }); // display the stitched-together sequence of a gene's CDS, cDNA, or protein
124
+ return (react_1.default.createElement("div", { ref: ref, "data-testid": "sequence_panel" },
125
+ react_1.default.createElement("div", { style: {
126
+ fontFamily: 'monospace',
127
+ wordWrap: 'break-word',
128
+ fontSize: 12,
129
+ maxWidth: 600,
130
+ } },
131
+ `>${feature.name || feature.id || 'unknown'}-${mode}\n`,
132
+ mode === 'cds' ? (react_1.default.createElement(GeneCDS, { cds: cds, sequence: sequence })) : mode === 'cdna' ? (react_1.default.createElement(GenecDNA, { exons: exons, cds: cds, utr: utr, sequence: sequence })) : mode === 'protein' ? (react_1.default.createElement(GeneProtein, { cds: cds, codonTable: codonTable, sequence: sequence })) : mode === 'gene' ? (react_1.default.createElement(GenecDNA, { exons: exons, cds: cds, utr: utr, sequence: sequence, includeIntrons: true })) : mode === 'gene_collapsed_intron' ? (react_1.default.createElement(GenecDNA, { exons: exons, cds: cds, sequence: sequence, utr: utr, includeIntrons: true, collapseIntron: true })) : mode === 'gene_updownstream' ? (react_1.default.createElement(GenecDNA, { exons: exons, cds: cds, sequence: sequence, utr: utr, upstream: upstream, downstream: downstream, includeIntrons: true })) : mode === 'gene_updownstream_collapsed_intron' ? (react_1.default.createElement(GenecDNA, { exons: exons, cds: cds, sequence: sequence, utr: utr, upstream: upstream, downstream: downstream, includeIntrons: true, collapseIntron: true })) : (react_1.default.createElement("div", null, "Unknown type")))));
133
+ });
134
+ // display the stitched-together sequence of a gene's CDS, cDNA, or protein
242
135
  // sequence. this is a best effort and weird genomic phenomena could lead these
243
136
  // to not be 100% accurate
244
-
245
-
246
- exports.SequencePanel = SequencePanel;
247
-
248
- function SequenceFeatureDetails(_ref6) {
249
- var _parentFeature$subfea;
250
-
251
- var model = _ref6.model,
252
- feature = _ref6.feature;
253
- var classes = useStyles();
254
- var parentFeature = feature;
255
- var hasCDS = (_parentFeature$subfea = parentFeature.subfeatures) === null || _parentFeature$subfea === void 0 ? void 0 : _parentFeature$subfea.find(function (sub) {
256
- return sub.type === 'CDS';
257
- });
258
- var seqPanelRef = (0, _react.useRef)(null);
259
-
260
- var _useInView = (0, _reactIntersectionObserver.useInView)(),
261
- ref = _useInView.ref,
262
- inView = _useInView.inView;
263
-
264
- var _useState = (0, _react.useState)(),
265
- _useState2 = (0, _slicedToArray2.default)(_useState, 2),
266
- sequence = _useState2[0],
267
- setSequence = _useState2[1];
268
-
269
- var _useState3 = (0, _react.useState)(),
270
- _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
271
- error = _useState4[0],
272
- setError = _useState4[1];
273
-
274
- var _useState5 = (0, _react.useState)(hasCDS ? 'cds' : 'cdna'),
275
- _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
276
- mode = _useState6[0],
277
- setMode = _useState6[1];
278
-
279
- var _useState7 = (0, _react.useState)(false),
280
- _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
281
- copied = _useState8[0],
282
- setCopied = _useState8[1];
283
-
284
- var _useState9 = (0, _react.useState)(false),
285
- _useState10 = (0, _slicedToArray2.default)(_useState9, 2),
286
- copiedHtml = _useState10[0],
287
- setCopiedHtml = _useState10[1];
288
-
289
- (0, _react.useEffect)(function () {
290
- var _model$view;
291
-
292
- var finished = false;
293
-
294
- if (!model || !inView) {
295
- return function () {};
296
- }
297
-
298
- var _getSession = (0, _util.getSession)(model),
299
- assemblyManager = _getSession.assemblyManager,
300
- rpcManager = _getSession.rpcManager;
301
-
302
- var _ref7 = ((_model$view = model.view) === null || _model$view === void 0 ? void 0 : _model$view.assemblyNames) || [],
303
- _ref8 = (0, _slicedToArray2.default)(_ref7, 1),
304
- assemblyName = _ref8[0];
305
-
306
- function fetchSeq(_x, _x2, _x3) {
307
- return _fetchSeq.apply(this, arguments);
308
- }
309
-
310
- function _fetchSeq() {
311
- _fetchSeq = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(start, end, refName) {
312
- var assembly, sessionId, feats, _ref11, _ref12, feat;
313
-
314
- return _regenerator.default.wrap(function _callee2$(_context2) {
315
- while (1) {
316
- switch (_context2.prev = _context2.next) {
317
- case 0:
318
- _context2.next = 2;
319
- return assemblyManager.waitForAssembly(assemblyName);
320
-
321
- case 2:
322
- assembly = _context2.sent;
323
-
324
- if (assembly) {
325
- _context2.next = 5;
326
- break;
327
- }
328
-
137
+ function SequenceFeatureDetails({ model, feature }) {
138
+ var _a;
139
+ const { classes } = useStyles();
140
+ const parentFeature = feature;
141
+ const hasCDS = (_a = parentFeature.subfeatures) === null || _a === void 0 ? void 0 : _a.find(sub => sub.type === 'CDS');
142
+ const seqPanelRef = (0, react_1.useRef)(null);
143
+ const { ref, inView } = (0, react_intersection_observer_1.useInView)();
144
+ const [sequence, setSequence] = (0, react_1.useState)();
145
+ const [error, setError] = (0, react_1.useState)();
146
+ const [mode, setMode] = (0, react_1.useState)(hasCDS ? 'cds' : 'cdna');
147
+ const [copied, setCopied] = (0, react_1.useState)(false);
148
+ const [copiedHtml, setCopiedHtml] = (0, react_1.useState)(false);
149
+ (0, react_1.useEffect)(() => {
150
+ var _a;
151
+ let finished = false;
152
+ if (!model || !inView) {
153
+ return () => { };
154
+ }
155
+ const { assemblyManager, rpcManager } = (0, util_1.getSession)(model);
156
+ const [assemblyName] = ((_a = model.view) === null || _a === void 0 ? void 0 : _a.assemblyNames) || [];
157
+ async function fetchSeq(start, end, refName) {
158
+ const assembly = await assemblyManager.waitForAssembly(assemblyName);
159
+ if (!assembly) {
329
160
  throw new Error('assembly not found');
330
-
331
- case 5:
332
- sessionId = 'getSequence';
333
- _context2.next = 8;
334
- return rpcManager.call(sessionId, 'CoreGetFeatures', {
335
- adapterConfig: (0, _configuration.getConf)(assembly, ['sequence', 'adapter']),
336
- sessionId: sessionId,
337
- regions: [{
338
- start: start,
339
- end: end,
340
- refName: assembly.getCanonicalRefName(refName)
341
- }]
342
- });
343
-
344
- case 8:
345
- feats = _context2.sent;
346
- _ref11 = feats, _ref12 = (0, _slicedToArray2.default)(_ref11, 1), feat = _ref12[0];
347
-
348
- if (feat) {
349
- _context2.next = 12;
350
- break;
351
- }
352
-
353
- throw new Error("sequence not found for feature with refName:".concat(refName));
354
-
355
- case 12:
356
- return _context2.abrupt("return", feat.get('seq'));
357
-
358
- case 13:
359
- case "end":
360
- return _context2.stop();
361
161
  }
362
- }
363
- }, _callee2);
364
- }));
365
- return _fetchSeq.apply(this, arguments);
366
- }
367
-
368
- ;
369
- (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
370
- var _ref10, start, end, refName, seq, up, down;
371
-
372
- return _regenerator.default.wrap(function _callee$(_context) {
373
- while (1) {
374
- switch (_context.prev = _context.next) {
375
- case 0:
376
- _context.prev = 0;
377
- _ref10 = feature, start = _ref10.start, end = _ref10.end, refName = _ref10.refName;
378
- _context.next = 4;
379
- return fetchSeq(start, end, refName);
380
-
381
- case 4:
382
- seq = _context.sent;
383
- _context.next = 7;
384
- return fetchSeq(Math.max(0, start - 500), start, refName);
385
-
386
- case 7:
387
- up = _context.sent;
388
- _context.next = 10;
389
- return fetchSeq(end, end + 500, refName);
390
-
391
- case 10:
392
- down = _context.sent;
393
-
394
- if (!finished) {
395
- setSequence({
396
- seq: seq,
397
- upstream: up,
398
- downstream: down
399
- });
400
- }
401
-
402
- _context.next = 17;
403
- break;
404
-
405
- case 14:
406
- _context.prev = 14;
407
- _context.t0 = _context["catch"](0);
408
- setError(_context.t0);
409
-
410
- case 17:
411
- case "end":
412
- return _context.stop();
413
- }
162
+ const sessionId = 'getSequence';
163
+ const feats = await rpcManager.call(sessionId, 'CoreGetFeatures', {
164
+ adapterConfig: (0, configuration_1.getConf)(assembly, ['sequence', 'adapter']),
165
+ sessionId,
166
+ regions: [
167
+ {
168
+ start,
169
+ end,
170
+ refName: assembly.getCanonicalRefName(refName),
171
+ },
172
+ ],
173
+ });
174
+ const [feat] = feats;
175
+ if (!feat) {
176
+ throw new Error(`sequence not found for feature with refName:${refName}`);
177
+ }
178
+ return feat.get('seq');
414
179
  }
415
- }, _callee, null, [[0, 14]]);
416
- }))();
417
- return function () {
418
- finished = true;
419
- };
420
- }, [feature, inView, model]);
421
- var loading = !sequence;
422
- return /*#__PURE__*/_react.default.createElement("div", {
423
- ref: ref
424
- }, /*#__PURE__*/_react.default.createElement(_core.Select, {
425
- value: mode,
426
- onChange: function onChange(event) {
427
- return setMode(event.target.value);
428
- }
429
- }, hasCDS ? /*#__PURE__*/_react.default.createElement(_core.MenuItem, {
430
- value: "cds"
431
- }, "CDS") : null, hasCDS ? /*#__PURE__*/_react.default.createElement(_core.MenuItem, {
432
- value: "protein"
433
- }, "Protein") : null, /*#__PURE__*/_react.default.createElement(_core.MenuItem, {
434
- value: "gene"
435
- }, "Gene w/ introns"), /*#__PURE__*/_react.default.createElement(_core.MenuItem, {
436
- value: "gene_collapsed_intron"
437
- }, "Gene w/ 10bp of intron"), /*#__PURE__*/_react.default.createElement(_core.MenuItem, {
438
- value: "gene_updownstream"
439
- }, "Gene w/ 500bp up+down stream"), /*#__PURE__*/_react.default.createElement(_core.MenuItem, {
440
- value: "gene_updownstream_collapsed_intron"
441
- }, "Gene w/ 500bp up+down stream w/ 10bp intron"), /*#__PURE__*/_react.default.createElement(_core.MenuItem, {
442
- value: "cdna"
443
- }, "cDNA")), /*#__PURE__*/_react.default.createElement(_core.Button, {
444
- className: classes.button,
445
- type: "button",
446
- variant: "contained",
447
- onClick: function onClick() {
448
- var ref = seqPanelRef.current;
449
-
450
- if (ref) {
451
- (0, _copyToClipboard.default)(ref.textContent || '', {
452
- format: 'text/plain'
453
- });
454
- setCopied(true);
455
- setTimeout(function () {
456
- return setCopied(false);
457
- }, 1000);
458
- }
459
- }
460
- }, copied ? 'Copied to clipboard!' : 'Copy as plaintext'), /*#__PURE__*/_react.default.createElement(_core.Tooltip, {
461
- title: "Note that 'Copy as HTML' can retain the colors but cannot be pasted into some programs like notepad that only expect plain text"
462
- }, /*#__PURE__*/_react.default.createElement(_core.Button, {
463
- className: classes.button,
464
- type: "button",
465
- variant: "contained",
466
- onClick: function onClick() {
467
- var ref = seqPanelRef.current;
468
-
469
- if (ref) {
470
- (0, _copyToClipboard.default)(ref.innerHTML, {
471
- format: 'text/html'
472
- });
473
- setCopiedHtml(true);
474
- setTimeout(function () {
475
- return setCopiedHtml(false);
476
- }, 1000);
477
- }
478
- }
479
- }, copiedHtml ? 'Copied to clipboard!' : 'Copy as HTML')), /*#__PURE__*/_react.default.createElement("div", {
480
- "data-testid": "feature_sequence"
481
- }, error ? /*#__PURE__*/_react.default.createElement(_core.Typography, {
482
- color: "error"
483
- }, "".concat(error)) : loading ? /*#__PURE__*/_react.default.createElement("div", null, "Loading gene sequence...") : sequence ? /*#__PURE__*/_react.default.createElement(SequencePanel, {
484
- ref: seqPanelRef,
485
- feature: parentFeature,
486
- mode: mode,
487
- sequence: sequence
488
- }) : /*#__PURE__*/_react.default.createElement("div", null, "No sequence found")));
489
- }
180
+ ;
181
+ (async () => {
182
+ try {
183
+ const { start, end, refName } = feature;
184
+ const seq = await fetchSeq(start, end, refName);
185
+ const up = await fetchSeq(Math.max(0, start - 500), start, refName);
186
+ const down = await fetchSeq(end, end + 500, refName);
187
+ if (!finished) {
188
+ setSequence({ seq, upstream: up, downstream: down });
189
+ }
190
+ }
191
+ catch (e) {
192
+ setError(e);
193
+ }
194
+ })();
195
+ return () => {
196
+ finished = true;
197
+ };
198
+ }, [feature, inView, model]);
199
+ const loading = !sequence;
200
+ return (react_1.default.createElement("div", { ref: ref },
201
+ react_1.default.createElement(material_1.FormControl, null,
202
+ react_1.default.createElement(material_1.Select, { value: mode, onChange: event => setMode(event.target.value) },
203
+ hasCDS ? react_1.default.createElement(material_1.MenuItem, { value: "cds" }, "CDS") : null,
204
+ hasCDS ? react_1.default.createElement(material_1.MenuItem, { value: "protein" }, "Protein") : null,
205
+ react_1.default.createElement(material_1.MenuItem, { value: "gene" }, "Gene w/ introns"),
206
+ react_1.default.createElement(material_1.MenuItem, { value: "gene_collapsed_intron" }, "Gene w/ 10bp of intron"),
207
+ react_1.default.createElement(material_1.MenuItem, { value: "gene_updownstream" }, "Gene w/ 500bp up+down stream"),
208
+ react_1.default.createElement(material_1.MenuItem, { value: "gene_updownstream_collapsed_intron" }, "Gene w/ 500bp up+down stream w/ 10bp intron"),
209
+ react_1.default.createElement(material_1.MenuItem, { value: "cdna" }, "cDNA"))),
210
+ react_1.default.createElement(material_1.Button, { className: classes.button, type: "button", variant: "contained", onClick: () => {
211
+ const ref = seqPanelRef.current;
212
+ if (ref) {
213
+ (0, copy_to_clipboard_1.default)(ref.textContent || '', { format: 'text/plain' });
214
+ setCopied(true);
215
+ setTimeout(() => setCopied(false), 1000);
216
+ }
217
+ } }, copied ? 'Copied to clipboard!' : 'Copy as plaintext'),
218
+ react_1.default.createElement(material_1.Tooltip, { title: "Note that 'Copy as HTML' can retain the colors but cannot be pasted into some programs like notepad that only expect plain text" },
219
+ react_1.default.createElement(material_1.Button, { className: classes.button, type: "button", variant: "contained", onClick: () => {
220
+ const ref = seqPanelRef.current;
221
+ if (ref) {
222
+ (0, copy_to_clipboard_1.default)(ref.innerHTML, { format: 'text/html' });
223
+ setCopiedHtml(true);
224
+ setTimeout(() => setCopiedHtml(false), 1000);
225
+ }
226
+ } }, copiedHtml ? 'Copied to clipboard!' : 'Copy as HTML')),
227
+ react_1.default.createElement("div", { "data-testid": "feature_sequence" }, error ? (react_1.default.createElement(material_1.Typography, { color: "error" }, `${error}`)) : loading ? (react_1.default.createElement("div", null, "Loading gene sequence...")) : sequence ? (react_1.default.createElement(exports.SequencePanel, { ref: seqPanelRef, feature: parentFeature, mode: mode, sequence: sequence })) : (react_1.default.createElement("div", null, "No sequence found")))));
228
+ }
229
+ exports.default = SequenceFeatureDetails;