Skip to content

Commit

Permalink
Lint fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Aug 30, 2024
1 parent 9b4d320 commit bbe60de
Show file tree
Hide file tree
Showing 15 changed files with 814 additions and 2,275 deletions.
13 changes: 13 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ import eslintPluginUnicorn from 'eslint-plugin-unicorn'
import tseslint from 'typescript-eslint'

export default tseslint.config(
{
ignores: [
'webpack.config.js',
'dist/*',
'esm/*',
'example/*',
'eslint.config.mjs',
],
},
{
languageOptions: {
parserOptions: {
Expand Down Expand Up @@ -73,12 +82,16 @@ export default tseslint.config(
'unicorn/escape-case': 'off',
'unicorn/prefer-number-properties': 'off',
'unicorn/no-process-exit': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/restrict-template-expressions': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/no-deprecated': 'off',
'no-empty': 'off',
},
},
)
5 changes: 0 additions & 5 deletions jest.config.js

This file was deleted.

15 changes: 6 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@
"src"
],
"scripts": {
"test": "jest",
"coverage": "npm test -- --coverage",
"lint": "eslint --report-unused-disable-directives --max-warnings 0 src test",
"test": "vitest",
"lint": "eslint --report-unused-disable-directives --max-warnings 0",
"format": "prettier --write .",
"clean": "rimraf dist esm",
"prebuild": "npm run clean && npm run lint",
"build:esm": "tsc --target es2018 --outDir esm",
"build:es5": "tsc --target es2015 --module commonjs --outDir dist",
"build": "npm run build:esm && npm run build:es5",
"postbuild": "webpack",
"preversion": "npm run lint && npm test && npm run build",
"prepublishOnly": "npm run lint && npm test && npm run build",
"preversion": "npm run lint && npm test run && npm run build",
"prepublishOnly": "npm run lint && npm test run && npm run build",
"version": "standard-changelog && git add CHANGELOG.md",
"postversion": "git push --follow-tags"
},
Expand All @@ -49,7 +49,6 @@
"devDependencies": {
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "^9.9.0",
"@types/jest": "^29.5.12",
"@types/long": "^4.0.0",
"@types/node": "^20.11.16",
"@typescript-eslint/eslint-plugin": "^8.0.1",
Expand All @@ -59,14 +58,12 @@
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-unicorn": "^55.0.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.5.0",
"prettier": "^3.3.3",
"rimraf": "^6.0.1",
"standard-changelog": "^6.0.0",
"ts-jest": "^29.1.1",
"typescript": "^5.3.3",
"typescript-eslint": "^8.0.1",
"vitest": "^2.0.5",
"webpack": "^5.93.0",
"webpack-cli": "^5.1.4"
},
Expand Down
2 changes: 1 addition & 1 deletion src/chunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default class Chunk {
}

toUniqueString() {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
return `${this.minv}..${this.maxv} (bin ${
this.bin
}, fetchedSize ${this.fetchedSize()})`
Expand Down
11 changes: 6 additions & 5 deletions src/csi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ export default class CSI extends IndexFile {
}
async lineCount(refName: string, opts: Options = {}): Promise<number> {
const indexData = await this.parse(opts)
if (!indexData) {
const refId = indexData.refNameToId[refName]
if (refId === undefined) {
return -1
}
const refId = indexData.refNameToId[refName]
const idx = indexData.indices[refId]
if (!idx) {
return -1
Expand All @@ -44,6 +44,7 @@ export default class CSI extends IndexFile {
}
return -1
}

indexCov() {
throw new Error('CSI indexes do not support indexcov')
}
Expand Down Expand Up @@ -206,10 +207,10 @@ export default class CSI extends IndexFile {
}

const indexData = await this.parse(opts)
if (!indexData) {
const refId = indexData.refNameToId[refName]
if (refId === undefined) {
return []
}
const refId = indexData.refNameToId[refName]
const ba = indexData.indices[refId]
if (!ba) {
return []
Expand Down Expand Up @@ -258,7 +259,7 @@ export default class CSI extends IndexFile {
`query ${beg}-${end} is too large for current binning scheme (shift ${this.minShift}, depth ${this.depth}), try a smaller query or a coarser index binning scheme`,
)
}
bins.push([b, e])
bins.push([b, e] as const)
}
return bins
}
Expand Down
2 changes: 1 addition & 1 deletion src/indexFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default abstract class IndexFile {

async parse(opts: Options = {}) {
if (!this.parseP) {
this.parseP = this._parse(opts).catch(e => {
this.parseP = this._parse(opts).catch((e: unknown) => {
this.parseP = undefined
throw e
})
Expand Down
100 changes: 51 additions & 49 deletions src/tabixIndexedFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,32 @@ function timeout(time: number) {
export default class TabixIndexedFile {
private filehandle: GenericFilehandle
private index: IndexFile
private chunkSizeLimit: number
private yieldTime: number
private renameRefSeq: (n: string) => string
private chunkCache: AbortablePromiseCache<Chunk, ReadChunk>

/**
* @param {object} args
*
* @param {string} [args.path]
*
* @param {filehandle} [args.filehandle]
*
* @param {string} [args.tbiPath]
*
* @param {filehandle} [args.tbiFilehandle]
*
* @param {string} [args.csiPath]
*
* @param {filehandle} [args.csiFilehandle]
* @param {number} [args.yieldTime] yield to main thread after N milliseconds if reading features is taking a long time to avoid hanging main thread
* @param {function} [args.renameRefSeqs] optional function with sig `string => string` to transform
* reference sequence names for the purpose of indexing and querying. note that the data that is returned is
* not altered, just the names of the reference sequences that are used for querying.
*
* @param {number} [args.yieldTime] yield to main thread after N milliseconds
* if reading features is taking a long time to avoid hanging main thread
*
* @param {function} [args.renameRefSeqs] optional function with sig `string
* => string` to transform reference sequence names for the purpose of
* indexing and querying. note that the data that is returned is not altered,
* just the names of the reference sequences that are used for querying.
*/
constructor({
path,
Expand All @@ -62,7 +71,6 @@ export default class TabixIndexedFile {
csiUrl,
csiFilehandle,
yieldTime = 500,
chunkSizeLimit = 50000000,
renameRefSeqs = n => n,
chunkCacheSize = 5 * 2 ** 20,
}: {
Expand All @@ -76,7 +84,6 @@ export default class TabixIndexedFile {
csiUrl?: string
csiFilehandle?: GenericFilehandle
yieldTime?: number
chunkSizeLimit?: number
renameRefSeqs?: (n: string) => string
chunkCacheSize?: number
}) {
Expand Down Expand Up @@ -133,7 +140,6 @@ export default class TabixIndexedFile {
)
}

this.chunkSizeLimit = chunkSizeLimit
this.renameRefSeq = renameRefSeqs
this.yieldTime = yieldTime
this.chunkCache = new AbortablePromiseCache<Chunk, ReadChunk>({
Expand All @@ -145,10 +151,16 @@ export default class TabixIndexedFile {

/**
* @param refName name of the reference sequence
*
* @param start start of the region (in 0-based half-open coordinates)
*
* @param end end of the region (in 0-based half-open coordinates)
* @param opts callback called for each line in the region. can also pass a object param containing obj.lineCallback, obj.signal, etc
* @returns promise that is resolved when the whole read is finished, rejected on error
*
* @param opts callback called for each line in the region. can also pass a
* object param containing obj.lineCallback, obj.signal, etc
*
* @returns promise that is resolved when the whole read is finished,
* rejected on error
*/
async getLines(
refName: string,
Expand All @@ -159,22 +171,14 @@ export default class TabixIndexedFile {
let signal: AbortSignal | undefined
let options: Options = {}
let callback: (line: string, lineOffset: number) => void
if (opts === undefined) {
throw new TypeError('line callback must be provided')
}

if (typeof opts === 'function') {
callback = opts
} else {
options = opts
callback = opts.lineCallback
signal = opts.signal
}
if (refName === undefined) {
throw new TypeError('must provide a reference sequence name')
}
if (!callback) {
throw new TypeError('line callback must be provided')
}

const metadata = await this.index.getMetadata(options)
checkAbortSignal(signal)
Expand All @@ -192,17 +196,6 @@ export default class TabixIndexedFile {
const chunks = await this.index.blocksForRange(refName, start, end, options)
checkAbortSignal(signal)

// check the chunks for any that are over the size limit. if
// any are, don't fetch any of them
for (const chunk of chunks) {
const size = chunk.fetchedSize()
if (size > this.chunkSizeLimit) {
throw new Error(
`Too much data. Chunk size ${size.toLocaleString()} bytes exceeds chunkSizeLimit of ${this.chunkSizeLimit.toLocaleString()}.`,
)
}
}

// now go through each chunk and parse and filter the lines out of it
let last = Date.now()
for (const c of chunks) {
Expand All @@ -224,8 +217,9 @@ export default class TabixIndexedFile {
const b = buffer.slice(blockStart, n)
const line = decoder?.decode(b) ?? b.toString()

// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (dpositions) {
while (blockStart + c.minv.dataPosition >= dpositions[pos++]) {}
while (blockStart + c.minv.dataPosition >= dpositions[pos++]!) {}
pos--
}

Expand Down Expand Up @@ -262,8 +256,8 @@ export default class TabixIndexedFile {
// then the blockStart-dpositions is an uncompressed file offset from
// that bgzip block boundary, and since the cpositions are multiplied by
// (1 << 8) these uncompressed offsets get a unique space
cpositions[pos] * (1 << 8) +
(blockStart - dpositions[pos]) +
cpositions[pos]! * (1 << 8) +
(blockStart - dpositions[pos]!) +
c.minv.dataPosition +
1,
)
Expand All @@ -290,14 +284,15 @@ export default class TabixIndexedFile {
}

/**
* get a buffer containing the "header" region of
* the file, which are the bytes up to the first
* non-meta line
* get a buffer containing the "header" region of the file, which are the
* bytes up to the first non-meta line
*/
async getHeaderBuffer(opts: Options = {}) {
const { firstDataLine, metaChar, maxBlockSize } =
await this.getMetadata(opts)
checkAbortSignal(opts.signal)

// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
const maxFetch = (firstDataLine?.blockPosition || 0) + maxBlockSize
// TODO: what if we don't have a firstDataLine, and the header
// actually takes up more than one block? this case is not covered here
Expand Down Expand Up @@ -325,8 +320,8 @@ export default class TabixIndexedFile {
}

/**
* get a string containing the "header" region of the
* file, is the portion up to the first non-meta line
* get a string containing the "header" region of the file, is the portion up
* to the first non-meta line
*
* @returns {Promise} for a string
*/
Expand All @@ -336,22 +331,26 @@ export default class TabixIndexedFile {
}

/**
* get an array of reference sequence names, in the order in which
* they occur in the file. reference sequence renaming is not applied
* to these names.
* get an array of reference sequence names, in the order in which they occur
* in the file. reference sequence renaming is not applied to these names.
*/
async getReferenceSequenceNames(opts: Options = {}) {
const metadata = await this.getMetadata(opts)
return metadata.refIdToName
}

/**
* @param {object} metadata metadata object from the parsed index,
* containing columnNumbers, metaChar, and format
* @param {object} metadata metadata object from the parsed index, containing
* columnNumbers, metaChar, and format
*
* @param {string} regionRefName
*
* @param {number} regionStart region start coordinate (0-based-half-open)
*
* @param {number} regionEnd region end coordinate (0-based-half-open)
*
* @param {array[string]} line
*
* @returns {object} like `{startCoordinate, overlaps}`. overlaps is boolean,
* true if line is a data line that overlaps the given region
*/
Expand Down Expand Up @@ -384,9 +383,9 @@ export default class TabixIndexedFile {
}
const maxColumn = Math.max(ref, start, end)

// this code is kind of complex, but it is fairly fast.
// basically, we want to avoid doing a split, because if the lines are really long
// that could lead to us allocating a bunch of extra memory, which is slow
// this code is kind of complex, but it is fairly fast. basically, we want
// to avoid doing a split, because if the lines are really long that could
// lead to us allocating a bunch of extra memory, which is slow

let currentColumnNumber = 1 // cols are numbered starting at 1 in the index metadata
let currentColumnStart = 0
Expand Down Expand Up @@ -470,8 +469,11 @@ export default class TabixIndexedFile {
}

/**
* return the approximate number of data lines in the given reference sequence
* return the approximate number of data lines in the given reference
* sequence
*
* @param refSeq reference sequence name
*
* @returns number of data lines present on that reference sequence
*/
async lineCount(refName: string, opts: Options = {}) {
Expand All @@ -496,8 +498,8 @@ export default class TabixIndexedFile {
* contiguous bgzip blocks) of the file
*/
async readChunk(c: Chunk, opts: Options = {}) {
// fetch the uncompressed data, uncompress carefully a block at a time,
// and stop when done
// fetch the uncompressed data, uncompress carefully a block at a time, and
// stop when done

const data = await this._readRegion(
c.minv.blockPosition,
Expand Down
Loading

0 comments on commit bbe60de

Please sign in to comment.