@gmod/bam 6.1.1 → 7.0.1

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.
package/esm/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gmod/bam",
3
- "version": "6.1.1",
3
+ "version": "7.0.1",
4
4
  "description": "Parser for BAM and BAM index (bai) files",
5
5
  "license": "MIT",
6
6
  "repository": "GMOD/bam-js",
@@ -29,15 +29,17 @@
29
29
  ],
30
30
  "scripts": {
31
31
  "test": "vitest",
32
+ "benchonly": "vitest bench",
33
+ "bench": "./scripts/build-both-branches.sh \"$BRANCH1\" \"$BRANCH2\" && vitest bench",
32
34
  "lint": "eslint --report-unused-disable-directives --max-warnings 0",
33
35
  "clean": "rimraf dist esm",
34
36
  "format": "prettier --write .",
35
37
  "build:esm": "tsc --outDir esm",
36
38
  "build:es5": "tsc --module commonjs --outDir dist",
37
- "build": "npm run build:esm && npm run build:es5",
38
- "prebuild": "npm run clean && npm run lint",
39
+ "build": "yarn build:esm && yarn build:es5",
40
+ "prebuild": "yarn clean",
39
41
  "postbuild:es5": "echo '{\"type\": \"commonjs\"}' > dist/package.json",
40
- "preversion": "npm run lint && npm test run && npm run build",
42
+ "preversion": "yarn lint && yarn test --run && yarn build",
41
43
  "version": "standard-changelog && git add CHANGELOG.md",
42
44
  "postversion": "git push --follow-tags"
43
45
  },
@@ -48,24 +50,23 @@
48
50
  "genomics"
49
51
  ],
50
52
  "dependencies": {
51
- "@gmod/abortable-promise-cache": "^3.0.1",
52
- "@gmod/bgzf-filehandle": "^4.0.0",
53
+ "@gmod/bgzf-filehandle": "^4.2.1",
53
54
  "crc": "^4.3.2",
54
55
  "generic-filehandle2": "^2.0.1",
55
56
  "quick-lru": "^4.0.0"
56
57
  },
57
58
  "devDependencies": {
58
- "@types/node": "^22.15.3",
59
- "@vitest/coverage-v8": "^3.0.9",
59
+ "@types/node": "^24.10.0",
60
+ "@vitest/coverage-v8": "^4.0.3",
60
61
  "eslint": "^9.9.0",
61
62
  "eslint-plugin-import": "^2.31.0",
62
- "eslint-plugin-unicorn": "^61.0.2",
63
+ "eslint-plugin-unicorn": "^62.0.0",
63
64
  "prettier": "^3.3.3",
64
65
  "rimraf": "^6.0.1",
65
66
  "standard-changelog": "^7.0.1",
66
67
  "typescript": "^5.0.4",
67
68
  "typescript-eslint": "^8.27.0",
68
- "vitest": "^3.0.9"
69
+ "vitest": "^4.0.3"
69
70
  },
