@gmod/bam 7.6.1 → 7.7.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 (71) hide show
  1. package/README.md +109 -98
  2. package/dist/bai.d.ts +6 -3
  3. package/dist/bai.js +32 -16
  4. package/dist/bai.js.map +1 -1
  5. package/dist/bamFile.d.ts +16 -3
  6. package/dist/bamFile.js +83 -36
  7. package/dist/bamFile.js.map +1 -1
  8. package/dist/chunk.d.ts +0 -1
  9. package/dist/chunk.js +0 -5
  10. package/dist/chunk.js.map +1 -1
  11. package/dist/csi.d.ts +0 -2
  12. package/dist/csi.js +4 -11
  13. package/dist/csi.js.map +1 -1
  14. package/dist/htsget.d.ts +16 -0
  15. package/dist/htsget.js +72 -52
  16. package/dist/htsget.js.map +1 -1
  17. package/dist/index.d.ts +1 -0
  18. package/dist/indexFile.d.ts +2 -3
  19. package/dist/indexFile.js.map +1 -1
  20. package/dist/sam.js +8 -3
  21. package/dist/sam.js.map +1 -1
  22. package/dist/util.d.ts +11 -3
  23. package/dist/util.js +35 -8
  24. package/dist/util.js.map +1 -1
  25. package/dist/virtualOffset.d.ts +8 -3
  26. package/dist/virtualOffset.js +0 -3
  27. package/dist/virtualOffset.js.map +1 -1
  28. package/esm/bai.d.ts +6 -3
  29. package/esm/bai.js +32 -16
  30. package/esm/bai.js.map +1 -1
  31. package/esm/bamFile.d.ts +16 -3
  32. package/esm/bamFile.js +83 -36
  33. package/esm/bamFile.js.map +1 -1
  34. package/esm/chunk.d.ts +0 -1
  35. package/esm/chunk.js +0 -5
  36. package/esm/chunk.js.map +1 -1
  37. package/esm/csi.d.ts +0 -2
  38. package/esm/csi.js +4 -11
  39. package/esm/csi.js.map +1 -1
  40. package/esm/htsget.d.ts +16 -0
  41. package/esm/htsget.js +73 -53
  42. package/esm/htsget.js.map +1 -1
  43. package/esm/index.d.ts +1 -0
  44. package/esm/indexFile.d.ts +2 -3
  45. package/esm/indexFile.js.map +1 -1
  46. package/esm/sam.js +8 -3
  47. package/esm/sam.js.map +1 -1
  48. package/esm/util.d.ts +11 -3
  49. package/esm/util.js +35 -8
  50. package/esm/util.js.map +1 -1
  51. package/esm/virtualOffset.d.ts +8 -3
  52. package/esm/virtualOffset.js +0 -3
  53. package/esm/virtualOffset.js.map +1 -1
  54. package/package.json +3 -3
  55. package/src/bai.ts +42 -20
  56. package/src/bamFile.ts +86 -38
  57. package/src/chunk.ts +0 -8
  58. package/src/csi.ts +4 -10
  59. package/src/htsget.ts +117 -62
  60. package/src/index.ts +2 -0
  61. package/src/indexFile.ts +2 -3
  62. package/src/sam.ts +8 -3
  63. package/src/util.ts +44 -11
  64. package/src/virtualOffset.ts +9 -8
  65. package/dist/long.d.ts +0 -1
  66. package/dist/long.js +0 -17
  67. package/dist/long.js.map +0 -1
  68. package/esm/long.d.ts +0 -1
  69. package/esm/long.js +0 -14
  70. package/esm/long.js.map +0 -1
  71. package/src/long.ts +0 -16
package/src/htsget.ts CHANGED
@@ -2,42 +2,111 @@ import { unzip } from '@gmod/bgzf-filehandle'
2
2
 
3
3
  import BamFile, { BAM_MAGIC } from './bamFile.ts'
4
4
  import Chunk from './chunk.ts'
