ipull
Version:
The only file downloader you'll ever need. For node.js and the browser, CLI and library for fast and reliable file downloads.
60 lines • 2.49 kB
JavaScript
export default class SmartChunkSplit {
_callback;
_options;
_lastChunkSize;
_bytesWriteLocation;
_chunks = [];
_closed = false;
constructor(_callback, _options) {
this._options = _options;
this._callback = _callback;
this._bytesWriteLocation = _options.startChunk * _options.chunkSize;
this._lastChunkSize = _options.lastChunkEndsFile ?
this.calcLastChunkSize() : this._options.chunkSize;
}
calcLastChunkSize() {
return this._options.totalSize - Math.max(this._options.endChunk - 1, 0) * this._options.chunkSize;
}
addChunk(data) {
this._chunks.push(data);
this._sendChunk();
}
get savedLength() {
return this._chunks.reduce((acc, chunk) => acc + chunk.length, 0);
}
closeAndSendLeftoversIfLengthIsUnknown() {
if (this._chunks.length > 0 && this._options.endChunk === Infinity) {
this._callback(this._chunks, this._bytesWriteLocation, this._options.startChunk++);
}
this._closed = true;
}
_sendChunk() {
if (this._closed)
return;
const checkThreshold = () => (this._options.endChunk - this._options.startChunk === 1 ?
this._lastChunkSize : this._options.chunkSize);
let calcChunkThreshold = 0;
while (this.savedLength >= (calcChunkThreshold = checkThreshold())) {
let sendLength = 0;
for (let i = 0; i < this._chunks.length; i++) {
const currentChunk = this._chunks[i];
sendLength += currentChunk.length;
if (sendLength >= calcChunkThreshold) {
const sendChunks = this._chunks.splice(0, i + 1);
const diffLength = sendLength - calcChunkThreshold;
if (diffLength > 0) {
const lastChunkEnd = currentChunk.length - diffLength;
const lastChunk = currentChunk.subarray(0, lastChunkEnd);
sendChunks.pop();
sendChunks.push(lastChunk);
this._chunks.unshift(currentChunk.subarray(lastChunkEnd));
}
this._callback(sendChunks, this._bytesWriteLocation, this._options.startChunk++);
this._bytesWriteLocation += calcChunkThreshold;
break;
}
}
}
}
}
//# sourceMappingURL=smart-chunk-split.js.map