@gmod/bam 1.1.17 → 2.0.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 (83) hide show
  1. package/CHANGELOG.md +65 -25
  2. package/README.md +108 -57
  3. package/dist/bai.d.ts +34 -15
  4. package/dist/bai.js +180 -273
  5. package/dist/bai.js.map +1 -1
  6. package/dist/bamFile.d.ts +33 -27
  7. package/dist/bamFile.js +353 -572
  8. package/dist/bamFile.js.map +1 -1
  9. package/dist/chunk.d.ts +4 -8
  10. package/dist/chunk.js +13 -21
  11. package/dist/chunk.js.map +1 -1
  12. package/dist/csi.d.ts +74 -10
  13. package/dist/csi.js +157 -256
  14. package/dist/csi.js.map +1 -1
  15. package/dist/errors.js +12 -57
  16. package/dist/errors.js.map +1 -1
  17. package/dist/htsget.d.ts +5 -8
  18. package/dist/htsget.js +120 -209
  19. package/dist/htsget.js.map +1 -1
  20. package/dist/index.d.ts +5 -6
  21. package/dist/index.js +11 -11
  22. package/dist/index.js.map +1 -1
  23. package/dist/indexFile.d.ts +0 -6
  24. package/dist/indexFile.js +3 -77
  25. package/dist/indexFile.js.map +1 -1
  26. package/dist/nullIndex.d.ts +7 -0
  27. package/dist/nullIndex.js +33 -0
  28. package/dist/nullIndex.js.map +1 -0
  29. package/dist/record.d.ts +2 -2
  30. package/dist/record.js +200 -193
  31. package/dist/record.js.map +1 -1
  32. package/dist/sam.js +12 -10
  33. package/dist/sam.js.map +1 -1
  34. package/dist/util.d.ts +13 -1
  35. package/dist/util.js +55 -58
  36. package/dist/util.js.map +1 -1
  37. package/dist/virtualOffset.js +13 -20
  38. package/dist/virtualOffset.js.map +1 -1
  39. package/esm/bai.d.ts +34 -15
  40. package/esm/bai.js +86 -91
  41. package/esm/bai.js.map +1 -1
  42. package/esm/bamFile.d.ts +33 -27
  43. package/esm/bamFile.js +124 -120
  44. package/esm/bamFile.js.map +1 -1
  45. package/esm/chunk.d.ts +4 -8
  46. package/esm/chunk.js +2 -8
  47. package/esm/chunk.js.map +1 -1
  48. package/esm/csi.d.ts +74 -10
  49. package/esm/csi.js +85 -93
  50. package/esm/csi.js.map +1 -1
  51. package/esm/htsget.d.ts +5 -8
  52. package/esm/htsget.js +68 -43
  53. package/esm/htsget.js.map +1 -1
  54. package/esm/index.d.ts +5 -6
  55. package/esm/index.js +5 -6
  56. package/esm/index.js.map +1 -1
  57. package/esm/indexFile.d.ts +0 -6
  58. package/esm/indexFile.js +0 -22
  59. package/esm/indexFile.js.map +1 -1
  60. package/esm/nullIndex.d.ts +7 -0
  61. package/esm/nullIndex.js +16 -0
  62. package/esm/nullIndex.js.map +1 -0
  63. package/esm/record.d.ts +2 -2
  64. package/esm/record.js +34 -24
  65. package/esm/record.js.map +1 -1
  66. package/esm/sam.js +9 -7
  67. package/esm/sam.js.map +1 -1
  68. package/esm/util.d.ts +13 -1
  69. package/esm/util.js +40 -14
  70. package/esm/util.js.map +1 -1
  71. package/package.json +19 -20
  72. package/src/bai.ts +99 -102
  73. package/src/bamFile.ts +174 -198
  74. package/src/chunk.ts +6 -20
  75. package/src/csi.ts +102 -111
  76. package/src/htsget.ts +81 -61
  77. package/src/index.ts +5 -7
  78. package/src/indexFile.ts +0 -27
  79. package/src/nullIndex.ts +18 -0
  80. package/src/record.ts +34 -24
  81. package/src/sam.ts +9 -7
  82. package/src/util.ts +54 -13
  83. package/src/declare.d.ts +0 -2
package/dist/bamFile.js CHANGED
@@ -1,15 +1,4 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
2
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
3
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
4
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -19,33 +8,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
19
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
20
9
  });
21
10
  };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (_) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
11
  var __asyncValues = (this && this.__asyncValues) || function (o) {
50
12
  if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
51
13
  var m = o[Symbol.asyncIterator], i;
@@ -57,7 +19,7 @@ var __await = (this && this.__await) || function (v) { return this instanceof __
57
19
  var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
58
20
  var i, p;
59
21
  return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
60
- function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
22
+ function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }
61
23
  };
62
24
  var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
63
25
  if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
@@ -70,120 +32,82 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
70
32
  function reject(value) { resume("throw", value); }
71
33
  function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
72
34
  };
73
- var __values = (this && this.__values) || function(o) {
74
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
75
- if (m) return m.call(o);
76
- if (o && typeof o.length === "number") return {
77
- next: function () {
78
- if (o && i >= o.length) o = void 0;
79
- return { value: o && o[i++], done: !o };
80
- }
81
- };
82
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
83
- };
84
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
85
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
86
37
  };
87
38
  Object.defineProperty(exports, "__esModule", { value: true });
88
39
  exports.BAM_MAGIC = void 0;
