"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformError = exports.fromArray = exports.unique = exports.consume = exports.filter = exports.map = exports.forEach = void 0;
const noopConsume = async (src) => {
    // eslint-disable-next-line no-underscore-dangle
    for await (const _msg of src) {
        // noop, just consume
    }
};
/**
 * Similar to Array#forEach or Stream.PassThrough.
 * Allows inspection of a pipeline without mutating it.
 * Note: Pipeline will block until forEach call resolves.
 */
async function* forEach(src, fn, onError) {
    let index = 0;
    for await (const v of src) {
        try {
            await fn(v, index, src);
        }
        catch (err) {
            if (onError) {
                await onError(err, v, index);
                continue;
            }
            else {
                throw err;
            }
        }
        finally {
            index += 1;
        }
        yield v;
    }
}
exports.forEach = forEach;
/**
 * Similar to Array#map or Stream.Transform.
 */
async function* map(src, fn, onError) {
    let index = 0;
    for await (const v of src) {
        try {
            yield await fn(v, index, src);
        }
        catch (err) {
            if (onError) {
                await onError(err, v, index);
                continue;
            }
            else {
                throw err;
            }
        }
        finally {
            index += 1;
        }
    }
}
exports.map = map;
/**
 * Similar to Array#filter
 */
async function* filter(src, fn, onError) {
    let index = 0;
    for await (const v of src) {
        let ok;
        try {
            ok = await fn(v, index, src);
        }
        catch (err) {
            if (onError) {
                await onError(err, v, index);
                continue;
            }
            else {
                throw err;
            }
        }
        finally {
            index += 1;
        }
        if (ok) {
            yield v;
        }
    }
}
exports.filter = filter;
/**
 * Start consuming generator.
 * Takes optional forEach function.
 */
async function consume(src, fn = (v) => v, onError) {
    return noopConsume(forEach(src, fn, onError));
}
exports.consume = consume;
async function* unique(source, getIdentity) {
    const seenIdentities = new Set();
    for await (const item of source) {
        const identity = getIdentity(item);
        if (!seenIdentities.has(identity)) {
            seenIdentities.add(identity);
            yield item;
        }
    }
}
exports.unique = unique;
const fromArray = async function* (items) {
    for (const item of items) {
        yield item;
    }
};
exports.fromArray = fromArray;
const transformError = async function* (src, transformFn) {
    try {
        for await (const item of src) {
            yield item;
        }
    }
    catch (err) {
        throw await transformFn(err);
    }
};
exports.transformError = transformError;
//# sourceMappingURL=GeneratorUtils.js.map