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