Skip to content

Commit

Permalink
Add polyfill
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Aug 9, 2024
1 parent 186bbc7 commit 4c91a5c
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 6 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@
"biojs"
],
"dependencies": {
"generic-filehandle": "^3.0.0",
"long": "^4.0.0"
"generic-filehandle": "^3.0.0"
},
"devDependencies": {
"@types/jest": "^29.2.4",
Expand Down
13 changes: 13 additions & 0 deletions src/bigint-polyfill/polyfill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { getBigInt64, getBigUint64 } from './pure'

if (!('getBigInt64' in DataView)) {
DataView.prototype.getBigInt64 = function (byteOffset, littleEndian) {
return getBigInt64(this, byteOffset, littleEndian)
}
}

if (!('getBigUint64' in DataView)) {
DataView.prototype.getBigUint64 = function (byteOffset, littleEndian) {
return getBigUint64(this, byteOffset, littleEndian)
}
}
42 changes: 42 additions & 0 deletions src/bigint-polyfill/pure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const BigInt32 = BigInt(32)

export function getBigInt64(
dataView: DataView,
byteOffset: number,
littleEndian: boolean | undefined,
): bigint {
const littleEndianMask = Number(!!littleEndian)
const bigEndianMask = Number(!littleEndian)

return (
(BigInt(
dataView.getInt32(byteOffset, littleEndian) * bigEndianMask +
dataView.getInt32(byteOffset + 4, littleEndian) * littleEndianMask,
) <<
BigInt32) |
BigInt(
dataView.getUint32(byteOffset, littleEndian) * littleEndianMask +
dataView.getUint32(byteOffset + 4, littleEndian) * bigEndianMask,
)
)
}

export function getBigUint64(
dataView: DataView,
byteOffset: number,
littleEndian: boolean | undefined,
): bigint {
const a = dataView.getUint32(byteOffset, littleEndian)
const b = dataView.getUint32(byteOffset + 4, littleEndian)

const littleEndianMask = Number(!!littleEndian)
const bigEndianMask = Number(!littleEndian)

// This branch-less optimization is 77x faster than normal ternary operator.
// and only 3% slower than native implementation
// https://jsbench.me/p8kyhg1eqv/1
return (
(BigInt(a * bigEndianMask + b * littleEndianMask) << BigInt32) |
BigInt(a * littleEndianMask + b * bigEndianMask)
)
}
2 changes: 0 additions & 2 deletions src/declare.d.ts

This file was deleted.

1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import './bigint-polyfill/polyfill'
export { default as TwoBitFile } from './twoBitFile'
7 changes: 5 additions & 2 deletions src/twoBitFile.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Long from 'long'
import { LocalFile, GenericFilehandle } from 'generic-filehandle'

const TWOBIT_MAGIC = 0x1a412743
Expand Down Expand Up @@ -316,7 +315,11 @@ export default class TwoBitFile {
* @param {number} [regionEnd] optional 0-based half-open end of the sequence region to fetch. defaults to end of the sequence
* @returns {Promise} for a string of sequence bases
*/
async getSequence(seqName: string, regionStart = 0, regionEnd = Number.POSITIVE_INFINITY) {
async getSequence(
seqName: string,
regionStart = 0,
regionEnd = Number.POSITIVE_INFINITY,
) {
const index = await this.getIndex()
const offset = index[seqName]
if (!offset) {
Expand Down

0 comments on commit 4c91a5c

Please sign in to comment.