@gmod/cram 3.0.6 → 4.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.
Files changed (248) hide show
  1. package/dist/craiIndex.js +70 -87
  2. package/dist/craiIndex.js.map +1 -1
  3. package/dist/cram-bundle.js +1 -1
  4. package/dist/cramFile/codecs/_base.d.ts +1 -1
  5. package/dist/cramFile/codecs/beta.d.ts +2 -2
  6. package/dist/cramFile/codecs/beta.js +1 -1
  7. package/dist/cramFile/codecs/beta.js.map +1 -1
  8. package/dist/cramFile/codecs/byteArrayLength.d.ts +2 -2
  9. package/dist/cramFile/codecs/byteArrayStop.d.ts +4 -4
  10. package/dist/cramFile/codecs/byteArrayStop.js +1 -1
  11. package/dist/cramFile/codecs/byteArrayStop.js.map +1 -1
  12. package/dist/cramFile/codecs/external.d.ts +1 -1
  13. package/dist/cramFile/codecs/external.js +1 -1
  14. package/dist/cramFile/codecs/external.js.map +1 -1
  15. package/dist/cramFile/codecs/gamma.d.ts +1 -1
  16. package/dist/cramFile/codecs/gamma.js +1 -1
  17. package/dist/cramFile/codecs/gamma.js.map +1 -1
  18. package/dist/cramFile/codecs/getBits.d.ts +1 -1
  19. package/dist/cramFile/codecs/getBits.js.map +1 -1
  20. package/dist/cramFile/codecs/huffman.d.ts +1 -1
  21. package/dist/cramFile/codecs/huffman.js +1 -1
  22. package/dist/cramFile/codecs/huffman.js.map +1 -1
  23. package/dist/cramFile/codecs/index.d.ts +1 -1
  24. package/dist/cramFile/codecs/index.js +5 -5
  25. package/dist/cramFile/codecs/index.js.map +1 -1
  26. package/dist/cramFile/codecs/subexp.d.ts +2 -2
  27. package/dist/cramFile/codecs/subexp.js +1 -1
  28. package/dist/cramFile/codecs/subexp.js.map +1 -1
  29. package/dist/cramFile/container/compressionScheme.d.ts +2 -2
  30. package/dist/cramFile/container/compressionScheme.js +1 -1
  31. package/dist/cramFile/container/compressionScheme.js.map +1 -1
  32. package/dist/cramFile/container/index.d.ts +1 -2
  33. package/dist/cramFile/container/index.js +62 -79
  34. package/dist/cramFile/container/index.js.map +1 -1
  35. package/dist/cramFile/file.d.ts +9 -13
  36. package/dist/cramFile/file.js +218 -249
  37. package/dist/cramFile/file.js.map +1 -1
  38. package/dist/cramFile/record.js +2 -2
  39. package/dist/cramFile/record.js.map +1 -1
  40. package/dist/cramFile/sectionParsers.d.ts +16 -16
  41. package/dist/cramFile/sectionParsers.js +12 -9
  42. package/dist/cramFile/sectionParsers.js.map +1 -1
  43. package/dist/cramFile/slice/decodeRecord.d.ts +3 -3
  44. package/dist/cramFile/slice/decodeRecord.js +11 -11
  45. package/dist/cramFile/slice/decodeRecord.js.map +1 -1
  46. package/dist/cramFile/slice/index.d.ts +2 -2
  47. package/dist/cramFile/slice/index.js +241 -262
  48. package/dist/cramFile/slice/index.js.map +1 -1
  49. package/dist/cramFile/util.d.ts +4 -2
  50. package/dist/cramFile/util.js +29 -6
  51. package/dist/cramFile/util.js.map +1 -1
  52. package/dist/htscodecs/arith_gen.d.ts +18 -0
  53. package/dist/htscodecs/arith_gen.js +318 -0
  54. package/dist/htscodecs/arith_gen.js.map +1 -0
  55. package/dist/htscodecs/arith_sh.d.ts +16 -0
  56. package/dist/htscodecs/arith_sh.js +128 -0
  57. package/dist/htscodecs/arith_sh.js.map +1 -0
  58. package/dist/htscodecs/byte_model.d.ts +11 -0
  59. package/dist/htscodecs/byte_model.js +113 -0
  60. package/dist/htscodecs/byte_model.js.map +1 -0
  61. package/dist/htscodecs/fqzcomp.d.ts +1 -0
  62. package/dist/htscodecs/fqzcomp.js +325 -0
  63. package/dist/htscodecs/fqzcomp.js.map +1 -0
  64. package/dist/htscodecs/index.d.ts +5 -0
  65. package/dist/htscodecs/index.js +70 -0
  66. package/dist/htscodecs/index.js.map +1 -0
  67. package/dist/htscodecs/iostream.d.ts +27 -0
  68. package/dist/htscodecs/iostream.js +243 -0
  69. package/dist/htscodecs/iostream.js.map +1 -0
  70. package/dist/htscodecs/rans.d.ts +1 -0
  71. package/dist/htscodecs/rans.js +213 -0
  72. package/dist/htscodecs/rans.js.map +1 -0
  73. package/dist/htscodecs/rans4x16.d.ts +1 -0
  74. package/dist/htscodecs/rans4x16.js +405 -0
  75. package/dist/htscodecs/rans4x16.js.map +1 -0
  76. package/dist/htscodecs/tok3.d.ts +2 -0
  77. package/dist/htscodecs/tok3.js +363 -0
  78. package/dist/htscodecs/tok3.js.map +1 -0
  79. package/dist/index.d.ts +1 -1
  80. package/dist/index.js +2 -2
  81. package/dist/index.js.map +1 -1
  82. package/dist/indexedCramFile.d.ts +4 -4
  83. package/dist/indexedCramFile.js +97 -108
  84. package/dist/indexedCramFile.js.map +1 -1
  85. package/dist/io/index.d.ts +2 -2
  86. package/dist/io/index.js +6 -6
  87. package/dist/io/index.js.map +1 -1
  88. package/dist/rans/constants.d.ts +1 -1
  89. package/dist/rans/constants.js +1 -1
  90. package/dist/rans/constants.js.map +1 -1
  91. package/dist/rans/d04.js.map +1 -1
  92. package/dist/rans/decoding.js.map +1 -1
  93. package/dist/rans/frequencies.js.map +1 -1
  94. package/dist/rans/index.js +5 -5
  95. package/dist/rans/index.js.map +1 -1
  96. package/dist/unzip.d.ts +1 -1
  97. package/dist/unzip.js +5 -3
  98. package/dist/unzip.js.map +1 -1
  99. package/esm/craiIndex.js +10 -12
  100. package/esm/craiIndex.js.map +1 -1
  101. package/esm/cramFile/codecs/_base.d.ts +1 -1
  102. package/esm/cramFile/codecs/beta.d.ts +2 -2
  103. package/esm/cramFile/codecs/beta.js +1 -1
  104. package/esm/cramFile/codecs/beta.js.map +1 -1
  105. package/esm/cramFile/codecs/byteArrayLength.d.ts +2 -2
  106. package/esm/cramFile/codecs/byteArrayStop.d.ts +4 -4
  107. package/esm/cramFile/codecs/byteArrayStop.js +1 -1
  108. package/esm/cramFile/codecs/byteArrayStop.js.map +1 -1
  109. package/esm/cramFile/codecs/external.d.ts +1 -1
  110. package/esm/cramFile/codecs/external.js +1 -1
  111. package/esm/cramFile/codecs/external.js.map +1 -1
  112. package/esm/cramFile/codecs/gamma.d.ts +1 -1
  113. package/esm/cramFile/codecs/gamma.js +1 -1
  114. package/esm/cramFile/codecs/gamma.js.map +1 -1
  115. package/esm/cramFile/codecs/getBits.d.ts +1 -1
  116. package/esm/cramFile/codecs/getBits.js.map +1 -1
  117. package/esm/cramFile/codecs/huffman.d.ts +1 -1
  118. package/esm/cramFile/codecs/huffman.js +1 -1
  119. package/esm/cramFile/codecs/huffman.js.map +1 -1
  120. package/esm/cramFile/codecs/index.d.ts +1 -1
  121. package/esm/cramFile/codecs/index.js +5 -5
  122. package/esm/cramFile/codecs/index.js.map +1 -1
  123. package/esm/cramFile/codecs/subexp.d.ts +2 -2
  124. package/esm/cramFile/codecs/subexp.js +1 -1
  125. package/esm/cramFile/codecs/subexp.js.map +1 -1
  126. package/esm/cramFile/container/compressionScheme.d.ts +2 -2
  127. package/esm/cramFile/container/compressionScheme.js +1 -1
  128. package/esm/cramFile/container/compressionScheme.js.map +1 -1
  129. package/esm/cramFile/container/index.d.ts +1 -2
  130. package/esm/cramFile/container/index.js +4 -7
  131. package/esm/cramFile/container/index.js.map +1 -1
  132. package/esm/cramFile/file.d.ts +9 -13
  133. package/esm/cramFile/file.js +54 -61
  134. package/esm/cramFile/file.js.map +1 -1
  135. package/esm/cramFile/record.js +2 -2
  136. package/esm/cramFile/record.js.map +1 -1
  137. package/esm/cramFile/sectionParsers.d.ts +16 -16
  138. package/esm/cramFile/sectionParsers.js +7 -7
  139. package/esm/cramFile/sectionParsers.js.map +1 -1
  140. package/esm/cramFile/slice/decodeRecord.d.ts +3 -3
  141. package/esm/cramFile/slice/decodeRecord.js +11 -11
  142. package/esm/cramFile/slice/decodeRecord.js.map +1 -1
  143. package/esm/cramFile/slice/index.d.ts +2 -2
  144. package/esm/cramFile/slice/index.js +7 -6
  145. package/esm/cramFile/slice/index.js.map +1 -1
  146. package/esm/cramFile/util.d.ts +4 -2
  147. package/esm/cramFile/util.js +19 -2
  148. package/esm/cramFile/util.js.map +1 -1
  149. package/esm/htscodecs/arith_gen.d.ts +18 -0
  150. package/esm/htscodecs/arith_gen.js +318 -0
  151. package/esm/htscodecs/arith_gen.js.map +1 -0
  152. package/esm/htscodecs/arith_sh.d.ts +16 -0
  153. package/esm/htscodecs/arith_sh.js +128 -0
  154. package/esm/htscodecs/arith_sh.js.map +1 -0
  155. package/esm/htscodecs/byte_model.d.ts +11 -0
  156. package/esm/htscodecs/byte_model.js +113 -0
  157. package/esm/htscodecs/byte_model.js.map +1 -0
  158. package/esm/htscodecs/fqzcomp.d.ts +1 -0
  159. package/esm/htscodecs/fqzcomp.js +325 -0
  160. package/esm/htscodecs/fqzcomp.js.map +1 -0
  161. package/esm/htscodecs/index.d.ts +5 -0
  162. package/esm/htscodecs/index.js +70 -0
  163. package/esm/htscodecs/index.js.map +1 -0
  164. package/esm/htscodecs/iostream.d.ts +27 -0
  165. package/esm/htscodecs/iostream.js +243 -0
  166. package/esm/htscodecs/iostream.js.map +1 -0
  167. package/esm/htscodecs/rans.d.ts +1 -0
  168. package/esm/htscodecs/rans.js +213 -0
  169. package/esm/htscodecs/rans.js.map +1 -0
  170. package/esm/htscodecs/rans4x16.d.ts +1 -0
  171. package/esm/htscodecs/rans4x16.js +405 -0
  172. package/esm/htscodecs/rans4x16.js.map +1 -0
  173. package/esm/htscodecs/tok3.d.ts +2 -0
  174. package/esm/htscodecs/tok3.js +363 -0
  175. package/esm/htscodecs/tok3.js.map +1 -0
  176. package/esm/index.d.ts +1 -1
  177. package/esm/index.js +1 -1
  178. package/esm/index.js.map +1 -1
  179. package/esm/indexedCramFile.d.ts +4 -4
  180. package/esm/indexedCramFile.js +10 -10
  181. package/esm/indexedCramFile.js.map +1 -1
  182. package/esm/io/index.d.ts +2 -2
  183. package/esm/io/index.js +1 -1
  184. package/esm/io/index.js.map +1 -1
  185. package/esm/rans/constants.d.ts +1 -1
  186. package/esm/rans/constants.js +1 -1
  187. package/esm/rans/constants.js.map +1 -1
  188. package/esm/rans/d04.js.map +1 -1
  189. package/esm/rans/decoding.js.map +1 -1
  190. package/esm/rans/frequencies.js.map +1 -1
  191. package/esm/rans/index.js +5 -5
  192. package/esm/rans/index.js.map +1 -1
  193. package/esm/unzip.d.ts +1 -1
  194. package/esm/unzip.js +4 -1
  195. package/esm/unzip.js.map +1 -1
  196. package/package.json +7 -10
  197. package/src/craiIndex.ts +17 -16
  198. package/src/cramFile/codecs/_base.ts +1 -1
  199. package/src/cramFile/codecs/beta.ts +3 -3
  200. package/src/cramFile/codecs/byteArrayLength.ts +1 -1
  201. package/src/cramFile/codecs/byteArrayStop.ts +3 -4
  202. package/src/cramFile/codecs/external.ts +3 -3
  203. package/src/cramFile/codecs/gamma.ts +2 -2
  204. package/src/cramFile/codecs/getBits.ts +1 -1
  205. package/src/cramFile/codecs/huffman.ts +2 -3
  206. package/src/cramFile/codecs/index.ts +7 -8
  207. package/src/cramFile/codecs/subexp.ts +3 -3
  208. package/src/cramFile/container/compressionScheme.ts +3 -3
  209. package/src/cramFile/container/index.ts +7 -10
  210. package/src/cramFile/file.ts +78 -86
  211. package/src/cramFile/record.ts +3 -3
  212. package/src/cramFile/sectionParsers.ts +27 -22
  213. package/src/cramFile/slice/decodeRecord.ts +17 -17
  214. package/src/cramFile/slice/index.ts +8 -9
  215. package/src/cramFile/util.ts +24 -6
  216. package/src/htscodecs/arith_gen.js +344 -0
  217. package/src/htscodecs/arith_sh.js +138 -0
  218. package/src/htscodecs/byte_model.js +126 -0
  219. package/src/htscodecs/fqzcomp.js +360 -0
  220. package/src/htscodecs/index.js +77 -0
  221. package/src/htscodecs/iostream.js +257 -0
  222. package/src/htscodecs/rans.js +233 -0
  223. package/src/htscodecs/rans4x16.js +452 -0
  224. package/src/htscodecs/tok3.js +413 -0
  225. package/src/index.ts +1 -1
  226. package/src/indexedCramFile.ts +6 -5
  227. package/src/io/index.ts +5 -4
  228. package/src/rans/constants.ts +1 -1
  229. package/src/rans/d04.ts +0 -1
  230. package/src/rans/decoding.ts +0 -1
  231. package/src/rans/frequencies.ts +0 -1
  232. package/src/rans/index.ts +5 -7
  233. package/src/unzip.ts +5 -1
  234. package/dist/cramFile/filehandle.d.ts +0 -1
  235. package/dist/cramFile/filehandle.js +0 -3
  236. package/dist/cramFile/filehandle.js.map +0 -1
  237. package/dist/unzip-pako.d.ts +0 -2
  238. package/dist/unzip-pako.js +0 -9
  239. package/dist/unzip-pako.js.map +0 -1
  240. package/esm/cramFile/filehandle.d.ts +0 -1
  241. package/esm/cramFile/filehandle.js +0 -2
  242. package/esm/cramFile/filehandle.js.map +0 -1
  243. package/esm/unzip-pako.d.ts +0 -2
  244. package/esm/unzip-pako.js +0 -6
  245. package/esm/unzip-pako.js.map +0 -1
  246. package/src/cramFile/filehandle.ts +0 -1
  247. package/src/typings/htscodecs.d.ts +0 -6
  248. package/src/unzip-pako.ts +0 -6