89
- var buffer_crc32_1 = __importDefault(require("buffer-crc32"));
90
- var bgzf_filehandle_1 = require("@gmod/bgzf-filehandle");
91
- var object_entries_ponyfill_1 = __importDefault(require("object.entries-ponyfill"));
92
- var generic_filehandle_1 = require("generic-filehandle");
93
- var abortable_promise_cache_1 = __importDefault(require("abortable-promise-cache"));
94
- var quick_lru_1 = __importDefault(require("quick-lru"));
95
- //locals
96
- var bai_1 = __importDefault(require("./bai"));
97
- var csi_1 = __importDefault(require("./csi"));
98
- var record_1 = __importDefault(require("./record"));
99
- var sam_1 = require("./sam");
100
- var util_1 = require("./util");
40
+ const buffer_1 = require("buffer");
41
+ const buffer_crc32_1 = __importDefault(require("buffer-crc32"));
42
+ const bgzf_filehandle_1 = require("@gmod/bgzf-filehandle");
43
+ const generic_filehandle_1 = require("generic-filehandle");
44
+ const abortable_promise_cache_1 = __importDefault(require("abortable-promise-cache"));
45
+ const quick_lru_1 = __importDefault(require("quick-lru"));
46
+ // locals
47
+ const bai_1 = __importDefault(require("./bai"));
48
+ const csi_1 = __importDefault(require("./csi"));
49
+ const record_1 = __importDefault(require("./record"));
50
+ const sam_1 = require("./sam");
51
+ const util_1 = require("./util");
101
52
  exports.BAM_MAGIC = 21840194;
