export const async = {
    /**
     * Attempts to run all the functions, which take callbacks. Runs the
     * callback function when they all resolve or upon the first error.
     * @param  {[]Function} fns
     * @param  {Function} callback
     */
    all(fns, callback) {
        let todo = fns.length;
        const cb = (err) => {
            if (err) {
                todo = -1;
                return callback(err);
            }

            todo--;
            if (todo === 0) {
                return callback();
            }

            return undefined;
        };

        for (let i = 0; i < fns.length && todo > 0; i++) {
            fns[i](cb);
        }
    },
    /**
     * Attempts to run all funcs and callbacks positively on the first success.
     * @param  {Function[]} fns
     * @param  {Function} callback
     */
    some(fns, callback) {
        let todo = fns.length;
        let firstFailed;
        const cb = (err, res) => {
            if (!err) {
                todo = 0;
                return callback(null, res);
            }
            if (!firstFailed) {
                firstFailed = err;
            }
            todo--;
            if (todo === 0) {
                return callback(firstFailed);
            }
            return null;
        };

        // most operations are sync, this will stop some from being run.
        for (let i = 0; i < fns.length && todo > 0; i++) {
            fns[i](cb);
        }
    },
};

/**
 * Similar to Object.assign, but stricter and about 4x faster.
 * @param  {Object} ...objects
 * @return {Object}
 */
export function assign(target) {
    for (let i = 1; i < arguments.length; i++) {
        const arg = arguments[i];
        if (!arg) continue;

        for (let k = 0, keys = Object.keys(arg); k < keys.length; k++) {
            target[keys[k]] = arg[keys[k]];
        }
    }

    return target;
}

/**
 * Simple, shallow clone of a plain object.
 * @param  {Object} obj
 * @return {Object}
 */
export function clone(obj) {
    return assign({}, obj);
}

/**
 * Escapes all RegEx control characters
 * @param  {String} obj
 * @return {String}
 */
export function escapeRegExp(str) {
    return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
}

@@ -246,34 +246,139 @@
    *
-/%0A    all(fns, callback) %7B
+ @return %7BFunction%5B%5D%7D fns%0A     */%0A    all(fns, callback) %7B%0A        if (fns.length === 0) %7B%0A            return callback();%0A        %7D
 %0A   
@@ -769,24 +769,44 @@
 ;%0A        %7D%0A
+        return fns;%0A
     %7D,%0A    /
@@ -951,24 +951,56 @@
 n%7D callback%0A
+     * @return %7BFunction%5B%5D%7D fns%0A
      */%0A    
@@ -1013,32 +1013,135 @@
 ns, callback) %7B%0A
+        if (fns.length === 0) %7B%0A            return callback(null, new Error('Empty array'));%0A        %7D%0A
         let todo
@@ -1713,24 +1713,44 @@
 ;%0A        %7D%0A
+        return fns;%0A
     %7D,%0A%7D;%0A%0A/

Handle empty arrays correctly