@gmod/cram 3.0.7 → 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 (268) 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 -247
  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 +9 -17
  53. package/dist/htscodecs/arith_gen.js +32 -272
  54. package/dist/htscodecs/arith_gen.js.map +1 -1
  55. package/dist/htscodecs/fqzcomp.d.ts +1 -2
  56. package/dist/htscodecs/fqzcomp.js +2 -421
  57. package/dist/htscodecs/fqzcomp.js.map +1 -1
  58. package/dist/htscodecs/index.d.ts +5 -5
  59. package/dist/htscodecs/index.js +10 -10
  60. package/dist/htscodecs/index.js.map +1 -1
  61. package/dist/htscodecs/iostream.d.ts +2 -1
  62. package/dist/htscodecs/iostream.js +3 -2
  63. package/dist/htscodecs/iostream.js.map +1 -1
  64. package/dist/htscodecs/rans.d.ts +1 -2
  65. package/dist/htscodecs/rans.js +3 -270
  66. package/dist/htscodecs/rans.js.map +1 -1
  67. package/dist/htscodecs/rans4x16.d.ts +0 -1
  68. package/dist/htscodecs/rans4x16.js +6 -497
  69. package/dist/htscodecs/rans4x16.js.map +1 -1
  70. package/dist/htscodecs/tok3.js +17 -1
  71. package/dist/htscodecs/tok3.js.map +1 -1
  72. package/dist/index.d.ts +1 -1
  73. package/dist/index.js +2 -2
  74. package/dist/index.js.map +1 -1
  75. package/dist/indexedCramFile.d.ts +4 -4
  76. package/dist/indexedCramFile.js +97 -108
  77. package/dist/indexedCramFile.js.map +1 -1
  78. package/dist/io/index.d.ts +2 -2
  79. package/dist/io/index.js +6 -6
  80. package/dist/io/index.js.map +1 -1
  81. package/dist/rans/constants.d.ts +1 -1
  82. package/dist/rans/constants.js +1 -1
  83. package/dist/rans/constants.js.map +1 -1
  84. package/dist/rans/d04.js.map +1 -1
  85. package/dist/rans/decoding.js.map +1 -1
  86. package/dist/rans/frequencies.js.map +1 -1
  87. package/dist/rans/index.js +5 -5
  88. package/dist/rans/index.js.map +1 -1
  89. package/dist/unzip.d.ts +1 -1
  90. package/dist/unzip.js +5 -3
  91. package/dist/unzip.js.map +1 -1
  92. package/esm/craiIndex.js +10 -12
  93. package/esm/craiIndex.js.map +1 -1
  94. package/esm/cramFile/codecs/_base.d.ts +1 -1
  95. package/esm/cramFile/codecs/beta.d.ts +2 -2
  96. package/esm/cramFile/codecs/beta.js +1 -1
  97. package/esm/cramFile/codecs/beta.js.map +1 -1
  98. package/esm/cramFile/codecs/byteArrayLength.d.ts +2 -2
  99. package/esm/cramFile/codecs/byteArrayStop.d.ts +4 -4
  100. package/esm/cramFile/codecs/byteArrayStop.js +1 -1
  101. package/esm/cramFile/codecs/byteArrayStop.js.map +1 -1
  102. package/esm/cramFile/codecs/external.d.ts +1 -1
  103. package/esm/cramFile/codecs/external.js +1 -1
  104. package/esm/cramFile/codecs/external.js.map +1 -1
  105. package/esm/cramFile/codecs/gamma.d.ts +1 -1
  106. package/esm/cramFile/codecs/gamma.js +1 -1
  107. package/esm/cramFile/codecs/gamma.js.map +1 -1
  108. package/esm/cramFile/codecs/getBits.d.ts +1 -1
  109. package/esm/cramFile/codecs/getBits.js.map +1 -1
  110. package/esm/cramFile/codecs/huffman.d.ts +1 -1
  111. package/esm/cramFile/codecs/huffman.js +1 -1
  112. package/esm/cramFile/codecs/huffman.js.map +1 -1
  113. package/esm/cramFile/codecs/index.d.ts +1 -1
  114. package/esm/cramFile/codecs/index.js +5 -5
  115. package/esm/cramFile/codecs/index.js.map +1 -1
  116. package/esm/cramFile/codecs/subexp.d.ts +2 -2
  117. package/esm/cramFile/codecs/subexp.js +1 -1
  118. package/esm/cramFile/codecs/subexp.js.map +1 -1
  119. package/esm/cramFile/container/compressionScheme.d.ts +2 -2
  120. package/esm/cramFile/container/compressionScheme.js +1 -1
  121. package/esm/cramFile/container/compressionScheme.js.map +1 -1
  122. package/esm/cramFile/container/index.d.ts +1 -2
  123. package/esm/cramFile/container/index.js +4 -7
  124. package/esm/cramFile/container/index.js.map +1 -1
  125. package/esm/cramFile/file.d.ts +9 -13
  126. package/esm/cramFile/file.js +47 -52
  127. package/esm/cramFile/file.js.map +1 -1
  128. package/esm/cramFile/record.js +2 -2
  129. package/esm/cramFile/record.js.map +1 -1
  130. package/esm/cramFile/sectionParsers.d.ts +16 -16
  131. package/esm/cramFile/sectionParsers.js +7 -7
  132. package/esm/cramFile/sectionParsers.js.map +1 -1
  133. package/esm/cramFile/slice/decodeRecord.d.ts +3 -3
  134. package/esm/cramFile/slice/decodeRecord.js +11 -11
  135. package/esm/cramFile/slice/decodeRecord.js.map +1 -1
  136. package/esm/cramFile/slice/index.d.ts +2 -2
  137. package/esm/cramFile/slice/index.js +7 -6
  138. package/esm/cramFile/slice/index.js.map +1 -1
  139. package/esm/cramFile/util.d.ts +4 -2
  140. package/esm/cramFile/util.js +19 -2
  141. package/esm/cramFile/util.js.map +1 -1
  142. package/esm/htscodecs/arith_gen.d.ts +9 -17
  143. package/esm/htscodecs/arith_gen.js +32 -272
  144. package/esm/htscodecs/arith_gen.js.map +1 -1
  145. package/esm/htscodecs/fqzcomp.d.ts +1 -2
  146. package/esm/htscodecs/fqzcomp.js +2 -421
  147. package/esm/htscodecs/fqzcomp.js.map +1 -1
  148. package/esm/htscodecs/index.d.ts +5 -5
  149. package/esm/htscodecs/index.js +10 -10
  150. package/esm/htscodecs/index.js.map +1 -1
  151. package/esm/htscodecs/iostream.d.ts +2 -1
  152. package/esm/htscodecs/iostream.js +3 -2
  153. package/esm/htscodecs/iostream.js.map +1 -1
  154. package/esm/htscodecs/rans.d.ts +1 -2
  155. package/esm/htscodecs/rans.js +3 -270
  156. package/esm/htscodecs/rans.js.map +1 -1
  157. package/esm/htscodecs/rans4x16.d.ts +0 -1
  158. package/esm/htscodecs/rans4x16.js +6 -497
  159. package/esm/htscodecs/rans4x16.js.map +1 -1
  160. package/esm/htscodecs/tok3.js +17 -1
  161. package/esm/htscodecs/tok3.js.map +1 -1
  162. package/esm/index.d.ts +1 -1
  163. package/esm/index.js +1 -1
  164. package/esm/index.js.map +1 -1
  165. package/esm/indexedCramFile.d.ts +4 -4
  166. package/esm/indexedCramFile.js +10 -10
  167. package/esm/indexedCramFile.js.map +1 -1
  168. package/esm/io/index.d.ts +2 -2
  169. package/esm/io/index.js +1 -1
  170. package/esm/io/index.js.map +1 -1
  171. package/esm/rans/constants.d.ts +1 -1
  172. package/esm/rans/constants.js +1 -1
  173. package/esm/rans/constants.js.map +1 -1
  174. package/esm/rans/d04.js.map +1 -1
  175. package/esm/rans/decoding.js.map +1 -1
  176. package/esm/rans/frequencies.js.map +1 -1
  177. package/esm/rans/index.js +5 -5
  178. package/esm/rans/index.js.map +1 -1
  179. package/esm/unzip.d.ts +1 -1
  180. package/esm/unzip.js +4 -1
  181. package/esm/unzip.js.map +1 -1
  182. package/package.json +7 -9
  183. package/src/craiIndex.ts +17 -16
  184. package/src/cramFile/codecs/_base.ts +1 -1
  185. package/src/cramFile/codecs/beta.ts +3 -3
  186. package/src/cramFile/codecs/byteArrayLength.ts +1 -1
  187. package/src/cramFile/codecs/byteArrayStop.ts +3 -4
  188. package/src/cramFile/codecs/external.ts +3 -3
  189. package/src/cramFile/codecs/gamma.ts +2 -2
  190. package/src/cramFile/codecs/getBits.ts +1 -1
  191. package/src/cramFile/codecs/huffman.ts +2 -3
  192. package/src/cramFile/codecs/index.ts +7 -8
  193. package/src/cramFile/codecs/subexp.ts +3 -3
  194. package/src/cramFile/container/compressionScheme.ts +3 -3
  195. package/src/cramFile/container/index.ts +7 -10
  196. package/src/cramFile/file.ts +71 -77
  197. package/src/cramFile/record.ts +3 -3
  198. package/src/cramFile/sectionParsers.ts +27 -22
  199. package/src/cramFile/slice/decodeRecord.ts +17 -17
  200. package/src/cramFile/slice/index.ts +8 -9
  201. package/src/cramFile/util.ts +24 -5
  202. package/src/htscodecs/arith_gen.js +33 -296
  203. package/src/htscodecs/fqzcomp.js +2 -476
  204. package/src/htscodecs/index.js +9 -11
  205. package/src/htscodecs/iostream.js +3 -2
  206. package/src/htscodecs/rans.js +3 -315
  207. package/src/htscodecs/rans4x16.js +6 -557
  208. package/src/htscodecs/tok3.js +18 -1
  209. package/src/index.ts +1 -1
  210. package/src/indexedCramFile.ts +6 -5
  211. package/src/io/index.ts +5 -4
  212. package/src/rans/constants.ts +1 -1
  213. package/src/rans/d04.ts +0 -1
  214. package/src/rans/decoding.ts +0 -1
  215. package/src/rans/frequencies.ts +0 -1
  216. package/src/rans/index.ts +5 -7
  217. package/src/unzip.ts +5 -1
  218. package/dist/cramFile/filehandle.d.ts +0 -1
  219. package/dist/cramFile/filehandle.js +0 -3
  220. package/dist/cramFile/filehandle.js.map +0 -1
  221. package/dist/htscodecs/main_arith_gen.d.ts +0 -1
  222. package/dist/htscodecs/main_arith_gen.js +0 -86
  223. package/dist/htscodecs/main_arith_gen.js.map +0 -1
  224. package/dist/htscodecs/main_fqzcomp.d.ts +0 -1
  225. package/dist/htscodecs/main_fqzcomp.js +0 -112
  226. package/dist/htscodecs/main_fqzcomp.js.map +0 -1
  227. package/dist/htscodecs/main_rans.d.ts +0 -1
  228. package/dist/htscodecs/main_rans.js +0 -83
  229. package/dist/htscodecs/main_rans.js.map +0 -1
  230. package/dist/htscodecs/main_rans4x16.d.ts +0 -1
  231. package/dist/htscodecs/main_rans4x16.js +0 -82
  232. package/dist/htscodecs/main_rans4x16.js.map +0 -1
  233. package/dist/htscodecs/main_tok3.d.ts +0 -1
  234. package/dist/htscodecs/main_tok3.js +0 -84
  235. package/dist/htscodecs/main_tok3.js.map +0 -1
  236. package/dist/unzip-pako.d.ts +0 -2
  237. package/dist/unzip-pako.js +0 -9
  238. package/dist/unzip-pako.js.map +0 -1
  239. package/esm/cramFile/filehandle.d.ts +0 -1
  240. package/esm/cramFile/filehandle.js +0 -2
  241. package/esm/cramFile/filehandle.js.map +0 -1
  242. package/esm/htscodecs/main_arith_gen.d.ts +0 -1
  243. package/esm/htscodecs/main_arith_gen.js +0 -86
  244. package/esm/htscodecs/main_arith_gen.js.map +0 -1
  245. package/esm/htscodecs/main_fqzcomp.d.ts +0 -1
  246. package/esm/htscodecs/main_fqzcomp.js +0 -112
  247. package/esm/htscodecs/main_fqzcomp.js.map +0 -1
  248. package/esm/htscodecs/main_rans.d.ts +0 -1
  249. package/esm/htscodecs/main_rans.js +0 -83
  250. package/esm/htscodecs/main_rans.js.map +0 -1
  251. package/esm/htscodecs/main_rans4x16.d.ts +0 -1
  252. package/esm/htscodecs/main_rans4x16.js +0 -82
  253. package/esm/htscodecs/main_rans4x16.js.map +0 -1
  254. package/esm/htscodecs/main_tok3.d.ts +0 -1
  255. package/esm/htscodecs/main_tok3.js +0 -84
  256. package/esm/htscodecs/main_tok3.js.map +0 -1
  257. package/esm/unzip-pako.d.ts +0 -2
  258. package/esm/unzip-pako.js +0 -6
  259. package/esm/unzip-pako.js.map +0 -1
  260. package/src/cramFile/filehandle.ts +0 -1
  261. package/src/htscodecs/Makefile +0 -142
  262. package/src/htscodecs/README.md +0 -64
  263. package/src/htscodecs/main_arith_gen.js +0 -96
  264. package/src/htscodecs/main_fqzcomp.js +0 -113
  265. package/src/htscodecs/main_rans.js +0 -88
  266. package/src/htscodecs/main_rans4x16.js +0 -87
  267. package/src/htscodecs/main_tok3.js +0 -86
  268. package/src/unzip-pako.ts +0 -6
