@gmod/cram 1.6.2 → 1.6.3

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 (42) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/cram-bundle.js +3 -3
  3. package/dist/cramFile/codecs/byteArrayLength.d.ts +1 -1
  4. package/dist/cramFile/codecs/byteArrayLength.js +1 -1
  5. package/dist/cramFile/codecs/byteArrayLength.js.map +1 -1
  6. package/dist/cramFile/codecs/byteArrayStop.js +1 -2
  7. package/dist/cramFile/codecs/byteArrayStop.js.map +1 -1
  8. package/dist/cramFile/codecs/external.js +1 -3
  9. package/dist/cramFile/codecs/external.js.map +1 -1
  10. package/dist/cramFile/container/compressionScheme.d.ts +1 -1
  11. package/dist/cramFile/container/compressionScheme.js +6 -4
  12. package/dist/cramFile/container/compressionScheme.js.map +1 -1
  13. package/dist/cramFile/file.js +17 -0
  14. package/dist/cramFile/file.js.map +1 -1
  15. package/dist/cramFile/slice/decodeRecord.js +62 -58
  16. package/dist/cramFile/slice/decodeRecord.js.map +1 -1
  17. package/dist/cramFile/slice/index.js +8 -5
  18. package/dist/cramFile/slice/index.js.map +1 -1
  19. package/esm/cramFile/codecs/byteArrayLength.d.ts +1 -1
  20. package/esm/cramFile/codecs/byteArrayLength.js +1 -1
  21. package/esm/cramFile/codecs/byteArrayLength.js.map +1 -1
  22. package/esm/cramFile/codecs/byteArrayStop.js +1 -2
  23. package/esm/cramFile/codecs/byteArrayStop.js.map +1 -1
  24. package/esm/cramFile/codecs/external.js +1 -3
  25. package/esm/cramFile/codecs/external.js.map +1 -1
  26. package/esm/cramFile/container/compressionScheme.d.ts +1 -1
  27. package/esm/cramFile/container/compressionScheme.js +6 -4
  28. package/esm/cramFile/container/compressionScheme.js.map +1 -1
  29. package/esm/cramFile/file.js +17 -0
  30. package/esm/cramFile/file.js.map +1 -1
  31. package/esm/cramFile/slice/decodeRecord.js +63 -59
  32. package/esm/cramFile/slice/decodeRecord.js.map +1 -1
  33. package/esm/cramFile/slice/index.js +11 -7
  34. package/esm/cramFile/slice/index.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/cramFile/codecs/byteArrayLength.js +1 -1
  37. package/src/cramFile/codecs/byteArrayStop.js +1 -2
  38. package/src/cramFile/codecs/external.js +1 -3
  39. package/src/cramFile/container/compressionScheme.js +6 -7
  40. package/src/cramFile/file.js +16 -0
  41. package/src/cramFile/slice/decodeRecord.js +61 -64
  42. package/src/cramFile/slice/index.js +11 -7
@@ -1,17 +1,17 @@
1
1
  import Long from 'long'
2
- import { CramMalformedError, CramUnimplementedError } from '../../errors'
2
+ import { CramMalformedError } from '../../errors'
3
3
  import CramRecord from '../record'
4
4
  import Constants from '../constants'
5
5
  /**
6
6
  * given a Buffer, read a string up to the first null character
7
7
  * @private
8
8
  */
