"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const stream_1 = require("stream");
class SizeChunker extends stream_1.Transform {
    constructor(options) {
        var _a, _b;
        super({ ...options, readableObjectMode: true });
        this.bytesPassed = 0;
        this.currentChunk = -1;
        this.lastEmittedChunk = undefined;
        this.chunkSize = (_a = options.chunkSize) !== null && _a !== void 0 ? _a : 10000;
        this.flushTail = (_b = options.flushTail) !== null && _b !== void 0 ? _b : false;
        this.readableObjectMode;
        this.once("end", () => {
            if (this.flushTail && (this.lastEmittedChunk !== undefined) && this.bytesPassed > 0) {
                this.emit("chunkEnd", this.currentChunk, () => { return; });
            }
        });
    }
    finishChunk(done) {
        if (this.listenerCount("chunkEnd") > 0) {
            this.emit("chunkEnd", this.currentChunk, function () {
                this.bytesPassed = 0;
                this.lastEmittedChunk = undefined;
                done();
            }.bind(this));
        }
        else {
            this.bytesPassed = 0;
            this.lastEmittedChunk = undefined;
            done();
        }
    }
    startChunk(done) {
        this.currentChunk++;
        if (this.listenerCount("chunkStart") > 0) {
            this.emit("chunkStart", this.currentChunk, done);
        }
        else {
            done();
        }
    }
    pushData(buf) {
        this.push({
            data: buf,
            id: this.currentChunk
        });
        this.bytesPassed += buf.length;
    }
    ;
    startIfNeededAndPushData(buf) {
        if (this.lastEmittedChunk != this.currentChunk) {
            this.startChunk(function () {
                this.lastEmittedChunk = this.currentChunk;
                this.pushData(buf);
            }.bind(this));
        }
        else {
            this.pushData(buf);
        }
    }
    _transform(chunk, _encoding, done) {
        const doTransform = function () {
            const bytesLeave = Math.min(chunk.length, this.chunkSize - this.bytesPassed);
            let remainder;
            if (this.bytesPassed + chunk.length < this.chunkSize) {
                this.startIfNeededAndPushData(chunk);
                done();
            }
            else {
                remainder = bytesLeave - chunk.length;
                if (remainder === 0) {
                    this.startIfNeededAndPushData(chunk);
                    this.finishChunk(done);
                }
                else {
                    this.startIfNeededAndPushData(chunk.slice(0, bytesLeave));
                    chunk = chunk.slice(bytesLeave);
                    this.finishChunk(doTransform);
                }
            }
        }.bind(this);
        doTransform();
    }
}
exports.default = SizeChunker;
//# sourceMappingURL=chunker.js.map