102
- var blockLen = 1 << 16;
103
- function flat(arr) {
104
- var _a;
105
- return (_a = []).concat.apply(_a, arr);
106
- }
53
+ const blockLen = 1 << 16;
107
54
  function gen2array(gen) {
108
- var gen_1, gen_1_1;
109
- var e_1, _a;
110
- return __awaiter(this, void 0, void 0, function () {
111
- var out, x, e_1_1;
112
- return __generator(this, function (_b) {
113
- switch (_b.label) {
114
- case 0:
115
- out = [];
116
- _b.label = 1;
117
- case 1:
118
- _b.trys.push([1, 6, 7, 12]);
119
- gen_1 = __asyncValues(gen);
120
- _b.label = 2;
121
- case 2: return [4 /*yield*/, gen_1.next()];
122
- case 3:
123
- if (!(gen_1_1 = _b.sent(), !gen_1_1.done)) return [3 /*break*/, 5];
124
- x = gen_1_1.value;
125
- out.push(x);
126
- _b.label = 4;
127
- case 4: return [3 /*break*/, 2];
128
- case 5: return [3 /*break*/, 12];
129
- case 6:
130
- e_1_1 = _b.sent();
131
- e_1 = { error: e_1_1 };
132
- return [3 /*break*/, 12];
133
- case 7:
134
- _b.trys.push([7, , 10, 11]);
135
- if (!(gen_1_1 && !gen_1_1.done && (_a = gen_1.return))) return [3 /*break*/, 9];
136
- return [4 /*yield*/, _a.call(gen_1)];
137
- case 8:
138
- _b.sent();
139
- _b.label = 9;
140
- case 9: return [3 /*break*/, 11];
141
- case 10:
142
- if (e_1) throw e_1.error;
143
- return [7 /*endfinally*/];
144
- case 11: return [7 /*endfinally*/];
145
- case 12: return [2 /*return*/, out];
55
+ var _a, gen_1, gen_1_1;
56
+ var _b, e_1, _c, _d;
57
+ return __awaiter(this, void 0, void 0, function* () {
58
+ let out = [];
59
+ try {
60
+ for (_a = true, gen_1 = __asyncValues(gen); gen_1_1 = yield gen_1.next(), _b = gen_1_1.done, !_b;) {
61
+ _d = gen_1_1.value;
62
+ _a = false;
63
+ try {
64
+ const x = _d;
65
+ out = out.concat(x);
66
+ }
67
+ finally {
68
+ _a = true;
69
+ }
146
70
  }
147
- });
71
+ }
72
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
73
+ finally {
74
+ try {
75
+ if (!_a && !_b && (_c = gen_1.return)) yield _c.call(gen_1);
76
+ }
77
+ finally { if (e_1) throw e_1.error; }
78
+ }
79
+ return out;
148
80
  });
149
81
  }
150
- var BamFile = /** @class */ (function () {
151
- /**
152
- * @param {object} args
153
- * @param {string} [args.bamPath]
154
- * @param {FileHandle} [args.bamFilehandle]
155
- * @param {string} [args.baiPath]
156
- * @param {FileHandle} [args.baiFilehandle]
157
- */
158
- function BamFile(_a) {
159
- var bamFilehandle = _a.bamFilehandle, bamPath = _a.bamPath, bamUrl = _a.bamUrl, baiPath = _a.baiPath, baiFilehandle = _a.baiFilehandle, baiUrl = _a.baiUrl, csiPath = _a.csiPath, csiFilehandle = _a.csiFilehandle, csiUrl = _a.csiUrl, fetchSizeLimit = _a.fetchSizeLimit, chunkSizeLimit = _a.chunkSizeLimit, _b = _a.yieldThreadTime, yieldThreadTime = _b === void 0 ? 100 : _b, _c = _a.renameRefSeqs, renameRefSeqs = _c === void 0 ? function (n) { return n; } : _c;
160
- var _this = this;
82
+ class NullFilehandle {
83
+ read() {
84
+ throw new Error('never called');
85
+ }
86
+ stat() {
87
+ throw new Error('never called');
88
+ }
89
+ readFile() {
90
+ throw new Error('never called');
91
+ }
92
+ close() {
93
+ throw new Error('never called');
94
+ }
95
+ }
96
+ class BamFile {
97
+ constructor({ bamFilehandle, bamPath, bamUrl, baiPath, baiFilehandle, baiUrl, csiPath, csiFilehandle, csiUrl, htsget, yieldThreadTime = 100, renameRefSeqs = n => n, }) {
98
+ this.htsget = false;
161
99
  this.featureCache = new abortable_promise_cache_1.default({
162
- //@ts-ignore
163
100
  cache: new quick_lru_1.default({
164
101
  maxSize: 50,
165
102
  }),
166
- //@ts-ignore
167
- fill: function (_a, signal) {
168
- var chunk = _a.chunk, opts = _a.opts;
169
- return __awaiter(_this, void 0, void 0, function () {
170
- var _b, data, cpositions, dpositions, feats;
171
- return __generator(this, function (_c) {
172
- switch (_c.label) {
173
- case 0: return [4 /*yield*/, this._readChunk({
174
- chunk: chunk,
175
- opts: __assign(__assign({}, opts), { signal: signal }),
176
- })];
177
- case 1:
178
- _b = _c.sent(), data = _b.data, cpositions = _b.cpositions, dpositions = _b.dpositions;
179
- return [4 /*yield*/, this.readBamFeatures(data, cpositions, dpositions, chunk)];
180
- case 2:
181
- feats = _c.sent();
182
- return [2 /*return*/, feats];
183
- }
184
- });
103
+ fill: (args, signal) => __awaiter(this, void 0, void 0, function* () {
104
+ const { chunk, opts } = args;
105
+ const { data, cpositions, dpositions } = yield this._readChunk({
106
+ chunk,
107
+ opts: Object.assign(Object.assign({}, opts), { signal }),
185
108
  });
186
- },
109
+ return this.readBamFeatures(data, cpositions, dpositions, chunk);
110
+ }),
187
111
  });
188
112
  this.renameRefSeq = renameRefSeqs;
189
113
  if (bamFilehandle) {
@@ -195,6 +119,10 @@ var BamFile = /** @class */ (function () {
195
119
  else if (bamUrl) {
196
120
  this.bam = new generic_filehandle_1.RemoteFile(bamUrl);
197
121
  }
122
+ else if (htsget) {
123
+ this.htsget = true;
124
+ this.bam = new NullFilehandle();
125
+ }
198
126
  else {
199
127
  throw new Error('unable to initialize bam');
200
128
  }
@@ -217,473 +145,326 @@ var BamFile = /** @class */ (function () {
217
145
  this.index = new bai_1.default({ filehandle: new generic_filehandle_1.RemoteFile(baiUrl) });
218
146
  }
219
147
  else if (bamPath) {
220
- this.index = new bai_1.default({ filehandle: new generic_filehandle_1.LocalFile("".concat(bamPath, ".bai")) });
148
+ this.index = new bai_1.default({ filehandle: new generic_filehandle_1.LocalFile(`${bamPath}.bai`) });
221
149
  }
222
150
  else if (bamUrl) {
223
- this.index = new bai_1.default({ filehandle: new generic_filehandle_1.RemoteFile("".concat(bamUrl, ".bai")) });
151
+ this.index = new bai_1.default({ filehandle: new generic_filehandle_1.RemoteFile(`${bamUrl}.bai`) });
152
+ }
153
+ else if (htsget) {
154
+ this.htsget = true;
224
155
  }
225
156
  else {
226
157
  throw new Error('unable to infer index format');
227
158
  }
228
- this.fetchSizeLimit = fetchSizeLimit || 500000000; // 500MB
229
- this.chunkSizeLimit = chunkSizeLimit || 300000000; // 300MB
230
159
  this.yieldThreadTime = yieldThreadTime;
231
160
  }
232
- BamFile.prototype.getHeader = function (origOpts) {
233
- if (origOpts === void 0) { origOpts = {}; }
234
- return __awaiter(this, void 0, void 0, function () {
235
- var opts, indexData, ret, buffer, res, bytesRead, uncba, headLen, _a, chrToIndex, indexToChr;
236
- return __generator(this, function (_b) {
237
- switch (_b.label) {
238
- case 0:
239
- opts = (0, util_1.makeOpts)(origOpts);
240
- return [4 /*yield*/, this.index.parse(opts)];
241
- case 1:
242
- indexData = _b.sent();
243
- ret = indexData.firstDataLine
244
- ? indexData.firstDataLine.blockPosition + 65535
245
- : undefined;
246
- if (!ret) return [3 /*break*/, 3];
247
- return [4 /*yield*/, this.bam.read(Buffer.alloc(ret + blockLen), 0, ret + blockLen, 0, opts)];
248
- case 2:
249
- res = _b.sent();
250
- bytesRead = res.bytesRead;
251
- (buffer = res.buffer);
252
- if (!bytesRead) {
253
- throw new Error('Error reading header');
254
- }
255
- if (bytesRead < ret) {
256
- buffer = buffer.subarray(0, bytesRead);
257
- }
258
- else {
259
- buffer = buffer.subarray(0, ret);
260
- }
261
- return [3 /*break*/, 5];
262
- case 3: return [4 /*yield*/, this.bam.readFile(opts)];
263
- case 4:
264
- buffer = (_b.sent());
265
- _b.label = 5;
266
- case 5: return [4 /*yield*/, (0, bgzf_filehandle_1.unzip)(buffer)];
267
- case 6:
268
- uncba = _b.sent();
269
- if (uncba.readInt32LE(0) !== exports.BAM_MAGIC) {
270
- throw new Error('Not a BAM file');
271
- }
272
- headLen = uncba.readInt32LE(4);
273
- this.header = uncba.toString('utf8', 8, 8 + headLen);
274
- return [4 /*yield*/, this._readRefSeqs(headLen + 8, 65535, opts)];
275
- case 7:
276
- _a = _b.sent(), chrToIndex = _a.chrToIndex, indexToChr = _a.indexToChr;
277
- this.chrToIndex = chrToIndex;
278
- this.indexToChr = indexToChr;
279
- return [2 /*return*/, (0, sam_1.parseHeaderText)(this.header)];
161
+ getHeaderPre(origOpts) {
162
+ return __awaiter(this, void 0, void 0, function* () {
163
+ const opts = (0, util_1.makeOpts)(origOpts);
164
+ if (!this.index) {
165
+ return;
166
+ }
167
+ const indexData = yield this.index.parse(opts);
168
+ const ret = indexData.firstDataLine
169
+ ? indexData.firstDataLine.blockPosition + 65535
170
+ : undefined;
171
+ let buffer;
172
+ if (ret) {
173
+ const s = ret + blockLen;
174
+ const res = yield this.bam.read(buffer_1.Buffer.alloc(s), 0, s, 0, opts);
175
+ if (!res.bytesRead) {
176
+ throw new Error('Error reading header');
280
177
  }
281
- });
178
+ buffer = res.buffer.subarray(0, Math.min(res.bytesRead, ret));
179
+ }
180
+ else {
181
+ buffer = (yield this.bam.readFile(opts));
182
+ }
183
+ const uncba = yield (0, bgzf_filehandle_1.unzip)(buffer);
184
+ if (uncba.readInt32LE(0) !== exports.BAM_MAGIC) {
185
+ throw new Error('Not a BAM file');
186
+ }
187
+ const headLen = uncba.readInt32LE(4);
188
+ this.header = uncba.toString('utf8', 8, 8 + headLen);
189
+ const { chrToIndex, indexToChr } = yield this._readRefSeqs(headLen + 8, 65535, opts);
190
+ this.chrToIndex = chrToIndex;
191
+ this.indexToChr = indexToChr;
192
+ return (0, sam_1.parseHeaderText)(this.header);
282
193
  });
283
- };
284
- BamFile.prototype.getHeaderText = function (opts) {
285
- if (opts === void 0) { opts = {}; }
286
- return __awaiter(this, void 0, void 0, function () {
287
- return __generator(this, function (_a) {
288
- switch (_a.label) {
289
- case 0: return [4 /*yield*/, this.getHeader(opts)];
290
- case 1:
291
- _a.sent();
292
- return [2 /*return*/, this.header];
293
- }
194
+ }
195
+ getHeader(opts) {
196
+ if (!this.headerP) {
197
+ this.headerP = this.getHeaderPre(opts).catch(e => {
198
+ this.headerP = undefined;
199
+ throw e;
294
200
  });
201
+ }
202
+ return this.headerP;
203
+ }
204
+ getHeaderText(opts = {}) {
205
+ return __awaiter(this, void 0, void 0, function* () {
206
+ yield this.getHeader(opts);
207
+ return this.header;
295
208
  });
296
- };
209
+ }
297
210
  // the full length of the refseq block is not given in advance so this grabs
298
211
  // a chunk and doubles it if all refseqs haven't been processed
299
- BamFile.prototype._readRefSeqs = function (start, refSeqBytes, opts) {
300
- if (opts === void 0) { opts = {}; }
301
- return __awaiter(this, void 0, void 0, function () {
302
- var size, _a, bytesRead, buffer, uncba, nRef, p, chrToIndex, indexToChr, i, lName, refName, lRef;
303
- return __generator(this, function (_b) {
304
- switch (_b.label) {
305
- case 0:
306
- if (start > refSeqBytes) {
307
- return [2 /*return*/, this._readRefSeqs(start, refSeqBytes * 2, opts)];
308
- }
309
- size = refSeqBytes + blockLen;
310
- return [4 /*yield*/, this.bam.read(Buffer.alloc(size), 0, refSeqBytes, 0, opts)];
311
- case 1:
312
- _a = _b.sent(), bytesRead = _a.bytesRead, buffer = _a.buffer;
313
- if (!bytesRead) {
314
- throw new Error('Error reading refseqs from header');
315
- }
316
- return [4 /*yield*/, (0, bgzf_filehandle_1.unzip)(buffer.subarray(0, Math.min(bytesRead, refSeqBytes)))];
317
- case 2:
318
- uncba = _b.sent();
319
- nRef = uncba.readInt32LE(start);
320
- p = start + 4;
321
- chrToIndex = {};
322
- indexToChr = [];
323
- for (i = 0; i < nRef; i += 1) {
324
- lName = uncba.readInt32LE(p);
325
- refName = this.renameRefSeq(uncba.toString('utf8', p + 4, p + 4 + lName - 1));
326
- lRef = uncba.readInt32LE(p + lName + 4);
327
- chrToIndex[refName] = i;
328
- indexToChr.push({ refName: refName, length: lRef });
329
- p = p + 8 + lName;
330
- if (p > uncba.length) {
331
- console.warn("BAM header is very big. Re-fetching ".concat(refSeqBytes, " bytes."));
332
- return [2 /*return*/, this._readRefSeqs(start, refSeqBytes * 2, opts)];
333
- }
334
- }
335
- return [2 /*return*/, { chrToIndex: chrToIndex, indexToChr: indexToChr }];
212
+ _readRefSeqs(start, refSeqBytes, opts) {
213
+ return __awaiter(this, void 0, void 0, function* () {
214
+ if (start > refSeqBytes) {
215
+ return this._readRefSeqs(start, refSeqBytes * 2, opts);
216
+ }
217
+ const size = refSeqBytes + blockLen;
218
+ const { bytesRead, buffer } = yield this.bam.read(buffer_1.Buffer.alloc(size), 0, refSeqBytes, 0, opts);
219
+ if (!bytesRead) {
220
+ throw new Error('Error reading refseqs from header');
221
+ }
222
+ const uncba = yield (0, bgzf_filehandle_1.unzip)(buffer.subarray(0, Math.min(bytesRead, refSeqBytes)));
223
+ const nRef = uncba.readInt32LE(start);
224
+ let p = start + 4;
225
+ const chrToIndex = {};
226
+ const indexToChr = [];
227
+ for (let i = 0; i < nRef; i += 1) {
228
+ const lName = uncba.readInt32LE(p);
229
+ const refName = this.renameRefSeq(uncba.toString('utf8', p + 4, p + 4 + lName - 1));
230
+ const lRef = uncba.readInt32LE(p + lName + 4);
231
+ chrToIndex[refName] = i;
232
+ indexToChr.push({ refName, length: lRef });
233
+ p = p + 8 + lName;
234
+ if (p > uncba.length) {
235
+ console.warn(`BAM header is very big. Re-fetching ${refSeqBytes} bytes.`);
236
+ return this._readRefSeqs(start, refSeqBytes * 2, opts);
336
237
  }
337
- });
238
+ }
239
+ return { chrToIndex, indexToChr };
338
240
  });
339
- };
340
- BamFile.prototype.getRecordsForRange = function (chr, min, max, opts) {
341
- if (opts === void 0) { opts = {
342
- viewAsPairs: false,
343
- pairAcrossChr: false,
344
- maxInsertSize: 200000,
345
- }; }
346
- return __awaiter(this, void 0, void 0, function () {
347
- var _a;
348
- return __generator(this, function (_b) {
349
- switch (_b.label) {
350
- case 0:
351
- _a = flat;
352
- return [4 /*yield*/, gen2array(this.streamRecordsForRange(chr, min, max, opts))];
353
- case 1: return [2 /*return*/, _a.apply(void 0, [_b.sent()])];
354
- }
355
- });
241
+ }
242
+ getRecordsForRange(chr, min, max, opts) {
243
+ return __awaiter(this, void 0, void 0, function* () {
244
+ return gen2array(this.streamRecordsForRange(chr, min, max, opts));
356
245
  });
357
- };
358
- BamFile.prototype.streamRecordsForRange = function (chr, min, max, opts) {
359
- if (opts === void 0) { opts = {}; }
360
- return __asyncGenerator(this, arguments, function streamRecordsForRange_1() {
361
- var signal, chrId, chunks, i, size, totalSize;
362
- return __generator(this, function (_a) {
363
- switch (_a.label) {
364
- case 0:
365
- signal = opts.signal;
366
- chrId = this.chrToIndex && this.chrToIndex[chr];
367
- if (!!(chrId >= 0)) return [3 /*break*/, 1];
368
- chunks = [];
369
- return [3 /*break*/, 3];
370
- case 1: return [4 /*yield*/, __await(this.index.blocksForRange(chrId, min - 1, max, opts))];
371
- case 2:
372
- chunks = _a.sent();
373
- if (!chunks) {
374
- throw new Error('Error in index fetch');
375
- }
376
- _a.label = 3;
377
- case 3:
378
- i = 0;
379
- _a.label = 4;
380
- case 4:
381
- if (!(i < chunks.length)) return [3 /*break*/, 7];
382
- return [4 /*yield*/, __await((0, util_1.abortBreakPoint)(signal))];
383
- case 5:
384
- _a.sent();
385
- size = chunks[i].fetchedSize();
386
- if (size > this.chunkSizeLimit) {
387
- throw new Error("Too many BAM features. BAM chunk size ".concat(size, " bytes exceeds chunkSizeLimit of ").concat(this.chunkSizeLimit));
388
- }
389
- _a.label = 6;
390
- case 6:
391
- i += 1;
392
- return [3 /*break*/, 4];
393
- case 7:
394
- totalSize = chunks
395
- .map(function (s) { return s.fetchedSize(); })
396
- .reduce(function (a, b) { return a + b; }, 0);
397
- if (totalSize > this.fetchSizeLimit) {
398
- throw new Error("data size of ".concat(totalSize.toLocaleString(), " bytes exceeded fetch size limit of ").concat(this.fetchSizeLimit.toLocaleString(), " bytes"));
399
- }
400
- return [5 /*yield**/, __values(__asyncDelegator(__asyncValues(this._fetchChunkFeatures(chunks, chrId, min, max, opts))))];
401
- case 8: return [4 /*yield*/, __await.apply(void 0, [_a.sent()])];
402
- case 9:
403
- _a.sent();
404
- return [2 /*return*/];
405
- }
406
- });
246
+ }
247
+ streamRecordsForRange(chr, min, max, opts) {
248
+ var _a;
249
+ return __asyncGenerator(this, arguments, function* streamRecordsForRange_1() {
250
+ yield __await(this.getHeader(opts));
251
+ const chrId = (_a = this.chrToIndex) === null || _a === void 0 ? void 0 : _a[chr];
252
+ if (chrId === undefined || !this.index) {
253
+ yield yield __await([]);
254
+ }
255
+ else {
256
+ const chunks = yield __await(this.index.blocksForRange(chrId, min - 1, max, opts));
257
+ yield __await(yield* __asyncDelegator(__asyncValues(this._fetchChunkFeatures(chunks, chrId, min, max, opts))));
258
+ }
407
259
  });
408
- };
409
- BamFile.prototype._fetchChunkFeatures = function (chunks, chrId, min, max, opts) {
410
- return __asyncGenerator(this, arguments, function _fetchChunkFeatures_1() {
411
- var _a, viewAsPairs, feats, done, i, c, records, recs, i_1, feature;
412
- return __generator(this, function (_b) {
413
- switch (_b.label) {
414
- case 0:
415
- _a = opts.viewAsPairs, viewAsPairs = _a === void 0 ? false : _a;
416
- feats = [];
417
- done = false;
418
- i = 0;
419
- _b.label = 1;
420
- case 1:
421
- if (!(i < chunks.length)) return [3 /*break*/, 6];
422
- c = chunks[i];
423
- return [4 /*yield*/, __await(this.featureCache.get(c.toString(), {
424
- chunk: c,
425
- opts: opts,
426
- }, opts.signal))];
427
- case 2:
428
- records = (_b.sent());
429
- recs = [];
430
- for (i_1 = 0; i_1 < records.length; i_1 += 1) {
431
- feature = records[i_1];
432
- if (feature.seq_id() === chrId) {
433
- if (feature.get('start') >= max) {
434
- // past end of range, can stop iterating
435
- done = true;
436
- break;
437
- }
438
- else if (feature.get('end') >= min) {
439
- // must be in range
440
- recs.push(feature);
441
- }
442
- }
260
+ }
261
+ _fetchChunkFeatures(chunks, chrId, min, max, opts = {}) {
262
+ return __asyncGenerator(this, arguments, function* _fetchChunkFeatures_1() {
263
+ const { viewAsPairs } = opts;
264
+ const feats = [];
265
+ let done = false;
266
+ for (const chunk of chunks) {
267
+ const records = yield __await(this.featureCache.get(chunk.toString(), { chunk, opts }, opts.signal));
268
+ const recs = [];
269
+ for (const feature of records) {
270
+ if (feature.seq_id() === chrId) {
271
+ if (feature.get('start') >= max) {
272
+ // past end of range, can stop iterating
273
+ done = true;
274
+ break;
443
275
  }
444
- feats.push(recs);
445
- return [4 /*yield*/, __await(recs)];
446
- case 3: return [4 /*yield*/, _b.sent()];
447
- case 4:
448
- _b.sent();
449
- if (done) {
450
- return [3 /*break*/, 6];
276
+ else if (feature.get('end') >= min) {
277
+ // must be in range
278
+ recs.push(feature);
451
279
  }
452
- _b.label = 5;
453
- case 5:
454
- i++;
455
- return [3 /*break*/, 1];
456
- case 6:
457
- (0, util_1.checkAbortSignal)(opts.signal);
458
- if (!viewAsPairs) return [3 /*break*/, 9];
459
- return [4 /*yield*/, __await(this.fetchPairs(chrId, feats, opts))];
460
- case 7: return [4 /*yield*/, _b.sent()];
461
- case 8:
462
- _b.sent();
463
- _b.label = 9;
464
- case 9: return [2 /*return*/];
280
+ }
465
281
  }
466
- });
282
+ feats.push(recs);
283
+ yield yield __await(recs);
284
+ if (done) {
285
+ break;
286
+ }
287
+ }
288
+ (0, util_1.checkAbortSignal)(opts.signal);
289
+ if (viewAsPairs) {
290
+ yield yield __await(this.fetchPairs(chrId, feats, opts));
291
+ }
467
292
  });
468
- };
469
- BamFile.prototype.fetchPairs = function (chrId, feats, opts) {
470
- return __awaiter(this, void 0, void 0, function () {
471
- var _a, pairAcrossChr, _b, maxInsertSize, unmatedPairs, readIds, matePromises, mateChunks, _c, mateTotalSize, mateFeatPromises, _d;
472
- var _this = this;
473
- return __generator(this, function (_e) {
474
- switch (_e.label) {
475
- case 0:
476
- _a = opts.pairAcrossChr, pairAcrossChr = _a === void 0 ? false : _a, _b = opts.maxInsertSize, maxInsertSize = _b === void 0 ? 200000 : _b;
477
- unmatedPairs = {};
478
- readIds = {};
479
- feats.map(function (ret) {
480
- var readNames = {};
481
- for (var i = 0; i < ret.length; i++) {
482
- var name_1 = ret[i].name();
483
- var id = ret[i].id();
484
- if (!readNames[name_1]) {
485
- readNames[name_1] = 0;
486
- }
487
- readNames[name_1]++;
488
- readIds[id] = 1;
489
- }
490
- (0, object_entries_ponyfill_1.default)(readNames).forEach(function (_a) {
491
- var k = _a[0], v = _a[1];
492
- if (v === 1) {
493
- unmatedPairs[k] = true;
494
- }
495
- });
496
- });
497
- matePromises = [];
498
- feats.map(function (ret) {
499
- for (var i = 0; i < ret.length; i++) {
500
- var f = ret[i];
501
- var name_2 = f.name();
502
- var start = f.get('start');
503
- var pnext = f._next_pos();
504
- var rnext = f._next_refid();
505
- if (unmatedPairs[name_2] &&
506
- (pairAcrossChr ||
507
- (rnext === chrId && Math.abs(start - pnext) < maxInsertSize))) {
508
- matePromises.push(_this.index.blocksForRange(rnext, pnext, pnext + 1, opts));
509
- }
510
- }
511
- });
512
- _c = flat;
513
- return [4 /*yield*/, Promise.all(matePromises)];
514
- case 1:
515
- mateChunks = _c.apply(void 0, [_e.sent()])
516
- .sort()
517
- .filter(function (item, pos, ary) { return !pos || item.toString() !== ary[pos - 1].toString(); });
518
- mateTotalSize = mateChunks
519
- .map(function (s) { return s.fetchedSize(); })
520
- .reduce(function (a, b) { return a + b; }, 0);
521
- if (mateTotalSize > this.fetchSizeLimit) {
522
- throw new Error("data size of ".concat(mateTotalSize.toLocaleString(), " bytes exceeded fetch size limit of ").concat(this.fetchSizeLimit.toLocaleString(), " bytes"));
523
- }
524
- mateFeatPromises = mateChunks.map(function (c) { return __awaiter(_this, void 0, void 0, function () {
525
- var _a, data, cpositions, dpositions, chunk, feats, mateRecs, i, feature;
526
- return __generator(this, function (_b) {
527
- switch (_b.label) {
528
- case 0: return [4 /*yield*/, this._readChunk({
529
- chunk: c,
530
- opts: opts,
531
- })];
532
- case 1:
533
- _a = _b.sent(), data = _a.data, cpositions = _a.cpositions, dpositions = _a.dpositions, chunk = _a.chunk;
534
- return [4 /*yield*/, this.readBamFeatures(data, cpositions, dpositions, chunk)];
535
- case 2:
536
- feats = _b.sent();
537
- mateRecs = [];
538
- for (i = 0; i < feats.length; i += 1) {
539
- feature = feats[i];
540
- if (unmatedPairs[feature.get('name')] && !readIds[feature.id()]) {
541
- mateRecs.push(feature);
542
- }
543
- }
544
- return [2 /*return*/, mateRecs];
545
- }
546
- });
547
- }); });
548
- _d = flat;
549
- return [4 /*yield*/, Promise.all(mateFeatPromises)];
550
- case 2: return [2 /*return*/, _d.apply(void 0, [_e.sent()])];
293
+ }
294
+ fetchPairs(chrId, feats, opts) {
295
+ return __awaiter(this, void 0, void 0, function* () {
296
+ const { pairAcrossChr, maxInsertSize = 200000 } = opts;
297
+ const unmatedPairs = {};
298
+ const readIds = {};
299
+ feats.map(ret => {
300
+ const readNames = {};
301
+ for (const element of ret) {
302
+ const name = element.name();
303
+ const id = element.id();
304
+ if (!readNames[name]) {
305
+ readNames[name] = 0;
306
+ }
307
+ readNames[name]++;
308
+ readIds[id] = 1;
309
+ }
310
+ for (const [k, v] of Object.entries(readNames)) {
311
+ if (v === 1) {
312
+ unmatedPairs[k] = true;
313
+ }
551
314
  }
552
315
  });
553
- });
554
- };
555
- BamFile.prototype._readChunk = function (_a) {
556
- var chunk = _a.chunk, opts = _a.opts;
557
- return __awaiter(this, void 0, void 0, function () {
558
- var size, _b, buffer, bytesRead, _c, data, cpositions, dpositions;
559
- return __generator(this, function (_d) {
560
- switch (_d.label) {
561
- case 0:
562
- size = chunk.fetchedSize();
563
- return [4 /*yield*/, this.bam.read(Buffer.alloc(size), 0, size, chunk.minv.blockPosition, opts)];
564
- case 1:
565
- _b = _d.sent(), buffer = _b.buffer, bytesRead = _b.bytesRead;
566
- return [4 /*yield*/, (0, bgzf_filehandle_1.unzipChunkSlice)(buffer.subarray(0, Math.min(bytesRead, size)), chunk)];
567
- case 2:
568
- _c = _d.sent(), data = _c.buffer, cpositions = _c.cpositions, dpositions = _c.dpositions;
569
- return [2 /*return*/, { data: data, cpositions: cpositions, dpositions: dpositions, chunk: chunk }];
316
+ const matePromises = [];
317
+ feats.map(ret => {
318
+ for (const f of ret) {
319
+ const name = f.name();
320
+ const start = f.get('start');
321
+ const pnext = f._next_pos();
322
+ const rnext = f._next_refid();
323
+ if (this.index &&
324
+ unmatedPairs[name] &&
325
+ (pairAcrossChr ||
326
+ (rnext === chrId && Math.abs(start - pnext) < maxInsertSize))) {
327
+ matePromises.push(this.index.blocksForRange(rnext, pnext, pnext + 1, opts));
328
+ }
570
329
  }
571
330
  });
331
+ // filter out duplicate chunks (the blocks are lists of chunks, blocks are
332
+ // concatenated, then filter dup chunks)
333
+ const map = new Map();
334
+ const res = yield Promise.all(matePromises);
335
+ for (const m of res.flat()) {
336
+ if (!map.has(m.toString())) {
337
+ map.set(m.toString(), m);
338
+ }
339
+ }
340
+ const mateFeatPromises = yield Promise.all([...map.values()].map((c) => __awaiter(this, void 0, void 0, function* () {
341
+ const { data, cpositions, dpositions, chunk } = yield this._readChunk({
342
+ chunk: c,
343
+ opts,
344
+ });
345
+ const mateRecs = [];
346
+ for (const feature of yield this.readBamFeatures(data, cpositions, dpositions, chunk)) {
347
+ if (unmatedPairs[feature.get('name')] && !readIds[feature.id()]) {
348
+ mateRecs.push(feature);
349
+ }
350
+ }
351
+ return mateRecs;
352
+ })));
353
+ return mateFeatPromises.flat();
572
354
  });
573
- };
574
- BamFile.prototype.readBamFeatures = function (ba, cpositions, dpositions, chunk) {
575
- return __awaiter(this, void 0, void 0, function () {
576
- var blockStart, sink, pos, last, blockSize, blockEnd, feature;
577
- return __generator(this, function (_a) {
578
- switch (_a.label) {
579
- case 0:
580
- blockStart = 0;
581
- sink = [];
582
- pos = 0;
583
- last = +Date.now();
584
- _a.label = 1;
585
- case 1:
586
- if (!(blockStart + 4 < ba.length)) return [3 /*break*/, 4];
587
- blockSize = ba.readInt32LE(blockStart);
588
- blockEnd = blockStart + 4 + blockSize - 1;
589
- // increment position to the current decompressed status
590
- if (dpositions) {
591
- while (blockStart + chunk.minv.dataPosition >= dpositions[pos++]) { }
592
- pos--;
593
- }
594
- if (!(blockEnd < ba.length)) return [3 /*break*/, 3];
595
- feature = new record_1.default({
596
- bytes: {
597
- byteArray: ba,
598
- start: blockStart,
599
- end: blockEnd,
600
- },
601
- // the below results in an automatically calculated file-offset based ID
602
- // if the info for that is available, otherwise crc32 of the features
603
- //
604
- // cpositions[pos] refers to actual file offset of a bgzip block boundaries
605
- //
606
- // we multiply by (1 <<8) in order to make sure each block has a "unique"
607
- // address space so that data in that block could never overlap
608
- //
609
- // then the blockStart-dpositions is an uncompressed file offset from
610
- // that bgzip block boundary, and since the cpositions are multiplied by
611
- // (1 << 8) these uncompressed offsets get a unique space
612
- //
613
- // this has an extra chunk.minv.dataPosition added on because it blockStart
614
- // starts at 0 instead of chunk.minv.dataPosition
615
- //
616
- // the +1 is just to avoid any possible uniqueId 0 but this does not realistically happen
617
- fileOffset: cpositions
618
- ? cpositions[pos] * (1 << 8) +
619
- (blockStart - dpositions[pos]) +
620
- chunk.minv.dataPosition +
621
- 1
622
- : // must be slice, not subarray for buffer polyfill on web
623
- buffer_crc32_1.default.signed(ba.slice(blockStart, blockEnd)),
624
- });
625
- sink.push(feature);
626
- if (!(this.yieldThreadTime && +Date.now() - last > this.yieldThreadTime)) return [3 /*break*/, 3];
627
- return [4 /*yield*/, (0, util_1.timeout)(1)];
628
- case 2:
629
- _a.sent();
355
+ }
356
+ _readRegion(position, size, opts = {}) {
357
+ return __awaiter(this, void 0, void 0, function* () {
358
+ const { bytesRead, buffer } = yield this.bam.read(buffer_1.Buffer.alloc(size), 0, size, position, opts);
359
+ return buffer.subarray(0, Math.min(bytesRead, size));
360
+ });
361
+ }
362
+ _readChunk({ chunk, opts }) {
363
+ return __awaiter(this, void 0, void 0, function* () {
364
+ const buffer = yield this._readRegion(chunk.minv.blockPosition, chunk.fetchedSize(), opts);
365
+ const { buffer: data, cpositions, dpositions, } = yield (0, bgzf_filehandle_1.unzipChunkSlice)(buffer, chunk);
366
+ return { data, cpositions, dpositions, chunk };
367
+ });
368
+ }
369
+ readBamFeatures(ba, cpositions, dpositions, chunk) {
370
+ return __awaiter(this, void 0, void 0, function* () {
371
+ let blockStart = 0;
372
+ const sink = [];
373
+ let pos = 0;
374
+ let last = +Date.now();
375
+ while (blockStart + 4 < ba.length) {
376
+ const blockSize = ba.readInt32LE(blockStart);
377
+ const blockEnd = blockStart + 4 + blockSize - 1;
378
+ // increment position to the current decompressed status
379
+ if (dpositions) {
380
+ while (blockStart + chunk.minv.dataPosition >= dpositions[pos++]) { }
381
+ pos--;
382
+ }
383
+ // only try to read the feature if we have all the bytes for it
384
+ if (blockEnd < ba.length) {
385
+ const feature = new record_1.default({
386
+ bytes: {
387
+ byteArray: ba,
388
+ start: blockStart,
389
+ end: blockEnd,
390
+ },
391
+ // the below results in an automatically calculated file-offset based
392
+ // ID if the info for that is available, otherwise crc32 of the
393
+ // features
394
+ //
395
+ // cpositions[pos] refers to actual file offset of a bgzip block
396
+ // boundaries
397
+ //
398
+ // we multiply by (1 <<8) in order to make sure each block has a
399
+ // "unique" address space so that data in that block could never
400
+ // overlap
401
+ //
402
+ // then the blockStart-dpositions is an uncompressed file offset from
403
+ // that bgzip block boundary, and since the cpositions are multiplied
404
+ // by (1 << 8) these uncompressed offsets get a unique space
405
+ //
406
+ // this has an extra chunk.minv.dataPosition added on because it
407
+ // blockStart starts at 0 instead of chunk.minv.dataPosition
408
+ //
409
+ // the +1 is just to avoid any possible uniqueId 0 but this does not
410
+ // realistically happen
411
+ fileOffset: cpositions.length > 0
412
+ ? cpositions[pos] * (1 << 8) +
413
+ (blockStart - dpositions[pos]) +
414
+ chunk.minv.dataPosition +
415
+ 1
416
+ : // must be slice, not subarray for buffer polyfill on web
417
+ buffer_crc32_1.default.signed(ba.slice(blockStart, blockEnd)),
418
+ });
419
+ sink.push(feature);
420
+ if (this.yieldThreadTime && +Date.now() - last > this.yieldThreadTime) {
421
+ yield (0, util_1.timeout)(1);
630
422
  last = +Date.now();
631
- _a.label = 3;
632
- case 3:
633
- blockStart = blockEnd + 1;
634
- return [3 /*break*/, 1];
635
- case 4: return [2 /*return*/, sink];
423
+ }
636
424
  }
637
- });
425
+ blockStart = blockEnd + 1;
426
+ }
427
+ return sink;
638
428
  });
639
- };
640
- BamFile.prototype.hasRefSeq = function (seqName) {
641
- return __awaiter(this, void 0, void 0, function () {
642
- var refId;
643
- return __generator(this, function (_a) {
644
- refId = this.chrToIndex && this.chrToIndex[seqName];
645
- return [2 /*return*/, this.index.hasRefSeq(refId)];
646
- });
429
+ }
430
+ hasRefSeq(seqName) {
431
+ var _a, _b;
432
+ return __awaiter(this, void 0, void 0, function* () {
433
+ const seqId = (_a = this.chrToIndex) === null || _a === void 0 ? void 0 : _a[seqName];
434
+ return seqId === undefined ? false : (_b = this.index) === null || _b === void 0 ? void 0 : _b.hasRefSeq(seqId);
647
435
  });
648
- };
649
- BamFile.prototype.lineCount = function (seqName) {
650
- return __awaiter(this, void 0, void 0, function () {
651
- var refId;
652
- return __generator(this, function (_a) {
653
- refId = this.chrToIndex && this.chrToIndex[seqName];
654
- return [2 /*return*/, this.index.lineCount(refId)];
655
- });
436
+ }
437
+ lineCount(seqName) {
438
+ var _a;
439
+ return __awaiter(this, void 0, void 0, function* () {
440
+ const seqId = (_a = this.chrToIndex) === null || _a === void 0 ? void 0 : _a[seqName];
441
+ return seqId === undefined || !this.index ? 0 : this.index.lineCount(seqId);
656
442
  });
657
- };
658
- BamFile.prototype.indexCov = function (seqName, start, end) {
659
- return __awaiter(this, void 0, void 0, function () {
660
- var seqId;
661
- return __generator(this, function (_a) {
662
- switch (_a.label) {
663
- case 0: return [4 /*yield*/, this.index.parse()];
664
- case 1:
665
- _a.sent();
666
- seqId = this.chrToIndex && this.chrToIndex[seqName];
667
- return [2 /*return*/, this.index.indexCov(seqId, start, end)];
668
- }
669
- });
443
+ }
444
+ indexCov(seqName, start, end) {
445
+ var _a;
446
+ return __awaiter(this, void 0, void 0, function* () {
447
+ if (!this.index) {
448
+ return [];
449
+ }
450
+ yield this.index.parse();
451
+ const seqId = (_a = this.chrToIndex) === null || _a === void 0 ? void 0 : _a[seqName];
452
+ return seqId === undefined ? [] : this.index.indexCov(seqId, start, end);
670
453
  });
671
- };
672
- BamFile.prototype.blocksForRange = function (seqName, start, end, opts) {
673
- return __awaiter(this, void 0, void 0, function () {
674
- var seqId;
675
- return __generator(this, function (_a) {
676
- switch (_a.label) {
677
- case 0: return [4 /*yield*/, this.index.parse()];
678
- case 1:
679
- _a.sent();
680
- seqId = this.chrToIndex && this.chrToIndex[seqName];
681
- return [2 /*return*/, this.index.blocksForRange(seqId, start, end, opts)];
682
- }
683
- });
454
+ }
455
+ blocksForRange(seqName, start, end, opts) {
456
+ var _a;
457
+ return __awaiter(this, void 0, void 0, function* () {
458
+ if (!this.index) {
459
+ return [];
460
+ }
461
+ yield this.index.parse();
462
+ const seqId = (_a = this.chrToIndex) === null || _a === void 0 ? void 0 : _a[seqName];
463
+ return seqId === undefined
464
+ ? []
465
+ : this.index.blocksForRange(seqId, start, end, opts);
684
466
  });
685
- };
686
- return BamFile;
687
- }());
467
+ }
468
+ }
688
469
  exports.default = BamFile;
689
470
  //# sourceMappingURL=bamFile.js.map