diff options
author | Florian Dold <florian.dold@gmail.com> | 2016-10-10 03:43:44 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2016-10-10 03:43:44 +0200 |
commit | abd94a7f5a50f43c797a11b53549ae48fff667c3 (patch) | |
tree | ab8ed457f65cdd72e13e0571d2975729428f1551 /node_modules/when/lib | |
parent | a0247c6a3fd6a09a41a7e35a3441324c4dcb58be (diff) |
add node_modules to address #4364
Diffstat (limited to 'node_modules/when/lib')
-rw-r--r-- | node_modules/when/lib/Promise.js | 17 | ||||
-rw-r--r-- | node_modules/when/lib/Scheduler.js | 80 | ||||
-rw-r--r-- | node_modules/when/lib/TimeoutError.js | 27 | ||||
-rw-r--r-- | node_modules/when/lib/apply.js | 55 | ||||
-rw-r--r-- | node_modules/when/lib/decorators/array.js | 289 | ||||
-rw-r--r-- | node_modules/when/lib/decorators/flow.js | 160 | ||||
-rw-r--r-- | node_modules/when/lib/decorators/fold.js | 27 | ||||
-rw-r--r-- | node_modules/when/lib/decorators/inspect.js | 20 | ||||
-rw-r--r-- | node_modules/when/lib/decorators/iterate.js | 65 | ||||
-rw-r--r-- | node_modules/when/lib/decorators/progress.js | 24 | ||||
-rw-r--r-- | node_modules/when/lib/decorators/timed.js | 78 | ||||
-rw-r--r-- | node_modules/when/lib/decorators/unhandledRejection.js | 86 | ||||
-rw-r--r-- | node_modules/when/lib/decorators/with.js | 38 | ||||
-rw-r--r-- | node_modules/when/lib/env.js | 73 | ||||
-rw-r--r-- | node_modules/when/lib/format.js | 56 | ||||
-rw-r--r-- | node_modules/when/lib/liftAll.js | 28 | ||||
-rw-r--r-- | node_modules/when/lib/makePromise.js | 927 | ||||
-rw-r--r-- | node_modules/when/lib/state.js | 35 |
18 files changed, 2085 insertions, 0 deletions
diff --git a/node_modules/when/lib/Promise.js b/node_modules/when/lib/Promise.js new file mode 100644 index 000000000..61c81c939 --- /dev/null +++ b/node_modules/when/lib/Promise.js @@ -0,0 +1,17 @@ +/** @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); }); diff --git a/node_modules/when/lib/Scheduler.js b/node_modules/when/lib/Scheduler.js new file mode 100644 index 000000000..4def2c2f0 --- /dev/null +++ b/node_modules/when/lib/Scheduler.js @@ -0,0 +1,80 @@ +/** @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(); })); diff --git a/node_modules/when/lib/TimeoutError.js b/node_modules/when/lib/TimeoutError.js new file mode 100644 index 000000000..960107f85 --- /dev/null +++ b/node_modules/when/lib/TimeoutError.js @@ -0,0 +1,27 @@ +/** @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(); }));
\ No newline at end of file diff --git a/node_modules/when/lib/apply.js b/node_modules/when/lib/apply.js new file mode 100644 index 000000000..1c4a95b1f --- /dev/null +++ b/node_modules/when/lib/apply.js @@ -0,0 +1,55 @@ +/** @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(); })); + + diff --git a/node_modules/when/lib/decorators/array.js b/node_modules/when/lib/decorators/array.js new file mode 100644 index 000000000..2f89c6150 --- /dev/null +++ b/node_modules/when/lib/decorators/array.js @@ -0,0 +1,289 @@ +/** @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) { + var h = Promise._handler(p); + if(h.state() === 0) { + return toPromise(p).then(state.fulfilled, state.rejected); + } + + h._unreport(); + return state.inspect(h); + } + + /** + * 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); })); diff --git a/node_modules/when/lib/decorators/flow.js b/node_modules/when/lib/decorators/flow.js new file mode 100644 index 000000000..635e4f493 --- /dev/null +++ b/node_modules/when/lib/decorators/flow.js @@ -0,0 +1,160 @@ +/** @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(); })); diff --git a/node_modules/when/lib/decorators/fold.js b/node_modules/when/lib/decorators/fold.js new file mode 100644 index 000000000..c7f027aa4 --- /dev/null +++ b/node_modules/when/lib/decorators/fold.js @@ -0,0 +1,27 @@ +/** @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(); })); diff --git a/node_modules/when/lib/decorators/inspect.js b/node_modules/when/lib/decorators/inspect.js new file mode 100644 index 000000000..95b87157d --- /dev/null +++ b/node_modules/when/lib/decorators/inspect.js @@ -0,0 +1,20 @@ +/** @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); })); diff --git a/node_modules/when/lib/decorators/iterate.js b/node_modules/when/lib/decorators/iterate.js new file mode 100644 index 000000000..3ea70b3c1 --- /dev/null +++ b/node_modules/when/lib/decorators/iterate.js @@ -0,0 +1,65 @@ +/** @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(); })); diff --git a/node_modules/when/lib/decorators/progress.js b/node_modules/when/lib/decorators/progress.js new file mode 100644 index 000000000..d45e3d0d5 --- /dev/null +++ b/node_modules/when/lib/decorators/progress.js @@ -0,0 +1,24 @@ +/** @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(); })); diff --git a/node_modules/when/lib/decorators/timed.js b/node_modules/when/lib/decorators/timed.js new file mode 100644 index 000000000..cd82ed436 --- /dev/null +++ b/node_modules/when/lib/decorators/timed.js @@ -0,0 +1,78 @@ +/** @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); })); diff --git a/node_modules/when/lib/decorators/unhandledRejection.js b/node_modules/when/lib/decorators/unhandledRejection.js new file mode 100644 index 000000000..fb966f762 --- /dev/null +++ b/node_modules/when/lib/decorators/unhandledRejection.js @@ -0,0 +1,86 @@ +/** @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); })); diff --git a/node_modules/when/lib/decorators/with.js b/node_modules/when/lib/decorators/with.js new file mode 100644 index 000000000..a0f05f0b0 --- /dev/null +++ b/node_modules/when/lib/decorators/with.js @@ -0,0 +1,38 @@ +/** @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(); })); + diff --git a/node_modules/when/lib/env.js b/node_modules/when/lib/env.js new file mode 100644 index 000000000..b5e1af7f8 --- /dev/null +++ b/node_modules/when/lib/env.js @@ -0,0 +1,73 @@ +/** @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 === 'function' && MutationObserver) || + (typeof WebKitMutationObserver === 'function' && 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); })); diff --git a/node_modules/when/lib/format.js b/node_modules/when/lib/format.js new file mode 100644 index 000000000..f56c81bc0 --- /dev/null +++ b/node_modules/when/lib/format.js @@ -0,0 +1,56 @@ +/** @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(); })); diff --git a/node_modules/when/lib/liftAll.js b/node_modules/when/lib/liftAll.js new file mode 100644 index 000000000..af4dd4f7a --- /dev/null +++ b/node_modules/when/lib/liftAll.js @@ -0,0 +1,28 @@ +/** @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(); })); diff --git a/node_modules/when/lib/makePromise.js b/node_modules/when/lib/makePromise.js new file mode 100644 index 000000000..76f259737 --- /dev/null +++ b/node_modules/when/lib/makePromise.js @@ -0,0 +1,927 @@ +/** @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 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' && typeof CustomEvent === 'function') { + return (function(noop, self, CustomEvent) { + var hasCustomEvent = false; + try { + var ev = new CustomEvent('unhandledRejection'); + hasCustomEvent = ev instanceof CustomEvent; + } catch (e) {} + + return !hasCustomEvent ? noop : function(type, rejection) { + var ev = new CustomEvent(type, { + detail: { + reason: rejection.value, + key: rejection + }, + bubbles: false, + cancelable: true + }); + + return !self.dispatchEvent(ev); + }; + }(noop, self, CustomEvent)); + } + + return noop; + } + + return Promise; + }; +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); diff --git a/node_modules/when/lib/state.js b/node_modules/when/lib/state.js new file mode 100644 index 000000000..6dbd47ded --- /dev/null +++ b/node_modules/when/lib/state.js @@ -0,0 +1,35 @@ +/** @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(); })); |