import * as varint from 'uint8-varint';
import { Uint8ArrayList } from 'uint8arraylist';
import { allocUnsafe } from 'uint8arrays/alloc';
import { MAX_DATA_LENGTH } from "./constants.js";
import { InvalidDataLengthError } from "./errors.js";
import { isAsyncIterable } from "./utils.js";
// Helper function to validate the chunk size against maxDataLength
function validateMaxDataLength(chunk, maxDataLength) {
    if (chunk.byteLength > maxDataLength) {
        throw new InvalidDataLengthError('Message length too long');
    }
}
const defaultEncoder = (length) => {
    const lengthLength = varint.encodingLength(length);
    const lengthBuf = allocUnsafe(lengthLength);
    varint.encode(length, lengthBuf);
    defaultEncoder.bytes = lengthLength;
    return lengthBuf;
};
defaultEncoder.bytes = 0;
export function encode(source, options) {
    options = options ?? {};
    const encodeLength = options.lengthEncoder ?? defaultEncoder;
    const maxDataLength = options?.maxDataLength ?? MAX_DATA_LENGTH;
    function* maybeYield(chunk) {
        validateMaxDataLength(chunk, maxDataLength);
        // length + data
        const length = encodeLength(chunk.byteLength);
        // yield only Uint8Arrays
        if (length instanceof Uint8Array) {
            yield length;
        }
        else {
            yield* length;
        }
        // yield only Uint8Arrays
        if (chunk instanceof Uint8Array) {
            yield chunk;
        }
        else {
            yield* chunk;
        }
    }
    if (isAsyncIterable(source)) {
        return (async function* () {
            for await (const chunk of source) {
                yield* maybeYield(chunk);
            }
        })();
    }
    return (function* () {
        for (const chunk of source) {
            yield* maybeYield(chunk);
        }
    })();
}
encode.single = (chunk, options) => {
    options = options ?? {};
    const encodeLength = options.lengthEncoder ?? defaultEncoder;
    const maxDataLength = options?.maxDataLength ?? MAX_DATA_LENGTH;
    validateMaxDataLength(chunk, maxDataLength);
    return new Uint8ArrayList(encodeLength(chunk.byteLength), chunk);
};
//# sourceMappingURL=encode.js.map