"use strict"; module.exports = function() { var makeSelfResolutionError = function () { return new TypeError("circular promise resolution chain\u000a\u000a See http://goo.gl/LhFpo0\u000a"); }; var reflect = function() { return new Promise.PromiseInspection(this._target()); }; var apiRejection = function(msg) { return Promise.reject(new TypeError(msg)); }; var util = require("./util.js"); var getDomain; if (util.isNode) { getDomain = function() { var ret = process.domain; if (ret === undefined) ret = null; return ret; }; } else { getDomain = function() { return null; }; } util.notEnumerableProp(Promise, "_getDomain", getDomain); var UNDEFINED_BINDING = {}; var async = require("./async.js"); var errors = require("./errors.js"); var TypeError = Promise.TypeError = errors.TypeError; Promise.RangeError = errors.RangeError; Promise.CancellationError = errors.CancellationError; Promise.TimeoutError = errors.TimeoutError; Promise.OperationalError = errors.OperationalError; Promise.RejectionError = errors.OperationalError; Promise.AggregateError = errors.AggregateError; var INTERNAL = function(){}; var APPLY = {}; var NEXT_FILTER = {e: null}; var tryConvertToPromise = require("./thenables.js")(Promise, INTERNAL); var PromiseArray = require("./promise_array.js")(Promise, INTERNAL, tryConvertToPromise, apiRejection); var CapturedTrace = require("./captured_trace.js")(); var isDebugging = require("./debuggability.js")(Promise, CapturedTrace); /*jshint unused:false*/ var createContext = require("./context.js")(Promise, CapturedTrace, isDebugging); var CatchFilter = require("./catch_filter.js")(NEXT_FILTER); var PromiseResolver = require("./promise_resolver.js"); var nodebackForPromise = PromiseResolver._nodebackForPromise; var errorObj = util.errorObj; var tryCatch = util.tryCatch; function Promise(resolver) { if (typeof resolver !== "function") { throw new TypeError("the promise constructor requires a resolver function\u000a\u000a See http://goo.gl/EC22Yn\u000a"); } if (this.constructor !== Promise) { throw new TypeError("the promise constructor cannot be invoked directly\u000a\u000a See http://goo.gl/KsIlge\u000a"); } this._bitField = 0; this._fulfillmentHandler0 = undefined; this._rejectionHandler0 = undefined; this._progressHandler0 = undefined; this._promise0 = undefined; this._receiver0 = undefined; this._settledValue = undefined; if (resolver !== INTERNAL) this._resolveFromResolver(resolver); } Promise.prototype.toString = function () { return "[object Promise]"; }; Promise.prototype.caught = Promise.prototype["catch"] = function (fn) { var len = arguments.length; if (len > 1) { var catchInstances = new Array(len - 1), j = 0, i; for (i = 0; i < len - 1; ++i) { var item = arguments[i]; if (typeof item === "function") { catchInstances[j++] = item; } else { return Promise.reject( new TypeError("Catch filter must inherit from Error or be a simple predicate function\u000a\u000a See http://goo.gl/o84o68\u000a")); } } catchInstances.length = j; fn = arguments[i]; var catchFilter = new CatchFilter(catchInstances, fn, this); return this._then(undefined, catchFilter.doFilter, undefined, catchFilter, undefined); } return this._then(undefined, fn, undefined, undefined, undefined); }; Promise.prototype.reflect = function () { return this._then(reflect, reflect, undefined, this, undefined); }; Promise.prototype.then = function (didFulfill, didReject, didProgress) { if (isDebugging() && arguments.length > 0 && typeof didFulfill !== "function" && typeof didReject !== "function") { var msg = ".then() only accepts functions but was passed: " + util.classString(didFulfill); if (arguments.length > 1) { msg += ", " + util.classString(didReject); } this._warn(msg); } return this._then(didFulfill, didReject, didProgress, undefined, undefined); }; Promise.prototype.done = function (didFulfill, didReject, didProgress) { var promise = this._then(didFulfill, didReject, didProgress, undefined, undefined); promise._setIsFinal(); }; Promise.prototype.spread = function (didFulfill, didReject) { return this.all()._then(didFulfill, didReject, undefined, APPLY, undefined); }; Promise.prototype.isCancellable = function () { return !this.isResolved() && this._cancellable(); }; Promise.prototype.toJSON = function () { var ret = { isFulfilled: false, isRejected: false, fulfillmentValue: undefined, rejectionReason: undefined }; if (this.isFulfilled()) { ret.fulfillmentValue = this.value(); ret.isFulfilled = true; } else if (this.isRejected()) { ret.rejectionReason = this.reason(); ret.isRejected = true; } return ret; }; Promise.prototype.all = function () { return new PromiseArray(this).promise(); }; Promise.prototype.error = function (fn) { return this.caught(util.originatesFromRejection, fn); }; Promise.is = function (val) { return val instanceof Promise; }; Promise.fromNode = function(fn) { var ret = new Promise(INTERNAL); var result = tryCatch(fn)(nodebackForPromise(ret)); if (result === errorObj) { ret._rejectCallback(result.e, true, true); } return ret; }; Promise.all = function (promises) { return new PromiseArray(promises).promise(); }; Promise.defer = Promise.pending = function () { var promise = new Promise(INTERNAL); return new PromiseResolver(promise); }; Promise.cast = function (obj) { var ret = tryConvertToPromise(obj); if (!(ret instanceof Promise)) { var val = ret; ret = new Promise(INTERNAL); ret._fulfillUnchecked(val); } return ret; }; Promise.resolve = Promise.fulfilled = Promise.cast; Promise.reject = Promise.rejected = function (reason) { var ret = new Promise(INTERNAL); ret._captureStackTrace(); ret._rejectCallback(reason, true); return ret; }; Promise.setScheduler = function(fn) { if (typeof fn !== "function") throw new TypeError("fn must be a function\u000a\u000a See http://goo.gl/916lJJ\u000a"); var prev = async._schedule; async._schedule = fn; return prev; }; Promise.prototype._then = function ( didFulfill, didReject, didProgress, receiver, internalData ) { var haveInternalData = internalData !== undefined; var ret = haveInternalData ? internalData : new Promise(INTERNAL); if (!haveInternalData) { ret._propagateFrom(this, 4 | 1); ret._captureStackTrace(); } var target = this._target(); if (target !== this) { if (receiver === undefined) receiver = this._boundTo; if (!haveInternalData) ret._setIsMigrated(); } var callbackIndex = target._addCallbacks(didFulfill, didReject, didProgress, ret, receiver, getDomain()); if (target._isResolved() && !target._isSettlePromisesQueued()) { async.invoke( target._settlePromiseAtPostResolution, target, callbackIndex); } return ret; }; Promise.prototype._settlePromiseAtPostResolution = function (index) { if (this._isRejectionUnhandled()) this._unsetRejectionIsUnhandled(); this._settlePromiseAt(index); }; Promise.prototype._length = function () { return this._bitField & 131071; }; Promise.prototype._isFollowingOrFulfilledOrRejected = function () { return (this._bitField & 939524096) > 0; }; Promise.prototype._isFollowing = function () { return (this._bitField & 536870912) === 536870912; }; Promise.prototype._setLength = function (len) { this._bitField = (this._bitField & -131072) | (len & 131071); }; Promise.prototype._setFulfilled = function () { this._bitField = this._bitField | 268435456; }; Promise.prototype._setRejected = function () { this._bitField = this._bitField | 134217728; }; Promise.prototype._setFollowing = function () { this._bitField = this._bitField | 536870912; }; Promise.prototype._setIsFinal = function () { this._bitField = this._bitField | 33554432; }; Promise.prototype._isFinal = function () { return (this._bitField & 33554432) > 0; }; Promise.prototype._cancellable = function () { return (this._bitField & 67108864) > 0; }; Promise.prototype._setCancellable = function () { this._bitField = this._bitField | 67108864; }; Promise.prototype._unsetCancellable = function () { this._bitField = this._bitField & (~67108864); }; Promise.prototype._setIsMigrated = function () { this._bitField = this._bitField | 4194304; }; Promise.prototype._unsetIsMigrated = function () { this._bitField = this._bitField & (~4194304); }; Promise.prototype._isMigrated = function () { return (this._bitField & 4194304) > 0; }; Promise.prototype._receiverAt = function (index) { var ret = index === 0 ? this._receiver0 : this[ index * 5 - 5 + 4]; if (ret === UNDEFINED_BINDING) { return undefined; } else if (ret === undefined && this._isBound()) { return this._boundValue(); } return ret; }; Promise.prototype._promiseAt = function (index) { return index === 0 ? this._promise0 : this[index * 5 - 5 + 3]; }; Promise.prototype._fulfillmentHandlerAt = function (index) { return index === 0 ? this._fulfillmentHandler0 : this[index * 5 - 5 + 0]; }; Promise.prototype._rejectionHandlerAt = function (index) { return index === 0 ? this._rejectionHandler0 : this[index * 5 - 5 + 1]; }; Promise.prototype._boundValue = function() { var ret = this._boundTo; if (ret !== undefined) { if (ret instanceof Promise) { if (ret.isFulfilled()) { return ret.value(); } else { return undefined; } } } return ret; }; Promise.prototype._migrateCallbacks = function (follower, index) { var fulfill = follower._fulfillmentHandlerAt(index); var reject = follower._rejectionHandlerAt(index); var progress = follower._progressHandlerAt(index); var promise = follower._promiseAt(index); var receiver = follower._receiverAt(index); if (promise instanceof Promise) promise._setIsMigrated(); if (receiver === undefined) receiver = UNDEFINED_BINDING; this._addCallbacks(fulfill, reject, progress, promise, receiver, null); }; Promise.prototype._addCallbacks = function ( fulfill, reject, progress, promise, receiver, domain ) { var index = this._length(); if (index >= 131071 - 5) { index = 0; this._setLength(0); } if (index === 0) { this._promise0 = promise; if (receiver !== undefined) this._receiver0 = receiver; if (typeof fulfill === "function" && !this._isCarryingStackTrace()) { this._fulfillmentHandler0 = domain === null ? fulfill : domain.bind(fulfill); } if (typeof reject === "function") { this._rejectionHandler0 = domain === null ? reject : domain.bind(reject); } if (typeof progress === "function") { this._progressHandler0 = domain === null ? progress : domain.bind(progress); } } else { var base = index * 5 - 5; this[base + 3] = promise; this[base + 4] = receiver; if (typeof fulfill === "function") { this[base + 0] = domain === null ? fulfill : domain.bind(fulfill); } if (typeof reject === "function") { this[base + 1] = domain === null ? reject : domain.bind(reject); } if (typeof progress === "function") { this[base + 2] = domain === null ? progress : domain.bind(progress); } } this._setLength(index + 1); return index; }; Promise.prototype._setProxyHandlers = function (receiver, promiseSlotValue) { var index = this._length(); if (index >= 131071 - 5) { index = 0; this._setLength(0); } if (index === 0) { this._promise0 = promiseSlotValue; this._receiver0 = receiver; } else { var base = index * 5 - 5; this[base + 3] = promiseSlotValue; this[base + 4] = receiver; } this._setLength(index + 1); }; Promise.prototype._proxyPromiseArray = function (promiseArray, index) { this._setProxyHandlers(promiseArray, index); }; Promise.prototype._resolveCallback = function(value, shouldBind) { if (this._isFollowingOrFulfilledOrRejected()) return; if (value === this) return this._rejectCallback(makeSelfResolutionError(), false, true); var maybePromise = tryConvertToPromise(value, this); if (!(maybePromise instanceof Promise)) return this._fulfill(value); var propagationFlags = 1 | (shouldBind ? 4 : 0); this._propagateFrom(maybePromise, propagationFlags); var promise = maybePromise._target(); if (promise._isPending()) { var len = this._length(); for (var i = 0; i < len; ++i) { promise._migrateCallbacks(this, i); } this._setFollowing(); this._setLength(0); this._setFollowee(promise); } else if (promise._isFulfilled()) { this._fulfillUnchecked(promise._value()); } else { this._rejectUnchecked(promise._reason(), promise._getCarriedStackTrace()); } }; Promise.prototype._rejectCallback = function(reason, synchronous, shouldNotMarkOriginatingFromRejection) { if (!shouldNotMarkOriginatingFromRejection) { util.markAsOriginatingFromRejection(reason); } var trace = util.ensureErrorObject(reason); var hasStack = trace === reason; this._attachExtraTrace(trace, synchronous ? hasStack : false); this._reject(reason, hasStack ? undefined : trace); }; Promise.prototype._resolveFromResolver = function (resolver) { var promise = this; this._captureStackTrace(); this._pushContext(); var synchronous = true; var r = tryCatch(resolver)(function(value) { if (promise === null) return; promise._resolveCallback(value); promise = null; }, function (reason) { if (promise === null) return; promise._rejectCallback(reason, synchronous); promise = null; }); synchronous = false; this._popContext(); if (r !== undefined && r === errorObj && promise !== null) { promise._rejectCallback(r.e, true, true); promise = null; } }; Promise.prototype._settlePromiseFromHandler = function ( handler, receiver, value, promise ) { if (promise._isRejected()) return; promise._pushContext(); var x; if (receiver === APPLY && !this._isRejected()) { x = tryCatch(handler).apply(this._boundValue(), value); } else { x = tryCatch(handler).call(receiver, value); } promise._popContext(); if (x === errorObj || x === promise || x === NEXT_FILTER) { var err = x === promise ? makeSelfResolutionError() : x.e; promise._rejectCallback(err, false, true); } else { promise._resolveCallback(x); } }; Promise.prototype._target = function() { var ret = this; while (ret._isFollowing()) ret = ret._followee(); return ret; }; Promise.prototype._followee = function() { return this._rejectionHandler0; }; Promise.prototype._setFollowee = function(promise) { this._rejectionHandler0 = promise; }; Promise.prototype._cleanValues = function () { if (this._cancellable()) { this._cancellationParent = undefined; } }; Promise.prototype._propagateFrom = function (parent, flags) { if ((flags & 1) > 0 && parent._cancellable()) { this._setCancellable(); this._cancellationParent = parent; } if ((flags & 4) > 0 && parent._isBound()) { this._setBoundTo(parent._boundTo); } }; Promise.prototype._fulfill = function (value) { if (this._isFollowingOrFulfilledOrRejected()) return; this._fulfillUnchecked(value); }; Promise.prototype._reject = function (reason, carriedStackTrace) { if (this._isFollowingOrFulfilledOrRejected()) return; this._rejectUnchecked(reason, carriedStackTrace); }; Promise.prototype._settlePromiseAt = function (index) { var promise = this._promiseAt(index); var isPromise = promise instanceof Promise; if (isPromise && promise._isMigrated()) { promise._unsetIsMigrated(); return async.invoke(this._settlePromiseAt, this, index); } var handler = this._isFulfilled() ? this._fulfillmentHandlerAt(index) : this._rejectionHandlerAt(index); var carriedStackTrace = this._isCarryingStackTrace() ? this._getCarriedStackTrace() : undefined; var value = this._settledValue; var receiver = this._receiverAt(index); this._clearCallbackDataAtIndex(index); if (typeof handler === "function") { if (!isPromise) { handler.call(receiver, value, promise); } else { this._settlePromiseFromHandler(handler, receiver, value, promise); } } else if (receiver instanceof PromiseArray) { if (!receiver._isResolved()) { if (this._isFulfilled()) { receiver._promiseFulfilled(value, promise); } else { receiver._promiseRejected(value, promise); } } } else if (isPromise) { if (this._isFulfilled()) { promise._fulfill(value); } else { promise._reject(value, carriedStackTrace); } } if (index >= 4 && (index & 31) === 4) async.invokeLater(this._setLength, this, 0); }; Promise.prototype._clearCallbackDataAtIndex = function(index) { if (index === 0) { if (!this._isCarryingStackTrace()) { this._fulfillmentHandler0 = undefined; } this._rejectionHandler0 = this._progressHandler0 = this._receiver0 = this._promise0 = undefined; } else { var base = index * 5 - 5; this[base + 3] = this[base + 4] = this[base + 0] = this[base + 1] = this[base + 2] = undefined; } }; Promise.prototype._isSettlePromisesQueued = function () { return (this._bitField & -1073741824) === -1073741824; }; Promise.prototype._setSettlePromisesQueued = function () { this._bitField = this._bitField | -1073741824; }; Promise.prototype._unsetSettlePromisesQueued = function () { this._bitField = this._bitField & (~-1073741824); }; Promise.prototype._queueSettlePromises = function() { async.settlePromises(this); this._setSettlePromisesQueued(); }; Promise.prototype._fulfillUnchecked = function (value) { if (value === this) { var err = makeSelfResolutionError(); this._attachExtraTrace(err); return this._rejectUnchecked(err, undefined); } this._setFulfilled(); this._settledValue = value; this._cleanValues(); if (this._length() > 0) { this._queueSettlePromises(); } }; Promise.prototype._rejectUncheckedCheckError = function (reason) { var trace = util.ensureErrorObject(reason); this._rejectUnchecked(reason, trace === reason ? undefined : trace); }; Promise.prototype._rejectUnchecked = function (reason, trace) { if (reason === this) { var err = makeSelfResolutionError(); this._attachExtraTrace(err); return this._rejectUnchecked(err); } this._setRejected(); this._settledValue = reason; this._cleanValues(); if (this._isFinal()) { async.throwLater(function(e) { if ("stack" in e) { async.invokeFirst( CapturedTrace.unhandledRejection, undefined, e); } throw e; }, trace === undefined ? reason : trace); return; } if (trace !== undefined && trace !== reason) { this._setCarriedStackTrace(trace); } if (this._length() > 0) { this._queueSettlePromises(); } else { this._ensurePossibleRejectionHandled(); } }; Promise.prototype._settlePromises = function () { this._unsetSettlePromisesQueued(); var len = this._length(); for (var i = 0; i < len; i++) { this._settlePromiseAt(i); } }; util.notEnumerableProp(Promise, "_makeSelfResolutionError", makeSelfResolutionError); require("./progress.js")(Promise, PromiseArray); require("./method.js")(Promise, INTERNAL, tryConvertToPromise, apiRejection); require("./bind.js")(Promise, INTERNAL, tryConvertToPromise); require("./finally.js")(Promise, NEXT_FILTER, tryConvertToPromise); require("./direct_resolve.js")(Promise); require("./synchronous_inspection.js")(Promise); require("./join.js")(Promise, PromiseArray, tryConvertToPromise, INTERNAL); Promise.Promise = Promise; require('./map.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL); require('./cancel.js')(Promise); require('./using.js')(Promise, apiRejection, tryConvertToPromise, createContext); require('./generators.js')(Promise, apiRejection, INTERNAL, tryConvertToPromise); require('./nodeify.js')(Promise); require('./call_get.js')(Promise); require('./props.js')(Promise, PromiseArray, tryConvertToPromise, apiRejection); require('./race.js')(Promise, INTERNAL, tryConvertToPromise, apiRejection); require('./reduce.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL); require('./settle.js')(Promise, PromiseArray); require('./some.js')(Promise, PromiseArray, apiRejection); require('./promisify.js')(Promise, INTERNAL); require('./any.js')(Promise); require('./each.js')(Promise, INTERNAL); require('./timers.js')(Promise, INTERNAL); require('./filter.js')(Promise, INTERNAL); util.toFastProperties(Promise); util.toFastProperties(Promise.prototype); function fillTypes(value) { var p = new Promise(INTERNAL); p._fulfillmentHandler0 = value; p._rejectionHandler0 = value; p._progressHandler0 = value; p._promise0 = value; p._receiver0 = value; p._settledValue = value; } // Complete slack tracking, opt out of field-type tracking and // stabilize map fillTypes({a: 1}); fillTypes({b: 2}); fillTypes({c: 3}); fillTypes(1); fillTypes(function(){}); fillTypes(undefined); fillTypes(false); fillTypes(new Promise(INTERNAL)); CapturedTrace.setBounds(async.firstLineError, util.lastLineError); return Promise; };