5
- import { parseHeaderText } from './sam.ts'
6
- import { appendInRange, concatUint8Array } from './util.ts'
5
+ import { appendInRange, concatUint8Array, parseRefSeqs } from './util.ts'
7
6
  import { VirtualOffset } from './virtualOffset.ts'
8
7
 
9
8
  import type { BamRecordClass, BamRecordLike } from './bamFile.ts'
10
9
  import type BamRecord from './record.ts'
11
10
  import type { BamOpts, BaseOpts } from './util.ts'
11
+ import type { Fetcher } from 'generic-filehandle2'
12
12
 
13
13
  interface HtsgetChunk {
14
14
  url: string
15
15
  headers?: Record<string, string>
16
+ // present on either all of a ticket's urls or none; only a hint, since the
17
+ // blocks still have to be concatenated in ticket order either way
18
+ class?: 'header' | 'body'
16
19
  }
17
20
 
18
- async function fetchOk(url: string, opts?: RequestInit) {
19
- const res = await fetch(url, opts)
21
+ interface HtsgetTicket {
22
+ htsget: { urls: HtsgetChunk[] }
23
+ }
24
+
25
+ interface HtsgetErrorBody {
26
+ htsget?: { error?: string; message?: string }
27
+ }
28
+
29
+ // Errors carry a JSON body naming the error type, e.g. {"htsget":
30
+ // {"error":"InvalidAuthentication","message":"..."}}. Surface that rather than
31
+ // the raw payload, since 401/403 are the first thing a misconfigured token hits.
32
+ function htsgetErrorMessage(text: string) {
33
+ let parsed: HtsgetErrorBody | undefined
34
+ try {
35
+ parsed = JSON.parse(text)
36
+ } catch {
37
+ // not JSON, fall through to the raw body
38
+ }
39
+ const err = parsed?.htsget
40
+ return err?.error === undefined
41
+ ? text
42
+ : err.message === undefined
43
+ ? err.error
44
+ : `${err.error}: ${err.message}`
45
+ }
46
+
47
+ /**
48
+ * Offset of the first alignment record in the concatenated ticket blocks.
49
+ *
50
+ * The spec has the client concatenate the blocks in ticket order to get a
51
+ * complete data stream, so whether the header is its own block is up to the
52
+ * server: htsnexus splits it into a leading `data:` url, while htsget-rs
53
+ * returns header and records together in a single url. Either way the
54
+ * concatenation starts with the BAM header, so seek past it rather than
55
+ * dropping blocks — a url count or class attribute can't tell the two layouts
56
+ * apart. Returns 0 when the stream has no header, which is what a server
57
+ * sending body-only blocks produces.
58
+ */
59
+ function recordsOffset(uncba: Uint8Array) {
60
+ const dataView = new DataView(
61
+ uncba.buffer,
62
+ uncba.byteOffset,
63
+ uncba.byteLength,
64
+ )
65
+ if (uncba.byteLength < 8 || dataView.getInt32(0, true) !== BAM_MAGIC) {
66
+ return 0
67
+ }
68
+ const refs = parseRefSeqs(uncba, 8 + dataView.getInt32(4, true), n => n)
69
+ if (!refs) {
70
+ throw new Error('truncated BAM header in htsget response')
71
+ }
72
+ return refs.end
73
+ }
74
+
75
+ async function fetchOk(fetchFn: Fetcher, url: string, opts?: RequestInit) {
76
+ const res = await fetchFn(url, opts)
20
77
  if (!res.ok) {
21
- throw new Error(`HTTP ${res.status} fetching ${url}: ${await res.text()}`)
78
+ throw new Error(
79
+ `HTTP ${res.status} fetching ${url}: ${htsgetErrorMessage(await res.text())}`,
80
+ )
22
81
  }
23
82
  return res
24
83
  }
25
84
 
26
- async function fetchChunk({ url, headers }: HtsgetChunk, opts?: RequestInit) {
85
+ async function fetchChunk(
86
+ fetchFn: Fetcher,
87
+ { url, headers }: HtsgetChunk,
88
+ opts?: RequestInit,
89
+ ) {
27
90
  // pass base64 data URLs straight to fetch; otherwise apply headers (minus
28
91
  // referer, which isn't a permitted client-set header).
29
92
  // https://stackoverflow.com/a/54123275/2129219
30
93
  const { referer: _referer, ...rest } = headers ?? {}
31
94
  const res = url.startsWith('data:')
32
- ? await fetchOk(url)
33
- : await fetchOk(url, { ...opts, headers: rest })
95
+ ? await fetchOk(fetchFn, url)
96
+ : await fetchOk(fetchFn, url, { ...opts, headers: rest })
34
97
  return new Uint8Array(await res.arrayBuffer())
35
98
  }
36
99
 
37
- async function fetchAndConcat(arr: HtsgetChunk[], opts?: RequestInit) {
100
+ async function fetchAndConcat(
101
+ fetchFn: Fetcher,
102
+ arr: HtsgetChunk[],
103
+ opts?: RequestInit,
104
+ ) {
38
105
  // Pipeline unzip after each fetch so decompression overlaps later fetches.
39
106
  return concatUint8Array(
40
- await Promise.all(arr.map(async c => unzip(await fetchChunk(c, opts)))),
107
+ await Promise.all(
108
+ arr.map(async c => unzip(await fetchChunk(fetchFn, c, opts))),
109
+ ),
41
110
  )
42
111
  }
43
112
 
@@ -48,14 +117,39 @@ export default class HtsgetFile<
48
117
 
49
118
  private trackId: string
50
119
 
120
+ private fetchFn: Fetcher
121
+
51
122
  constructor(args: {
52
123
  trackId: string
53
124
  baseUrl: string
54
125
  recordClass?: BamRecordClass<T>
126
+ /**
127
+ * fetch implementation used for every request, so an `Authorization: Bearer
128
+ * <token>` header can be added for servers that require one. It is also
129
+ * called with the data-block urls from the ticket, which may point at
130
+ * third-party hosts, so only attach credentials to hosts you trust — the
131
+ * spec has servers put whatever a data block needs in that url's own
132
+ * `headers` field, which is applied either way.
133
+ */
134
+ fetch?: Fetcher
55
135
  }) {
56
136
  super({ htsget: true, recordClass: args.recordClass })
57
137
  this.baseUrl = args.baseUrl
58
138
  this.trackId = args.trackId
139
+ this.fetchFn = args.fetch ?? ((input, init) => fetch(input, init))
140
+ }
141
+
142
+ /**
143
+ * Requests a ticket and returns its data blocks decompressed and
144
+ * concatenated, which per the spec is a complete BAM stream.
145
+ */
146
+ private async fetchTicket(query: string, opts?: BaseOpts) {
147
+ const url = `${this.baseUrl}/${this.trackId}?${query}`
148
+ const res = await fetchOk(this.fetchFn, url, { signal: opts?.signal })
149
+ const ticket: HtsgetTicket = await res.json()
150
+ return fetchAndConcat(this.fetchFn, ticket.htsget.urls, {
151
+ signal: opts?.signal,
152
+ })
59
153
  }
60
154
 
61
155
  async getRecordsForRange(
@@ -65,71 +159,32 @@ export default class HtsgetFile<
65
159
  opts?: BamOpts,
66
160
  ) {
67
161
  await this.getHeader(opts)
68
- const base = `${this.baseUrl}/${this.trackId}`
69
- const url = `${base}?referenceName=${chr}&start=${min}&end=${max}&format=BAM`
70
162
  const chrId = this.chrToIndex?.[chr]
71
163
  if (chrId === undefined) {
72
164
  return []
73
165
  }
74
- const result = await fetchOk(url, opts)
75
- const data = await result.json()
76
- const uncba = await fetchAndConcat(data.htsget.urls.slice(1), {
77
- signal: opts?.signal,
78
- })
79
-
166
+ const uncba = await this.fetchTicket(
167
+ `referenceName=${chr}&start=${min}&end=${max}&format=BAM`,
168
+ opts,
169
+ )
80
170
  const zero = new VirtualOffset(0, 0)
81
- const allRecords = this.readBamFeatures(
82
- uncba,
171
+ const records = this.readBamFeatures(
172
+ uncba.subarray(recordsOffset(uncba)),
83
173
  [],
84
174
  [],
85
175
  new Chunk(zero, zero, 0),
86
176
  )
87
-
88
- return appendInRange(allRecords, chrId, min, max)
177
+ return appendInRange(records, chrId, min, max)
89
178
  }
90
179
 
91
180
  async getHeaderPre(opts: BaseOpts = {}) {
92
- const url = `${this.baseUrl}/${this.trackId}?referenceName=na&class=header`
93
- const result = await fetchOk(url, opts)
94
- const data = await result.json()
95
- const uncba = await fetchAndConcat(data.htsget.urls, {
96
- signal: opts.signal,
97
- })
98
- const dataView = new DataView(
99
- uncba.buffer,
100
- uncba.byteOffset,
101
- uncba.byteLength,
102
- )
103
-
104
- if (dataView.getInt32(0, true) !== BAM_MAGIC) {
105
- throw new Error('Not a BAM file')
106
- }
107
- const headLen = dataView.getInt32(4, true)
108
-
109
- const decoder = new TextDecoder()
110
- const headerText = decoder.decode(uncba.subarray(8, 8 + headLen))
111
- const samHeader = parseHeaderText(headerText)
112
-
113
- // use the @SQ lines in the header to figure out the
114
- // mapping between ref ref ID numbers and names
115
- const idToName: { refName: string; length: number }[] = []
116
- const nameToId: Record<string, number> = {}
117
- const sqLines = samHeader.filter(l => l.tag === 'SQ')
118
- for (const [refId, sqLine] of sqLines.entries()) {
119
- let refName = ''
120
- let length = 0
121
- for (const item of sqLine.data) {
122
- if (item.tag === 'SN') {
123
- refName = item.value
124
- } else if (item.tag === 'LN') {
125
- length = +item.value
126
- }
127
- }
128
- nameToId[refName] = refId
129
- idToName[refId] = { refName, length }
181
+ // format is the only parameter the spec permits alongside class=header;
182
+ // servers SHOULD reject anything else with InvalidInput
183
+ const uncba = await this.fetchTicket('class=header&format=BAM', opts)
184
+ const samHeader = this.applyHeader(uncba)
185
+ if (!samHeader) {
186
+ throw new Error('Insufficient data for reference sequences')
130
187
  }
131
- this.chrToIndex = nameToId
132
- this.indexToChr = idToName
133
188
  return samHeader
134
189
  }
135
190
  }
package/src/index.ts CHANGED
@@ -6,3 +6,5 @@ export { default as HtsgetFile } from './htsget.ts'
6
6
 
7
7
  export type { Bytes } from './record.ts'
8
8
  export type { BamRecordClass, BamRecordLike } from './bamFile.ts'
9
+ // for typing the HtsgetFile `fetch` option
10
+ export type { Fetcher } from 'generic-filehandle2'
package/src/indexFile.ts CHANGED
@@ -4,7 +4,7 @@ import { optimizeChunks } from './util.ts'
4
4
 
5
5
  import type Chunk from './chunk.ts'
6
6
  import type { BaseOpts } from './util.ts'
7
- import type { Offset, VirtualOffset } from './virtualOffset.ts'
7
+ import type { OffsetCoords, VirtualOffset } from './virtualOffset.ts'
8
8
  import type { GenericFilehandle } from 'generic-filehandle2'
9
9
 
10
10
  export interface Region {
@@ -21,7 +21,6 @@ export interface RefIndex {
21
21
  export interface ParsedIndexBase<R extends RefIndex = RefIndex> {
22
22
  firstDataLine: VirtualOffset | undefined
23
23
  refCount: number
24
- maxBlockSize: number
25
24
  indices: (refId: number) => R | undefined
26
25
  }
27
26
 
@@ -84,7 +83,7 @@ export default abstract class IndexFile<
84
83
  protected abstract getLowestChunk(
85
84
  refIndex: RefIndex,
86
85
  min: number,
87
- ): Offset | undefined
86
+ ): OffsetCoords | undefined
88
87
 
89
88
  async blocksForRange(
90
89
  refId: number,
package/src/sam.ts CHANGED
@@ -8,9 +8,14 @@ export function parseHeaderText(text: string) {
8
8
  tag: tag.slice(1),
9
9
  data: fields.map(f => {
10
10
  const r = f.indexOf(':')
11
- const fieldTag = f.slice(0, r)
12
- const value = f.slice(r + 1)
13
- return { tag: fieldTag, value }
11
+ // A field with no colon is not a TAG:VALUE pair — @CO lines are free
12
+ // text, one comment per line (`samtools view -H c2#pad.3.0.cram`).
13
+ // Without this branch `slice(0, -1)` silently drops the comment's last
14
+ // character into the tag. Same shape @gmod/cram's parseHeaderText
15
+ // returns, so both feed a consumer's header parser identically.
16
+ return r === -1
17
+ ? { tag: f, value: '' }
18
+ : { tag: f.slice(0, r), value: f.slice(r + 1) }
14
19
  }),
15
20
  })
16
21
  }
package/src/util.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import Chunk from './chunk.ts'
2
- import { longFromBytesToUnsigned } from './long.ts'
3
2
  import { VirtualOffset } from './virtualOffset.ts'
4
3
 
5
- import type { Offset } from './virtualOffset.ts'
4
+ import type { OffsetCoords } from './virtualOffset.ts'
6
5
 
7
6
  export interface BamOpts {
8
7
  viewAsPairs?: boolean
@@ -30,7 +29,7 @@ export interface BaseOpts {
30
29
  onProgress?: (bytesDownloaded: number, totalBytes?: number) => void
31
30
  }
32
31
 
33
- export function optimizeChunks(chunks: Chunk[], lowest?: Offset) {
32
+ export function optimizeChunks(chunks: Chunk[], lowest?: OffsetCoords) {
34
33
  const n = chunks.length
35
34
  if (n === 0) {
36
35
  return chunks
@@ -102,9 +101,22 @@ export function optimizeChunks(chunks: Chunk[], lowest?: Offset) {
102
101
  return mergedChunks
103
102
  }
104
103
 
104
+ // The pseudo-bin's mapped-record count, a little-endian uint64. Read as two
105
+ // 32-bit halves rather than via BigInt: exact up to Number.MAX_SAFE_INTEGER,
106
+ // which is far past any real record count, and allocates nothing.
105
107
  export function parsePseudoBin(bytes: Uint8Array, offset: number) {
108
+ const low =
109
+ bytes[offset]! |
110
+ (bytes[offset + 1]! << 8) |
111
+ (bytes[offset + 2]! << 16) |
112
+ (bytes[offset + 3]! << 24)
113
+ const high =
114
+ bytes[offset + 4]! |
115
+ (bytes[offset + 5]! << 8) |
116
+ (bytes[offset + 6]! << 16) |
117
+ (bytes[offset + 7]! << 24)
106
118
  return {
107
- lineCount: longFromBytesToUnsigned(bytes, offset),
119
+ lineCount: (high >>> 0) * 2 ** 32 + (low >>> 0),
108
120
  }
109
121
  }
110
122
 
@@ -117,13 +129,21 @@ export function parsePseudoBin(bytes: Uint8Array, offset: number) {
117
129
  // Shrinks both the byte estimate and the actual fetch with no extra I/O.
118
130
  export function clampChunkEnds(
119
131
  chunks: Chunk[],
120
- extraBoundaries: number[] = [],
132
+ extraBoundaries: ArrayLike<number> = [],
121
133
  ) {
122
- const boundaries = [...extraBoundaries]
134
+ // Float64Array rather than number[]: `extraBoundaries` is the linear index,
135
+ // which runs to tens of thousands of entries on a human-sized reference, and
136
+ // this is the only place they get copied.
137
+ const boundaries = new Float64Array(
138
+ extraBoundaries.length + chunks.length * 2,
139
+ )
140
+ boundaries.set(extraBoundaries)
141
+ let n = extraBoundaries.length
123
142
  for (const c of chunks) {
124
- boundaries.push(c.minv.blockPosition, c.maxv.blockPosition)
143
+ boundaries[n++] = c.minv.blockPosition
144
+ boundaries[n++] = c.maxv.blockPosition
125
145
  }
126
- boundaries.sort((a, b) => a - b)
146
+ boundaries.sort()
127
147
 
128
148
  for (const c of chunks) {
129
149
  const max = c.maxv.blockPosition
@@ -184,14 +204,24 @@ export function parseRefSeqs(
184
204
  indexToChr.push({ refName, length: lRef })
185
205
  p += 8 + lName
186
206
  }
187
- return { chrToIndex, indexToChr }
207
+ // end is the offset just past the header, i.e. where alignment records start
208
+ return { chrToIndex, indexToChr, end: p }
188
209
  }
189
210
 
190
- // SYNC: ~/src/gmod/tabix-js/src/util.ts minVirtualOffset
211
+ // SYNC: ~/src/gmod/tabix-js/src/util.ts minVirtualOffset — but NOT the 0:0
212
+ // skip below, which is only sound for BAM. A tabix'd file with no header lines
213
+ // really does have its first record at 0:0.
191
214
  /**
192
215
  * The smallest of `current` and the `count` packed virtual offsets starting at
193
216
  * `offset`, allocating at most one VirtualOffset rather than one per entry.
194
217
  *
218
+ * 0:0 is skipped rather than treated as the minimum. No BAM record can live
219
+ * there — the magic and header occupy the start of the file — so it is the
220
+ * "unset" placeholder htslib leaves in linear-index windows ahead of a
221
+ * reference's first read (see test/data/HG00096_illumina_lowcov.bam.bai, whose
222
+ * first three windows are 0). Counting it collapses firstDataLine to 0:0 and
223
+ * makes callers size a header read from nothing.
224
+ *
195
225
  * The index first pass exists only to find this minimum, and it visits every
196
226
  * linear-index entry in the file to do it. Building a VirtualOffset per entry
197
227
  * to compare and discard it is the bulk of that pass.
@@ -215,7 +245,10 @@ export function minVirtualOffset(
215
245
  bytes[p + 3]! * 0x100 +
216
246
  bytes[p + 2]!
217
247
  const data = (bytes[p + 1]! << 8) | bytes[p]!
218
- if (block < minBlock || (block === minBlock && data < minData)) {
248
+ if (
249
+ (block !== 0 || data !== 0) &&
250
+ (block < minBlock || (block === minBlock && data < minData))
251
+ ) {
219
252
  minBlock = block
220
253
  minData = data
221
254
  found = true
@@ -1,8 +1,15 @@
1
- export interface Offset {
1
+ /**
2
+ * The two coordinates a virtual offset packs, without the `blockPos:dataPos`
3
+ * string form. What every consumer that only compares positions needs — the
4
+ * BAI linear index stores these as raw numbers and materializes no object.
5
+ */
6
+ export interface OffsetCoords {
2
7
  blockPosition: number
3
8
  dataPosition: number
9
+ }
10
+
11
+ export interface Offset extends OffsetCoords {
4
12
  toString(): string
5
- compareTo(arg: Offset): number
6
13
  }
7
14
 
8
15
  export class VirtualOffset {
@@ -16,12 +23,6 @@ export class VirtualOffset {
16
23
  toString() {
17
24
  return `${this.blockPosition}:${this.dataPosition}`
18
25
  }
19
-
20
- compareTo(b: VirtualOffset) {
21
- return (
22
- this.blockPosition - b.blockPosition || this.dataPosition - b.dataPosition
23
- )
24
- }
25
26
  }
26
27
  export function fromBytes(bytes: Uint8Array, offset = 0) {
27
28
  return new VirtualOffset(
package/dist/long.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare function longFromBytesToUnsigned(source: Uint8Array, i?: number): number;
package/dist/long.js DELETED
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.longFromBytesToUnsigned = longFromBytesToUnsigned;
4
- const TWO_PWR_32_DBL = 2 ** 32;
5
- // avoids dependency on long.js
6
- function longFromBytesToUnsigned(source, i = 0) {
7
- const low = source[i] |
8
- (source[i + 1] << 8) |
9
- (source[i + 2] << 16) |
10
- (source[i + 3] << 24);
11
- const high = source[i + 4] |
12
- (source[i + 5] << 8) |
13
- (source[i + 6] << 16) |
14
- (source[i + 7] << 24);
15
- return (high >>> 0) * TWO_PWR_32_DBL + (low >>> 0);
16
- }
17
- //# sourceMappingURL=long.js.map
package/dist/long.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"long.js","sourceRoot":"","sources":["../src/long.ts"],"names":[],"mappings":";;AAGA,0DAYC;AAfD,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,CAAA;AAE9B,+BAA+B;AAC/B,SAAgB,uBAAuB,CAAC,MAAkB,EAAE,CAAC,GAAG,CAAC;IAC/D,MAAM,GAAG,GACP,MAAM,CAAC,CAAC,CAAE;QACV,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC;QACrB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC;QACtB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC,CAAA;IACxB,MAAM,IAAI,GACR,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE;QACd,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC;QACrB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC;QACtB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC,CAAA;IACxB,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,cAAc,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAA;AACpD,CAAC"}
package/esm/long.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare function longFromBytesToUnsigned(source: Uint8Array, i?: number): number;
package/esm/long.js DELETED
@@ -1,14 +0,0 @@
1
- const TWO_PWR_32_DBL = 2 ** 32;
2
- // avoids dependency on long.js
3
- export function longFromBytesToUnsigned(source, i = 0) {
4
- const low = source[i] |
5
- (source[i + 1] << 8) |
6
- (source[i + 2] << 16) |
7
- (source[i + 3] << 24);
8
- const high = source[i + 4] |
9
- (source[i + 5] << 8) |
10
- (source[i + 6] << 16) |
11
- (source[i + 7] << 24);
12
- return (high >>> 0) * TWO_PWR_32_DBL + (low >>> 0);
13
- }
14
- //# sourceMappingURL=long.js.map
package/esm/long.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"long.js","sourceRoot":"","sources":["../src/long.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,CAAA;AAE9B,+BAA+B;AAC/B,MAAM,UAAU,uBAAuB,CAAC,MAAkB,EAAE,CAAC,GAAG,CAAC;IAC/D,MAAM,GAAG,GACP,MAAM,CAAC,CAAC,CAAE;QACV,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC;QACrB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC;QACtB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC,CAAA;IACxB,MAAM,IAAI,GACR,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE;QACd,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC;QACrB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC;QACtB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC,CAAA;IACxB,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,cAAc,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAA;AACpD,CAAC"}
package/src/long.ts DELETED
@@ -1,16 +0,0 @@
1
- const TWO_PWR_32_DBL = 2 ** 32
2
-
3
- // avoids dependency on long.js
4
- export function longFromBytesToUnsigned(source: Uint8Array, i = 0) {
5
- const low =
6
- source[i]! |
7
- (source[i + 1]! << 8) |
8
- (source[i + 2]! << 16) |
9
- (source[i + 3]! << 24)
10
- const high =
11
- source[i + 4]! |
12
- (source[i + 5]! << 8) |
13
- (source[i + 6]! << 16) |
14
- (source[i + 7]! << 24)
15
- return (high >>> 0) * TWO_PWR_32_DBL + (low >>> 0)
16
- }