@gmod/tabix 1.5.11 → 1.5.12
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/CHANGELOG.md +9 -4
- package/dist/chunk.d.ts +0 -6
- package/dist/chunk.js +1 -6
- package/dist/chunk.js.map +1 -1
- package/dist/csi.d.ts +6 -16
- package/dist/csi.js +4 -7
- package/dist/csi.js.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/indexFile.d.ts +2 -6
- package/dist/indexFile.js +4 -3
- package/dist/indexFile.js.map +1 -1
- package/dist/tabixIndexedFile.d.ts +2 -4
- package/dist/tabixIndexedFile.js +25 -47
- package/dist/tabixIndexedFile.js.map +1 -1
- package/dist/tbi.d.ts +3 -9
- package/dist/tbi.js +2 -3
- package/dist/tbi.js.map +1 -1
- package/dist/util.js +1 -6
- package/dist/util.js.map +1 -1
- package/dist/virtualOffset.js.map +1 -1
- package/esm/chunk.d.ts +0 -6
- package/esm/chunk.js +1 -6
- package/esm/chunk.js.map +1 -1
- package/esm/csi.d.ts +6 -16
- package/esm/csi.js +4 -5
- package/esm/csi.js.map +1 -1
- package/esm/index.d.ts +3 -4
- package/esm/index.js +3 -4
- package/esm/index.js.map +1 -1
- package/esm/indexFile.d.ts +2 -6
- package/esm/indexFile.js +4 -3
- package/esm/indexFile.js.map +1 -1
- package/esm/tabixIndexedFile.d.ts +2 -4
- package/esm/tabixIndexedFile.js +25 -47
- package/esm/tabixIndexedFile.js.map +1 -1
- package/esm/tbi.d.ts +3 -9
- package/esm/tbi.js +2 -3
- package/esm/tbi.js.map +1 -1
- package/esm/util.js +1 -6
- package/esm/util.js.map +1 -1
- package/esm/virtualOffset.js.map +1 -1
- package/package.json +14 -13
- package/src/chunk.ts +1 -6
- package/src/csi.ts +6 -7
- package/src/index.ts +3 -5
- package/src/indexFile.ts +4 -4
- package/src/tabixIndexedFile.ts +32 -52
- package/src/tbi.ts +5 -6
- package/src/util.ts +1 -5
package/esm/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,YAAY,CAAC,IAAU;IACrC,IACE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,gBAAgB,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC,EACtC;
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/esm/virtualOffset.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualOffset.js","sourceRoot":"","sources":["../src/virtualOffset.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,OAAO,OAAO,aAAa;IAGhC,YAAY,aAAqB,EAAE,YAAoB;QACrD,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA,CAAC,wCAAwC;QAC3E,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA,CAAC,sCAAsC;IACzE,CAAC;IAED,QAAQ;QACN,OAAO,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,YAAY,EAAE,CAAA;IACrD,CAAC;IAED,SAAS,CAAC,CAAgB;QACxB,OAAO,CACL,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,IAAI,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAC3E,CAAA;IACH,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,GAAG,IAAqB;QACjC,IAAI,GAAG,CAAA;QACP,IAAI,CAAC,GAAG,CAAC,CAAA;QACT,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"virtualOffset.js","sourceRoot":"","sources":["../src/virtualOffset.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,OAAO,OAAO,aAAa;IAGhC,YAAY,aAAqB,EAAE,YAAoB;QACrD,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA,CAAC,wCAAwC;QAC3E,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA,CAAC,sCAAsC;IACzE,CAAC;IAED,QAAQ;QACN,OAAO,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,YAAY,EAAE,CAAA;IACrD,CAAC;IAED,SAAS,CAAC,CAAgB;QACxB,OAAO,CACL,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,IAAI,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAC3E,CAAA;IACH,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,GAAG,IAAqB;QACjC,IAAI,GAAG,CAAA;QACP,IAAI,CAAC,GAAG,CAAC,CAAA;QACT,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QACf,CAAC;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/B,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;YACf,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;CACF;AACD,MAAM,UAAU,SAAS,CAAC,KAAa,EAAE,MAAM,GAAG,CAAC,EAAE,SAAS,GAAG,KAAK;IACpE,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;IACpE,CAAC;IAED,OAAO,IAAI,aAAa,CACtB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,aAAa;QAC/B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,WAAW;QAC/B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,SAAS;QAC7B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,OAAO;QAC3B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK;QACzB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EACnB,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CACzC,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gmod/tabix",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.12",
|
|
4
4
|
"description": "Read Tabix-indexed files, supports both .tbi and .csi indexes",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "GMOD/tabix-js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"test": "jest",
|
|
24
24
|
"coverage": "npm test -- --coverage",
|
|
25
|
-
"lint": "eslint --ext .js,.ts src
|
|
25
|
+
"lint": "eslint --ext .js,.ts src",
|
|
26
26
|
"clean": "rimraf dist esm",
|
|
27
27
|
"prebuild": "npm run clean && npm run lint",
|
|
28
28
|
"build:esm": "tsc --target es2018 --outDir esm",
|
|
@@ -46,22 +46,23 @@
|
|
|
46
46
|
"quick-lru": "^4.0.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@types/jest": "^29.5.
|
|
49
|
+
"@types/jest": "^29.5.11",
|
|
50
50
|
"@types/long": "^4.0.0",
|
|
51
|
-
"@types/node": "^
|
|
52
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
53
|
-
"@typescript-eslint/parser": "^
|
|
51
|
+
"@types/node": "^20.10.5",
|
|
52
|
+
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
|
53
|
+
"@typescript-eslint/parser": "^6.15.0",
|
|
54
54
|
"eslint": "^8.40.0",
|
|
55
|
-
"eslint-config-prettier": "^
|
|
55
|
+
"eslint-config-prettier": "^9.1.0",
|
|
56
56
|
"eslint-plugin-import": "^2.27.5",
|
|
57
|
-
"eslint-plugin-prettier": "^
|
|
58
|
-
"
|
|
57
|
+
"eslint-plugin-prettier": "^5.0.1",
|
|
58
|
+
"eslint-plugin-unicorn": "^49.0.0",
|
|
59
|
+
"jest": "^29.7.0",
|
|
59
60
|
"jest-environment-jsdom": "^29.5.0",
|
|
60
|
-
"prettier": "^
|
|
61
|
+
"prettier": "^3.1.1",
|
|
61
62
|
"rimraf": "^5.0.1",
|
|
62
|
-
"standard-changelog": "^
|
|
63
|
-
"ts-jest": "^29.1.
|
|
64
|
-
"typescript": "^5.
|
|
63
|
+
"standard-changelog": "^5.0.0",
|
|
64
|
+
"ts-jest": "^29.1.1",
|
|
65
|
+
"typescript": "^5.3.3"
|
|
65
66
|
},
|
|
66
67
|
"publishConfig": {
|
|
67
68
|
"access": "public"
|
package/src/chunk.ts
CHANGED
|
@@ -7,12 +7,6 @@ export default class Chunk {
|
|
|
7
7
|
public bin: number
|
|
8
8
|
public _fetchedSize?: number
|
|
9
9
|
|
|
10
|
-
/**
|
|
11
|
-
* @param {VirtualOffset} minv
|
|
12
|
-
* @param {VirtualOffset} maxv
|
|
13
|
-
* @param {number} bin
|
|
14
|
-
* @param {number} [fetchedSize]
|
|
15
|
-
*/
|
|
16
10
|
constructor(
|
|
17
11
|
minv: VirtualOffset,
|
|
18
12
|
maxv: VirtualOffset,
|
|
@@ -26,6 +20,7 @@ export default class Chunk {
|
|
|
26
20
|
}
|
|
27
21
|
|
|
28
22
|
toUniqueString() {
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
29
24
|
return `${this.minv}..${this.maxv} (bin ${
|
|
30
25
|
this.bin
|
|
31
26
|
}, fetchedSize ${this.fetchedSize()})`
|
package/src/csi.ts
CHANGED
|
@@ -44,7 +44,7 @@ export default class CSI extends IndexFile {
|
|
|
44
44
|
}
|
|
45
45
|
return -1
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
indexCov() {
|
|
48
48
|
throw new Error('CSI indexes do not support indexcov')
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -85,7 +85,7 @@ export default class CSI extends IndexFile {
|
|
|
85
85
|
let currRefId = 0
|
|
86
86
|
let currNameStart = 0
|
|
87
87
|
const refIdToName = []
|
|
88
|
-
const refNameToId:
|
|
88
|
+
const refNameToId: Record<string, number> = {}
|
|
89
89
|
for (let i = 0; i < namesBytes.length; i += 1) {
|
|
90
90
|
if (!namesBytes[i]) {
|
|
91
91
|
if (currNameStart < i) {
|
|
@@ -104,7 +104,7 @@ export default class CSI extends IndexFile {
|
|
|
104
104
|
// fetch and parse the index
|
|
105
105
|
|
|
106
106
|
async _parse(opts: Options = {}) {
|
|
107
|
-
const bytes = await unzip(
|
|
107
|
+
const bytes = await unzip(await this.filehandle.readFile(opts))
|
|
108
108
|
|
|
109
109
|
// check TBI magic numbers
|
|
110
110
|
let csiVersion
|
|
@@ -142,7 +142,7 @@ export default class CSI extends IndexFile {
|
|
|
142
142
|
// the binning index
|
|
143
143
|
const binCount = bytes.readInt32LE(currOffset)
|
|
144
144
|
currOffset += 4
|
|
145
|
-
const binIndex:
|
|
145
|
+
const binIndex: Record<string, Chunk[]> = {}
|
|
146
146
|
let stats // < provided by parsing a pseudo-bin, if present
|
|
147
147
|
for (let j = 0; j < binCount; j += 1) {
|
|
148
148
|
const bin = bytes.readUInt32LE(currOffset)
|
|
@@ -224,9 +224,8 @@ export default class CSI extends IndexFile {
|
|
|
224
224
|
for (const [start, end] of overlappingBins) {
|
|
225
225
|
for (let bin = start; bin <= end; bin++) {
|
|
226
226
|
if (ba.binIndex[bin]) {
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
chunks.push(new Chunk(binChunks[c].minv, binChunks[c].maxv, bin))
|
|
227
|
+
for (const c of ba.binIndex[bin]) {
|
|
228
|
+
chunks.push(new Chunk(c.minv, c.maxv, bin))
|
|
230
229
|
}
|
|
231
230
|
}
|
|
232
231
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export { TabixIndexedFile, TBI, CSI }
|
|
1
|
+
export { default as TabixIndexedFile } from './tabixIndexedFile'
|
|
2
|
+
export { default as CSI } from './csi'
|
|
3
|
+
export { default as TBI } from './tbi'
|
package/src/indexFile.ts
CHANGED
|
@@ -9,7 +9,7 @@ export interface Options {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export interface IndexData {
|
|
12
|
-
refNameToId:
|
|
12
|
+
refNameToId: Record<string, number>
|
|
13
13
|
refIdToName: string[]
|
|
14
14
|
metaChar: string | null
|
|
15
15
|
columnNumbers: { ref: number; start: number; end: number }
|
|
@@ -39,8 +39,7 @@ export default abstract class IndexFile {
|
|
|
39
39
|
protected abstract _parse(opts: Options): Promise<IndexData>
|
|
40
40
|
|
|
41
41
|
public async getMetadata(opts: Options = {}) {
|
|
42
|
-
|
|
43
|
-
const { indices, ...rest } = await this.parse(opts)
|
|
42
|
+
const { indices: _indices, ...rest } = await this.parse(opts)
|
|
44
43
|
return rest
|
|
45
44
|
}
|
|
46
45
|
|
|
@@ -75,6 +74,7 @@ export default abstract class IndexFile {
|
|
|
75
74
|
}
|
|
76
75
|
|
|
77
76
|
async hasRefSeq(seqId: number, opts: Options = {}) {
|
|
78
|
-
|
|
77
|
+
const idx = await this.parse(opts)
|
|
78
|
+
return !!idx.indices[seqId]?.binIndex
|
|
79
79
|
}
|
|
80
80
|
}
|
package/src/tabixIndexedFile.ts
CHANGED
|
@@ -13,7 +13,7 @@ import CSI from './csi'
|
|
|
13
13
|
type GetLinesCallback = (line: string, fileOffset: number) => void
|
|
14
14
|
|
|
15
15
|
const decoder =
|
|
16
|
-
typeof TextDecoder !== 'undefined' ? new TextDecoder('
|
|
16
|
+
typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined
|
|
17
17
|
|
|
18
18
|
interface GetLinesOpts {
|
|
19
19
|
[key: string]: unknown
|
|
@@ -132,14 +132,14 @@ export default class TabixIndexedFile {
|
|
|
132
132
|
*/
|
|
133
133
|
async getLines(
|
|
134
134
|
refName: string,
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
s: number | undefined,
|
|
136
|
+
e: number | undefined,
|
|
137
137
|
opts: GetLinesOpts | GetLinesCallback,
|
|
138
138
|
) {
|
|
139
139
|
let signal: AbortSignal | undefined
|
|
140
140
|
let options: Options = {}
|
|
141
141
|
let callback: (line: string, lineOffset: number) => void
|
|
142
|
-
if (
|
|
142
|
+
if (opts === undefined) {
|
|
143
143
|
throw new TypeError('line callback must be provided')
|
|
144
144
|
}
|
|
145
145
|
if (typeof opts === 'function') {
|
|
@@ -157,12 +157,8 @@ export default class TabixIndexedFile {
|
|
|
157
157
|
|
|
158
158
|
const metadata = await this.index.getMetadata(options)
|
|
159
159
|
checkAbortSignal(signal)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
if (!end) {
|
|
164
|
-
end = metadata.maxRefLength
|
|
165
|
-
}
|
|
160
|
+
const start = s ?? 0
|
|
161
|
+
const end = e ?? metadata.maxRefLength
|
|
166
162
|
if (!(start <= end)) {
|
|
167
163
|
throw new TypeError(
|
|
168
164
|
'invalid start and end coordinates. start must be less than or equal to end',
|
|
@@ -177,8 +173,8 @@ export default class TabixIndexedFile {
|
|
|
177
173
|
|
|
178
174
|
// check the chunks for any that are over the size limit. if
|
|
179
175
|
// any are, don't fetch any of them
|
|
180
|
-
for (
|
|
181
|
-
const size =
|
|
176
|
+
for (const chunk of chunks) {
|
|
177
|
+
const size = chunk.fetchedSize()
|
|
182
178
|
if (size > this.chunkSizeLimit) {
|
|
183
179
|
throw new Error(
|
|
184
180
|
`Too much data. Chunk size ${size.toLocaleString()} bytes exceeds chunkSizeLimit of ${this.chunkSizeLimit.toLocaleString()}.`,
|
|
@@ -188,12 +184,12 @@ export default class TabixIndexedFile {
|
|
|
188
184
|
|
|
189
185
|
// now go through each chunk and parse and filter the lines out of it
|
|
190
186
|
let last = Date.now()
|
|
191
|
-
for (
|
|
187
|
+
for (const c of chunks) {
|
|
192
188
|
let previousStartCoordinate: number | undefined
|
|
193
|
-
const c = chunks[chunkNum]
|
|
194
189
|
const { buffer, cpositions, dpositions } = await this.chunkCache.get(
|
|
195
190
|
c.toString(),
|
|
196
191
|
c,
|
|
192
|
+
signal,
|
|
197
193
|
)
|
|
198
194
|
|
|
199
195
|
checkAbortSignal(signal)
|
|
@@ -205,7 +201,7 @@ export default class TabixIndexedFile {
|
|
|
205
201
|
break
|
|
206
202
|
}
|
|
207
203
|
const b = buffer.slice(blockStart, n)
|
|
208
|
-
const line = decoder?.decode(b)
|
|
204
|
+
const line = decoder?.decode(b) ?? b.toString()
|
|
209
205
|
|
|
210
206
|
if (dpositions) {
|
|
211
207
|
while (blockStart + c.minv.dataPosition >= dpositions[pos++]) {}
|
|
@@ -278,25 +274,15 @@ export default class TabixIndexedFile {
|
|
|
278
274
|
* non-meta line
|
|
279
275
|
*/
|
|
280
276
|
async getHeaderBuffer(opts: Options = {}) {
|
|
281
|
-
const { firstDataLine, metaChar, maxBlockSize } =
|
|
282
|
-
opts
|
|
283
|
-
)
|
|
277
|
+
const { firstDataLine, metaChar, maxBlockSize } =
|
|
278
|
+
await this.getMetadata(opts)
|
|
284
279
|
checkAbortSignal(opts.signal)
|
|
285
280
|
const maxFetch = (firstDataLine?.blockPosition || 0) + maxBlockSize
|
|
286
281
|
// TODO: what if we don't have a firstDataLine, and the header
|
|
287
282
|
// actually takes up more than one block? this case is not covered here
|
|
288
283
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
try {
|
|
292
|
-
bytes = await unzip(bytes)
|
|
293
|
-
} catch (e) {
|
|
294
|
-
console.error(e)
|
|
295
|
-
throw new Error(
|
|
296
|
-
//@ts-ignore
|
|
297
|
-
`error decompressing block ${e.code} at 0 (length ${maxFetch}) ${e}`,
|
|
298
|
-
)
|
|
299
|
-
}
|
|
284
|
+
const buf = await this._readRegion(0, maxFetch, opts)
|
|
285
|
+
const bytes = await unzip(buf)
|
|
300
286
|
|
|
301
287
|
// trim off lines after the last non-meta line
|
|
302
288
|
if (metaChar) {
|
|
@@ -312,7 +298,7 @@ export default class TabixIndexedFile {
|
|
|
312
298
|
lastNewline = i
|
|
313
299
|
}
|
|
314
300
|
}
|
|
315
|
-
|
|
301
|
+
return bytes.slice(0, lastNewline + 1)
|
|
316
302
|
}
|
|
317
303
|
return bytes
|
|
318
304
|
}
|
|
@@ -357,7 +343,7 @@ export default class TabixIndexedFile {
|
|
|
357
343
|
) {
|
|
358
344
|
const { columnNumbers, metaChar, coordinateType, format } = metadata
|
|
359
345
|
// skip meta lines
|
|
360
|
-
if (line.
|
|
346
|
+
if (metaChar && line.startsWith(metaChar)) {
|
|
361
347
|
return { overlaps: false }
|
|
362
348
|
}
|
|
363
349
|
|
|
@@ -412,17 +398,15 @@ export default class TabixIndexedFile {
|
|
|
412
398
|
} else if (format === 'VCF' && currentColumnNumber === 4) {
|
|
413
399
|
refSeq = line.slice(currentColumnStart, i)
|
|
414
400
|
} else if (currentColumnNumber === end) {
|
|
415
|
-
let endCoordinate
|
|
416
401
|
// this will never match if there is no end column
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
}
|
|
402
|
+
const endCoordinate =
|
|
403
|
+
format === 'VCF'
|
|
404
|
+
? this._getVcfEnd(
|
|
405
|
+
startCoordinate,
|
|
406
|
+
refSeq,
|
|
407
|
+
line.slice(currentColumnStart, i),
|
|
408
|
+
)
|
|
409
|
+
: parseInt(line.slice(currentColumnStart, i), 10)
|
|
426
410
|
if (endCoordinate <= regionStart) {
|
|
427
411
|
return { overlaps: false }
|
|
428
412
|
}
|
|
@@ -439,12 +423,12 @@ export default class TabixIndexedFile {
|
|
|
439
423
|
|
|
440
424
|
_getVcfEnd(startCoordinate: number, refSeq: string, info: any) {
|
|
441
425
|
let endCoordinate = startCoordinate + refSeq.length
|
|
442
|
-
// ignore TRA features as they specify CHR2 and END
|
|
443
|
-
//
|
|
444
|
-
//
|
|
445
|
-
//
|
|
446
|
-
// at the end of this one
|
|
447
|
-
const isTRA = info.
|
|
426
|
+
// ignore TRA features as they specify CHR2 and END as being on a different
|
|
427
|
+
// chromosome
|
|
428
|
+
//
|
|
429
|
+
// if CHR2 is on the same chromosome, still ignore it because there should
|
|
430
|
+
// be another pairwise feature at the end of this one
|
|
431
|
+
const isTRA = info.includes('SVTYPE=TRA')
|
|
448
432
|
if (info[0] !== '.' && !isTRA) {
|
|
449
433
|
let prevChar = ';'
|
|
450
434
|
for (let j = 0; j < info.length; j += 1) {
|
|
@@ -499,10 +483,6 @@ export default class TabixIndexedFile {
|
|
|
499
483
|
c.fetchedSize(),
|
|
500
484
|
opts,
|
|
501
485
|
)
|
|
502
|
-
|
|
503
|
-
return unzipChunkSlice(data, c)
|
|
504
|
-
} catch (e) {
|
|
505
|
-
throw new Error(`error decompressing c ${c.toString()} ${e}`)
|
|
506
|
-
}
|
|
486
|
+
return unzipChunkSlice(data, c)
|
|
507
487
|
}
|
|
508
488
|
}
|
package/src/tbi.ts
CHANGED
|
@@ -60,7 +60,7 @@ export default class TabixIndex extends IndexFile {
|
|
|
60
60
|
const formatFlags = bytes.readInt32LE(8)
|
|
61
61
|
const coordinateType =
|
|
62
62
|
formatFlags & 0x10000 ? 'zero-based-half-open' : '1-based-closed'
|
|
63
|
-
const formatOpts:
|
|
63
|
+
const formatOpts: Record<number, string> = {
|
|
64
64
|
0: 'generic',
|
|
65
65
|
1: 'SAM',
|
|
66
66
|
2: 'VCF',
|
|
@@ -94,7 +94,7 @@ export default class TabixIndex extends IndexFile {
|
|
|
94
94
|
// the binning index
|
|
95
95
|
const binCount = bytes.readInt32LE(currOffset)
|
|
96
96
|
currOffset += 4
|
|
97
|
-
const binIndex:
|
|
97
|
+
const binIndex: Record<number, Chunk[]> = {}
|
|
98
98
|
let stats
|
|
99
99
|
for (let j = 0; j < binCount; j += 1) {
|
|
100
100
|
const bin = bytes.readUInt32LE(currOffset)
|
|
@@ -167,7 +167,7 @@ export default class TabixIndex extends IndexFile {
|
|
|
167
167
|
let currRefId = 0
|
|
168
168
|
let currNameStart = 0
|
|
169
169
|
const refIdToName: string[] = []
|
|
170
|
-
const refNameToId:
|
|
170
|
+
const refNameToId: Record<string, number> = {}
|
|
171
171
|
for (let i = 0; i < namesBytes.length; i += 1) {
|
|
172
172
|
if (!namesBytes[i]) {
|
|
173
173
|
if (currNameStart < i) {
|
|
@@ -223,9 +223,8 @@ export default class TabixIndex extends IndexFile {
|
|
|
223
223
|
for (const [start, end] of overlappingBins) {
|
|
224
224
|
for (let bin = start; bin <= end; bin++) {
|
|
225
225
|
if (ba.binIndex[bin]) {
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
chunks.push(new Chunk(binChunks[c].minv, binChunks[c].maxv, bin))
|
|
226
|
+
for (const c of ba.binIndex[bin]) {
|
|
227
|
+
chunks.push(new Chunk(c.minv, c.maxv, bin))
|
|
229
228
|
}
|
|
230
229
|
}
|
|
231
230
|
}
|
package/src/util.ts
CHANGED
|
@@ -70,11 +70,7 @@ export function optimizeChunks(chunks: Chunk[], lowest: VirtualOffset) {
|
|
|
70
70
|
|
|
71
71
|
chunks.sort(function (c0, c1) {
|
|
72
72
|
const dif = c0.minv.blockPosition - c1.minv.blockPosition
|
|
73
|
-
|
|
74
|
-
return dif
|
|
75
|
-
} else {
|
|
76
|
-
return c0.minv.dataPosition - c1.minv.dataPosition
|
|
77
|
-
}
|
|
73
|
+
return dif !== 0 ? dif : c0.minv.dataPosition - c1.minv.dataPosition
|
|
78
74
|
})
|
|
79
75
|
|
|
80
76
|
chunks.forEach(chunk => {
|