pax_global_header00006660000000000000000000000064143257251220014515gustar00rootroot0000000000000052 comment=9d5851d7adefde580589a041ebfcbd030d39f6fd promise-8.3.0/000077500000000000000000000000001432572512200132035ustar00rootroot00000000000000promise-8.3.0/.github/000077500000000000000000000000001432572512200145435ustar00rootroot00000000000000promise-8.3.0/.github/FUNDING.yml000066400000000000000000000013431432572512200163610ustar00rootroot00000000000000# These are supported funding model platforms github: [ForbesLindesay]# Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: # Replace with a single Patreon username open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: npm/promise # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] promise-8.3.0/.github/workflows/000077500000000000000000000000001432572512200166005ustar00rootroot00000000000000promise-8.3.0/.github/workflows/rollingversions-canary.yml000066400000000000000000000016171432572512200240420ustar00rootroot00000000000000name: Publish Canary on: push: branches: - master jobs: test: runs-on: ubuntu-latest strategy: matrix: node-version: [14.x] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - run: yarn install - run: yarn build - run: yarn test publish-canary: runs-on: ubuntu-latest needs: test steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: node-version: 14.x registry-url: 'https://registry.npmjs.org' - run: yarn install - run: yarn build - run: npx rollingversions publish --canary $GITHUB_RUN_NUMBER env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} promise-8.3.0/.github/workflows/rollingversions.yml000066400000000000000000000016041432572512200225630ustar00rootroot00000000000000name: Release on: repository_dispatch: types: [rollingversions_publish_approved] jobs: test: runs-on: ubuntu-latest strategy: matrix: node-version: [14.x] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - run: yarn install - run: yarn build - run: yarn test publish: runs-on: ubuntu-latest needs: test steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: node-version: 14.x registry-url: 'https://registry.npmjs.org' - run: yarn install - run: yarn build - run: npx rollingversions publish env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} promise-8.3.0/.github/workflows/test.yml000066400000000000000000000006621432572512200203060ustar00rootroot00000000000000name: Test on: pull_request: branches: - master jobs: test: runs-on: ubuntu-latest strategy: matrix: node-version: [14.x] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - run: yarn install - run: yarn build - run: yarn test promise-8.3.0/.gitignore000066400000000000000000000001241432572512200151700ustar00rootroot00000000000000components build node_modules /lib /domains /setimmediate coverage package-lock.jsonpromise-8.3.0/.jshintrc000066400000000000000000000000641432572512200150300ustar00rootroot00000000000000{ "asi": true, "node": true, "strict": true } promise-8.3.0/.npmignore000066400000000000000000000001101432572512200151720ustar00rootroot00000000000000components node_modules test .gitignore .github component.json coverage promise-8.3.0/LICENSE000066400000000000000000000020431432572512200142070ustar00rootroot00000000000000Copyright (c) 2014 Forbes Lindesay Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. promise-8.3.0/Readme.md000066400000000000000000000264251432572512200147330ustar00rootroot00000000000000 # promise This is a simple implementation of Promises. It is a super set of ES6 Promises designed to have readable, performant code and to provide just the extensions that are absolutely necessary for using promises today. For detailed tutorials on its use, see www.promisejs.org **N.B.** This promise exposes internals via underscore (`_`) prefixed properties. If you use these, your code will break with each new release. [![Build Status](https://img.shields.io/github/workflow/status/then/promise/Publish%20Canary/master?style=for-the-badge)](https://github.com/then/promise/actions?query=workflow%3APublish%20Canary+branch%3Amaster) [![Rolling Versions](https://img.shields.io/badge/Rolling%20Versions-Enabled-brightgreen?style=for-the-badge)](https://rollingversions.com/then/promise) [![NPM version](https://img.shields.io/npm/v/promise?style=for-the-badge)](https://www.npmjs.com/package/promise) [![Downloads](https://img.shields.io/npm/dm/promise.svg?style=for-the-badge)](https://www.npmjs.org/package/promise) ## Installation **Server:** $ npm install promise **Client:** You can use browserify on the client, or use the pre-compiled script that acts as a polyfill. ```html ``` Note that the [es5-shim](https://github.com/es-shims/es5-shim) must be loaded before this library to support browsers pre IE9. ```html ``` ## Usage The example below shows how you can load the promise library (in a way that works on both client and server using node or browserify). It then demonstrates creating a promise from scratch. You simply call `new Promise(fn)`. There is a complete specification for what is returned by this method in [Promises/A+](http://promises-aplus.github.com/promises-spec/). ```javascript var Promise = require('promise'); var promise = new Promise(function (resolve, reject) { get('http://www.google.com', function (err, res) { if (err) reject(err); else resolve(res); }); }); ``` If you need [domains](https://nodejs.org/api/domain.html) support, you should instead use: ```js var Promise = require('promise/domains'); ``` If you are in an environment that implements `setImmediate` and don't want the optimisations provided by asap, you can use: ```js var Promise = require('promise/setimmediate'); ``` If you only want part of the features, e.g. just a pure ES6 polyfill: ```js var Promise = require('promise/lib/es6-extensions'); // or require('promise/domains/es6-extensions'); // or require('promise/setimmediate/es6-extensions'); ``` ## Unhandled Rejections By default, promises silence any unhandled rejections. You can enable logging of unhandled ReferenceErrors and TypeErrors via: ```js require('promise/lib/rejection-tracking').enable(); ``` Due to the performance cost, you should only do this during development. You can enable logging of all unhandled rejections if you need to debug an exception you think is being swallowed by promises: ```js require('promise/lib/rejection-tracking').enable( {allRejections: true} ); ``` Due to the high probability of false positives, I only recommend using this when debugging specific issues that you think may be being swallowed. For the preferred debugging method, see `Promise#done(onFulfilled, onRejected)`. `rejection-tracking.enable(options)` takes the following options: - allRejections (`boolean`) - track all exceptions, not just reference errors and type errors. Note that this has a high probability of resulting in false positives if your code loads data optimistically - whitelist (`Array`) - this defaults to `[ReferenceError, TypeError]` but you can override it with your own list of error constructors to track. - `onUnhandled(id, error)` and `onHandled(id, error)` - you can use these to provide your own customised display for errors. Note that if possible you should indicate that the error was a false positive if `onHandled` is called. `onHandled` is only called if `onUnhandled` has already been called. To reduce the chance of false-positives there is a delay of up to 2 seconds before errors are logged. This means that if you attach an error handler within 2 seconds, it won't be logged as a false positive. ReferenceErrors and TypeErrors are only subject to a 100ms delay due to the higher likelihood that the error is due to programmer error. ## API Detailed API reference docs are available at https://www.promisejs.org/api/. Before all examples, you will need: ```js var Promise = require('promise'); ``` ### new Promise(resolver) This creates and returns a new promise. `resolver` must be a function. The `resolver` function is passed two arguments: 1. `resolve` should be called with a single argument. If it is called with a non-promise value then the promise is fulfilled with that value. If it is called with a promise (A) then the returned promise takes on the state of that new promise (A). 2. `reject` should be called with a single argument. The returned promise will be rejected with that argument. ### Static Functions These methods are invoked by calling `Promise.methodName`. #### Promise.resolve(value) (deprecated aliases: `Promise.from(value)`, `Promise.cast(value)`) Converts values and foreign promises into Promises/A+ promises. If you pass it a value then it returns a Promise for that value. If you pass it something that is close to a promise (such as a jQuery attempt at a promise) it returns a Promise that takes on the state of `value` (rejected or fulfilled). #### Promise.reject(value) Returns a rejected promise with the given value. #### Promise.all(array) Returns a promise for an array. If it is called with a single argument that `Array.isArray` then this returns a promise for a copy of that array with any promises replaced by their fulfilled values. e.g. ```js Promise.all([Promise.resolve('a'), 'b', Promise.resolve('c')]) .then(function (res) { assert(res[0] === 'a') assert(res[1] === 'b') assert(res[2] === 'c') }) ``` #### Promise.any(array) Returns a single promise that fulfills as soon as any of the promises in the iterable fulfills, with the value of the fulfilled promise. If no promises in the iterable fulfill (if all of the given promises are rejected), then the returned promise is rejected with an `AggregateError` ```js var rejected = Promise.reject(0); var first = new Promise(function (resolve){ setTimeout(resolve, 100, 'quick') }); var second = new Promise(function (resolve){ setTimeout(resolve, 500, 'slow') }); var promises = [rejected, first, second]; Promise.any(promises) // => succeeds with `quick` ``` #### Promise.allSettled(array) Returns a promise that resolves after all of the given promises have either fulfilled or rejected, with an array of objects that each describes the outcome of each promise. ```js Promise.allSettled([Promise.resolve('a'), Promise.reject('error'), Promise.resolve('c')]) .then(function (res) { res[0] // { status: "fulfilled", value: 'a' } res[1] // { status: "rejected", reason: 'error' } res[2] // { status: "fulfilled", value: 'c' } }) ``` #### Promise.race(array) Returns a promise that resolves or rejects with the result of the first promise to resolve/reject, e.g. ```js var rejected = Promise.reject(new Error('Whatever')); var fulfilled = new Promise(function (resolve) { setTimeout(() => resolve('success'), 500); }); var race = Promise.race([rejected, fulfilled]); // => immediately rejected with `new Error('Whatever')` var success = Promise.resolve('immediate success'); var first = Promise.race([success, fulfilled]); // => immediately succeeds with `immediate success` ``` #### Promise.denodeify(fn) _Non Standard_ Takes a function which accepts a node style callback and returns a new function that returns a promise instead. e.g. ```javascript var fs = require('fs') var read = Promise.denodeify(fs.readFile) var write = Promise.denodeify(fs.writeFile) var p = read('foo.json', 'utf8') .then(function (str) { return write('foo.json', JSON.stringify(JSON.parse(str), null, ' '), 'utf8') }) ``` #### Promise.nodeify(fn) _Non Standard_ The twin to `denodeify` is useful when you want to export an API that can be used by people who haven't learnt about the brilliance of promises yet. ```javascript module.exports = Promise.nodeify(awesomeAPI) function awesomeAPI(a, b) { return download(a, b) } ``` If the last argument passed to `module.exports` is a function, then it will be treated like a node.js callback and not parsed on to the child function, otherwise the API will just return a promise. ### Prototype Methods These methods are invoked on a promise instance by calling `myPromise.methodName` ### Promise#then(onFulfilled, onRejected) This method follows the [Promises/A+ spec](http://promises-aplus.github.io/promises-spec/). It explains things very clearly so I recommend you read it. Either `onFulfilled` or `onRejected` will be called and they will not be called more than once. They will be passed a single argument and will always be called asynchronously (in the next turn of the event loop). If the promise is fulfilled then `onFulfilled` is called. If the promise is rejected then `onRejected` is called. The call to `.then` also returns a promise. If the handler that is called returns a promise, the promise returned by `.then` takes on the state of that returned promise. If the handler that is called returns a value that is not a promise, the promise returned by `.then` will be fulfilled with that value. If the handler that is called throws an exception then the promise returned by `.then` is rejected with that exception. #### Promise#catch(onRejected) Sugar for `Promise#then(null, onRejected)`, to mirror `catch` in synchronous code. #### Promise#done(onFulfilled, onRejected) _Non Standard_ The same semantics as `.then` except that it does not return a promise and any exceptions are re-thrown so that they can be logged (crashing the application in non-browser environments) #### Promise#nodeify(callback) _Non Standard_ If `callback` is `null` or `undefined` it just returns `this`. If `callback` is a function it is called with rejection reason as the first argument and result as the second argument (as per the node.js convention). This lets you write API functions that look like: ```javascript function awesomeAPI(foo, bar, callback) { return internalAPI(foo, bar) .then(parseResult) .then(null, retryErrors) .nodeify(callback) } ``` People who use typical node.js style callbacks will be able to just pass a callback and get the expected behavior. The enlightened people can not pass a callback and will get awesome promises. ## Enterprise Support Available as part of the Tidelift Subscription The maintainers of promise and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-promise?utm_source=npm-promise&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) ## License MIT promise-8.3.0/build.js000066400000000000000000000043631432572512200146460ustar00rootroot00000000000000'use strict'; var fs = require('fs'); var rimraf = require('rimraf'); var acorn = require('acorn'); var walk = require('acorn/dist/walk'); var crypto = require('crypto'); var shasum = crypto.createHash('sha512'); fs.readdirSync(__dirname + '/src').sort().forEach(function (filename) { shasum.update(fs.readFileSync(__dirname + '/src/' + filename, 'utf8')); }); const names = {}; const characterSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; let i = characterSet.indexOf(shasum.digest('base64').replace(/[^0-9a-zA-Z]/g, '')[0]); function getIdFor(name) { if (names[name]) return names[name]; return names[name] = '_' + characterSet[i++ % characterSet.length] } function fixup(src) { var ast = acorn.parse(src); src = src.split(''); walk.simple(ast, { MemberExpression: function (node) { if (node.computed) return; if (node.property.type !== 'Identifier') return; if (node.property.name[0] !== '_') return; replace(node.property, getIdFor(node.property.name)); } }); function replace(node, str) { for (var i = node.start; i < node.end; i++) { src[i] = ''; } src[node.start] = str; } return src.join(''); } rimraf.sync(__dirname + '/lib/'); fs.mkdirSync(__dirname + '/lib/'); fs.readdirSync(__dirname + '/src').forEach(function (filename) { var src = fs.readFileSync(__dirname + '/src/' + filename, 'utf8'); var out = fixup(src); fs.writeFileSync(__dirname + '/lib/' + filename, out); }); rimraf.sync(__dirname + '/domains/'); fs.mkdirSync(__dirname + '/domains/'); fs.readdirSync(__dirname + '/src').forEach(function (filename) { var src = fs.readFileSync(__dirname + '/src/' + filename, 'utf8'); var out = fixup(src); out = out.replace(/require\(\'asap\/raw\'\)/g, "require('asap')"); fs.writeFileSync(__dirname + '/domains/' + filename, out); }); rimraf.sync(__dirname + '/setimmediate/'); fs.mkdirSync(__dirname + '/setimmediate/'); fs.readdirSync(__dirname + '/src').forEach(function (filename) { var src = fs.readFileSync(__dirname + '/src/' + filename, 'utf8'); var out = fixup(src); out = out.replace(/var asap \= require\(\'([a-z\/]+)\'\);/g, ''); out = out.replace(/asap/g, "setImmediate"); fs.writeFileSync(__dirname + '/setimmediate/' + filename, out); }); promise-8.3.0/component.json000066400000000000000000000006501432572512200161010ustar00rootroot00000000000000{ "name": "promise", "repo": "then/promise", "description": "Bare bones Promises/A+ implementation", "version": "8.1.0", "keywords": [], "dependencies": { "johntron/asap": "*" }, "development": {}, "license": "MIT", "main": "index.js", "scripts": [ "index.js", "lib/core.js", "lib/done.js", "lib/es6-extensions.js", "lib/node-extensions.js" ], "twitter": "@ForbesLindesay" }promise-8.3.0/core.js000066400000000000000000000002351432572512200144710ustar00rootroot00000000000000'use strict'; module.exports = require('./lib/core.js'); console.error('require("promise/core") is deprecated, use require("promise/lib/core") instead.'); promise-8.3.0/index.d.ts000066400000000000000000000437071432572512200151170ustar00rootroot00000000000000/** * Represents the completion of an asynchronous operation */ interface ThenPromise extends Promise { /** * Attaches callbacks for the resolution and/or rejection of the ThenPromise. * @param onfulfilled The callback to execute when the ThenPromise is resolved. * @param onrejected The callback to execute when the ThenPromise is rejected. * @returns A ThenPromise for the completion of which ever callback is executed. */ then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): ThenPromise; /** * Attaches a callback for only the rejection of the ThenPromise. * @param onrejected The callback to execute when the ThenPromise is rejected. * @returns A ThenPromise for the completion of the callback. */ catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): ThenPromise; // Extensions specific to then/promise /** * Attaches callbacks for the resolution and/or rejection of the ThenPromise, without returning a new promise. * @param onfulfilled The callback to execute when the ThenPromise is resolved. * @param onrejected The callback to execute when the ThenPromise is rejected. */ done(onfulfilled?: ((value: T) => any) | undefined | null, onrejected?: ((reason: any) => any) | undefined | null): void; /** * Calls a node.js style callback. If none is provided, the promise is returned. */ nodeify(callback: void | null): ThenPromise; nodeify(callback: (err: Error, value: T) => void): void; } interface PromiseFulfilledResult { status: "fulfilled"; value: T; } interface PromiseRejectedResult { status: "rejected"; reason: any; } type PromiseSettledResult = PromiseFulfilledResult | PromiseRejectedResult; interface ThenPromiseConstructor { /** * A reference to the prototype. */ readonly prototype: ThenPromise; /** * Creates a new ThenPromise. * @param executor A callback used to initialize the promise. This callback is passed two arguments: * a resolve callback used resolve the promise with a value or the result of another promise, * and a reject callback used to reject the promise with a provided reason or error. */ new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => any): ThenPromise; /** * The any function returns a promise that is fulfilled by the first given promise to be fulfilled, or rejected with an AggregateError containing an array of rejection reasons if all of the given promises are rejected. It resolves all elements of the passed iterable to promises as it runs this algorithm. * @param values An array or iterable of Promises. * @returns A new Promise. */ any(values: T): Promise>; /** * The any function returns a promise that is fulfilled by the first given promise to be fulfilled, or rejected with an AggregateError containing an array of rejection reasons if all of the given promises are rejected. It resolves all elements of the passed iterable to promises as it runs this algorithm. * @param values An array or iterable of Promises. * @returns A new Promise. */ any(values: Iterable>): Promise> /** * Creates a Promise that is resolved with an array of results when all * of the provided Promises resolve or reject. * @param values An array of Promises. * @returns A new Promise. */ allSettled(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): ThenPromise<[PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult]>; /** * Creates a Promise that is resolved with an array of results when all * of the provided Promises resolve or reject. * @param values An array of Promises. * @returns A new Promise. */ allSettled(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): ThenPromise<[PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult]>; /** * Creates a Promise that is resolved with an array of results when all * of the provided Promises resolve or reject. * @param values An array of Promises. * @returns A new Promise. */ allSettled(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): ThenPromise<[PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult]>; /** * Creates a Promise that is resolved with an array of results when all * of the provided Promises resolve or reject. * @param values An array of Promises. * @returns A new Promise. */ allSettled(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): ThenPromise<[PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult]>; /** * Creates a Promise that is resolved with an array of results when all * of the provided Promises resolve or reject. * @param values An array of Promises. * @returns A new Promise. */ allSettled(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike]): ThenPromise<[PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult]>; /** * Creates a Promise that is resolved with an array of results when all * of the provided Promises resolve or reject. * @param values An array of Promises. * @returns A new Promise. */ allSettled(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike]): ThenPromise<[PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult]>; /** * Creates a Promise that is resolved with an array of results when all * of the provided Promises resolve or reject. * @param values An array of Promises. * @returns A new Promise. */ allSettled(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike ]): ThenPromise<[PromiseSettledResult, PromiseSettledResult, PromiseSettledResult, PromiseSettledResult]>; /** * Creates a Promise that is resolved with an array of results when all * of the provided Promises resolve or reject. * @param values An array of Promises. * @returns A new Promise. */ allSettled(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): ThenPromise<[PromiseSettledResult, PromiseSettledResult, PromiseSettledResult]>; /** * Creates a Promise that is resolved with an array of results when all * of the provided Promises resolve or reject. * @param values An array of Promises. * @returns A new Promise. */ allSettled(values: [T1 | PromiseLike, T2 | PromiseLike]): ThenPromise<[PromiseSettledResult, PromiseSettledResult]>; /** * Creates a Promise that is resolved with an array of results when all * of the provided Promises resolve or reject. * @param values An array of Promises. * @returns A new Promise. */ allSettled(values: (T | PromiseLike)[]): ThenPromise[]>; /** * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises * resolve, or rejected when any ThenPromise is rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; /** * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises * resolve, or rejected when any ThenPromise is rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; /** * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises * resolve, or rejected when any ThenPromise is rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7, T8]>; /** * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises * resolve, or rejected when any ThenPromise is rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7]>; /** * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises * resolve, or rejected when any ThenPromise is rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6]>; /** * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises * resolve, or rejected when any ThenPromise is rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5]>; /** * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises * resolve, or rejected when any ThenPromise is rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike ]): ThenPromise<[T1, T2, T3, T4]>; /** * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises * resolve, or rejected when any ThenPromise is rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): ThenPromise<[T1, T2, T3]>; /** * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises * resolve, or rejected when any ThenPromise is rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ all(values: [T1 | PromiseLike, T2 | PromiseLike]): ThenPromise<[T1, T2]>; /** * Creates a ThenPromise that is resolved with an array of results when all of the provided Promises * resolve, or rejected when any ThenPromise is rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ all(values: (T | PromiseLike)[]): ThenPromise; /** * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved * or rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): ThenPromise; /** * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved * or rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): ThenPromise; /** * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved * or rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): ThenPromise; /** * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved * or rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): ThenPromise; /** * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved * or rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): ThenPromise; /** * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved * or rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): ThenPromise; /** * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved * or rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): ThenPromise; /** * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved * or rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): ThenPromise; /** * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved * or rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ race(values: [T1 | PromiseLike, T2 | PromiseLike]): ThenPromise; /** * Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved * or rejected. * @param values An array of Promises. * @returns A new ThenPromise. */ race(values: (T | PromiseLike)[]): ThenPromise; /** * Creates a new rejected promise for the provided reason. * @param reason The reason the promise was rejected. * @returns A new rejected ThenPromise. */ reject(reason: any): ThenPromise; /** * Creates a new rejected promise for the provided reason. * @param reason The reason the promise was rejected. * @returns A new rejected ThenPromise. */ reject(reason: any): ThenPromise; /** * Creates a new resolved promise for the provided value. * @param value A promise. * @returns A promise whose internal state matches the provided promise. */ resolve(value: T | PromiseLike): ThenPromise; /** * Creates a new resolved promise . * @returns A resolved promise. */ resolve(): ThenPromise; // Extensions specific to then/promise denodeify: (fn: Function) => (...args: any[]) => ThenPromise; nodeify: (fn: Function) => Function; } declare var ThenPromise: ThenPromiseConstructor; export = ThenPromise; promise-8.3.0/index.js000066400000000000000000000000611432572512200146450ustar00rootroot00000000000000'use strict'; module.exports = require('./lib') promise-8.3.0/index.js.flow000066400000000000000000000033041432572512200156160ustar00rootroot00000000000000// @flow declare class ThenPromise<+R> extends Promise { constructor(callback: ( resolve: (result: Promise | R) => void, reject: (error: any) => void ) => mixed): void; then(onFulfill: null | void, onReject: null | void): ThenPromise; then( onFulfill: null | void, onReject: (error: any) => Promise | U ): ThenPromise; then( onFulfill: (value: R) => Promise | U, onReject: null | void | ((error: any) => Promise | U) ): ThenPromise; catch(onReject: null | void): ThenPromise; catch( onReject: (error: any) => Promise | U ): ThenPromise; // Extensions specific to then/promise /** * Attaches callbacks for the resolution and/or rejection of the ThenPromise, without returning a new promise. * @param onfulfilled The callback to execute when the ThenPromise is resolved. * @param onrejected The callback to execute when the ThenPromise is rejected. */ done(onfulfilled?: (value: R) => any, onrejected?: (reason: any) => any): void; /** * Calls a node.js style callback. If none is provided, the promise is returned. */ nodeify(callback: void | null): ThenPromise; nodeify(callback: (err: Error, value: R) => void): void; static resolve(object: Promise | T): ThenPromise; static reject(error?: any): ThenPromise; static all>(promises: T): ThenPromise<$TupleMap>; static race | T>(promises: Iterable): ThenPromise; // Extensions specific to then/promise static denodeify(fn: Function): (...args: any[]) => ThenPromise; static nodeify(fn: Function): Function; } module.exports = ThenPromise; promise-8.3.0/package.json000066400000000000000000000021261432572512200154720ustar00rootroot00000000000000{ "name": "promise", "version": "8.1.0", "description": "Bare bones Promises/A+ implementation", "main": "index.js", "scripts": { "build": "node build", "pretest": "node build", "pretest-resolve": "node build", "pretest-extensions": "node build", "pretest-memory-leak": "node build", "test": "mocha --bail --timeout 200 --slow 99999 -R dot && npm run test-memory-leak", "test-resolve": "mocha test/resolver-tests.js --timeout 200 --slow 999999", "test-extensions": "mocha test/extensions-tests.js --timeout 200 --slow 999999", "test-memory-leak": "node --expose-gc test/memory-leak.js", "coverage": "istanbul cover node_modules/mocha/bin/_mocha -- --bail --timeout 200 --slow 99999 -R dot" }, "repository": { "type": "git", "url": "https://github.com/then/promise.git" }, "author": "ForbesLindesay", "license": "MIT", "devDependencies": { "acorn": "^1.0.1", "better-assert": "*", "istanbul": "^0.3.13", "mocha": "*", "promises-aplus-tests": "*", "rimraf": "^2.3.2" }, "dependencies": { "asap": "~2.0.6" } }promise-8.3.0/polyfill-done.js000066400000000000000000000005361432572512200163220ustar00rootroot00000000000000// should work in any browser without browserify if (typeof Promise.prototype.done !== 'function') { Promise.prototype.done = function (onFulfilled, onRejected) { var self = arguments.length ? this.then.apply(this, arguments) : this self.then(null, function (err) { setTimeout(function () { throw err }, 0) }) } }promise-8.3.0/polyfill.js000066400000000000000000000003471432572512200153770ustar00rootroot00000000000000// not "use strict" so we can declare global "Promise" var asap = require('asap'); if (typeof Promise === 'undefined') { Promise = require('./lib/core.js') require('./lib/es6-extensions.js') } require('./polyfill-done.js'); promise-8.3.0/src/000077500000000000000000000000001432572512200137725ustar00rootroot00000000000000promise-8.3.0/src/core.js000066400000000000000000000117471432572512200152720ustar00rootroot00000000000000'use strict'; var asap = require('asap/raw'); function noop() {} // States: // // 0 - pending // 1 - fulfilled with _value // 2 - rejected with _value // 3 - adopted the state of another promise, _value // // once the state is no longer pending (0) it is immutable // All `_` prefixed properties will be reduced to `_{random number}` // at build time to obfuscate them and discourage their use. // We don't use symbols or Object.defineProperty to fully hide them // because the performance isn't good enough. // to avoid using try/catch inside critical functions, we // extract them to here. var LAST_ERROR = null; var IS_ERROR = {}; function getThen(obj) { try { return obj.then; } catch (ex) { LAST_ERROR = ex; return IS_ERROR; } } function tryCallOne(fn, a) { try { return fn(a); } catch (ex) { LAST_ERROR = ex; return IS_ERROR; } } function tryCallTwo(fn, a, b) { try { fn(a, b); } catch (ex) { LAST_ERROR = ex; return IS_ERROR; } } module.exports = Promise; function Promise(fn) { if (typeof this !== 'object') { throw new TypeError('Promises must be constructed via new'); } if (typeof fn !== 'function') { throw new TypeError('Promise constructor\'s argument is not a function'); } this._deferredState = 0; this._state = 0; this._value = null; this._deferreds = null; if (fn === noop) return; doResolve(fn, this); } Promise._onHandle = null; Promise._onReject = null; Promise._noop = noop; Promise.prototype.then = function(onFulfilled, onRejected) { if (this.constructor !== Promise) { return safeThen(this, onFulfilled, onRejected); } var res = new Promise(noop); handle(this, new Handler(onFulfilled, onRejected, res)); return res; }; function safeThen(self, onFulfilled, onRejected) { return new self.constructor(function (resolve, reject) { var res = new Promise(noop); res.then(resolve, reject); handle(self, new Handler(onFulfilled, onRejected, res)); }); } function handle(self, deferred) { while (self._state === 3) { self = self._value; } if (Promise._onHandle) { Promise._onHandle(self); } if (self._state === 0) { if (self._deferredState === 0) { self._deferredState = 1; self._deferreds = deferred; return; } if (self._deferredState === 1) { self._deferredState = 2; self._deferreds = [self._deferreds, deferred]; return; } self._deferreds.push(deferred); return; } handleResolved(self, deferred); } function handleResolved(self, deferred) { asap(function() { var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; if (cb === null) { if (self._state === 1) { resolve(deferred.promise, self._value); } else { reject(deferred.promise, self._value); } return; } var ret = tryCallOne(cb, self._value); if (ret === IS_ERROR) { reject(deferred.promise, LAST_ERROR); } else { resolve(deferred.promise, ret); } }); } function resolve(self, newValue) { // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure if (newValue === self) { return reject( self, new TypeError('A promise cannot be resolved with itself.') ); } if ( newValue && (typeof newValue === 'object' || typeof newValue === 'function') ) { var then = getThen(newValue); if (then === IS_ERROR) { return reject(self, LAST_ERROR); } if ( then === self.then && newValue instanceof Promise ) { self._state = 3; self._value = newValue; finale(self); return; } else if (typeof then === 'function') { doResolve(then.bind(newValue), self); return; } } self._state = 1; self._value = newValue; finale(self); } function reject(self, newValue) { self._state = 2; self._value = newValue; if (Promise._onReject) { Promise._onReject(self, newValue); } finale(self); } function finale(self) { if (self._deferredState === 1) { handle(self, self._deferreds); self._deferreds = null; } if (self._deferredState === 2) { for (var i = 0; i < self._deferreds.length; i++) { handle(self, self._deferreds[i]); } self._deferreds = null; } } function Handler(onFulfilled, onRejected, promise){ this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; this.onRejected = typeof onRejected === 'function' ? onRejected : null; this.promise = promise; } /** * Take a potentially misbehaving resolver function and make sure * onFulfilled and onRejected are only called once. * * Makes no guarantees about asynchrony. */ function doResolve(fn, promise) { var done = false; var res = tryCallTwo(fn, function (value) { if (done) return; done = true; resolve(promise, value); }, function (reason) { if (done) return; done = true; reject(promise, reason); }); if (!done && res === IS_ERROR) { done = true; reject(promise, LAST_ERROR); } } promise-8.3.0/src/done.js000066400000000000000000000004721432572512200152600ustar00rootroot00000000000000'use strict'; var Promise = require('./core.js'); module.exports = Promise; Promise.prototype.done = function (onFulfilled, onRejected) { var self = arguments.length ? this.then.apply(this, arguments) : this; self.then(null, function (err) { setTimeout(function () { throw err; }, 0); }); }; promise-8.3.0/src/es6-extensions.js000066400000000000000000000113311432572512200172210ustar00rootroot00000000000000'use strict'; //This file contains the ES6 extensions to the core Promises/A+ API var Promise = require('./core.js'); module.exports = Promise; /* Static Functions */ var TRUE = valuePromise(true); var FALSE = valuePromise(false); var NULL = valuePromise(null); var UNDEFINED = valuePromise(undefined); var ZERO = valuePromise(0); var EMPTYSTRING = valuePromise(''); function valuePromise(value) { var p = new Promise(Promise._noop); p._state = 1; p._value = value; return p; } Promise.resolve = function (value) { if (value instanceof Promise) return value; if (value === null) return NULL; if (value === undefined) return UNDEFINED; if (value === true) return TRUE; if (value === false) return FALSE; if (value === 0) return ZERO; if (value === '') return EMPTYSTRING; if (typeof value === 'object' || typeof value === 'function') { try { var then = value.then; if (typeof then === 'function') { return new Promise(then.bind(value)); } } catch (ex) { return new Promise(function (resolve, reject) { reject(ex); }); } } return valuePromise(value); }; var iterableToArray = function (iterable) { if (typeof Array.from === 'function') { // ES2015+, iterables exist iterableToArray = Array.from; return Array.from(iterable); } // ES5, only arrays and array-likes exist iterableToArray = function (x) { return Array.prototype.slice.call(x); }; return Array.prototype.slice.call(iterable); } Promise.all = function (arr) { var args = iterableToArray(arr); return new Promise(function (resolve, reject) { if (args.length === 0) return resolve([]); var remaining = args.length; function res(i, val) { if (val && (typeof val === 'object' || typeof val === 'function')) { if (val instanceof Promise && val.then === Promise.prototype.then) { while (val._state === 3) { val = val._value; } if (val._state === 1) return res(i, val._value); if (val._state === 2) reject(val._value); val.then(function (val) { res(i, val); }, reject); return; } else { var then = val.then; if (typeof then === 'function') { var p = new Promise(then.bind(val)); p.then(function (val) { res(i, val); }, reject); return; } } } args[i] = val; if (--remaining === 0) { resolve(args); } } for (var i = 0; i < args.length; i++) { res(i, args[i]); } }); }; function onSettledFulfill(value) { return { status: 'fulfilled', value: value }; } function onSettledReject(reason) { return { status: 'rejected', reason: reason }; } function mapAllSettled(item) { if(item && (typeof item === 'object' || typeof item === 'function')){ if(item instanceof Promise && item.then === Promise.prototype.then){ return item.then(onSettledFulfill, onSettledReject); } var then = item.then; if (typeof then === 'function') { return new Promise(then.bind(item)).then(onSettledFulfill, onSettledReject) } } return onSettledFulfill(item); } Promise.allSettled = function (iterable) { return Promise.all(iterableToArray(iterable).map(mapAllSettled)); }; Promise.reject = function (value) { return new Promise(function (resolve, reject) { reject(value); }); }; Promise.race = function (values) { return new Promise(function (resolve, reject) { iterableToArray(values).forEach(function(value){ Promise.resolve(value).then(resolve, reject); }); }); }; /* Prototype Methods */ Promise.prototype['catch'] = function (onRejected) { return this.then(null, onRejected); }; function getAggregateError(errors){ if(typeof AggregateError === 'function'){ return new AggregateError(errors,'All promises were rejected'); } var error = new Error('All promises were rejected'); error.name = 'AggregateError'; error.errors = errors; return error; } Promise.any = function promiseAny(values) { return new Promise(function(resolve, reject) { var promises = iterableToArray(values); var hasResolved = false; var rejectionReasons = []; function resolveOnce(value) { if (!hasResolved) { hasResolved = true; resolve(value); } } function rejectionCheck(reason) { rejectionReasons.push(reason); if (rejectionReasons.length === promises.length) { reject(getAggregateError(rejectionReasons)); } } if(promises.length === 0){ reject(getAggregateError(rejectionReasons)); } else { promises.forEach(function(value){ Promise.resolve(value).then(resolveOnce, rejectionCheck); }); } }); }; promise-8.3.0/src/finally.js000066400000000000000000000005311432572512200157650ustar00rootroot00000000000000'use strict'; var Promise = require('./core.js'); module.exports = Promise; Promise.prototype.finally = function (f) { return this.then(function (value) { return Promise.resolve(f()).then(function () { return value; }); }, function (err) { return Promise.resolve(f()).then(function () { throw err; }); }); }; promise-8.3.0/src/index.js000066400000000000000000000003031432572512200154330ustar00rootroot00000000000000'use strict'; module.exports = require('./core.js'); require('./done.js'); require('./finally.js'); require('./es6-extensions.js'); require('./node-extensions.js'); require('./synchronous.js'); promise-8.3.0/src/node-extensions.js000066400000000000000000000063071432572512200174600ustar00rootroot00000000000000'use strict'; // This file contains then/promise specific extensions that are only useful // for node.js interop var Promise = require('./core.js'); var asap = require('asap'); module.exports = Promise; /* Static Functions */ Promise.denodeify = function (fn, argumentCount) { if ( typeof argumentCount === 'number' && argumentCount !== Infinity ) { return denodeifyWithCount(fn, argumentCount); } else { return denodeifyWithoutCount(fn); } }; var callbackFn = ( 'function (err, res) {' + 'if (err) { rj(err); } else { rs(res); }' + '}' ); function denodeifyWithCount(fn, argumentCount) { var args = []; for (var i = 0; i < argumentCount; i++) { args.push('a' + i); } var body = [ 'return function (' + args.join(',') + ') {', 'var self = this;', 'return new Promise(function (rs, rj) {', 'var res = fn.call(', ['self'].concat(args).concat([callbackFn]).join(','), ');', 'if (res &&', '(typeof res === "object" || typeof res === "function") &&', 'typeof res.then === "function"', ') {rs(res);}', '});', '};' ].join(''); return Function(['Promise', 'fn'], body)(Promise, fn); } function denodeifyWithoutCount(fn) { var fnLength = Math.max(fn.length - 1, 3); var args = []; for (var i = 0; i < fnLength; i++) { args.push('a' + i); } var body = [ 'return function (' + args.join(',') + ') {', 'var self = this;', 'var args;', 'var argLength = arguments.length;', 'if (arguments.length > ' + fnLength + ') {', 'args = new Array(arguments.length + 1);', 'for (var i = 0; i < arguments.length; i++) {', 'args[i] = arguments[i];', '}', '}', 'return new Promise(function (rs, rj) {', 'var cb = ' + callbackFn + ';', 'var res;', 'switch (argLength) {', args.concat(['extra']).map(function (_, index) { return ( 'case ' + (index) + ':' + 'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' + 'break;' ); }).join(''), 'default:', 'args[argLength] = cb;', 'res = fn.apply(self, args);', '}', 'if (res &&', '(typeof res === "object" || typeof res === "function") &&', 'typeof res.then === "function"', ') {rs(res);}', '});', '};' ].join(''); return Function( ['Promise', 'fn'], body )(Promise, fn); } Promise.nodeify = function (fn) { return function () { var args = Array.prototype.slice.call(arguments); var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null; var ctx = this; try { return fn.apply(this, arguments).nodeify(callback, ctx); } catch (ex) { if (callback === null || typeof callback == 'undefined') { return new Promise(function (resolve, reject) { reject(ex); }); } else { asap(function () { callback.call(ctx, ex); }) } } } }; Promise.prototype.nodeify = function (callback, ctx) { if (typeof callback != 'function') return this; this.then(function (value) { asap(function () { callback.call(ctx, null, value); }); }, function (err) { asap(function () { callback.call(ctx, err); }); }); }; promise-8.3.0/src/rejection-tracking.js000066400000000000000000000056651432572512200201260ustar00rootroot00000000000000'use strict'; var Promise = require('./core'); var DEFAULT_WHITELIST = [ ReferenceError, TypeError, RangeError ]; var enabled = false; exports.disable = disable; function disable() { enabled = false; Promise._onHandle = null; Promise._onReject = null; } exports.enable = enable; function enable(options) { options = options || {}; if (enabled) disable(); enabled = true; var id = 0; var displayId = 0; var rejections = {}; Promise._onHandle = function (promise) { if ( promise._state === 2 && // IS REJECTED rejections[promise._rejectionId] ) { if (rejections[promise._rejectionId].logged) { onHandled(promise._rejectionId); } else { clearTimeout(rejections[promise._rejectionId].timeout); } delete rejections[promise._rejectionId]; } }; Promise._onReject = function (promise, err) { if (promise._deferredState === 0) { // not yet handled promise._rejectionId = id++; rejections[promise._rejectionId] = { displayId: null, error: err, timeout: setTimeout( onUnhandled.bind(null, promise._rejectionId), // For reference errors and type errors, this almost always // means the programmer made a mistake, so log them after just // 100ms // otherwise, wait 2 seconds to see if they get handled matchWhitelist(err, DEFAULT_WHITELIST) ? 100 : 2000 ), logged: false }; } }; function onUnhandled(id) { if ( options.allRejections || matchWhitelist( rejections[id].error, options.whitelist || DEFAULT_WHITELIST ) ) { rejections[id].displayId = displayId++; if (options.onUnhandled) { rejections[id].logged = true; options.onUnhandled( rejections[id].displayId, rejections[id].error ); } else { rejections[id].logged = true; logError( rejections[id].displayId, rejections[id].error ); } } } function onHandled(id) { if (rejections[id].logged) { if (options.onHandled) { options.onHandled(rejections[id].displayId, rejections[id].error); } else if (!rejections[id].onUnhandled) { console.warn( 'Promise Rejection Handled (id: ' + rejections[id].displayId + '):' ); console.warn( ' This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id ' + rejections[id].displayId + '.' ); } } } } function logError(id, error) { console.warn('Possible Unhandled Promise Rejection (id: ' + id + '):'); var errStr = (error && (error.stack || error)) + ''; errStr.split('\n').forEach(function (line) { console.warn(' ' + line); }); } function matchWhitelist(error, list) { return list.some(function (cls) { return error instanceof cls; }); }promise-8.3.0/src/synchronous.js000066400000000000000000000026301432572512200167230ustar00rootroot00000000000000'use strict'; var Promise = require('./core.js'); module.exports = Promise; Promise.enableSynchronous = function () { Promise.prototype.isPending = function() { return this.getState() == 0; }; Promise.prototype.isFulfilled = function() { return this.getState() == 1; }; Promise.prototype.isRejected = function() { return this.getState() == 2; }; Promise.prototype.getValue = function () { if (this._state === 3) { return this._value.getValue(); } if (!this.isFulfilled()) { throw new Error('Cannot get a value of an unfulfilled promise.'); } return this._value; }; Promise.prototype.getReason = function () { if (this._state === 3) { return this._value.getReason(); } if (!this.isRejected()) { throw new Error('Cannot get a rejection reason of a non-rejected promise.'); } return this._value; }; Promise.prototype.getState = function () { if (this._state === 3) { return this._value.getState(); } if (this._state === -1 || this._state === -2) { return 0; } return this._state; }; }; Promise.disableSynchronous = function() { Promise.prototype.isPending = undefined; Promise.prototype.isFulfilled = undefined; Promise.prototype.isRejected = undefined; Promise.prototype.getValue = undefined; Promise.prototype.getReason = undefined; Promise.prototype.getState = undefined; }; promise-8.3.0/test/000077500000000000000000000000001432572512200141625ustar00rootroot00000000000000promise-8.3.0/test/adapter-a.js000066400000000000000000000005361432572512200163620ustar00rootroot00000000000000var Promise = require('../'); exports.deferred = function () { var resolve, reject; var promise = new Promise(function (_resolve, _reject) { resolve = _resolve; reject = _reject; }); return { promise: promise, resolve: resolve, reject: reject }; }; exports.resolved = Promise.resolve; exports.rejected = Promise.reject;promise-8.3.0/test/extensions-tests.js000066400000000000000000000665611432572512200200750ustar00rootroot00000000000000var assert = require('better-assert') var Promise = require('../') var sentinel = {} var promise = new Promise(function (resolve) { resolve(sentinel) }) var thenable = {then: function (fulfilled, rejected) { fulfilled(sentinel) }} var thenableRejected = {then: function (fulfilled, rejected) { rejected(sentinel) }} var a = {} var b = {} var c = {} var A = Promise.resolve(a) var B = Promise.resolve(b) var C = Promise.resolve(c) var rejection = {} var rejected = new Promise(function (resolve, reject) { reject(rejection) }) describe('extensions', function () { describe('Promise.denodeify(fn, [argumentCount])', function () { it('returns a function that uses promises instead of callbacks', function (done) { function wrap(val, key, callback) { return callback(null, {val: val, key: key}) } var pwrap = Promise.denodeify(wrap) pwrap(sentinel, 'foo') .then(function (wrapper) { assert(wrapper.val === sentinel) assert(wrapper.key === 'foo') done() }) }) it('converts callback error arguments into rejection', function (done) { function fail(val, key, callback) { return callback(sentinel) } var pfail = Promise.denodeify(fail) pfail(promise, 'foo') .then(null, function (err) { assert(err === sentinel) done() }) }) it('with an argumentCount it ignores extra arguments', function (done) { function wrap(val, key, callback) { return callback(null, {val: val, key: key}) } var pwrap = Promise.denodeify(wrap, 2) pwrap(sentinel, 'foo', 'wtf') .then(function (wrapper) { assert(wrapper.val === sentinel) assert(wrapper.key === 'foo') done() }) }) it('resolves correctly when the wrapped function returns a promise anyway', function (done) { function wrap(val, key, callback) { return new Promise(function(resolve, reject) { resolve({val: val, key: key}) }) } var pwrap = Promise.denodeify(wrap) pwrap(sentinel, 'foo') .then(function (wrapper) { assert(wrapper.val === sentinel) assert(wrapper.key === 'foo') done() }) }) }) describe('Promise.nodeify(fn)', function () { it('converts a promise returning function into a callback function', function (done) { var add = Promise.nodeify(function (a, b) { return Promise.resolve(a) .then(function (a) { return a + b }) }) add(1, 2, function (err, res) { if (err) return done(err) assert(res === 3) return done() }) }) it('converts rejected promises into the first argument of the callback', function (done) { var add = Promise.nodeify(function (a, b) { return Promise.resolve(a) .then(function (a) { throw sentinel }) }) var add2 = Promise.nodeify(function (a, b) { throw sentinel }) add(1, 2, function (err, res) { assert(err === sentinel) add2(1, 2, function (err, res){ assert(err === sentinel) done() }) }) }) it('passes through when no callback is provided', function (done) { var add = Promise.nodeify(function (a, b) { return Promise.resolve(a) .then(function (a) { return a + b }) }) add(1, 2) .then(function (res) { assert(res === 3) done() }) }) it('passes through the `this` argument', function (done) { var ctx = {} var add = Promise.nodeify(function (a, b) { return Promise.resolve(a) .then(function (a) { return a + b }) }) add.call(ctx, 1, 2, function (err, res) { assert(res === 3) assert(this === ctx) done() }) }) }) describe('Promise.any(...)', function () { describe('an array', function () { describe('that is empty', function () { it('returns a rejected promise for an empty array', function (done) { var res = Promise.any([]) assert(res instanceof Promise) res.catch(function (err) { assert(Array.isArray(err.errors)) assert(err.errors.length === 0) }).nodeify(done) }) it('returns a rejected promise for not argument', function (done) { var res = Promise.any() assert(res instanceof Promise) res.catch(function (err) { assert(err instanceof Error) }).nodeify(done) }) }) describe('of objects', function () { it('resolved with a first fulfilled value', function (done) { var res = Promise.any([a, b, c]) assert(res instanceof Promise) res.then(function (res) { assert(a === res) }).nodeify(done) }) }) describe('of promises', function () { it('resolved with a first fulfilled value', function (done) { var res = Promise.any([B, C]) assert(res instanceof Promise) res.then(function (res) { assert(b === res) }).nodeify(done) }) }) describe('of mixed values', function () { it('returns a promise for an array containing the fulfilled values', function (done) { var res = Promise.any([c,B]) assert(res instanceof Promise) res.then(function (res) { assert(res === c) }).nodeify(done) }) }) describe('containing all rejected promise', function () { it('rejects the resulting promise', function (done) { var rejectionB ={test:2} var rejectedB = new Promise(function (resolve, reject) { reject(rejectionB) }) var res = Promise.any([rejected, rejectedB]) assert(res instanceof Promise) res.catch(function (err) { assert(Array.isArray(err.errors)) assert(err.errors[0] === rejection) assert(err.errors[1] === rejectionB) assert(err.errors.length === 2) }).nodeify(done) }) }) describe('when given a foreign promise', function () { it('should provide the correct value of `this`', function (done) { var p = {then: function (onFulfilled) { onFulfilled({self: this}); }}; Promise.any([p]).then(function (results) { assert(p === results.self); }).nodeify(done); }); }); }) }) describe('Promise.allSettled(...)', function () { describe('an array', function () { describe('that is empty', function () { it('returns a promise for an empty array', function (done) { var res = Promise.allSettled([]) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res.length === 0) }) .nodeify(done) }) }) describe('of objects', function () { it('returns a promise for the array', function (done) { var res = Promise.allSettled([a, b, c]) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0].status === "fulfilled") assert(res[0].value === a) assert(res[1].status === "fulfilled") assert(res[1].value === b) assert(res[2].status === "fulfilled") assert(res[2].value === c) }) .nodeify(done) }) }) describe('of promises', function () { it('returns a promise for an array containing the fulfilled values', function (done) { var d = {} var resolveD var res = Promise.allSettled([A, B, C, new Promise(function (resolve) { resolveD = resolve })]) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0].status === "fulfilled") assert(res[0].value === a) assert(res[1].status === "fulfilled") assert(res[1].value === b) assert(res[2].status === "fulfilled") assert(res[2].value === c) assert(res[3].status === "fulfilled") assert(res[3].value === d) }) .nodeify(done) resolveD(d) }) }) describe('of mixed values', function () { it('returns a promise for an array containing the fulfilled values', function (done) { var res = Promise.allSettled([A, b, C]) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0].status === "fulfilled") assert(res[0].value === a) assert(res[1].status === "fulfilled") assert(res[1].value === b) assert(res[2].status === "fulfilled") assert(res[2].value === c) }) .nodeify(done) }) }) describe('containing at least one rejected promise', function () { it('should not rejects the resulting promise', function (done) { var res = Promise.allSettled([A, rejected, C]) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0].status === "fulfilled") assert(res[0].value === a) assert(res[1].status === "rejected") assert(res[1].reason === rejection) assert(res[2].status === "fulfilled") assert(res[2].value === c) }) .nodeify(done) }) }) describe('containing at least one eventually rejected promise', function () { it('rejects the resulting promise', function (done) { var rejectB var rejected = new Promise(function (resolve, reject) { rejectB = reject }) var res = Promise.allSettled([A, rejected, C]) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0].status === "fulfilled") assert(res[0].value === a) assert(res[1].status === "rejected") assert(res[1].reason === rejection) assert(res[2].status === "fulfilled") assert(res[2].value === c) }) .nodeify(done) rejectB(rejection) }) }) describe('with a promise that resolves twice', function () { it('still waits for all the other promises', function (done) { var a = 1; var fakePromise = {then: function (onFulfilled) { onFulfilled(a); onFulfilled(2) }} var eventuallyRejected = {then: function (_, onRejected) { this.onRejected = onRejected }} var res = Promise.allSettled([fakePromise, eventuallyRejected]) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0].status === "fulfilled") assert(res[0].value === a) assert(res[1].status === "rejected") assert(res[1].reason === rejection) }) .nodeify(done) eventuallyRejected.onRejected(rejection); }) }) describe('when given a foreign promise', function () { it('should provide the correct value of `this`', function (done) { var p = {then: function (onFulfilled) { onFulfilled({self: this}); }}; Promise.allSettled([p]).then(function (results) { assert(p === results[0].value.self); }).nodeify(done); }); }); }) describe('a Set', function () { describe('that is empty', function () { it('returns a promise for an empty array', function (done) { var res = Promise.allSettled(new Set([])) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res.length === 0) }) .nodeify(done) }) }) describe('of objects', function () { it('returns a promise for the array', function (done) { var res = Promise.allSettled(new Set([a, b, c])) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0].status === "fulfilled") assert(res[0].value === a) assert(res[1].status === "fulfilled") assert(res[1].value === b) assert(res[2].status === "fulfilled") assert(res[2].value === c) }) .nodeify(done) }) }) describe('of promises', function () { it('returns a promise for an array containing the fulfilled values', function (done) { var d = {} var resolveD var res = Promise.allSettled(new Set([A, B, C, new Promise(function (resolve) { resolveD = resolve })])) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0].status === "fulfilled") assert(res[0].value === a) assert(res[1].status === "fulfilled") assert(res[1].value === b) assert(res[2].status === "fulfilled") assert(res[2].value === c) assert(res[3].status === "fulfilled") assert(res[3].value === d) }) .nodeify(done) resolveD(d) }) }) describe('of mixed values', function () { it('returns a promise for an array containing the fulfilled values', function (done) { var res = Promise.allSettled(new Set([A, b, C])) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0].status === "fulfilled") assert(res[0].value === a) assert(res[1].status === "fulfilled") assert(res[1].value === b) assert(res[2].status === "fulfilled") assert(res[2].value === c) }) .nodeify(done) }) }) describe('containing at least one rejected promise', function () { it('rejects the resulting promise', function (done) { var res = Promise.allSettled(new Set([A, rejected, C])) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0].status === "fulfilled") assert(res[0].value === a) assert(res[1].status === "rejected") assert(res[1].reason === rejection) assert(res[2].status === "fulfilled") assert(res[2].value === c) }) .nodeify(done) }) }) describe('containing at least one eventually rejected promise', function () { it('rejects the resulting promise', function (done) { var rejectB var rejected = new Promise(function (resolve, reject) { rejectB = reject }) var res = Promise.allSettled(new Set([A, rejected, C])) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0].status === "fulfilled") assert(res[0].value === a) assert(res[1].status === "rejected") assert(res[1].reason === rejection) assert(res[2].status === "fulfilled") assert(res[2].value === c) }) .nodeify(done) rejectB(rejection) }) }) describe('with a promise that resolves twice', function () { it('still waits for all the other promises', function (done) { var a = 1 var fakePromise = {then: function (onFulfilled) { onFulfilled(a); onFulfilled(2) }} var eventuallyRejected = {then: function (_, onRejected) { this.onRejected = onRejected }} var res = Promise.allSettled(new Set([fakePromise, eventuallyRejected])) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0].status === "fulfilled") assert(res[0].value === a) assert(res[1].status === "rejected") assert(res[1].reason === rejection) }) .nodeify(done) eventuallyRejected.onRejected(rejection); }) }) describe('when given a foreign promise', function () { it('should provide the correct value of `this`', function (done) { var p = {then: function (onFulfilled) { onFulfilled({self: this}); }}; Promise.allSettled(new Set([p])).then(function (results) { assert(p === results[0].value.self); }).nodeify(done); }); }); }) }) describe('Promise.all(...)', function () { describe('an array', function () { describe('that is empty', function () { it('returns a promise for an empty array', function (done) { var res = Promise.all([]) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res.length === 0) }) .nodeify(done) }) }) describe('of objects', function () { it('returns a promise for the array', function (done) { var res = Promise.all([a, b, c]) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0] === a) assert(res[1] === b) assert(res[2] === c) }) .nodeify(done) }) }) describe('of promises', function () { it('returns a promise for an array containing the fulfilled values', function (done) { var d = {} var resolveD var res = Promise.all([A, B, C, new Promise(function (resolve) { resolveD = resolve })]) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0] === a) assert(res[1] === b) assert(res[2] === c) assert(res[3] === d) }) .nodeify(done) resolveD(d) }) }) describe('of mixed values', function () { it('returns a promise for an array containing the fulfilled values', function (done) { var res = Promise.all([A, b, C]) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0] === a) assert(res[1] === b) assert(res[2] === c) }) .nodeify(done) }) }) describe('containing at least one rejected promise', function () { it('rejects the resulting promise', function (done) { var res = Promise.all([A, rejected, C]) assert(res instanceof Promise) res.then(function (res) { throw new Error('Should be rejected') }, function (err) { assert(err === rejection) }) .nodeify(done) }) }) describe('containing at least one eventually rejected promise', function () { it('rejects the resulting promise', function (done) { var rejectB var rejected = new Promise(function (resolve, reject) { rejectB = reject }) var res = Promise.all([A, rejected, C]) assert(res instanceof Promise) res.then(function (res) { throw new Error('Should be rejected') }, function (err) { assert(err === rejection) }) .nodeify(done) rejectB(rejection) }) }) describe('with a promise that resolves twice', function () { it('still waits for all the other promises', function (done) { var fakePromise = {then: function (onFulfilled) { onFulfilled(1); onFulfilled(2) }} var eventuallyRejected = {then: function (_, onRejected) { this.onRejected = onRejected }} var res = Promise.all([fakePromise, eventuallyRejected]) assert(res instanceof Promise) res.then(function (res) { throw new Error('Should be rejected') }, function (err) { assert(err === rejection) }) .nodeify(done) eventuallyRejected.onRejected(rejection); }) }) describe('when given a foreign promise', function () { it('should provide the correct value of `this`', function (done) { var p = {then: function (onFulfilled) { onFulfilled({self: this}); }}; Promise.all([p]).then(function (results) { assert(p === results[0].self); }).nodeify(done); }); }); }) describe('a Set', function () { describe('that is empty', function () { it('returns a promise for an empty array', function (done) { var res = Promise.all(new Set([])) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res.length === 0) }) .nodeify(done) }) }) describe('of objects', function () { it('returns a promise for the array', function (done) { var res = Promise.all(new Set([a, b, c])) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0] === a) assert(res[1] === b) assert(res[2] === c) }) .nodeify(done) }) }) describe('of promises', function () { it('returns a promise for an array containing the fulfilled values', function (done) { var d = {} var resolveD var res = Promise.all(new Set([A, B, C, new Promise(function (resolve) { resolveD = resolve })])) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0] === a) assert(res[1] === b) assert(res[2] === c) assert(res[3] === d) }) .nodeify(done) resolveD(d) }) }) describe('of mixed values', function () { it('returns a promise for an array containing the fulfilled values', function (done) { var res = Promise.all(new Set([A, b, C])) assert(res instanceof Promise) res.then(function (res) { assert(Array.isArray(res)) assert(res[0] === a) assert(res[1] === b) assert(res[2] === c) }) .nodeify(done) }) }) describe('containing at least one rejected promise', function () { it('rejects the resulting promise', function (done) { var res = Promise.all(new Set([A, rejected, C])) assert(res instanceof Promise) res.then(function (res) { throw new Error('Should be rejected') }, function (err) { assert(err === rejection) }) .nodeify(done) }) }) describe('containing at least one eventually rejected promise', function () { it('rejects the resulting promise', function (done) { var rejectB var rejected = new Promise(function (resolve, reject) { rejectB = reject }) var res = Promise.all(new Set([A, rejected, C])) assert(res instanceof Promise) res.then(function (res) { throw new Error('Should be rejected') }, function (err) { assert(err === rejection) }) .nodeify(done) rejectB(rejection) }) }) describe('with a promise that resolves twice', function () { it('still waits for all the other promises', function (done) { var fakePromise = {then: function (onFulfilled) { onFulfilled(1); onFulfilled(2) }} var eventuallyRejected = {then: function (_, onRejected) { this.onRejected = onRejected }} var res = Promise.all(new Set([fakePromise, eventuallyRejected])) assert(res instanceof Promise) res.then(function (res) { throw new Error('Should be rejected') }, function (err) { assert(err === rejection) }) .nodeify(done) eventuallyRejected.onRejected(rejection); }) }) describe('when given a foreign promise', function () { it('should provide the correct value of `this`', function (done) { var p = {then: function (onFulfilled) { onFulfilled({self: this}); }}; Promise.all(new Set([p])).then(function (results) { assert(p === results[0].self); }).nodeify(done); }); }); }) }) describe('promise.done(onFulfilled, onRejected)', function () { it.skip('behaves like then except for not returning anything', function () { //todo }) it ('rethrows unhandled rejections', function (done) { var originalTimeout = global.setTimeout global.setTimeout = function(callback) { try { callback() } catch (x) { assert(x.message === 'It worked') global.setTimeout = originalTimeout return done() } done(new Error('Callback should have thrown an exception')) } Promise.resolve().done(function() { throw new Error('It worked') }) }) }) describe('promise.nodeify(callback)', function () { it('converts a promise returning function into a callback function', function (done) { function add(a, b, callback) { return Promise.resolve(a) .then(function (a) { return a + b }) .nodeify(callback) } add(1, 2, function (err, res) { if (err) return done(err) assert(res === 3) return done() }) }) it('converts rejected promises into the first argument of the callback', function (done) { function add(a, b, callback) { return Promise.resolve(a) .then(function (a) { throw sentinel }) .nodeify(callback) } add(1, 2, function (err, res) { assert(err === sentinel) done() }) }) it('passes through when no callback is provided', function (done) { function add(a, b, callback) { return Promise.resolve(a) .then(function (a) { return a + b }) .nodeify(callback) } add(1, 2) .then(function (res) { assert(res === 3) done() }) }) it('accepts a `context` argument', function (done) { var ctx = {} function add(a, b, callback) { return Promise.resolve(a) .then(function (a) { return a + b }) .nodeify(callback, ctx) } add(1, 2, function (err, res) { assert(res === 3) assert(this === ctx) done() }) }) }) describe('inheritance', function () { it('allows its prototype methods to act upon foreign constructors', function () { function Awesome(fn) { if (!(this instanceof Awesome)) return new Awesome(fn) Promise.call(this, fn) } Awesome.prototype = Object.create(Promise.prototype) Awesome.prototype.constructor = Awesome var awesome = new Awesome(function () {}) assert(awesome.constructor === Awesome) assert(awesome.then(function () {}).constructor === Awesome) }) }) }) promise-8.3.0/test/memory-leak.js000066400000000000000000000017371432572512200167520ustar00rootroot00000000000000'use strict'; var assert = require('assert') var Promise = require('../') var i = 0 var sampleA, sampleB function next() { return new Promise(function (resolve) { i++ /* if (i % 100000 === 0) { global.gc() console.dir(process.memoryUsage()) } */ if (i === 100000 && typeof global.gc === 'function') { global.gc() sampleA = process.memoryUsage() } if (i > 100000 * 10) { if (typeof global.gc === 'function') { global.gc() sampleB = process.memoryUsage() console.log('Memory usage at start:'); console.dir(sampleA) console.log('Memory usage at end:'); console.dir(sampleB) assert(sampleA.heapUsed * 1.2 > sampleB.heapUsed, 'heapUsed should not grow by more than 20%') } } else { setImmediate(resolve) } }).then(next) } if (typeof global.gc !== 'function') { console.warn('You must run with --expose-gc to test for memory leak.') } next().done() promise-8.3.0/test/nested-promises.js000066400000000000000000000034111432572512200176400ustar00rootroot00000000000000'use strict'; var assert = require('assert'); var Promise = require('../'); describe('nested promises', function () { it('does not result in any weird behaviour - 1', function (done) { var resolveA, resolveB, resolveC; var A = new Promise(function (resolve, reject) { resolveA = resolve; }); var B = new Promise(function (resolve, reject) { resolveB = resolve; }); var C = new Promise(function (resolve, reject) { resolveC = resolve; }); resolveA(B); resolveB(C); resolveC('foo'); A.done(function (result) { assert(result === 'foo'); done(); }); }); it('does not result in any weird behaviour - 2', function (done) { var resolveA, resolveB, resolveC, resolveD; var A = new Promise(function (resolve, reject) { resolveA = resolve; }); var B = new Promise(function (resolve, reject) { resolveB = resolve; }); var C = new Promise(function (resolve, reject) { resolveC = resolve; }); var D = new Promise(function (resolve, reject) { resolveD = resolve; }); var Athen = A.then, Bthen = B.then, Cthen = C.then, Dthen = D.then; resolveA(B); resolveB(C); resolveC(D); resolveD('foo'); A.done(function (result) { assert(result === 'foo'); done(); }); }); it('does not result in any weird behaviour - 2', function (done) { var promises = []; var resolveFns = []; for (var i = 0; i < 100; i++) { promises.push(new Promise(function (resolve) { resolveFns.push(resolve); })); } for (var i = 0; i < 99; i++) { resolveFns[i](promises[i + 1]); } resolveFns[99]('foo'); promises[0].done(function (result) { assert(result === 'foo'); done(); }); }); });promise-8.3.0/test/promises-tests.js000066400000000000000000000001511432572512200175160ustar00rootroot00000000000000var tests = require('promises-aplus-tests'); var adapter = require('./adapter-a'); tests.mocha(adapter);promise-8.3.0/test/rejection-tracking.js000066400000000000000000000052761432572512200203140ustar00rootroot00000000000000'use strict'; var assert = require('assert'); var Promise = require('../'); var tracking = require('../lib/rejection-tracking'); describe('unhandled rejections', function () { it('tracks rejected promises', function (done) { this.timeout(300); var calls = [], promise; tracking.enable({ onUnhandled: function (id, err) { calls.push(['unhandled', id, err]); promise.done(null, function (err) { assert.deepEqual(calls, [ ['unhandled', 0, err], ['handled', 0, err] ]); done(); }); }, onHandled: function (id, err) { calls.push(['handled', id, err]); } }); promise = Promise.reject(new TypeError('A fake type error')); }) it('tracks rejected promises', function (done) { this.timeout(2200); var calls = [], promise; tracking.enable({ allRejections: true, onUnhandled: function (id, err) { calls.push(['unhandled', id, err]); promise.done(null, function (err) { assert.deepEqual(calls, [ ['unhandled', 0, err], ['handled', 0, err] ]); done(); }); }, onHandled: function (id, err) { calls.push(['handled', id, err]); } }); promise = Promise.reject({}); }) it('tracks rejected promises', function (done) { this.timeout(500); var calls = [], promise; tracking.enable({ onUnhandled: function (id, err) { done(new Error('Expected exception to be handled in time')); }, onHandled: function (id, err) { } }); promise = Promise.reject(new TypeError('A fake type error')); var isDone = false; setTimeout(function () { promise.done(null, function (err) { // ignore isDone = true; }); }, 50); setTimeout(function () { assert(isDone); done(); }, 400); }) it('tracks rejected promises', function (done) { this.timeout(2300); var warn = console.warn; var warnings = []; console.warn = function (str) { warnings.push(str); }; var expectedWarnings = [ 'Possible Unhandled Promise Rejection (id: 0):', ' my', ' multi', ' line', ' error', 'Promise Rejection Handled (id: 0):', ' This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id 0.' ]; tracking.enable({allRejections: true}); var promise = Promise.reject('my\nmulti\nline\nerror'); setTimeout(function () { promise.done(null, function (err) { console.warn = warn; assert.deepEqual(warnings, expectedWarnings); done(); }); }, 2100); }) })promise-8.3.0/test/resolver-tests.js000066400000000000000000000125671432572512200175340ustar00rootroot00000000000000var assert = require('better-assert'); var Promise = require('../'); var sentinel = {}; var promise = new Promise(function (resolve) { resolve(sentinel); }); var _it = it; describe('resolver-tests', function () { describe('The Promise Constructor', function () { it('has `Object.getPrototypeOf(promise) === Promise.prototype`', function () { assert(Object.getPrototypeOf(promise) === Promise.prototype) }) it('has `promise.constructor === Promise`', function () { assert(promise.constructor === Promise) }) it('has `promise.constructor === Promise.prototype.constructor`', function () { assert(promise.constructor === Promise.prototype.constructor) }) it('has `Promise.length === 1`', function () { assert(Promise.length === 1) }) describe('if resolver is not a function', function () { it('must throw a `TypeError`', function () { try { new Promise({}) } catch (ex) { assert(ex instanceof TypeError) return } throw new Error('Should have thrown a TypeError') }) }) describe('if resolver is a function', function () { it('must be called with the promise\'s resolver arguments', function (done) { new Promise(function (resolve, reject) { assert(typeof resolve === 'function') assert(typeof reject === 'function') done(); }) }) it('must be called immediately, before `Promise` returns', function () { var called = false; new Promise(function (resolve, reject) { called = true; }) assert(called) }) }) describe('Calling resolve(x)', function () { describe('if promise is resolved', function () { it('nothing happens', function (done) { var thenable = {then: function (onComplete) { setTimeout(function () { onComplete(sentinel) }, 50) }}; new Promise(function (resolve) { process.nextTick(function () { resolve(thenable) resolve(null) }); }) .then(function (result) { assert(result === sentinel) }) .then(function () { done() }, function (err) { done(err || new Error('Promise rejected')); }) }) }) describe('otherwise', function () { describe('if x is a thenable', function () { it('assimilates the thenable', function () { }) }) describe('otherwise', function () { it('is fulfilled with x as the fulfillment value', function (done) { new Promise(function (resolve, reject) { resolve(sentinel) }) .then(function (fulfillmentValue) { assert(fulfillmentValue === sentinel) }) .then(function () { done() }, function (err) { done(err || new Error('Promise rejected')); }) }) }) }) }) describe('Calling reject(x)', function () { describe('if promise is resolved', function () { it('nothing happens', function (done) { var thenable = {then: function (onComplete) { setTimeout(function () { onComplete(sentinel) }, 50) }}; new Promise(function (resolve, reject) { process.nextTick(function () { resolve(thenable) reject('foo') }); }) .then(function (result) { assert(result === sentinel) }) .then(function () { done() }, function (err) { done(err || new Error('Promise rejected')); }) }) }) describe('otherwise', function () { it('is rejected with x as the rejection reason', function (done) { new Promise(function (resolve, reject) { reject(sentinel) }) .then(null, function (rejectionReason) { assert(rejectionReason === sentinel) }) .then(function () { done() }, function (err) { done(err || new Error('Promise rejected')); }) }) }) }) }) describe('if resolver throws', function () { describe('if promise is resolved', function () { it('nothing happens', function (done) { var thenable = {then: function (onComplete) { setTimeout(function () { onComplete(sentinel) }, 50) }}; new Promise(function (resolve, reject) { resolve(thenable) throw new Error('foo'); }) .then(function (result) { assert(result === sentinel) }) .then(function () { done() }, function (err) { done(err || new Error('Promise rejected')); }) }) }) describe('otherwise', function () { it('is rejected with e as the rejection reason', function (done) { new Promise(function (resolve, reject) { throw sentinel }) .then(null, function (rejectionReason) { assert(rejectionReason === sentinel) }) .then(function () { done() }, function (err) { done(err || new Error('Promise rejected')); }) }) }) }) })promise-8.3.0/test/synchronous-inspection-tests.js000066400000000000000000000161041432572512200224250ustar00rootroot00000000000000var assert = require('better-assert'); var Promise = require('../'); describe('synchronous-inspection-tests', function () { it('cannot synchronously inspect before enabling synchronous inspection', function(done) { var finished = null; var fulfilledPromise = new Promise(function(resolve, reject) { setTimeout(function() { resolve(); }, 10); }); var rejectedPromise = new Promise(function(resolve, reject) { setTimeout(function() { reject(); }, 10); }); assert(fulfilledPromise.getValue == undefined); assert(fulfilledPromise.getReason == undefined); assert(fulfilledPromise.isFulfilled == undefined); assert(fulfilledPromise.isPending == undefined); assert(fulfilledPromise.isRejected == undefined); assert(rejectedPromise.getValue == undefined); assert(rejectedPromise.getReason == undefined); assert(rejectedPromise.isFulfilled == undefined); assert(rejectedPromise.isPending == undefined); assert(rejectedPromise.isRejected == undefined); setTimeout(function() { assert(fulfilledPromise.getValue == undefined); assert(fulfilledPromise.getReason == undefined); assert(fulfilledPromise.isFulfilled == undefined); assert(fulfilledPromise.isPending == undefined); assert(fulfilledPromise.isRejected == undefined); assert(rejectedPromise.getValue == undefined); assert(rejectedPromise.getReason == undefined); assert(rejectedPromise.isFulfilled == undefined); assert(rejectedPromise.isPending == undefined); assert(rejectedPromise.isRejected == undefined); done() }, 30); }); it('can poll a promise to see if it is resolved', function (done) { Promise.enableSynchronous(); var finished = null; var fulfilledPromise = new Promise(function(resolve, reject) { var interval = setInterval(function() { if (finished !== null) { clearTimeout(interval); if (finished) { resolve(true); } else { reject(false); } } }, 10); }); assert(fulfilledPromise.getState() === 0); assert(fulfilledPromise.isPending()); assert(!fulfilledPromise.isFulfilled()); assert(!fulfilledPromise.isRejected()); finished = true; setTimeout(function () { assert(fulfilledPromise.getState() === 1); assert(fulfilledPromise.isFulfilled()); assert(!fulfilledPromise.isRejected()); assert(fulfilledPromise.getValue()); assert(!fulfilledPromise.isPending()); done(); }, 30); }); it('can poll a promise to see if it is rejected', function (done) { Promise.enableSynchronous(); var finished = null; var fulfilledPromise = new Promise(function(resolve, reject) { var interval = setInterval(function() { if (finished !== null) { clearTimeout(interval); if (finished) { resolve(true); } else { reject(false); } } }, 10); }); assert(fulfilledPromise.getState() === 0); assert(fulfilledPromise.isPending()); assert(!fulfilledPromise.isFulfilled()); assert(!fulfilledPromise.isRejected()); finished = false; setTimeout(function () { assert(fulfilledPromise.getState() === 2); assert(!fulfilledPromise.isFulfilled()); assert(fulfilledPromise.isRejected()); assert(!fulfilledPromise.getReason()); assert(!fulfilledPromise.isPending()); done(); }, 30); }); it('will throw an error if getting a value of an unfulfilled promise', function (done) { Promise.enableSynchronous(); var finished = null; var fulfilledPromise = new Promise(function(resolve, reject) { var interval = setInterval(function() { if (finished !== null) { clearTimeout(interval); if (finished) { resolve(true); } else { reject(false); } } }, 10); }); assert(fulfilledPromise.isPending()); assert(!fulfilledPromise.isFulfilled()); assert(!fulfilledPromise.isRejected()); try { fulfilledPromise.getValue(); assert(false); } catch (e) { assert(true); } finished = false; setTimeout(function () { try { fulfilledPromise.getValue(); assert(false); } catch (e) { assert(true); } done(); }, 30); }); it('will throw an error if getting a reason of a non-rejected promise', function (done) { Promise.enableSynchronous(); var finished = null; var fulfilledPromise = new Promise(function(resolve, reject) { var interval = setInterval(function() { if (finished !== null) { clearTimeout(interval); if (finished) { resolve(true); } else { reject(false); } } }, 10); }); assert(fulfilledPromise.isPending()); assert(!fulfilledPromise.isFulfilled()); assert(!fulfilledPromise.isRejected()); try { fulfilledPromise.getReason(); assert(false); } catch (e) { assert(true); } finished = true; setTimeout(function () { try { fulfilledPromise.getReason(); assert(false); } catch (e) { assert(true); } done() }, 30); }); it('can disable synchronous inspection', function() { Promise.enableSynchronous(); var testPromise = Promise.resolve('someValue'); assert(testPromise.getValue() == 'someValue'); Promise.disableSynchronous(); assert(testPromise.getValue == undefined); }); it('can synchronously poll a resolving promise chain', function (done) { Promise.enableSynchronous(); var fulfilledPromise = new Promise(function(resolve, reject) { var interval = setTimeout(function() { resolve(Promise.resolve(true)); }, 10); }); assert(fulfilledPromise.getState() === 0); assert(fulfilledPromise.isPending()); assert(!fulfilledPromise.isFulfilled()); assert(!fulfilledPromise.isRejected()); setTimeout(function() { assert(fulfilledPromise.getState() === 1); assert(fulfilledPromise.isFulfilled()); assert(!fulfilledPromise.isRejected()); assert(fulfilledPromise.getValue()); assert(!fulfilledPromise.isPending()); done(); }, 30); }); it('can synchronously poll a rejecting promise chain', function(done) { Promise.enableSynchronous(); var rejectedPromise = new Promise(function(resolve, reject) { setTimeout(function() { resolve(Promise.reject(false)); }, 10); }); assert(rejectedPromise.getState() === 0); assert(rejectedPromise.isPending()); assert(!rejectedPromise.isFulfilled()); assert(!rejectedPromise.isRejected()); setTimeout(function() { assert(rejectedPromise.getState() === 2); assert(!rejectedPromise.isFulfilled()); assert(rejectedPromise.isRejected()); assert(!rejectedPromise.getReason()); assert(!rejectedPromise.isPending()); done(); }, 30); }); });