82f2b76e25
We now use webpack instead of SystemJS, effectively bundling modules into one file (plus commons chunks) for every entry point. This results in a much smaller extension size (almost half). Furthermore we use yarn/npm even for extension run-time dependencies. This relieves us from manually vendoring and building dependencies. It's also easier to understand for new developers familiar with node.
4059 lines
111 KiB
JavaScript
4059 lines
111 KiB
JavaScript
!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.when=e():"undefined"!=typeof global?global.when=e():"undefined"!=typeof self&&(self.when=e())}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
|
require('../monitor/console');
|
|
module.exports = require('./when.browserify.js');
|
|
|
|
|
|
},{"../monitor/console":30,"./when.browserify.js":2}],2:[function(require,module,exports){
|
|
var when = module.exports = require('../when');
|
|
|
|
when.callbacks = require('../callbacks');
|
|
when.cancelable = require('../cancelable');
|
|
when.delay = require('../delay');
|
|
when.fn = require('../function');
|
|
when.guard = require('../guard');
|
|
when.keys = require('../keys');
|
|
when.nodefn = when.node = require('../node');
|
|
when.parallel = require('../parallel');
|
|
when.pipeline = require('../pipeline');
|
|
when.poll = require('../poll');
|
|
when.sequence = require('../sequence');
|
|
when.timeout = require('../timeout');
|
|
|
|
},{"../callbacks":3,"../cancelable":4,"../delay":5,"../function":6,"../guard":7,"../keys":8,"../node":32,"../parallel":33,"../pipeline":34,"../poll":35,"../sequence":36,"../timeout":37,"../when":38}],3:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2013-2014 original author or authors */
|
|
|
|
/**
|
|
* Collection of helper functions for interacting with 'traditional',
|
|
* callback-taking functions using a promise interface.
|
|
*
|
|
* @author Renato Zannon
|
|
* @contributor Brian Cavalier
|
|
*/
|
|
|
|
(function(define) {
|
|
define(function(require) {
|
|
|
|
var when = require('./when');
|
|
var Promise = when.Promise;
|
|
var _liftAll = require('./lib/liftAll');
|
|
var slice = Array.prototype.slice;
|
|
|
|
var makeApply = require('./lib/apply');
|
|
var _apply = makeApply(Promise, dispatch);
|
|
|
|
return {
|
|
lift: lift,
|
|
liftAll: liftAll,
|
|
apply: apply,
|
|
call: call,
|
|
promisify: promisify
|
|
};
|
|
|
|
/**
|
|
* Takes a `traditional` callback-taking function and returns a promise for its
|
|
* result, accepting an optional array of arguments (that might be values or
|
|
* promises). It assumes that the function takes its callback and errback as
|
|
* the last two arguments. The resolution of the promise depends on whether the
|
|
* function will call its callback or its errback.
|
|
*
|
|
* @example
|
|
* var domIsLoaded = callbacks.apply($);
|
|
* domIsLoaded.then(function() {
|
|
* doMyDomStuff();
|
|
* });
|
|
*
|
|
* @example
|
|
* function existingAjaxyFunction(url, callback, errback) {
|
|
* // Complex logic you'd rather not change
|
|
* }
|
|
*
|
|
* var promise = callbacks.apply(existingAjaxyFunction, ["/movies.json"]);
|
|
*
|
|
* promise.then(function(movies) {
|
|
* // Work with movies
|
|
* }, function(reason) {
|
|
* // Handle error
|
|
* });
|
|
*
|
|
* @param {function} asyncFunction function to be called
|
|
* @param {Array} [extraAsyncArgs] array of arguments to asyncFunction
|
|
* @returns {Promise} promise for the callback value of asyncFunction
|
|
*/
|
|
function apply(asyncFunction, extraAsyncArgs) {
|
|
return _apply(asyncFunction, this, extraAsyncArgs || []);
|
|
}
|
|
|
|
/**
|
|
* Apply helper that allows specifying thisArg
|
|
* @private
|
|
*/
|
|
function dispatch(f, thisArg, args, h) {
|
|
args.push(alwaysUnary(h.resolve, h), alwaysUnary(h.reject, h));
|
|
tryCatchResolve(f, thisArg, args, h);
|
|
}
|
|
|
|
function tryCatchResolve(f, thisArg, args, resolver) {
|
|
try {
|
|
f.apply(thisArg, args);
|
|
} catch(e) {
|
|
resolver.reject(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Works as `callbacks.apply` does, with the difference that the arguments to
|
|
* the function are passed individually, instead of as an array.
|
|
*
|
|
* @example
|
|
* function sumInFiveSeconds(a, b, callback) {
|
|
* setTimeout(function() {
|
|
* callback(a + b);
|
|
* }, 5000);
|
|
* }
|
|
*
|
|
* var sumPromise = callbacks.call(sumInFiveSeconds, 5, 10);
|
|
*
|
|
* // Logs '15' 5 seconds later
|
|
* sumPromise.then(console.log);
|
|
*
|
|
* @param {function} asyncFunction function to be called
|
|
* @param {...*} args arguments that will be forwarded to the function
|
|
* @returns {Promise} promise for the callback value of asyncFunction
|
|
*/
|
|
function call(asyncFunction/*, arg1, arg2...*/) {
|
|
return _apply(asyncFunction, this, slice.call(arguments, 1));
|
|
}
|
|
|
|
/**
|
|
* Takes a 'traditional' callback/errback-taking function and returns a function
|
|
* that returns a promise instead. The resolution/rejection of the promise
|
|
* depends on whether the original function will call its callback or its
|
|
* errback.
|
|
*
|
|
* If additional arguments are passed to the `lift` call, they will be prepended
|
|
* on the calls to the original function, much like `Function.prototype.bind`.
|
|
*
|
|
* The resulting function is also "promise-aware", in the sense that, if given
|
|
* promises as arguments, it will wait for their resolution before executing.
|
|
*
|
|
* @example
|
|
* function traditionalAjax(method, url, callback, errback) {
|
|
* var xhr = new XMLHttpRequest();
|
|
* xhr.open(method, url);
|
|
*
|
|
* xhr.onload = callback;
|
|
* xhr.onerror = errback;
|
|
*
|
|
* xhr.send();
|
|
* }
|
|
*
|
|
* var promiseAjax = callbacks.lift(traditionalAjax);
|
|
* promiseAjax("GET", "/movies.json").then(console.log, console.error);
|
|
*
|
|
* var promiseAjaxGet = callbacks.lift(traditionalAjax, "GET");
|
|
* promiseAjaxGet("/movies.json").then(console.log, console.error);
|
|
*
|
|
* @param {Function} f traditional async function to be decorated
|
|
* @param {...*} [args] arguments to be prepended for the new function @deprecated
|
|
* @returns {Function} a promise-returning function
|
|
*/
|
|
function lift(f/*, args...*/) {
|
|
var args = arguments.length > 1 ? slice.call(arguments, 1) : [];
|
|
return function() {
|
|
return _apply(f, this, args.concat(slice.call(arguments)));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Lift all the functions/methods on src
|
|
* @param {object|function} src source whose functions will be lifted
|
|
* @param {function?} combine optional function for customizing the lifting
|
|
* process. It is passed dst, the lifted function, and the property name of
|
|
* the original function on src.
|
|
* @param {(object|function)?} dst option destination host onto which to place lifted
|
|
* functions. If not provided, liftAll returns a new object.
|
|
* @returns {*} If dst is provided, returns dst with lifted functions as
|
|
* properties. If dst not provided, returns a new object with lifted functions.
|
|
*/
|
|
function liftAll(src, combine, dst) {
|
|
return _liftAll(lift, combine, dst, src);
|
|
}
|
|
|
|
/**
|
|
* `promisify` is a version of `lift` that allows fine-grained control over the
|
|
* arguments that passed to the underlying function. It is intended to handle
|
|
* functions that don't follow the common callback and errback positions.
|
|
*
|
|
* The control is done by passing an object whose 'callback' and/or 'errback'
|
|
* keys, whose values are the corresponding 0-based indexes of the arguments on
|
|
* the function. Negative values are interpreted as being relative to the end
|
|
* of the arguments array.
|
|
*
|
|
* If arguments are given on the call to the 'promisified' function, they are
|
|
* intermingled with the callback and errback. If a promise is given among them,
|
|
* the execution of the function will only occur after its resolution.
|
|
*
|
|
* @example
|
|
* var delay = callbacks.promisify(setTimeout, {
|
|
* callback: 0
|
|
* });
|
|
*
|
|
* delay(100).then(function() {
|
|
* console.log("This happens 100ms afterwards");
|
|
* });
|
|
*
|
|
* @example
|
|
* function callbackAsLast(errback, followsStandards, callback) {
|
|
* if(followsStandards) {
|
|
* callback("well done!");
|
|
* } else {
|
|
* errback("some programmers just want to watch the world burn");
|
|
* }
|
|
* }
|
|
*
|
|
* var promisified = callbacks.promisify(callbackAsLast, {
|
|
* callback: -1,
|
|
* errback: 0,
|
|
* });
|
|
*
|
|
* promisified(true).then(console.log, console.error);
|
|
* promisified(false).then(console.log, console.error);
|
|
*
|
|
* @param {Function} asyncFunction traditional function to be decorated
|
|
* @param {object} positions
|
|
* @param {number} [positions.callback] index at which asyncFunction expects to
|
|
* receive a success callback
|
|
* @param {number} [positions.errback] index at which asyncFunction expects to
|
|
* receive an error callback
|
|
* @returns {function} promisified function that accepts
|
|
*
|
|
* @deprecated
|
|
*/
|
|
function promisify(asyncFunction, positions) {
|
|
|
|
return function() {
|
|
var thisArg = this;
|
|
return Promise.all(arguments).then(function(args) {
|
|
var p = Promise._defer();
|
|
|
|
var callbackPos, errbackPos;
|
|
|
|
if(typeof positions.callback === 'number') {
|
|
callbackPos = normalizePosition(args, positions.callback);
|
|
}
|
|
|
|
if(typeof positions.errback === 'number') {
|
|
errbackPos = normalizePosition(args, positions.errback);
|
|
}
|
|
|
|
if(errbackPos < callbackPos) {
|
|
insertCallback(args, errbackPos, p._handler.reject, p._handler);
|
|
insertCallback(args, callbackPos, p._handler.resolve, p._handler);
|
|
} else {
|
|
insertCallback(args, callbackPos, p._handler.resolve, p._handler);
|
|
insertCallback(args, errbackPos, p._handler.reject, p._handler);
|
|
}
|
|
|
|
asyncFunction.apply(thisArg, args);
|
|
|
|
return p;
|
|
});
|
|
};
|
|
}
|
|
|
|
function normalizePosition(args, pos) {
|
|
return pos < 0 ? (args.length + pos + 2) : pos;
|
|
}
|
|
|
|
function insertCallback(args, pos, callback, thisArg) {
|
|
if(typeof pos === 'number') {
|
|
args.splice(pos, 0, alwaysUnary(callback, thisArg));
|
|
}
|
|
}
|
|
|
|
function alwaysUnary(fn, thisArg) {
|
|
return function() {
|
|
if (arguments.length > 1) {
|
|
fn.call(thisArg, slice.call(arguments));
|
|
} else {
|
|
fn.apply(thisArg, arguments);
|
|
}
|
|
};
|
|
}
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
},{"./lib/apply":12,"./lib/liftAll":24,"./when":38}],4:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright B Cavalier & J Hann */
|
|
|
|
/**
|
|
* cancelable.js
|
|
* @deprecated
|
|
*
|
|
* Decorator that makes a deferred "cancelable". It adds a cancel() method that
|
|
* will call a special cancel handler function and then reject the deferred. The
|
|
* cancel handler can be used to do resource cleanup, or anything else that should
|
|
* be done before any other rejection handlers are executed.
|
|
*
|
|
* Usage:
|
|
*
|
|
* var cancelableDeferred = cancelable(when.defer(), myCancelHandler);
|
|
*
|
|
* @author brian@hovercraftstudios.com
|
|
*/
|
|
|
|
(function(define) {
|
|
define(function() {
|
|
|
|
/**
|
|
* Makes deferred cancelable, adding a cancel() method.
|
|
* @deprecated
|
|
*
|
|
* @param deferred {Deferred} the {@link Deferred} to make cancelable
|
|
* @param canceler {Function} cancel handler function to execute when this deferred
|
|
* is canceled. This is guaranteed to run before all other rejection handlers.
|
|
* The canceler will NOT be executed if the deferred is rejected in the standard
|
|
* way, i.e. deferred.reject(). It ONLY executes if the deferred is canceled,
|
|
* i.e. deferred.cancel()
|
|
*
|
|
* @returns deferred, with an added cancel() method.
|
|
*/
|
|
return function(deferred, canceler) {
|
|
// Add a cancel method to the deferred to reject the delegate
|
|
// with the special canceled indicator.
|
|
deferred.cancel = function() {
|
|
try {
|
|
deferred.reject(canceler(deferred));
|
|
} catch(e) {
|
|
deferred.reject(e);
|
|
}
|
|
|
|
return deferred.promise;
|
|
};
|
|
|
|
return deferred;
|
|
};
|
|
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(); });
|
|
|
|
|
|
|
|
},{}],5:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2011-2013 original author or authors */
|
|
|
|
/**
|
|
* delay.js
|
|
*
|
|
* Helper that returns a promise that resolves after a delay.
|
|
*
|
|
* @author Brian Cavalier
|
|
* @author John Hann
|
|
*/
|
|
|
|
(function(define) {
|
|
define(function(require) {
|
|
|
|
var when = require('./when');
|
|
|
|
/**
|
|
* @deprecated Use when(value).delay(ms)
|
|
*/
|
|
return function delay(msec, value) {
|
|
return when(value).delay(msec);
|
|
};
|
|
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
|
|
|
|
},{"./when":38}],6:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2013-2014 original author or authors */
|
|
|
|
/**
|
|
* Collection of helper functions for wrapping and executing 'traditional'
|
|
* synchronous functions in a promise interface.
|
|
*
|
|
* @author Brian Cavalier
|
|
* @contributor Renato Zannon
|
|
*/
|
|
|
|
(function(define) {
|
|
define(function(require) {
|
|
|
|
var when = require('./when');
|
|
var attempt = when['try'];
|
|
var _liftAll = require('./lib/liftAll');
|
|
var _apply = require('./lib/apply')(when.Promise);
|
|
var slice = Array.prototype.slice;
|
|
|
|
return {
|
|
lift: lift,
|
|
liftAll: liftAll,
|
|
call: attempt,
|
|
apply: apply,
|
|
compose: compose
|
|
};
|
|
|
|
/**
|
|
* Takes a function and an optional array of arguments (that might be promises),
|
|
* and calls the function. The return value is a promise whose resolution
|
|
* depends on the value returned by the function.
|
|
* @param {function} f function to be called
|
|
* @param {Array} [args] array of arguments to func
|
|
* @returns {Promise} promise for the return value of func
|
|
*/
|
|
function apply(f, args) {
|
|
// slice args just in case the caller passed an Arguments instance
|
|
return _apply(f, this, args == null ? [] : slice.call(args));
|
|
}
|
|
|
|
/**
|
|
* Takes a 'regular' function and returns a version of that function that
|
|
* returns a promise instead of a plain value, and handles thrown errors by
|
|
* returning a rejected promise. Also accepts a list of arguments to be
|
|
* prepended to the new function, as does Function.prototype.bind.
|
|
*
|
|
* The resulting function is promise-aware, in the sense that it accepts
|
|
* promise arguments, and waits for their resolution.
|
|
* @param {Function} f function to be bound
|
|
* @param {...*} [args] arguments to be prepended for the new function @deprecated
|
|
* @returns {Function} a promise-returning function
|
|
*/
|
|
function lift(f /*, args... */) {
|
|
var args = arguments.length > 1 ? slice.call(arguments, 1) : [];
|
|
return function() {
|
|
return _apply(f, this, args.concat(slice.call(arguments)));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Lift all the functions/methods on src
|
|
* @param {object|function} src source whose functions will be lifted
|
|
* @param {function?} combine optional function for customizing the lifting
|
|
* process. It is passed dst, the lifted function, and the property name of
|
|
* the original function on src.
|
|
* @param {(object|function)?} dst option destination host onto which to place lifted
|
|
* functions. If not provided, liftAll returns a new object.
|
|
* @returns {*} If dst is provided, returns dst with lifted functions as
|
|
* properties. If dst not provided, returns a new object with lifted functions.
|
|
*/
|
|
function liftAll(src, combine, dst) {
|
|
return _liftAll(lift, combine, dst, src);
|
|
}
|
|
|
|
/**
|
|
* Composes multiple functions by piping their return values. It is
|
|
* transparent to whether the functions return 'regular' values or promises:
|
|
* the piped argument is always a resolved value. If one of the functions
|
|
* throws or returns a rejected promise, the composed promise will be also
|
|
* rejected.
|
|
*
|
|
* The arguments (or promises to arguments) given to the returned function (if
|
|
* any), are passed directly to the first function on the 'pipeline'.
|
|
* @param {Function} f the function to which the arguments will be passed
|
|
* @param {...Function} [funcs] functions that will be composed, in order
|
|
* @returns {Function} a promise-returning composition of the functions
|
|
*/
|
|
function compose(f /*, funcs... */) {
|
|
var funcs = slice.call(arguments, 1);
|
|
|
|
return function() {
|
|
var thisArg = this;
|
|
var args = slice.call(arguments);
|
|
var firstPromise = attempt.apply(thisArg, [f].concat(args));
|
|
|
|
return when.reduce(funcs, function(arg, func) {
|
|
return func.call(thisArg, arg);
|
|
}, firstPromise);
|
|
};
|
|
}
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
|
|
|
|
},{"./lib/apply":12,"./lib/liftAll":24,"./when":38}],7:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2011-2013 original author or authors */
|
|
|
|
/**
|
|
* Generalized promise concurrency guard
|
|
* Adapted from original concept by Sakari Jokinen (Rocket Pack, Ltd.)
|
|
*
|
|
* @author Brian Cavalier
|
|
* @author John Hann
|
|
* @contributor Sakari Jokinen
|
|
*/
|
|
(function(define) {
|
|
define(function(require) {
|
|
|
|
var when = require('./when');
|
|
var slice = Array.prototype.slice;
|
|
|
|
guard.n = n;
|
|
|
|
return guard;
|
|
|
|
/**
|
|
* Creates a guarded version of f that can only be entered when the supplied
|
|
* condition allows.
|
|
* @param {function} condition represents a critical section that may only
|
|
* be entered when allowed by the condition
|
|
* @param {function} f function to guard
|
|
* @returns {function} guarded version of f
|
|
*/
|
|
function guard(condition, f) {
|
|
return function() {
|
|
var args = slice.call(arguments);
|
|
|
|
return when(condition()).withThis(this).then(function(exit) {
|
|
return when(f.apply(this, args))['finally'](exit);
|
|
});
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a condition that allows only n simultaneous executions
|
|
* of a guarded function
|
|
* @param {number} allowed number of allowed simultaneous executions
|
|
* @returns {function} condition function which returns a promise that
|
|
* fulfills when the critical section may be entered. The fulfillment
|
|
* value is a function ("notifyExit") that must be called when the critical
|
|
* section has been exited.
|
|
*/
|
|
function n(allowed) {
|
|
var count = 0;
|
|
var waiting = [];
|
|
|
|
return function enter() {
|
|
return when.promise(function(resolve) {
|
|
if(count < allowed) {
|
|
resolve(exit);
|
|
} else {
|
|
waiting.push(resolve);
|
|
}
|
|
count += 1;
|
|
});
|
|
};
|
|
|
|
function exit() {
|
|
count = Math.max(count - 1, 0);
|
|
if(waiting.length > 0) {
|
|
waiting.shift()(exit);
|
|
}
|
|
}
|
|
}
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
|
|
|
|
},{"./when":38}],8:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2011-2013 original author or authors */
|
|
|
|
/**
|
|
* Licensed under the MIT License at:
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
*
|
|
* @author Brian Cavalier
|
|
* @author John Hann
|
|
*/
|
|
(function(define) { 'use strict';
|
|
define(function(require) {
|
|
|
|
var when = require('./when');
|
|
var Promise = when.Promise;
|
|
var toPromise = when.resolve;
|
|
|
|
return {
|
|
all: when.lift(all),
|
|
map: map,
|
|
settle: settle
|
|
};
|
|
|
|
/**
|
|
* Resolve all the key-value pairs in the supplied object or promise
|
|
* for an object.
|
|
* @param {Promise|object} object or promise for object whose key-value pairs
|
|
* will be resolved
|
|
* @returns {Promise} promise for an object with the fully resolved key-value pairs
|
|
*/
|
|
function all(object) {
|
|
var p = Promise._defer();
|
|
var resolver = Promise._handler(p);
|
|
|
|
var results = {};
|
|
var keys = Object.keys(object);
|
|
var pending = keys.length;
|
|
|
|
for(var i=0, k; i<keys.length; ++i) {
|
|
k = keys[i];
|
|
Promise._handler(object[k]).fold(settleKey, k, results, resolver);
|
|
}
|
|
|
|
if(pending === 0) {
|
|
resolver.resolve(results);
|
|
}
|
|
|
|
return p;
|
|
|
|
function settleKey(k, x, resolver) {
|
|
/*jshint validthis:true*/
|
|
this[k] = x;
|
|
if(--pending === 0) {
|
|
resolver.resolve(results);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Map values in the supplied object's keys
|
|
* @param {Promise|object} object or promise for object whose key-value pairs
|
|
* will be reduced
|
|
* @param {function(value:*, key:String):*} f mapping function which may
|
|
* return either a promise or a value
|
|
* @returns {Promise} promise for an object with the mapped and fully
|
|
* resolved key-value pairs
|
|
*/
|
|
function map(object, f) {
|
|
return toPromise(object).then(function(object) {
|
|
return all(Object.keys(object).reduce(function(o, k) {
|
|
o[k] = toPromise(object[k]).fold(mapWithKey, k);
|
|
return o;
|
|
}, {}));
|
|
});
|
|
|
|
function mapWithKey(k, x) {
|
|
return f(x, k);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Resolve all key-value pairs in the supplied object and return a promise
|
|
* that will always fulfill with the outcome states of all input promises.
|
|
* @param {object} object whose key-value pairs will be settled
|
|
* @returns {Promise} promise for an object with the mapped and fully
|
|
* settled key-value pairs
|
|
*/
|
|
function settle(object) {
|
|
var keys = Object.keys(object);
|
|
var results = {};
|
|
|
|
if(keys.length === 0) {
|
|
return toPromise(results);
|
|
}
|
|
|
|
var p = Promise._defer();
|
|
var resolver = Promise._handler(p);
|
|
var promises = keys.map(function(k) { return object[k]; });
|
|
|
|
when.settle(promises).then(function(states) {
|
|
populateResults(keys, states, results, resolver);
|
|
});
|
|
|
|
return p;
|
|
}
|
|
|
|
function populateResults(keys, states, results, resolver) {
|
|
for(var i=0; i<keys.length; i++) {
|
|
results[keys[i]] = states[i];
|
|
}
|
|
resolver.resolve(results);
|
|
}
|
|
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
},{"./when":38}],9:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function (require) {
|
|
|
|
var makePromise = require('./makePromise');
|
|
var Scheduler = require('./Scheduler');
|
|
var async = require('./env').asap;
|
|
|
|
return makePromise({
|
|
scheduler: new Scheduler(async)
|
|
});
|
|
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
},{"./Scheduler":10,"./env":22,"./makePromise":25}],10:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
// Credit to Twisol (https://github.com/Twisol) for suggesting
|
|
// this type of extensible queue + trampoline approach for next-tick conflation.
|
|
|
|
/**
|
|
* Async task scheduler
|
|
* @param {function} async function to schedule a single async function
|
|
* @constructor
|
|
*/
|
|
function Scheduler(async) {
|
|
this._async = async;
|
|
this._running = false;
|
|
|
|
this._queue = this;
|
|
this._queueLen = 0;
|
|
this._afterQueue = {};
|
|
this._afterQueueLen = 0;
|
|
|
|
var self = this;
|
|
this.drain = function() {
|
|
self._drain();
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Enqueue a task
|
|
* @param {{ run:function }} task
|
|
*/
|
|
Scheduler.prototype.enqueue = function(task) {
|
|
this._queue[this._queueLen++] = task;
|
|
this.run();
|
|
};
|
|
|
|
/**
|
|
* Enqueue a task to run after the main task queue
|
|
* @param {{ run:function }} task
|
|
*/
|
|
Scheduler.prototype.afterQueue = function(task) {
|
|
this._afterQueue[this._afterQueueLen++] = task;
|
|
this.run();
|
|
};
|
|
|
|
Scheduler.prototype.run = function() {
|
|
if (!this._running) {
|
|
this._running = true;
|
|
this._async(this.drain);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Drain the handler queue entirely, and then the after queue
|
|
*/
|
|
Scheduler.prototype._drain = function() {
|
|
var i = 0;
|
|
for (; i < this._queueLen; ++i) {
|
|
this._queue[i].run();
|
|
this._queue[i] = void 0;
|
|
}
|
|
|
|
this._queueLen = 0;
|
|
this._running = false;
|
|
|
|
for (i = 0; i < this._afterQueueLen; ++i) {
|
|
this._afterQueue[i].run();
|
|
this._afterQueue[i] = void 0;
|
|
}
|
|
|
|
this._afterQueueLen = 0;
|
|
};
|
|
|
|
return Scheduler;
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
|
|
},{}],11:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
/**
|
|
* Custom error type for promises rejected by promise.timeout
|
|
* @param {string} message
|
|
* @constructor
|
|
*/
|
|
function TimeoutError (message) {
|
|
Error.call(this);
|
|
this.message = message;
|
|
this.name = TimeoutError.name;
|
|
if (typeof Error.captureStackTrace === 'function') {
|
|
Error.captureStackTrace(this, TimeoutError);
|
|
}
|
|
}
|
|
|
|
TimeoutError.prototype = Object.create(Error.prototype);
|
|
TimeoutError.prototype.constructor = TimeoutError;
|
|
|
|
return TimeoutError;
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
},{}],12:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
makeApply.tryCatchResolve = tryCatchResolve;
|
|
|
|
return makeApply;
|
|
|
|
function makeApply(Promise, call) {
|
|
if(arguments.length < 2) {
|
|
call = tryCatchResolve;
|
|
}
|
|
|
|
return apply;
|
|
|
|
function apply(f, thisArg, args) {
|
|
var p = Promise._defer();
|
|
var l = args.length;
|
|
var params = new Array(l);
|
|
callAndResolve({ f:f, thisArg:thisArg, args:args, params:params, i:l-1, call:call }, p._handler);
|
|
|
|
return p;
|
|
}
|
|
|
|
function callAndResolve(c, h) {
|
|
if(c.i < 0) {
|
|
return call(c.f, c.thisArg, c.params, h);
|
|
}
|
|
|
|
var handler = Promise._handler(c.args[c.i]);
|
|
handler.fold(callAndResolveNext, c, void 0, h);
|
|
}
|
|
|
|
function callAndResolveNext(c, x, h) {
|
|
c.params[c.i] = x;
|
|
c.i -= 1;
|
|
callAndResolve(c, h);
|
|
}
|
|
}
|
|
|
|
function tryCatchResolve(f, thisArg, args, resolver) {
|
|
try {
|
|
resolver.resolve(f.apply(thisArg, args));
|
|
} catch(e) {
|
|
resolver.reject(e);
|
|
}
|
|
}
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
|
|
|
|
|
|
},{}],13:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function(require) {
|
|
|
|
var state = require('../state');
|
|
var applier = require('../apply');
|
|
|
|
return function array(Promise) {
|
|
|
|
var applyFold = applier(Promise);
|
|
var toPromise = Promise.resolve;
|
|
var all = Promise.all;
|
|
|
|
var ar = Array.prototype.reduce;
|
|
var arr = Array.prototype.reduceRight;
|
|
var slice = Array.prototype.slice;
|
|
|
|
// Additional array combinators
|
|
|
|
Promise.any = any;
|
|
Promise.some = some;
|
|
Promise.settle = settle;
|
|
|
|
Promise.map = map;
|
|
Promise.filter = filter;
|
|
Promise.reduce = reduce;
|
|
Promise.reduceRight = reduceRight;
|
|
|
|
/**
|
|
* When this promise fulfills with an array, do
|
|
* onFulfilled.apply(void 0, array)
|
|
* @param {function} onFulfilled function to apply
|
|
* @returns {Promise} promise for the result of applying onFulfilled
|
|
*/
|
|
Promise.prototype.spread = function(onFulfilled) {
|
|
return this.then(all).then(function(array) {
|
|
return onFulfilled.apply(this, array);
|
|
});
|
|
};
|
|
|
|
return Promise;
|
|
|
|
/**
|
|
* One-winner competitive race.
|
|
* Return a promise that will fulfill when one of the promises
|
|
* in the input array fulfills, or will reject when all promises
|
|
* have rejected.
|
|
* @param {array} promises
|
|
* @returns {Promise} promise for the first fulfilled value
|
|
*/
|
|
function any(promises) {
|
|
var p = Promise._defer();
|
|
var resolver = p._handler;
|
|
var l = promises.length>>>0;
|
|
|
|
var pending = l;
|
|
var errors = [];
|
|
|
|
for (var h, x, i = 0; i < l; ++i) {
|
|
x = promises[i];
|
|
if(x === void 0 && !(i in promises)) {
|
|
--pending;
|
|
continue;
|
|
}
|
|
|
|
h = Promise._handler(x);
|
|
if(h.state() > 0) {
|
|
resolver.become(h);
|
|
Promise._visitRemaining(promises, i, h);
|
|
break;
|
|
} else {
|
|
h.visit(resolver, handleFulfill, handleReject);
|
|
}
|
|
}
|
|
|
|
if(pending === 0) {
|
|
resolver.reject(new RangeError('any(): array must not be empty'));
|
|
}
|
|
|
|
return p;
|
|
|
|
function handleFulfill(x) {
|
|
/*jshint validthis:true*/
|
|
errors = null;
|
|
this.resolve(x); // this === resolver
|
|
}
|
|
|
|
function handleReject(e) {
|
|
/*jshint validthis:true*/
|
|
if(this.resolved) { // this === resolver
|
|
return;
|
|
}
|
|
|
|
errors.push(e);
|
|
if(--pending === 0) {
|
|
this.reject(errors);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* N-winner competitive race
|
|
* Return a promise that will fulfill when n input promises have
|
|
* fulfilled, or will reject when it becomes impossible for n
|
|
* input promises to fulfill (ie when promises.length - n + 1
|
|
* have rejected)
|
|
* @param {array} promises
|
|
* @param {number} n
|
|
* @returns {Promise} promise for the earliest n fulfillment values
|
|
*
|
|
* @deprecated
|
|
*/
|
|
function some(promises, n) {
|
|
/*jshint maxcomplexity:7*/
|
|
var p = Promise._defer();
|
|
var resolver = p._handler;
|
|
|
|
var results = [];
|
|
var errors = [];
|
|
|
|
var l = promises.length>>>0;
|
|
var nFulfill = 0;
|
|
var nReject;
|
|
var x, i; // reused in both for() loops
|
|
|
|
// First pass: count actual array items
|
|
for(i=0; i<l; ++i) {
|
|
x = promises[i];
|
|
if(x === void 0 && !(i in promises)) {
|
|
continue;
|
|
}
|
|
++nFulfill;
|
|
}
|
|
|
|
// Compute actual goals
|
|
n = Math.max(n, 0);
|
|
nReject = (nFulfill - n + 1);
|
|
nFulfill = Math.min(n, nFulfill);
|
|
|
|
if(n > nFulfill) {
|
|
resolver.reject(new RangeError('some(): array must contain at least '
|
|
+ n + ' item(s), but had ' + nFulfill));
|
|
} else if(nFulfill === 0) {
|
|
resolver.resolve(results);
|
|
}
|
|
|
|
// Second pass: observe each array item, make progress toward goals
|
|
for(i=0; i<l; ++i) {
|
|
x = promises[i];
|
|
if(x === void 0 && !(i in promises)) {
|
|
continue;
|
|
}
|
|
|
|
Promise._handler(x).visit(resolver, fulfill, reject, resolver.notify);
|
|
}
|
|
|
|
return p;
|
|
|
|
function fulfill(x) {
|
|
/*jshint validthis:true*/
|
|
if(this.resolved) { // this === resolver
|
|
return;
|
|
}
|
|
|
|
results.push(x);
|
|
if(--nFulfill === 0) {
|
|
errors = null;
|
|
this.resolve(results);
|
|
}
|
|
}
|
|
|
|
function reject(e) {
|
|
/*jshint validthis:true*/
|
|
if(this.resolved) { // this === resolver
|
|
return;
|
|
}
|
|
|
|
errors.push(e);
|
|
if(--nReject === 0) {
|
|
results = null;
|
|
this.reject(errors);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply f to the value of each promise in a list of promises
|
|
* and return a new list containing the results.
|
|
* @param {array} promises
|
|
* @param {function(x:*, index:Number):*} f mapping function
|
|
* @returns {Promise}
|
|
*/
|
|
function map(promises, f) {
|
|
return Promise._traverse(f, promises);
|
|
}
|
|
|
|
/**
|
|
* Filter the provided array of promises using the provided predicate. Input may
|
|
* contain promises and values
|
|
* @param {Array} promises array of promises and values
|
|
* @param {function(x:*, index:Number):boolean} predicate filtering predicate.
|
|
* Must return truthy (or promise for truthy) for items to retain.
|
|
* @returns {Promise} promise that will fulfill with an array containing all items
|
|
* for which predicate returned truthy.
|
|
*/
|
|
function filter(promises, predicate) {
|
|
var a = slice.call(promises);
|
|
return Promise._traverse(predicate, a).then(function(keep) {
|
|
return filterSync(a, keep);
|
|
});
|
|
}
|
|
|
|
function filterSync(promises, keep) {
|
|
// Safe because we know all promises have fulfilled if we've made it this far
|
|
var l = keep.length;
|
|
var filtered = new Array(l);
|
|
for(var i=0, j=0; i<l; ++i) {
|
|
if(keep[i]) {
|
|
filtered[j++] = Promise._handler(promises[i]).value;
|
|
}
|
|
}
|
|
filtered.length = j;
|
|
return filtered;
|
|
|
|
}
|
|
|
|
/**
|
|
* Return a promise that will always fulfill with an array containing
|
|
* the outcome states of all input promises. The returned promise
|
|
* will never reject.
|
|
* @param {Array} promises
|
|
* @returns {Promise} promise for array of settled state descriptors
|
|
*/
|
|
function settle(promises) {
|
|
return all(promises.map(settleOne));
|
|
}
|
|
|
|
function settleOne(p) {
|
|
// Optimize the case where we get an already-resolved when.js promise
|
|
// by extracting its state:
|
|
var handler;
|
|
if (p instanceof Promise) {
|
|
// This is our own Promise type and we can reach its handler internals:
|
|
handler = p._handler.join();
|
|
}
|
|
if((handler && handler.state() === 0) || !handler) {
|
|
// Either still pending, or not a Promise at all:
|
|
return toPromise(p).then(state.fulfilled, state.rejected);
|
|
}
|
|
|
|
// The promise is our own, but it is already resolved. Take a shortcut.
|
|
// Since we're not actually handling the resolution, we need to disable
|
|
// rejection reporting.
|
|
handler._unreport();
|
|
return state.inspect(handler);
|
|
}
|
|
|
|
/**
|
|
* Traditional reduce function, similar to `Array.prototype.reduce()`, but
|
|
* input may contain promises and/or values, and reduceFunc
|
|
* may return either a value or a promise, *and* initialValue may
|
|
* be a promise for the starting value.
|
|
* @param {Array|Promise} promises array or promise for an array of anything,
|
|
* may contain a mix of promises and values.
|
|
* @param {function(accumulated:*, x:*, index:Number):*} f reduce function
|
|
* @returns {Promise} that will resolve to the final reduced value
|
|
*/
|
|
function reduce(promises, f /*, initialValue */) {
|
|
return arguments.length > 2 ? ar.call(promises, liftCombine(f), arguments[2])
|
|
: ar.call(promises, liftCombine(f));
|
|
}
|
|
|
|
/**
|
|
* Traditional reduce function, similar to `Array.prototype.reduceRight()`, but
|
|
* input may contain promises and/or values, and reduceFunc
|
|
* may return either a value or a promise, *and* initialValue may
|
|
* be a promise for the starting value.
|
|
* @param {Array|Promise} promises array or promise for an array of anything,
|
|
* may contain a mix of promises and values.
|
|
* @param {function(accumulated:*, x:*, index:Number):*} f reduce function
|
|
* @returns {Promise} that will resolve to the final reduced value
|
|
*/
|
|
function reduceRight(promises, f /*, initialValue */) {
|
|
return arguments.length > 2 ? arr.call(promises, liftCombine(f), arguments[2])
|
|
: arr.call(promises, liftCombine(f));
|
|
}
|
|
|
|
function liftCombine(f) {
|
|
return function(z, x, i) {
|
|
return applyFold(f, void 0, [z,x,i]);
|
|
};
|
|
}
|
|
};
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
|
|
|
|
},{"../apply":12,"../state":26}],14:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
return function flow(Promise) {
|
|
|
|
var resolve = Promise.resolve;
|
|
var reject = Promise.reject;
|
|
var origCatch = Promise.prototype['catch'];
|
|
|
|
/**
|
|
* Handle the ultimate fulfillment value or rejection reason, and assume
|
|
* responsibility for all errors. If an error propagates out of result
|
|
* or handleFatalError, it will be rethrown to the host, resulting in a
|
|
* loud stack track on most platforms and a crash on some.
|
|
* @param {function?} onResult
|
|
* @param {function?} onError
|
|
* @returns {undefined}
|
|
*/
|
|
Promise.prototype.done = function(onResult, onError) {
|
|
this._handler.visit(this._handler.receiver, onResult, onError);
|
|
};
|
|
|
|
/**
|
|
* Add Error-type and predicate matching to catch. Examples:
|
|
* promise.catch(TypeError, handleTypeError)
|
|
* .catch(predicate, handleMatchedErrors)
|
|
* .catch(handleRemainingErrors)
|
|
* @param onRejected
|
|
* @returns {*}
|
|
*/
|
|
Promise.prototype['catch'] = Promise.prototype.otherwise = function(onRejected) {
|
|
if (arguments.length < 2) {
|
|
return origCatch.call(this, onRejected);
|
|
}
|
|
|
|
if(typeof onRejected !== 'function') {
|
|
return this.ensure(rejectInvalidPredicate);
|
|
}
|
|
|
|
return origCatch.call(this, createCatchFilter(arguments[1], onRejected));
|
|
};
|
|
|
|
/**
|
|
* Wraps the provided catch handler, so that it will only be called
|
|
* if the predicate evaluates truthy
|
|
* @param {?function} handler
|
|
* @param {function} predicate
|
|
* @returns {function} conditional catch handler
|
|
*/
|
|
function createCatchFilter(handler, predicate) {
|
|
return function(e) {
|
|
return evaluatePredicate(e, predicate)
|
|
? handler.call(this, e)
|
|
: reject(e);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Ensures that onFulfilledOrRejected will be called regardless of whether
|
|
* this promise is fulfilled or rejected. onFulfilledOrRejected WILL NOT
|
|
* receive the promises' value or reason. Any returned value will be disregarded.
|
|
* onFulfilledOrRejected may throw or return a rejected promise to signal
|
|
* an additional error.
|
|
* @param {function} handler handler to be called regardless of
|
|
* fulfillment or rejection
|
|
* @returns {Promise}
|
|
*/
|
|
Promise.prototype['finally'] = Promise.prototype.ensure = function(handler) {
|
|
if(typeof handler !== 'function') {
|
|
return this;
|
|
}
|
|
|
|
return this.then(function(x) {
|
|
return runSideEffect(handler, this, identity, x);
|
|
}, function(e) {
|
|
return runSideEffect(handler, this, reject, e);
|
|
});
|
|
};
|
|
|
|
function runSideEffect (handler, thisArg, propagate, value) {
|
|
var result = handler.call(thisArg);
|
|
return maybeThenable(result)
|
|
? propagateValue(result, propagate, value)
|
|
: propagate(value);
|
|
}
|
|
|
|
function propagateValue (result, propagate, x) {
|
|
return resolve(result).then(function () {
|
|
return propagate(x);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Recover from a failure by returning a defaultValue. If defaultValue
|
|
* is a promise, it's fulfillment value will be used. If defaultValue is
|
|
* a promise that rejects, the returned promise will reject with the
|
|
* same reason.
|
|
* @param {*} defaultValue
|
|
* @returns {Promise} new promise
|
|
*/
|
|
Promise.prototype['else'] = Promise.prototype.orElse = function(defaultValue) {
|
|
return this.then(void 0, function() {
|
|
return defaultValue;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Shortcut for .then(function() { return value; })
|
|
* @param {*} value
|
|
* @return {Promise} a promise that:
|
|
* - is fulfilled if value is not a promise, or
|
|
* - if value is a promise, will fulfill with its value, or reject
|
|
* with its reason.
|
|
*/
|
|
Promise.prototype['yield'] = function(value) {
|
|
return this.then(function() {
|
|
return value;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Runs a side effect when this promise fulfills, without changing the
|
|
* fulfillment value.
|
|
* @param {function} onFulfilledSideEffect
|
|
* @returns {Promise}
|
|
*/
|
|
Promise.prototype.tap = function(onFulfilledSideEffect) {
|
|
return this.then(onFulfilledSideEffect)['yield'](this);
|
|
};
|
|
|
|
return Promise;
|
|
};
|
|
|
|
function rejectInvalidPredicate() {
|
|
throw new TypeError('catch predicate must be a function');
|
|
}
|
|
|
|
function evaluatePredicate(e, predicate) {
|
|
return isError(predicate) ? e instanceof predicate : predicate(e);
|
|
}
|
|
|
|
function isError(predicate) {
|
|
return predicate === Error
|
|
|| (predicate != null && predicate.prototype instanceof Error);
|
|
}
|
|
|
|
function maybeThenable(x) {
|
|
return (typeof x === 'object' || typeof x === 'function') && x !== null;
|
|
}
|
|
|
|
function identity(x) {
|
|
return x;
|
|
}
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
|
|
},{}],15:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
/** @author Jeff Escalante */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
return function fold(Promise) {
|
|
|
|
Promise.prototype.fold = function(f, z) {
|
|
var promise = this._beget();
|
|
|
|
this._handler.fold(function(z, x, to) {
|
|
Promise._handler(z).fold(function(x, z, to) {
|
|
to.resolve(f.call(this, z, x));
|
|
}, x, this, to);
|
|
}, z, promise._handler.receiver, promise._handler);
|
|
|
|
return promise;
|
|
};
|
|
|
|
return Promise;
|
|
};
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
|
|
},{}],16:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function(require) {
|
|
|
|
var inspect = require('../state').inspect;
|
|
|
|
return function inspection(Promise) {
|
|
|
|
Promise.prototype.inspect = function() {
|
|
return inspect(Promise._handler(this));
|
|
};
|
|
|
|
return Promise;
|
|
};
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
|
|
|
|
},{"../state":26}],17:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
return function generate(Promise) {
|
|
|
|
var resolve = Promise.resolve;
|
|
|
|
Promise.iterate = iterate;
|
|
Promise.unfold = unfold;
|
|
|
|
return Promise;
|
|
|
|
/**
|
|
* @deprecated Use github.com/cujojs/most streams and most.iterate
|
|
* Generate a (potentially infinite) stream of promised values:
|
|
* x, f(x), f(f(x)), etc. until condition(x) returns true
|
|
* @param {function} f function to generate a new x from the previous x
|
|
* @param {function} condition function that, given the current x, returns
|
|
* truthy when the iterate should stop
|
|
* @param {function} handler function to handle the value produced by f
|
|
* @param {*|Promise} x starting value, may be a promise
|
|
* @return {Promise} the result of the last call to f before
|
|
* condition returns true
|
|
*/
|
|
function iterate(f, condition, handler, x) {
|
|
return unfold(function(x) {
|
|
return [x, f(x)];
|
|
}, condition, handler, x);
|
|
}
|
|
|
|
/**
|
|
* @deprecated Use github.com/cujojs/most streams and most.unfold
|
|
* Generate a (potentially infinite) stream of promised values
|
|
* by applying handler(generator(seed)) iteratively until
|
|
* condition(seed) returns true.
|
|
* @param {function} unspool function that generates a [value, newSeed]
|
|
* given a seed.
|
|
* @param {function} condition function that, given the current seed, returns
|
|
* truthy when the unfold should stop
|
|
* @param {function} handler function to handle the value produced by unspool
|
|
* @param x {*|Promise} starting value, may be a promise
|
|
* @return {Promise} the result of the last value produced by unspool before
|
|
* condition returns true
|
|
*/
|
|
function unfold(unspool, condition, handler, x) {
|
|
return resolve(x).then(function(seed) {
|
|
return resolve(condition(seed)).then(function(done) {
|
|
return done ? seed : resolve(unspool(seed)).spread(next);
|
|
});
|
|
});
|
|
|
|
function next(item, newSeed) {
|
|
return resolve(handler(item)).then(function() {
|
|
return unfold(unspool, condition, handler, newSeed);
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
|
|
},{}],18:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
return function progress(Promise) {
|
|
|
|
/**
|
|
* @deprecated
|
|
* Register a progress handler for this promise
|
|
* @param {function} onProgress
|
|
* @returns {Promise}
|
|
*/
|
|
Promise.prototype.progress = function(onProgress) {
|
|
return this.then(void 0, void 0, onProgress);
|
|
};
|
|
|
|
return Promise;
|
|
};
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
|
|
},{}],19:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function(require) {
|
|
|
|
var env = require('../env');
|
|
var TimeoutError = require('../TimeoutError');
|
|
|
|
function setTimeout(f, ms, x, y) {
|
|
return env.setTimer(function() {
|
|
f(x, y, ms);
|
|
}, ms);
|
|
}
|
|
|
|
return function timed(Promise) {
|
|
/**
|
|
* Return a new promise whose fulfillment value is revealed only
|
|
* after ms milliseconds
|
|
* @param {number} ms milliseconds
|
|
* @returns {Promise}
|
|
*/
|
|
Promise.prototype.delay = function(ms) {
|
|
var p = this._beget();
|
|
this._handler.fold(handleDelay, ms, void 0, p._handler);
|
|
return p;
|
|
};
|
|
|
|
function handleDelay(ms, x, h) {
|
|
setTimeout(resolveDelay, ms, x, h);
|
|
}
|
|
|
|
function resolveDelay(x, h) {
|
|
h.resolve(x);
|
|
}
|
|
|
|
/**
|
|
* Return a new promise that rejects after ms milliseconds unless
|
|
* this promise fulfills earlier, in which case the returned promise
|
|
* fulfills with the same value.
|
|
* @param {number} ms milliseconds
|
|
* @param {Error|*=} reason optional rejection reason to use, defaults
|
|
* to a TimeoutError if not provided
|
|
* @returns {Promise}
|
|
*/
|
|
Promise.prototype.timeout = function(ms, reason) {
|
|
var p = this._beget();
|
|
var h = p._handler;
|
|
|
|
var t = setTimeout(onTimeout, ms, reason, p._handler);
|
|
|
|
this._handler.visit(h,
|
|
function onFulfill(x) {
|
|
env.clearTimer(t);
|
|
this.resolve(x); // this = h
|
|
},
|
|
function onReject(x) {
|
|
env.clearTimer(t);
|
|
this.reject(x); // this = h
|
|
},
|
|
h.notify);
|
|
|
|
return p;
|
|
};
|
|
|
|
function onTimeout(reason, h, ms) {
|
|
var e = typeof reason === 'undefined'
|
|
? new TimeoutError('timed out after ' + ms + 'ms')
|
|
: reason;
|
|
h.reject(e);
|
|
}
|
|
|
|
return Promise;
|
|
};
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
|
|
|
|
},{"../TimeoutError":11,"../env":22}],20:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function(require) {
|
|
|
|
var setTimer = require('../env').setTimer;
|
|
var format = require('../format');
|
|
|
|
return function unhandledRejection(Promise) {
|
|
|
|
var logError = noop;
|
|
var logInfo = noop;
|
|
var localConsole;
|
|
|
|
if(typeof console !== 'undefined') {
|
|
// Alias console to prevent things like uglify's drop_console option from
|
|
// removing console.log/error. Unhandled rejections fall into the same
|
|
// category as uncaught exceptions, and build tools shouldn't silence them.
|
|
localConsole = console;
|
|
logError = typeof localConsole.error !== 'undefined'
|
|
? function (e) { localConsole.error(e); }
|
|
: function (e) { localConsole.log(e); };
|
|
|
|
logInfo = typeof localConsole.info !== 'undefined'
|
|
? function (e) { localConsole.info(e); }
|
|
: function (e) { localConsole.log(e); };
|
|
}
|
|
|
|
Promise.onPotentiallyUnhandledRejection = function(rejection) {
|
|
enqueue(report, rejection);
|
|
};
|
|
|
|
Promise.onPotentiallyUnhandledRejectionHandled = function(rejection) {
|
|
enqueue(unreport, rejection);
|
|
};
|
|
|
|
Promise.onFatalRejection = function(rejection) {
|
|
enqueue(throwit, rejection.value);
|
|
};
|
|
|
|
var tasks = [];
|
|
var reported = [];
|
|
var running = null;
|
|
|
|
function report(r) {
|
|
if(!r.handled) {
|
|
reported.push(r);
|
|
logError('Potentially unhandled rejection [' + r.id + '] ' + format.formatError(r.value));
|
|
}
|
|
}
|
|
|
|
function unreport(r) {
|
|
var i = reported.indexOf(r);
|
|
if(i >= 0) {
|
|
reported.splice(i, 1);
|
|
logInfo('Handled previous rejection [' + r.id + '] ' + format.formatObject(r.value));
|
|
}
|
|
}
|
|
|
|
function enqueue(f, x) {
|
|
tasks.push(f, x);
|
|
if(running === null) {
|
|
running = setTimer(flush, 0);
|
|
}
|
|
}
|
|
|
|
function flush() {
|
|
running = null;
|
|
while(tasks.length > 0) {
|
|
tasks.shift()(tasks.shift());
|
|
}
|
|
}
|
|
|
|
return Promise;
|
|
};
|
|
|
|
function throwit(e) {
|
|
throw e;
|
|
}
|
|
|
|
function noop() {}
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
|
|
|
|
},{"../env":22,"../format":23}],21:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
return function addWith(Promise) {
|
|
/**
|
|
* Returns a promise whose handlers will be called with `this` set to
|
|
* the supplied receiver. Subsequent promises derived from the
|
|
* returned promise will also have their handlers called with receiver
|
|
* as `this`. Calling `with` with undefined or no arguments will return
|
|
* a promise whose handlers will again be called in the usual Promises/A+
|
|
* way (no `this`) thus safely undoing any previous `with` in the
|
|
* promise chain.
|
|
*
|
|
* WARNING: Promises returned from `with`/`withThis` are NOT Promises/A+
|
|
* compliant, specifically violating 2.2.5 (http://promisesaplus.com/#point-41)
|
|
*
|
|
* @param {object} receiver `this` value for all handlers attached to
|
|
* the returned promise.
|
|
* @returns {Promise}
|
|
*/
|
|
Promise.prototype['with'] = Promise.prototype.withThis = function(receiver) {
|
|
var p = this._beget();
|
|
var child = p._handler;
|
|
child.receiver = receiver;
|
|
this._handler.chain(child, receiver);
|
|
return p;
|
|
};
|
|
|
|
return Promise;
|
|
};
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
|
|
|
|
},{}],22:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
/*global process,document,setTimeout,clearTimeout,MutationObserver,WebKitMutationObserver*/
|
|
(function(define) { 'use strict';
|
|
define(function(require) {
|
|
/*jshint maxcomplexity:6*/
|
|
|
|
// Sniff "best" async scheduling option
|
|
// Prefer process.nextTick or MutationObserver, then check for
|
|
// setTimeout, and finally vertx, since its the only env that doesn't
|
|
// have setTimeout
|
|
|
|
var MutationObs;
|
|
var capturedSetTimeout = typeof setTimeout !== 'undefined' && setTimeout;
|
|
|
|
// Default env
|
|
var setTimer = function(f, ms) { return setTimeout(f, ms); };
|
|
var clearTimer = function(t) { return clearTimeout(t); };
|
|
var asap = function (f) { return capturedSetTimeout(f, 0); };
|
|
|
|
// Detect specific env
|
|
if (isNode()) { // Node
|
|
asap = function (f) { return process.nextTick(f); };
|
|
|
|
} else if (MutationObs = hasMutationObserver()) { // Modern browser
|
|
asap = initMutationObserver(MutationObs);
|
|
|
|
} else if (!capturedSetTimeout) { // vert.x
|
|
var vertxRequire = require;
|
|
var vertx = vertxRequire('vertx');
|
|
setTimer = function (f, ms) { return vertx.setTimer(ms, f); };
|
|
clearTimer = vertx.cancelTimer;
|
|
asap = vertx.runOnLoop || vertx.runOnContext;
|
|
}
|
|
|
|
return {
|
|
setTimer: setTimer,
|
|
clearTimer: clearTimer,
|
|
asap: asap
|
|
};
|
|
|
|
function isNode () {
|
|
return typeof process !== 'undefined' &&
|
|
Object.prototype.toString.call(process) === '[object process]';
|
|
}
|
|
|
|
function hasMutationObserver () {
|
|
return (typeof MutationObserver !== 'undefined' && MutationObserver) ||
|
|
(typeof WebKitMutationObserver !== 'undefined' && WebKitMutationObserver);
|
|
}
|
|
|
|
function initMutationObserver(MutationObserver) {
|
|
var scheduled;
|
|
var node = document.createTextNode('');
|
|
var o = new MutationObserver(run);
|
|
o.observe(node, { characterData: true });
|
|
|
|
function run() {
|
|
var f = scheduled;
|
|
scheduled = void 0;
|
|
f();
|
|
}
|
|
|
|
var i = 0;
|
|
return function (f) {
|
|
scheduled = f;
|
|
node.data = (i ^= 1);
|
|
};
|
|
}
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
|
|
|
|
},{}],23:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
return {
|
|
formatError: formatError,
|
|
formatObject: formatObject,
|
|
tryStringify: tryStringify
|
|
};
|
|
|
|
/**
|
|
* Format an error into a string. If e is an Error and has a stack property,
|
|
* it's returned. Otherwise, e is formatted using formatObject, with a
|
|
* warning added about e not being a proper Error.
|
|
* @param {*} e
|
|
* @returns {String} formatted string, suitable for output to developers
|
|
*/
|
|
function formatError(e) {
|
|
var s = typeof e === 'object' && e !== null && (e.stack || e.message) ? e.stack || e.message : formatObject(e);
|
|
return e instanceof Error ? s : s + ' (WARNING: non-Error used)';
|
|
}
|
|
|
|
/**
|
|
* Format an object, detecting "plain" objects and running them through
|
|
* JSON.stringify if possible.
|
|
* @param {Object} o
|
|
* @returns {string}
|
|
*/
|
|
function formatObject(o) {
|
|
var s = String(o);
|
|
if(s === '[object Object]' && typeof JSON !== 'undefined') {
|
|
s = tryStringify(o, s);
|
|
}
|
|
return s;
|
|
}
|
|
|
|
/**
|
|
* Try to return the result of JSON.stringify(x). If that fails, return
|
|
* defaultValue
|
|
* @param {*} x
|
|
* @param {*} defaultValue
|
|
* @returns {String|*} JSON.stringify(x) or defaultValue
|
|
*/
|
|
function tryStringify(x, defaultValue) {
|
|
try {
|
|
return JSON.stringify(x);
|
|
} catch(e) {
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
|
|
},{}],24:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
return function liftAll(liftOne, combine, dst, src) {
|
|
if(typeof combine === 'undefined') {
|
|
combine = defaultCombine;
|
|
}
|
|
|
|
return Object.keys(src).reduce(function(dst, key) {
|
|
var f = src[key];
|
|
return typeof f === 'function' ? combine(dst, liftOne(f), key) : dst;
|
|
}, typeof dst === 'undefined' ? defaultDst(src) : dst);
|
|
};
|
|
|
|
function defaultCombine(o, f, k) {
|
|
o[k] = f;
|
|
return o;
|
|
}
|
|
|
|
function defaultDst(src) {
|
|
return typeof src === 'function' ? src.bind() : Object.create(src);
|
|
}
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
|
|
},{}],25:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
return function makePromise(environment) {
|
|
|
|
var tasks = environment.scheduler;
|
|
var emitRejection = initEmitRejection();
|
|
|
|
var objectCreate = Object.create ||
|
|
function(proto) {
|
|
function Child() {}
|
|
Child.prototype = proto;
|
|
return new Child();
|
|
};
|
|
|
|
/**
|
|
* Create a promise whose fate is determined by resolver
|
|
* @constructor
|
|
* @returns {Promise} promise
|
|
* @name Promise
|
|
*/
|
|
function Promise(resolver, handler) {
|
|
this._handler = resolver === Handler ? handler : init(resolver);
|
|
}
|
|
|
|
/**
|
|
* Run the supplied resolver
|
|
* @param resolver
|
|
* @returns {Pending}
|
|
*/
|
|
function init(resolver) {
|
|
var handler = new Pending();
|
|
|
|
try {
|
|
resolver(promiseResolve, promiseReject, promiseNotify);
|
|
} catch (e) {
|
|
promiseReject(e);
|
|
}
|
|
|
|
return handler;
|
|
|
|
/**
|
|
* Transition from pre-resolution state to post-resolution state, notifying
|
|
* all listeners of the ultimate fulfillment or rejection
|
|
* @param {*} x resolution value
|
|
*/
|
|
function promiseResolve (x) {
|
|
handler.resolve(x);
|
|
}
|
|
/**
|
|
* Reject this promise with reason, which will be used verbatim
|
|
* @param {Error|*} reason rejection reason, strongly suggested
|
|
* to be an Error type
|
|
*/
|
|
function promiseReject (reason) {
|
|
handler.reject(reason);
|
|
}
|
|
|
|
/**
|
|
* @deprecated
|
|
* Issue a progress event, notifying all progress listeners
|
|
* @param {*} x progress event payload to pass to all listeners
|
|
*/
|
|
function promiseNotify (x) {
|
|
handler.notify(x);
|
|
}
|
|
}
|
|
|
|
// Creation
|
|
|
|
Promise.resolve = resolve;
|
|
Promise.reject = reject;
|
|
Promise.never = never;
|
|
|
|
Promise._defer = defer;
|
|
Promise._handler = getHandler;
|
|
|
|
/**
|
|
* Returns a trusted promise. If x is already a trusted promise, it is
|
|
* returned, otherwise returns a new trusted Promise which follows x.
|
|
* @param {*} x
|
|
* @return {Promise} promise
|
|
*/
|
|
function resolve(x) {
|
|
return isPromise(x) ? x
|
|
: new Promise(Handler, new Async(getHandler(x)));
|
|
}
|
|
|
|
/**
|
|
* Return a reject promise with x as its reason (x is used verbatim)
|
|
* @param {*} x
|
|
* @returns {Promise} rejected promise
|
|
*/
|
|
function reject(x) {
|
|
return new Promise(Handler, new Async(new Rejected(x)));
|
|
}
|
|
|
|
/**
|
|
* Return a promise that remains pending forever
|
|
* @returns {Promise} forever-pending promise.
|
|
*/
|
|
function never() {
|
|
return foreverPendingPromise; // Should be frozen
|
|
}
|
|
|
|
/**
|
|
* Creates an internal {promise, resolver} pair
|
|
* @private
|
|
* @returns {Promise}
|
|
*/
|
|
function defer() {
|
|
return new Promise(Handler, new Pending());
|
|
}
|
|
|
|
// Transformation and flow control
|
|
|
|
/**
|
|
* Transform this promise's fulfillment value, returning a new Promise
|
|
* for the transformed result. If the promise cannot be fulfilled, onRejected
|
|
* is called with the reason. onProgress *may* be called with updates toward
|
|
* this promise's fulfillment.
|
|
* @param {function=} onFulfilled fulfillment handler
|
|
* @param {function=} onRejected rejection handler
|
|
* @param {function=} onProgress @deprecated progress handler
|
|
* @return {Promise} new promise
|
|
*/
|
|
Promise.prototype.then = function(onFulfilled, onRejected, onProgress) {
|
|
var parent = this._handler;
|
|
var state = parent.join().state();
|
|
|
|
if ((typeof onFulfilled !== 'function' && state > 0) ||
|
|
(typeof onRejected !== 'function' && state < 0)) {
|
|
// Short circuit: value will not change, simply share handler
|
|
return new this.constructor(Handler, parent);
|
|
}
|
|
|
|
var p = this._beget();
|
|
var child = p._handler;
|
|
|
|
parent.chain(child, parent.receiver, onFulfilled, onRejected, onProgress);
|
|
|
|
return p;
|
|
};
|
|
|
|
/**
|
|
* If this promise cannot be fulfilled due to an error, call onRejected to
|
|
* handle the error. Shortcut for .then(undefined, onRejected)
|
|
* @param {function?} onRejected
|
|
* @return {Promise}
|
|
*/
|
|
Promise.prototype['catch'] = function(onRejected) {
|
|
return this.then(void 0, onRejected);
|
|
};
|
|
|
|
/**
|
|
* Creates a new, pending promise of the same type as this promise
|
|
* @private
|
|
* @returns {Promise}
|
|
*/
|
|
Promise.prototype._beget = function() {
|
|
return begetFrom(this._handler, this.constructor);
|
|
};
|
|
|
|
function begetFrom(parent, Promise) {
|
|
var child = new Pending(parent.receiver, parent.join().context);
|
|
return new Promise(Handler, child);
|
|
}
|
|
|
|
// Array combinators
|
|
|
|
Promise.all = all;
|
|
Promise.race = race;
|
|
Promise._traverse = traverse;
|
|
|
|
/**
|
|
* Return a promise that will fulfill when all promises in the
|
|
* input array have fulfilled, or will reject when one of the
|
|
* promises rejects.
|
|
* @param {array} promises array of promises
|
|
* @returns {Promise} promise for array of fulfillment values
|
|
*/
|
|
function all(promises) {
|
|
return traverseWith(snd, null, promises);
|
|
}
|
|
|
|
/**
|
|
* Array<Promise<X>> -> Promise<Array<f(X)>>
|
|
* @private
|
|
* @param {function} f function to apply to each promise's value
|
|
* @param {Array} promises array of promises
|
|
* @returns {Promise} promise for transformed values
|
|
*/
|
|
function traverse(f, promises) {
|
|
return traverseWith(tryCatch2, f, promises);
|
|
}
|
|
|
|
function traverseWith(tryMap, f, promises) {
|
|
var handler = typeof f === 'function' ? mapAt : settleAt;
|
|
|
|
var resolver = new Pending();
|
|
var pending = promises.length >>> 0;
|
|
var results = new Array(pending);
|
|
|
|
for (var i = 0, x; i < promises.length && !resolver.resolved; ++i) {
|
|
x = promises[i];
|
|
|
|
if (x === void 0 && !(i in promises)) {
|
|
--pending;
|
|
continue;
|
|
}
|
|
|
|
traverseAt(promises, handler, i, x, resolver);
|
|
}
|
|
|
|
if(pending === 0) {
|
|
resolver.become(new Fulfilled(results));
|
|
}
|
|
|
|
return new Promise(Handler, resolver);
|
|
|
|
function mapAt(i, x, resolver) {
|
|
if(!resolver.resolved) {
|
|
traverseAt(promises, settleAt, i, tryMap(f, x, i), resolver);
|
|
}
|
|
}
|
|
|
|
function settleAt(i, x, resolver) {
|
|
results[i] = x;
|
|
if(--pending === 0) {
|
|
resolver.become(new Fulfilled(results));
|
|
}
|
|
}
|
|
}
|
|
|
|
function traverseAt(promises, handler, i, x, resolver) {
|
|
if (maybeThenable(x)) {
|
|
var h = getHandlerMaybeThenable(x);
|
|
var s = h.state();
|
|
|
|
if (s === 0) {
|
|
h.fold(handler, i, void 0, resolver);
|
|
} else if (s > 0) {
|
|
handler(i, h.value, resolver);
|
|
} else {
|
|
resolver.become(h);
|
|
visitRemaining(promises, i+1, h);
|
|
}
|
|
} else {
|
|
handler(i, x, resolver);
|
|
}
|
|
}
|
|
|
|
Promise._visitRemaining = visitRemaining;
|
|
function visitRemaining(promises, start, handler) {
|
|
for(var i=start; i<promises.length; ++i) {
|
|
markAsHandled(getHandler(promises[i]), handler);
|
|
}
|
|
}
|
|
|
|
function markAsHandled(h, handler) {
|
|
if(h === handler) {
|
|
return;
|
|
}
|
|
|
|
var s = h.state();
|
|
if(s === 0) {
|
|
h.visit(h, void 0, h._unreport);
|
|
} else if(s < 0) {
|
|
h._unreport();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fulfill-reject competitive race. Return a promise that will settle
|
|
* to the same state as the earliest input promise to settle.
|
|
*
|
|
* WARNING: The ES6 Promise spec requires that race()ing an empty array
|
|
* must return a promise that is pending forever. This implementation
|
|
* returns a singleton forever-pending promise, the same singleton that is
|
|
* returned by Promise.never(), thus can be checked with ===
|
|
*
|
|
* @param {array} promises array of promises to race
|
|
* @returns {Promise} if input is non-empty, a promise that will settle
|
|
* to the same outcome as the earliest input promise to settle. if empty
|
|
* is empty, returns a promise that will never settle.
|
|
*/
|
|
function race(promises) {
|
|
if(typeof promises !== 'object' || promises === null) {
|
|
return reject(new TypeError('non-iterable passed to race()'));
|
|
}
|
|
|
|
// Sigh, race([]) is untestable unless we return *something*
|
|
// that is recognizable without calling .then() on it.
|
|
return promises.length === 0 ? never()
|
|
: promises.length === 1 ? resolve(promises[0])
|
|
: runRace(promises);
|
|
}
|
|
|
|
function runRace(promises) {
|
|
var resolver = new Pending();
|
|
var i, x, h;
|
|
for(i=0; i<promises.length; ++i) {
|
|
x = promises[i];
|
|
if (x === void 0 && !(i in promises)) {
|
|
continue;
|
|
}
|
|
|
|
h = getHandler(x);
|
|
if(h.state() !== 0) {
|
|
resolver.become(h);
|
|
visitRemaining(promises, i+1, h);
|
|
break;
|
|
} else {
|
|
h.visit(resolver, resolver.resolve, resolver.reject);
|
|
}
|
|
}
|
|
return new Promise(Handler, resolver);
|
|
}
|
|
|
|
// Promise internals
|
|
// Below this, everything is @private
|
|
|
|
/**
|
|
* Get an appropriate handler for x, without checking for cycles
|
|
* @param {*} x
|
|
* @returns {object} handler
|
|
*/
|
|
function getHandler(x) {
|
|
if(isPromise(x)) {
|
|
return x._handler.join();
|
|
}
|
|
return maybeThenable(x) ? getHandlerUntrusted(x) : new Fulfilled(x);
|
|
}
|
|
|
|
/**
|
|
* Get a handler for thenable x.
|
|
* NOTE: You must only call this if maybeThenable(x) == true
|
|
* @param {object|function|Promise} x
|
|
* @returns {object} handler
|
|
*/
|
|
function getHandlerMaybeThenable(x) {
|
|
return isPromise(x) ? x._handler.join() : getHandlerUntrusted(x);
|
|
}
|
|
|
|
/**
|
|
* Get a handler for potentially untrusted thenable x
|
|
* @param {*} x
|
|
* @returns {object} handler
|
|
*/
|
|
function getHandlerUntrusted(x) {
|
|
try {
|
|
var untrustedThen = x.then;
|
|
return typeof untrustedThen === 'function'
|
|
? new Thenable(untrustedThen, x)
|
|
: new Fulfilled(x);
|
|
} catch(e) {
|
|
return new Rejected(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handler for a promise that is pending forever
|
|
* @constructor
|
|
*/
|
|
function Handler() {}
|
|
|
|
Handler.prototype.when
|
|
= Handler.prototype.become
|
|
= Handler.prototype.notify // deprecated
|
|
= Handler.prototype.fail
|
|
= Handler.prototype._unreport
|
|
= Handler.prototype._report
|
|
= noop;
|
|
|
|
Handler.prototype._state = 0;
|
|
|
|
Handler.prototype.state = function() {
|
|
return this._state;
|
|
};
|
|
|
|
/**
|
|
* Recursively collapse handler chain to find the handler
|
|
* nearest to the fully resolved value.
|
|
* @returns {object} handler nearest the fully resolved value
|
|
*/
|
|
Handler.prototype.join = function() {
|
|
var h = this;
|
|
while(h.handler !== void 0) {
|
|
h = h.handler;
|
|
}
|
|
return h;
|
|
};
|
|
|
|
Handler.prototype.chain = function(to, receiver, fulfilled, rejected, progress) {
|
|
this.when({
|
|
resolver: to,
|
|
receiver: receiver,
|
|
fulfilled: fulfilled,
|
|
rejected: rejected,
|
|
progress: progress
|
|
});
|
|
};
|
|
|
|
Handler.prototype.visit = function(receiver, fulfilled, rejected, progress) {
|
|
this.chain(failIfRejected, receiver, fulfilled, rejected, progress);
|
|
};
|
|
|
|
Handler.prototype.fold = function(f, z, c, to) {
|
|
this.when(new Fold(f, z, c, to));
|
|
};
|
|
|
|
/**
|
|
* Handler that invokes fail() on any handler it becomes
|
|
* @constructor
|
|
*/
|
|
function FailIfRejected() {}
|
|
|
|
inherit(Handler, FailIfRejected);
|
|
|
|
FailIfRejected.prototype.become = function(h) {
|
|
h.fail();
|
|
};
|
|
|
|
var failIfRejected = new FailIfRejected();
|
|
|
|
/**
|
|
* Handler that manages a queue of consumers waiting on a pending promise
|
|
* @constructor
|
|
*/
|
|
function Pending(receiver, inheritedContext) {
|
|
Promise.createContext(this, inheritedContext);
|
|
|
|
this.consumers = void 0;
|
|
this.receiver = receiver;
|
|
this.handler = void 0;
|
|
this.resolved = false;
|
|
}
|
|
|
|
inherit(Handler, Pending);
|
|
|
|
Pending.prototype._state = 0;
|
|
|
|
Pending.prototype.resolve = function(x) {
|
|
this.become(getHandler(x));
|
|
};
|
|
|
|
Pending.prototype.reject = function(x) {
|
|
if(this.resolved) {
|
|
return;
|
|
}
|
|
|
|
this.become(new Rejected(x));
|
|
};
|
|
|
|
Pending.prototype.join = function() {
|
|
if (!this.resolved) {
|
|
return this;
|
|
}
|
|
|
|
var h = this;
|
|
|
|
while (h.handler !== void 0) {
|
|
h = h.handler;
|
|
if (h === this) {
|
|
return this.handler = cycle();
|
|
}
|
|
}
|
|
|
|
return h;
|
|
};
|
|
|
|
Pending.prototype.run = function() {
|
|
var q = this.consumers;
|
|
var handler = this.handler;
|
|
this.handler = this.handler.join();
|
|
this.consumers = void 0;
|
|
|
|
for (var i = 0; i < q.length; ++i) {
|
|
handler.when(q[i]);
|
|
}
|
|
};
|
|
|
|
Pending.prototype.become = function(handler) {
|
|
if(this.resolved) {
|
|
return;
|
|
}
|
|
|
|
this.resolved = true;
|
|
this.handler = handler;
|
|
if(this.consumers !== void 0) {
|
|
tasks.enqueue(this);
|
|
}
|
|
|
|
if(this.context !== void 0) {
|
|
handler._report(this.context);
|
|
}
|
|
};
|
|
|
|
Pending.prototype.when = function(continuation) {
|
|
if(this.resolved) {
|
|
tasks.enqueue(new ContinuationTask(continuation, this.handler));
|
|
} else {
|
|
if(this.consumers === void 0) {
|
|
this.consumers = [continuation];
|
|
} else {
|
|
this.consumers.push(continuation);
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @deprecated
|
|
*/
|
|
Pending.prototype.notify = function(x) {
|
|
if(!this.resolved) {
|
|
tasks.enqueue(new ProgressTask(x, this));
|
|
}
|
|
};
|
|
|
|
Pending.prototype.fail = function(context) {
|
|
var c = typeof context === 'undefined' ? this.context : context;
|
|
this.resolved && this.handler.join().fail(c);
|
|
};
|
|
|
|
Pending.prototype._report = function(context) {
|
|
this.resolved && this.handler.join()._report(context);
|
|
};
|
|
|
|
Pending.prototype._unreport = function() {
|
|
this.resolved && this.handler.join()._unreport();
|
|
};
|
|
|
|
/**
|
|
* Wrap another handler and force it into a future stack
|
|
* @param {object} handler
|
|
* @constructor
|
|
*/
|
|
function Async(handler) {
|
|
this.handler = handler;
|
|
}
|
|
|
|
inherit(Handler, Async);
|
|
|
|
Async.prototype.when = function(continuation) {
|
|
tasks.enqueue(new ContinuationTask(continuation, this));
|
|
};
|
|
|
|
Async.prototype._report = function(context) {
|
|
this.join()._report(context);
|
|
};
|
|
|
|
Async.prototype._unreport = function() {
|
|
this.join()._unreport();
|
|
};
|
|
|
|
/**
|
|
* Handler that wraps an untrusted thenable and assimilates it in a future stack
|
|
* @param {function} then
|
|
* @param {{then: function}} thenable
|
|
* @constructor
|
|
*/
|
|
function Thenable(then, thenable) {
|
|
Pending.call(this);
|
|
tasks.enqueue(new AssimilateTask(then, thenable, this));
|
|
}
|
|
|
|
inherit(Pending, Thenable);
|
|
|
|
/**
|
|
* Handler for a fulfilled promise
|
|
* @param {*} x fulfillment value
|
|
* @constructor
|
|
*/
|
|
function Fulfilled(x) {
|
|
Promise.createContext(this);
|
|
this.value = x;
|
|
}
|
|
|
|
inherit(Handler, Fulfilled);
|
|
|
|
Fulfilled.prototype._state = 1;
|
|
|
|
Fulfilled.prototype.fold = function(f, z, c, to) {
|
|
runContinuation3(f, z, this, c, to);
|
|
};
|
|
|
|
Fulfilled.prototype.when = function(cont) {
|
|
runContinuation1(cont.fulfilled, this, cont.receiver, cont.resolver);
|
|
};
|
|
|
|
var errorId = 0;
|
|
|
|
/**
|
|
* Handler for a rejected promise
|
|
* @param {*} x rejection reason
|
|
* @constructor
|
|
*/
|
|
function Rejected(x) {
|
|
Promise.createContext(this);
|
|
|
|
this.id = ++errorId;
|
|
this.value = x;
|
|
this.handled = false;
|
|
this.reported = false;
|
|
|
|
this._report();
|
|
}
|
|
|
|
inherit(Handler, Rejected);
|
|
|
|
Rejected.prototype._state = -1;
|
|
|
|
Rejected.prototype.fold = function(f, z, c, to) {
|
|
to.become(this);
|
|
};
|
|
|
|
Rejected.prototype.when = function(cont) {
|
|
if(typeof cont.rejected === 'function') {
|
|
this._unreport();
|
|
}
|
|
runContinuation1(cont.rejected, this, cont.receiver, cont.resolver);
|
|
};
|
|
|
|
Rejected.prototype._report = function(context) {
|
|
tasks.afterQueue(new ReportTask(this, context));
|
|
};
|
|
|
|
Rejected.prototype._unreport = function() {
|
|
if(this.handled) {
|
|
return;
|
|
}
|
|
this.handled = true;
|
|
tasks.afterQueue(new UnreportTask(this));
|
|
};
|
|
|
|
Rejected.prototype.fail = function(context) {
|
|
this.reported = true;
|
|
emitRejection('unhandledRejection', this);
|
|
Promise.onFatalRejection(this, context === void 0 ? this.context : context);
|
|
};
|
|
|
|
function ReportTask(rejection, context) {
|
|
this.rejection = rejection;
|
|
this.context = context;
|
|
}
|
|
|
|
ReportTask.prototype.run = function() {
|
|
if(!this.rejection.handled && !this.rejection.reported) {
|
|
this.rejection.reported = true;
|
|
emitRejection('unhandledRejection', this.rejection) ||
|
|
Promise.onPotentiallyUnhandledRejection(this.rejection, this.context);
|
|
}
|
|
};
|
|
|
|
function UnreportTask(rejection) {
|
|
this.rejection = rejection;
|
|
}
|
|
|
|
UnreportTask.prototype.run = function() {
|
|
if(this.rejection.reported) {
|
|
emitRejection('rejectionHandled', this.rejection) ||
|
|
Promise.onPotentiallyUnhandledRejectionHandled(this.rejection);
|
|
}
|
|
};
|
|
|
|
// Unhandled rejection hooks
|
|
// By default, everything is a noop
|
|
|
|
Promise.createContext
|
|
= Promise.enterContext
|
|
= Promise.exitContext
|
|
= Promise.onPotentiallyUnhandledRejection
|
|
= Promise.onPotentiallyUnhandledRejectionHandled
|
|
= Promise.onFatalRejection
|
|
= noop;
|
|
|
|
// Errors and singletons
|
|
|
|
var foreverPendingHandler = new Handler();
|
|
var foreverPendingPromise = new Promise(Handler, foreverPendingHandler);
|
|
|
|
function cycle() {
|
|
return new Rejected(new TypeError('Promise cycle'));
|
|
}
|
|
|
|
// Task runners
|
|
|
|
/**
|
|
* Run a single consumer
|
|
* @constructor
|
|
*/
|
|
function ContinuationTask(continuation, handler) {
|
|
this.continuation = continuation;
|
|
this.handler = handler;
|
|
}
|
|
|
|
ContinuationTask.prototype.run = function() {
|
|
this.handler.join().when(this.continuation);
|
|
};
|
|
|
|
/**
|
|
* Run a queue of progress handlers
|
|
* @constructor
|
|
*/
|
|
function ProgressTask(value, handler) {
|
|
this.handler = handler;
|
|
this.value = value;
|
|
}
|
|
|
|
ProgressTask.prototype.run = function() {
|
|
var q = this.handler.consumers;
|
|
if(q === void 0) {
|
|
return;
|
|
}
|
|
|
|
for (var c, i = 0; i < q.length; ++i) {
|
|
c = q[i];
|
|
runNotify(c.progress, this.value, this.handler, c.receiver, c.resolver);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Assimilate a thenable, sending it's value to resolver
|
|
* @param {function} then
|
|
* @param {object|function} thenable
|
|
* @param {object} resolver
|
|
* @constructor
|
|
*/
|
|
function AssimilateTask(then, thenable, resolver) {
|
|
this._then = then;
|
|
this.thenable = thenable;
|
|
this.resolver = resolver;
|
|
}
|
|
|
|
AssimilateTask.prototype.run = function() {
|
|
var h = this.resolver;
|
|
tryAssimilate(this._then, this.thenable, _resolve, _reject, _notify);
|
|
|
|
function _resolve(x) { h.resolve(x); }
|
|
function _reject(x) { h.reject(x); }
|
|
function _notify(x) { h.notify(x); }
|
|
};
|
|
|
|
function tryAssimilate(then, thenable, resolve, reject, notify) {
|
|
try {
|
|
then.call(thenable, resolve, reject, notify);
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fold a handler value with z
|
|
* @constructor
|
|
*/
|
|
function Fold(f, z, c, to) {
|
|
this.f = f; this.z = z; this.c = c; this.to = to;
|
|
this.resolver = failIfRejected;
|
|
this.receiver = this;
|
|
}
|
|
|
|
Fold.prototype.fulfilled = function(x) {
|
|
this.f.call(this.c, this.z, x, this.to);
|
|
};
|
|
|
|
Fold.prototype.rejected = function(x) {
|
|
this.to.reject(x);
|
|
};
|
|
|
|
Fold.prototype.progress = function(x) {
|
|
this.to.notify(x);
|
|
};
|
|
|
|
// Other helpers
|
|
|
|
/**
|
|
* @param {*} x
|
|
* @returns {boolean} true iff x is a trusted Promise
|
|
*/
|
|
function isPromise(x) {
|
|
return x instanceof Promise;
|
|
}
|
|
|
|
/**
|
|
* Test just enough to rule out primitives, in order to take faster
|
|
* paths in some code
|
|
* @param {*} x
|
|
* @returns {boolean} false iff x is guaranteed *not* to be a thenable
|
|
*/
|
|
function maybeThenable(x) {
|
|
return (typeof x === 'object' || typeof x === 'function') && x !== null;
|
|
}
|
|
|
|
function runContinuation1(f, h, receiver, next) {
|
|
if(typeof f !== 'function') {
|
|
return next.become(h);
|
|
}
|
|
|
|
Promise.enterContext(h);
|
|
tryCatchReject(f, h.value, receiver, next);
|
|
Promise.exitContext();
|
|
}
|
|
|
|
function runContinuation3(f, x, h, receiver, next) {
|
|
if(typeof f !== 'function') {
|
|
return next.become(h);
|
|
}
|
|
|
|
Promise.enterContext(h);
|
|
tryCatchReject3(f, x, h.value, receiver, next);
|
|
Promise.exitContext();
|
|
}
|
|
|
|
/**
|
|
* @deprecated
|
|
*/
|
|
function runNotify(f, x, h, receiver, next) {
|
|
if(typeof f !== 'function') {
|
|
return next.notify(x);
|
|
}
|
|
|
|
Promise.enterContext(h);
|
|
tryCatchReturn(f, x, receiver, next);
|
|
Promise.exitContext();
|
|
}
|
|
|
|
function tryCatch2(f, a, b) {
|
|
try {
|
|
return f(a, b);
|
|
} catch(e) {
|
|
return reject(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return f.call(thisArg, x), or if it throws return a rejected promise for
|
|
* the thrown exception
|
|
*/
|
|
function tryCatchReject(f, x, thisArg, next) {
|
|
try {
|
|
next.become(getHandler(f.call(thisArg, x)));
|
|
} catch(e) {
|
|
next.become(new Rejected(e));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Same as above, but includes the extra argument parameter.
|
|
*/
|
|
function tryCatchReject3(f, x, y, thisArg, next) {
|
|
try {
|
|
f.call(thisArg, x, y, next);
|
|
} catch(e) {
|
|
next.become(new Rejected(e));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @deprecated
|
|
* Return f.call(thisArg, x), or if it throws, *return* the exception
|
|
*/
|
|
function tryCatchReturn(f, x, thisArg, next) {
|
|
try {
|
|
next.notify(f.call(thisArg, x));
|
|
} catch(e) {
|
|
next.notify(e);
|
|
}
|
|
}
|
|
|
|
function inherit(Parent, Child) {
|
|
Child.prototype = objectCreate(Parent.prototype);
|
|
Child.prototype.constructor = Child;
|
|
}
|
|
|
|
function snd(x, y) {
|
|
return y;
|
|
}
|
|
|
|
function noop() {}
|
|
|
|
function hasCustomEvent() {
|
|
if(typeof CustomEvent === 'function') {
|
|
try {
|
|
var ev = new CustomEvent('unhandledRejection');
|
|
return ev instanceof CustomEvent;
|
|
} catch (ignoredException) {}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function hasInternetExplorerCustomEvent() {
|
|
if(typeof document !== 'undefined' && typeof document.createEvent === 'function') {
|
|
try {
|
|
// Try to create one event to make sure it's supported
|
|
var ev = document.createEvent('CustomEvent');
|
|
ev.initCustomEvent('eventType', false, true, {});
|
|
return true;
|
|
} catch (ignoredException) {}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function initEmitRejection() {
|
|
/*global process, self, CustomEvent*/
|
|
if(typeof process !== 'undefined' && process !== null
|
|
&& typeof process.emit === 'function') {
|
|
// Returning falsy here means to call the default
|
|
// onPotentiallyUnhandledRejection API. This is safe even in
|
|
// browserify since process.emit always returns falsy in browserify:
|
|
// https://github.com/defunctzombie/node-process/blob/master/browser.js#L40-L46
|
|
return function(type, rejection) {
|
|
return type === 'unhandledRejection'
|
|
? process.emit(type, rejection.value, rejection)
|
|
: process.emit(type, rejection);
|
|
};
|
|
} else if(typeof self !== 'undefined' && hasCustomEvent()) {
|
|
return (function (self, CustomEvent) {
|
|
return function (type, rejection) {
|
|
var ev = new CustomEvent(type, {
|
|
detail: {
|
|
reason: rejection.value,
|
|
key: rejection
|
|
},
|
|
bubbles: false,
|
|
cancelable: true
|
|
});
|
|
|
|
return !self.dispatchEvent(ev);
|
|
};
|
|
}(self, CustomEvent));
|
|
} else if(typeof self !== 'undefined' && hasInternetExplorerCustomEvent()) {
|
|
return (function(self, document) {
|
|
return function(type, rejection) {
|
|
var ev = document.createEvent('CustomEvent');
|
|
ev.initCustomEvent(type, false, true, {
|
|
reason: rejection.value,
|
|
key: rejection
|
|
});
|
|
|
|
return !self.dispatchEvent(ev);
|
|
};
|
|
}(self, document));
|
|
}
|
|
|
|
return noop;
|
|
}
|
|
|
|
return Promise;
|
|
};
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
|
|
},{}],26:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
return {
|
|
pending: toPendingState,
|
|
fulfilled: toFulfilledState,
|
|
rejected: toRejectedState,
|
|
inspect: inspect
|
|
};
|
|
|
|
function toPendingState() {
|
|
return { state: 'pending' };
|
|
}
|
|
|
|
function toRejectedState(e) {
|
|
return { state: 'rejected', reason: e };
|
|
}
|
|
|
|
function toFulfilledState(x) {
|
|
return { state: 'fulfilled', value: x };
|
|
}
|
|
|
|
function inspect(handler) {
|
|
var state = handler.state();
|
|
return state === 0 ? toPendingState()
|
|
: state > 0 ? toFulfilledState(handler.value)
|
|
: toRejectedState(handler.value);
|
|
}
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
|
|
},{}],27:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function(require) {
|
|
|
|
var PromiseMonitor = require('./monitor/PromiseMonitor');
|
|
var ConsoleReporter = require('./monitor/ConsoleReporter');
|
|
|
|
var promiseMonitor = new PromiseMonitor(new ConsoleReporter());
|
|
|
|
return function(Promise) {
|
|
return promiseMonitor.monitor(Promise);
|
|
};
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
|
|
|
|
},{"./monitor/ConsoleReporter":28,"./monitor/PromiseMonitor":29}],28:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function(require) {
|
|
|
|
var error = require('./error');
|
|
var unhandledRejectionsMsg = '[promises] Unhandled rejections: ';
|
|
var allHandledMsg = '[promises] All previously unhandled rejections have now been handled';
|
|
|
|
function ConsoleReporter() {
|
|
this._previouslyReported = false;
|
|
}
|
|
|
|
ConsoleReporter.prototype = initDefaultLogging();
|
|
|
|
ConsoleReporter.prototype.log = function(traces) {
|
|
if(traces.length === 0) {
|
|
if(this._previouslyReported) {
|
|
this._previouslyReported = false;
|
|
this.msg(allHandledMsg);
|
|
}
|
|
return;
|
|
}
|
|
|
|
this._previouslyReported = true;
|
|
this.groupStart(unhandledRejectionsMsg + traces.length);
|
|
try {
|
|
this._log(traces);
|
|
} finally {
|
|
this.groupEnd();
|
|
}
|
|
};
|
|
|
|
ConsoleReporter.prototype._log = function(traces) {
|
|
for(var i=0; i<traces.length; ++i) {
|
|
this.warn(error.format(traces[i]));
|
|
}
|
|
};
|
|
|
|
function initDefaultLogging() {
|
|
/*jshint maxcomplexity:7*/
|
|
var log, warn, groupStart, groupEnd;
|
|
|
|
if(typeof console === 'undefined') {
|
|
log = warn = consoleNotAvailable;
|
|
} else {
|
|
// Alias console to prevent things like uglify's drop_console option from
|
|
// removing console.log/error. Unhandled rejections fall into the same
|
|
// category as uncaught exceptions, and build tools shouldn't silence them.
|
|
var localConsole = console;
|
|
if(typeof localConsole.error === 'function'
|
|
&& typeof localConsole.dir === 'function') {
|
|
warn = function(s) {
|
|
localConsole.error(s);
|
|
};
|
|
|
|
log = function(s) {
|
|
localConsole.log(s);
|
|
};
|
|
|
|
if(typeof localConsole.groupCollapsed === 'function') {
|
|
groupStart = function(s) {
|
|
localConsole.groupCollapsed(s);
|
|
};
|
|
groupEnd = function() {
|
|
localConsole.groupEnd();
|
|
};
|
|
}
|
|
} else {
|
|
// IE8 has console.log and JSON, so we can make a
|
|
// reasonably useful warn() from those.
|
|
// Credit to webpro (https://github.com/webpro) for this idea
|
|
// typeof localConsole.log will return 'object' in IE8, so can't test it with === 'function'
|
|
// Since this is more of a corner case for IE8, I'm ok to check it with !== 'undefined' to reduce complexity
|
|
if (typeof localConsole.log !== 'undefined' && typeof JSON !== 'undefined') {
|
|
log = warn = function(x) {
|
|
if (typeof x !== 'string') {
|
|
try {
|
|
x = JSON.stringify(x);
|
|
} catch (e) {
|
|
}
|
|
}
|
|
localConsole.log(x);
|
|
};
|
|
} else {
|
|
log = warn = consoleNotAvailable;
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
msg: log,
|
|
warn: warn,
|
|
groupStart: groupStart || warn,
|
|
groupEnd: groupEnd || consoleNotAvailable
|
|
};
|
|
}
|
|
|
|
function consoleNotAvailable() {}
|
|
|
|
return ConsoleReporter;
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
|
|
|
|
},{"./error":31}],29:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function(require) {
|
|
|
|
var defaultStackJumpSeparator = 'from execution context:';
|
|
var defaultStackFilter = /[\s\(\/\\](node|module|timers)\.js:|when([\/\\]{1,2}(lib|monitor|es6-shim)[\/\\]{1,2}|\.js)|(new\sPromise)\b|(\b(PromiseMonitor|ConsoleReporter|Scheduler|RunHandlerTask|ProgressTask|Promise|.*Handler)\.[\w_]\w\w+\b)|\b(tryCatch\w+|getHandler\w*)\b/i;
|
|
|
|
var setTimer = require('../lib/env').setTimer;
|
|
var error = require('./error');
|
|
|
|
var executionContext = [];
|
|
|
|
function PromiseMonitor(reporter) {
|
|
this.logDelay = 0;
|
|
this.stackFilter = defaultStackFilter;
|
|
this.stackJumpSeparator = defaultStackJumpSeparator;
|
|
this.filterDuplicateFrames = true;
|
|
|
|
this._reporter = reporter;
|
|
if(typeof reporter.configurePromiseMonitor === 'function') {
|
|
reporter.configurePromiseMonitor(this);
|
|
}
|
|
|
|
this._traces = [];
|
|
this._traceTask = 0;
|
|
|
|
var self = this;
|
|
this._doLogTraces = function() {
|
|
self._logTraces();
|
|
};
|
|
}
|
|
|
|
PromiseMonitor.prototype.monitor = function(Promise) {
|
|
var self = this;
|
|
Promise.createContext = function(p, context) {
|
|
p.context = self.createContext(p, context);
|
|
};
|
|
|
|
Promise.enterContext = function(p) {
|
|
executionContext.push(p.context);
|
|
};
|
|
|
|
Promise.exitContext = function() {
|
|
executionContext.pop();
|
|
};
|
|
|
|
Promise.onPotentiallyUnhandledRejection = function(rejection, extraContext) {
|
|
return self.addTrace(rejection, extraContext);
|
|
};
|
|
|
|
Promise.onPotentiallyUnhandledRejectionHandled = function(rejection) {
|
|
return self.removeTrace(rejection);
|
|
};
|
|
|
|
Promise.onFatalRejection = function(rejection, extraContext) {
|
|
return self.fatal(rejection, extraContext);
|
|
};
|
|
|
|
return this;
|
|
};
|
|
|
|
PromiseMonitor.prototype.createContext = function(at, parentContext) {
|
|
var context = {
|
|
parent: parentContext || executionContext[executionContext.length - 1],
|
|
stack: void 0
|
|
};
|
|
error.captureStack(context, at.constructor);
|
|
return context;
|
|
};
|
|
|
|
PromiseMonitor.prototype.addTrace = function(handler, extraContext) {
|
|
var t, i;
|
|
|
|
for(i = this._traces.length-1; i >= 0; --i) {
|
|
t = this._traces[i];
|
|
if(t.handler === handler) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(i >= 0) {
|
|
t.extraContext = extraContext;
|
|
} else {
|
|
this._traces.push({
|
|
handler: handler,
|
|
extraContext: extraContext
|
|
});
|
|
}
|
|
|
|
this.logTraces();
|
|
};
|
|
|
|
PromiseMonitor.prototype.removeTrace = function(/*handler*/) {
|
|
this.logTraces();
|
|
};
|
|
|
|
PromiseMonitor.prototype.fatal = function(handler, extraContext) {
|
|
var err = new Error();
|
|
err.stack = this._createLongTrace(handler.value, handler.context, extraContext).join('\n');
|
|
setTimer(function() {
|
|
throw err;
|
|
}, 0);
|
|
};
|
|
|
|
PromiseMonitor.prototype.logTraces = function() {
|
|
if(!this._traceTask) {
|
|
this._traceTask = setTimer(this._doLogTraces, this.logDelay);
|
|
}
|
|
};
|
|
|
|
PromiseMonitor.prototype._logTraces = function() {
|
|
this._traceTask = void 0;
|
|
this._traces = this._traces.filter(filterHandled);
|
|
this._reporter.log(this.formatTraces(this._traces));
|
|
};
|
|
|
|
|
|
PromiseMonitor.prototype.formatTraces = function(traces) {
|
|
return traces.map(function(t) {
|
|
return this._createLongTrace(t.handler.value, t.handler.context, t.extraContext);
|
|
}, this);
|
|
};
|
|
|
|
PromiseMonitor.prototype._createLongTrace = function(e, context, extraContext) {
|
|
var trace = error.parse(e) || [String(e) + ' (WARNING: non-Error used)'];
|
|
trace = filterFrames(this.stackFilter, trace, 0);
|
|
this._appendContext(trace, context);
|
|
this._appendContext(trace, extraContext);
|
|
return this.filterDuplicateFrames ? this._removeDuplicates(trace) : trace;
|
|
};
|
|
|
|
PromiseMonitor.prototype._removeDuplicates = function(trace) {
|
|
var seen = {};
|
|
var sep = this.stackJumpSeparator;
|
|
var count = 0;
|
|
return trace.reduceRight(function(deduped, line, i) {
|
|
if(i === 0) {
|
|
deduped.unshift(line);
|
|
} else if(line === sep) {
|
|
if(count > 0) {
|
|
deduped.unshift(line);
|
|
count = 0;
|
|
}
|
|
} else if(!seen[line]) {
|
|
seen[line] = true;
|
|
deduped.unshift(line);
|
|
++count;
|
|
}
|
|
return deduped;
|
|
}, []);
|
|
};
|
|
|
|
PromiseMonitor.prototype._appendContext = function(trace, context) {
|
|
trace.push.apply(trace, this._createTrace(context));
|
|
};
|
|
|
|
PromiseMonitor.prototype._createTrace = function(traceChain) {
|
|
var trace = [];
|
|
var stack;
|
|
|
|
while(traceChain) {
|
|
stack = error.parse(traceChain);
|
|
|
|
if (stack) {
|
|
stack = filterFrames(this.stackFilter, stack);
|
|
appendStack(trace, stack, this.stackJumpSeparator);
|
|
}
|
|
|
|
traceChain = traceChain.parent;
|
|
}
|
|
|
|
return trace;
|
|
};
|
|
|
|
function appendStack(trace, stack, separator) {
|
|
if (stack.length > 1) {
|
|
stack[0] = separator;
|
|
trace.push.apply(trace, stack);
|
|
}
|
|
}
|
|
|
|
function filterFrames(stackFilter, stack) {
|
|
return stack.filter(function(frame) {
|
|
return !stackFilter.test(frame);
|
|
});
|
|
}
|
|
|
|
function filterHandled(t) {
|
|
return !t.handler.handled;
|
|
}
|
|
|
|
return PromiseMonitor;
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
|
|
|
|
},{"../lib/env":22,"./error":31}],30:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function(require) {
|
|
|
|
var monitor = require('../monitor');
|
|
var Promise = require('../when').Promise;
|
|
|
|
return monitor(Promise);
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
|
|
|
|
},{"../monitor":27,"../when":38}],31:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
/** @author Brian Cavalier */
|
|
/** @author John Hann */
|
|
|
|
(function(define) { 'use strict';
|
|
define(function() {
|
|
|
|
var parse, captureStack, format;
|
|
|
|
if(Error.captureStackTrace) {
|
|
// Use Error.captureStackTrace if available
|
|
parse = function(e) {
|
|
return e && e.stack && e.stack.split('\n');
|
|
};
|
|
|
|
format = formatAsString;
|
|
captureStack = Error.captureStackTrace;
|
|
|
|
} else {
|
|
// Otherwise, do minimal feature detection to determine
|
|
// how to capture and format reasonable stacks.
|
|
parse = function(e) {
|
|
var stack = e && e.stack && e.stack.split('\n');
|
|
if(stack && e.message) {
|
|
stack.unshift(e.message);
|
|
}
|
|
return stack;
|
|
};
|
|
|
|
(function() {
|
|
var e = new Error();
|
|
if(typeof e.stack !== 'string') {
|
|
format = formatAsString;
|
|
captureStack = captureSpiderMonkeyStack;
|
|
} else {
|
|
format = formatAsErrorWithStack;
|
|
captureStack = useStackDirectly;
|
|
}
|
|
}());
|
|
}
|
|
|
|
function captureSpiderMonkeyStack(host) {
|
|
try {
|
|
throw new Error();
|
|
} catch(err) {
|
|
host.stack = err.stack;
|
|
}
|
|
}
|
|
|
|
function useStackDirectly(host) {
|
|
host.stack = new Error().stack;
|
|
}
|
|
|
|
function formatAsString(longTrace) {
|
|
return join(longTrace);
|
|
}
|
|
|
|
function formatAsErrorWithStack(longTrace) {
|
|
var e = new Error();
|
|
e.stack = formatAsString(longTrace);
|
|
return e;
|
|
}
|
|
|
|
// About 5-10x faster than String.prototype.join o_O
|
|
function join(a) {
|
|
var sep = false;
|
|
var s = '';
|
|
for(var i=0; i< a.length; ++i) {
|
|
if(sep) {
|
|
s += '\n' + a[i];
|
|
} else {
|
|
s+= a[i];
|
|
sep = true;
|
|
}
|
|
}
|
|
return s;
|
|
}
|
|
|
|
return {
|
|
parse: parse,
|
|
format: format,
|
|
captureStack: captureStack
|
|
};
|
|
|
|
});
|
|
}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
|
|
|
|
},{}],32:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2013 original author or authors */
|
|
|
|
/**
|
|
* Collection of helpers for interfacing with node-style asynchronous functions
|
|
* using promises.
|
|
*
|
|
* @author Brian Cavalier
|
|
* @contributor Renato Zannon
|
|
*/
|
|
|
|
(function(define) {
|
|
define(function(require) {
|
|
|
|
var when = require('./when');
|
|
var _liftAll = require('./lib/liftAll');
|
|
var setTimer = require('./lib/env').setTimer;
|
|
var slice = Array.prototype.slice;
|
|
|
|
var _apply = require('./lib/apply')(when.Promise, dispatch);
|
|
|
|
return {
|
|
lift: lift,
|
|
liftAll: liftAll,
|
|
apply: apply,
|
|
call: call,
|
|
createCallback: createCallback,
|
|
bindCallback: bindCallback,
|
|
liftCallback: liftCallback
|
|
};
|
|
|
|
/**
|
|
* Takes a node-style async function and calls it immediately (with an optional
|
|
* array of arguments or promises for arguments). It returns a promise whose
|
|
* resolution depends on whether the async functions calls its callback with the
|
|
* conventional error argument or not.
|
|
*
|
|
* With this it becomes possible to leverage existing APIs while still reaping
|
|
* the benefits of promises.
|
|
*
|
|
* @example
|
|
* function onlySmallNumbers(n, callback) {
|
|
* if(n < 10) {
|
|
* callback(null, n + 10);
|
|
* } else {
|
|
* callback(new Error("Calculation failed"));
|
|
* }
|
|
* }
|
|
*
|
|
* var nodefn = require("when/node/function");
|
|
*
|
|
* // Logs '15'
|
|
* nodefn.apply(onlySmallNumbers, [5]).then(console.log, console.error);
|
|
*
|
|
* // Logs 'Calculation failed'
|
|
* nodefn.apply(onlySmallNumbers, [15]).then(console.log, console.error);
|
|
*
|
|
* @param {function} f node-style function that will be called
|
|
* @param {Array} [args] array of arguments to func
|
|
* @returns {Promise} promise for the value func passes to its callback
|
|
*/
|
|
function apply(f, args) {
|
|
return _apply(f, this, args || []);
|
|
}
|
|
|
|
function dispatch(f, thisArg, args, h) {
|
|
var cb = createCallback(h);
|
|
try {
|
|
switch(args.length) {
|
|
case 2: f.call(thisArg, args[0], args[1], cb); break;
|
|
case 1: f.call(thisArg, args[0], cb); break;
|
|
case 0: f.call(thisArg, cb); break;
|
|
default:
|
|
args.push(cb);
|
|
f.apply(thisArg, args);
|
|
}
|
|
} catch(e) {
|
|
h.reject(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Has the same behavior that {@link apply} has, with the difference that the
|
|
* arguments to the function are provided individually, while {@link apply} accepts
|
|
* a single array.
|
|
*
|
|
* @example
|
|
* function sumSmallNumbers(x, y, callback) {
|
|
* var result = x + y;
|
|
* if(result < 10) {
|
|
* callback(null, result);
|
|
* } else {
|
|
* callback(new Error("Calculation failed"));
|
|
* }
|
|
* }
|
|
*
|
|
* // Logs '5'
|
|
* nodefn.call(sumSmallNumbers, 2, 3).then(console.log, console.error);
|
|
*
|
|
* // Logs 'Calculation failed'
|
|
* nodefn.call(sumSmallNumbers, 5, 10).then(console.log, console.error);
|
|
*
|
|
* @param {function} f node-style function that will be called
|
|
* @param {...*} [args] arguments that will be forwarded to the function
|
|
* @returns {Promise} promise for the value func passes to its callback
|
|
*/
|
|
function call(f /*, args... */) {
|
|
return _apply(f, this, slice.call(arguments, 1));
|
|
}
|
|
|
|
/**
|
|
* Takes a node-style function and returns new function that wraps the
|
|
* original and, instead of taking a callback, returns a promise. Also, it
|
|
* knows how to handle promises given as arguments, waiting for their
|
|
* resolution before executing.
|
|
*
|
|
* Upon execution, the orginal function is executed as well. If it passes
|
|
* a truthy value as the first argument to the callback, it will be
|
|
* interpreted as an error condition, and the promise will be rejected
|
|
* with it. Otherwise, the call is considered a resolution, and the promise
|
|
* is resolved with the callback's second argument.
|
|
*
|
|
* @example
|
|
* var fs = require("fs"), nodefn = require("when/node/function");
|
|
*
|
|
* var promiseRead = nodefn.lift(fs.readFile);
|
|
*
|
|
* // The promise is resolved with the contents of the file if everything
|
|
* // goes ok
|
|
* promiseRead('exists.txt').then(console.log, console.error);
|
|
*
|
|
* // And will be rejected if something doesn't work out
|
|
* // (e.g. the files does not exist)
|
|
* promiseRead('doesnt_exist.txt').then(console.log, console.error);
|
|
*
|
|
*
|
|
* @param {Function} f node-style function to be lifted
|
|
* @param {...*} [args] arguments to be prepended for the new function @deprecated
|
|
* @returns {Function} a promise-returning function
|
|
*/
|
|
function lift(f /*, args... */) {
|
|
var args1 = arguments.length > 1 ? slice.call(arguments, 1) : [];
|
|
return function() {
|
|
// TODO: Simplify once partialing has been removed
|
|
var l = args1.length;
|
|
var al = arguments.length;
|
|
var args = new Array(al + l);
|
|
var i;
|
|
for(i=0; i<l; ++i) {
|
|
args[i] = args1[i];
|
|
}
|
|
for(i=0; i<al; ++i) {
|
|
args[i+l] = arguments[i];
|
|
}
|
|
return _apply(f, this, args);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Lift all the functions/methods on src
|
|
* @param {object|function} src source whose functions will be lifted
|
|
* @param {function?} combine optional function for customizing the lifting
|
|
* process. It is passed dst, the lifted function, and the property name of
|
|
* the original function on src.
|
|
* @param {(object|function)?} dst option destination host onto which to place lifted
|
|
* functions. If not provided, liftAll returns a new object.
|
|
* @returns {*} If dst is provided, returns dst with lifted functions as
|
|
* properties. If dst not provided, returns a new object with lifted functions.
|
|
*/
|
|
function liftAll(src, combine, dst) {
|
|
return _liftAll(lift, combine, dst, src);
|
|
}
|
|
|
|
/**
|
|
* Takes an object that responds to the resolver interface, and returns
|
|
* a function that will resolve or reject it depending on how it is called.
|
|
*
|
|
* @example
|
|
* function callbackTakingFunction(callback) {
|
|
* if(somethingWrongHappened) {
|
|
* callback(error);
|
|
* } else {
|
|
* callback(null, interestingValue);
|
|
* }
|
|
* }
|
|
*
|
|
* var when = require('when'), nodefn = require('when/node/function');
|
|
*
|
|
* var deferred = when.defer();
|
|
* callbackTakingFunction(nodefn.createCallback(deferred.resolver));
|
|
*
|
|
* deferred.promise.then(function(interestingValue) {
|
|
* // Use interestingValue
|
|
* });
|
|
*
|
|
* @param {Resolver} resolver that will be 'attached' to the callback
|
|
* @returns {Function} a node-style callback function
|
|
*/
|
|
function createCallback(resolver) {
|
|
return function(err, value) {
|
|
if(err) {
|
|
resolver.reject(err);
|
|
} else if(arguments.length > 2) {
|
|
resolver.resolve(slice.call(arguments, 1));
|
|
} else {
|
|
resolver.resolve(value);
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Attaches a node-style callback to a promise, ensuring the callback is
|
|
* called for either fulfillment or rejection. Returns a promise with the same
|
|
* state as the passed-in promise.
|
|
*
|
|
* @example
|
|
* var deferred = when.defer();
|
|
*
|
|
* function callback(err, value) {
|
|
* // Handle err or use value
|
|
* }
|
|
*
|
|
* bindCallback(deferred.promise, callback);
|
|
*
|
|
* deferred.resolve('interesting value');
|
|
*
|
|
* @param {Promise} promise The promise to be attached to.
|
|
* @param {Function} callback The node-style callback to attach.
|
|
* @returns {Promise} A promise with the same state as the passed-in promise.
|
|
*/
|
|
function bindCallback(promise, callback) {
|
|
promise = when(promise);
|
|
|
|
if (callback) {
|
|
promise.then(success, wrapped);
|
|
}
|
|
|
|
return promise;
|
|
|
|
function success(value) {
|
|
wrapped(null, value);
|
|
}
|
|
|
|
function wrapped(err, value) {
|
|
setTimer(function () {
|
|
callback(err, value);
|
|
}, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Takes a node-style callback and returns new function that accepts a
|
|
* promise, calling the original callback when the promise is either
|
|
* fulfilled or rejected with the appropriate arguments.
|
|
*
|
|
* @example
|
|
* var deferred = when.defer();
|
|
*
|
|
* function callback(err, value) {
|
|
* // Handle err or use value
|
|
* }
|
|
*
|
|
* var wrapped = liftCallback(callback);
|
|
*
|
|
* // `wrapped` can now be passed around at will
|
|
* wrapped(deferred.promise);
|
|
*
|
|
* deferred.resolve('interesting value');
|
|
*
|
|
* @param {Function} callback The node-style callback to wrap.
|
|
* @returns {Function} The lifted, promise-accepting function.
|
|
*/
|
|
function liftCallback(callback) {
|
|
return function(promise) {
|
|
return bindCallback(promise, callback);
|
|
};
|
|
}
|
|
});
|
|
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
|
|
|
|
|
|
},{"./lib/apply":12,"./lib/env":22,"./lib/liftAll":24,"./when":38}],33:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2011-2013 original author or authors */
|
|
|
|
/**
|
|
* parallel.js
|
|
*
|
|
* Run a set of task functions in parallel. All tasks will
|
|
* receive the same args
|
|
*
|
|
* @author Brian Cavalier
|
|
* @author John Hann
|
|
*/
|
|
|
|
(function(define) {
|
|
define(function(require) {
|
|
|
|
var when = require('./when');
|
|
var all = when.Promise.all;
|
|
var slice = Array.prototype.slice;
|
|
|
|
/**
|
|
* Run array of tasks in parallel
|
|
* @param tasks {Array|Promise} array or promiseForArray of task functions
|
|
* @param [args] {*} arguments to be passed to all tasks
|
|
* @return {Promise} promise for array containing the
|
|
* result of each task in the array position corresponding
|
|
* to position of the task in the tasks array
|
|
*/
|
|
return function parallel(tasks /*, args... */) {
|
|
return all(slice.call(arguments, 1)).then(function(args) {
|
|
return when.map(tasks, function(task) {
|
|
return task.apply(void 0, args);
|
|
});
|
|
});
|
|
};
|
|
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
|
|
|
|
},{"./when":38}],34:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2011-2013 original author or authors */
|
|
|
|
/**
|
|
* pipeline.js
|
|
*
|
|
* Run a set of task functions in sequence, passing the result
|
|
* of the previous as an argument to the next. Like a shell
|
|
* pipeline, e.g. `cat file.txt | grep 'foo' | sed -e 's/foo/bar/g'
|
|
*
|
|
* @author Brian Cavalier
|
|
* @author John Hann
|
|
*/
|
|
|
|
(function(define) {
|
|
define(function(require) {
|
|
|
|
var when = require('./when');
|
|
var all = when.Promise.all;
|
|
var slice = Array.prototype.slice;
|
|
|
|
/**
|
|
* Run array of tasks in a pipeline where the next
|
|
* tasks receives the result of the previous. The first task
|
|
* will receive the initialArgs as its argument list.
|
|
* @param tasks {Array|Promise} array or promise for array of task functions
|
|
* @param [initialArgs...] {*} arguments to be passed to the first task
|
|
* @return {Promise} promise for return value of the final task
|
|
*/
|
|
return function pipeline(tasks /* initialArgs... */) {
|
|
// Self-optimizing function to run first task with multiple
|
|
// args using apply, but subsequence tasks via direct invocation
|
|
var runTask = function(args, task) {
|
|
runTask = function(arg, task) {
|
|
return task(arg);
|
|
};
|
|
|
|
return task.apply(null, args);
|
|
};
|
|
|
|
return all(slice.call(arguments, 1)).then(function(args) {
|
|
return when.reduce(tasks, function(arg, task) {
|
|
return runTask(arg, task);
|
|
}, args);
|
|
});
|
|
};
|
|
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
|
|
|
|
},{"./when":38}],35:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2012-2013 original author or authors */
|
|
|
|
/**
|
|
* poll.js
|
|
*
|
|
* Helper that polls until cancelled or for a condition to become true.
|
|
*
|
|
* @author Scott Andrews
|
|
*/
|
|
|
|
(function (define) { 'use strict';
|
|
define(function(require) {
|
|
|
|
var when = require('./when');
|
|
var attempt = when['try'];
|
|
var cancelable = require('./cancelable');
|
|
|
|
/**
|
|
* Periodically execute the task function on the msec delay. The result of
|
|
* the task may be verified by watching for a condition to become true. The
|
|
* returned deferred is cancellable if the polling needs to be cancelled
|
|
* externally before reaching a resolved state.
|
|
*
|
|
* The next vote is scheduled after the results of the current vote are
|
|
* verified and rejected.
|
|
*
|
|
* Polling may be terminated by the verifier returning a truthy value,
|
|
* invoking cancel() on the returned promise, or the task function returning
|
|
* a rejected promise.
|
|
*
|
|
* Usage:
|
|
*
|
|
* var count = 0;
|
|
* function doSomething() { return count++ }
|
|
*
|
|
* // poll until cancelled
|
|
* var p = poll(doSomething, 1000);
|
|
* ...
|
|
* p.cancel();
|
|
*
|
|
* // poll until condition is met
|
|
* poll(doSomething, 1000, function(result) { return result > 10 })
|
|
* .then(function(result) { assert result == 10 });
|
|
*
|
|
* // delay first vote
|
|
* poll(doSomething, 1000, anyFunc, true);
|
|
*
|
|
* @param task {Function} function that is executed after every timeout
|
|
* @param interval {number|Function} timeout in milliseconds
|
|
* @param [verifier] {Function} function to evaluate the result of the vote.
|
|
* May return a {Promise} or a {Boolean}. Rejecting the promise or a
|
|
* falsey value will schedule the next vote.
|
|
* @param [delayInitialTask] {boolean} if truthy, the first vote is scheduled
|
|
* instead of immediate
|
|
*
|
|
* @returns {Promise}
|
|
*/
|
|
return function poll(task, interval, verifier, delayInitialTask) {
|
|
var deferred, canceled, reject;
|
|
|
|
canceled = false;
|
|
deferred = cancelable(when.defer(), function () { canceled = true; });
|
|
reject = deferred.reject;
|
|
|
|
verifier = verifier || function () { return false; };
|
|
|
|
if (typeof interval !== 'function') {
|
|
interval = (function (interval) {
|
|
return function () { return when().delay(interval); };
|
|
})(interval);
|
|
}
|
|
|
|
function certify(result) {
|
|
deferred.resolve(result);
|
|
}
|
|
|
|
function schedule(result) {
|
|
attempt(interval).then(vote, reject);
|
|
if (result !== void 0) {
|
|
deferred.notify(result);
|
|
}
|
|
}
|
|
|
|
function vote() {
|
|
if (canceled) { return; }
|
|
when(task(),
|
|
function (result) {
|
|
when(verifier(result),
|
|
function (verification) {
|
|
return verification ? certify(result) : schedule(result);
|
|
},
|
|
function () { schedule(result); }
|
|
);
|
|
},
|
|
reject
|
|
);
|
|
}
|
|
|
|
if (delayInitialTask) {
|
|
schedule();
|
|
} else {
|
|
// if task() is blocking, vote will also block
|
|
vote();
|
|
}
|
|
|
|
// make the promise cancelable
|
|
deferred.promise = Object.create(deferred.promise);
|
|
deferred.promise.cancel = deferred.cancel;
|
|
|
|
return deferred.promise;
|
|
};
|
|
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
},{"./cancelable":4,"./when":38}],36:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2011-2013 original author or authors */
|
|
|
|
/**
|
|
* sequence.js
|
|
*
|
|
* Run a set of task functions in sequence. All tasks will
|
|
* receive the same args.
|
|
*
|
|
* @author Brian Cavalier
|
|
* @author John Hann
|
|
*/
|
|
|
|
(function(define) {
|
|
define(function(require) {
|
|
|
|
var when = require('./when');
|
|
var all = when.Promise.all;
|
|
var slice = Array.prototype.slice;
|
|
|
|
/**
|
|
* Run array of tasks in sequence with no overlap
|
|
* @param tasks {Array|Promise} array or promiseForArray of task functions
|
|
* @param [args] {*} arguments to be passed to all tasks
|
|
* @return {Promise} promise for an array containing
|
|
* the result of each task in the array position corresponding
|
|
* to position of the task in the tasks array
|
|
*/
|
|
return function sequence(tasks /*, args... */) {
|
|
var results = [];
|
|
|
|
return all(slice.call(arguments, 1)).then(function(args) {
|
|
return when.reduce(tasks, function(results, task) {
|
|
return when(task.apply(void 0, args), addResult);
|
|
}, results);
|
|
});
|
|
|
|
function addResult(result) {
|
|
results.push(result);
|
|
return results;
|
|
}
|
|
};
|
|
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
|
|
|
|
},{"./when":38}],37:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2011-2013 original author or authors */
|
|
|
|
/**
|
|
* timeout.js
|
|
*
|
|
* Helper that returns a promise that rejects after a specified timeout,
|
|
* if not explicitly resolved or rejected before that.
|
|
*
|
|
* @author Brian Cavalier
|
|
* @author John Hann
|
|
*/
|
|
|
|
(function(define) {
|
|
define(function(require) {
|
|
|
|
var when = require('./when');
|
|
|
|
/**
|
|
* @deprecated Use when(trigger).timeout(ms)
|
|
*/
|
|
return function timeout(msec, trigger) {
|
|
return when(trigger).timeout(msec);
|
|
};
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
|
|
|
|
},{"./when":38}],38:[function(require,module,exports){
|
|
/** @license MIT License (c) copyright 2010-2014 original author or authors */
|
|
|
|
/**
|
|
* Promises/A+ and when() implementation
|
|
* when is part of the cujoJS family of libraries (http://cujojs.com/)
|
|
* @author Brian Cavalier
|
|
* @author John Hann
|
|
*/
|
|
(function(define) { 'use strict';
|
|
define(function (require) {
|
|
|
|
var timed = require('./lib/decorators/timed');
|
|
var array = require('./lib/decorators/array');
|
|
var flow = require('./lib/decorators/flow');
|
|
var fold = require('./lib/decorators/fold');
|
|
var inspect = require('./lib/decorators/inspect');
|
|
var generate = require('./lib/decorators/iterate');
|
|
var progress = require('./lib/decorators/progress');
|
|
var withThis = require('./lib/decorators/with');
|
|
var unhandledRejection = require('./lib/decorators/unhandledRejection');
|
|
var TimeoutError = require('./lib/TimeoutError');
|
|
|
|
var Promise = [array, flow, fold, generate, progress,
|
|
inspect, withThis, timed, unhandledRejection]
|
|
.reduce(function(Promise, feature) {
|
|
return feature(Promise);
|
|
}, require('./lib/Promise'));
|
|
|
|
var apply = require('./lib/apply')(Promise);
|
|
|
|
// Public API
|
|
|
|
when.promise = promise; // Create a pending promise
|
|
when.resolve = Promise.resolve; // Create a resolved promise
|
|
when.reject = Promise.reject; // Create a rejected promise
|
|
|
|
when.lift = lift; // lift a function to return promises
|
|
when['try'] = attempt; // call a function and return a promise
|
|
when.attempt = attempt; // alias for when.try
|
|
|
|
when.iterate = Promise.iterate; // DEPRECATED (use cujojs/most streams) Generate a stream of promises
|
|
when.unfold = Promise.unfold; // DEPRECATED (use cujojs/most streams) Generate a stream of promises
|
|
|
|
when.join = join; // Join 2 or more promises
|
|
|
|
when.all = all; // Resolve a list of promises
|
|
when.settle = settle; // Settle a list of promises
|
|
|
|
when.any = lift(Promise.any); // One-winner race
|
|
when.some = lift(Promise.some); // Multi-winner race
|
|
when.race = lift(Promise.race); // First-to-settle race
|
|
|
|
when.map = map; // Array.map() for promises
|
|
when.filter = filter; // Array.filter() for promises
|
|
when.reduce = lift(Promise.reduce); // Array.reduce() for promises
|
|
when.reduceRight = lift(Promise.reduceRight); // Array.reduceRight() for promises
|
|
|
|
when.isPromiseLike = isPromiseLike; // Is something promise-like, aka thenable
|
|
|
|
when.Promise = Promise; // Promise constructor
|
|
when.defer = defer; // Create a {promise, resolve, reject} tuple
|
|
|
|
// Error types
|
|
|
|
when.TimeoutError = TimeoutError;
|
|
|
|
/**
|
|
* Get a trusted promise for x, or by transforming x with onFulfilled
|
|
*
|
|
* @param {*} x
|
|
* @param {function?} onFulfilled callback to be called when x is
|
|
* successfully fulfilled. If promiseOrValue is an immediate value, callback
|
|
* will be invoked immediately.
|
|
* @param {function?} onRejected callback to be called when x is
|
|
* rejected.
|
|
* @param {function?} onProgress callback to be called when progress updates
|
|
* are issued for x. @deprecated
|
|
* @returns {Promise} a new promise that will fulfill with the return
|
|
* value of callback or errback or the completion value of promiseOrValue if
|
|
* callback and/or errback is not supplied.
|
|
*/
|
|
function when(x, onFulfilled, onRejected, onProgress) {
|
|
var p = Promise.resolve(x);
|
|
if (arguments.length < 2) {
|
|
return p;
|
|
}
|
|
|
|
return p.then(onFulfilled, onRejected, onProgress);
|
|
}
|
|
|
|
/**
|
|
* Creates a new promise whose fate is determined by resolver.
|
|
* @param {function} resolver function(resolve, reject, notify)
|
|
* @returns {Promise} promise whose fate is determine by resolver
|
|
*/
|
|
function promise(resolver) {
|
|
return new Promise(resolver);
|
|
}
|
|
|
|
/**
|
|
* Lift the supplied function, creating a version of f that returns
|
|
* promises, and accepts promises as arguments.
|
|
* @param {function} f
|
|
* @returns {Function} version of f that returns promises
|
|
*/
|
|
function lift(f) {
|
|
return function() {
|
|
for(var i=0, l=arguments.length, a=new Array(l); i<l; ++i) {
|
|
a[i] = arguments[i];
|
|
}
|
|
return apply(f, this, a);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Call f in a future turn, with the supplied args, and return a promise
|
|
* for the result.
|
|
* @param {function} f
|
|
* @returns {Promise}
|
|
*/
|
|
function attempt(f /*, args... */) {
|
|
/*jshint validthis:true */
|
|
for(var i=0, l=arguments.length-1, a=new Array(l); i<l; ++i) {
|
|
a[i] = arguments[i+1];
|
|
}
|
|
return apply(f, this, a);
|
|
}
|
|
|
|
/**
|
|
* Creates a {promise, resolver} pair, either or both of which
|
|
* may be given out safely to consumers.
|
|
* @return {{promise: Promise, resolve: function, reject: function, notify: function}}
|
|
*/
|
|
function defer() {
|
|
return new Deferred();
|
|
}
|
|
|
|
function Deferred() {
|
|
var p = Promise._defer();
|
|
|
|
function resolve(x) { p._handler.resolve(x); }
|
|
function reject(x) { p._handler.reject(x); }
|
|
function notify(x) { p._handler.notify(x); }
|
|
|
|
this.promise = p;
|
|
this.resolve = resolve;
|
|
this.reject = reject;
|
|
this.notify = notify;
|
|
this.resolver = { resolve: resolve, reject: reject, notify: notify };
|
|
}
|
|
|
|
/**
|
|
* Determines if x is promise-like, i.e. a thenable object
|
|
* NOTE: Will return true for *any thenable object*, and isn't truly
|
|
* safe, since it may attempt to access the `then` property of x (i.e.
|
|
* clever/malicious getters may do weird things)
|
|
* @param {*} x anything
|
|
* @returns {boolean} true if x is promise-like
|
|
*/
|
|
function isPromiseLike(x) {
|
|
return x && typeof x.then === 'function';
|
|
}
|
|
|
|
/**
|
|
* Return a promise that will resolve only once all the supplied arguments
|
|
* have resolved. The resolution value of the returned promise will be an array
|
|
* containing the resolution values of each of the arguments.
|
|
* @param {...*} arguments may be a mix of promises and values
|
|
* @returns {Promise}
|
|
*/
|
|
function join(/* ...promises */) {
|
|
return Promise.all(arguments);
|
|
}
|
|
|
|
/**
|
|
* Return a promise that will fulfill once all input promises have
|
|
* fulfilled, or reject when any one input promise rejects.
|
|
* @param {array|Promise} promises array (or promise for an array) of promises
|
|
* @returns {Promise}
|
|
*/
|
|
function all(promises) {
|
|
return when(promises, Promise.all);
|
|
}
|
|
|
|
/**
|
|
* Return a promise that will always fulfill with an array containing
|
|
* the outcome states of all input promises. The returned promise
|
|
* will only reject if `promises` itself is a rejected promise.
|
|
* @param {array|Promise} promises array (or promise for an array) of promises
|
|
* @returns {Promise} promise for array of settled state descriptors
|
|
*/
|
|
function settle(promises) {
|
|
return when(promises, Promise.settle);
|
|
}
|
|
|
|
/**
|
|
* Promise-aware array map function, similar to `Array.prototype.map()`,
|
|
* but input array may contain promises or values.
|
|
* @param {Array|Promise} promises array of anything, may contain promises and values
|
|
* @param {function(x:*, index:Number):*} mapFunc map function which may
|
|
* return a promise or value
|
|
* @returns {Promise} promise that will fulfill with an array of mapped values
|
|
* or reject if any input promise rejects.
|
|
*/
|
|
function map(promises, mapFunc) {
|
|
return when(promises, function(promises) {
|
|
return Promise.map(promises, mapFunc);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Filter the provided array of promises using the provided predicate. Input may
|
|
* contain promises and values
|
|
* @param {Array|Promise} promises array of promises and values
|
|
* @param {function(x:*, index:Number):boolean} predicate filtering predicate.
|
|
* Must return truthy (or promise for truthy) for items to retain.
|
|
* @returns {Promise} promise that will fulfill with an array containing all items
|
|
* for which predicate returned truthy.
|
|
*/
|
|
function filter(promises, predicate) {
|
|
return when(promises, function(promises) {
|
|
return Promise.filter(promises, predicate);
|
|
});
|
|
}
|
|
|
|
return when;
|
|
});
|
|
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
|
|
|
|
},{"./lib/Promise":9,"./lib/TimeoutError":11,"./lib/apply":12,"./lib/decorators/array":13,"./lib/decorators/flow":14,"./lib/decorators/fold":15,"./lib/decorators/inspect":16,"./lib/decorators/iterate":17,"./lib/decorators/progress":18,"./lib/decorators/timed":19,"./lib/decorators/unhandledRejection":20,"./lib/decorators/with":21}]},{},[1])
|
|
//# sourceMappingURL=when.debug.js.map
|
|
(1)
|
|
});
|
|
; |