@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
|
@@ -7,6 +7,7 @@ import CramRecord from '../record'
|
|
|
7
7
|
import CramContainer from '../container'
|
|
8
8
|
import CramFile, { CramFileBlock } from '../file'
|
|
9
9
|
import {
|
|
10
|
+
getSectionParsers,
|
|
10
11
|
isMappedSliceHeader,
|
|
11
12
|
MappedSliceHeader,
|
|
12
13
|
UnmappedSliceHeader,
|
|
@@ -191,10 +192,15 @@ export default class CramSlice {
|
|
|
191
192
|
}
|
|
192
193
|
|
|
193
194
|
// memoize
|
|
194
|
-
async getHeader()
|
|
195
|
+
async getHeader() {
|
|
195
196
|
// fetch and parse the slice header
|
|
196
|
-
const
|
|
197
|
+
const { majorVersion } = await this.file.getDefinition()
|
|
198
|
+
const sectionParsers = getSectionParsers(majorVersion)
|
|
197
199
|
const containerHeader = await this.container.getHeader()
|
|
200
|
+
if (!containerHeader) {
|
|
201
|
+
throw new Error('no container header detected')
|
|
202
|
+
}
|
|
203
|
+
|
|
198
204
|
const header = await this.file.readBlock(
|
|
199
205
|
containerHeader._endPosition + this.containerPosition,
|
|
200
206
|
)
|
|
@@ -230,7 +236,7 @@ export default class CramSlice {
|
|
|
230
236
|
// read all the blocks into memory and store them
|
|
231
237
|
let blockPosition = header._endPosition
|
|
232
238
|
const blocks: CramFileBlock[] = new Array(header.parsedContent.numBlocks)
|
|
233
|
-
for (let i = 0; i < blocks.length; i
|
|
239
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
234
240
|
const block = await this.file.readBlock(blockPosition)
|
|
235
241
|
if (block === undefined) {
|
|
236
242
|
throw new Error('block undefined')
|
|
@@ -363,14 +369,14 @@ export default class CramSlice {
|
|
|
363
369
|
this.file.options.checkSequenceMD5 &&
|
|
364
370
|
isMappedSliceHeader(sliceHeader.parsedContent) &&
|
|
365
371
|
sliceHeader.parsedContent.refSeqId >= 0 &&
|
|
366
|
-
sliceHeader.parsedContent.md5
|
|
372
|
+
sliceHeader.parsedContent.md5?.join('') !== '0000000000000000'
|
|
367
373
|
) {
|
|
368
374
|
const refRegion = await this.getReferenceRegion()
|
|
369
375
|
if (refRegion) {
|
|
370
376
|
const { seq, start, end } = refRegion
|
|
371
377
|
const seqMd5 = sequenceMD5(seq)
|
|
372
378
|
const storedMd5 = sliceHeader.parsedContent.md5
|
|
373
|
-
|
|
379
|
+
?.map(byte => (byte < 16 ? '0' : '') + byte.toString(16))
|
|
374
380
|
.join('')
|
|
375
381
|
if (seqMd5 !== storedMd5) {
|
|
376
382
|
throw new CramMalformedError(
|
package/src/cramFile/util.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import md5 from 'md5'
|
|
2
|
-
import
|
|
2
|
+
import Long from 'long'
|
|
3
3
|
import { CramBufferOverrunError } from './codecs/getBits'
|
|
4
4
|
|
|
5
5
|
export function itf8Size(v: number) {
|
|
@@ -18,10 +18,7 @@ export function itf8Size(v: number) {
|
|
|
18
18
|
return 5
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export function parseItf8(
|
|
22
|
-
buffer: Uint8Array,
|
|
23
|
-
initialOffset: number,
|
|
24
|
-
): [number, number] {
|
|
21
|
+
export function parseItf8(buffer: Uint8Array, initialOffset: number) {
|
|
25
22
|
let offset = initialOffset
|
|
26
23
|
const countFlags = buffer[offset]
|
|
27
24
|
let result
|
|
@@ -60,106 +57,108 @@ export function parseItf8(
|
|
|
60
57
|
'Attempted to read beyond end of buffer; this file seems truncated.',
|
|
61
58
|
)
|
|
62
59
|
}
|
|
63
|
-
return [result, offset - initialOffset]
|
|
60
|
+
return [result, offset - initialOffset] as const
|
|
64
61
|
}
|
|
65
62
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
63
|
+
export function parseLtf8(buffer: Buffer, initialOffset: number) {
|
|
64
|
+
let offset = initialOffset
|
|
65
|
+
const countFlags = buffer[offset]
|
|
66
|
+
let n
|
|
67
|
+
if (countFlags < 0x80) {
|
|
68
|
+
n = countFlags
|
|
69
|
+
offset += 1
|
|
70
|
+
} else if (countFlags < 0xc0) {
|
|
71
|
+
n = ((buffer[offset] << 8) | buffer[offset + 1]) & 0x3fff
|
|
72
|
+
offset += 2
|
|
73
|
+
} else if (countFlags < 0xe0) {
|
|
74
|
+
n =
|
|
75
|
+
((buffer[offset] << 16) |
|
|
76
|
+
(buffer[offset + 1] << 8) |
|
|
77
|
+
buffer[offset + 2]) &
|
|
78
|
+
0x1fffff
|
|
79
|
+
n = ((countFlags & 63) << 16) | buffer.readUInt16LE(offset + 1)
|
|
80
|
+
offset += 3
|
|
81
|
+
} else if (countFlags < 0xf0) {
|
|
82
|
+
n =
|
|
83
|
+
((buffer[offset] << 24) |
|
|
84
|
+
(buffer[offset + 1] << 16) |
|
|
85
|
+
(buffer[offset + 2] << 8) |
|
|
86
|
+
buffer[offset + 3]) &
|
|
87
|
+
0x0fffffff
|
|
88
|
+
offset += 4
|
|
89
|
+
} else if (countFlags < 0xf8) {
|
|
90
|
+
n =
|
|
91
|
+
((buffer[offset] & 15) * Math.pow(2, 32) + (buffer[offset + 1] << 24)) |
|
|
92
|
+
((buffer[offset + 2] << 16) |
|
|
93
|
+
(buffer[offset + 3] << 8) |
|
|
94
|
+
buffer[offset + 4])
|
|
95
|
+
// TODO *val_p = uv < 0x80000000UL ? uv : -((int32_t) (0xffffffffUL - uv)) - 1;
|
|
96
|
+
offset += 5
|
|
97
|
+
} else if (countFlags < 0xfc) {
|
|
98
|
+
n =
|
|
99
|
+
((((buffer[offset] & 7) << 8) | buffer[offset + 1]) * Math.pow(2, 32) +
|
|
100
|
+
(buffer[offset + 2] << 24)) |
|
|
101
|
+
((buffer[offset + 3] << 16) |
|
|
102
|
+
(buffer[offset + 4] << 8) |
|
|
103
|
+
buffer[offset + 5])
|
|
104
|
+
offset += 6
|
|
105
|
+
} else if (countFlags < 0xfe) {
|
|
106
|
+
n =
|
|
107
|
+
((((buffer[offset] & 3) << 16) |
|
|
108
|
+
(buffer[offset + 1] << 8) |
|
|
109
|
+
buffer[offset + 2]) *
|
|
110
|
+
Math.pow(2, 32) +
|
|
111
|
+
(buffer[offset + 3] << 24)) |
|
|
112
|
+
((buffer[offset + 4] << 16) |
|
|
113
|
+
(buffer[offset + 5] << 8) |
|
|
114
|
+
buffer[offset + 6])
|
|
115
|
+
offset += 7
|
|
116
|
+
} else if (countFlags < 0xff) {
|
|
117
|
+
n = Long.fromBytesBE(
|
|
118
|
+
buffer.slice(offset + 1, offset + 8) as unknown as number[],
|
|
119
|
+
)
|
|
120
|
+
if (
|
|
121
|
+
n.greaterThan(Number.MAX_SAFE_INTEGER) ||
|
|
122
|
+
n.lessThan(Number.MIN_SAFE_INTEGER)
|
|
123
|
+
) {
|
|
124
|
+
throw new Error('integer overflow')
|
|
125
|
+
}
|
|
126
|
+
n = n.toNumber()
|
|
127
|
+
offset += 8
|
|
128
|
+
} else {
|
|
129
|
+
n = Long.fromBytesBE(
|
|
130
|
+
buffer.slice(offset + 1, offset + 9) as unknown as number[],
|
|
131
|
+
)
|
|
132
|
+
if (
|
|
133
|
+
n.greaterThan(Number.MAX_SAFE_INTEGER) ||
|
|
134
|
+
n.lessThan(Number.MIN_SAFE_INTEGER)
|
|
135
|
+
) {
|
|
136
|
+
throw new Error('integer overflow')
|
|
137
|
+
}
|
|
138
|
+
n = n.toNumber()
|
|
139
|
+
offset += 9
|
|
140
|
+
}
|
|
141
|
+
return [n, offset - initialOffset] as const
|
|
143
142
|
}
|
|
144
143
|
|
|
145
144
|
export function parseItem<T>(
|
|
146
145
|
buffer: Buffer,
|
|
147
|
-
parser:
|
|
146
|
+
parser: (buffer: Buffer, offset: number) => { offset: number; value: T },
|
|
148
147
|
startBufferPosition = 0,
|
|
149
148
|
startFilePosition = 0,
|
|
150
|
-
)
|
|
151
|
-
const { offset,
|
|
149
|
+
) {
|
|
150
|
+
const { offset, value } = parser(buffer, startBufferPosition)
|
|
152
151
|
return {
|
|
153
|
-
...
|
|
152
|
+
...value,
|
|
154
153
|
_endPosition: offset + startFilePosition,
|
|
155
154
|
_size: offset - startBufferPosition,
|
|
156
155
|
}
|
|
157
156
|
}
|
|
158
157
|
|
|
159
|
-
// this would be nice as a decorator, but i'm a little worried about
|
|
160
|
-
//
|
|
161
|
-
//
|
|
162
|
-
//
|
|
158
|
+
// this would be nice as a decorator, but i'm a little worried about babel
|
|
159
|
+
// support for it going away or changing. memoizes a method in the stupidest
|
|
160
|
+
// possible way, with no regard for the arguments. actually, this only works
|
|
161
|
+
// on methods that take no arguments
|
|
163
162
|
export function tinyMemoize(_class: any, methodName: any) {
|
|
164
163
|
const method = _class.prototype[methodName]
|
|
165
164
|
const memoAttrName = `_memo_${methodName}`
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
declare module '@gmod/binary-parser' {
|
|
2
|
-
export interface Options {
|
|
3
|
-
stripNull?: boolean
|
|
4
|
-
formatter?: (item: any) => any
|
|
5
|
-
length?: number | string | ((this: { $parent: unknown }) => void)
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export class Parser<T = unknown> {
|
|
9
|
-
public static start<TStart>(): Parser<TStart>
|
|
10
|
-
|
|
11
|
-
public uint8(name?: string | null, options?: Options): Parser
|
|
12
|
-
|
|
13
|
-
public itf8(name?: string | null, options?: Options): Parser
|
|
14
|
-
|
|
15
|
-
public ltf8(name?: string | null, options?: Options): Parser
|
|
16
|
-
|
|
17
|
-
public uint32(name?: string | null, options?: Options): Parser
|
|
18
|
-
|
|
19
|
-
public int32(name?: string | null, options?: Options): Parser
|
|
20
|
-
|
|
21
|
-
public buffer(name?: string | null, options?: Options): Parser
|
|
22
|
-
|
|
23
|
-
public string(name?: string | null, options?: Options): Parser
|
|
24
|
-
|
|
25
|
-
public namely(name: string): Parser
|
|
26
|
-
|
|
27
|
-
public nest(
|
|
28
|
-
name?: string | null,
|
|
29
|
-
options?: { type: Parser | string } & Options,
|
|
30
|
-
): Parser
|
|
31
|
-
|
|
32
|
-
public choice(
|
|
33
|
-
name?: string | null,
|
|
34
|
-
options?: { tag: string; choices: any } & Options,
|
|
35
|
-
): Parser
|
|
36
|
-
|
|
37
|
-
public array(
|
|
38
|
-
name?: string | null,
|
|
39
|
-
options?: { type: string | Parser } & Options,
|
|
40
|
-
): Parser
|
|
41
|
-
|
|
42
|
-
parse(bytes: Buffer): { result: T; offset: number }
|
|
43
|
-
}
|
|
44
|
-
}
|