@gmod/cram 2.0.4 → 3.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.
- package/CHANGELOG.md +10 -0
- package/dist/cram-bundle.js +1 -1
- package/dist/cramFile/codecs/byteArrayLength.js +1 -1
- package/dist/cramFile/codecs/byteArrayLength.js.map +1 -1
- package/dist/cramFile/codecs/external.js +1 -1
- package/dist/cramFile/codecs/external.js.map +1 -1
- package/dist/cramFile/codecs/huffman.js +2 -1
- package/dist/cramFile/codecs/huffman.js.map +1 -1
- package/dist/cramFile/container/compressionScheme.d.ts +0 -3
- package/dist/cramFile/container/compressionScheme.js +0 -4
- package/dist/cramFile/container/compressionScheme.js.map +1 -1
- package/dist/cramFile/container/index.d.ts +56 -3
- package/dist/cramFile/container/index.js +15 -9
- package/dist/cramFile/container/index.js.map +1 -1
- package/dist/cramFile/file.d.ts +24 -59
- package/dist/cramFile/file.js +21 -26
- package/dist/cramFile/file.js.map +1 -1
- package/dist/cramFile/record.d.ts +1 -1
- package/dist/cramFile/sectionParsers.d.ts +195 -48
- package/dist/cramFile/sectionParsers.js +621 -303
- package/dist/cramFile/sectionParsers.js.map +1 -1
- package/dist/cramFile/slice/index.d.ts +23 -1
- package/dist/cramFile/slice/index.js +9 -6
- package/dist/cramFile/slice/index.js.map +1 -1
- package/dist/cramFile/util.d.ts +6 -4
- package/dist/cramFile/util.js +88 -6
- package/dist/cramFile/util.js.map +1 -1
- package/esm/cramFile/codecs/byteArrayLength.js +1 -1
- package/esm/cramFile/codecs/byteArrayLength.js.map +1 -1
- package/esm/cramFile/codecs/external.js +1 -1
- package/esm/cramFile/codecs/external.js.map +1 -1
- package/esm/cramFile/codecs/huffman.js +2 -1
- package/esm/cramFile/codecs/huffman.js.map +1 -1
- package/esm/cramFile/container/compressionScheme.d.ts +0 -3
- package/esm/cramFile/container/compressionScheme.js +0 -4
- package/esm/cramFile/container/compressionScheme.js.map +1 -1
- package/esm/cramFile/container/index.d.ts +56 -3
- package/esm/cramFile/container/index.js +15 -9
- package/esm/cramFile/container/index.js.map +1 -1
- package/esm/cramFile/file.d.ts +24 -59
- package/esm/cramFile/file.js +22 -25
- package/esm/cramFile/file.js.map +1 -1
- package/esm/cramFile/record.d.ts +1 -1
- package/esm/cramFile/sectionParsers.d.ts +195 -48
- package/esm/cramFile/sectionParsers.js +620 -303
- package/esm/cramFile/sectionParsers.js.map +1 -1
- package/esm/cramFile/slice/index.d.ts +23 -1
- package/esm/cramFile/slice/index.js +10 -7
- package/esm/cramFile/slice/index.js.map +1 -1
- package/esm/cramFile/util.d.ts +6 -4
- package/esm/cramFile/util.js +87 -6
- package/esm/cramFile/util.js.map +1 -1
- package/package.json +7 -8
- package/src/cramFile/codecs/byteArrayLength.ts +1 -2
- package/src/cramFile/codecs/external.ts +1 -1
- package/src/cramFile/codecs/huffman.ts +2 -1
- package/src/cramFile/container/compressionScheme.ts +1 -8
- package/src/cramFile/container/index.ts +21 -10
- package/src/cramFile/file.ts +28 -43
- package/src/cramFile/record.ts +1 -1
- package/src/cramFile/sectionParsers.ts +668 -390
- package/src/cramFile/slice/index.ts +11 -5
- package/src/cramFile/util.ts +90 -91
- package/src/typings/binary-parser.d.ts +0 -44
package/src/cramFile/file.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { unzip } from '../unzip'
|
|
|
2
2
|
import crc32 from 'buffer-crc32'
|
|
3
3
|
import QuickLRU from 'quick-lru'
|
|
4
4
|
import htscodecs from '@jkbonfield/htscodecs'
|
|
5
|
-
import { Parser } from '@gmod/binary-parser'
|
|
6
5
|
// @ts-expect-error
|
|
7
6
|
import bzip2 from 'bzip2'
|
|
8
7
|
import { XzReadableStream } from 'xz-decompress'
|
|
@@ -11,7 +10,7 @@ import ransuncompress from '../rans'
|
|
|
11
10
|
import {
|
|
12
11
|
BlockHeader,
|
|
13
12
|
CompressionMethod,
|
|
14
|
-
cramFileDefinition
|
|
13
|
+
cramFileDefinition,
|
|
15
14
|
getSectionParsers,
|
|
16
15
|
} from './sectionParsers'
|
|
17
16
|
|
|
@@ -32,25 +31,20 @@ function bufferToStream(buf: Buffer) {
|
|
|
32
31
|
})
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
//source:https://abdulapopoola.com/2019/01/20/check-endianness-with-javascript/
|
|
34
|
+
// source:https://abdulapopoola.com/2019/01/20/check-endianness-with-javascript/
|
|
36
35
|
function getEndianness() {
|
|
37
36
|
const uInt32 = new Uint32Array([0x11223344])
|
|
38
37
|
const uInt8 = new Uint8Array(uInt32.buffer)
|
|
39
38
|
|
|
40
39
|
if (uInt8[0] === 0x44) {
|
|
41
|
-
return 0 //little-endian
|
|
40
|
+
return 0 // little-endian
|
|
42
41
|
} else if (uInt8[0] === 0x11) {
|
|
43
|
-
return 1 //big-endian
|
|
42
|
+
return 1 // big-endian
|
|
44
43
|
} else {
|
|
45
|
-
return 2 //mixed-endian?
|
|
44
|
+
return 2 // mixed-endian?
|
|
46
45
|
}
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
// export type CramFileSource =
|
|
50
|
-
// | { url: string; path?: undefined; filehandle?: undefined }
|
|
51
|
-
// | { path: string; url?: undefined; filehandle?: undefined }
|
|
52
|
-
// | { filehandle: Filehandle; url?: undefined; path?: undefined }
|
|
53
|
-
|
|
54
48
|
export interface CramFileSource {
|
|
55
49
|
filehandle?: Filehandle
|
|
56
50
|
url?: string
|
|
@@ -110,15 +104,7 @@ export default class CramFile {
|
|
|
110
104
|
}
|
|
111
105
|
|
|
112
106
|
// can just read this object like a filehandle
|
|
113
|
-
read(
|
|
114
|
-
buffer: Buffer,
|
|
115
|
-
offset: number,
|
|
116
|
-
length: number,
|
|
117
|
-
position: number,
|
|
118
|
-
): Promise<{
|
|
119
|
-
bytesRead: number
|
|
120
|
-
buffer: Buffer
|
|
121
|
-
}> {
|
|
107
|
+
read(buffer: Buffer, offset: number, length: number, position: number) {
|
|
122
108
|
return this.file.read(buffer, offset, length, position)
|
|
123
109
|
}
|
|
124
110
|
|
|
@@ -129,10 +115,10 @@ export default class CramFile {
|
|
|
129
115
|
|
|
130
116
|
// memoized
|
|
131
117
|
async getDefinition() {
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
118
|
+
const { maxLength, parser } = cramFileDefinition()
|
|
119
|
+
const headbytes = Buffer.allocUnsafe(maxLength)
|
|
120
|
+
await this.file.read(headbytes, 0, maxLength, 0)
|
|
121
|
+
const definition = parser(headbytes).value
|
|
136
122
|
if (definition.majorVersion !== 2 && definition.majorVersion !== 3) {
|
|
137
123
|
throw new CramUnimplementedError(
|
|
138
124
|
`CRAM version ${definition.majorVersion} not supported`,
|
|
@@ -169,21 +155,16 @@ export default class CramFile {
|
|
|
169
155
|
return this.header
|
|
170
156
|
}
|
|
171
157
|
|
|
172
|
-
// memoize
|
|
173
|
-
async getSectionParsers() {
|
|
174
|
-
const { majorVersion } = await this.getDefinition()
|
|
175
|
-
return getSectionParsers(majorVersion)
|
|
176
|
-
}
|
|
177
|
-
|
|
178
158
|
async getContainerById(containerNumber: number) {
|
|
179
|
-
const
|
|
159
|
+
const { majorVersion } = await this.getDefinition()
|
|
160
|
+
const sectionParsers = getSectionParsers(majorVersion)
|
|
180
161
|
let position = sectionParsers.cramFileDefinition.maxLength
|
|
181
162
|
const { size: fileSize } = await this.file.stat()
|
|
182
163
|
const { cramContainerHeader1 } = sectionParsers
|
|
183
164
|
|
|
184
165
|
// skip with a series of reads to the proper container
|
|
185
166
|
let currentContainer
|
|
186
|
-
for (let i = 0; i <= containerNumber; i
|
|
167
|
+
for (let i = 0; i <= containerNumber; i++) {
|
|
187
168
|
// if we are about to go off the end of the file
|
|
188
169
|
// and have not found that container, it does not exist
|
|
189
170
|
if (position + cramContainerHeader1.maxLength + 8 >= fileSize) {
|
|
@@ -197,13 +178,12 @@ export default class CramFile {
|
|
|
197
178
|
`container ${containerNumber} not found in file`,
|
|
198
179
|
)
|
|
199
180
|
}
|
|
200
|
-
// if this is the first container, read all the blocks in the
|
|
201
|
-
//
|
|
202
|
-
//
|
|
203
|
-
// in htslib
|
|
181
|
+
// if this is the first container, read all the blocks in the container
|
|
182
|
+
// to determine its length, because we cannot trust the container
|
|
183
|
+
// header's given length due to a bug somewhere in htslib
|
|
204
184
|
if (i === 0) {
|
|
205
185
|
position = currentHeader._endPosition
|
|
206
|
-
for (let j = 0; j < currentHeader.numBlocks; j
|
|
186
|
+
for (let j = 0; j < currentHeader.numBlocks; j++) {
|
|
207
187
|
const block = await this.readBlock(position)
|
|
208
188
|
if (block === undefined) {
|
|
209
189
|
return undefined
|
|
@@ -239,7 +219,8 @@ export default class CramFile {
|
|
|
239
219
|
* @returns {Promise[number]} the number of containers in the file
|
|
240
220
|
*/
|
|
241
221
|
async containerCount(): Promise<number | undefined> {
|
|
242
|
-
const
|
|
222
|
+
const { majorVersion } = await this.getDefinition()
|
|
223
|
+
const sectionParsers = getSectionParsers(majorVersion)
|
|
243
224
|
const { size: fileSize } = await this.file.stat()
|
|
244
225
|
const { cramContainerHeader1 } = sectionParsers
|
|
245
226
|
|
|
@@ -256,7 +237,7 @@ export default class CramFile {
|
|
|
256
237
|
// header's given length due to a bug somewhere in htslib
|
|
257
238
|
if (containerCount === 0) {
|
|
258
239
|
position = currentHeader._endPosition
|
|
259
|
-
for (let j = 0; j < currentHeader.numBlocks; j
|
|
240
|
+
for (let j = 0; j < currentHeader.numBlocks; j++) {
|
|
260
241
|
const block = await this.readBlock(position)
|
|
261
242
|
if (block === undefined) {
|
|
262
243
|
return undefined
|
|
@@ -278,7 +259,8 @@ export default class CramFile {
|
|
|
278
259
|
}
|
|
279
260
|
|
|
280
261
|
async readBlockHeader(position: number) {
|
|
281
|
-
const
|
|
262
|
+
const { majorVersion } = await this.getDefinition()
|
|
263
|
+
const sectionParsers = getSectionParsers(majorVersion)
|
|
282
264
|
const { cramBlockHeader } = sectionParsers
|
|
283
265
|
const { size: fileSize } = await this.file.stat()
|
|
284
266
|
|
|
@@ -292,7 +274,10 @@ export default class CramFile {
|
|
|
292
274
|
}
|
|
293
275
|
|
|
294
276
|
async _parseSection<T>(
|
|
295
|
-
section: {
|
|
277
|
+
section: {
|
|
278
|
+
maxLength: number
|
|
279
|
+
parser: (buffer: Buffer, offset: number) => { offset: number; value: T }
|
|
280
|
+
},
|
|
296
281
|
position: number,
|
|
297
282
|
size = section.maxLength,
|
|
298
283
|
preReadBuffer = undefined,
|
|
@@ -363,9 +348,9 @@ export default class CramFile {
|
|
|
363
348
|
}
|
|
364
349
|
}
|
|
365
350
|
|
|
366
|
-
async readBlock(position: number)
|
|
351
|
+
async readBlock(position: number) {
|
|
367
352
|
const { majorVersion } = await this.getDefinition()
|
|
368
|
-
const sectionParsers =
|
|
353
|
+
const sectionParsers = getSectionParsers(majorVersion)
|
|
369
354
|
const blockHeader = await this.readBlockHeader(position)
|
|
370
355
|
if (blockHeader === undefined) {
|
|
371
356
|
return undefined
|
package/src/cramFile/record.ts
CHANGED