9
- function readNullTerminatedStringFromBuffer(buffer) {
10
- const zeroOffset = buffer.indexOf(0)
11
- if (zeroOffset === -1) {
12
- return buffer.toString('utf8')
9
+ function readNullTerminatedString(buffer) {
10
+ let r = ''
11
+ for (let i = 0; i < buffer.length && buffer[i] !== 0; i++) {
12
+ r += String.fromCharCode(buffer[i])
13
13
  }
14
- return buffer.toString('utf8', 0, zeroOffset)
14
+ return r
15
15
  }
16
16
 
17
17
  /**
@@ -20,72 +20,85 @@ function readNullTerminatedStringFromBuffer(buffer) {
20
20
  */
21
21
  function parseTagValueArray(buffer) {
22
22
  const arrayType = String.fromCharCode(buffer[0])
23
- const length = buffer.readInt32LE(1)
24
-
25
- const schema = {
26
- c: ['readInt8', 1],
27
- C: ['readUInt8', 1],
28
- s: ['readInt16LE', 2],
29
- S: ['readUInt16LE', 2],
30
- i: ['readInt32LE', 4],
31
- I: ['readUInt32LE', 4],
32
- f: ['readFloatLE', 4],
33
- }[arrayType]
34
- if (!schema) {
35
- throw new CramMalformedError(`invalid tag value array type '${arrayType}'`)
36
- }
23
+ const length = Int32Array.from(buffer.slice(1))[0]
37
24
 
38
- const [getMethod, itemSize] = schema
39
25
  const array = new Array(length)
40
- let offset = 5
41
- for (let i = 0; i < length; i += 1) {
42
- array[i] = buffer[getMethod](offset)
43
- offset += itemSize
26
+ buffer = buffer.slice(5)
27
+
28
+ if (arrayType === 'c') {
29
+ const arr = new Int8Array(buffer.buffer)
30
+ for (let i = 0; i < length; i += 1) {
31
+ array[i] = arr[i]
32
+ }
33
+ } else if (arrayType === 'C') {
34
+ const arr = new Uint8Array(buffer.buffer)
35
+ for (let i = 0; i < length; i += 1) {
36
+ array[i] = arr[i]
37
+ }
38
+ } else if (arrayType === 's') {
39
+ const arr = new Int16Array(buffer.buffer)
40
+ for (let i = 0; i < length; i += 1) {
41
+ array[i] = arr[i]
42
+ }
43
+ } else if (arrayType === 'S') {
44
+ const arr = new Uint16Array(buffer.buffer)
45
+ for (let i = 0; i < length; i += 1) {
46
+ array[i] = arr[i]
47
+ }
48
+ } else if (arrayType === 'i') {
49
+ const arr = new Int32Array(buffer.buffer)
50
+ for (let i = 0; i < length; i += 1) {
51
+ array[i] = arr[i]
52
+ }
53
+ } else if (arrayType === 'I') {
54
+ const arr = new Uint32Array(buffer.buffer)
55
+ for (let i = 0; i < length; i += 1) {
56
+ array[i] = arr[i]
57
+ }
58
+ } else if (arrayType === 'f') {
59
+ const arr = new Float32Array(buffer.buffer)
60
+ for (let i = 0; i < length; i += 1) {
61
+ array[i] = arr[i]
62
+ }
63
+ } else {
64
+ throw new Error('unknown type: ' + arrayType)
44
65
  }
66
+
45
67
  return array
46
68
  }
47
-
48
69
  function parseTagData(tagType, buffer) {
49
- if (!buffer.readInt32LE) {
50
- buffer = Buffer.from(buffer)
51
- }
52
70
  if (tagType === 'Z') {
53
- return readNullTerminatedStringFromBuffer(buffer)
71
+ return readNullTerminatedString(buffer)
54
72
  }
55
73
  if (tagType === 'A') {
56
74
  return String.fromCharCode(buffer[0])
57
75
  }
58
76
  if (tagType === 'I') {
59
- const val = Long.fromBytesLE(buffer)
60
- if (
61
- val.greaterThan(Number.MAX_SAFE_INTEGER) ||
62
- val.lessThan(Number.MIN_SAFE_INTEGER)
63
- ) {
64
- throw new CramUnimplementedError('integer overflow')
65
- }
66
- return val.toNumber()
77
+ return Long.fromBytesLE(buffer).toNumber()
67
78
  }
68
79
  if (tagType === 'i') {
69
- return buffer.readInt32LE(0)
80
+ return new Int32Array(buffer.buffer)[0]
70
81
  }
71
82
  if (tagType === 's') {
72
- return buffer.readInt16LE(0)
83
+ return new Int16Array(buffer.buffer)[0]
73
84
  }
74
85
  if (tagType === 'S') {
75
- return buffer.readUInt16LE(0)
86
+ return new Uint16Array(buffer.buffer)[0]
76
87
  }
77
88
  if (tagType === 'c') {
78
- return buffer.readInt8(0)
89
+ return new Int8Array(buffer.buffer)[0]
79
90
  }
80
91
  if (tagType === 'C') {
81
- return buffer.readUInt8(0)
92
+ return buffer[0]
82
93
  }
83
94
  if (tagType === 'f') {
84
- return buffer.readFloatLE(0)
95
+ return new Float32Array(buffer.buffer)[0]
85
96
  }
86
97
  if (tagType === 'H') {
87
- const hex = readNullTerminatedStringFromBuffer(buffer)
88
- return Number.parseInt(hex.replace(/^0x/, ''), 16)
98
+ return Number.parseInt(
99
+ readNullTerminatedString(buffer).replace(/^0x/, ''),
100
+ 16,
101
+ )
89
102
  }
90
103
  if (tagType === 'B') {
91
104
  return parseTagValueArray(buffer)
@@ -176,22 +189,6 @@ function decodeReadFeatures(
176
189
  return readFeatures
177
190
  }
178
191
 
179
- function thingToString(thing) {
180
- if (thing instanceof Buffer) {
181
- return readNullTerminatedStringFromBuffer(thing)
182
- }
183
- if (thing.length && thing.indexOf) {
184
- // array-like
185
- if (!thing[thing.length - 1]) {
186
- // trim zeroes off the end if necessary
187
- const termIndex = thing.indexOf(0)
188
- return String.fromCharCode(...thing.slice(0, termIndex))
189
- }
190
- return String.fromCharCode(...thing)
191
- }
192
- return String(thing)
193
- }
194
-
195
192
  export default function decodeRecord(
196
193
  slice,
197
194
  decodeDataSeries,
@@ -228,7 +225,7 @@ export default function decodeRecord(
228
225
  cramRecord.readGroupId = decodeDataSeries('RG')
229
226
 
230
227
  if (compressionScheme.readNamesIncluded) {
231
- cramRecord.readName = thingToString(decodeDataSeries('RN'))
228
+ cramRecord.readName = readNullTerminatedString(decodeDataSeries('RN'))
232
229
  }
233
230
 
234
231
  // mate record
@@ -237,7 +234,7 @@ export default function decodeRecord(
237
234
  const mate = {}
238
235
  mate.flags = decodeDataSeries('MF')
239
236
  if (!compressionScheme.readNamesIncluded) {
240
- mate.readName = thingToString(decodeDataSeries('RN'))
237
+ mate.readName = readNullTerminatedString(decodeDataSeries('RN'))
241
238
  cramRecord.readName = mate.readName
242
239
  }
243
240
  mate.sequenceId = decodeDataSeries('NS')
@@ -336,18 +336,22 @@ export default class CramSlice {
336
336
  }
337
337
 
338
338
  // tracks the read position within the block. codec.decode() methods
339
- // advance the byte and bit positions in the cursor as they decode data
340
- // note that we are only decoding a single block here, the core data block
339
+ // advance the byte and bit positions in the cursor as they decode
340
+ // data note that we are only decoding a single block here, the core
341
+ // data block
341
342
  const coreDataBlock = await this.getCoreDataBlock()
342
343
  const cursors = {
343
344
  lastAlignmentStart: sliceHeader.content.refSeqStart || 0,
344
345
  coreBlock: { bitPosition: 7, bytePosition: 0 },
345
346
  externalBlocks: {
347
+ map: new Map(),
346
348
  getCursor(contentId) {
347
- if (!this[contentId]) {
348
- this[contentId] = { bitPosition: 7, bytePosition: 0 }
349
+ let r = this.map.get(contentId)
350
+ if (r === undefined) {
351
+ r = { bitPosition: 7, bytePosition: 0 }
352
+ this.map.set(contentId, r)
349
353
  }
350
- return this[contentId]
354
+ return r
351
355
  },
352
356
  },
353
357
  }
@@ -394,8 +398,8 @@ export default class CramSlice {
394
398
  }
395
399
  }
396
400
 
397
- // interpret `recordsToNextFragment` attributes to make standard `mate` objects
398
- // Resolve mate pair cross-references between records in this slice
401
+ // interpret `recordsToNextFragment` attributes to make standard `mate`
402
+ // objects Resolve mate pair cross-references between records in this slice
399
403
  for (let i = 0; i < records.length; i += 1) {
400
404
  const { mateRecordNumber } = records[i]
401
405
  if (mateRecordNumber >= 0) {