lib/jam.js
function jam(func, context) {
    ensureFunc(func, 'function');

    var steps = [];

    // ##### Chain resolver.

    // The resolver will execute all functions passed to the chain as soon as `nextTick`.
    // Thus jam will not works across async context where the chain is not built all at
    // once in a single event loop, which is not really a problem from my personal
    // experience.
    tick(function resolve(e) {
      var args = Array.prototype.slice.call(arguments);

      // Any errors passed to next() are (fast-)forwarded to the last function in the
      // chain skipping any functions that's left to be executed.
      if (e) return steps[steps.length - 1].apply(this, args);

      // Any parameters given to next() are passed as arguments to the next function in
      // the chain (except for errors, of course.)
      var next = steps.shift()
        , args = Array.prototype.slice.call(arguments)

      if (steps.length) {
        args.shift(); // error arg
        args.unshift(resolve); // next() function
      }

      return next.apply(this, args);
    });

    // ##### Chain context continuation.

    // Subsequent invocation of the function returned from the `jam` function simply adds
    // the given function to the chain.
    function continuable(func, context) {
      ensureFunc(func, 'function');

      if (context) { // TODO: Handle falsy things?
        func = bind(func, context);
      }

      steps.push(func);
      return continuable;
    };

    return includeHelpers(continuable(func, context));
  }
function jam(func, context) {
    ensureFunc(func, 'function');

    var steps = [];

    // ##### Chain resolver.

    // The resolver will execute all functions passed to the chain as soon as `nextTick`.
    // Thus jam will not works across async context where the chain is not built all at
    // once in a single event loop, which is not really a problem from my personal
    // experience.
    tick(function resolve(e) {
      var args = Array.prototype.slice.call(arguments);

      // Any errors passed to next() are (fast-)forwarded to the last function in the
      // chain skipping any functions that's left to be executed.
      if (e) return steps[steps.length - 1].apply(this, args);

      // Any parameters given to next() are passed as arguments to the next function in
      // the chain (except for errors, of course.)
      var next = steps.shift()
        , args = Array.prototype.slice.call(arguments)

      if (steps.length) {
        args.shift(); // error arg
        args.unshift(resolve); // next() function
      }

      return next.apply(this, args);
    });

    // ##### Chain context continuation.

    // Subsequent invocation of the function returned from the `jam` function simply adds
    // the given function to the chain.
    function continuable(func, context) {
      ensureFunc(func, 'function');

      if (context) { // TODO: Handle falsy things?
        func = bind(func, context);
      }

      steps.push(func);
      return continuable;
    };

    return includeHelpers(continuable(func, context));
  }
# JAM function Exported function starts the asynchronous call chain.