70
71
  "publishConfig": {
71
72
  "access": "public"
package/src/bamFile.ts CHANGED
@@ -9,7 +9,7 @@ import CSI from './csi.ts'
9
9
  import NullFilehandle from './nullFilehandle.ts'
10
10
  import BAMFeature from './record.ts'
11
11
  import { parseHeaderText } from './sam.ts'
12
- import { checkAbortSignal, gen2array, makeOpts, timeout } from './util.ts'
12
+ import { gen2array, makeOpts } from './util.ts'
13
13
 
14
14
  import type { BamOpts, BaseOpts } from './util.ts'
15
15
  import type { GenericFilehandle } from 'generic-filehandle2'
@@ -24,7 +24,6 @@ export default class BamFile {
24
24
  public header?: string
25
25
  public chrToIndex?: Record<string, number>
26
26
  public indexToChr?: { refName: string; length: number }[]
27
- public yieldThreadTime: number
28
27
  public index?: BAI | CSI
29
28
  public htsget = false
30
29
  public headerP?: ReturnType<BamFile['getHeaderPre']>
@@ -43,7 +42,6 @@ export default class BamFile {
43
42
  csiFilehandle,
44
43
  csiUrl,
45
44
  htsget,
46
- yieldThreadTime = 100,
47
45
  renameRefSeqs = n => n,
48
46
  }: {
49
47
  bamFilehandle?: GenericFilehandle
@@ -56,7 +54,6 @@ export default class BamFile {
56
54
  csiFilehandle?: GenericFilehandle
57
55
  csiUrl?: string
58
56
  renameRefSeqs?: (a: string) => string
59
- yieldThreadTime?: number
60
57
  htsget?: boolean
61
58
  }) {
62
59
  this.renameRefSeq = renameRefSeqs
@@ -94,26 +91,24 @@ export default class BamFile {
94
91
  } else {
95
92
  throw new Error('unable to infer index format')
96
93
  }
97
- this.yieldThreadTime = yieldThreadTime
98
94
  }
99
95
 
100
96
  async getHeaderPre(origOpts?: BaseOpts) {
101
97
  const opts = makeOpts(origOpts)
102
98
  if (!this.index) {
103
- return
99
+ return undefined
104
100
  }
105
101
  const indexData = await this.index.parse(opts)
106
- const ret = indexData.firstDataLine
107
- ? indexData.firstDataLine.blockPosition + 65535
108
- : undefined
109
- let buffer
110
- if (ret) {
111
- const s = ret + blockLen
112
- buffer = await this.bam.read(s, 0)
113
- } else {
114
- buffer = await this.bam.readFile(opts)
115
- }
116
102
 
103
+ // firstDataLine is not defined in cases where there is no data in the file
104
+ // (just bam header and nothing else)
105
+ const buffer =
106
+ indexData.firstDataLine === undefined
107
+ ? await this.bam.readFile()
108
+ : await this.bam.read(
109
+ indexData.firstDataLine.blockPosition + blockLen,
110
+ 0,
111
+ )
117
112
  const uncba = await unzip(buffer)
118
113
  const dataView = new DataView(uncba.buffer)
119
114
 
@@ -121,14 +116,10 @@ export default class BamFile {
121
116
  throw new Error('Not a BAM file')
122
117
  }
123
118
  const headLen = dataView.getInt32(4, true)
124
-
125
119
  const decoder = new TextDecoder('utf8')
126
120
  this.header = decoder.decode(uncba.subarray(8, 8 + headLen))
127
- const { chrToIndex, indexToChr } = await this._readRefSeqs(
128
- headLen + 8,
129
- 65535,
130
- opts,
131
- )
121
+
122
+ const { chrToIndex, indexToChr } = this._parseRefSeqs(uncba, headLen + 8)
132
123
  this.chrToIndex = chrToIndex
133
124
  this.indexToChr = indexToChr
134
125
 
@@ -150,29 +141,28 @@ export default class BamFile {
150
141
  return this.header
151
142
  }
152
143
 
153
- // the full length of the refseq block is not given in advance so this grabs
154
- // a chunk and doubles it if all refseqs haven't been processed
155
- async _readRefSeqs(
144
+ _parseRefSeqs(
145
+ uncba: Uint8Array,
156
146
  start: number,
157
- refSeqBytes: number,
158
- opts?: BaseOpts,
159
- ): Promise<{
147
+ ): {
160
148
  chrToIndex: Record<string, number>
161
149
  indexToChr: { refName: string; length: number }[]
162
- }> {
163
- if (start > refSeqBytes) {
164
- return this._readRefSeqs(start, refSeqBytes * 2, opts)
165
- }
166
- // const size = refSeqBytes + blockLen <-- use this?
167
- const buffer = await this.bam.read(refSeqBytes, 0, opts)
168
- const uncba = await unzip(buffer)
150
+ } {
169
151
  const dataView = new DataView(uncba.buffer)
170
152
  const nRef = dataView.getInt32(start, true)
171
153
  let p = start + 4
154
+
172
155
  const chrToIndex: Record<string, number> = {}
173
156
  const indexToChr: { refName: string; length: number }[] = []
174
157
  const decoder = new TextDecoder('utf8')
158
+
175
159
  for (let i = 0; i < nRef; i += 1) {
160
+ if (p + 8 > uncba.length) {
161
+ throw new Error(
162
+ `Insufficient data for reference sequences: need more than ${uncba.length} bytes`,
163
+ )
164
+ }
165
+
176
166
  const lName = dataView.getInt32(p, true)
177
167
  const refName = this.renameRefSeq(
178
168
  decoder.decode(uncba.subarray(p + 4, p + 4 + lName - 1)),
@@ -183,13 +173,8 @@ export default class BamFile {
183
173
  indexToChr.push({ refName, length: lRef })
184
174
 
185
175
  p = p + 8 + lName
186
- if (p > uncba.length) {
187
- console.warn(
188
- `BAM header is very big. Re-fetching ${refSeqBytes} bytes.`,
189
- )
190
- return this._readRefSeqs(start, refSeqBytes * 2, opts)
191
- }
192
176
  }
177
+
193
178
  return { chrToIndex, indexToChr }
194
179
  }
195
180
 
@@ -211,11 +196,10 @@ export default class BamFile {
211
196
  await this.getHeader(opts)
212
197
  const chrId = this.chrToIndex?.[chr]
213
198
  if (chrId === undefined || !this.index) {
214
- yield []
215
- } else {
216
- const chunks = await this.index.blocksForRange(chrId, min - 1, max, opts)
217
- yield* this._fetchChunkFeatures(chunks, chrId, min, max, opts)
199
+ return
218
200
  }
201
+ const chunks = await this.index.blocksForRange(chrId, min - 1, max, opts)
202
+ yield* this._fetchChunkFeatures(chunks, chrId, min, max, opts)
219
203
  }
220
204
 
221
205
  async *_fetchChunkFeatures(
@@ -239,6 +223,9 @@ export default class BamFile {
239
223
  cpositions,
240
224
  dpositions,
241
225
  chunk,
226
+ chrId,
227
+ min,
228
+ max,
242
229
  )
243
230
 
244
231
  const recs = [] as BAMFeature[]
@@ -261,7 +248,6 @@ export default class BamFile {
261
248
  }
262
249
  }
263
250
 
264
- checkAbortSignal(opts.signal)
265
251
  if (viewAsPairs) {
266
252
  yield this.fetchPairs(chrId, feats, opts)
267
253
  }
@@ -271,7 +257,7 @@ export default class BamFile {
271
257
  const { pairAcrossChr, maxInsertSize = 200000 } = opts
272
258
  const unmatedPairs: Record<string, boolean> = {}
273
259
  const readIds: Record<string, number> = {}
274
- feats.map(ret => {
260
+ for (const ret of feats) {
275
261
  const readNames: Record<string, number> = {}
276
262
  for (const element of ret) {
277
263
  const name = element.name
@@ -287,10 +273,10 @@ export default class BamFile {
287
273
  unmatedPairs[k] = true
288
274
  }
289
275
  }
290
- })
276
+ }
291
277
 
292
278
  const matePromises: Promise<Chunk[]>[] = []
293
- feats.map(ret => {
279
+ for (const ret of feats) {
294
280
  for (const f of ret) {
295
281
  const name = f.name
296
282
  const start = f.start
@@ -307,7 +293,7 @@ export default class BamFile {
307
293
  )
308
294
  }
309
295
  }
310
- })
296
+ }
311
297
 
312
298
  // filter out duplicate chunks (the blocks are lists of chunks, blocks are
313
299
  // concatenated, then filter dup chunks)
@@ -362,69 +348,54 @@ export default class BamFile {
362
348
  cpositions: number[],
363
349
  dpositions: number[],
364
350
  chunk: Chunk,
351
+ chrId?: number,
352
+ min?: number,
353
+ max?: number,
365
354
  ) {
366
355
  let blockStart = 0
367
356
  const sink = [] as BAMFeature[]
368
357
  let pos = 0
369
- let last = Date.now()
370
358
 
371
359
  const dataView = new DataView(ba.buffer)
360
+ const hasDpositions = dpositions.length > 0
361
+ const hasCpositions = cpositions.length > 0
362
+ const hasFilter =
363
+ chrId !== undefined && min !== undefined && max !== undefined
364
+
372
365
  while (blockStart + 4 < ba.length) {
373
366
  const blockSize = dataView.getInt32(blockStart, true)
374
367
  const blockEnd = blockStart + 4 + blockSize - 1
375
368
 
376
- // increment position to the current decompressed status
377
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
378
- if (dpositions) {
369
+ if (hasDpositions) {
379
370
  while (blockStart + chunk.minv.dataPosition >= dpositions[pos++]!) {}
380
371
  pos--
381
372
  }
382
373
 
383
- // only try to read the feature if we have all the bytes for it
384
374
  if (blockEnd < ba.length) {
375
+ if (
376
+ hasFilter &&
377
+ blockStart + 12 < ba.length &&
378
+ !this._shouldIncludeFeature(dataView, blockStart, chrId, max)
379
+ ) {
380
+ blockStart = blockEnd + 1
381
+ continue
382
+ }
383
+
385
384
  const feature = new BAMFeature({
386
385
  bytes: {
387
386
  byteArray: ba,
388
387
  start: blockStart,
389
388
  end: blockEnd,
390
389
  },
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:
412
- cpositions.length > 0
413
- ? cpositions[pos]! * (1 << 8) +
414
- (blockStart - dpositions[pos]!) +
415
- chunk.minv.dataPosition +
416
- 1
417
- : // this shift >>> 0 is equivalent to crc32(b).unsigned but uses the
418
- // internal calculator of crc32 to avoid accidentally importing buffer
419
- // https://github.com/alexgorbatchev/crc/blob/31fc3853e417b5fb5ec83335428805842575f699/src/define_crc.ts#L5
420
- crc32(ba.subarray(blockStart, blockEnd)) >>> 0,
390
+ fileOffset: hasCpositions
391
+ ? cpositions[pos]! * (1 << 8) +
392
+ (blockStart - dpositions[pos]!) +
393
+ chunk.minv.dataPosition +
394
+ 1
395
+ : crc32(ba.subarray(blockStart, blockEnd)) >>> 0,
421
396
  })
422
397
 
423
398
  sink.push(feature)
424
- if (this.yieldThreadTime && Date.now() - last > this.yieldThreadTime) {
425
- await timeout(1)
426
- last = Date.now()
427
- }
428
399
  }
429
400
 
430
401
  blockStart = blockEnd + 1
@@ -432,6 +403,17 @@ export default class BamFile {
432
403
  return sink
433
404
  }
434
405
 
406
+ _shouldIncludeFeature(
407
+ dataView: DataView,
408
+ blockStart: number,
409
+ chrId: number,
410
+ max: number,
411
+ ) {
412
+ const ref_id = dataView.getInt32(blockStart + 4, true)
413
+ const start = dataView.getInt32(blockStart + 8, true)
414
+ return ref_id === chrId && start < max
415
+ }
416
+
435
417
  async hasRefSeq(seqName: string) {
436
418
  const seqId = this.chrToIndex?.[seqName]
437
419
  return seqId === undefined ? false : this.index?.hasRefSeq(seqId)