@@ -1,27 +1,27 @@
1
- import { Buffer } from 'buffer'
2
- import crc32 from 'crc/crc32'
3
- import QuickLRU from 'quick-lru'
4
- import htscodecs from '@jkbonfield/htscodecs'
5
1
  import bzip2 from 'bzip2'
2
+ import crc32 from 'crc/calculators/crc32'
3
+ import QuickLRU from 'quick-lru'
6
4
  import { XzReadableStream } from 'xz-decompress'
5
+
7
6
  import { CramMalformedError, CramUnimplementedError } from '../errors'
8
- // locals
9
- import { unzip } from '../unzip'
7
+ import htscodecs from '../htscodecs'
8
+ import { open } from '../io'
10
9
  import ransuncompress from '../rans'
10
+ import { parseHeaderText } from '../sam'
11
+ import { unzip } from '../unzip'
12
+ import CramContainer from './container'
13
+ import CramRecord from './record'
11
14
  import {
12
15
  BlockHeader,
13
16
  CompressionMethod,
14
17
  cramFileDefinition,
15
18
  getSectionParsers,
16
19
  } from './sectionParsers'
17
- import CramContainer from './container'
18
- import CramRecord from './record'
19
- import { open } from '../io'
20
- import { parseItem, tinyMemoize } from './util'
21
- import { parseHeaderText } from '../sam'
22
- import { Filehandle } from './filehandle'
20
+ import { concatUint8Array, parseItem, tinyMemoize } from './util'
21
+
22
+ import type { GenericFilehandle } from 'generic-filehandle2'
23
23
 
