@jbrowse/plugin-legacy-jbrowse 1.6.9 → 1.7.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.
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.clone = clone;
9
+ exports.deepUpdate = deepUpdate;
10
+ exports.fillTemplate = fillTemplate;
11
+ exports.isSource = isSource;
12
+ exports.isTrack = isTrack;
13
+
14
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
15
+
16
+ var _getValue = _interopRequireDefault(require("get-value"));
17
+
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ function isTrack(arg) {
20
+ return arg && arg.label && typeof arg.label === 'string';
21
+ } // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+
23
+
24
+ function isSource(arg) {
25
+ return arg && arg.url && typeof arg.url === 'string';
26
+ }
27
+ /**
28
+ * updates a with values from b, recursively
29
+ */
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+
32
+
33
+ function deepUpdate(a, b) {
34
+ for (var _i = 0, _Object$keys = Object.keys(b); _i < _Object$keys.length; _i++) {
35
+ var prop = _Object$keys[_i];
36
+
37
+ if (prop in a && (0, _typeof2["default"])(b[prop]) === 'object' && (0, _typeof2["default"])(a[prop]) === 'object') {
38
+ deepUpdate(a[prop], b[prop]);
39
+ } else if (typeof a[prop] === 'undefined' || typeof b[prop] !== 'undefined') {
40
+ a[prop] = b[prop];
41
+ }
42
+ }
43
+
44
+ return a;
45
+ }
46
+ /**
47
+ * replace variables in a template string with values
48
+ * @param template - String with variable names in curly brackets
49
+ * e.g., `http://foo/{bar}?arg={baz.foo}`
50
+ * @param fillWith - object with attribute-value mappings
51
+ * e.g., `{ 'bar': 'someurl', 'baz': { 'foo': 42 } }`
52
+ * @returns the template string with variables in fillWith replaced
53
+ * e.g., 'htp://foo/someurl?arg=valueforbaz'
54
+ */
55
+
56
+
57
+ function fillTemplate(template, fillWith) {
58
+ var _this = this;
59
+
60
+ return template.replace(/\{([\w\s.]+)\}/g, function (match, varName) {
61
+ varName = varName.replace(/\s+/g, ''); // remove all whitespace
62
+
63
+ var fill = (0, _getValue["default"])(fillWith, varName);
64
+
65
+ if (fill !== undefined) {
66
+ if (typeof fill === 'function') {
67
+ return fill(varName);
68
+ }
69
+
70
+ return fill;
71
+ }
72
+
73
+ if (fillWith.callback) {
74
+ // @ts-ignore
75
+ var v = fillWith.callback.call(_this, varName);
76
+
77
+ if (v !== undefined) {
78
+ return v;
79
+ }
80
+ }
81
+
82
+ return match;
83
+ });
84
+ }
85
+ /**
86
+ * Clones objects (including DOM nodes) and all children.
87
+ * Warning: do not clone cyclic structures
88
+ * (Lifted from dojo https://github.com/dojo/dojo/blob/master/_base/lang.js)
89
+ * @param src - The object to clone
90
+ */
91
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
92
+
93
+
94
+ function clone(src) {
95
+ if (!src || (0, _typeof2["default"])(src) !== 'object' || Object.prototype.toString.call(src) === '[object Function]') {
96
+ // null, undefined, any non-object, or function
97
+ return src; // anything
98
+ }
99
+
100
+ if (src.nodeType && 'cloneNode' in src) {
101
+ // DOM Node
102
+ return src.cloneNode(true); // Node
103
+ }
104
+
105
+ if (src instanceof Date) {
106
+ // Date
107
+ return new Date(src.getTime()); // Date
108
+ }
109
+
110
+ if (src instanceof RegExp) {
111
+ // RegExp
112
+ return new RegExp(src); // RegExp
113
+ }
114
+
115
+ var r;
116
+ var i;
117
+ var l;
118
+
119
+ if (Array.isArray(src)) {
120
+ // array
121
+ r = [];
122
+
123
+ for (i = 0, l = src.length; i < l; ++i) {
124
+ if (i in src) {
125
+ r[i] = clone(src[i]);
126
+ }
127
+ } // we don't clone functions for performance reasons
128
+ // }else if(d.isFunction(src)){
129
+ // // function
130
+ // r = function(){ return src.apply(this, arguments); };
131
+
132
+ } else {
133
+ // generic objects
134
+ r = src.constructor ? new src.constructor() : {};
135
+ }
136
+
137
+ return mixin(r, src, clone);
138
+ }
139
+ /**
140
+ * Copies/adds all properties of source to dest; returns dest.
141
+ * (Lifted from dojo https://github.com/dojo/dojo/blob/master/_base/lang.js)
142
+ *
143
+ * All properties, including functions (sometimes termed "methods"), excluding
144
+ * any non-standard extensions found in Object.prototype, are copied/added to
145
+ * dest. Copying/adding each particular property is delegated to copyFunc
146
+ * (if any); copyFunc defaults to the Javascript assignment operator if not
147
+ * provided. Notice that by default, mixin executes a so-called "shallow copy"
148
+ * and aggregate types are copied/added by reference.
149
+ * @param dest - The object to which to copy/add all properties contained in
150
+ * source.
151
+ * @param source - The object from which to draw all properties to copy into dest.
152
+ * @param copyFunc - The process used to copy/add a property in source; defaults
153
+ * to the Javascript assignment operator.
154
+ * @returns dest, as modified
155
+ */
156
+
157
+
158
+ function mixin(dest, source, copyFunc) {
159
+ var name;
160
+ var s;
161
+ var empty = {};
162
+
163
+ for (name in source) {
164
+ // the (!(name in empty) || empty[name] !== s) condition avoids copying
165
+ // properties in "source" inherited from Object.prototype. For example,
166
+ // if dest has a custom toString() method, don't overwrite it with the
167
+ // toString() method that source inherited from Object.prototype
168
+ s = source[name];
169
+
170
+ if (!(name in dest) || // @ts-ignore
171
+ dest[name] !== s && (!(name in empty) || empty[name] !== s)) {
172
+ dest[name] = copyFunc ? copyFunc(s) : s;
173
+ }
174
+ }
175
+
176
+ return dest; // Object
177
+ }
@@ -0,0 +1,350 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports["default"] = void 0;
9
+
10
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
+
12
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
+
14
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
15
+
16
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
17
+
18
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
19
+
20
+ var _bufferCrc = _interopRequireDefault(require("buffer-crc32"));
21
+
22
+ /*
23
+ * Helper class allows reading names index generated in JBrowse1
24
+ * Adapted from https://github.com/GMOD/jbrowse/blob/master/src/JBrowse/Store/Hash.js
25
+ */
26
+ var HttpMap = /*#__PURE__*/function () {
27
+ function HttpMap(args) {
28
+ (0, _classCallCheck2["default"])(this, HttpMap);
29
+ (0, _defineProperty2["default"])(this, "url", void 0);
30
+ // make sure url has a trailing slash
31
+ this.url = /\/$/.test(args.url) ? args.url : "".concat(args.url, "/");
32
+ }
33
+ /**
34
+ * loads meta.json file from names directory and reads number of hash_bits used
35
+ */
36
+
37
+
38
+ (0, _createClass2["default"])(HttpMap, [{
39
+ key: "readMeta",
40
+ value: function () {
41
+ var _readMeta = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
42
+ var meta, compress, tracks, hashHexCharacters;
43
+ return _regenerator["default"].wrap(function _callee$(_context) {
44
+ while (1) {
45
+ switch (_context.prev = _context.next) {
46
+ case 0:
47
+ _context.next = 2;
48
+ return this.loadFile('meta.json');
49
+
50
+ case 2:
51
+ meta = _context.sent;
52
+ compress = meta.compress, tracks = meta.track_names;
53
+ hashHexCharacters = Math.ceil(meta.hash_bits / 4);
54
+ return _context.abrupt("return", {
55
+ hashHexCharacters: hashHexCharacters,
56
+ compress: compress,
57
+ tracks: tracks
58
+ });
59
+
60
+ case 6:
61
+ case "end":
62
+ return _context.stop();
63
+ }
64
+ }
65
+ }, _callee, this);
66
+ }));
67
+
68
+ function readMeta() {
69
+ return _readMeta.apply(this, arguments);
70
+ }
71
+
72
+ return readMeta;
73
+ }()
74
+ }, {
75
+ key: "getHashHexCharacters",
76
+ value: function () {
77
+ var _getHashHexCharacters = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
78
+ var meta;
79
+ return _regenerator["default"].wrap(function _callee2$(_context2) {
80
+ while (1) {
81
+ switch (_context2.prev = _context2.next) {
82
+ case 0:
83
+ _context2.next = 2;
84
+ return this.readMeta();
85
+
86
+ case 2:
87
+ meta = _context2.sent;
88
+ return _context2.abrupt("return", meta.hashHexCharacters);
89
+
90
+ case 4:
91
+ case "end":
92
+ return _context2.stop();
93
+ }
94
+ }
95
+ }, _callee2, this);
96
+ }));
97
+
98
+ function getHashHexCharacters() {
99
+ return _getHashHexCharacters.apply(this, arguments);
100
+ }
101
+
102
+ return getHashHexCharacters;
103
+ }()
104
+ }, {
105
+ key: "getCompress",
106
+ value: function () {
107
+ var _getCompress = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() {
108
+ var meta;
109
+ return _regenerator["default"].wrap(function _callee3$(_context3) {
110
+ while (1) {
111
+ switch (_context3.prev = _context3.next) {
112
+ case 0:
113
+ _context3.next = 2;
114
+ return this.readMeta();
115
+
116
+ case 2:
117
+ meta = _context3.sent;
118
+ return _context3.abrupt("return", meta.compress);
119
+
120
+ case 4:
121
+ case "end":
122
+ return _context3.stop();
123
+ }
124
+ }
125
+ }, _callee3, this);
126
+ }));
127
+
128
+ function getCompress() {
129
+ return _getCompress.apply(this, arguments);
130
+ }
131
+
132
+ return getCompress;
133
+ }()
134
+ }, {
135
+ key: "getTrackNames",
136
+ value: function () {
137
+ var _getTrackNames = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4() {
138
+ var meta;
139
+ return _regenerator["default"].wrap(function _callee4$(_context4) {
140
+ while (1) {
141
+ switch (_context4.prev = _context4.next) {
142
+ case 0:
143
+ _context4.next = 2;
144
+ return this.readMeta();
145
+
146
+ case 2:
147
+ meta = _context4.sent;
148
+ return _context4.abrupt("return", meta.tracks);
149
+
150
+ case 4:
151
+ case "end":
152
+ return _context4.stop();
153
+ }
154
+ }
155
+ }, _callee4, this);
156
+ }));
157
+
158
+ function getTrackNames() {
159
+ return _getTrackNames.apply(this, arguments);
160
+ }
161
+
162
+ return getTrackNames;
163
+ }()
164
+ /**
165
+ * Returns contents of a bucket given a key
166
+ * @param key - string
167
+ */
168
+
169
+ }, {
170
+ key: "get",
171
+ value: function () {
172
+ var _get = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5(key) {
173
+ var bucket;
174
+ return _regenerator["default"].wrap(function _callee5$(_context5) {
175
+ while (1) {
176
+ switch (_context5.prev = _context5.next) {
177
+ case 0:
178
+ _context5.next = 2;
179
+ return this.getBucket(key);
180
+
181
+ case 2:
182
+ bucket = _context5.sent;
183
+ return _context5.abrupt("return", bucket[key]);
184
+
185
+ case 4:
186
+ case "end":
187
+ return _context5.stop();
188
+ }
189
+ }
190
+ }, _callee5, this);
191
+ }));
192
+
193
+ function get(_x) {
194
+ return _get.apply(this, arguments);
195
+ }
196
+
197
+ return get;
198
+ }()
199
+ /**
200
+ * Returns a bucket given a key
201
+ * @param key - string
202
+ */
203
+
204
+ }, {
205
+ key: "getBucket",
206
+ value: function () {
207
+ var _getBucket = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee6(key) {
208
+ var bucketIdent, hexToDirPath;
209
+ return _regenerator["default"].wrap(function _callee6$(_context6) {
210
+ while (1) {
211
+ switch (_context6.prev = _context6.next) {
212
+ case 0:
213
+ bucketIdent = this.hash(key);
214
+ _context6.next = 3;
215
+ return this.hexToDirPath(bucketIdent);
216
+
217
+ case 3:
218
+ hexToDirPath = _context6.sent;
219
+ return _context6.abrupt("return", this.loadFile(hexToDirPath));
220
+
221
+ case 5:
222
+ case "end":
223
+ return _context6.stop();
224
+ }
225
+ }
226
+ }, _callee6, this);
227
+ }));
228
+
229
+ function getBucket(_x2) {
230
+ return _getBucket.apply(this, arguments);
231
+ }
232
+
233
+ return getBucket;
234
+ }()
235
+ /**
236
+ * Loads a file using the url and provided id.
237
+ * Returns response object with contents of the file
238
+ * @param id - string
239
+ */
240
+
241
+ }, {
242
+ key: "loadFile",
243
+ value: function () {
244
+ var _loadFile = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee7(id) {
245
+ var response;
246
+ return _regenerator["default"].wrap(function _callee7$(_context7) {
247
+ while (1) {
248
+ switch (_context7.prev = _context7.next) {
249
+ case 0:
250
+ _context7.next = 2;
251
+ return fetch("".concat(this.url).concat(id));
252
+
253
+ case 2:
254
+ response = _context7.sent;
255
+
256
+ if (response.ok) {
257
+ _context7.next = 5;
258
+ break;
259
+ }
260
+
261
+ throw new Error("HTTP ".concat(response.status, " ").concat(response.statusText));
262
+
263
+ case 5:
264
+ return _context7.abrupt("return", response.json());
265
+
266
+ case 6:
267
+ case "end":
268
+ return _context7.stop();
269
+ }
270
+ }
271
+ }, _callee7, this);
272
+ }));
273
+
274
+ function loadFile(_x3) {
275
+ return _loadFile.apply(this, arguments);
276
+ }
277
+
278
+ return loadFile;
279
+ }()
280
+ /**
281
+ * Returns the corresponding path of the file given a hex string
282
+ * @param hex - hex string
283
+ */
284
+
285
+ }, {
286
+ key: "hexToDirPath",
287
+ value: function () {
288
+ var _hexToDirPath = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee8(hex) {
289
+ var hashHexCharacters, compress, dirpath, i;
290
+ return _regenerator["default"].wrap(function _callee8$(_context8) {
291
+ while (1) {
292
+ switch (_context8.prev = _context8.next) {
293
+ case 0:
294
+ _context8.next = 2;
295
+ return this.getHashHexCharacters();
296
+
297
+ case 2:
298
+ hashHexCharacters = _context8.sent;
299
+
300
+ if (!hashHexCharacters) {
301
+ _context8.next = 12;
302
+ break;
303
+ }
304
+
305
+ _context8.next = 6;
306
+ return this.getCompress();
307
+
308
+ case 6:
309
+ compress = _context8.sent;
310
+
311
+ while (hex.length < 8) {
312
+ hex = "0".concat(hex);
313
+ }
314
+
315
+ hex = hex.substr(8 - hashHexCharacters);
316
+ dirpath = [];
317
+
318
+ for (i = 0; i < hex.length; i += 3) {
319
+ dirpath.push(hex.substring(i, i + 3));
320
+ }
321
+
322
+ return _context8.abrupt("return", "".concat(dirpath.join('/'), ".json").concat(compress ? 'z' : ''));
323
+
324
+ case 12:
325
+ return _context8.abrupt("return", '');
326
+
327
+ case 13:
328
+ case "end":
329
+ return _context8.stop();
330
+ }
331
+ }
332
+ }, _callee8, this);
333
+ }));
334
+
335
+ function hexToDirPath(_x4) {
336
+ return _hexToDirPath.apply(this, arguments);
337
+ }
338
+
339
+ return hexToDirPath;
340
+ }()
341
+ }, {
342
+ key: "hash",
343
+ value: function hash(data) {
344
+ return (0, _bufferCrc["default"])(Buffer.from(data)).toString('hex').toLowerCase().replace('-', 'n');
345
+ }
346
+ }]);
347
+ return HttpMap;
348
+ }();
349
+
350
+ exports["default"] = HttpMap;
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
6
+
7
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
8
+
9
+ var _path = _interopRequireDefault(require("path"));
10
+
11
+ var _meta = _interopRequireDefault(require("../../test_data/names/meta.json"));
12
+
13
+ var _ = _interopRequireDefault(require("../../test_data/names/0.json"));
14
+
15
+ var _f = _interopRequireDefault(require("../../test_data/names/f.json"));
16
+
17
+ var _HttpMap = _interopRequireDefault(require("./HttpMap"));
18
+
19
+ describe('test JBrowse1 hash implementation', function () {
20
+ test('read from meta', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
21
+ var mockFetch, rootTemplate, spy, hashMap;
22
+ return _regenerator["default"].wrap(function _callee$(_context) {
23
+ while (1) {
24
+ switch (_context.prev = _context.next) {
25
+ case 0:
26
+ mockFetch = function _mockFetch(url) {
27
+ var response = {};
28
+
29
+ if (url.includes('names/meta.json')) {
30
+ response = _meta["default"];
31
+ }
32
+
33
+ return Promise.resolve(new Response(JSON.stringify(response)));
34
+ };
35
+
36
+ rootTemplate = _path["default"].join(__dirname, '..', '..', '..', '..', 'test_data', 'names').replace(/\\/g, '\\\\');
37
+ spy = jest.spyOn(global, 'fetch'); // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+
39
+ spy.mockImplementation(mockFetch);
40
+ hashMap = new _HttpMap["default"]({
41
+ url: rootTemplate
42
+ });
43
+ _context.next = 7;
44
+ return hashMap.getBucket('apple');
45
+
46
+ case 7:
47
+ _context.t0 = expect;
48
+ _context.next = 10;
49
+ return hashMap.getHashHexCharacters();
50
+
51
+ case 10:
52
+ _context.t1 = _context.sent;
53
+ (0, _context.t0)(_context.t1).toBe(1);
54
+ _context.t2 = expect;
55
+ _context.next = 15;
56
+ return hashMap.getCompress();
57
+
58
+ case 15:
59
+ _context.t3 = _context.sent;
60
+ (0, _context.t2)(_context.t3).toBe(0);
61
+
62
+ case 17:
63
+ case "end":
64
+ return _context.stop();
65
+ }
66
+ }
67
+ }, _callee);
68
+ })));
69
+ test('get bucket contents', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
70
+ var mockFetch, rootTemplate, spy, hashMap;
71
+ return _regenerator["default"].wrap(function _callee2$(_context2) {
72
+ while (1) {
73
+ switch (_context2.prev = _context2.next) {
74
+ case 0:
75
+ mockFetch = function _mockFetch2(url) {
76
+ var response = {};
77
+
78
+ if (url.includes('names/meta.json')) {
79
+ response = _meta["default"];
80
+ }
81
+
82
+ if (url.includes('names/0.json')) {
83
+ response = _["default"];
84
+ }
85
+
86
+ if (url.includes('names/f.json')) {
87
+ response = _f["default"];
88
+ }
89
+
90
+ return Promise.resolve(new Response(JSON.stringify(response)));
91
+ };
92
+
93
+ rootTemplate = _path["default"].join(__dirname, '..', '..', '..', '..', 'test_data', 'names').replace(/\\/g, '\\\\');
94
+ spy = jest.spyOn(global, 'fetch'); // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
+
96
+ spy.mockImplementation(mockFetch);
97
+ hashMap = new _HttpMap["default"]({
98
+ url: rootTemplate
99
+ });
100
+ _context2.next = 7;
101
+ return hashMap.getBucket('apple');
102
+
103
+ case 7:
104
+ expect(spy).toHaveBeenLastCalledWith("".concat(rootTemplate, "/0.json"));
105
+ _context2.next = 10;
106
+ return hashMap.getBucket('apple3');
107
+
108
+ case 10:
109
+ expect(spy).toHaveBeenLastCalledWith("".concat(rootTemplate, "/f.json"));
110
+
111
+ case 11:
112
+ case "end":
113
+ return _context2.stop();
114
+ }
115
+ }
116
+ }, _callee2);
117
+ })));
118
+ });