package/src/craiIndex.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { unzip } from './unzip'
2
- import { open } from './io'
3
- import { CramMalformedError } from './errors'
4
1
  import { CramFileSource } from './cramFile/file'
5
- import { Filehandle } from './cramFile/filehandle'
2
+ import { CramMalformedError } from './errors'
3
+ import { open } from './io'
4
+ import { unzip } from './unzip'
5
+
6
+ import type { GenericFilehandle } from 'generic-filehandle2'
6
7
 
7
8
  const BAI_MAGIC = 21_578_050 // BAI\1
8
9
 
@@ -33,11 +34,8 @@ function addRecordToIndex(index: ParsedIndex, record: number[]) {
33
34
  })
34
35
  }
35
36
 
36
- function maybeUnzip(data: Buffer) {
37
- if (data[0] === 31 && data[1] === 139) {
38
- return unzip(data)
39
- }
40
- return data
37
+ function maybeUnzip(data: Uint8Array) {
38
+ return data[0] === 31 && data[1] === 139 ? unzip(data) : data
41
39
  }
42
40
 
43
41
  export default class CraiIndex {
@@ -50,10 +48,12 @@ export default class CraiIndex {
50
48
  // 4. Container start byte position in the file
51
49
  // 5. Slice start byte position in the container data (‘blocks’)
52
50
  // 6. Slice size in bytes
53
- // Each line represents a slice in the CRAM file. Please note that all slices must be listed in index file.
51
+ //
52
+ // Each line represents a slice in the CRAM file. Please note that all slices
53
+ // must be listed in index file.
54
54
  private parseIndexP?: Promise<ParsedIndex>
55
55
 
56
- private filehandle: Filehandle
56
+ private filehandle: GenericFilehandle
57
57
 
58
58
  /**
59
59
  *
@@ -69,18 +69,19 @@ export default class CraiIndex {
69
69
  async parseIndex() {
70
70
  const index: ParsedIndex = {}
71
71
  const uncompressedBuffer = maybeUnzip(await this.filehandle.readFile())
72
+ const dataView = new DataView(uncompressedBuffer.buffer)
72
73
  if (
73
74
  uncompressedBuffer.length > 4 &&
74
- uncompressedBuffer.readUInt32LE(0) === BAI_MAGIC
75
+ dataView.getUint32(0, true) === BAI_MAGIC
75
76
  ) {
76
77
  throw new CramMalformedError(
77
78
  'invalid .crai index file. note: file appears to be a .bai index. this is technically legal but please open a github issue if you need support',
78
79
  )
79
80
  }
80
- // interpret the text as regular ascii, since it is
81
- // supposed to be only digits and whitespace characters
82
- // this is written in a deliberately low-level fashion for performance,
83
- // because some .crai files can be pretty large.
81
+ // interpret the text as regular ascii, since it is supposed to be only
82
+ // digits and whitespace characters this is written in a deliberately
83
+ // low-level fashion for performance, because some .crai files can be
84
+ // pretty large.
84
85
  let currentRecord: number[] = []
85
86
  let currentString = ''
86
87
  for (const charCode of uncompressedBuffer) {
@@ -1,5 +1,5 @@
1
- import CramSlice from '../slice'
2
1
  import { CramFileBlock } from '../file'
2
+ import CramSlice from '../slice'
3
3
  import { DataType } from './dataSeriesTypes'
4
4
 
5
5
  export interface DataTypeMapping {
@@ -1,9 +1,9 @@
1
- import { CramUnimplementedError } from '../../errors'
2
1
  import CramCodec, { Cursors } from './_base'
3
2
  import { getBits } from './getBits'
4
- import CramSlice from '../slice'
5
- import { CramFileBlock } from '../file'
3
+ import { CramUnimplementedError } from '../../errors'
6
4
  import { BetaEncoding } from '../encoding'
5
+ import { CramFileBlock } from '../file'
6
+ import CramSlice from '../slice'
7
7
 
8
8
  export default class BetaCodec extends CramCodec<
9
9
  'int',
@@ -1,7 +1,7 @@
1
1
  import CramCodec, { Cursors } from './_base'
2
2
  import { ByteArrayLengthEncoding, CramEncoding } from '../encoding'
3
- import CramSlice from '../slice'
4
3
  import { CramFileBlock } from '../file'
4
+ import CramSlice from '../slice'
5
5
  import { DataType } from './dataSeriesTypes'
6
6
  import { tinyMemoize } from '../util'
7
7
 
@@ -1,9 +1,8 @@
1
- import { CramMalformedError } from '../../errors'
2
-
3
1
  import CramCodec, { Cursor, Cursors } from './_base'
4
- import CramSlice from '../slice'
5
- import { CramFileBlock } from '../file'
2
+ import { CramMalformedError } from '../../errors'
6
3
  import { ByteArrayStopCramEncoding } from '../encoding'
4
+ import { CramFileBlock } from '../file'
5
+ import CramSlice from '../slice'
7
6
  import { CramBufferOverrunError } from './getBits'
8
7
 
9
8
  export default class ByteArrayStopCodec extends CramCodec<
@@ -1,8 +1,8 @@
1
- import { CramMalformedError, CramUnimplementedError } from '../../errors'
2
1
  import CramCodec, { Cursor, Cursors } from './_base'
3
- import { parseItf8 } from '../util'
4
- import CramSlice from '../slice'
2
+ import { CramMalformedError, CramUnimplementedError } from '../../errors'
5
3
  import { CramFileBlock } from '../file'
4
+ import CramSlice from '../slice'
5
+ import { parseItf8 } from '../util'
6
6
  import { CramBufferOverrunError } from './getBits'
7
7
  import { ExternalCramEncoding } from '../encoding'
8
8
 
@@ -1,9 +1,9 @@
1
- import { CramUnimplementedError } from '../../errors'
2
1
  import CramCodec, { Cursors } from './_base'
3
2
  import { getBits } from './getBits'
3
+ import { CramUnimplementedError } from '../../errors'
4
4
  import { GammaEncoding } from '../encoding'
5
- import CramSlice from '../slice'
6
5
  import { CramFileBlock } from '../file'
6
+ import CramSlice from '../slice'
7
7
 
8
8
  export default class GammaCodec extends CramCodec<
9
9
  'int',
@@ -1,7 +1,7 @@
1
1
  export class CramBufferOverrunError extends Error {}
2
2
 
3
3
  export function getBits(
4
- data: Buffer,
4
+ data: Uint8Array,
5
5
  cursor: { bytePosition: number; bitPosition: number },
6
6
  numBits: number,
7
7
  ) {
@@ -1,10 +1,9 @@
1
- import { CramMalformedError } from '../../errors'
2
1
  import CramCodec, { Cursor, Cursors } from './_base'
3
2
  import { getBits } from './getBits'
3
+ import { CramMalformedError } from '../../errors'
4
4
  import { HuffmanEncoding } from '../encoding'
5
-
6
- import CramSlice from '../slice'
7
5
  import { CramFileBlock } from '../file'
6
+ import CramSlice from '../slice'
8
7
 
9
8
  function numberOfSetBits(ii: number) {
10
9
  let i = (ii - (ii >> 1)) & 0x55555555
@@ -1,15 +1,14 @@
1
- import { CramUnimplementedError } from '../../errors'
2
-
3
- import HuffmanIntCodec from './huffman'
4
- import ExternalCodec from './external'
5
- import ByteArrayStopCodec from './byteArrayStop'
6
- import ByteArrayLengthCodec from './byteArrayLength'
1
+ import CramCodec from './_base'
7
2
  import BetaCodec from './beta'
3
+ import ByteArrayLengthCodec from './byteArrayLength'
4
+ import ByteArrayStopCodec from './byteArrayStop'
5
+ import { DataType } from './dataSeriesTypes'
6
+ import ExternalCodec from './external'
8
7
  import GammaCodec from './gamma'
8
+ import HuffmanIntCodec from './huffman'
9
9
  import SubexpCodec from './subexp'
10
- import CramCodec from './_base'
10
+ import { CramUnimplementedError } from '../../errors'
11
11
  import { CramEncoding } from '../encoding'
12
- import { DataType } from './dataSeriesTypes'
13
12
 
14
13
  const codecClasses = {
15
14
  1: ExternalCodec,
@@ -1,9 +1,9 @@
1
- import { CramUnimplementedError } from '../../errors'
2
1
  import CramCodec, { Cursors } from './_base'
3
2
  import { getBits } from './getBits'
4
- import CramSlice from '../slice'
5
- import { CramFileBlock } from '../file'
3
+ import { CramUnimplementedError } from '../../errors'
6
4
  import { SubexpEncoding } from '../encoding'
5
+ import { CramFileBlock } from '../file'
6
+ import CramSlice from '../slice'
7
7
 
8
8
  export default class SubexpCodec extends CramCodec<
9
9
  'int',
@@ -1,12 +1,12 @@
1
+ import { CramMalformedError } from '../../errors'
1
2
  import { instantiateCodec } from '../codecs'
2
3
  import CramCodec from '../codecs/_base'
3
- import { CramCompressionHeader } from '../sectionParsers'
4
- import { CramEncoding } from '../encoding'
5
- import { CramMalformedError } from '../../errors'
6
4
  import {
7
5
  DataSeriesEncodingKey,
8
6
  DataSeriesEncodingMap,
9
7
  } from '../codecs/dataSeriesTypes'
8
+ import { CramEncoding } from '../encoding'
9
+ import { CramCompressionHeader } from '../sectionParsers'
10
10
 
11
11
  // the hardcoded data type to be decoded for each core
12
12
  // data field
@@ -1,8 +1,7 @@
1
- import { Buffer } from 'buffer'
2
1
  import { CramMalformedError } from '../../errors'
3
2
  // locals
4
- import { itf8Size, parseItem, tinyMemoize } from '../util'
5
3
  import CramSlice from '../slice'
4
+ import { itf8Size, parseItem, tinyMemoize } from '../util'
6
5
  import CramContainerCompressionScheme from './compressionScheme'
7
6
  import CramFile from '../file'
8
7
  import { getSectionParsers } from '../sectionParsers'
@@ -88,8 +87,10 @@ export default class CramContainer {
88
87
 
89
88
  // parse the container header. do it in 2 pieces because you cannot tell
90
89
  // how much to buffer until you read numLandmarks
91
- const bytes1 = Buffer.allocUnsafe(cramContainerHeader1.maxLength)
92
- await this.file.read(bytes1, 0, cramContainerHeader1.maxLength, position)
90
+ const bytes1 = await this.file.read(
91
+ cramContainerHeader1.maxLength,
92
+ position,
93
+ )
93
94
  const header1 = parseItem(bytes1, cramContainerHeader1.parser)
94
95
  const numLandmarksSize = itf8Size(header1.numLandmarks)
95
96
  if (position + header1.length >= fileSize) {
@@ -99,12 +100,8 @@ export default class CramContainer {
99
100
  )
100
101
  return undefined
101
102
  }
102
- const bytes2 = Buffer.allocUnsafe(
103
- cramContainerHeader2.maxLength(header1.numLandmarks),
104
- )
105
- await this.file.read(
106
- bytes2,
107
- 0,
103
+
104
+ const bytes2 = await this.file.read(
108
105
  cramContainerHeader2.maxLength(header1.numLandmarks),
109
106
  position + header1._size - numLandmarksSize,
110
107
  )
@@ -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 '../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,13 +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
- const headerLength = content.readInt32LE(0)
141
- const textStart = 4
142
- const text = content.toString('utf8', textStart, textStart + headerLength)
143
- this.header = text
144
- return parseHeaderText(text)
145
149
  }
146
150
 
147
151
  async getHeaderText() {
@@ -200,9 +204,11 @@ export default class CramFile {
200
204
  recordedCrc32: number,
201
205
  description: string,
202
206
  ) {
203
- const b = Buffer.allocUnsafe(length)
204
- await this.file.read(b, 0, length, position)
205
- 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
206
212
  if (calculatedCrc32 !== recordedCrc32) {
207
213
  throw new CramMalformedError(
208
214
  `crc mismatch in ${description}: recorded CRC32 = ${recordedCrc32}, but calculated CRC32 = ${calculatedCrc32}`,
@@ -264,21 +270,23 @@ export default class CramFile {
264
270
  return undefined
265
271
  }
266
272
 
267
- const buffer = Buffer.allocUnsafe(cramBlockHeader.maxLength)
268
- await this.file.read(buffer, 0, cramBlockHeader.maxLength, position)
273
+ const buffer = await this.file.read(cramBlockHeader.maxLength, position)
269
274
  return parseItem(buffer, cramBlockHeader.parser, 0, position)
270
275
  }
271
276
 
272
277
  async _parseSection<T>(
273
278
  section: {
274
279
  maxLength: number
275
- parser: (buffer: Buffer, offset: number) => { offset: number; value: T }
280
+ parser: (
281
+ buffer: Uint8Array,
282
+ offset: number,
283
+ ) => { offset: number; value: T }
276
284
  },
277
285
  position: number,
278
286
  size = section.maxLength,
279
- preReadBuffer?: Buffer,
287
+ preReadBuffer?: Uint8Array,
280
288
  ) {
281
- let buffer: Buffer
289
+ let buffer: Uint8Array
282
290
  if (preReadBuffer) {
283
291
  buffer = preReadBuffer
284
292
  } else {
@@ -286,8 +294,7 @@ export default class CramFile {
286
294
  if (position + size >= fileSize) {
287
295
  return undefined
288
296
  }
289
- buffer = Buffer.allocUnsafe(size)
290
- await this.file.read(buffer, 0, size, position)
297
+ buffer = await this.file.read(size, position)
291
298
  }
292
299
  const data = parseItem(buffer, section.parser, 0, position)
293
300
  if (data._size !== size) {
@@ -300,43 +307,43 @@ export default class CramFile {
300
307
 
301
308
  async _uncompress(
302
309
  compressionMethod: CompressionMethod,
303
- inputBuffer: Buffer,
304
- outputBuffer: Buffer,
310
+ inputBuffer: Uint8Array,
311
+ uncompressedSize: number,
305
312
  ) {
306
313
  if (compressionMethod === 'gzip') {
307
- const result = unzip(inputBuffer)
308
- result.copy(outputBuffer)
314
+ return unzip(inputBuffer)
309
315
  } else if (compressionMethod === 'bzip2') {
310
316
  const bits = bzip2.array(inputBuffer)
311
317
  let size = bzip2.header(bits)
312
- let j = 0
313
318
  let chunk: Uint8Array | -1
319
+ const chunks = []
314
320
  do {
315
321
  chunk = bzip2.decompress(bits, size)
316
322
  if (chunk !== -1) {
317
- Buffer.from(chunk).copy(outputBuffer, j)
318
- j += chunk.length
323
+ chunks.push(chunk)
319
324
  size -= chunk.length
320
325
  }
321
326
  } while (chunk !== -1)
327
+ return concatUint8Array(chunks)
322
328
  } else if (compressionMethod === 'lzma') {
323
329
  const decompressedResponse = new Response(
324
330
  new XzReadableStream(bufferToStream(inputBuffer)),
325
331
  )
326
- const ret = Buffer.from(await decompressedResponse.arrayBuffer())
327
- ret.copy(outputBuffer)
332
+ return new Uint8Array(await decompressedResponse.arrayBuffer())
328
333
  } else if (compressionMethod === 'rans') {
334
+ const outputBuffer = new Uint8Array(uncompressedSize)
329
335
  ransuncompress(inputBuffer, outputBuffer)
336
+ return outputBuffer
330
337
  // htscodecs r4x8 is slower, but compatible.
331
338
  // htscodecs.r4x8_uncompress(inputBuffer, outputBuffer);
332
339
  } else if (compressionMethod === 'rans4x16') {
333
- htscodecs.r4x16_uncompress(inputBuffer, outputBuffer)
340
+ return htscodecs.r4x16_uncompress(inputBuffer)
334
341
  } else if (compressionMethod === 'arith') {
335
- htscodecs.arith_uncompress(inputBuffer, outputBuffer)
342
+ return htscodecs.arith_uncompress(inputBuffer)
336
343
  } else if (compressionMethod === 'fqzcomp') {
337
- htscodecs.fqzcomp_uncompress(inputBuffer, outputBuffer)
344
+ return htscodecs.fqzcomp_uncompress(inputBuffer)
338
345
  } else if (compressionMethod === 'tok3') {
339
- htscodecs.tok3_uncompress(inputBuffer, outputBuffer)
346
+ return htscodecs.tok3_uncompress(inputBuffer)
340
347
  } else {
341
348
  throw new CramUnimplementedError(
342
349
  `${compressionMethod} decompression not yet implemented`,
@@ -353,7 +360,18 @@ export default class CramFile {
353
360
  }
354
361
  const blockContentPosition = blockHeader._endPosition
355
362
 
356
- 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
357
375
 
358
376
  const block: CramFileBlock = {
359
377
  ...blockHeader,
@@ -361,30 +379,6 @@ export default class CramFile {
361
379
  contentPosition: blockContentPosition,
362
380
  content: uncompressedData,
363
381
  }
364
-
365
- if (blockHeader.compressionMethod !== 'raw') {
366
- const compressedData = Buffer.allocUnsafe(blockHeader.compressedSize)
367
- await this.read(
368
- compressedData,
369
- 0,
370
- blockHeader.compressedSize,
371
- blockContentPosition,
372
- )
373
-
374
- await this._uncompress(
375
- blockHeader.compressionMethod,
376
- compressedData,
377
- uncompressedData,
378
- )
379
- } else {
380
- await this.read(
381
- uncompressedData,
382
- 0,
383
- blockHeader.uncompressedSize,
384
- blockContentPosition,
385
- )
386
- }
387
-
388
382
  if (majorVersion >= 3) {
389
383
  // parse the crc32
390
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(