myseq-vcf
Version:
Query local or remote Tabix-indexed VCFs by genomic position
105 lines (83 loc) • 2.73 kB
JavaScript
;
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/* global FileReader, fetch */
const AbstractFileReader = require('./AbstractFileReader');
class LocalFileReader extends AbstractFileReader {
constructor(file) {
super();
_defineProperty(this, "file", void 0);
_defineProperty(this, "size", void 0);
this.file = file;
this.size = file.size;
}
name() {
return this.file.name;
}
bytes(start = 0, length) {
return new Promise((resolve, reject) => {
const lengthToRead = length === undefined ? this.size - start : length;
const blob = this.file.slice(start, start + lengthToRead);
const reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = () => {
reject(reader.error);
};
reader.readAsArrayBuffer(blob);
});
}
}
class RemoteFileReader extends AbstractFileReader {
constructor(url) {
super();
_defineProperty(this, "url", void 0);
this.url = url;
}
bytes(start = 0, length) {
const options = {
method: 'GET'
};
if (start !== 0 || length !== undefined) {
// Requesting only a portion of the file
options.headers = {
Range: length !== undefined ? `bytes=${start}-${start + (length - 1)}` : `bytes=${start}-`
};
} // https://github.com/webtorrent/webtorrent/issues/1193
// Chrome will attempt to fulfill portions of a range request from the cache
// occasionally resulting a failed fetch. Automatically retry fetch once on
// an error while setting options to bypass the cache.
return new Promise((resolve, reject) => {
const wrappedFetch = (retry, addlOptions = {}) => {
fetch(this.url, { ...options,
...addlOptions
}).then(response => {
if (response.ok) {
resolve(response.arrayBuffer());
} else {
// Don't retry on HTTP error
reject(new Error('Bad response from server'));
}
}).catch(error => {
if (retry > 0) {
wrappedFetch(retry - 1, { ...addlOptions,
cache: 'reload'
});
} else {
reject(error);
}
});
};
wrappedFetch(1);
}); // return fetch(this.url, options).then((response) => {
// if (response.ok) {
// return response.arrayBuffer();
// }
// throw new Error('Bad response from server');
// });
}
}
module.exports = {
LocalFileReader,
RemoteFileReader
};