"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.batch = batch;
const _array_1 = require("./_array");
/**
 * Helper to split a large number of calls into
 * smaller batches of concurrent calls.
 * @param {Array} values Any array of values with which to invoke fn
 * @param {Function} fn The function that will be invoked with each value
 * @param {number} [batchSize=5] The number of concurrent calls to fn, defaults to 5
 * @returns {Promise<IBatch[]>}
 */
function batch(values, fn, batchSize = 5) {
    const toSerialBatchChain = (promise, batchOfValues) => {
        const executeBatch = (prevResults) => {
            const batchResults = batchOfValues.map((id) => fn(id));
            return Promise.all(batchResults).then((results) => prevResults.concat(results));
        };
        return promise.then(executeBatch);
    };
    // split values into batches of values
    const batches = (0, _array_1.splitArrayByLength)(values, batchSize);
    // batches are processed serially, however
    // all calls within a batch are concurrent
    return batches.reduce(toSerialBatchChain, Promise.resolve([]));
}
//# sourceMappingURL=batch.js.map