/**
 * Chunked Builder (Browser Compatible)
 *
 * Browser-compatible version that uses Uint8Array instead of Buffer.
 * This file provides the same API but works in browser environments.
 */
import { textEncoder } from "./shared.js";
/**
 * Efficient builder for accumulating and consolidating string chunks
 * Browser-compatible version
 */
export class ChunkedBuilder {
    constructor(options = {}) {
        this._pieces = [];
        this._chunks = [];
        this._totalLength = 0;
        this._chunkSize = options.chunkSize ?? 10000;
    }
    /**
     * Add a piece to the builder
     */
    push(piece) {
        this._pieces.push(piece);
        this._totalLength += piece.length;
        if (this._pieces.length >= this._chunkSize) {
            this._consolidate();
        }
    }
    /**
     * Add multiple pieces
     */
    pushAll(pieces) {
        const len = pieces.length;
        for (let i = 0; i < len; i++) {
            this._pieces.push(pieces[i]);
            this._totalLength += pieces[i].length;
        }
        if (this._pieces.length >= this._chunkSize) {
            this._consolidate();
        }
    }
    /**
     * Consolidate pieces into chunks
     */
    _consolidate() {
        if (this._pieces.length > 0) {
            this._chunks.push(this._pieces.join(""));
            this._pieces.length = 0;
        }
    }
    /**
     * Get current cursor position (useful for tracking changes)
     */
    get cursor() {
        return this._chunks.length * this._chunkSize + this._pieces.length;
    }
    /**
     * Get total piece/chunk count
     */
    get length() {
        return this._pieces.length + this._chunks.length;
    }
    /**
     * Get total string length (character count)
     */
    get stringLength() {
        return this._totalLength;
    }
    /**
     * Check if empty
     */
    get isEmpty() {
        return this._pieces.length === 0 && this._chunks.length === 0;
    }
    /**
     * Clear all content
     */
    clear() {
        this._pieces.length = 0;
        this._chunks.length = 0;
        this._totalLength = 0;
    }
    /**
     * Build final string
     */
    toString() {
        const chunksLen = this._chunks.length;
        const piecesLen = this._pieces.length;
        // Fast path: only pieces, no chunks
        if (chunksLen === 0) {
            if (piecesLen === 0) {
                return "";
            }
            if (piecesLen === 1) {
                return this._pieces[0];
            }
            return this._pieces.join("");
        }
        // Has chunks - consolidate and join
        if (piecesLen > 0) {
            this._chunks.push(this._pieces.join(""));
            this._pieces.length = 0;
        }
        if (this._chunks.length === 1) {
            return this._chunks[0];
        }
        return this._chunks.join("");
    }
    /**
     * Convert to Uint8Array (browser-compatible)
     */
    toUint8Array() {
        return textEncoder.encode(this.toString());
    }
}
/**
 * Chunked builder with rollback/commit support
 * Browser-compatible version
 */
export class TransactionalChunkedBuilder extends ChunkedBuilder {
    constructor() {
        super(...arguments);
        this._snapshots = [];
    }
    /**
     * Create a rollback point
     */
    snapshot() {
        const snap = {
            piecesLength: this._pieces.length,
            chunksLength: this._chunks.length,
            totalLength: this._totalLength
        };
        this._snapshots.push(snap);
        return snap;
    }
    /**
     * Commit the current snapshot (remove rollback point)
     */
    commit() {
        this._snapshots.pop();
    }
    /**
     * Rollback to the last snapshot
     */
    rollback() {
        const snap = this._snapshots.pop();
        if (!snap) {
            throw new Error("No snapshot to rollback to");
        }
        if (this._pieces.length > snap.piecesLength) {
            this._pieces.length = snap.piecesLength;
        }
        if (this._chunks.length > snap.chunksLength) {
            this._chunks.length = snap.chunksLength;
        }
        this._totalLength = snap.totalLength;
    }
    /**
     * Check if there are active snapshots
     */
    get hasSnapshots() {
        return this._snapshots.length > 0;
    }
}
