UNPKG

apr144-bam

Version:

Parser for BAM and BAM index (bai) files

145 lines 5.44 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseNameBytes = exports.findFirstData = exports.parsePseudoBin = exports.optimizeChunks = exports.makeOpts = exports.canMergeBlocks = exports.abortBreakPoint = exports.checkAbortSignal = exports.longToNumber = exports.timeout = void 0; const long_1 = __importDefault(require("long")); function timeout(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } exports.timeout = timeout; function longToNumber(long) { if (long.greaterThan(Number.MAX_SAFE_INTEGER) || long.lessThan(Number.MIN_SAFE_INTEGER)) { throw new Error('integer overflow'); } return long.toNumber(); } exports.longToNumber = longToNumber; /** * Properly check if the given AbortSignal is aborted. * Per the standard, if the signal reads as aborted, * this function throws either a DOMException AbortError, or a regular error * with a `code` attribute set to `ERR_ABORTED`. * * For convenience, passing `undefined` is a no-op * * @param {AbortSignal} [signal] an AbortSignal, or anything with an `aborted` attribute * @returns nothing */ function checkAbortSignal(signal) { if (!signal) { return; } if (signal.aborted) { // console.log('bam aborted!') if (typeof DOMException === 'undefined') { const e = new Error('aborted'); //@ts-ignore e.code = 'ERR_ABORTED'; throw e; } else { throw new DOMException('aborted', 'AbortError'); } } } exports.checkAbortSignal = checkAbortSignal; /** * Skips to the next tick, then runs `checkAbortSignal`. * Await this to inside an otherwise synchronous loop to * provide a place to break when an abort signal is received. * @param {AbortSignal} signal */ function abortBreakPoint(signal) { return __awaiter(this, void 0, void 0, function* () { yield Promise.resolve(); checkAbortSignal(signal); }); } exports.abortBreakPoint = abortBreakPoint; function canMergeBlocks(chunk1, chunk2) { return (chunk2.minv.blockPosition - chunk1.maxv.blockPosition < 65000 && chunk2.maxv.blockPosition - chunk1.minv.blockPosition < 5000000); } exports.canMergeBlocks = canMergeBlocks; function makeOpts(obj = {}) { return 'aborted' in obj ? { signal: obj } : obj; } exports.makeOpts = makeOpts; function optimizeChunks(chunks, lowest) { const mergedChunks = []; let lastChunk; if (chunks.length === 0) { return chunks; } chunks.sort((c0, c1) => { const dif = c0.minv.blockPosition - c1.minv.blockPosition; return dif === 0 ? c0.minv.dataPosition - c1.minv.dataPosition : dif; }); for (const chunk of chunks) { if (!lowest || chunk.maxv.compareTo(lowest) > 0) { if (lastChunk === undefined) { mergedChunks.push(chunk); lastChunk = chunk; } else { if (canMergeBlocks(lastChunk, chunk)) { if (chunk.maxv.compareTo(lastChunk.maxv) > 0) { lastChunk.maxv = chunk.maxv; } } else { mergedChunks.push(chunk); lastChunk = chunk; } } } } return mergedChunks; } exports.optimizeChunks = optimizeChunks; function parsePseudoBin(bytes, offset) { const lineCount = longToNumber(long_1.default.fromBytesLE(Array.prototype.slice.call(bytes, offset, offset + 8), true)); return { lineCount }; } exports.parsePseudoBin = parsePseudoBin; function findFirstData(firstDataLine, virtualOffset) { return firstDataLine ? firstDataLine.compareTo(virtualOffset) > 0 ? virtualOffset : firstDataLine : virtualOffset; } exports.findFirstData = findFirstData; function parseNameBytes(namesBytes, renameRefSeq = s => s) { let currRefId = 0; let currNameStart = 0; const refIdToName = []; const refNameToId = {}; for (let i = 0; i < namesBytes.length; i += 1) { if (!namesBytes[i]) { if (currNameStart < i) { let refName = namesBytes.toString('utf8', currNameStart, i); refName = renameRefSeq(refName); refIdToName[currRefId] = refName; refNameToId[refName] = currRefId; } currNameStart = i + 1; currRefId += 1; } } return { refNameToId, refIdToName }; } exports.parseNameBytes = parseNameBytes; //# sourceMappingURL=util.js.map