24
- function bufferToStream(buf: Buffer) {
24
+ function bufferToStream(buf: Uint8Array) {
25
25
  return new ReadableStream({
26
26
  start(controller) {
27
27
  controller.enqueue(buf)
@@ -45,7 +45,7 @@ function getEndianness() {
45
45
  }
46
46
 
47
47
  export interface CramFileSource {
48
- filehandle?: Filehandle
48
+ filehandle?: GenericFilehandle
49
49
  url?: string
50
50
  path?: string
51
51
  }
@@ -66,12 +66,12 @@ export type CramFileBlock = BlockHeader & {
66
66
  _endPosition: number
67
67
  contentPosition: number
68
68
  _size: number
69
- content: Buffer
69
+ content: Uint8Array
70
70
  crc32?: number
71
71
  }
72
72
 
73
73
  export default class CramFile {
74
- private file: Filehandle
74
+ private file: GenericFilehandle
75
75
  public validateChecksums: boolean
76
76
  public fetchReferenceSequenceCallback?: SeqFetch
77
77
  public options: {
@@ -101,21 +101,20 @@ export default class CramFile {
101
101
  }
102
102
  }
103
103
 
104
- // can just read this object like a filehandle
105
- read(buffer: Buffer, offset: number, length: number, position: number) {
106
- return this.file.read(buffer, offset, length, position)
107
- }
108
-
109
104
  // can just stat this object like a filehandle
110
105
  stat() {
111
106
  return this.file.stat()
112
107
  }
113
108
 
109
+ // can just stat this object like a filehandle
110
+ read(length: number, position: number) {
111
+ return this.file.read(length, position)
112
+ }
113
+
114
114
  // memoized
115
115
  async getDefinition() {
116
116
  const { maxLength, parser } = cramFileDefinition()
117
- const headbytes = Buffer.allocUnsafe(maxLength)
118
- await this.file.read(headbytes, 0, maxLength, 0)
117
+ const headbytes = await this.file.read(maxLength, 0)
119
118
  const definition = parser(headbytes).value
120
119
  if (definition.majorVersion !== 2 && definition.majorVersion !== 3) {
121
120
  throw new CramUnimplementedError(
@@ -135,17 +134,18 @@ export default class CramFile {
135
134
  const firstBlock = await firstContainer.getFirstBlock()
136
135
  if (firstBlock === undefined) {
137
136
  return parseHeaderText('')
137
+ } else {
138
+ const content = firstBlock.content
139
+ const dataView = new DataView(content.buffer)
140
+ const headerLength = dataView.getInt32(0, true)
141
+ const textStart = 4
142
+ const decoder = new TextDecoder('utf8')
143
+ const text = decoder.decode(
144
+ content.subarray(textStart, textStart + headerLength),
145
+ )
146
+ this.header = text
147
+ return parseHeaderText(text)
138
148
  }
139
- const content = firstBlock.content
140
- // find the end of the trailing zeros in the header text
141
- const headerLength = content.readInt32LE(0)
142
- const textStart = 4
143
- // let textEnd = content.length - 1
144
- // while (textEnd >= textStart && !content[textEnd]) textEnd -= 1
145
- // trim off the trailing zeros
146
- const text = content.toString('utf8', textStart, textStart + headerLength)
147
- this.header = text
148
- return parseHeaderText(text)
149
149
  }
150
150
 
151
151
  async getHeaderText() {
@@ -189,7 +189,8 @@ export default class CramFile {
189
189
  position = block._endPosition
190
190
  }
191
191
  } else {
192
- // otherwise, just traverse to the next container using the container's length
192
+ // otherwise, just traverse to the next container using the container's
193
+ // length
193
194
  position += currentHeader._size + currentHeader.length
194
195
  }
195
196
  }
@@ -203,9 +204,11 @@ export default class CramFile {
203
204
  recordedCrc32: number,
204
205
  description: string,
205
206
  ) {
206
- const b = Buffer.allocUnsafe(length)
207
- await this.file.read(b, 0, length, position)
208
- const calculatedCrc32 = crc32.unsigned(b)
207
+ const b = await this.file.read(length, position)
208
+ // this shift >>> 0 is equivalent to crc32(b).unsigned but uses the
209
+ // internal calculator of crc32 to avoid accidentally importing buffer
210
+ // https://github.com/alexgorbatchev/crc/blob/31fc3853e417b5fb5ec83335428805842575f699/src/define_crc.ts#L5
211
+ const calculatedCrc32 = crc32(b) >>> 0
209
212
  if (calculatedCrc32 !== recordedCrc32) {
210
213
  throw new CramMalformedError(
211
214
  `crc mismatch in ${description}: recorded CRC32 = ${recordedCrc32}, but calculated CRC32 = ${calculatedCrc32}`,
@@ -230,9 +233,9 @@ export default class CramFile {
230
233
  if (!currentHeader) {
231
234
  break
232
235
  }
233
- // if this is the first container, read all the blocks in the
234
- // container, because we cannot trust the container
235
- // header's given length due to a bug somewhere in htslib
236
+ // if this is the first container, read all the blocks in the container,
237
+ // because we cannot trust the container header's given length due to a
238
+ // bug somewhere in htslib
236
239
  if (containerCount === 0) {
237
240
  position = currentHeader._endPosition
238
241
  for (let j = 0; j < currentHeader.numBlocks; j++) {
@@ -243,7 +246,8 @@ export default class CramFile {
243
246
  position = block._endPosition
244
247
  }
245
248
  } else {
246
- // otherwise, just traverse to the next container using the container's length
249
+ // otherwise, just traverse to the next container using the container's
250
+ // length
247
251
  position += currentHeader._size + currentHeader.length
248
252
  }
249
253
  containerCount += 1
@@ -266,21 +270,23 @@ export default class CramFile {
266
270
  return undefined
267
271
  }
268
272
 
269
- const buffer = Buffer.allocUnsafe(cramBlockHeader.maxLength)
270
- await this.file.read(buffer, 0, cramBlockHeader.maxLength, position)
273
+ const buffer = await this.file.read(cramBlockHeader.maxLength, position)
271
274
  return parseItem(buffer, cramBlockHeader.parser, 0, position)
272
275
  }
273
276
 
274
277
  async _parseSection<T>(
275
278
  section: {
276
279
  maxLength: number
277
- parser: (buffer: Buffer, offset: number) => { offset: number; value: T }
280
+ parser: (
281
+ buffer: Uint8Array,
282
+ offset: number,
283
+ ) => { offset: number; value: T }
278
284
  },
279
285
  position: number,
280
286
  size = section.maxLength,
281
- preReadBuffer?: Buffer,
287
+ preReadBuffer?: Uint8Array,
282
288
  ) {
283
- let buffer: Buffer
289
+ let buffer: Uint8Array
284
290
  if (preReadBuffer) {
285
291
  buffer = preReadBuffer
286
292
  } else {
@@ -288,8 +294,7 @@ export default class CramFile {
288
294
  if (position + size >= fileSize) {
289
295
  return undefined
290
296
  }
291
- buffer = Buffer.allocUnsafe(size)
292
- await this.file.read(buffer, 0, size, position)
297
+ buffer = await this.file.read(size, position)
293
298
  }
294
299
  const data = parseItem(buffer, section.parser, 0, position)
295
300
  if (data._size !== size) {
@@ -302,43 +307,43 @@ export default class CramFile {
302
307
 
303
308
  async _uncompress(
304
309
  compressionMethod: CompressionMethod,
305
- inputBuffer: Buffer,
306
- outputBuffer: Buffer,
310
+ inputBuffer: Uint8Array,
311
+ uncompressedSize: number,
307
312
  ) {
308
313
  if (compressionMethod === 'gzip') {
309
- const result = unzip(inputBuffer)
310
- result.copy(outputBuffer)
314
+ return unzip(inputBuffer)
311
315
  } else if (compressionMethod === 'bzip2') {
312
316
  const bits = bzip2.array(inputBuffer)
313
317
  let size = bzip2.header(bits)
314
- let j = 0
315
318
  let chunk: Uint8Array | -1
319
+ const chunks = []
316
320
  do {
317
321
  chunk = bzip2.decompress(bits, size)
318
322
  if (chunk !== -1) {
319
- Buffer.from(chunk).copy(outputBuffer, j)
320
- j += chunk.length
323
+ chunks.push(chunk)
321
324
  size -= chunk.length
322
325
  }
323
326
  } while (chunk !== -1)
327
+ return concatUint8Array(chunks)
324
328
  } else if (compressionMethod === 'lzma') {
325
329
  const decompressedResponse = new Response(
326
330
  new XzReadableStream(bufferToStream(inputBuffer)),
327
331
  )
328
- const ret = Buffer.from(await decompressedResponse.arrayBuffer())
329
- ret.copy(outputBuffer)
332
+ return new Uint8Array(await decompressedResponse.arrayBuffer())
330
333
  } else if (compressionMethod === 'rans') {
334
+ const outputBuffer = new Uint8Array(uncompressedSize)
331
335
  ransuncompress(inputBuffer, outputBuffer)
336
+ return outputBuffer
332
337
  // htscodecs r4x8 is slower, but compatible.
333
338
  // htscodecs.r4x8_uncompress(inputBuffer, outputBuffer);
334
339
  } else if (compressionMethod === 'rans4x16') {
335
- htscodecs.r4x16_uncompress(inputBuffer, outputBuffer)
340
+ return htscodecs.r4x16_uncompress(inputBuffer)
336
341
  } else if (compressionMethod === 'arith') {
337
- htscodecs.arith_uncompress(inputBuffer, outputBuffer)
342
+ return htscodecs.arith_uncompress(inputBuffer)
338
343
  } else if (compressionMethod === 'fqzcomp') {
339
- htscodecs.fqzcomp_uncompress(inputBuffer, outputBuffer)
344
+ return htscodecs.fqzcomp_uncompress(inputBuffer)
340
345
  } else if (compressionMethod === 'tok3') {
341
- htscodecs.tok3_uncompress(inputBuffer, outputBuffer)
346
+ return htscodecs.tok3_uncompress(inputBuffer)
342
347
  } else {
343
348
  throw new CramUnimplementedError(
344
349
  `${compressionMethod} decompression not yet implemented`,
@@ -355,7 +360,18 @@ export default class CramFile {
355
360
  }
356
361
  const blockContentPosition = blockHeader._endPosition
357
362
 
358
- const uncompressedData = Buffer.allocUnsafe(blockHeader.uncompressedSize)
363
+ const d = await this.file.read(
364
+ blockHeader.compressedSize,
365
+ blockContentPosition,
366
+ )
367
+ const uncompressedData =
368
+ blockHeader.compressionMethod !== 'raw'
369
+ ? await this._uncompress(
370
+ blockHeader.compressionMethod,
371
+ d,
372
+ blockHeader.uncompressedSize,
373
+ )
374
+ : d
359
375
 
360
376
  const block: CramFileBlock = {
361
377
  ...blockHeader,
@@ -363,30 +379,6 @@ export default class CramFile {
363
379
  contentPosition: blockContentPosition,
364
380
  content: uncompressedData,
365
381
  }
366
-
367
- if (blockHeader.compressionMethod !== 'raw') {
368
- const compressedData = Buffer.allocUnsafe(blockHeader.compressedSize)
369
- await this.read(
370
- compressedData,
371
- 0,
372
- blockHeader.compressedSize,
373
- blockContentPosition,
374
- )
375
-
376
- await this._uncompress(
377
- blockHeader.compressionMethod,
378
- compressedData,
379
- uncompressedData,
380
- )
381
- } else {
382
- await this.read(
383
- uncompressedData,
384
- 0,
385
- blockHeader.uncompressedSize,
386
- blockContentPosition,
387
- )
388
- }
389
-
390
382
  if (majorVersion >= 3) {
391
383
  // parse the crc32
392
384
  const crc = await this._parseSection(
@@ -1,5 +1,6 @@
1
1
  import Constants from './constants'
2
2
  import CramContainerCompressionScheme from './container/compressionScheme'
3
+
3
4
  import type decodeRecord from './slice/decodeRecord'
4
5
 
5
6
  export interface RefRegion {
@@ -13,7 +14,6 @@ export interface ReadFeature {
13
14
  pos: number
14
15
  refPos: number
15
16
  data: any
16
-
17
17
  ref?: string
18
18
  sub?: string
19
19
  }
@@ -458,8 +458,8 @@ export default class CramRecord {
458
458
  compressionScheme: CramContainerCompressionScheme,
459
459
  ) {
460
460
  if (this.readFeatures) {
461
- // use the reference bases to decode the bases
462
- // substituted in each base substitution
461
+ // use the reference bases to decode the bases substituted in each base
462
+ // substitution
463
463
  this.readFeatures.forEach(readFeature => {
464
464
  if (readFeature.code === 'X') {
465
465
  decodeBaseSubstitution(
@@ -1,23 +1,22 @@
1
1
  import { TupleOf } from '../typescript'
2
- import { parseItf8, parseLtf8 } from './util'
3
2
  import { DataSeriesEncodingMap } from './codecs/dataSeriesTypes'
4
3
  import { CramEncoding } from './encoding'
4
+ import { parseItf8, parseLtf8 } from './util'
5
5
 
6
6
  export function cramFileDefinition() {
7
7
  return {
8
- parser: (buffer: Buffer, _startOffset = 0) => {
9
- const b = buffer
8
+ parser: (b: Uint8Array, _startOffset = 0) => {
10
9
  const dataView = new DataView(b.buffer, b.byteOffset, b.length)
10
+ const decoder = new TextDecoder('utf8')
11
11
  let offset = 0
12
- const magic = buffer.subarray(offset, offset + 4).toString()
12
+ const magic = decoder.decode(b.subarray(offset, offset + 4))
13
13
  offset += 4
14
14
  const majorVersion = dataView.getUint8(offset)
15
15
  offset += 1
16
16
  const minorVersion = dataView.getUint8(offset)
17
17
  offset += 1
18
- const fileId = b
19
- .subarray(offset, offset + 20)
20
- .toString()
18
+ const fileId = decoder
19
+ .decode(b.subarray(offset, offset + 20))
21
20
  .replaceAll('\0', '')
22
21
  offset += 20
23
22
  return {
@@ -34,7 +33,7 @@ export function cramFileDefinition() {
34
33
  }
35
34
  }
36
35
  export function cramBlockHeader() {
37
- const parser = (buffer: Buffer, _startOffset = 0) => {
36
+ const parser = (buffer: Uint8Array, _startOffset = 0) => {
38
37
  const b = buffer
39
38
  const dataView = new DataView(b.buffer, b.byteOffset, b.length)
40
39
  let offset = 0
@@ -97,7 +96,7 @@ export function cramBlockHeader() {
97
96
 
98
97
  export function cramBlockCrc32() {
99
98
  return {
100
- parser: (buffer: Buffer, offset: number) => {
99
+ parser: (buffer: Uint8Array, offset: number) => {
101
100
  const b = buffer
102
101
  const dataView = new DataView(b.buffer, b.byteOffset, b.length)
103
102
  const crc32 = dataView.getUint32(offset, true)
@@ -115,8 +114,13 @@ export function cramBlockCrc32() {
115
114
 
116
115
  export type CramTagDictionary = string[][]
117
116
 
118
- function makeTagSet(buffer: Buffer, stringStart: number, stringEnd: number) {
119
- const str = buffer.toString('utf8', stringStart, stringEnd)
117
+ function makeTagSet(
118
+ buffer: Uint8Array,
119
+ stringStart: number,
120
+ stringEnd: number,
121
+ ) {
122
+ const decoder = new TextDecoder('utf8')
123
+ const str = decoder.decode(buffer.subarray(stringStart, stringEnd))
120
124
  const tags = []
121
125
  for (let i = 0; i < str.length; i += 3) {
122
126
  tags.push(str.slice(i, i + 3))
@@ -126,7 +130,7 @@ function makeTagSet(buffer: Buffer, stringStart: number, stringEnd: number) {
126
130
 
127
131
  export function cramTagDictionary() {
128
132
  return {
129
- parser: (buffer: Buffer, offset: number) => {
133
+ parser: (buffer: Uint8Array, offset: number) => {
130
134
  const [size, newOffset1] = parseItf8(buffer, offset)
131
135
  offset += newOffset1
132
136
  const subbuf = buffer.subarray(offset, offset + size)
@@ -169,7 +173,7 @@ export interface CramPreservationMap {
169
173
 
170
174
  export function cramPreservationMap() {
171
175
  return {
172
- parser: (buffer: Buffer, offset: number) => {
176
+ parser: (buffer: Uint8Array, offset: number) => {
173
177
  const b = buffer
174
178
  const dataView = new DataView(b.buffer, b.byteOffset, b.length)
175
179
  const [mapSize, newOffset1] = parseItf8(buffer, offset)
@@ -284,7 +288,7 @@ function cramUnmappedSliceHeader(majorVersion: number) {
284
288
  maxLength += 5 * 2
285
289
  maxLength += 16
286
290
 
287
- const parser = (buffer: Buffer, offset: number) => {
291
+ const parser = (buffer: Uint8Array, offset: number) => {
288
292
  const [numRecords, newOffset1] = parseItf8(buffer, offset)
289
293
  offset += newOffset1
290
294
  let recordCounter = 0
@@ -348,7 +352,7 @@ function cramMappedSliceHeader(majorVersion: number) {
348
352
  maxLength += 16 // MD5
349
353
 
350
354
  return {
351
- parser: (buffer: Buffer, offset: number) => {
355
+ parser: (buffer: Uint8Array, offset: number) => {
352
356
  // L0
353
357
  const [refSeqId, newOffset1] = parseItf8(buffer, offset)
354
358
  offset += newOffset1
@@ -419,12 +423,13 @@ function cramMappedSliceHeader(majorVersion: number) {
419
423
 
420
424
  function cramEncoding() {
421
425
  return {
422
- parser: (buffer: Buffer, offset: number) => cramEncodingSub(buffer, offset),
426
+ parser: (buffer: Uint8Array, offset: number) =>
427
+ cramEncodingSub(buffer, offset),
423
428
  }
424
429
  }
425
430
 
426
431
  function cramEncodingSub(
427
- buffer: Buffer,
432
+ buffer: Uint8Array,
428
433
  offset: number,
429
434
  ): { value: Value; offset: number } {
430
435
  const b = buffer
@@ -542,7 +547,7 @@ function cramEncodingSub(
542
547
 
543
548
  function cramDataSeriesEncodingMap() {
544
549
  return {
545
- parser: (buffer: Buffer, offset: number) => {
550
+ parser: (buffer: Uint8Array, offset: number) => {
546
551
  const [mapSize, newOffset1] = parseItf8(buffer, offset)
547
552
  offset += newOffset1
548
553
  const [mapCount, newOffset2] = parseItf8(buffer, offset)
@@ -572,7 +577,7 @@ function cramDataSeriesEncodingMap() {
572
577
 
573
578
  function cramTagEncodingMap() {
574
579
  return {
575
- parser: (buffer: Buffer, offset: number) => {
580
+ parser: (buffer: Uint8Array, offset: number) => {
576
581
  const [mapSize, newOffset1] = parseItf8(buffer, offset)
577
582
  offset += newOffset1
578
583
  const [mapCount, newOffset2] = parseItf8(buffer, offset)
@@ -604,7 +609,7 @@ function cramTagEncodingMap() {
604
609
 
605
610
  function cramCompressionHeader() {
606
611
  return {
607
- parser: (buffer: Buffer, offset: number) => {
612
+ parser: (buffer: Uint8Array, offset: number) => {
608
613
  // TODO: if we want to support CRAM v1, we will need to refactor
609
614
  // compression header into 2 parts to parse the landmarks, like the
610
615
  // container header
@@ -644,7 +649,7 @@ function cramContainerHeader1(majorVersion: number) {
644
649
  maxLength += 5 + 5
645
650
  return {
646
651
  maxLength,
647
- parser: (buffer: Buffer, offset: number) => {
652
+ parser: (buffer: Uint8Array, offset: number) => {
648
653
  const b = buffer
649
654
  const dataView = new DataView(b.buffer, b.byteOffset, b.length)
650
655
  // byte size of the container data (blocks)
@@ -704,7 +709,7 @@ function cramContainerHeader1(majorVersion: number) {
704
709
 
705
710
  function cramContainerHeader2(majorVersion: number) {
706
711
  return {
707
- parser: (buffer: Buffer, offset: number) => {
712
+ parser: (buffer: Uint8Array, offset: number) => {
708
713
  const b = buffer
709
714
  const dataView = new DataView(b.buffer, b.byteOffset, b.length)
710
715
  const [numLandmarks, newOffset1] = parseItf8(buffer, offset)
@@ -1,4 +1,9 @@
1
1
  import { CramMalformedError } from '../../errors'
2
+ import { Cursors, DataTypeMapping } from '../codecs/_base'
3
+ import { DataSeriesEncodingKey } from '../codecs/dataSeriesTypes'
4
+ import CramContainerCompressionScheme, {
5
+ DataSeriesTypes,
6
+ } from '../container/compressionScheme'
2
7
  import {
3
8
  BamFlagsDecoder,
4
9
  CramFlagsDecoder,
@@ -6,13 +11,8 @@ import {
6
11
  ReadFeature,
7
12
  } from '../record'
8
13
  import CramSlice, { SliceHeader } from './index'
9
- import { isMappedSliceHeader } from '../sectionParsers'
10
- import CramContainerCompressionScheme, {
11
- DataSeriesTypes,
12
- } from '../container/compressionScheme'
13
14
  import { CramFileBlock } from '../file'
14
- import { Cursors, DataTypeMapping } from '../codecs/_base'
15
- import { DataSeriesEncodingKey } from '../codecs/dataSeriesTypes'
15
+ import { isMappedSliceHeader } from '../sectionParsers'
16
16
 
17
17
  /**
18
18
  * given a Buffer, read a string up to the first null character
@@ -42,37 +42,37 @@ function parseTagValueArray(buffer: Uint8Array) {
42
42
 
43
43
  if (arrayType === 'c') {
44
44
  const arr = new Int8Array(buffer.buffer)
45
- for (let i = 0; i < length; i += 1) {
45
+ for (let i = 0; i < length; i++) {
46
46
  array[i] = arr[i]!
47
47
  }
48
48
  } else if (arrayType === 'C') {
49
49
  const arr = new Uint8Array(buffer.buffer)
50
- for (let i = 0; i < length; i += 1) {
50
+ for (let i = 0; i < length; i++) {
51
51
  array[i] = arr[i]!
52
52
  }
53
53
  } else if (arrayType === 's') {
54
54
  const arr = new Int16Array(buffer.buffer)
55
- for (let i = 0; i < length; i += 1) {
55
+ for (let i = 0; i < length; i++) {
56
56
  array[i] = arr[i]!
57
57
  }
58
58
  } else if (arrayType === 'S') {
59
59
  const arr = new Uint16Array(buffer.buffer)
60
- for (let i = 0; i < length; i += 1) {
60
+ for (let i = 0; i < length; i++) {
61
61
  array[i] = arr[i]!
62
62
  }
63
63
  } else if (arrayType === 'i') {
64
64
  const arr = new Int32Array(buffer.buffer)
65
- for (let i = 0; i < length; i += 1) {
65
+ for (let i = 0; i < length; i++) {
66
66
  array[i] = arr[i]!
67
67
  }
68
68
  } else if (arrayType === 'I') {
69
69
  const arr = new Uint32Array(buffer.buffer)
70
- for (let i = 0; i < length; i += 1) {
70
+ for (let i = 0; i < length; i++) {
71
71
  array[i] = arr[i]!
72
72
  }
73
73
  } else if (arrayType === 'f') {
74
74
  const arr = new Float32Array(buffer.buffer)
75
- for (let i = 0; i < length; i += 1) {
75
+ for (let i = 0; i < length; i++) {
76
76
  array[i] = arr[i]!
77
77
  }
78
78
  } else {
@@ -158,7 +158,7 @@ function decodeReadFeatures(
158
158
  return data
159
159
  }
160
160
 
161
- for (let i = 0; i < readFeatureCount; i += 1) {
161
+ for (let i = 0; i < readFeatureCount; i++) {
162
162
  const code = String.fromCharCode(decodeDataSeries('FC'))
163
163
 
164
164
  const readPosDelta = decodeDataSeries('FP')
@@ -315,7 +315,7 @@ export default function decodeRecord(
315
315
  // TN = tag names
316
316
  const TN = compressionScheme.getTagNames(TLindex)!
317
317
  const ntags = TN.length
318
- for (let i = 0; i < ntags; i += 1) {
318
+ for (let i = 0; i < ntags; i++) {
319
319
  const tagId = TN[i]!
320
320
  const tagName = tagId.slice(0, 2)
321
321
  const tagType = tagId.slice(2, 3)
@@ -381,14 +381,14 @@ export default function decodeRecord(
381
381
  qualityScores = null
382
382
  } else {
383
383
  const bases = new Array(readLength) as number[]
384
- for (let i = 0; i < bases.length; i += 1) {
384
+ for (let i = 0; i < bases.length; i++) {
385
385
  bases[i] = decodeDataSeries('BA')
386
386
  }
387
387
  readBases = String.fromCharCode(...bases)
388
388
 
389
389
  if (CramFlagsDecoder.isPreservingQualityScores(cramFlags)) {
390
390
  qualityScores = new Array(readLength)
391
- for (let i = 0; i < bases.length; i += 1) {
391
+ for (let i = 0; i < bases.length; i++) {
392
392
  qualityScores[i] = decodeDataSeries('QS')
393
393
  }
394
394
  }
@@ -1,21 +1,20 @@
1
1
  import { CramArgumentError, CramMalformedError } from '../../errors'
2
- import { parseItem, sequenceMD5, tinyMemoize } from '../util'
3
-
2
+ import { Cursors, DataTypeMapping } from '../codecs/_base'
3
+ import { CramBufferOverrunError } from '../codecs/getBits'
4
4
  import Constants from '../constants'
5
5
  import decodeRecord, { DataSeriesDecoder } from './decodeRecord'
6
- import CramRecord from '../record'
6
+ import { DataSeriesEncodingKey } from '../codecs/dataSeriesTypes'
7
7
  import CramContainer from '../container'
8
+ import { DataSeriesTypes } from '../container/compressionScheme'
8
9
  import CramFile, { CramFileBlock } from '../file'
10
+ import CramRecord from '../record'
9
11
  import {
10
- getSectionParsers,
11
- isMappedSliceHeader,
12
12
  MappedSliceHeader,
13
13
  UnmappedSliceHeader,
14
+ getSectionParsers,
15
+ isMappedSliceHeader,
14
16
  } from '../sectionParsers'
15
- import { CramBufferOverrunError } from '../codecs/getBits'
16
- import { Cursors, DataTypeMapping } from '../codecs/_base'
17
- import { DataSeriesEncodingKey } from '../codecs/dataSeriesTypes'
18
- import { DataSeriesTypes } from '../container/compressionScheme'
17
+ import { parseItem, sequenceMD5, tinyMemoize } from '../util'
19
18
 
20
19
  export type SliceHeader = CramFileBlock & {
21
20
  parsedContent: MappedSliceHeader | UnmappedSliceHeader